Skip to content

Commit 371a592

Browse files
committed
[MERGE #1382 @commonlisp] Wasm: drop and tee_local
Merge pull request #1382 from commonlisp:wasm_dropop - implemented drop and tee_local opcodes - drop and tee_local test case plus fixes There may need to be some validation (TBD) for block-like ops to ensure any nested ops do not yield values except for the last.
2 parents b928129 + 79328b0 commit 371a592

File tree

13 files changed

+136
-178
lines changed

13 files changed

+136
-178
lines changed

lib/WasmReader/WasmBinaryOpCodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ WASM_CTRL_OPCODE(BrIf, 0x07, Limit, false)
8181
WASM_CTRL_OPCODE(BrTable, 0x08, Limit, false)
8282
WASM_CTRL_OPCODE(Return, 0x09, Limit, false)
8383
WASM_CTRL_OPCODE(Unreachable, 0x0a, Limit, true)
84+
WASM_CTRL_OPCODE(Drop, 0x0b, Limit, false)
8485
WASM_CTRL_OPCODE(End, 0x0f, Limit, false)
8586
WASM_CTRL_OPCODE(Select, 0x05, Limit, false)
8687

@@ -94,6 +95,7 @@ WASM_MISC_OPCODE(SetLocal, 0x15, Limit, false)
9495
WASM_MISC_OPCODE(Call, 0x16, Limit, false)
9596
WASM_MISC_OPCODE(CallIndirect, 0x17, Limit, false)
9697
WASM_MISC_OPCODE(CallImport, 0x18, Limit, false)
98+
WASM_MISC_OPCODE(TeeLocal, 0x19, Limit, false)
9799

98100
// Load memory expressions.
99101
WASM_MEMREAD_OPCODE(I32LoadMem8S, 0x20, I_I, false)

lib/WasmReader/WasmBinaryReader.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,15 @@ WasmBinaryReader::ASTNode()
369369
break;
370370
case wbSetLocal:
371371
case wbGetLocal:
372+
case wbTeeLocal:
372373
VarNode();
373374
break;
374375
case wbIf:
375376
case wbElse:
376377
// no node attributes
377378
break;
379+
case wbDrop:
380+
break;
378381
case wbEnd:
379382
break;
380383
case wbNop:

lib/WasmReader/WasmByteCodeGenerator.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,9 @@ WasmBytecodeGenerator::EmitExpr(WasmOp op)
486486
info = EmitGetLocal();
487487
break;
488488
case wbSetLocal:
489-
info = EmitSetLocal();
489+
return EmitSetLocal(false);
490+
case wbTeeLocal:
491+
info = EmitSetLocal(true);
490492
break;
491493
case wbReturn:
492494
info = EmitReturnExpr();
@@ -534,6 +536,9 @@ WasmBytecodeGenerator::EmitExpr(WasmOp op)
534536
case wbBrTable:
535537
info = EmitBrTable();
536538
break;
539+
case wbDrop:
540+
info = EmitDrop();
541+
break;
537542
case wbNop:
538543
info = EmitInfo();
539544
break;
@@ -582,7 +587,7 @@ WasmBytecodeGenerator::EmitGetLocal()
582587
}
583588

584589
EmitInfo
585-
WasmBytecodeGenerator::EmitSetLocal()
590+
WasmBytecodeGenerator::EmitSetLocal(bool tee)
586591
{
587592
uint localNum = GetReader()->m_currentNode.var.num;
588593
if (localNum >= m_funcInfo->GetLocalCount())
@@ -600,7 +605,15 @@ WasmBytecodeGenerator::EmitSetLocal()
600605

601606
m_writer.AsmReg2(GetLoadOp(local.type), local.location, info.location);
602607

603-
return info;
608+
if (tee)
609+
{
610+
return info;
611+
}
612+
else
613+
{
614+
ReleaseLocation(&info);
615+
return EmitInfo();
616+
}
604617
}
605618

606619
template<WasmTypes::WasmType type>
@@ -975,6 +988,14 @@ WasmBytecodeGenerator::EmitBrTable()
975988
return EmitInfo(WasmTypes::Unreachable);
976989
}
977990

991+
EmitInfo
992+
WasmBytecodeGenerator::EmitDrop()
993+
{
994+
EmitInfo info = PopEvalStack();
995+
ReleaseLocation(&info);
996+
return EmitInfo();
997+
}
998+
978999
template<Js::OpCodeAsmJs op, typename Signature>
9791000
EmitInfo
9801001
WasmBytecodeGenerator::EmitBinExpr()

