From 7bce33982a94ab391208f9228b489b98568821b8 Mon Sep 17 00:00:00 2001 From: extempore Date: Mon, 28 Nov 2011 08:03:10 +0000 Subject: [PATCH] Fix for erroneous bytecode generation. A remedy for an IllegalAccessError where generated bytecode referred to an inaccessible type. Closes SI-1430. Bonus materials: - tore out all the invokedynamic support. The shipped jdk7 implementation shows limited resemblance to the one this was written against; the code mostly serves to distract. (I think I could get invokedynamic working pretty quickly, except that it would mean having a codebase for java7 and one for 5-6, which is not a yak I wish to shave today.) - gave NullClass and NothingClass objects of their own, which allowed a nice polymorphic simplification of isSubClass, plus a couple other streamlinings. git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@26078 5e8d7ff9-d8ef-0310-90f0-a4852d11357a --- lib/fjbg.jar | Bin 131538 -> 130014 bytes .../scala/reflect/internal/Definitions.scala | 26 +++- .../scala/reflect/internal/Symbols.scala | 19 +-- .../scala/reflect/internal/Types.scala | 3 +- .../reflect/internal/transform/Erasure.scala | 2 +- .../tools/nsc/backend/icode/GenICode.scala | 17 +- .../tools/nsc/backend/icode/Members.scala | 1 - .../tools/nsc/backend/icode/Opcodes.scala | 4 - .../icode/analysis/CopyPropagation.scala | 2 +- .../scala/tools/nsc/backend/jvm/GenJVM.scala | 147 ++++++++---------- .../nsc/interpreter/CompletionOutput.scala | 2 +- .../tools/nsc/matching/ParallelMatching.scala | 2 +- .../tools/nsc/symtab/SymbolTrackers.scala | 2 +- .../symtab/classfile/ClassfileParser.scala | 2 +- .../scala/tools/nsc/typechecker/Typers.scala | 9 +- .../ch/epfl/lamp/fjbg/JAttributeFactory.java | 1 - .../lamp/fjbg/JBootstrapInvokeDynamic.java | 69 -------- src/fjbg/ch/epfl/lamp/fjbg/JClass.java | 8 - .../scala/runtime/DynamicDispatch.java-notyet | 42 ----- test/files/run/t1430.check | 1 + test/files/run/t1430/Bar_1.java | 8 + test/files/run/t1430/Test_2.scala | 16 ++ 22 files changed, 136 insertions(+), 247 deletions(-) delete mode 100644 src/fjbg/ch/epfl/lamp/fjbg/JBootstrapInvokeDynamic.java delete mode 100644 src/library/scala/runtime/DynamicDispatch.java-notyet create mode 100644 test/files/run/t1430.check create mode 100644 test/files/run/t1430/Bar_1.java create mode 100644 test/files/run/t1430/Test_2.scala diff --git a/lib/fjbg.jar b/lib/fjbg.jar index 3ef762812a2dd21e69310faf6163f5693270b5ab..e7bf61d7181bf6b14a3391ecd4cf901c090a86cd 100644 GIT binary patch delta 10641 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 delta 12076 zcmaL71yoes_dY(C?(XjHZbTaC6c7+;MOsQ^1nEYEp%Fn)8ip7Nkp}6I2I-Op1w`RD z%=o_V-_Lig|F9PK@I24nXYYN^z2`9ZES_PGy}-iPzk`Z~0|H@zKs6EE$@pCO)e+o^ z8I+Nx)*uk*Ve)M=q5+>2ytpUv{Bck4@#%H&@smsFP%GiuJ_f{PhxO)?LIiLjuCf3> z;`#`Ag=PWwv2Fn96?Pjy3~wlI&R_rLL<4~=;C-?{0A7FsGQ0v1Lcik*qal>sL|zyO zWt-~MNDU?kL{1C>aU+%Ps{jQ!)ePH`c8Xjc^|olQvPaVD-2}US-90QIZ7K|F1;cLj zzMThA1eaTOT!hj~`2nu6Ufd^VX>Qvei!XQf<0VHUIDDsST`tvsvi|(uoJ@pDqkMUE zw3sD%_R(+n!`xQRb@LI$^WW!ASdj)Vm%~QF40$mOC_31M@0oh2c7Gv)fW2|L?VHWo z#HkOA4uh!~^@Vs>U*IUPt#;rH^`1wCZrTSKxABT76y3M(?&;#rBl?;5>gYYu&m$M= z%FpN8Sh5C&hvvdyUA#QX4$9k6E3vmX@7(^;-(FbRdtMS+8Sa5*Lud>7inS~rWYpcz z+0mdp9eIFNeen4_H|`+P0}HH}bfiqJh?7sLn07=;J>~GrxO>?C*S&5*i}y!&s9Rqi zJ)&++X8KmYPGv@iEvt5Vubpck9os02pUqLgz9u?9MO_ci6#XaLyI1_uT{ZjDT`$89 zd(rn^rg6yzh#r-he$JW1A)A$wlE}=YQk0bvmbe=GbRPXGEWz7E(+FAvj#e__P35A@ zkZ`Q6*`_PiebKLuYm~Mg+a2e!rQ6PWYcIitvF<*2@w2Qt8(!yRTg}i#P6`RiiyyVj z`OnzgsSDO;;taA!L^%9p)LgAZIqM!+%S}n3>I&#-`CiUH_4?!)bD=#W93kfU(O@=#j8l)Q_`@JS_ekxL>=xw!6J* z=2Nh=_BeK<*5wXI!b7M)XGAPp?N*V5BiVo}(7EQGB%0QRbV06@czQyz zxC#cE^DB*Z@8E{8o$i|276GO0sX+@ju^yGEFhk!D?`V|+h?}!$Z~IhA8FjgkZ5>4L znF)uH@+2(7Vu-U>0QJY5RgD>1 zHhK>oXAWEK!lTq1e#72o`9=d)Iw;sy3bUnQazCH`D*R^r6zz*`e+heql3-WRX)_6f zj^Yc`FHDK2){5H^KWhm>*Y6&VWqXPJW@)i1^#~TLBzpg?L@L^d1?;cJ?rO;!ZZiK# z$I;m?lmfbL-eI9DjZIitp`qR%;B8Sj^TS{+`r)XdbOEkN!4GYpix_+3F8+Cn4tjEO zKCGtT(iL;O(sTMn{pzT%(B(2CR&L>k>UFpCohf@u?NsE;g=9LwD(7f&PA_Sw87`4F%3tO*ohT0QPVnRoDDH2=dvgEEuVX6>i9&gH!jT!t_<%U z4t-V*;$h1YGl`TAuH@u4yLFYQ@Ax%j#c-fx_h{G=!s%yW?yTVH6wHi!_eJi?~bof z#PD>zCS_NUY^zyRVEO5V504WieM9k)sCSQy)^1?YV;eroAsNw@&~#gyc6(2ulP~hV z>G5e^Yo!^!6+bb+mbjCv!g<}hydS!ruBlWw+fXc<{Km-9$devo#CY*59;KFvDNw)+ z7=147PWogZ$J|reon&u1^_9xSx>R>DxF7@koYdwynT?83ATa1h6y>*|bf@`}AoPep z8t-lBq`x{>9RB`o{DMI%IU=>DrfI6~7yEBmHyaAm*E@=@6zMQ>G;<=fjYddmT9`T2yD=Xc(9 zN)8*yT6BeY7J~fP&y(g;Z!NB^FIq5&8<7)Y-puan8o^tqBev*{Gw@Fp7 z$D_Ubnn9@(3723>9YT*>9J{A}=(5%wKU7u5W2ZG0{GP~}wl%?8nnLAq{eQWg>2&gJ z(ZzpNdtF)_dOq>w2T|qiGp%siW=F{*&OWs-y;fp`Vyr57;PSbNt|w{^hPgiA~OeG!=OIR`;;*2Tz6EzCy4?X-Pk z87l0;F|ROLEj=D?^-$sup`81+m)|rUh+DR!YMvMGFS_f@6>nYQjmFHdJP;lxwoJ`H z)tAZX$;o5Q6VDm z_2kLWM&GM_F9|*V4*cYR0j4{bvmWHqi&RU$IgaDTC@ee|zbhr#p-_Ghw3{3>jh^JH z3a}G@W&PyrIkS>AxKTQ;xX+48z1Ny5vd@OgsO-hhW+~J8FAK zJ6ZE+yGil$x&o)N;Z|qkJq3>;1*e1Gd+rC&voOW$pL>2FqjTLhDhg#VEcPuC%U#2y zE)mG$W=wV{VO4u#DGvV`Sx{7>{TjKC9e-4!Lm6gu{%g!UwCcVy{*OU4olbOHCrlrg zHU-Ip&~?<5l!)1>WnLK9m5FqyRKT((OXt>o%u9{O=bnb=oE~R8OwtYd>?dnRFyG~S zRA*7|)A^|e4|Qt0a4ta!Y4q0Xqsku{h{Etk(5xDr2v+(RR5a=u@3=f3ALCFlQGZsy7 z!JP=BRW4*@c~RqGJW=|F+uqek+RvvrP(RrmHM2C$xdaC-{$5Tb6i5# z(J5{Cbor;BI@2Zye6|P6)QQL1%K0YDJzS8^+jn*nH^>l3TNq*wsxdt_T@cub#W*PH zrw`n~P&Yne@wMMAfyH@JN5shQmcl|y?|JK}nX94~#c**L&$rKs@R6I$7YEI44`t&| zgg&;EILo%9IwrV-b09N%sZy}0&>+o5eV*zp7O10&Phhiyw~zsLmZ2xlp)v7%uAFJF z+VxoXRHF-3AJTLEovQELqD%5TEoNg`bd_lC_CkIpL3WFpZ`~J3yz%R2Oy{NXK4W7V zikrOZ@~>01DvsW!_ozoTy1|ss#@~&bem=0MXO-a^9`Pd%>DFkqnfgq5w2%?&{v_&7 z0DA316UlAbtYeWau$;JE^{%3GQ-4~WO=Z2;kE+3J@%KH`BS}%rKG3w@ymvq9neQ#- zzqA&0ZJBs@)LbC_J@ef-1;>{9VgcLMtt&3As(@6I0 zqV0Fc_>u#|DtZptNfMW`TyF*9T`L>pkKBSs)m1Sp(LbmCh9W)jrHG0(gqEW4+U)9ffp!*czKw$Fx3BKe+%mCXF=du}`c&(D1p;y$m%Mt@Zwu)DJHFEf=FdFnThe zsLD1Gm_|e%5b=CYmEb|zZq}=NhO5oJnsPnJ5A)x-WUVljpRnw-fBpOE zcEvnHUQY@FQ3^l|2mtDoTn2nFc2J5*{dJy1A0(pECj=z~#ew*a;X9@`6e{L8VIdUe z4h9-omF!6z;+p33>YiQCFwH#LJn1kY7ls1x<7Luy}Z<#J4<*U<@fB1$HvxS{qOSBe#>(ef^jnNl7?>) z;ldr!AcZL*A#^ALKp-%pLnw+(e z#3C1;nx)(~qdtV)M&;U$y-wgFHK<&=bByVM68<2C<|bCohhywspWL92#iK#gl+F|C z1sL%$;tx-k$Q7%0qW*3y&~ugl5K)Hxy$XYFd@KHqJNxrTxx3Lh1>YJX1n&QSYpn1^=6} z6DD2T_{paud^`(GcAYwpZ;SHer3cNfdlzM`h;Yom@-d3clK7FYLpJ6NrJG$Tg4)Z? z>1@Kb?br~R# z;Iup94=dP^tSl9uwPdMFzHj;TasSVv$=QH$?~x*+pByr?@&4Xy=^A2abLplRzrMG{ zD=CmaF1H%k8Z~XhQBP58W}kM&G7KGYPvy5@nIv|XaExS)&>R?Lhy|-+vF@g8_E#kt zoVx}X@ug|At+xHhXpgJXI-H}=PFBNHk?fYBg4V0Nc)aY$VK6@e;~1$b3?ALx7X3y^ zS}Vc&L4e|cFJ}6@FIz|Q?8WjH2CJB2w#G5B*`4VqtO$k#wRl*g#oEb?6-S?L-@e5vPb9r-#pxNK+QBNFO4SU;-3NFMcMzDRax^S`?>`34@*fDD!E zBXQz9hsjJGHS7*TR_uJest+?7Y>w)o<=T_PCKbZ#9yCJi*gfEfPUtCZw`yBh`%tLc zB-n|I|c_zw~0jU=nc|z8svI28!bh0tzKe(I4vp; z_J)pD#OZQ95`P)%%~A^fez)m0@x(1%e-q=xI(#8j3C?aYYs;FqIr+>%A@KtCDZ>=P zxh@K~-^x4A!uCDD4{X(qR89@<%BTIVkD^>zj&Ec8I;OsKcg$Hg#!Pf)#a@W}orRRJ zEFHdA^V9a|Z5@&~gKr>V$@d&PNz15Ay`L~K{ou8Aq|lhK_dS2}yiUO2l{qAJ*I0=v zHS!|&qEO|%xNOm*-Qo4vhiRgA6ltPVID-^ZOn7xC^8pWyF2F_5u1;t?BdN{<7P5yz z66S21rgL3S6)b0Ck~wxYcx(=TtYA;HQ>k)kl$avbZWT*y79dB zSg}X7_Cr^6yS2%o^qDeJ3K;Znf{X}RJ`@H&(Xz}FV2n83A>RL44?pf|uuceSQM+?^gMn%f|_~ndz^i zzdE0?<}eg7l6Ft0zp?Dk=($xa@1LpvtS~V$LDrM9fb>PbE_2AwcEHXfeH}9sKpo>$p>nm|27%Ma&$LYcUV#rk>pF+{c z(H}+Lx+Jy5-xAe1>^R!1gVVm%>JvziN8HWe8OdY}ezR(nfF76|Tr!U9bE}wg{e+~Y zY*Z=7n)toV+q~^ln%~*(`8HMFvz#auLXO?Dv*zGNeUm$KlcwT^Y~UQ|utuWpvl**x z$Z^1n#fhULu9|l-{T8e=TE^R3B#~pK?T`0}mD|}2x`uV}uLHyaW9!B(HF?jP2Q%tQ zw7%1t&<+~*#X)R5bq<#4-QMS-qo}s;1Z1uUR7zuozqtNXW8p?8W(^hBC*VRfJ zArTBG0rI6&SH9E{RRi@HqPWMbWnkAW3sv(;uso~l!L|aE3~hjv74Fz4xfZfZQo{V_ z#`G2UpUTS0*=Aeu+nuzRoZXK(Pz3sUc9U3e*KDtKH1Zr z;SuPT|28JE4D5!BtXj+YDVa`}q%W1o*4ot_|4*J5vgVtA62`zD~AQNW#PK zPb1aK?{fFk*Jlz52#huMJ=Xn9XyxEthRZ=S0bP&EtTao^dnH0~=yNUAwR3PZSN!vf zX!+)T-Qs0sCad<>ZH#F8PjQnU`|iq5$$1K34TKA;t7rym?f2a$AZ$60=;|Q4r0ksK z2X8M{YfCfPvrV%qXZ*Ab{<5QSA5EY`0`zRTD;0(lRvKXX9M}@vBklP8*3ytwQu|?Z zU#53YXMwVeC_{_k+Pf!iofH0%H1uQq?~=2G#P?rS`y`2B$uaivo~*H)*%|N z-mzIp*Fd>epi6e%s1JJ}NSEW``$8a35glAk>XvuyN%o|j)h``(_}Syyq7Aw;l_sy~;x3#=jB3z8TuxaYy5>2*YXQ7u zgTXOaY=eyRnPh9qjJ^7@y;C@}y&4z%dm7a2V~k^0FB5QWS9iddy<6g8A|-mMUaa5p zh5gca(~!$z+1@X_>GoXsc2M*j=UuyRG0m#OZ4LBq7vDH7-)XbioQ=P#xeK)l3Nd>m zBb)$8oSRCL&b!N~HXQlg#{+LdsUvC{)nA9|*o33MQ)BJ6WlrdN@BHZjpB*$09P-xL zfvbB%k&t($wsiX140@fL&?2|rVIh~u6db|vE2iiAKIO&p_)BbyL-s@)JNl=p>6gF1 z8^_=qM`OjS(dyiKrK=L>_&R6f*cx@E77cs-o~6NnusF%na|z4_K2-9x&OE-}F5`!X zSPZJfS_j^a|{K47l4C-ID?3-_I{0J;0TPGxPqD~iK73d;eNf>Zq z&0Q16*Ly$B?i=*-$570a1w+?hj_b=6dFs^0i4}^jk8Uh?2Z&0YTL+gveuxyTlK&OA zH^>feRm=b4%Y_o?Ikq|I9kid5Yu}%+p4b?JiNr?a<{y!orfU{-KY0BK@)Uf$Q}=E61(o>_}Y~YZ=+c+jIjX84pIeNo5=e*4TY)DDrFY^34uQ zRGsDR?o3t$lJ)G~l1|C0qJIW%6iW8~Ry}+kp@C7p<};h4|JlUtYe)1NG2TWM-H;Ne zpK*qdNTo_@Ac>}u>=$08Y$Fnw%FdFrg8pbG+B(`7+ue$GaMDp;jlAeogKK$EnT?Z0=C$uplbq zJ)9M=Ynk-*qx;fV{}Lxie4L`IDUH=DFr)snp=Xjc0@%haXuKKd~hX z?|BSe9dL<%>`&iNg+LwG-k)tYIlpw*z%Si6m%*G8`lS#^{{iQxyvoU!r5xRNRTSu%LfI%`zv zu^MJw8T5>NwXW=gBDYrEIkeFMz)$!h`*Mkb{^R6-`{0?w$j=CVDMc_r0 zxRbS5$MKrd%A;e*?F9vGP1_x)RP^<_3e)#KuPr6&$gA{6amw48ShD0TE-{OJzXT!H z(floXM;WT_A*$|CEi5olPEu)DNLiQ?mG&avn6gNrV$atB97rsAq@ljBQ?!w(N2;uR zIQ2rOT#cs5h>J>^L@Zczme14#=leSy_-2ISNY8(;tDwy{^TX>6&_mdR>^fBSBmGuo zt+km9k^lloZ?l|PYHx^BqmUl#!djVfqjE{XUMZ&l7oWE|p~bn(`)8*z<>yV~=y6p# zXlzqPZtrnuKQCvzD))s@(yw%lRiW_ig4~DINeOKt0_UcqDrMlecEoQqwO}qBP;>dt zuSYg~Nhx-vFK8CGDGsGQvILwBZJnRw zjDHIvDJC_$^&4GA8K;k1J9u#4UE$R7$l;AF`oj7XhY>3Z@J}%{oBpjh(o@BdBDe2u zYelGH^v|3*o_^+wdlNV@LYLk9_)`!A<)~cQYxKLy@y>6<=UMpLIo$Avir1&LikH1C zLLRxWyA_zgAU&Adcs^q^yTx_>(V_m3%p**kWm1tt_PV63c4Mt?sn}-Ti=|y$r8zL> z@w-)RBIU}|Q(%E>`vL-c!ArF-Tm^^Rk`nv9g@<4(NUFwo;}Lz!4rg)CY4w+u>~D=0FA zb6Y{KPUixRL}%lw)5?}dY*ulb+a%4}kQI|gJok}x|GbJ%n6>zf(!VLG5Xy{tYdXcEmK9(fPO*yyAN)TR>K$%IO0X^i^J~kn5jeAB-|LnMd~VeC!aPGNBaN2$j+ za3p{@(_k;kj*e)=Nrj>!8pLv|Na{>J0ojOBd?SXS_P^JjCaY8({ z0Ai?VDjV{s#j^|xq~F<0a^&d@w@$;cPWaIe5x7gCf8F6jhPME8NbEL%nPy!! z5-IMLK{nPt|LLoC+hHPzE1OA){3)=_)nP>xFEMSTl zyN2*Mpa-ebO9tjJ5IX*JKoIHKCI>)A_U2R!#39Pr@Z&vDiEO=T*FGY;YV8;#mwZHXKv~;z(1@TEGU`imnIDkz##zfSVOA#zl$= zJ^*4U*f+x!>&4g13Q4R7SR34$;2@%EXf9}IEAV;t9u+cL4KOqewE!mof=RjZzq<-& zijfQ?=_i2MaM}v&A?dUH%AE~3UHZomza2P3)&jE=xP#2rWC-9uwt}aDSxi*;@g|7n z5+L>W0Vl}oB|u#4CPMg}|MvsGmHvE)Kzm9}@V1>Z{G}y;LWYVwD+M=zU@rr-wDU;L z!Nbw@{|FS}0ssYKxeOrY8YB?@Hwr(HGKxzEDP0B-!;Js|E6C(BzX+E^}_cT3k5D23h<^xpxE75+RgKs{jqtO?rQwrTQm3 z__Z)3i2|YYSOu67%Ku)+f zBI%`7c*ORSDa$V@Uy3k6vep4SL@4f9Z*}M4H+cuV>H>dR?@Qf?Q({D^AxUe0DwMYd z_d=m?LqNvY02+kr!y7P538AJ}z=a5|1C$6ta~)2EC?nL*)&U*_SaJiBs3O3{b$|>J zMO=*)ksti9nhOaC#PL@Y4FL!x_Xa?Z^tk~y_XQu5Jj6Bsd|QLKKSuiQW5SVY_)_k$OWwDmVYc+;;=sONWDU5Watu!dq}KHxmxB zrl_S7{pTX-hQQ2A0kSzE;d=lHBE;<*(Ejxem_n3=3ps$hL1g*Yga5BAgYw~O5k!Xw zrGpx4nIHVg>WK>i$^NBGcmt1u1){S9kV7uE|MW<(1MkuL-9HR+#Di|Yhh_hOKwLDyE z*73j}doFNSe^*4H^ItXd-k%I*_uy`-yKe}H{62vD-{554FgE@FF>C+WT-`9jL;o-= zh;H$Njt^hJ2LcuEe{*#kL3B&rPY9{n|1+an_u(!SCgB7#z%wDF^zJdhjgacqb+p>RR}4Y;`u}%?m{K=VF@);Y_wXD_xM~fai_BjROJr|U zERavq00G2C0>Fc~9sNn>)(Jc|YQ=wfGDOu8{`PRP!&{fg^}wtqGqnH^KWzBm3W3zWwH3 zJtsn1oi*cQ2)~tW;bHw<*P}9s=Na-;GbH~E-q-WW8-NzVR03c^md^eu^bI9agQPgm z0a8Q`^5<|guNH~IH&>XDpz}Wlu{V@{!wp3Pfp4!cA$@QP5e)YN@dZ0Pn43r6-@#OW zKzwr9{%01{U53ON2C-f#oBZIhK0u;xyjnU8+C?0x|#P1#1z2BuoP=6#942;WsD def isTerm = false // to be overridden def isType = false // to be overridden def isClass = false // to be overridden + def isBottomClass = false // to be overridden def isAliasType = false // to be overridden def isAbstractType = false // to be overridden private[scala] def isSkolem = false // to be overridden @@ -951,6 +952,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => } def hasRawInfo: Boolean = infos ne null + def hasCompleteInfo = hasRawInfo && rawInfo.isComplete /** Return info without checking for initialization or completing */ def rawInfo: Type = { @@ -1236,17 +1238,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => owner == that || owner != NoSymbol && (owner isNestedIn that) /** Is this class symbol a subclass of that symbol? */ - final def isNonBottomSubClass(that: Symbol): Boolean = - this == that || this.isError || that.isError || + final def isNonBottomSubClass(that: Symbol): Boolean = ( + (this eq that) || this.isError || that.isError || info.baseTypeIndex(that) >= 0 - - final def isSubClass(that: Symbol): Boolean = ( - isNonBottomSubClass(that) || - this == NothingClass || - this == NullClass && - (that == AnyClass || - that != NothingClass && (that isSubClass ObjectClass)) ) + + /** Overridden in NullClass and NothingClass for custom behavior. + */ + def isSubClass(that: Symbol) = isNonBottomSubClass(that) + final def isNumericSubClass(that: Symbol): Boolean = definitions.isNumericSubClass(this, that) @@ -2425,6 +2425,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => unlock() validTo = currentPeriod } + override def isSubClass(that: Symbol) = false override def filter(cond: Symbol => Boolean) = this override def defString: String = toString override def locationString: String = "" diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index d11d2e1c1..f98b63d35 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -3063,8 +3063,7 @@ A type's typeSymbol should never be inspected directly. case TypeRef(pre, sym, args) if (variance != 0) && (occurCount isDefinedAt sym) => val repl = if (variance == 1) dropSingletonType(tp1.bounds.hi) else tp1.bounds.lo //println("eliminate "+sym+"/"+repl+"/"+occurCount(sym)+"/"+(tparams exists (repl.contains)))//DEBUG - if (repl.typeSymbol != NothingClass && repl.typeSymbol != NullClass && - occurCount(sym) == 1 && !(tparams exists (repl.contains))) + if (!repl.typeSymbol.isBottomClass && occurCount(sym) == 1 && !(tparams exists (repl.contains))) repl else tp1 case _ => diff --git a/src/compiler/scala/reflect/internal/transform/Erasure.scala b/src/compiler/scala/reflect/internal/transform/Erasure.scala index c038c1347..6c130e2bf 100644 --- a/src/compiler/scala/reflect/internal/transform/Erasure.scala +++ b/src/compiler/scala/reflect/internal/transform/Erasure.scala @@ -75,7 +75,7 @@ trait Erasure { case TypeRef(pre, sym, args) => if (sym == ArrayClass) if (unboundedGenericArrayLevel(tp) == 1) ObjectClass.tpe - else if (args.head.typeSymbol == NothingClass || args.head.typeSymbol == NullClass) arrayType(ObjectClass.tpe) + else if (args.head.typeSymbol.isBottomClass) arrayType(ObjectClass.tpe) else typeRef(apply(pre), sym, args map this) else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass || sym == NotNullClass) erasedTypeRef(ObjectClass) else if (sym == UnitClass) erasedTypeRef(BoxedUnitClass) diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 7d41f8c73..c28eca5a3 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -24,7 +24,7 @@ abstract class GenICode extends SubComponent { import icodes._ import icodes.opcodes._ import definitions.{ - ArrayClass, ObjectClass, ThrowableClass, StringClass, StringModule, NothingClass, NullClass, AnyRefClass, + ArrayClass, ObjectClass, ThrowableClass, StringClass, StringModule, AnyRefClass, Object_equals, Object_isInstanceOf, Object_asInstanceOf, ScalaRunTimeModule, BoxedNumberClass, BoxedCharacterClass, getMember @@ -923,13 +923,14 @@ abstract class GenICode extends SubComponent { } case ApplyDynamic(qual, args) => - assert(!forMSIL) - ctx.clazz.bootstrapClass = Some("scala.runtime.DynamicDispatch") - val ctx1 = genLoad(qual, ctx, ObjectReference) - genLoadArguments(args, tree.symbol.info.paramTypes, ctx1) - ctx1.bb.emit(CALL_METHOD(tree.symbol, InvokeDynamic), tree.pos) - ctx1 - + assert(!forMSIL, tree) + // TODO - this is where we'd catch dynamic applies for invokedynamic. + sys.error("No invokedynamic support yet.") + // val ctx1 = genLoad(qual, ctx, ObjectReference) + // genLoadArguments(args, tree.symbol.info.paramTypes, ctx1) + // ctx1.bb.emit(CALL_METHOD(tree.symbol, InvokeDynamic), tree.pos) + // ctx1 + case This(qual) => assert(tree.symbol == ctx.clazz.symbol || tree.symbol.isModuleClass, "Trying to access the this of another class: " + diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index b5602448d..497bce727 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -106,7 +106,6 @@ trait Members { self: ICodes => var fields: List[IField] = Nil var methods: List[IMethod] = Nil var cunit: CompilationUnit = _ - var bootstrapClass: Option[String] = None def addField(f: IField): this.type = { fields = f :: fields; diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala index c4edd7337..da7e37837 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala @@ -616,7 +616,6 @@ trait Opcodes { self: ICodes => /** Returns a string representation of this style. */ override def toString(): String = this match { case Dynamic => "dynamic" - case InvokeDynamic => "invoke-dynamic" case Static(false) => "static-class" case Static(true) => "static-instance" case SuperCall(mix) => "super(" + mix + ")" @@ -626,9 +625,6 @@ trait Opcodes { self: ICodes => /** Virtual calls */ case object Dynamic extends InvokeStyle - /** InvokeDynamic a la JSR 292 (experimental). */ - case object InvokeDynamic extends InvokeStyle - /** * Special invoke. Static(true) is used for calls to private * members. diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala index 897f08f08..eccde8f40 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala @@ -321,7 +321,7 @@ abstract class CopyPropagation { out.stack = Unknown :: out.stack.drop(i.consumed) case CALL_METHOD(method, style) => style match { - case Dynamic | InvokeDynamic => + case Dynamic => out = simulateCall(in, method, false) case Static(onInstance) => diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 55e82a186..142216ac6 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -31,7 +31,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with import icodes._ import icodes.opcodes._ import definitions.{ - NullClass, RuntimeNullClass, NothingClass, RuntimeNothingClass, AnyClass, ObjectClass, ThrowsClass, ThrowableClass, ClassfileAnnotationClass, SerializableClass, StringClass, ClassClass, FunctionClass, DeprecatedAttr, SerializableAttr, SerialVersionUIDAttr, VolatileAttr, @@ -332,8 +331,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with ifaces, c.cunit.source.toString) - if (isStaticModule(c.symbol) || serialVUID != None || isParcelableClass || - clasz.bootstrapClass.isDefined) { + if (isStaticModule(c.symbol) || serialVUID != None || isParcelableClass) { if (isStaticModule(c.symbol)) addModuleInstanceField addStaticInit(jclass, c.lookupStaticCtor) @@ -375,9 +373,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } } - if (clasz.bootstrapClass.isDefined) - jclass setBootstrapClass clasz.bootstrapClass.get - clasz.fields foreach genField clasz.methods foreach genMethod @@ -913,8 +908,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with mopt match { case Some(m) => - if (clasz.bootstrapClass.isDefined) legacyEmitBootstrapMethodInstall(clinit) - val oldLastBlock = m.code.blocks.last val lastBlock = m.code.newBlock oldLastBlock.replaceInstruction(oldLastBlock.length - 1, JUMP(lastBlock)) @@ -940,11 +933,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with if (isParcelableClass) addCreatorCode(BytecodeGenerator.this, lastBlock) - if (clasz.bootstrapClass.isDefined) { - // emit bootstrap method install - //emitBootstrapMethodInstall(block) - } - lastBlock emit RETURN(UNIT) lastBlock.close @@ -975,28 +963,9 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with if (isParcelableClass) legacyAddCreatorCode(BytecodeGenerator.this, clinit) - if (clasz.bootstrapClass.isDefined) - legacyEmitBootstrapMethodInstall(clinit) - clinit.emitRETURN() } - /** Emit code that installs a boostrap method for invoke dynamic. It - * installs the default method, found in scala.runtime.DynamicDispatch. - */ - def legacyEmitBootstrapMethodInstall(jcode: JExtendedCode) { - jcode emitPUSH jclass.getType.asInstanceOf[JReferenceType] - jcode emitPUSH new JObjectType("scala.runtime.DynamicDispatch") - jcode emitPUSH "bootstrapInvokeDynamic" - jcode.emitGETSTATIC("java.dyn.Linkage", "BOOTSTRAP_METHOD_TYPE", MethodTypeType) - jcode.emitDUP - jcode.emitINVOKESTATIC("scala.Console", "println", new JMethodType(JType.VOID, Array(JAVA_LANG_OBJECT))) - jcode.emitINVOKESTATIC("java.dyn.MethodHandles", "findStatic", - new JMethodType(MethodHandleType, Array(JavaLangClassType, JAVA_LANG_STRING, MethodTypeType))) - jcode.emitINVOKESTATIC("java.dyn.Linkage", "registerBootstrapMethod", - new JMethodType(JType.VOID, Array(JavaLangClassType, MethodHandleType))) - } - /** Add a forwarder for method m */ def addForwarder(jclass: JClass, module: Symbol, m: Symbol) { val moduleName = javaName(module) @@ -1196,6 +1165,68 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with log("Empty exception range: " + p) } } + + def isAccessibleFrom(target: Symbol, site: Symbol): Boolean = { + target.isPublic || target.isProtected && { + (site.enclClass isSubClass target.enclClass) || + (site.enclosingPackage == target.privateWithin) + } + } + + def genCallMethod(call: CALL_METHOD) { + val CALL_METHOD(method, style) = call + val siteSymbol = clasz.symbol + val hostSymbol = call.hostClass + val methodOwner = method.owner + // info calls so that types are up to date; erasure may add lateINTERFACE to traits + hostSymbol.info ; methodOwner.info + + def isInterfaceCall(sym: Symbol) = ( + sym.isInterface + || sym.isJavaDefined && sym.isNonBottomSubClass(ClassfileAnnotationClass) + ) + // whether to reference the type of the receiver or + // the type of the method owner (if not an interface!) + val useMethodOwner = ( + style != Dynamic + || !isInterfaceCall(hostSymbol) && isAccessibleFrom(methodOwner, siteSymbol) + || hostSymbol.isBottomClass + ) + val receiver = if (useMethodOwner) methodOwner else hostSymbol + val jowner = javaName(receiver) + val jname = javaName(method) + val jtype = javaType(method).asInstanceOf[JMethodType] + + def emit(invoke: String) { + log("%s %s %s.%s:%s".format(invoke, receiver.accessString, jowner, jname, jtype)) + invoke match { + case "invokeinterface" => jcode.emitINVOKEINTERFACE(jowner, jname, jtype) + case "invokevirtual" => jcode.emitINVOKEVIRTUAL(jowner, jname, jtype) + case "invokespecial" => jcode.emitINVOKESPECIAL(jowner, jname, jtype) + case "invokestatic" => jcode.emitINVOKESTATIC(jowner, jname, jtype) + } + } + def initModule() { + // we initialize the MODULE$ field immediately after the super ctor + if (isStaticModule(siteSymbol) && !isModuleInitialized && + jmethod.getName() == JMethod.INSTANCE_CONSTRUCTOR_NAME && + jname == JMethod.INSTANCE_CONSTRUCTOR_NAME) { + isModuleInitialized = true + jcode.emitALOAD_0() + jcode.emitPUTSTATIC(jclass.getName(), + nme.MODULE_INSTANCE_FIELD.toString, + jclass.getType()) + } + } + + style match { + case Static(true) => emit("invokespecial") + case Static(false) => emit("invokestatic") + case Dynamic if isInterfaceCall(receiver) => emit("invokeinterface") + case Dynamic => emit("invokevirtual") + case SuperCall(_) => emit("invokespecial") ; initModule() + } + } def genBlock(b: BasicBlock) { labels(b).anchorToNext() @@ -1276,43 +1307,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with jcode.emitINVOKEVIRTUAL(target, "clone", arrayCloneType) case call @ CALL_METHOD(method, style) => - val owner: String = javaName(method.owner) - // reference the type of the receiver instead of the method owner (if not an interface!) - val dynamicOwner = - if (needsInterfaceCall(call.hostClass)) owner - else javaName(call.hostClass) - val jname = javaName(method) - val jtype = javaType(method).asInstanceOf[JMethodType] - - style match { - case InvokeDynamic => - jcode.emitINVOKEINTERFACE("java.dyn.Dynamic", jname, jtype) - - case Dynamic => - if (needsInterfaceCall(method.owner)) - jcode.emitINVOKEINTERFACE(owner, jname, jtype) - else - jcode.emitINVOKEVIRTUAL(dynamicOwner, jname, jtype) - - case Static(instance) => - if (instance) - jcode.emitINVOKESPECIAL(owner, jname, jtype) - else - jcode.emitINVOKESTATIC(owner, jname, jtype) - - case SuperCall(_) => - jcode.emitINVOKESPECIAL(owner, jname, jtype) - // we initialize the MODULE$ field immediately after the super ctor - if (isStaticModule(clasz.symbol) && !isModuleInitialized && - jmethod.getName() == JMethod.INSTANCE_CONSTRUCTOR_NAME && - jname == JMethod.INSTANCE_CONSTRUCTOR_NAME) { - isModuleInitialized = true - jcode.emitALOAD_0() - jcode.emitPUTSTATIC(jclass.getName(), - nme.MODULE_INSTANCE_FIELD.toString, - jclass.getType()) - } - } + genCallMethod(call) case BOX(kind) => val boxedType = definitions.boxedClass(kind.toType.typeSymbol) @@ -1839,20 +1834,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with ////////////////////// Utilities //////////////////////// - /** Calls to methods in 'sym' need invokeinterface? */ - def needsInterfaceCall(sym: Symbol): Boolean = { - debuglog("checking for interface call: " + sym.fullName) - // the following call to 'info' may cause certain symbols to fail loading - // because we're too late in the compilation chain (aliases to overloaded - // symbols will not be properly resolved, see scala.Range, method - // `super$++` that fails in UnPickler at LazyTypeRefAndAlias.complete - if (sym.isTrait) sym.info // needed so that the type is up to date - // (erasure may add lateINTERFACE to traits) - - sym.isInterface || - (sym.isJavaDefined && sym.isNonBottomSubClass(ClassfileAnnotationClass)) - } - /** Merge adjacent ranges. */ private def mergeEntries(ranges: List[(Int, Int)]): List[(Int, Int)] = (ranges.foldLeft(Nil: List[(Int, Int)]) { (collapsed: List[(Int, Int)], p: (Int, Int)) => (collapsed, p) match { diff --git a/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala b/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala index 73ab64162..529aa4939 100644 --- a/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala +++ b/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala @@ -15,7 +15,7 @@ trait CompletionOutput { val global: Global import global._ - import definitions.{ NothingClass, AnyClass, isTupleTypeOrSubtype, isFunctionType, isRepeatedParamType } + import definitions.{ isTupleTypeOrSubtype, isFunctionType, isRepeatedParamType } /** Reducing fully qualified noise for some common packages. */ diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index faedb21b6..bf137542d 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -25,7 +25,7 @@ trait ParallelMatching extends ast.TreeDSL import global.{ typer => _, _ } import definitions.{ - AnyRefClass, NothingClass, IntClass, BooleanClass, SomeClass, OptionClass, + AnyRefClass, IntClass, BooleanClass, SomeClass, OptionClass, getProductArgs, productProj, Object_eq, Any_asInstanceOf } import CODE._ diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala index c95c15ab2..cf97949d8 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala @@ -131,7 +131,7 @@ trait SymbolTrackers { else " (" + Flags.flagsToString(masked) + ")" } def symString(sym: Symbol) = ( - if (settings.debug.value && sym.hasRawInfo && sym.rawInfo.isComplete) { + if (settings.debug.value && sym.hasCompleteInfo) { val s = sym.defString take 240 if (s.length == 240) s + "..." else s } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 93413cde5..0d20101f9 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -1257,7 +1257,7 @@ abstract class ClassfileParser { protected def getScope(flags: Int): Scope = if (isStatic(flags)) staticDefs else instanceDefs - private def setPrivateWithin(sym: Symbol, jflags: Int) { + private def setPrivateWithin(sym: Symbol, jflags: Int) { if ((jflags & (JAVA_ACC_PRIVATE | JAVA_ACC_PROTECTED | JAVA_ACC_PUBLIC)) == 0) // See ticket #1687 for an example of when topLevelClass is NoSymbol: it // apparently occurs when processing v45.3 bytecode. diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index cc72284a0..cc4914ece 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1033,8 +1033,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { && qual.isTerm && ((qual.symbol eq null) || !qual.symbol.isTerm || qual.symbol.isValue) && !qtpe.isError - && qtpe.typeSymbol != NullClass - && qtpe.typeSymbol != NothingClass + && !qtpe.typeSymbol.isBottomClass && qtpe != WildcardType && !qual.isInstanceOf[ApplyImplicitView] // don't chain views && context.implicitsEnabled @@ -2190,10 +2189,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { * in an argument closure overlaps with an uninstantiated formal? */ def needsInstantiation(tparams: List[Symbol], formals: List[Type], args: List[Tree]) = { - def isLowerBounded(tparam: Symbol) = { - val losym = tparam.info.bounds.lo.typeSymbol - losym != NothingClass && losym != NullClass - } + def isLowerBounded(tparam: Symbol) = !tparam.info.bounds.lo.typeSymbol.isBottomClass + (formals, args).zipped exists { case (formal, Function(vparams, _)) => (vparams exists (_.tpt.isEmpty)) && diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java b/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java index 212058a66..b66bbd8bc 100644 --- a/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java +++ b/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java @@ -48,7 +48,6 @@ public class JAttributeFactory { Constructor defaultConstructor) { this.context = context; this.defaultConstructor = defaultConstructor; - registerClass("BootstrapInvokeDynamic", JBootstrapInvokeDynamic.class); registerClass("Code", JCodeAttribute.class); registerClass("ConstantValue", JConstantValueAttribute.class); registerClass("EnclosingMethod", JEnclosingMethodAttribute.class); diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JBootstrapInvokeDynamic.java b/src/fjbg/ch/epfl/lamp/fjbg/JBootstrapInvokeDynamic.java deleted file mode 100644 index b54cae15a..000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JBootstrapInvokeDynamic.java +++ /dev/null @@ -1,69 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2011 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Iterator; - -/** - * BootstrapInvokeDynamic entry, as described by JSR 292 (invoke dynamic) - * - * @author Iulian Dragos - * @version 1.0 - * - */ -public class JBootstrapInvokeDynamic extends JAttribute { - /** Constant pool of the current classfile. */ - private JConstantPool pool; - - protected final int classIdx; - - public JBootstrapInvokeDynamic(FJBGContext context, - JClass clazz, - String className) { - super(context, clazz); - this.pool = clazz.pool; - - this.classIdx = pool.addClass(className); - } - - public JBootstrapInvokeDynamic(FJBGContext context, - JClass clazz, - Object owner, - String name, - int size, - DataInputStream stream) - throws IOException { - super(context, clazz, name); - - this.classIdx = stream.readShort(); - - assert name.equals(getName()); - } - - public String getName() { return "BootstrapInvokeDynamic"; } - - // Follows javap output format for BootstrapInvokeDynamic attribute. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(" BootstrapInvokeDynamic:"); - buf.append("\n #"); - buf.append(classIdx); - buf.append("; // class "); - buf.append(pool.lookupClass(classIdx)); - buf.append("\n"); - return buf.toString(); - } - - protected int getSize() { - return 2; // Short.SIZE - } - - protected void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(classIdx); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JClass.java b/src/fjbg/ch/epfl/lamp/fjbg/JClass.java index b7687ba3c..518af7bb1 100644 --- a/src/fjbg/ch/epfl/lamp/fjbg/JClass.java +++ b/src/fjbg/ch/epfl/lamp/fjbg/JClass.java @@ -26,8 +26,6 @@ public class JClass extends JMember { protected final String sourceFileName; protected final JConstantPool pool; - protected JBootstrapInvokeDynamic bootstrapClassAttr = null; - public final static String[] NO_INTERFACES = new String[0]; protected final LinkedList/**/ methods = new LinkedList(); @@ -306,12 +304,6 @@ public class JClass extends JMember { bStream.close(); fStream.close(); } - - public void setBootstrapClass(String bootstrapClass) { - assert bootstrapClassAttr == null; - bootstrapClassAttr = new JBootstrapInvokeDynamic(context, this, bootstrapClass); - addAttribute(bootstrapClassAttr); - } /** * Writes the contents of the class to a data stream. diff --git a/src/library/scala/runtime/DynamicDispatch.java-notyet b/src/library/scala/runtime/DynamicDispatch.java-notyet deleted file mode 100644 index 744ee7926..000000000 --- a/src/library/scala/runtime/DynamicDispatch.java-notyet +++ /dev/null @@ -1,42 +0,0 @@ -package scala.runtime; - -import java.dyn.CallSite; -import java.dyn.MethodHandle; - -/** - * This class resolves calls through refinement types. The - * bootstrap method is called when an invokedynamic is found - * by the Java VM. - * - * Note: Requires Java 7 with invoke dynamic support (see JSR 292) - * - * @author Iulian Dragos - * @see JSR292 - */ -public class DynamicDispatch { - - /** - * Resolve an invoke dynamic in Scala code. invokedynamic calls appear - * when a method defined by a refinement type is called. It is resolved - * by looking up a method with the same name and types in the receiver - * object. It is guaranteed by the type checker that such a method - * exists. - * - * The current implementation is not correct, a call site being - * always bootstrapped to a method handle. A bound call site should be - * guarded by a test on the receiver type. Such code should either - * be generated by the compiler, or by this bootstrap method using - * one of the code combinators provided in java.dyn.*. - * - * ATM, they are not yet available in the JVM. - */ - public static Object bootstrapInvokeDynamic(CallSite cs, Object... args) { - println(cs); - - MethodHandle mh = MethodHandles.findVirtual(cs.callerClass(), - cs.name(), - cs.type()); - cs.setTarget(mh); - return mh(args); - } -} diff --git a/test/files/run/t1430.check b/test/files/run/t1430.check new file mode 100644 index 000000000..a68818270 --- /dev/null +++ b/test/files/run/t1430.check @@ -0,0 +1 @@ +Baz diff --git a/test/files/run/t1430/Bar_1.java b/test/files/run/t1430/Bar_1.java new file mode 100644 index 000000000..4db2eafcb --- /dev/null +++ b/test/files/run/t1430/Bar_1.java @@ -0,0 +1,8 @@ +package j; + +interface Foo { + public void foo(); +} +public interface Bar_1 extends Foo { + public void bar(); +} diff --git a/test/files/run/t1430/Test_2.scala b/test/files/run/t1430/Test_2.scala new file mode 100644 index 000000000..7af65de5c --- /dev/null +++ b/test/files/run/t1430/Test_2.scala @@ -0,0 +1,16 @@ +package s { + object Boop extends j.Bar_1 { + def foo() {} + def bar() {} + } + class Baz(x: j.Bar_1) { + x.foo + override def toString = "Baz" + } +} + +object Test { + def main(args: Array[String]): Unit = { + println(new s.Baz(s.Boop)) + } +}