• 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    Returnundefined,
22    Sttoglobalrecord,
23    Strictnoteq,
24    Tryldglobalbyname,
25    Imm,
26    Jeqz,
27    Jmp,
28    Jnez,
29    Label,
30    Lda,
31    Ldai,
32    Sta,
33    VReg,
34    IRNode
35} from "../../src/irnodes";
36import { checkInstructions, compileMainSnippet, SnippetCompiler } from "../utils/base";
37import { creatAstFromSnippet } from "../utils/asthelper"
38import { PandaGen } from '../../src/pandagen';
39
40describe("switchTest", function () {
41    it("single case", function () {
42        let insns = compileMainSnippet("let a = 0; switch (a) {case 0 : ;}");
43        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
44        let rhs = new VReg();
45        let caseLabel = new Label();
46        let switchEndLabel = new Label();
47        let expected = [
48            new Ldai(new Imm(0)),
49            new Sttoglobalrecord(new Imm(0), 'a'),
50            // switch bodynew Imm(0),
51            new Tryldglobalbyname(new Imm(1), 'a'),
52            new Sta(rhs),
53            new Ldai(new Imm(0)),
54            new Strictnoteq(new Imm(2), rhs),
55            new Jeqz(caseLabel),
56            new Jmp(switchEndLabel),
57            // switch cases
58            caseLabel,
59            switchEndLabel,
60            new Returnundefined()
61        ];
62        expect(checkInstructions(insns, expected)).to.be.true;
63        expect((<Jnez>insns[6]).getTarget() === insns[8]).to.be.true;
64        expect((<Jmp>insns[7]).getTarget() === insns[9]).to.be.true;
65    });
66
67    it("multiple cases without break", function () {
68        let insns = compileMainSnippet(`let a = 0; switch (a)
69                                 {
70                                  case 0 : ;
71                                  case 1 : ;
72                                  default : ;
73                                 }`);
74        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
75        let rhs = new VReg();
76        let caseLabel_0 = new Label();
77        let caseLabel_1 = new Label();
78        let defaultLabel = new Label();
79        let switchEndLabel = new Label();
80        let expected = [
81            new Ldai(new Imm(0)),
82            new Sttoglobalrecord(new Imm(0), 'a'),
83            // switch body
84            new Tryldglobalbyname(new Imm(1), 'a'),
85            new Sta(rhs),
86            new Ldai(new Imm(0)),
87            new Strictnoteq(new Imm(2), rhs),
88            new Jeqz(caseLabel_0),
89            new Ldai(new Imm(1)),
90            new Strictnoteq(new Imm(3), rhs),
91            new Jeqz(caseLabel_1),
92            new Jmp(defaultLabel),
93            // cases
94            caseLabel_0,
95            caseLabel_1,
96            // default case
97            defaultLabel,
98            switchEndLabel,
99            new Returnundefined()
100        ];
101        expect(checkInstructions(insns, expected)).to.be.true;
102    });
103
104    it("multiple cases with default", function () {
105        let insns = compileMainSnippet(`let a = 0; switch (a)
106                                 {
107                                  case 0 : break;
108                                  case 1 : break;
109                                  default : ;
110                                 }`);
111        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
112        let rhs = new VReg();
113        let caseLabel_0 = new Label();
114        let caseLabel_1 = new Label();
115        let defaultLabel = new Label();
116        let switchEndLabel = new Label();
117        let expected = [
118            new Ldai(new Imm(0)),
119            new Sttoglobalrecord(new Imm(0), 'a'),
120            // switch body
121            new Tryldglobalbyname(new Imm(1), 'a'),
122            new Sta(rhs),
123            new Ldai(new Imm(0)),
124            new Strictnoteq(new Imm(2), rhs),
125            new Jeqz(caseLabel_0),
126            new Ldai(new Imm(1)),
127            new Strictnoteq(new Imm(3), rhs),
128            new Jeqz(caseLabel_1),
129            new Jmp(defaultLabel),
130            // switch cases
131            caseLabel_0,
132            new Jmp(switchEndLabel),
133            caseLabel_1,
134            new Jmp(switchEndLabel),
135            defaultLabel,
136            switchEndLabel,
137            new Returnundefined()
138        ];
139        expect(checkInstructions(insns, expected)).to.be.true;
140    });
141
142    it("multiple cases without default", function () {
143        let insns = compileMainSnippet(`let a = 0; switch (a)
144                                 {
145                                  case 0 : break;
146                                  case 1 : break;
147                                 }`);
148        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
149        let rhs = new VReg();
150        let caseLabel_0 = new Label();
151        let caseLabel_1 = new Label();
152        let switchEndLabel = new Label();
153        let expected = [
154            new Ldai(new Imm(0)),
155            new Sttoglobalrecord(new Imm(0), 'a'),
156            // switch body
157            new Tryldglobalbyname(new Imm(1), 'a'),
158            new Sta(rhs),
159            new Ldai(new Imm(0)),
160            new Strictnoteq(new Imm(2), rhs),
161            new Jeqz(caseLabel_0),
162            new Ldai(new Imm(1)),
163            new Strictnoteq(new Imm(3), rhs),
164            new Jeqz(caseLabel_1),
165            new Jmp(switchEndLabel),
166            // switch cases
167            caseLabel_0,
168            new Jmp(switchEndLabel),
169            caseLabel_1,
170            new Jmp(switchEndLabel),
171            switchEndLabel,
172            new Returnundefined()
173        ];
174        expect(checkInstructions(insns, expected)).to.be.true;
175    });
176
177    it("multiple cases with default surrounded by cases", function () {
178        let insns = compileMainSnippet(`let a = 0; switch (a)
179                                 {
180                                  case 0 : break;
181                                  default : ;
182                                  case 1 : ;
183                                 }`);
184        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
185        let rhs = new VReg();
186        let caseLabel_0 = new Label();
187        let caseLabel_1 = new Label();
188        let defaultLabel = new Label();
189        let switchEndLabel = new Label();
190        let expected = [
191            new Ldai(new Imm(0)),
192            new Sttoglobalrecord(new Imm(0), 'a'),
193            // switch body
194            new Tryldglobalbyname(new Imm(1), 'a'),
195            new Sta(rhs),
196            new Ldai(new Imm(0)),
197            new Strictnoteq(new Imm(2), rhs),
198            new Jeqz(caseLabel_0),
199            new Ldai(new Imm(1)),
200            new Strictnoteq(new Imm(3), rhs),
201            new Jeqz(caseLabel_1),
202            new Jmp(defaultLabel),
203            // switch cases
204            caseLabel_0,
205            new Jmp(switchEndLabel),
206            // default case
207            defaultLabel,
208            caseLabel_1,
209            switchEndLabel,
210            new Returnundefined()
211        ];
212        expect(checkInstructions(insns, expected)).to.be.true;
213    });
214
215    it("discriminant's scope", function () {
216        let snippetCompiler = new SnippetCompiler();
217        snippetCompiler.compile(
218            `function test() {
219                let a = 0;
220                switch (a) {
221                    case 0:
222                        const a = 0;
223                        break;
224                }
225            }`);
226        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
227
228        let a = new VReg();
229        let discriminant_a = new VReg();
230        let body_a = new VReg();
231        let caseLabel_0 = new Label();
232        let switchEndLabel = new Label();
233        let expected = [
234            new Ldai(new Imm(0)),
235            new Sta(a),
236            // switch discriminant
237            new Lda(a),
238            new Sta(discriminant_a),
239            // switch body
240            new Ldai(new Imm(0)),
241            new Strictnoteq(new Imm(1), discriminant_a),
242            new Jeqz(caseLabel_0),
243            new Jmp(switchEndLabel),
244            // switch cases
245            caseLabel_0,
246            new Ldai(new Imm(0)),
247            new Sta(body_a),
248            new Jmp(switchEndLabel),
249            switchEndLabel,
250            new Returnundefined()
251        ];
252        let functionPg = snippetCompiler.getPandaGenByName("UnitTest.test");
253        let insns = functionPg!.getInsns();
254
255        expect(checkInstructions(insns, expected)).to.be.true;
256    });
257});
258