• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}