• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 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 {
17    Dynamicimport,
18    Callarg0,
19    Callarg1,
20    Callargs2,
21    Callargs3,
22    Callrange,
23    WideCallrange,
24    Callthis0,
25    Callthis1,
26    Callthis2,
27    Callthis3,
28    Callthisrange,
29    WideCallthisrange,
30    Closeiterator,
31    Copydataproperties,
32    Createarraywithbuffer,
33    Createemptyarray,
34    Createemptyobject,
35    Createobjectwithbuffer,
36    Createobjectwithexcludedkeys,
37    Createregexpwithliteral,
38    Debugger,
39    Defineclasswithbuffer,
40    Definefunc,
41    Definegettersetterbyvalue,
42    Definemethod,
43    Delobjprop,
44    Getiterator,
45    Getnextpropname,
46    Getpropiterator,
47    Getmodulenamespace,
48    Isfalse,
49    Istrue,
50    Ldglobalvar,
51    Ldlexvar,
52    Ldobjbyindex,
53    Ldobjbyname,
54    Ldobjbyvalue,
55    Ldsuperbyname,
56    Ldsuperbyvalue,
57    Newlexenv,
58    Newlexenvwithname,
59    Newobjrange,
60    Poplexenv,
61    Returnundefined,
62    Setobjectwithproto,
63    Starrayspread,
64    Stconsttoglobalrecord,
65    Stglobalvar,
66    Stlexvar,
67    Stmodulevar,
68    Stobjbyindex,
69    Stobjbyname,
70    Stobjbyvalue,
71    Stownbyindex,
72    Stownbyname,
73    Stownbynamewithnameset,
74    Stownbyvalue,
75    Stownbyvaluewithnameset,
76    Stsuperbyname,
77    Stsuperbyvalue,
78    Supercallthisrange,
79    Supercallspread,
80    ThrowConstassignment,
81    ThrowDeletesuperproperty,
82    Throw,
83    ThrowIfnotobject,
84    ThrowIfsupernotcorrectcall,
85    ThrowPatternnoncoercible,
86    ThrowNotexists,
87    ThrowUndefinedifholewithname,
88    Tryldglobalbyname,
89    Trystglobalbyname,
90    Fldai,
91    Imm,
92    IRNode,
93    Jmp,
94    Label,
95    Lda,
96    Ldai,
97    LdaStr,
98    Mov,
99    Sta,
100    Ldbigint,
101    VReg,
102    WideNewlexenv,
103    WideNewlexenvwithname,
104    WideLdlexvar,
105    WideStlexvar,
106    WideLdobjbyindex,
107    WideStobjbyindex,
108    WideStownbyindex,
109    WideNewobjrange,
110    WideCreateobjectwithexcludedkeys,
111    WideSupercallthisrange,
112    WideSupercallarrowrange,
113    Supercallarrowrange,
114    WideGetmodulenamespace,
115    Ldlocalmodulevar,
116    WideLdlocalmodulevar,
117    Ldexternalmodulevar,
118    WideLdexternalmodulevar,
119    WideStmodulevar,
120    Sttoglobalrecord
121} from "../irnodes";
122import { MAX_INT16, MAX_INT8 } from "./util";
123
124export function loadAccumulatorInt(value: number): IRNode {
125    return new Ldai(new Imm(value));
126}
127
128export function loadAccumulatorFloat(value: number): IRNode {
129    return new Fldai(new Imm(value));
130}
131
132export function loadAccumulatorString(value: string): IRNode {
133    return new LdaStr(value);
134}
135
136export function loadAccumulator(vreg: VReg): IRNode {
137    return new Lda(vreg);
138}
139
140export function storeAccumulator(vreg: VReg): IRNode {
141    return new Sta(vreg);
142}
143
144export function deleteObjProperty(obj: VReg): IRNode {
145    return new Delobjprop(obj);
146}
147
148export function moveVreg(vd: VReg, vs: VReg): IRNode {
149    return new Mov(vd, vs);
150}
151
152export function jumpTarget(target: Label): IRNode {
153    return new Jmp(target);
154}
155
156export function creatDebugger(): IRNode {
157    return new Debugger();
158}
159
160export function throwException(): IRNode {
161    return new Throw();
162}
163
164export function throwConstAssignment(name: VReg): IRNode {
165    return new ThrowConstassignment(name);
166}
167
168export function throwUndefinedIfHole(name: string): IRNode {
169    return new ThrowUndefinedifholewithname(name);
170}
171
172export function throwThrowNotExists(): IRNode {
173    return new ThrowNotexists();
174}
175
176export function throwDeleteSuperProperty(): IRNode {
177    return new ThrowDeletesuperproperty();
178}
179
180export function newLexicalEnv(numVars: number, scopeInfoId: string | undefined): IRNode {
181    if (scopeInfoId === undefined) {
182        return numVars <= MAX_INT8 ? new Newlexenv(new Imm(numVars)) :
183                                     new WideNewlexenv(new Imm(numVars));
184    }
185    return numVars <= MAX_INT8 ? new Newlexenvwithname(new Imm(numVars), scopeInfoId) :
186                                 new WideNewlexenvwithname(new Imm(numVars), scopeInfoId);
187}
188
189export function popLexicalEnv(): IRNode {
190    return new Poplexenv();
191}
192
193export function loadLexicalVar(level: number, slot: number): IRNode {
194    if ((level > MAX_INT8) || (slot > MAX_INT8)) {
195        return new WideLdlexvar(new Imm(level), new Imm(slot));
196    }
197    return new Ldlexvar(new Imm(level), new Imm(slot));
198}
199
200export function storeLexicalVar(level: number, slot: number): IRNode {
201    if ((level > MAX_INT8) || (slot > MAX_INT8)) {
202        return new WideStlexvar(new Imm(level), new Imm(slot));
203    }
204    return new Stlexvar(new Imm(level), new Imm(slot));
205}
206
207export function tryLoadGlobalByName(key: string): IRNode {
208    return new Tryldglobalbyname(new Imm(0), key);
209}
210
211export function tryStoreGlobalByName(key: string): IRNode {
212    return new Trystglobalbyname(new Imm(0), key);
213}
214
215export function loadGlobalVar(name: string): IRNode {
216    return new Ldglobalvar(new Imm(0), name);
217}
218
219export function storeGlobalVar(name: string): IRNode {
220    return new Stglobalvar(new Imm(0), name);
221}
222
223export function loadObjByName(key: string): IRNode {
224    return new Ldobjbyname(new Imm(0), key);
225}
226
227export function storeObjByName(obj: VReg, key: string): IRNode {
228    return new Stobjbyname(new Imm(0), key, obj);
229}
230
231export function loadObjByIndex(index: number): IRNode {
232    return index <= MAX_INT16 ? new Ldobjbyindex(new Imm(0), new Imm(index)) :
233                                new WideLdobjbyindex(new Imm(index));
234}
235
236export function storeObjByIndex(obj: VReg, index: number): IRNode {
237    return index <= MAX_INT16 ? new Stobjbyindex(new Imm(0), obj, new Imm(index)) :
238                                new WideStobjbyindex(obj, new Imm(index));
239}
240
241export function loadObjByValue(obj: VReg): IRNode {
242    return new Ldobjbyvalue(new Imm(0), obj);
243}
244
245export function storeObjByValue(obj: VReg, prop: VReg): IRNode {
246    return new Stobjbyvalue(new Imm(0), obj, prop);
247}
248
249export function storeOwnByName(obj: VReg, key: string, nameSetting: boolean): IRNode {
250    return nameSetting ? new Stownbynamewithnameset(new Imm(0), key, obj) :
251                         new Stownbyname(new Imm(0), key, obj);
252}
253
254export function storeOwnByIndex(obj: VReg, index: number): IRNode {
255    return index <= MAX_INT16 ? new Stownbyindex(new Imm(0), obj, new Imm(index)) :
256                                new WideStownbyindex(obj, new Imm(index));
257}
258
259export function storeOwnByValue(obj: VReg, value: VReg, nameSetting: boolean): IRNode {
260    return nameSetting ? new Stownbyvaluewithnameset(new Imm(0), obj, value) :
261                         new Stownbyvalue(new Imm(0), obj, value);
262}
263
264export function throwIfSuperNotCorrectCall(num: number): IRNode {
265    return new ThrowIfsupernotcorrectcall(new Imm(num));
266}
267
268export function call(args: VReg[], passThis: boolean): IRNode {
269    let length = args.length;
270    let insn: IRNode;
271    if (!passThis) {
272        switch (length) {
273            case 0:
274                insn = new Callarg0(new Imm(0));
275                break;
276            case 1:
277                insn = new Callarg1(new Imm(0), args[0]);
278                break;
279            case 2:
280                insn = new Callargs2(new Imm(0), args[0], args[1]);
281                break;
282            case 3:
283                insn = new Callargs3(new Imm(0), args[0], args[1], args[2]);
284                break;
285            default:
286                insn = length <= MAX_INT8 ? new Callrange(new Imm(0), new Imm(length), args) :
287                                                  new WideCallrange(new Imm(length), args);
288        }
289    } else {
290        insn = callThis(args);
291    }
292
293    return insn;
294}
295
296function callThis(args: Array<VReg>): IRNode {
297    let insn: IRNode;
298    let thisReg: VReg = args[0];
299    let length = args.length;
300    switch (length) {
301        case 1: {
302            insn = new Callthis0(new Imm(0), thisReg);
303            break;
304        }
305        case 2: {
306            insn = new Callthis1(new Imm(0), thisReg, args[1]);
307            break;
308        }
309        case 3: {
310            insn = new Callthis2(new Imm(0), thisReg, args[1], args[2]);
311            break;
312        }
313        case 4: {
314            insn = new Callthis3(new Imm(0), thisReg, args[1], args[2], args[3]);
315            break;
316        }
317        default: {
318            insn = (length - 1) <= MAX_INT8 ? new Callthisrange(new Imm(0), new Imm(length - 1), args) :
319                                              new WideCallthisrange(new Imm(length - 1), args);
320            break;
321        }
322    }
323    return insn;
324}
325
326export function newObject(args: VReg[]): IRNode {
327    let length = args.length;
328    return length <= MAX_INT8 ? new Newobjrange(new Imm(0), new Imm(length), args) :
329                                new WideNewobjrange(new Imm(length), args);
330}
331
332export function getPropIterator(): IRNode {
333    return new Getpropiterator();
334}
335
336export function getNextPropName(iter: VReg): IRNode {
337    return new Getnextpropname(iter);
338}
339
340export function returnUndefined(): IRNode {
341    return new Returnundefined();
342}
343
344export function createEmptyObject(): IRNode {
345    return new Createemptyobject();
346}
347
348export function createObjectWithBuffer(bufferId: string): IRNode {
349    return new Createobjectwithbuffer(new Imm(0), bufferId);
350}
351
352export function setObjectWithProto(proto: VReg): IRNode {
353    return new Setobjectwithproto(new Imm(0), proto);
354}
355
356export function copyDataProperties(dstObj: VReg): IRNode {
357    return new Copydataproperties(dstObj);
358}
359
360export function defineGetterSetterByValue(obj: VReg, name: VReg, getter: VReg, setter: VReg): IRNode {
361    return new Definegettersetterbyvalue(obj, name, getter, setter);
362}
363
364export function createEmptyArray(): IRNode {
365    return new Createemptyarray(new Imm(0));
366}
367
368export function createArrayWithBuffer(bufferId: string): IRNode {
369    return new Createarraywithbuffer(new Imm(0), bufferId);
370}
371
372export function storeArraySpread(array: VReg, index: VReg): IRNode {
373    return new Starrayspread(array, index);
374}
375
376export function defineClassWithBuffer(id: string, litId: string, parameterLength: number, base: VReg): IRNode {
377    return new Defineclasswithbuffer(new Imm(0), id, litId, new Imm(parameterLength), base);
378}
379
380export function createObjectWithExcludedKeys(obj: VReg, args: VReg[]): IRNode {
381    let followedArgs = args.length - 1;
382    return followedArgs <= MAX_INT8 ? new Createobjectwithexcludedkeys(new Imm(followedArgs), obj, args) :
383                                      new WideCreateobjectwithexcludedkeys(new Imm(followedArgs), obj, args);
384}
385
386export function throwObjectNonCoercible(): IRNode {
387    return new ThrowPatternnoncoercible();
388}
389
390export function throwIfNotObject(v: VReg): IRNode {
391    return new ThrowIfnotobject(v);
392}
393
394export function getIterator(): IRNode {
395    return new Getiterator(new Imm(0));
396}
397
398export function closeIterator(iter: VReg): IRNode {
399    return new Closeiterator(new Imm(0), iter);
400}
401
402export function superCall(num: number, args: Array<VReg>): IRNode {
403    return num <= MAX_INT8 ? new Supercallthisrange(new Imm(0), new Imm(num), args) :
404                             new WideSupercallthisrange(new Imm(num), args);
405}
406
407export function superCallInArrow(num: number, args: Array<VReg>): IRNode {
408    return num <= MAX_INT8 ? new Supercallarrowrange(new Imm(0), new Imm(num), args) :
409                             new WideSupercallarrowrange(new Imm(num), args);
410}
411
412export function superCallSpread(vs: VReg): IRNode {
413    return new Supercallspread(new Imm(0), vs);
414}
415
416export function ldSuperByName(key: string): IRNode {
417    return new Ldsuperbyname(new Imm(0), key); // obj is in acc
418}
419
420export function stSuperByName(obj: VReg, key: string): IRNode {
421    return new Stsuperbyname(new Imm(0), key, obj);
422}
423
424export function stSuperByValue(obj: VReg, prop: VReg): IRNode {
425    return new Stsuperbyvalue(new Imm(0), obj, prop);
426}
427
428export function ldSuperByValue(obj: VReg): IRNode {
429    return new Ldsuperbyvalue(new Imm(0), obj); // prop is in acc
430}
431
432export function loadLocalModuleVariable(index: number): IRNode {
433    return index <= MAX_INT8 ? new Ldlocalmodulevar(new Imm(index)) : new WideLdlocalmodulevar(new Imm(index));
434}
435
436export function loadExternalModuleVariable(index: number): IRNode {
437    return index <= MAX_INT8 ? new Ldexternalmodulevar(new Imm(index)) : new WideLdexternalmodulevar(new Imm(index));
438}
439
440
441export function dynamicImport() {
442    return new Dynamicimport();
443}
444
445export function storeModuleVariable(index: number): IRNode {
446    return index <= MAX_INT8 ? new Stmodulevar(new Imm(index)) : new WideStmodulevar(new Imm(index));
447}
448
449export function getModuleNamespace(moduleRequestIdx: number): IRNode {
450    return moduleRequestIdx <= MAX_INT8 ? new Getmodulenamespace(new Imm(moduleRequestIdx)) :
451                                          new WideGetmodulenamespace(new Imm(moduleRequestIdx));
452}
453
454export function defineFunc(name: string, paramLength: number): IRNode {
455    return new Definefunc(new Imm(0), name, new Imm(paramLength));
456}
457
458export function defineMethod(name: string, paramLength: number): IRNode {
459    return new Definemethod(new Imm(0), name, new Imm(paramLength));
460}
461
462export function isTrue(): IRNode {
463    return new Istrue();
464}
465
466export function isFalse(): IRNode {
467    return new Isfalse();
468}
469
470export function createRegExpWithLiteral(pattern: string, flags: number): IRNode {
471    return new Createregexpwithliteral(new Imm(0), pattern, new Imm(flags));
472}
473
474export function stLetOrClassToGlobalRecord(name: string): IRNode {
475    return new Sttoglobalrecord(new Imm(0), name);
476}
477
478export function stConstToGlobalRecord(name: string): IRNode {
479    return new Stconsttoglobalrecord(new Imm(0), name);
480}
481
482export function loadAccumulatorBigInt(value: string): IRNode {
483    return new Ldbigint(value);
484}