• 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    Createobjectwithbuffer,
22    Definegettersetterbyvalue,
23    Definemethod,
24    Ldobjbyname,
25    Stobjbyname,
26    Tryldglobalbyname,
27    Imm,
28    Lda,
29    Ldai,
30    LdaStr,
31    Mov,
32    Sta,
33    VReg,
34    IRNode
35} from "../../src/irnodes";
36import { checkInstructions, compileAllSnippet, compileMainSnippet } from "../utils/base";
37import { creatAstFromSnippet } from "../utils/asthelper";
38import { PandaGen } from '../../src/pandagen';
39
40describe("PropertyAccess", function () {
41    it('get obj.property', function () {
42        let insns = compileMainSnippet(`let obj;
43                                obj.property;`);
44        IRNode.pg = new PandaGen("foo", creatAstFromSnippet(`let obj;
45        obj.property;`), 0, undefined);
46        IRNode.pg.updateIcSize(1);
47
48        let objReg = new VReg();
49
50        let expected = [
51            new Tryldglobalbyname(new Imm(1), 'obj'),
52            new Sta(objReg),
53            new Lda(objReg),
54            new Ldobjbyname(new Imm(2), "property")
55        ];
56
57        insns = insns.slice(2, insns.length - 1); // cut off let obj and return.
58        expect(checkInstructions(insns, expected)).to.be.true;
59    });
60
61    it('set obj.property', function () {
62        let insns = compileMainSnippet(`let obj;
63                                obj.property = 0;`);
64        IRNode.pg = new PandaGen("foo", creatAstFromSnippet(`let obj;
65        obj.property;`), 0, undefined);
66        IRNode.pg.updateIcSize(1);
67        let objReg = new VReg();
68        let tempObj = new VReg();
69
70        let expected = [
71            new Tryldglobalbyname(new Imm(1), 'obj'),
72            new Sta(tempObj),
73            new Mov(objReg, tempObj),
74            new Ldai(new Imm(0)),
75            new Stobjbyname(new Imm(2), "property", objReg),
76        ];
77
78        insns = insns.slice(2, insns.length - 1); // cut off let obj and return.
79        expect(checkInstructions(insns, expected)).to.be.true;
80    });
81
82    it('SetAccessor', function () {
83        let compilerunit = compileAllSnippet(`
84            let obj = {
85                set myMethod (arg) {
86                    this.a = arg;
87                }
88            }`);
89        IRNode.pg = new PandaGen("foo", creatAstFromSnippet(`
90        let obj = {
91            set myMethod (arg) {
92                this.a = arg;
93            }
94        }`), 0, undefined);
95
96        let objInstance = new VReg();
97        let funcReg = new VReg();
98        let propReg = new VReg();
99
100        let expected = [
101            new Createobjectwithbuffer(new Imm(0), "_0"),
102            new Sta(objInstance),
103            new Lda(new VReg()),
104            new Definemethod(new Imm(1), "myMethod", new Imm(1)),
105            new Sta(funcReg),
106            new LdaStr("myMethod"),
107            new Sta(propReg),
108            new Lda(new VReg()),
109            new Definegettersetterbyvalue(objInstance, propReg, new VReg(), funcReg),
110        ];
111
112        compilerunit.forEach(element => {
113            if (element.internalName == "func_main_0") {
114                let insns = element.getInsns();
115
116                insns = insns.slice(0, insns.length - 3);
117                expect(checkInstructions(insns, expected)).to.be.true;
118            }
119
120            if (element.internalName == "myMethod") {
121                let parameterLength = element.getParameterLength();
122                expect(parameterLength == 1).to.be.true;
123            }
124        });
125    });
126
127    it('GetAccessor', function () {
128        let compilerunit = compileAllSnippet(`
129            let obj = {
130                get a() { return 'a'; },
131            }`);
132
133        IRNode.pg = new PandaGen("foo", creatAstFromSnippet(`
134        let obj = {
135            get a() { return 'a'; },
136        }`), 0, undefined);
137
138        let objInstance = new VReg();
139        let funcReg = new VReg();
140        let propReg = new VReg();
141
142        let expected = [
143            new Createobjectwithbuffer(new Imm(0), "_0"),
144            new Sta(objInstance),
145            new Lda(new VReg()),
146            new Definemethod(new Imm(1), "a", new Imm(0)),
147            new Sta(funcReg),
148            new LdaStr("a"),
149            new Sta(propReg),
150            new Lda(new VReg()),
151            new Definegettersetterbyvalue(objInstance, propReg, funcReg, new VReg()),
152        ];
153
154        compilerunit.forEach(element => {
155            if (element.internalName == "func_main_0") {
156                let insns = element.getInsns();
157
158                insns = insns.slice(0, insns.length - 3);
159                expect(checkInstructions(insns, expected)).to.be.true;
160            }
161        });
162    });
163
164    it('GetAccessor&SetAccessor', function () {
165        let compilerunit = compileAllSnippet(`let obj = {
166            get a() { return 'a'; },
167            set a(x) {}
168        }`);
169
170        IRNode.pg = new PandaGen("foo", creatAstFromSnippet(`let obj = {
171            get a() { return 'a'; },
172            set a(x) {}
173        }`), 0, undefined);
174
175        let objInstance = new VReg();
176        let getterReg = new VReg();
177        let setterReg = new VReg();
178        let propReg = new VReg();
179
180        let expected = [
181            new Createobjectwithbuffer(new Imm(0), "_0"),
182            new Sta(objInstance),
183            new Lda(new VReg()),
184            new Definemethod(new Imm(1), "#1#a", new Imm(0)),
185            new Sta(getterReg),
186            new Lda(new VReg()),
187            new Definemethod(new Imm(2), "#2#a", new Imm(1)),
188            new Sta(setterReg),
189            new LdaStr("a"),
190            new Sta(propReg),
191            new Lda(new VReg()),
192            new Definegettersetterbyvalue(objInstance, propReg, getterReg, setterReg),
193        ];
194
195        compilerunit.forEach(element => {
196            if (element.internalName == "func_main_0") {
197                let insns = element.getInsns();
198
199                insns = insns.slice(0, insns.length - 3);
200                expect(checkInstructions(insns, expected)).to.be.true;
201            }
202        });
203    });
204});
205