lib/WasmReader/WasmByteCodeGenerator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,9 @@ namespace Wasm
132132
EmitInfo EmitCall();
133133
EmitInfo EmitIfElseExpr();
134134
EmitInfo EmitBrTable();
135+
EmitInfo EmitDrop();
135136
EmitInfo EmitGetLocal();
136-
EmitInfo EmitSetLocal();
137+
EmitInfo EmitSetLocal(bool tee);
137138
EmitInfo EmitReturnExpr();
138139
EmitInfo EmitSelect();
139140
#if DBG_DUMP
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
labels.wast:302: $assert_return_23 unexpectedly threw: Error: Compiling wasm failed: function misc1[16]: Invalid type for LHS
2-
labels.wast:303: $assert_return_24 unexpectedly threw: Error: Compiling wasm failed: function misc2[17]: Invalid type for LHS
3-
24/26 tests passed.
1+
labels.wast:302: $assert_return_21 unexpectedly threw: Error: Compiling wasm failed: function misc1[14]: Invalid type for LHS
2+
labels.wast:303: $assert_return_22 unexpectedly threw: Error: Compiling wasm failed: function misc2[15]: Invalid type for LHS
3+
22/24 tests passed.
-172 Bytes
Binary file not shown.
Lines changed: 28 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,28 @@
1-
{
2-
"modules": [{
3-
"filename": "labels.0.wasm",
4-
"commands": [{
5-
"type": "assert_return",
6-
"name": "$assert_return_0",
7-
"file": "labels.wast",
8-
"line": 279
9-
}, {
10-
"type": "assert_return",
11-
"name": "$assert_return_1",
12-
"file": "labels.wast",
13-
"line": 280
14-
}, {
15-
"type": "assert_return",
16-
"name": "$assert_return_2",
17-
"file": "labels.wast",
18-
"line": 281
19-
}, {
20-
"type": "assert_return",
21-
"name": "$assert_return_3",
22-
"file": "labels.wast",
23-
"line": 282
24-
}, {
25-
"type": "assert_return",
26-
"name": "$assert_return_4",
27-
"file": "labels.wast",
28-
"line": 283
29-
}, {
30-
"type": "assert_return",
31-
"name": "$assert_return_5",
32-
"file": "labels.wast",
33-
"line": 284
34-
}, {
35-
"type": "assert_return",
36-
"name": "$assert_return_6",
37-
"file": "labels.wast",
38-
"line": 285
39-
}, {
40-
"type": "assert_return",
41-
"name": "$assert_return_7",
42-
"file": "labels.wast",
43-
"line": 286
44-
}, {
45-
"type": "assert_return",
46-
"name": "$assert_return_8",
47-
"file": "labels.wast",
48-
"line": 287
49-
}, {
50-
"type": "assert_return",
51-
"name": "$assert_return_9",
52-
"file": "labels.wast",
53-
"line": 288
54-
}, {
55-
"type": "assert_return",
56-
"name": "$assert_return_10",
57-
"file": "labels.wast",
58-
"line": 289
59-
}, {
60-
"type": "assert_return",
61-
"name": "$assert_return_11",
62-
"file": "labels.wast",
63-
"line": 290
64-
}, {
65-
"type": "assert_return",
66-
"name": "$assert_return_12",
67-
"file": "labels.wast",
68-
"line": 291
69-
}, {
70-
"type": "assert_return",
71-
"name": "$assert_return_13",
72-
"file": "labels.wast",
73-
"line": 292
74-
}, {
75-
"type": "assert_return",
76-
"name": "$assert_return_14",
77-
"file": "labels.wast",
78-
"line": 293
79-
}, {
80-
"type": "assert_return",
81-
"name": "$assert_return_15",
82-
"file": "labels.wast",
83-
"line": 294
84-
}, {
85-
"type": "assert_return",
86-
"name": "$assert_return_16",
87-
"file": "labels.wast",
88-
"line": 295
89-
}, {
90-
"type": "assert_return",
91-
"name": "$assert_return_17",
92-
"file": "labels.wast",
93-
"line": 296
94-
}, {
95-
"type": "assert_return",
96-
"name": "$assert_return_18",
97-
"file": "labels.wast",
98-
"line": 297
99-
}, {
100-
"type": "assert_return",
101-
"name": "$assert_return_19",
102-
"file": "labels.wast",
103-
"line": 298
104-
}, {
105-
"type": "assert_return",
106-
"name": "$assert_return_20",
107-
"file": "labels.wast",
108-
"line": 299
109-
}, {
110-
"type": "assert_return",
111-
"name": "$assert_return_21",
112-
"file": "labels.wast",
113-
"line": 300
114-
}, {
115-
"type": "assert_return",
116-
"name": "$assert_return_22",
117-
"file": "labels.wast",
118-
"line": 301
119-
}, {
120-
"type": "assert_return",
121-
"name": "$assert_return_23",
122-
"file": "labels.wast",
123-
"line": 302
124-
}, {
125-
"type": "assert_return",
126-
"name": "$assert_return_24",
127-
"file": "labels.wast",
128-
"line": 303
129-
}, {
130-
"type": "assert_return",
131-
"name": "$assert_return_25",
132-
"file": "labels.wast",
133-
"line": 304
134-
}]
135-
}]
136-
}
1+
{"modules": [
2+
{"filename": "labels.0.wasm", "commands": [
3+
{"type": "assert_return", "name": "$assert_return_0", "file": "labels.wast", "line": 279},
4+
{"type": "assert_return", "name": "$assert_return_1", "file": "labels.wast", "line": 280},
5+
{"type": "assert_return", "name": "$assert_return_2", "file": "labels.wast", "line": 281},
6+
{"type": "assert_return", "name": "$assert_return_3", "file": "labels.wast", "line": 282},
7+
{"type": "assert_return", "name": "$assert_return_4", "file": "labels.wast", "line": 283},
8+
{"type": "assert_return", "name": "$assert_return_5", "file": "labels.wast", "line": 284},
9+
{"type": "assert_return", "name": "$assert_return_6", "file": "labels.wast", "line": 285},
10+
{"type": "assert_return", "name": "$assert_return_7", "file": "labels.wast", "line": 286},
11+
{"type": "assert_return", "name": "$assert_return_8", "file": "labels.wast", "line": 287},
12+
{"type": "assert_return", "name": "$assert_return_9", "file": "labels.wast", "line": 288},
13+
{"type": "assert_return", "name": "$assert_return_10", "file": "labels.wast", "line": 289},
14+
{"type": "assert_return", "name": "$assert_return_11", "file": "labels.wast", "line": 290},
15+
{"type": "assert_return", "name": "$assert_return_12", "file": "labels.wast", "line": 291},
16+
{"type": "assert_return", "name": "$assert_return_13", "file": "labels.wast", "line": 292},
17+
{"type": "assert_return", "name": "$assert_return_14", "file": "labels.wast", "line": 293},
18+
{"type": "assert_return", "name": "$assert_return_15", "file": "labels.wast", "line": 294},
19+
{"type": "assert_return", "name": "$assert_return_16", "file": "labels.wast", "line": 295},
20+
{"type": "assert_return", "name": "$assert_return_17", "file": "labels.wast", "line": 297},
21+
{"type": "assert_return", "name": "$assert_return_18", "file": "labels.wast", "line": 298},
22+
{"type": "assert_return", "name": "$assert_return_19", "file": "labels.wast", "line": 300},
23+
{"type": "assert_return", "name": "$assert_return_20", "file": "labels.wast", "line": 301},
24+
{"type": "assert_return", "name": "$assert_return_21", "file": "labels.wast", "line": 302},
25+
{"type": "assert_return", "name": "$assert_return_22", "file": "labels.wast", "line": 303},
26+
{"type": "assert_return", "name": "$assert_return_23", "file": "labels.wast", "line": 304}
27+
]}
28+
]}

