Skip to content

Commit 9f01f4f

Browse files
aardvark179gbrail
authored andcommitted
Convert NativeGenerator to descriptor.
1 parent 6e1adbe commit 9f01f4f

2 files changed

Lines changed: 60 additions & 126 deletions

File tree

rhino/src/main/java/org/mozilla/javascript/NativeGenerator.java

Lines changed: 59 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
package org.mozilla.javascript;
88

9+
import static org.mozilla.javascript.ClassDescriptor.Destination.CTOR;
10+
import static org.mozilla.javascript.Symbol.Kind.REGULAR;
11+
912
import java.io.Serial;
1013

1114
/**
@@ -14,34 +17,27 @@
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;

rhino/src/main/java/org/mozilla/javascript/NativeIterator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static void init(Context cx, TopLevel scope, boolean sealed) {
5353
if (cx.getLanguageVersion() >= Context.VERSION_ES6) {
5454
ES6Generator.init(scope, sealed);
5555
} else {
56-
NativeGenerator.init(scope, sealed);
56+
NativeGenerator.init(cx, scope, sealed);
5757
}
5858

5959
// StopIteration

0 commit comments

Comments
 (0)