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 Returnundefined, 22 Sttoglobalrecord, 23 Throw, 24 Trystglobalbyname, 25 Imm, 26 Jmp, 27 Label, 28 Lda, 29 Ldai, 30 Sta, 31 VReg, 32 IRNode 33} from "../../src/irnodes"; 34import { checkInstructions, compileMainSnippet } from "../utils/base"; 35import { creatAstFromSnippet } from "../utils/asthelper" 36import { PandaGen } from '../../src/pandagen'; 37 38describe("TryCatch", function () { 39 it('tryCatch', function () { 40 let insns = compileMainSnippet(`let a = 0; 41 try {a = 1;} 42 catch {a = 2;}`); 43 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 44 let tryBeginLabel = new Label(); 45 let tryEndLabel = new Label(); 46 let catchBeginLabel = new Label(); 47 let catchEndLabel = new Label(); 48 49 let expected = [ 50 new Ldai(new Imm(0)), 51 new Sttoglobalrecord(new Imm(0), 'a'), 52 tryBeginLabel, 53 new Ldai(new Imm(1)), 54 new Trystglobalbyname(new Imm(1), 'a'), 55 tryEndLabel, 56 new Jmp(catchEndLabel), 57 catchBeginLabel, 58 new Ldai(new Imm(2)), 59 new Trystglobalbyname(new Imm(2), 'a'), 60 catchEndLabel, 61 new Returnundefined() 62 ]; 63 64 expect(checkInstructions(insns, expected)).to.be.true; 65 }); 66 67 it('tryCatchWithIdentifier', function () { 68 let insns = compileMainSnippet(`let a = 0; 69 try {a = 1;} 70 catch(err) {a = 2;}`); 71 72 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 73 let tryBeginLabel = new Label(); 74 let tryEndLabel = new Label(); 75 let catchBeginLabel = new Label(); 76 let catchEndLabel = new Label(); 77 let err = new VReg(); 78 79 let expected = [ 80 new Ldai(new Imm(0)), 81 new Sttoglobalrecord(new Imm(0), 'a'), 82 tryBeginLabel, 83 new Ldai(new Imm(1)), 84 new Trystglobalbyname(new Imm(1), 'a'), 85 tryEndLabel, 86 new Jmp(catchEndLabel), 87 catchBeginLabel, 88 new Sta(err), 89 new Ldai(new Imm(2)), 90 new Trystglobalbyname(new Imm(2), 'a'), 91 catchEndLabel, 92 new Returnundefined() 93 ]; 94 95 expect(checkInstructions(insns, expected)).to.be.true; 96 }); 97 98 it('tryFinally', function () { 99 let insns = compileMainSnippet(`let a = 0; 100 try {a = 1;} 101 finally {a = 3;}`); 102 103 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 104 let tryBeginLabel = new Label(); 105 let tryEndLabel = new Label(); 106 let catchBeginLabel = new Label(); 107 let catchEndLabel = new Label(); 108 let exceptionVreg = new VReg(); 109 110 let expected = [ 111 new Ldai(new Imm(0)), 112 new Sttoglobalrecord(new Imm(0), 'a'), 113 tryBeginLabel, 114 new Ldai(new Imm(1)), 115 new Trystglobalbyname(new Imm(1), 'a'), 116 tryEndLabel, 117 new Ldai(new Imm(3)), 118 new Trystglobalbyname(new Imm(2), 'a'), 119 new Jmp(catchEndLabel), 120 catchBeginLabel, 121 new Sta(exceptionVreg), 122 new Ldai(new Imm(3)), 123 new Trystglobalbyname(new Imm(3), 'a'), 124 new Lda(exceptionVreg), 125 new Throw(), 126 catchEndLabel, 127 new Returnundefined() 128 ]; 129 130 expect(checkInstructions(insns, expected)).to.be.true; 131 }); 132 133 it('tryCatchFinally', function () { 134 let insns = compileMainSnippet(`let a = 0; 135 try {a = 1;} 136 catch {a = 2;} 137 finally {a = 3;}`); 138 139 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 140 let exceptionVreg = new VReg(); 141 let tryBeginLabel = new Label(); 142 let tryEndLabel = new Label(); 143 let catchBeginLabel = new Label(); 144 let nestedTryBeginLabel = new Label(); 145 let nestedTryEndLabel = new Label(); 146 let nestedCatchBeginLabel = new Label(); 147 let nestedCatchEndLabel = new Label(); 148 let catchEndLabel = new Label(); 149 150 let expected = [ 151 new Ldai(new Imm(0)), 152 new Sttoglobalrecord(new Imm(0), 'a'), 153 tryBeginLabel, 154 nestedTryBeginLabel, 155 new Ldai(new Imm(1)), 156 new Trystglobalbyname(new Imm(1), 'a'), 157 nestedTryEndLabel, 158 new Jmp(tryEndLabel), 159 nestedCatchBeginLabel, 160 new Ldai(new Imm(2)), 161 new Trystglobalbyname(new Imm(2), 'a'), 162 nestedCatchEndLabel, 163 tryEndLabel, 164 new Ldai(new Imm(3)), 165 new Trystglobalbyname(new Imm(3), 'a'), 166 new Jmp(catchEndLabel), 167 catchBeginLabel, 168 new Sta(exceptionVreg), 169 new Ldai(new Imm(3)), 170 new Trystglobalbyname(new Imm(4), 'a'), 171 new Lda(exceptionVreg), 172 new Throw(), 173 catchEndLabel, 174 new Returnundefined() 175 ]; 176 177 expect(checkInstructions(insns, expected)).to.be.true; 178 }); 179});