66
77package org .mozilla .javascript ;
88
9+ import static org .mozilla .javascript .ClassDescriptor .Destination .CTOR ;
10+ import static org .mozilla .javascript .Symbol .Kind .REGULAR ;
11+
912import java .io .Serial ;
1013
1114/**
1417 *
1518 * @author Norris Boyd
1619 */
17- public final class NativeGenerator extends IdScriptableObject {
20+ public final class NativeGenerator extends ScriptableObject {
1821 @ Serial private static final long serialVersionUID = -1383456283657974338L ;
1922
20- private static final Object GENERATOR_TAG = "Generator" ;
21-
22- static NativeGenerator init (TopLevel scope , boolean sealed ) {
23- // Generator
24- // Can't use "NativeGenerator().exportAsJSClass" since we don't want
25- // to define "Generator" as a constructor in the top-level scope.
26-
27- NativeGenerator prototype = new NativeGenerator ();
28- if (scope != null ) {
29- prototype .setParentScope (scope );
30- prototype .setPrototype (getObjectPrototype (scope ));
31- }
32- prototype .activatePrototypeMap (MAX_PROTOTYPE_ID );
33- if (sealed ) {
34- prototype .sealObject ();
35- }
36-
37- // Need to access Generator prototype when constructing
38- // Generator instances, but don't have a generator constructor
39- // to use to find the prototype. Use the "associateValue"
40- // approach instead.
41- if (scope != null ) {
42- scope .associateValue (GENERATOR_TAG , prototype );
43- }
23+ private static final SymbolKey GENERATOR_TAG = new SymbolKey ("GeneratorPrototype" , REGULAR );
24+ private static final ClassDescriptor DESCRIPTOR ;
25+
26+ static {
27+ DESCRIPTOR =
28+ new ClassDescriptor .Builder (GENERATOR_TAG )
29+ .withMethod (CTOR , "close" , 1 , NativeGenerator ::js_close )
30+ .withMethod (CTOR , "next" , 1 , NativeGenerator ::js_next )
31+ .withMethod (CTOR , "send" , 0 , NativeGenerator ::js_send )
32+ .withMethod (CTOR , "throw" , 0 , NativeGenerator ::js_throw )
33+ .withMethod (CTOR , "__iterator__" , 1 , NativeGenerator ::js_iterator )
34+ .build ();
35+ }
4436
37+ static NativeGenerator init (Context cx , TopLevel scope , boolean sealed ) {
38+ var prototype = new NativeGenerator ();
39+ DESCRIPTOR .populateGlobal (cx , scope , prototype , sealed );
40+ scope .associateValue (GENERATOR_TAG , prototype );
4541 return prototype ;
4642 }
4743
@@ -68,78 +64,49 @@ public String getClassName() {
6864 return "Generator" ;
6965 }
7066
71- @ Override
72- protected void initPrototypeId (int id ) {
73- String s ;
74- int arity ;
75- switch (id ) {
76- case Id_close :
77- arity = 1 ;
78- s = "close" ;
79- break ;
80- case Id_next :
81- arity = 1 ;
82- s = "next" ;
83- break ;
84- case Id_send :
85- arity = 0 ;
86- s = "send" ;
87- break ;
88- case Id_throw :
89- arity = 0 ;
90- s = "throw" ;
91- break ;
92- case Id___iterator__ :
93- arity = 1 ;
94- s = "__iterator__" ;
95- break ;
96- default :
97- throw new IllegalArgumentException (String .valueOf (id ));
98- }
99- initPrototypeMethod (GENERATOR_TAG , id , s , arity );
67+ private static Object js_close (
68+ Context cx , JSFunction f , Object nt , VarScope s , Object thisObj , Object [] args ) {
69+ // need to run any pending finally clauses
70+ var generator = realThis (thisObj );
71+ return generator .resume (cx , s , GENERATOR_CLOSE , new GeneratorClosedException ());
10072 }
10173
102- @ Override
103- public Object execIdCall (
104- IdFunctionObject f , Context cx , VarScope scope , Scriptable thisObj , Object [] args ) {
105- if (!f .hasTag (GENERATOR_TAG )) {
106- return super .execIdCall (f , cx , scope , thisObj , args );
107- }
108- int id = f .methodId ();
109-
110- NativeGenerator generator = ensureType (thisObj , NativeGenerator .class , f );
111-
112- switch (id ) {
113- case Id_close :
114- // need to run any pending finally clauses
115- return generator .resume (cx , scope , GENERATOR_CLOSE , new GeneratorClosedException ());
116-
117- case Id_next :
118- // arguments to next() are ignored
119- generator .firstTime = false ;
120- return generator .resume (cx , scope , GENERATOR_SEND , Undefined .instance );
121-
122- case Id_send :
123- {
124- Object arg = args .length > 0 ? args [0 ] : Undefined .instance ;
125- if (generator .firstTime && !arg .equals (Undefined .instance )) {
126- throw ScriptRuntime .typeErrorById ("msg.send.newborn" );
127- }
128- return generator .resume (cx , scope , GENERATOR_SEND , arg );
129- }
130-
131- case Id_throw :
132- return generator .resume (
133- cx , scope , GENERATOR_THROW , args .length > 0 ? args [0 ] : Undefined .instance );
134-
135- case Id___iterator__ :
136- return thisObj ;
137-
138- default :
139- throw new IllegalArgumentException (String .valueOf (id ));
74+ private static Object js_next (
75+ Context cx , JSFunction f , Object nt , VarScope s , Object thisObj , Object [] args ) {
76+ // arguments to next() are ignored
77+ var generator = realThis (thisObj );
78+ generator .firstTime = false ;
79+ return generator .resume (cx , s , GENERATOR_SEND , Undefined .instance );
80+ }
81+
82+ private static Object js_send (
83+ Context cx , JSFunction f , Object nt , VarScope s , Object thisObj , Object [] args ) {
84+ {
85+ var generator = realThis (thisObj );
86+ Object arg = args .length > 0 ? args [0 ] : Undefined .instance ;
87+ if (generator .firstTime && !arg .equals (Undefined .instance )) {
88+ throw ScriptRuntime .typeErrorById ("msg.send.newborn" );
89+ }
90+ return generator .resume (cx , s , GENERATOR_SEND , arg );
14091 }
14192 }
14293
94+ private static Object js_throw (
95+ Context cx , JSFunction f , Object nt , VarScope s , Object thisObj , Object [] args ) {
96+ var generator = realThis (thisObj );
97+ return generator .resume (
98+ cx , s , GENERATOR_THROW , args .length > 0 ? args [0 ] : Undefined .instance );
99+ }
100+
101+ private static Object js_iterator (
102+ Context cx , JSFunction f , Object nt , VarScope s , Object thisObj , Object [] args ) {
103+ return thisObj ;
104+ }
105+
106+ private static NativeGenerator realThis (Object thisObj ) {
107+ return LambdaConstructor .convertThisObject (thisObj , NativeGenerator .class );
108+ }
109+
143110 private Object resume (Context cx , VarScope scope , int operation , Object value ) {
144111 if (savedState == null ) {
145112 if (operation == GENERATOR_CLOSE ) return Undefined .instance ;
@@ -178,39 +145,6 @@ private Object resume(Context cx, VarScope scope, int operation, Object value) {
178145 }
179146 }
180147
181- @ Override
182- protected int findPrototypeId (String s ) {
183- int id ;
184- switch (s ) {
185- case "close" :
186- id = Id_close ;
187- break ;
188- case "next" :
189- id = Id_next ;
190- break ;
191- case "send" :
192- id = Id_send ;
193- break ;
194- case "throw" :
195- id = Id_throw ;
196- break ;
197- case "__iterator__" :
198- id = Id___iterator__ ;
199- break ;
200- default :
201- id = 0 ;
202- break ;
203- }
204- return id ;
205- }
206-
207- private static final int Id_close = 1 ,
208- Id_next = 2 ,
209- Id_send = 3 ,
210- Id_throw = 4 ,
211- Id___iterator__ = 5 ,
212- MAX_PROTOTYPE_ID = 5 ;
213-
214148 private JSFunction function ;
215149 private Object savedState ;
216150 private String lineSource ;
0 commit comments