test/WasmSpec/testsuite/labels.wast

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -179,26 +179,26 @@
179179
(i32.const 2)
180180
)
181181

182-
(func $br_if0 (result i32)
183-
(local $i i32)
184-
(set_local $i (i32.const 0))
185-
(block $outer
186-
(block $inner
187-
(br_if $inner (i32.const 0))
188-
(set_local $i (i32.or (get_local $i) (i32.const 0x1)))
189-
(br_if $inner (i32.const 1))
190-
(set_local $i (i32.or (get_local $i) (i32.const 0x2)))
191-
)
192-
(br_if $outer
193-
(set_local $i (i32.or (get_local $i) (i32.const 0x4))) (i32.const 0)
194-
)
195-
(set_local $i (i32.or (get_local $i) (i32.const 0x8)))
196-
(br_if $outer
197-
(set_local $i (i32.or (get_local $i) (i32.const 0x10))) (i32.const 1)
198-
)
199-
(set_local $i (i32.or (get_local $i) (i32.const 0x20)))
200-
)
201-
)
182+
;; (func $br_if0 (result i32)
183+
;; (local $i i32)
184+
;; (set_local $i (i32.const 0))
185+
;; (block $outer
186+
;; (block $inner
187+
;; (br_if $inner (i32.const 0))
188+
;; (set_local $i (i32.or (get_local $i) (i32.const 0x1)))
189+
;; (br_if $inner (i32.const 1))
190+
;; (set_local $i (i32.or (get_local $i) (i32.const 0x2)))
191+
;; )
192+
;; (br_if $outer
193+
;; (set_local $i (i32.or (get_local $i) (i32.const 0x4))) (i32.const 0)
194+
;; )
195+
;; (set_local $i (i32.or (get_local $i) (i32.const 0x8)))
196+
;; (br_if $outer
197+
;; (set_local $i (i32.or (get_local $i) (i32.const 0x10))) (i32.const 1)
198+
;; )
199+
;; (set_local $i (i32.or (get_local $i) (i32.const 0x20)))
200+
;; )
201+
;; )
202202

