static NativeGenerator init(ScriptableObject scope, boolean sealed) { // Generator // Can't use "NativeGenerator().exportAsJSClass" since we don't want // to define "Generator" as a constructor in the top-level scope. NativeGenerator prototype = new NativeGenerator(); if (scope != null) { prototype.setParentScope(scope); prototype.setPrototype(getObjectPrototype(scope)); } prototype.activatePrototypeMap(MAX_PROTOTYPE_ID); if (sealed) { prototype.sealObject(); } // Need to access Generator prototype when constructing // Generator instances, but don't have a generator constructor // to use to find the prototype. Use the "associateValue" // approach instead. if (scope != null) { scope.associateValue(GENERATOR_TAG, prototype); } return prototype; }
static void init(ScriptableObject scope, boolean sealed) { // Iterator NativeIterator iterator = new NativeIterator(); iterator.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed); // Generator NativeGenerator.init(scope, sealed); // StopIteration NativeObject obj = new StopIteration(); obj.setPrototype(getObjectPrototype(scope)); obj.setParentScope(scope); if (sealed) { obj.sealObject(); } ScriptableObject.defineProperty(scope, STOP_ITERATION, obj, ScriptableObject.DONTENUM); // Use "associateValue" so that generators can continue to // throw StopIteration even if the property of the global // scope is replaced or deleted. scope.associateValue(ITERATOR_TAG, obj); }
@Override public Object execIdCall( IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!f.hasTag(GENERATOR_TAG)) { return super.execIdCall(f, cx, scope, thisObj, args); } int id = f.methodId(); if (!(thisObj instanceof NativeGenerator)) throw incompatibleCallError(f); NativeGenerator generator = (NativeGenerator) thisObj; switch (id) { case Id_close: // need to run any pending finally clauses return generator.resume(cx, scope, GENERATOR_CLOSE, new GeneratorClosedException()); case Id_next: // arguments to next() are ignored generator.firstTime = false; return generator.resume(cx, scope, GENERATOR_SEND, Undefined.instance); case Id_send: { Object arg = args.length > 0 ? args[0] : Undefined.instance; if (generator.firstTime && !arg.equals(Undefined.instance)) { throw ScriptRuntime.typeError0("msg.send.newborn"); } return generator.resume(cx, scope, GENERATOR_SEND, arg); } case Id_throw: return generator.resume( cx, scope, GENERATOR_THROW, args.length > 0 ? args[0] : Undefined.instance); case Id___iterator__: return thisObj; default: throw new IllegalArgumentException(String.valueOf(id)); } }