diff --git a/ts2panda/src/base/bcGenUtil.ts b/ts2panda/src/base/bcGenUtil.ts index ebde0fb13733f9e72f786904550f42c643c57de1..03bea6d7419dc921c033a10eb72ac39e3a712571 100644 --- a/ts2panda/src/base/bcGenUtil.ts +++ b/ts2panda/src/base/bcGenUtil.ts @@ -34,6 +34,7 @@ import { EcmaDefineclasswithbuffer, EcmaDefinefuncdyn, EcmaDefinegeneratorfunc, + EcmaDefineasyncgeneratorfunc, //new add EcmaDefinegettersetterbyvalue, EcmaDefinemethod, EcmaDefinencfuncdyn, @@ -398,6 +399,10 @@ export function defineGeneratorFunc(name: string, env: VReg, paramLength: number return new EcmaDefinegeneratorfunc(name, new Imm(paramLength), env); } +export function defineAsyncGeneratorFunc(name: string, env: VReg, paramLength: number) { //new add + return new EcmaDefineasyncgeneratorfunc(name, new Imm(paramLength), env); +} + export function defineNCFunc(name: string, env: VReg, paramLength: number) { return new EcmaDefinencfuncdyn(name, new Imm(paramLength), env); } diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index 0d311fcb7a79fa3d4e937786ff3ff957066d5d81..7eafe39a45662ead276312cd240d4a1a6efed8b2 100644 --- a/ts2panda/src/compiler.ts +++ b/ts2panda/src/compiler.ts @@ -60,6 +60,7 @@ import { compileYieldExpression } from "./expression/yieldExpression"; import { AsyncFunctionBuilder } from "./function/asyncFunctionBuilder"; import { FunctionBuilder, FunctionBuilderType } from "./function/functionBuilder"; import { GeneratorFunctionBuilder } from "./function/generatorFunctionBuilder"; +import { AsyncGeneratorFunctionBuilder } from "./function/asyncGeneratorFunctionBuilder"; // new add import { hoistFunctionInBlock } from "./hoisting"; @@ -162,6 +163,7 @@ export class Compiler { if (this.rootNode.kind == ts.SyntaxKind.SourceFile) { this.compileSourceFileOrBlock(this.rootNode); } else { + console.log("----compile---1---"); this.compileFunctionLikeDeclaration(this.rootNode); this.callOpt(); } @@ -336,19 +338,22 @@ export class Compiler { let pandaGen = this.pandaGen; if (body.kind == ts.SyntaxKind.Block) { + console.log("----createFuncBuilder---6.1---"); this.pushScope(body); this.compileSourceFileOrBlock(body); this.popScope(); } else if (kind == ts.SyntaxKind.ArrowFunction) { + console.log("----createFuncBuilder---6.2---"); this.compileExpression(body); - let retValue = pandaGen.getTemp(); pandaGen.storeAccumulator(body, retValue); if (this.funcBuilder instanceof AsyncFunctionBuilder) { + console.log("----createFuncBuilder---6.3---"); this.funcBuilder.resolve(body, retValue); pandaGen.return(NodeKind.Invalid); } else { + console.log("----createFuncBuilder---6.4---"); pandaGen.loadAccumulator(body, retValue); } pandaGen.freeTemps(retValue); @@ -414,8 +419,11 @@ export class Compiler { if (decl.modifiers[i].kind == ts.SyntaxKind.AsyncKeyword) { // async generator if (decl.asteriskToken) { - throw new Error("Async generator is not supported"); + console.log("----createFuncBuilder---4.1---"); + return new AsyncGeneratorFunctionBuilder(pandaGen, this); // new add + //throw new Error("Async generator is not supported"); } else { // async + console.log("----createFuncBuilder---4.11---"); return new AsyncFunctionBuilder(pandaGen); } } @@ -423,9 +431,10 @@ export class Compiler { } if (decl.asteriskToken) { + console.log("----createFuncBuilder---4.12---"); return new GeneratorFunctionBuilder(pandaGen, this); } - + console.log("----createFuncBuilder---4.13---"); return new FunctionBuilder(); } @@ -434,6 +443,7 @@ export class Compiler { this.compileFunctionParameterDeclaration(decl); if (ts.isConstructorDeclaration(decl)) { + console.log("----compileFunctionLikeDeclaration---2---"); let classNode = decl.parent; if (jshelpers.getClassExtendsHeritageElement(classNode) && !extractCtorOfClass(classNode)) { compileDefaultConstructor(this, decl); @@ -442,15 +452,19 @@ export class Compiler { } if (decl.kind == ts.SyntaxKind.FunctionExpression) { + console.log("----compileFunctionLikeDeclaration---3---"); if (decl.name) { + console.log("----compileFunctionLikeDeclaration---4---"); let funcName = jshelpers.getTextOfIdentifierOrLiteral(decl.name); (pandaGen.getScope()!).addFuncName(funcName); } } - this.funcBuilder = this.createFuncBuilder(decl); + console.log("----compileFunctionLikeDeclaration---5---this.funcBuilder" + this.funcBuilder); this.funcBuilder.prepare(decl, this.recorder); + if (decl.body) { + console.log("----compileFunctionLikeDeclaration---5.1---this.funcBuilder" + this.funcBuilder); this.compileFunctionBody(decl.kind, decl.body); } @@ -1142,7 +1156,7 @@ export class Compiler { private compileAwaitExpression(expr: ts.AwaitExpression) { let pandaGen = this.pandaGen; - if (!(this.funcBuilder instanceof AsyncFunctionBuilder)) { + if (!(this.funcBuilder instanceof AsyncFunctionBuilder || this.funcBuilder instanceof AsyncGeneratorFunctionBuilder)) { //new add throw new DiagnosticError(expr.parent, DiagnosticCode.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules); } diff --git a/ts2panda/src/expression/yieldExpression.ts b/ts2panda/src/expression/yieldExpression.ts index 99fc5f856b924926160ff4ecc94c907f7d192ba4..8d31a9768d6e70d88b304ec25b3f511bc2f87790 100644 --- a/ts2panda/src/expression/yieldExpression.ts +++ b/ts2panda/src/expression/yieldExpression.ts @@ -17,10 +17,11 @@ import * as ts from "typescript"; import { GeneratorFunctionBuilder } from "../function/generatorFunctionBuilder"; import { DiagnosticCode, DiagnosticError } from "../diagnostic"; import { CacheList, getVregisterCache } from "../base/vregisterCache"; +import { AsyncGeneratorFunctionBuilder } from "../function/asyncGeneratorFunctionBuilder"; //new add import { Compiler } from "../compiler"; export function compileYieldExpression(compiler: Compiler, expr: ts.YieldExpression) { - if (!(compiler.getFuncBuilder() instanceof GeneratorFunctionBuilder)) { + if (!(compiler.getFuncBuilder() instanceof GeneratorFunctionBuilder || compiler.getFuncBuilder() instanceof AsyncGeneratorFunctionBuilder)) { //new add throw new DiagnosticError(expr.parent, DiagnosticCode.A_yield_expression_is_only_allowed_in_a_generator_body); } @@ -29,7 +30,7 @@ export function compileYieldExpression(compiler: Compiler, expr: ts.YieldExpress function genYieldExpr(compiler: Compiler, expr: ts.YieldExpression) { let pandaGen = compiler.getPandaGen(); - let funcBuilder = compiler.getFuncBuilder(); + let funcBuilder = compiler.getFuncBuilder(); //new add if (expr.expression) { let retValue = pandaGen.getTemp(); @@ -45,7 +46,7 @@ function genYieldExpr(compiler: Compiler, expr: ts.YieldExpression) { } function genYieldStarExpr(compiler: Compiler, expr: ts.YieldExpression) { - let funcBuilder = compiler.getFuncBuilder(); + let funcBuilder = compiler.getFuncBuilder();//hyq if (!expr.expression) { throw new Error("yield* must have an expression!"); } diff --git a/ts2panda/src/function/asyncGeneratorFunctionBuilder.ts b/ts2panda/src/function/asyncGeneratorFunctionBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..7807d11142b50d45eab608b9193573f3fb637de3 --- /dev/null +++ b/ts2panda/src/function/asyncGeneratorFunctionBuilder.ts @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Scope } from "src/scope"; +import ts from "typescript"; +import { CacheList, getVregisterCache } from "../base/vregisterCache"; +import { Compiler, ControlFlowChange } from "../compiler"; +import { + Label, + VReg +} from "../irnodes"; +import { PandaGen } from "../pandagen"; +//import { Recorder } from "../recorder"; +import { IteratorRecord, IteratorType, getIteratorRecord } from "../statement/forOfStatement"; +import { AsyncFunctionBuilder } from "./asyncFunctionBuilder"; //new add + +enum ResumeMode { Return = 0, Throw, Next }; + +/** + * async function *foo() { + * yield 'a' + * } +*/ +export class AsyncGeneratorFunctionBuilder { //new add + private asyncPandaGen: PandaGen; + private compiler: Compiler; + private asyncGenObj: VReg; + private retValue: VReg; + + constructor(pandaGen: PandaGen, compiler: Compiler) { + console.log("----createFuncBuilder---4.2---"); + this.asyncPandaGen = pandaGen; + this.compiler = compiler; + this.asyncGenObj = pandaGen.getTemp(); + this.retValue = pandaGen.getTemp(); + console.log("----createFuncBuilder---4.3---"); + } + + prepare(node: ts.Node) { + console.log("----createFuncBuilder---5.1---"); + let pandaGen = this.asyncPandaGen; + // backend handle funcobj, frontend set undefined + pandaGen.createAsyncGeneratorObj(node, getVregisterCache(pandaGen, CacheList.FUNC)); + pandaGen.storeAccumulator(node, this.asyncGenObj); + pandaGen.suspendGenerator(node, this.asyncGenObj, getVregisterCache(pandaGen, CacheList.undefined)); + pandaGen.resumeGenerator(node, this.asyncGenObj); + pandaGen.storeAccumulator(node, this.retValue); + console.log("----createFuncBuilder---5.2---"); + this.handleMode(node); + + } + + await(node: ts.Node, value: VReg): void { + let pandaGen = this.asyncPandaGen; + let promise = this.asyncPandaGen.getTemp(); + + pandaGen.asyncFunctionAwaitUncaught(node, this.asyncGenObj, value); + pandaGen.storeAccumulator(node, promise); + + pandaGen.suspendGenerator(node, this.asyncGenObj, promise); + + pandaGen.freeTemps(promise); + + pandaGen.resumeGenerator(node, this.asyncGenObj); + pandaGen.storeAccumulator(node, this.retValue); + + this.handleMode(node); + } + + yield(node: ts.Node, value: VReg) { + let pandaGen = this.asyncPandaGen; + let iterRslt = pandaGen.getTemp(); + + //pandaGen.EcmaAsyncGenratorYield(node, this.asyncGenObj, value, CacheList.False); // new add + //pandaGen.asyncFunctionAwaitUncaught(node, this.asyncGenObj, value); // new add + this.await(node, value); //new add + pandaGen.storeAccumulator(node, iterRslt); + pandaGen.suspendGenerator(node, this.asyncGenObj, iterRslt); + pandaGen.freeTemps(iterRslt); + pandaGen.resumeGenerator(node, this.asyncGenObj); + pandaGen.storeAccumulator(node, this.retValue); + this.asyncHandleMode(node, value); +/* + this.await(node, value); // new add + pandaGen.suspendGenerator(node, this.asyncGenObj, value); // new add + pandaGen.freeTemps(value); //new add + + pandaGen.resumeGenerator(node, this.asyncGenObj); + pandaGen.storeAccumulator(node, this.retValue); + + this.asyncHandleMode(node); +*/ + } +/* + yieldStar(expr: ts.YieldExpression) { + let pandaGen = this.pandaGen; + let method = pandaGen.getTemp(); + let object = pandaGen.getTemp(); + + let receivedValue = pandaGen.getTemp(); + let modeType = pandaGen.getTemp(); + + let loopStartLabel = new Label(); + let callreturnLabel = new Label(); + let callthrowLabel = new Label(); + let iteratorCompletionLabel = new Label(); + let exitLabel_return = new Label(); + let exitLabel_throw = new Label(); + let exitLabel_value = new Label(); + let exitLabel_TypeError = new Label(); + // get innerIterator & iterator.[[Nextmethod]] (spec 4 & 5), support async in the future + let type: IteratorType = IteratorType.Async; + let iterator: IteratorRecord = getIteratorRecord(pandaGen, expr, method, object, type);//封装了设置为next的方法。 + + // init receivedValue with Undefined (spec 6) + pandaGen.moveVreg(expr, receivedValue, getVregisterCache(pandaGen, CacheList.undefined)); + + // init modeType with Next (spec 6) + pandaGen.loadAccumulatorInt(expr, ResumeMode.Next); + pandaGen.storeAccumulator(expr, modeType); + + + + + // starts executeing iterator.[[method]] (spec 7) + pandaGen.label(expr, loopStartLabel); + pandaGen.loadAccumulatorInt(expr, ResumeMode.Next); + + pandaGen.condition(expr, ts.SyntaxKind.EqualsEqualsToken, modeType, callreturnLabel); + //1 call next//如果是next的话执行下面,否则跳转到pandaGen.label(expr, callreturnLabel); + pandaGen.call(expr, [iterator.getNextMethod(), iterator.getObject(), receivedValue], true); + pandaGen.branch(expr, iteratorCompletionLabel); + + // call return + pandaGen.label(expr, callreturnLabel); + pandaGen.loadAccumulatorInt(expr, ResumeMode.Return); + pandaGen.condition(expr, ts.SyntaxKind.EqualsEqualsToken, modeType, callthrowLabel); + + //if is return 执行下面,否则跳转到 callthrowLabel + + //********return start + + pandaGen.loadObjProperty(expr, iterator.getObject(), "return"); + pandaGen.storeAccumulator(expr, method); + + // whether iterator.[[return]] exists + pandaGen.condition(expr, ts.SyntaxKind.ExclamationEqualsEqualsToken, + getVregisterCache(pandaGen, CacheList.undefined), exitLabel_return); + pandaGen.call(expr, [method, iterator.getObject(), receivedValue], true); + pandaGen.branch(expr, iteratorCompletionLabel); + + // no return method + pandaGen.label(expr, exitLabel_return); + + // if there are finally blocks, should implement these at first. + this.compiler.compileFinallyBeforeCFC( + undefined, + ControlFlowChange.Break, + undefined + ); + + // spec 7.c.iii.2 Return Completion(received). + this.await(expr, receivedValue)//spec 7.c.iii.1 hyq 注意一下下面这句话的作用。 + pandaGen.loadAccumulator(expr, receivedValue); + pandaGen.return(expr); + + /************* return end + + // call throw + pandaGen.label(expr, callthrowLabel); + + pandaGen.loadObjProperty(expr, iterator.getObject(), "throw"); + pandaGen.storeAccumulator(expr, method); + + // whether iterator.[[throw]] exists 存在执行下面直到pandaGen.branch(expr, iteratorCompletionabel); + pandaGen.condition(expr, ts.SyntaxKind.ExclamationEqualsEqualsToken, getVregisterCache(pandaGen, CacheList.undefined), exitLabel_throw); + + pandaGen.call(expr, [method, iterator.getObject(), receivedValue], true); + pandaGen.branch(expr, iteratorCompletionLabel); + + // NOTE: If iterator does not have a throw method, this throw is + // going to terminate the yield* loop. But first we need to give + // iterator a chance to clean up. + + //7.b.iii + pandaGen.label(expr, exitLabel_throw); + pandaGen.loadObjProperty(expr, iterator.getObject(), "return"); + pandaGen.storeAccumulator(expr, method); + + // whether iterator.[[return]] exists + pandaGen.condition(expr, ts.SyntaxKind.ExclamationEqualsEqualsToken, + getVregisterCache(pandaGen, CacheList.undefined), exitLabel_TypeError); + + // [[return]] exists + pandaGen.call(expr, [method, iterator.getObject()], true); + let innerResult = pandaGen.getTemp(); + pandaGen.storeAccumulator(expr, innerResult); + + pandaGen.throwIfNotObject(expr, innerResult); + pandaGen.freeTemps(innerResult); + + pandaGen.label(expr, exitLabel_TypeError); + + pandaGen.throwThrowNotExist(expr); + // iteratorCompletion + pandaGen.label(expr, iteratorCompletionLabel); + + pandaGen.storeAccumulator(expr, this.retVal); + //7.a.ii 7.b.ii.2 7.c.vv. v. If generatorKind is async, + //set innerReturnResult to ? Await(innerReturnResult). + + this.await(expr, this.retVal); + + //If Type(innerResult) is not Object, throw a TypeError exception. + pandaGen.throwIfNotObject(expr, this.retVal); + + pandaGen.loadObjProperty(expr, this.retVal, "done"); + pandaGen.jumpIfTrue(expr, exitLabel_value); + + + pandaGen.suspendGenerator(expr, this.genObj, this.retVal); + pandaGen.resumeGenerator(expr, this.genObj); + pandaGen.storeAccumulator(expr, receivedValue); + pandaGen.getResumeMode(expr, this.genObj); + pandaGen.storeAccumulator(expr, modeType); + pandaGen.branch(expr, loopStartLabel); + + // spec 7.a.v.1/7.b.ii.6.a/7.c.viii Return ? IteratorValue(innerResult). + // Decide if we trigger a return or if the yield* expression should just + // produce a value. + let outputLabel = new Label(); + + pandaGen.label(expr, exitLabel_value); + pandaGen.loadObjProperty(expr, this.retVal, "value"); + let outputResult = pandaGen.getTemp(); + pandaGen.storeAccumulator(expr, outputResult); + pandaGen.loadAccumulatorInt(expr, ResumeMode.Return); + pandaGen.condition(expr, ts.SyntaxKind.EqualsEqualsToken, modeType, outputLabel); + + this.compiler.compileFinallyBeforeCFC( + undefined, + ControlFlowChange.Break, + undefined + ); + pandaGen.loadAccumulator(expr, outputResult); + pandaGen.return(expr); + + pandaGen.label(expr, outputLabel); + + pandaGen.loadAccumulator(expr, outputResult);//hyq + + pandaGen.freeTemps(method, object, receivedValue, modeType, outputResult); + } +*/ + + private asyncHandleMode(node: ts.Node, value: VReg) { + let pandaGen = this.asyncPandaGen; + + let modeType = pandaGen.getTemp(); + + pandaGen.getResumeMode(node, this.asyncGenObj); + pandaGen.storeAccumulator(node, modeType); + + // .return(value) + pandaGen.loadAccumulatorInt(node, ResumeMode.Return); + + let notRetLabel = new Label(); + + pandaGen.condition(node, ts.SyntaxKind.EqualsEqualsToken, modeType, notRetLabel); + this.await(node, value); //new add + pandaGen.EcmaAsyncgeneratorresolve(node, this.asyncGenObj, value); // new add + + pandaGen.loadAccumulator(node, this.retValue); + pandaGen.return(node); + + // .throw(value) + pandaGen.label(node, notRetLabel); + + pandaGen.loadAccumulatorInt(node, ResumeMode.Throw); + + let notThrowLabel = new Label(); + + pandaGen.condition(node, ts.SyntaxKind.EqualsEqualsToken, modeType, notThrowLabel); + pandaGen.loadAccumulator(node, this.retValue); + pandaGen.throw(node); + + pandaGen.freeTemps(modeType); + + // .next(value) + pandaGen.label(node, notThrowLabel); + pandaGen.loadAccumulator(node, this.retValue); + } + + private handleMode(node: ts.Node) { + console.log("----handleMode---5.11---"); + let pandaGen = this.asyncPandaGen; + + let modeType = pandaGen.getTemp(); + + pandaGen.getResumeMode(node, this.asyncGenObj); + pandaGen.storeAccumulator(node, modeType); + + // .return(value) + pandaGen.loadAccumulatorInt(node, ResumeMode.Return); + + let notRetLabel = new Label(); + + pandaGen.condition(node, ts.SyntaxKind.EqualsEqualsToken, modeType, notRetLabel); + + // if there are finally blocks, should implement these at first. + this.compiler.compileFinallyBeforeCFC( + undefined, + ControlFlowChange.Break, + undefined + ); + + pandaGen.loadAccumulator(node, this.retValue); + pandaGen.return(node); + + // .throw(value) + pandaGen.label(node, notRetLabel); + + pandaGen.loadAccumulatorInt(node, ResumeMode.Throw); + + let notThrowLabel = new Label(); + + pandaGen.condition(node, ts.SyntaxKind.EqualsEqualsToken, modeType, notThrowLabel); + pandaGen.loadAccumulator(node, this.retValue); + pandaGen.throw(node); + + pandaGen.freeTemps(modeType); + + // .next(value) + pandaGen.label(node, notThrowLabel); + console.log("----handleMode---5.12---"); + pandaGen.loadAccumulator(node, this.retValue); + } + + cleanUp() { + this.asyncPandaGen.freeTemps(this.asyncGenObj, this.retValue); + } +} diff --git a/ts2panda/src/function/functionBuilder.ts b/ts2panda/src/function/functionBuilder.ts index f05185a8e159f2d17fc4a7425d63fb70250bfb7c..48df3399f7535091f34c927e29f07af09030a086 100644 --- a/ts2panda/src/function/functionBuilder.ts +++ b/ts2panda/src/function/functionBuilder.ts @@ -16,8 +16,9 @@ import * as ts from "typescript"; import { GeneratorFunctionBuilder } from "./generatorFunctionBuilder"; import { AsyncFunctionBuilder } from "./asyncFunctionBuilder"; +import { AsyncGeneratorFunctionBuilder } from "./asyncGeneratorFunctionBuilder"; //new add -export type FunctionBuilderType = AsyncFunctionBuilder | GeneratorFunctionBuilder | FunctionBuilder; +export type FunctionBuilderType = AsyncFunctionBuilder | GeneratorFunctionBuilder | FunctionBuilder | AsyncGeneratorFunctionBuilder; export class FunctionBuilder { // @ts-ignore diff --git a/ts2panda/src/index.ts b/ts2panda/src/index.ts index d8d01480b293d782ad3c3ca70cde7b7795d2ebe2..25a034360b60aceca9dda1e51af52c919a6bf11d 100644 --- a/ts2panda/src/index.ts +++ b/ts2panda/src/index.ts @@ -188,7 +188,7 @@ namespace Compiler { allowJs: true, noEmitOnError: true, noImplicitAny: true, - target: ts.ScriptTarget.ES2017, + target: ts.ScriptTarget.ES2018, module: ts.ModuleKind.ES2015, strictNullChecks: true, skipLibCheck: true, diff --git a/ts2panda/src/pandagen.ts b/ts2panda/src/pandagen.ts index 0db314b6bdbce401e9834dfa2bf3396a3089eed1..d25482d6538d53ba5206b2f425222babce8e679e 100644 --- a/ts2panda/src/pandagen.ts +++ b/ts2panda/src/pandagen.ts @@ -42,6 +42,7 @@ import { defineClassWithBuffer, defineFunc, defineGeneratorFunc, + defineAsyncGeneratorFunc, //new add defineGetterSetterByValue, defineMethod, defineNCFunc, @@ -133,7 +134,9 @@ import { EcmaCallspreaddyn, EcmaCopyrestargs, EcmaCreategeneratorobj, + EcmaCreateasyncgeneratorobj, // new add EcmaCreateiterresultobj, + EcmaAsyncgeneratorresolve, //new add EcmaDecdyn, EcmaDiv2dyn, EcmaEqdyn, @@ -948,6 +951,11 @@ export class PandaGen { if (realNode.modifiers[i].kind == ts.SyntaxKind.AsyncKeyword) { if (realNode.asteriskToken) { // support async* further + this.add( + node, + defineAsyncGeneratorFunc(name, env, paramLength) + ); + return; } else { // async this.add( node, @@ -1006,10 +1014,19 @@ export class PandaGen { this.add(node, new EcmaCreategeneratorobj(funcObj)); } + createAsyncGeneratorObj(node: ts.Node, funcObj: VReg) { + console.log("----createAsyncGeneratorObj---AAAAA---"); + this.add(node, new EcmaCreateasyncgeneratorobj(funcObj)); // new add + } + EcmaCreateiterresultobj(node: ts.Node, value: VReg, done: VReg) { this.add(node, new EcmaCreateiterresultobj(value, done)); } + EcmaAsyncgeneratorresolve(node: ts.Node, genObj: VReg, value: VReg) { //new add + this.add(node, new EcmaAsyncgeneratorresolve(genObj, value)); + } + suspendGenerator(node: ts.Node, genObj: VReg, iterRslt: VReg) { this.add(node, new EcmaSuspendgenerator(genObj, iterRslt)); }