From f0980301da172204492b74e9122838e367f724d1 Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Wed, 22 Jul 2020 23:51:09 +0200 Subject: [PATCH] avm1: Implement arguments.callee --- core/src/avm1/function.rs | 5 +- core/src/avm1/globals/function.rs | 2 + core/src/avm1/object/script_object.rs | 85 ++++++++++++---------- core/tests/swfs/avm1/arguments/output.txt | 24 ++++++ core/tests/swfs/avm1/arguments/test.fla | Bin 4862 -> 4881 bytes core/tests/swfs/avm1/arguments/test.swf | Bin 866 -> 889 bytes 6 files changed, 78 insertions(+), 38 deletions(-) diff --git a/core/src/avm1/function.rs b/core/src/avm1/function.rs index afac8833d..5cc6be7f1 100644 --- a/core/src/avm1/function.rs +++ b/core/src/avm1/function.rs @@ -240,6 +240,7 @@ impl<'gc> Executable<'gc> { base_proto: Option>, args: &[Value<'gc>], reason: ExecutionReason, + callee: Object<'gc>, ) -> Result, Error<'gc>> { match self { Executable::Native(nf) => nf(activation, ac, this, args), @@ -250,7 +251,7 @@ impl<'gc> Executable<'gc> { ); let arguments = ScriptObject::array(ac.gc_context, Some(activation.avm.prototypes().array)); - arguments.define_value(ac.gc_context, "callee", this.into(), DontEnum.into()); + arguments.define_value(ac.gc_context, "callee", callee.into(), DontEnum.into()); if !af.suppress_arguments { for i in 0..args.len() { @@ -494,6 +495,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> { ) -> Result<(), Error<'gc>> { self.base.set(name, value, activation, context) } + fn call( &self, name: &str, @@ -512,6 +514,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> { base_proto, args, ExecutionReason::FunctionCall, + (*self).into(), ) } else { Ok(Value::Undefined) diff --git a/core/src/avm1/globals/function.rs b/core/src/avm1/globals/function.rs index 949a24e4e..af53c7df1 100644 --- a/core/src/avm1/globals/function.rs +++ b/core/src/avm1/globals/function.rs @@ -44,6 +44,7 @@ pub fn call<'gc>( None, args, ExecutionReason::FunctionCall, + func, ), _ => Ok(Value::Undefined), } @@ -85,6 +86,7 @@ pub fn apply<'gc>( None, &child_args, ExecutionReason::FunctionCall, + func, ), _ => Ok(Value::Undefined), } diff --git a/core/src/avm1/object/script_object.rs b/core/src/avm1/object/script_object.rs index d65b257bd..837abd616 100644 --- a/core/src/avm1/object/script_object.rs +++ b/core/src/avm1/object/script_object.rs @@ -59,6 +59,7 @@ impl<'gc> Watcher<'gc> { base_proto, &args, ExecutionReason::Special, + self.callback, ) } else { Ok(Value::Undefined) @@ -292,19 +293,21 @@ impl<'gc> ScriptObject<'gc> { if let Some(this_proto) = proto { worked = true; - if let Some(rval) = this_proto - .call_setter(name, value.clone(), activation, context) - .and_then(|o| o.as_executable()) + if let Some(rval) = + this_proto.call_setter(name, value.clone(), activation, context) { - let _ = rval.exec( - "[Setter]", - activation, - context, - this, - Some(this_proto), - &[value.clone()], - ExecutionReason::Special, - ); + if let Some(exec) = rval.as_executable() { + let _ = exec.exec( + "[Setter]", + activation, + context, + this, + Some(this_proto), + &[value.clone()], + ExecutionReason::Special, + rval, + ); + } } } } @@ -357,16 +360,19 @@ impl<'gc> ScriptObject<'gc> { } }; - if let Some(rval) = rval.and_then(|o| o.as_executable()) { - let _ = rval.exec( - "[Setter]", - activation, - context, - this, - base_proto, - &[value], - ExecutionReason::Special, - ); + if let Some(rval) = rval { + if let Some(exec) = rval.as_executable() { + let _ = exec.exec( + "[Setter]", + activation, + context, + this, + base_proto, + &[value], + ExecutionReason::Special, + rval, + ); + } } return return_value; @@ -397,7 +403,7 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> { return Ok(self.proto().map_or(Value::Undefined, Value::Object)); } - let mut exec = None; + let mut getter = None; if let Some(value) = self .0 @@ -406,24 +412,29 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> { .get(name, activation.is_case_sensitive()) { match value { - Property::Virtual { get, .. } => exec = Some(get.to_owned()), + Property::Virtual { get, .. } => getter = Some(get.to_owned()), Property::Stored { value, .. } => return Ok(value.to_owned()), } } - if let Some(get) = exec.and_then(|o| o.as_executable()) { - // Errors, even fatal ones, are completely and silently ignored here. - match get.exec( - "[Getter]", - activation, - context, - this, - Some((*self).into()), - &[], - ExecutionReason::Special, - ) { - Ok(value) => Ok(value), - Err(_) => Ok(Value::Undefined), + if let Some(getter) = getter { + if let Some(exec) = getter.as_executable() { + // Errors, even fatal ones, are completely and silently ignored here. + match exec.exec( + "[Getter]", + activation, + context, + this, + Some((*self).into()), + &[], + ExecutionReason::Special, + getter, + ) { + Ok(value) => Ok(value), + Err(_) => Ok(Value::Undefined), + } + } else { + Ok(Value::Undefined) } } else { Ok(Value::Undefined) diff --git a/core/tests/swfs/avm1/arguments/output.txt b/core/tests/swfs/avm1/arguments/output.txt index ad774a615..6b7fcd8c5 100644 --- a/core/tests/swfs/avm1/arguments/output.txt +++ b/core/tests/swfs/avm1/arguments/output.txt @@ -11,6 +11,12 @@ true // arguments.__proto__ === Array.prototype true +// arguments.callee +[type Function] + +// arguments.callee === dump +true + // dump("a") @@ -26,6 +32,12 @@ true // arguments.__proto__ === Array.prototype true +// arguments.callee +[type Function] + +// arguments.callee === dump +true + // arguments[0] a @@ -44,6 +56,12 @@ true // arguments.__proto__ === Array.prototype true +// arguments.callee +[type Function] + +// arguments.callee === dump +true + // arguments[1] b @@ -66,6 +84,12 @@ true // arguments.__proto__ === Array.prototype true +// arguments.callee +[type Function] + +// arguments.callee === dump +true + // arguments[3] d diff --git a/core/tests/swfs/avm1/arguments/test.fla b/core/tests/swfs/avm1/arguments/test.fla index b5221ea78cda5eaa7f7dc4e63b413de406d14003..dea00434062b6b014f1b242c24b16ea25472ae98 100644 GIT binary patch delta 1833 zcmV+^2iExhC6OkOiht|_m#Jj~003|d000jF002Z!O+;^Fb!}yCbS`*pY^_&aZ`v>v zeV^3-;CU}p?P3Dqqis?NwL+`Zu1HkdBw8VpIN&XbBgZMQssDYB^U=@{3e$Kp_nvd^ zxptfj=JoyEHM3)%1OlvlFNn@p5w+k#i0~Yt<#MSl+Zy9@)PHI=b@b!zc5E+*k3Z8O z5;(94Oj!jZh&1f58PRO!qm}C=ygq`!jyab#9;i<|8W0QWlIeQi2#+WWEZEXo62u7> zjNb$VG-F=u0C${>gY@MVC%g@@wqR2)CfZ1Y{+~HVMd$Bm1B(O)@QIWPKkB z$&5yFdCOR6K^J=wspLj@PNKTxkYk?=Z1p|ITpoP@$;TAgwncd)4a>vJHxvYtF56BV z0v&GPQn0KcJFF%OsoMmQ>7;Afw#_^y8~tPqheKmnoPVPQ1&?JDG#V3+*n&7&q((n2 z;wC-TS=cnAwgbrXA}b3vA^1hscg&H_&U&r>&MGCHY&&gEL$MzvJ~82m}K1jjaMK!gD1b9IFxczjXL74gk5RIpkR%_G5FEb6qf^g)s!zpu;% z1J3cfPJg@tJk0rY8geGsbP6oXN(D3(5$llDHnfvM3GJad@6Q#i>rwQJyr9t;Jh4tcuDLO_kXqQecQcF&Pl^z=&c*c^0Z{S5Z!^f z$m(qhHd1c7yeP8p?YhEyg!mDb$PiaJ@AFT=Bb>dJIR$XGx7Nm{l{HU6EZ@hjoHkAp zaq=n~guL1Y7&<$uKRsQV=#ZDRi4K3Un{rI4LqqS6AC%9Zox=?6oMuWyP0=l*7;Txw zihqz#^J4I$%H%gkoCbpMF%g0W^VfdNFrIldT703A{0+6<6d$Fz8$o=K;l}iLGEQ|l zT(d}0UH<&(oORkQquXgiw5Lel=x!J3bkFt|Y3ns29er<+-kGso#OU|;7wOjQiE)UN zUY&^1`yV0)I59dkBCY-Rq@(w1MD)^gVt=B_L#UqX{4d7kUrHU;`>yVxV`73PGW68^fMYO1DK5Rot6cMd+s{(rFO zUCc8YJTM7H>^@3u?Z>z88i+z$``q@CpSf%jT|MRO?&;$&czOuBp?2XkdUG;QvV=(r z=1H6iGPgAv@)0BIa}kCbC{yHvt@Vos;ER6)T%I$~Hkx{XFb0-o;8xqR@Oxk)Y(k`7 zmX2GbZ4t8rRzq_d>e|c0F}d|FSATTs&ekSUW(307Y-Y@w2G8#y?smHcjA`mBLl=uw z(z%|Bvn9wH$73SMqfACT1;srb@u{>mtpT>iYFo)0;Xo#o6gV=5-#Cg)=&gyN(zaPKUjgV8jKL(n?MJ-AzW2$Xs1?SGiaL^|r| zCLUr;njM0ycgQ3NZGkK^cQAZqOGqWHqL@R|BueuZ-bSh9?&9z;8ZUkc0N=g!Vs8YzmqdZ+HhJTBU!CNNyG!NL|Q7Le?yDoj7T&F_PG+@`BqXI@0g~WBw zI|x};({n!z`WW{;e16&Ow@uXPG&}8n>0`BY57y(sv=Ds-8y2vZYheY0vD-fdyH&ae z`zeo9Kcewpz#o9vqq&NN+H(u1qI~J@9s631t{=ov>2^kQ!3yPVZGSDjwpUQplnxRa zlX=rOR?ZWv9v-k!W2?P)jqG*#85GM%(02Tli01f~t zvqTU)0SW8_m#Jj~003~4i4im#mgR+9$^rlYI}!i@6#xJL0000000000000h?*bzbk z3kQ=N57AXM&6aW+e00;m823_?~5D=nh8~^|S8~^|S6951J0000000000 X000$}oDx6*p_APb8wTJI00000?7>Pi delta 1813 zcmV+w2kQ8dCjKRmihr=>Y*1ta004jt000jF002Z!O+;^Fb!}yCbS`*pY^_&oPunmQ z{f@+c@VqZYbTMhuQXoO9K-G|7R4Upg0YYx#wBC|9ava)j;=j*v9;8jv2O6J@?>Xn5 z>(@=q>-)QFX2(7W1ep6?5S`B>YQd=x;WF|zs3HTa0@C-K;~j(lYrbfvJUFfB+^nw7Wbi$ z%xEZww~U1rbg>taN^FQHB&rJzIQB{3R{!Ui%fkbZ{Fx$KwkV%Tr{(753km{Bmt`jo zfex2&DOl!^6;=a<)NKODbkeab+h!h(V z_XxqUA{_(xT%4ITt{x@mxf+KB=k4&|EwNMF-+!|Ab@w>gD-DOCw`e58X32CRx&d>M zCK9e zcYpWdLjYC21k53)fgpTDgrLFXy&f}+#~zKQUuh)2sTRxP!!&jyhz~N{i2h01t1g>u zHj`wRpF^FqPP=7vJ8g(|6zLh=^&*|_+3q53y+)*??<{h9W~>)6dcEC6x;1NJ?BnFL zPQ*C@6aWGU2ml6M^-wJ9 z#$C7q006HL000#L002!zR6#9CPDU?nWprU=VRT_Gcx`O$Sj%$SFcjVM6&hvP+L8>I zpux^iL#A1{%_PjUTOo_!iC?uuF!{AE`bqtT%H|Qkg!GX`rh~?K?CX2aLFecS4}ZOj zB4hksC@>axVdB7_-+w?51`hnv_OYLNVj6yY%*E~FrxAa==iLBaxQ$*xi#UsgVxWkl zMAE{6EJ(+K>gzI$AgEH*y#xE@1Mt31eA?&M@R6QLHc$ zdA0;u;|zr4d6=m%O+b0i#_3Es5H`TpSj{WWHbjXut2vrHjZwieL`;k}$R)VWrd}?X zO7l^gM(%Rvml2awaGj?UA*JSI5%6wpV1V%~i~`U)Cq1-Zc?eVt^vAWZg?|m)F)T77 zgf=@A+wZVNG2Q}MX6|A5+LnMRRztC9lhAf+8)YYVA14jM$>O(Ao-)_+qdooq)|Y^9 zY{_PMRJk8;Bq9-uL`iK8*|jF%bdu&VQ!dN0DCDeUK@Ul=@^lih9(qc8?eDAQ@crW} zDUQ*hN~wkq>UgCbEi!>_gnvwDITynRt-#s-y7YZ|l}N=BF0KZy4wzvWP(ldCgXXYl zdmn~wI#F|$i~gNf`44uzL)A6O(Ngob>BY+p z^#6OYjPAC}x&`;z>+pWMjOt%^{bGSOZx)B<`1<2Saw0jAoJdY2Cz2D%n<8oSHvdhC zByivyUbw#iP)h>@6tfTq6A1(n-R5wUClDtI0ss{N3;-VhHnUd{JOK%?@-R5u{0000S0000J00000000000000000Iz`F%T7##S$t3j+5{b8wSk~00000 DLJv`W diff --git a/core/tests/swfs/avm1/arguments/test.swf b/core/tests/swfs/avm1/arguments/test.swf index cb1492cc1354b1c4f80c5b101b622b02b479a50a..ee457bbe15469862f0d30bf7309e8ec121698577 100644 GIT binary patch literal 889 zcmV-<1BU!VS5ps42mk6Bx8%27ZM1^Q?D1Nw{HU5b>bM0V3e03Z40&5U+u2~J?6 z4{-l4fF~ueA8Z4_+lSj50LRSrtaJMWO@=`jTfA#lFOwv)G;KT{tK)r@vJ1^PIy%yH zQ!`D4Gn9B5CU~NR@zZJxr4BZU9p*=gPeUYnJfNebS*>QalVP;54PzC%bU;*x4z&r6 zG(*)j;loK*hY_4m)}u6NwFL{E1USA#uNn179CLddpw5qVq@cmb4_tI`XdG+rD+^x4 z=2y$qOsCHZmLy3QinXvBi_yj({k0U44oiFv$68n5eE9%VzEv~Uy!zJrCKHc{eB z>ijy!Z;0ZFsE@TJ@l%(?ch>FReBi^Omb2sJoOn00-GA+-TD59wqdkw4+{G|D?VDWJSS;2`nE!^jCyWl$Q;0B&iAbth&7%@A zrTJR^nwUEOwXqMRxtseb8~Q++yV1{y=~@f4IGANl>tAUt`v|rWbfl}Rt8dG9$^gH6 zrLRHL5M~#tWeh8w8j$cJxrFRi9HBfh>Y+Accnb5nBJcMjMibiaqh_-?r>QBD@Dqf^ z6qeYE+`&OW2xPZ4qtwoejcc5$|cMxjeQKO`>iUCwo(NQ8G=^Cbe5Yw!=uB#@!TYo#QrJg-u1 zR^f_c8lvEL< PC#xj*j)VUKQ{h&_@qNM* literal 866 zcmV-o1D*UsS5pt+2LJ$goTXIHZ`(E){j4~Rx~6TqcFPVq5H4UeSR_jFVkbiE)wP-; z2WLZ;orb}nMJf?yi-IKA_G!oM)T4nN26TVS{;rgiC0lNOpz92n;`hGy9;rv#6Iky7 zJbn-GO$nSQTLAF;)2(%YqlkL;nRARL!$A<+qH0zylO(h;9*@WRxTf>y0-J}2huE;N zWod$;#nT`m6D^3JS6V1_a9Hd{ewg??K(Z!%K1!OEN@hD5h6~#u)(Pc(rn`KICnUtC zZeZynNOmV;B;nCH=Yv*Tve5B>#FyyDh^=}Q!HjILH&YVlTEFqL6 zl8KJ+M@fEKw$xoj8;+tudS2AUY`}&rNMaGMnZ`?9+vCxYBrOt#1K%am5KpxDlDof+ z$y=s*GU_9|B!2Fe#G7@ycOUq0h;w$FoH6fic6>e!89rk%A4M(`^yk@y>2~dtAWlf& zvJ1)6kk?10|jA5nH2Q0WqE+KmqTPRPAd#D{nWD4_fMc(U$5l?uphnmgioTjHp zB2Ew%U07m8`7iLRtm#PPB!AD-7jn9{B6Ua0<2ZxJTirf@QU#Q5`$4wy=FV&bHpE>3ITekEXWR1es5*N9_aOVIo6YUzuIJ<9 s>g+zKTN|ZY`cI^T`lVnfw=kYoXOBRAww990lJwOo30?~D1HAJ*{ubT0YXATM