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