• 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 {
17    expect
18} from 'chai';
19import 'mocha';
20import {
21    EcmaCreateobjectwithbuffer,
22    EcmaDefinegettersetterbyvalue,
23    EcmaDefinemethod,
24    EcmaLdobjbyname,
25    EcmaStobjbyname,
26    EcmaTryldglobalbyname,
27    Imm,
28    LdaDyn,
29    LdaiDyn,
30    LdaStr,
31    MovDyn,
32    ResultType,
33    StaDyn,
34    VReg
35} from "../../src/irnodes";
36import { checkInstructions, compileAllSnippet, compileMainSnippet } from "../utils/base";
37
38describe("PropertyAccess", function () {
39    it('get obj.property', function () {
40        let insns = compileMainSnippet(`let obj;
41                                obj.property;`);
42
43        let objReg = new VReg();
44
45        let expected = [
46            new EcmaTryldglobalbyname('obj'),
47            new StaDyn(objReg),
48            new EcmaLdobjbyname("property", objReg)
49        ];
50
51        insns = insns.slice(2, insns.length - 1); // cut off let obj and return.dyn
52        expect(checkInstructions(insns, expected)).to.be.true;
53    });
54
55    it('set obj.property', function () {
56        let insns = compileMainSnippet(`let obj;
57                                obj.property = 0;`);
58        let objReg = new VReg();
59        let tempObj = new VReg();
60
61        let expected = [
62            new EcmaTryldglobalbyname('obj'),
63            new StaDyn(tempObj),
64            new MovDyn(objReg, tempObj),
65            new LdaiDyn(new Imm(0)),
66            new EcmaStobjbyname("property", objReg),
67        ];
68
69        insns = insns.slice(2, insns.length - 1); // cut off let obj and return.dyn
70        expect(checkInstructions(insns, expected)).to.be.true;
71    });
72
73    it('SetAccessor', function () {
74        let compilerunit = compileAllSnippet(`
75            let obj = {
76                set myMethod (arg) {
77                    this.a = arg;
78                }
79            }`);
80
81        let objInstance = new VReg();
82        let funcReg = new VReg();
83        let propReg = new VReg();
84
85        let expected = [
86            new EcmaCreateobjectwithbuffer(new Imm(0)),
87            new StaDyn(objInstance),
88            new LdaDyn(new VReg()),
89            new EcmaDefinemethod("myMethod", new Imm(1), new VReg()),
90            new StaDyn(funcReg),
91            new LdaStr("myMethod"),
92            new StaDyn(propReg),
93            new LdaDyn(new VReg()),
94            new EcmaDefinegettersetterbyvalue(objInstance, propReg, new VReg(), funcReg),
95        ];
96
97        compilerunit.forEach(element => {
98            if (element.internalName == "func_main_0") {
99                let insns = element.getInsns();
100
101                insns = insns.slice(0, insns.length - 3);
102                expect(checkInstructions(insns, expected)).to.be.true;
103            }
104
105            if (element.internalName == "myMethod") {
106                let parameterLength = element.getParameterLength();
107                expect(parameterLength == 1).to.be.true;
108            }
109        });
110    });
111
112    it('GetAccessor', function () {
113        let compilerunit = compileAllSnippet(`
114            let obj = {
115                get a() { return 'a'; };
116            }`);
117
118        let objInstance = new VReg();
119        let funcReg = new VReg();
120        let propReg = new VReg();
121
122        let expected = [
123            new EcmaCreateobjectwithbuffer(new Imm(0)),
124            new StaDyn(objInstance),
125            new LdaDyn(new VReg()),
126            new EcmaDefinemethod("a", new Imm(0), new VReg()),
127            new StaDyn(funcReg),
128            new LdaStr("a"),
129            new StaDyn(propReg),
130            new LdaDyn(new VReg()),
131            new EcmaDefinegettersetterbyvalue(objInstance, propReg, funcReg, new VReg()),
132        ];
133
134        compilerunit.forEach(element => {
135            if (element.internalName == "func_main_0") {
136                let insns = element.getInsns();
137
138                insns = insns.slice(0, insns.length - 3);
139                expect(checkInstructions(insns, expected)).to.be.true;
140            }
141        });
142    });
143
144    it('GetAccessor&SetAccessor', function () {
145        let compilerunit = compileAllSnippet(`let obj = {
146            get a() { return 'a'; },
147            set a(x) {}
148        }`);
149
150        let objInstance = new VReg();
151        let getterReg = new VReg();
152        let setterReg = new VReg();
153        let propReg = new VReg();
154
155        let expected = [
156            new EcmaCreateobjectwithbuffer(new Imm(0)),
157            new StaDyn(objInstance),
158            new LdaDyn(new VReg()),
159            new EcmaDefinemethod("#1#a", new Imm(0), new VReg()),
160            new StaDyn(getterReg),
161            new LdaDyn(new VReg()),
162            new EcmaDefinemethod("#2#a", new Imm(1), new VReg()),
163            new StaDyn(setterReg),
164            new LdaStr("a"),
165            new StaDyn(propReg),
166            new LdaDyn(new VReg()),
167            new EcmaDefinegettersetterbyvalue(objInstance, propReg, getterReg, setterReg),
168        ];
169
170        compilerunit.forEach(element => {
171            if (element.internalName == "func_main_0") {
172                let insns = element.getInsns();
173
174                insns = insns.slice(0, insns.length - 3);
175                expect(checkInstructions(insns, expected)).to.be.true;
176            }
177        });
178    });
179});
180