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