• 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    EcmaLessdyn,
22    EcmaReturnundefined,
23    EcmaStlettoglobalrecord,
24    EcmaTryldglobalbyname,
25    EcmaTrystglobalbyname,
26    Imm,
27    Jeqz,
28    Jmp,
29    Label, LdaiDyn,
30    ResultType,
31    StaDyn,
32    VReg
33} from "../../src/irnodes";
34import { checkInstructions, compileMainSnippet } from "../utils/base";
35
36
37describe("DoWhileLoopTest", function () {
38    it('doWhileLoopEmpty', function () {
39        let insns = compileMainSnippet("do {} while (true)");
40
41        let jumps = insns.filter(item => item instanceof Jmp);
42
43        expect(jumps.length).to.equal(1);
44
45        let jmpLabel = (<Jmp>jumps[0]).getTarget();
46
47        expect(jmpLabel).to.equal(insns[0]);
48    });
49
50    it('doWhileLoopWithBody', function () {
51        let insns = compileMainSnippet("let a = 5;" +
52            "do { a++ } while (a < 11);");
53
54        let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz));
55
56        expect(jumps.length).to.equal(2);
57
58        let jgezLabel = (<Jmp>jumps[0]).getTarget();
59        let jmpLabel = (<Jmp>jumps[1]).getTarget();
60
61        expect(jmpLabel).to.equal(insns[2]);
62        expect(jgezLabel).to.equal(insns[15]);
63
64        expect(insns[13]).to.equal(jumps[0]);
65        expect(insns[14]).to.equal(jumps[1]);
66    });
67
68    it('doWhileLoopWithContinue', function () {
69        let insns = compileMainSnippet("let a = 5;" +
70            "do { a = 1; continue; } while (a < 1);");
71        let a = new VReg();
72        let lhs = new VReg();
73        let labelPre = new Label();
74        let labelCond = new Label();
75        let labelPost = new Label();
76        let expected = [
77            new LdaiDyn(new Imm(5)),
78            new EcmaStlettoglobalrecord('a'),
79            // body
80            labelPre,
81            new LdaiDyn(new Imm(1)),
82            new EcmaTrystglobalbyname('a'),
83            new Jmp(labelCond), // continue
84            // condition
85            labelCond,
86            new EcmaTryldglobalbyname('a'),
87            new StaDyn(lhs),
88            new LdaiDyn(new Imm(1)),
89            new EcmaLessdyn(lhs),
90            new Jeqz(labelPost),
91            new Jmp(labelPre),
92            labelPost,
93            new EcmaReturnundefined()
94        ]
95
96        // check the instruction kinds are the same as we expect
97        expect(checkInstructions(insns, expected)).to.be.true;
98        // check continue jumps to the expected instruction
99        let jmp = <Jmp>insns[5];
100        let targetLabel = (jmp).getTarget();
101        expect(targetLabel).to.equal(insns[6]);
102    });
103
104    it('doWhileLoopWithBreak', function () {
105        let insns = compileMainSnippet("let a = 5;" +
106            "do { a = 1; break; } while (a < 1);");
107        let a = new VReg();
108        let lhs = new VReg();
109        let labelPre = new Label();
110        let labelPost = new Label();
111        let labelCond = new Label();
112        let expected = [
113            new LdaiDyn(new Imm(5)),
114            new EcmaStlettoglobalrecord('a'),
115            //body
116            labelPre,
117            new LdaiDyn(new Imm(1)),
118            new EcmaTrystglobalbyname('a'),
119            new Jmp(labelPost), // break
120            // condition
121            labelCond,
122            new EcmaTryldglobalbyname('a'),
123            new StaDyn(lhs),
124            new LdaiDyn(new Imm(1)),
125            new EcmaLessdyn(lhs),
126            new Jeqz(labelPost),
127            new Jmp(labelPre),
128            labelPost,
129            new EcmaReturnundefined()
130        ]
131
132        // check the instruction kinds are the same as we expect
133        expect(checkInstructions(insns, expected)).to.be.true;
134        // check continue jumps to the expected instruction
135        let jmp = <Jmp>insns[5];
136        let targetLabel = (jmp).getTarget();
137        expect(targetLabel).to.equal(insns[13]);
138    });
139});