1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import * as ts from "typescript"; 17import { Compiler } from "../compiler"; 18import { VReg } from "../irnodes"; 19import { containSpreadElement } from "../base/util"; 20import { createArrayFromElements } from "./arrayLiteralExpression"; 21 22export function compileNewExpression(expr: ts.NewExpression, compiler: Compiler) { 23 let pandaGen = compiler.getPandaGen(); 24 let ctorReg = pandaGen.getTemp(); 25 let newTargetReg = pandaGen.getTemp(); 26 27 // get the ctor function 28 compiler.compileExpression(expr.expression); 29 pandaGen.storeAccumulator(expr, ctorReg); 30 31 // new.target will be the same as ctor 32 pandaGen.moveVreg(expr, newTargetReg, ctorReg); 33 34 if (containSpreadElement(expr.arguments)) { 35 let argRegs = pandaGen.getTemp(); 36 createArrayFromElements(expr, compiler, <ts.NodeArray<ts.Expression>>expr.arguments, argRegs); 37 38 pandaGen.newObjSpread(expr, ctorReg, newTargetReg); 39 pandaGen.freeTemps(ctorReg, newTargetReg, argRegs); 40 41 return; 42 } 43 44 // prepare arguments for newobj.dyn.range instruction 45 let numArgs = 2; // for the ctor 46 if (expr.arguments) { 47 numArgs += expr.arguments.length; 48 } 49 50 let argRegs = new Array<VReg>(numArgs); 51 argRegs[0] = ctorReg; 52 argRegs[1] = newTargetReg; 53 54 let argIndex = 2; 55 if (expr.arguments) { 56 // store ctor arguments in registers 57 expr.arguments.forEach((argExpr: ts.Expression) => { 58 let argReg = pandaGen.getTemp(); 59 compiler.compileExpression(argExpr); 60 pandaGen.storeAccumulator(expr, argReg); 61 argRegs[argIndex++] = argReg; 62 }); 63 } 64 65 // generate the instruction to create new instance 66 pandaGen.newObject(expr, argRegs); 67 68 // free temp registers 69 pandaGen.freeTemps(...argRegs); 70}