203203
(func $br_if1 (result i32)
204204
(block $l0
@@ -213,17 +213,17 @@
213213
(br $l1 (i32.const 1)))))
214214
(i32.const 1)))
215215

216-
(func $br_if3 (result i32)
217-
(local $i1 i32)
218-
(i32.add
219-
(block $l0
220-
(br_if $l0 (set_local $i1 (i32.const 1)) (set_local $i1 (i32.const 2)))
221-
(i32.const 0)
222-
)
223-
(i32.const 0)
224-
)
225-
(get_local $i1)
226-
)
216+
;; (func $br_if3 (result i32)
217+
;; (local $i1 i32)
218+
;; (i32.add
219+
;; (block $l0
220+
;; (br_if $l0 (set_local $i1 (i32.const 1)) (set_local $i1 (i32.const 2)))
221+
;; (i32.const 0)
222+
;; )
223+
;; (i32.const 0)
224+
;; )
225+
;; (get_local $i1)
226+
;; )
227227

228228
(func $br_if4
229229
(block $l0 (br_if $l0 (nop) (i32.const 1)))
@@ -265,10 +265,10 @@
265265
(export "if2" $if2)
266266
(export "switch" $switch)
267267
(export "return" $return)
268-
(export "br_if0" $br_if0)
268+
;; (export "br_if0" $br_if0)
269269
(export "br_if1" $br_if1)
270270
(export "br_if2" $br_if2)
271-
(export "br_if3" $br_if3)
271+
;; (export "br_if3" $br_if3)
272272
(export "br_if4" $br_if4)
273273
(export "br" $br)
274274
(export "misc1" $misc1)
@@ -293,10 +293,10 @@
293293
(assert_return (invoke "return" (i32.const 0)) (i32.const 0))
294294
(assert_return (invoke "return" (i32.const 1)) (i32.const 2))
295295
(assert_return (invoke "return" (i32.const 2)) (i32.const 2))
296-
(assert_return (invoke "br_if0") (i32.const 0x1d))
296+
;;(assert_return (invoke "br_if0") (i32.const 0x1d))
297297
(assert_return (invoke "br_if1") (i32.const 1))
298298
(assert_return (invoke "br_if2") (i32.const 1))
299-
(assert_return (invoke "br_if3") (i32.const 2))
299+
;;(assert_return (invoke "br_if3") (i32.const 2))
300300
(assert_return (invoke "br_if4"))
301301
(assert_return (invoke "br") (i32.const 1))
302302
(assert_return (invoke "misc1") (i32.const 1))

test/wasm/dropteelocal.baseline

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
100

test/wasm/dropteelocal.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
const blob = WScript.LoadBinaryFile('dropteelocal.wasm')
7+
const view = new Uint8Array(blob);
8+
var a = Wasm.instantiateModule(view, {}).exports;
9+
print(a.tee(1)); // == 100

0 commit comments

Comments
 (0)