1414 * @see org.mozilla.javascript.NativeCall
1515 * @author Norris Boyd
1616 */
17- final class Arguments extends IdScriptableObject {
17+ class Arguments extends ScriptableObject {
1818 private static final long serialVersionUID = 4275508002492040609L ;
1919
2020 private static final String CLASS_NAME = "Arguments" ;
2121
2222 // Fields to hold caller, callee and length properties,
2323 // where NOT_FOUND value tags deleted properties.
24- // In addition if callerObj == NULL_VALUE, it tags null for scripts, as
25- // initial callerObj == null means access to caller arguments available
26- // only in JS <= 1.3 scripts
27- private Object callerObj ;
24+ // In addition, the 'caller' arguments is only available in JS <= 1.3 scripts
2825 private Object calleeObj ;
2926 private Object lengthObj ;
3027
31- private int callerAttr = DONTENUM ;
32- private int calleeAttr = DONTENUM ;
33- private int lengthAttr = DONTENUM ;
34-
3528 private NativeCall activation ;
3629
3730 // Initially args holds activation.getOriginalArgs(), but any modification
3831 // of its elements triggers creation of a copy. If its element holds NOT_FOUND,
3932 // it indicates deleted index, in which case super class is queried.
4033 private Object [] args ;
4134
42- public Arguments (NativeCall activation ) {
35+ public Arguments (NativeCall activation , Context cx ) {
4336 this .activation = activation ;
4437
4538 Scriptable parent = activation .getParentScope ();
@@ -52,19 +45,13 @@ public Arguments(NativeCall activation) {
5245 JSFunction f = activation .function ;
5346 calleeObj = f ;
5447
55- int version = f .getLanguageVersion ();
56- if (version <= Context .VERSION_1_3 && version != Context .VERSION_DEFAULT ) {
57- callerObj = null ;
58- } else {
59- callerObj = NOT_FOUND ;
60- }
61-
6248 defineProperty (
6349 SymbolKey .ITERATOR ,
6450 TopLevel .getBuiltinPrototype (
6551 ScriptableObject .getTopLevelScope (parent ), TopLevel .Builtins .Array )
6652 .get ("values" , parent ),
6753 ScriptableObject .DONTENUM );
54+ defineProperty ("length" , lengthObj , ScriptableObject .DONTENUM );
6855
6956 if (activation .isStrict ) {
7057 // ECMAScript2015
@@ -75,14 +62,28 @@ public Arguments(NativeCall activation) {
7562 // 9. Perform DefinePropertyOrThrow(obj, "callee", PropertyDescriptor {[[Get]]:
7663 // %ThrowTypeError%,
7764 // [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}).
78- setGetterOrSetter ("caller" , 0 , new ThrowTypeError (parent , "caller" ), true );
79- setGetterOrSetter ("caller" , 0 , new ThrowTypeError (parent , "caller" ), false );
80- setGetterOrSetter ("callee" , 0 , new ThrowTypeError (parent , "callee" ), true );
81- setGetterOrSetter ("callee" , 0 , new ThrowTypeError (parent , "callee" ), false );
82- setAttributes ("caller" , DONTENUM | PERMANENT );
83- setAttributes ("callee" , DONTENUM | PERMANENT );
84- callerObj = null ;
65+ BaseFunction typeErrorThrower = ScriptRuntime .typeErrorThrower (cx );
66+ int version = cx .getLanguageVersion ();
67+ if (version <= Context .VERSION_1_8 ) {
68+ setGetterOrSetter ("caller" , 0 , typeErrorThrower , true );
69+ setGetterOrSetter ("caller" , 0 , typeErrorThrower , false );
70+ setGetterOrSetter ("callee" , 0 , typeErrorThrower , true );
71+ setGetterOrSetter ("callee" , 0 , typeErrorThrower , false );
72+ setAttributes ("caller" , DONTENUM | PERMANENT );
73+ setAttributes ("callee" , DONTENUM | PERMANENT );
74+ } else {
75+ setGetterOrSetter ("callee" , 0 , typeErrorThrower , true );
76+ setGetterOrSetter ("callee" , 0 , typeErrorThrower , false );
77+ setAttributes ("callee" , DONTENUM | PERMANENT );
78+ }
8579 calleeObj = null ;
80+ } else {
81+ defineProperty ("callee" , calleeObj , ScriptableObject .DONTENUM );
82+
83+ int version = cx .getLanguageVersion ();
84+ if (version <= Context .VERSION_1_3 && version != Context .VERSION_DEFAULT ) {
85+ defineProperty ("caller" , (Object ) null , ScriptableObject .DONTENUM );
86+ }
8687 }
8788 }
8889
@@ -196,6 +197,11 @@ public void put(String name, Scriptable start, Object value) {
196197 super .put (name , start , value );
197198 }
198199
200+ @ Override
201+ public void put (Symbol key , Scriptable start , Object value ) {
202+ super .put (key , start , value );
203+ }
204+
199205 @ Override
200206 public void delete (int index ) {
201207 if (0 <= index && index < args .length ) {
@@ -204,128 +210,6 @@ public void delete(int index) {
204210 super .delete (index );
205211 }
206212
207- private static final int Id_callee = 1 ,
208- Id_length = 2 ,
209- Id_caller = 3 ,
210- MAX_INSTANCE_ID = Id_caller ;
211-
212- @ Override
213- protected int getMaxInstanceId () {
214- return MAX_INSTANCE_ID ;
215- }
216-
217- @ Override
218- protected int findInstanceIdInfo (String s ) {
219- int id ;
220- switch (s ) {
221- case "callee" :
222- id = Id_callee ;
223- break ;
224- case "length" :
225- id = Id_length ;
226- break ;
227- case "caller" :
228- id = Id_caller ;
229- break ;
230- default :
231- id = 0 ;
232- break ;
233- }
234- Context cx = Context .getContext ();
235- if (cx .isStrictMode ()) {
236- if (id == Id_callee || id == Id_caller ) {
237- return super .findInstanceIdInfo (s );
238- }
239- }
240-
241- if (id == 0 ) return super .findInstanceIdInfo (s );
242-
243- int attr ;
244- switch (id ) {
245- case Id_callee :
246- attr = calleeAttr ;
247- break ;
248- case Id_caller :
249- attr = callerAttr ;
250- break ;
251- case Id_length :
252- attr = lengthAttr ;
253- break ;
254- default :
255- throw new IllegalStateException ();
256- }
257- return instanceIdInfo (attr , id );
258- }
259-
260- @ Override
261- protected String getInstanceIdName (int id ) {
262- switch (id ) {
263- case Id_callee :
264- return "callee" ;
265- case Id_length :
266- return "length" ;
267- case Id_caller :
268- return "caller" ;
269- }
270- return null ;
271- }
272-
273- @ Override
274- protected Object getInstanceIdValue (int id ) {
275- switch (id ) {
276- case Id_callee :
277- return calleeObj ;
278- case Id_length :
279- return lengthObj ;
280- case Id_caller :
281- {
282- Object value = callerObj ;
283- if (value == UniqueTag .NULL_VALUE ) {
284- value = null ;
285- } else if (value == null ) {
286- NativeCall caller = activation .parentActivationCall ;
287- if (caller != null ) {
288- value = caller .get ("arguments" , caller );
289- }
290- }
291- return value ;
292- }
293- }
294- return super .getInstanceIdValue (id );
295- }
296-
297- @ Override
298- protected void setInstanceIdValue (int id , Object value ) {
299- switch (id ) {
300- case Id_callee :
301- calleeObj = value ;
302- return ;
303- case Id_length :
304- lengthObj = value ;
305- return ;
306- case Id_caller :
307- callerObj = (value != null ) ? value : UniqueTag .NULL_VALUE ;
308- return ;
309- }
310- super .setInstanceIdValue (id , value );
311- }
312-
313- @ Override
314- protected void setInstanceIdAttributes (int id , int attr ) {
315- switch (id ) {
316- case Id_callee :
317- calleeAttr = attr ;
318- return ;
319- case Id_length :
320- lengthAttr = attr ;
321- return ;
322- case Id_caller :
323- callerAttr = attr ;
324- return ;
325- }
326- super .setInstanceIdAttributes (id , attr );
327- }
328-
329213 @ Override
330214 Object [] getIds (CompoundOperationMap map , boolean getNonEnumerable , boolean getSymbols ) {
331215 Object [] ids = super .getIds (map , getNonEnumerable , getSymbols );
@@ -428,28 +312,60 @@ protected boolean defineOwnProperty(
428312 return true ;
429313 }
430314
431- private static final class ThrowTypeError extends BaseFunction {
432- private static final long serialVersionUID = -744615873947395749L ;
433- private String propertyName ;
315+ static final class ReadonlyArguments extends Arguments {
316+ private boolean initialized ;
434317
435- ThrowTypeError (Scriptable scope , String propertyName ) {
436- this .propertyName = propertyName ;
437- setPrototype (ScriptableObject .getFunctionPrototype (scope ));
318+ public ReadonlyArguments (Arguments arguments , Context cx ) {
319+ super (arguments .activation , cx );
320+ initialized = true ;
321+ }
438322
439- setAttributes ("length" , DONTENUM | PERMANENT | READONLY );
440- setAttributes ("name" , DONTENUM | PERMANENT | READONLY );
323+ @ Override
324+ public void put (int index , Scriptable start , Object value ) {
325+ if (initialized ) {
326+ return ;
327+ }
328+ super .put (index , start , value );
329+ }
441330
442- setAttributes ("arity" , DONTENUM );
443- delete ("arity" );
444- setAttributes ("arguments" , DONTENUM );
445- delete ("arguments" );
331+ @ Override
332+ public void put (String name , Scriptable start , Object value ) {
333+ if (initialized ) {
334+ return ;
335+ }
336+ super .put (name , start , value );
337+ }
338+
339+ @ Override
340+ public void put (Symbol key , Scriptable start , Object value ) {
341+ if (initialized ) {
342+ return ;
343+ }
344+ super .put (key , start , value );
345+ }
346+
347+ @ Override
348+ public void delete (int index ) {
349+ if (initialized ) {
350+ return ;
351+ }
352+ super .delete (index );
353+ }
446354
447- preventExtensions ();
355+ @ Override
356+ public void delete (String name ) {
357+ if (initialized ) {
358+ return ;
359+ }
360+ super .delete (name );
448361 }
449362
450363 @ Override
451- public Object call (Context cx , Scriptable scope , Scriptable thisObj , Object [] args ) {
452- throw ScriptRuntime .typeErrorById ("msg.arguments.not.access.strict" , propertyName );
364+ public void delete (Symbol key ) {
365+ if (initialized ) {
366+ return ;
367+ }
368+ super .delete (key );
453369 }
454370 }
455371}
0 commit comments