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