Skip to content

Commit f132d53

Browse files
committed
Implement rethrowing
1 parent 862cb39 commit f132d53

15 files changed

Lines changed: 296 additions & 43 deletions

File tree

WebAssembly.Tests/Instructions/CatchTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using Microsoft.VisualStudio.TestTools.UnitTesting;
23

34
namespace WebAssembly.Instructions;
@@ -129,4 +130,52 @@ public void Catch_MultipleExceptionTags()
129130
}
130131
).Test());
131132
}
133+
134+
135+
/// <summary>
136+
/// Tests compilation and execution of the <see cref="Rethrow"/> instruction.
137+
/// </summary>
138+
[TestMethod]
139+
public void Catch_TryInCatch()
140+
{
141+
Assert.AreEqual(1, AssemblyBuilder.CreateInstance<dynamic>("Test", WebAssemblyValueType.Int32,
142+
new Instruction[]
143+
{
144+
new Try(),
145+
146+
new Throw(0),
147+
148+
new Catch(0),
149+
150+
new Try(),
151+
new Throw(1),
152+
new Catch(1),
153+
new Int32Constant(1),
154+
new Return(),
155+
new End(),
156+
157+
new End(),
158+
159+
new Int32Constant(0),
160+
new End()
161+
},
162+
module =>
163+
{
164+
module.Types.Add(new WebAssemblyType
165+
{
166+
Parameters = Array.Empty<WebAssemblyValueType>()
167+
});
168+
169+
module.Tags.Add(new WebAssemblyTag
170+
{
171+
TypeIndex = 1
172+
});
173+
174+
module.Tags.Add(new WebAssemblyTag
175+
{
176+
TypeIndex = 1
177+
});
178+
}
179+
).Test());
180+
}
132181
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using Microsoft.VisualStudio.TestTools.UnitTesting;
3+
using WebAssembly.Runtime;
4+
5+
namespace WebAssembly.Instructions;
6+
7+
/// <summary>
8+
/// Tests the <see cref="Rethrow"/> instruction.
9+
/// </summary>
10+
[TestClass]
11+
public class RethrowTests
12+
{
13+
/// <summary>
14+
/// Tests compilation and execution of the <see cref="Rethrow"/> instruction.
15+
/// </summary>
16+
[TestMethod]
17+
public void Rethrow_Exception()
18+
{
19+
Assert.ThrowsException<WebAssemblyException>(() =>
20+
{
21+
AssemblyBuilder.CreateInstance<dynamic>("Test", WebAssemblyValueType.Int32,
22+
new Instruction[]
23+
{
24+
new Try(),
25+
new Throw(0),
26+
new Catch(0),
27+
new Rethrow(0),
28+
new End(),
29+
30+
new Int32Constant(0),
31+
new End()
32+
},
33+
module =>
34+
{
35+
module.Types.Add(new WebAssemblyType
36+
{
37+
Parameters = Array.Empty<WebAssemblyValueType>()
38+
});
39+
40+
module.Tags.Add(new WebAssemblyTag
41+
{
42+
TypeIndex = 1
43+
});
44+
}
45+
).Test();
46+
});
47+
}
48+
}

WebAssembly.Tests/Instructions/TryTests.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,36 @@ namespace WebAssembly.Instructions;
88
[TestClass]
99
public class TryTests
1010
{
11-
// Dummy type
11+
/// <summary>
12+
/// Tests compilation and execution of the <see cref="Catch"/> instruction when there are no exceptions.
13+
/// </summary>
14+
[TestMethod]
15+
public void Try_ReturnValue()
16+
{
17+
Assert.AreEqual<int>(0, AssemblyBuilder.CreateInstance<dynamic>("Test", WebAssemblyValueType.Int32,
18+
new Instruction[]
19+
{
20+
new Try(BlockType.Int32),
21+
new Int32Constant(0),
22+
new Catch(0),
23+
new End(),
24+
new End()
25+
},
26+
module =>
27+
{
28+
module.Types.Add(new WebAssemblyType
29+
{
30+
Parameters = new[]
31+
{
32+
WebAssemblyValueType.Int32
33+
},
34+
});
35+
36+
module.Tags.Add(new WebAssemblyTag
37+
{
38+
TypeIndex = 1
39+
});
40+
}
41+
).Test());
42+
}
1243
}
328 Bytes
Binary file not shown.
26 Bytes
Binary file not shown.
29 Bytes
Binary file not shown.
30 Bytes
Binary file not shown.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{"source_filename": "rethrow.wast",
2+
"commands": [
3+
{"type": "module", "line": 3, "filename": "rethrow.0.wasm"},
4+
{"type": "assert_exception", "line": 75, "action": {"type": "invoke", "field": "catch-rethrow-0", "args": []}, "expected": []},
5+
{"type": "assert_exception", "line": 77, "action": {"type": "invoke", "field": "catch-rethrow-1", "args": [{"type": "i32", "value": "0"}]}, "expected": [{"type": "i32"}]},
6+
{"type": "assert_return", "line": 78, "action": {"type": "invoke", "field": "catch-rethrow-1", "args": [{"type": "i32", "value": "1"}]}, "expected": [{"type": "i32", "value": "23"}]},
7+
{"type": "assert_exception", "line": 80, "action": {"type": "invoke", "field": "catchall-rethrow-0", "args": []}, "expected": []},
8+
{"type": "assert_exception", "line": 82, "action": {"type": "invoke", "field": "catchall-rethrow-1", "args": [{"type": "i32", "value": "0"}]}, "expected": [{"type": "i32"}]},
9+
{"type": "assert_return", "line": 83, "action": {"type": "invoke", "field": "catchall-rethrow-1", "args": [{"type": "i32", "value": "1"}]}, "expected": [{"type": "i32", "value": "23"}]},
10+
{"type": "assert_exception", "line": 84, "action": {"type": "invoke", "field": "rethrow-nested", "args": [{"type": "i32", "value": "0"}]}, "expected": [{"type": "i32"}]},
11+
{"type": "assert_exception", "line": 85, "action": {"type": "invoke", "field": "rethrow-nested", "args": [{"type": "i32", "value": "1"}]}, "expected": [{"type": "i32"}]},
12+
{"type": "assert_return", "line": 86, "action": {"type": "invoke", "field": "rethrow-nested", "args": [{"type": "i32", "value": "2"}]}, "expected": [{"type": "i32", "value": "23"}]},
13+
{"type": "assert_return", "line": 88, "action": {"type": "invoke", "field": "rethrow-recatch", "args": [{"type": "i32", "value": "0"}]}, "expected": [{"type": "i32", "value": "23"}]},
14+
{"type": "assert_return", "line": 89, "action": {"type": "invoke", "field": "rethrow-recatch", "args": [{"type": "i32", "value": "1"}]}, "expected": [{"type": "i32", "value": "42"}]},
15+
{"type": "assert_exception", "line": 91, "action": {"type": "invoke", "field": "rethrow-stack-polymorphism", "args": []}, "expected": []},
16+
{"type": "assert_invalid", "line": 93, "filename": "rethrow.1.wasm", "text": "invalid rethrow label", "module_type": "binary"},
17+
{"type": "assert_invalid", "line": 94, "filename": "rethrow.2.wasm", "text": "invalid rethrow label", "module_type": "binary"},
18+
{"type": "assert_invalid", "line": 95, "filename": "rethrow.3.wasm", "text": "invalid rethrow label", "module_type": "binary"}]}

WebAssembly.Tests/Runtime/SpecTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,4 +948,20 @@ public void SpecTest_throw()
948948

949949
SpecTestRunner.Run(Path.Combine("Runtime", "SpecTestData", "throw"), "throw.json", skips.Contains);
950950
}
951+
952+
/// <summary>
953+
/// Runs the switch tests.
954+
/// </summary>
955+
[TestMethod]
956+
public void SpecTest_rethrow()
957+
{
958+
var skips = new HashSet<uint>
959+
{
960+
93, // TODO: Validate invalid rethrow
961+
94, // TODO: Validate invalid rethrow
962+
95, // TODO: Validate invalid rethrow
963+
};
964+
965+
SpecTestRunner.Run(Path.Combine("Runtime", "SpecTestData", "rethrow"), "rethrow.json", skips.Contains);
966+
}
951967
}

WebAssembly/Instruction.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ internal static IEnumerable<Instruction> Parse(Reader reader)
133133
depth++;
134134
break;
135135

136+
case OpCode.Rethrow: yield return new Rethrow(reader); break;
136137
case OpCode.Throw: yield return new Throw(reader); break;
137138
case OpCode.Catch: yield return new Catch(reader); break;
138139
case OpCode.CatchAll: yield return new CatchAll(); break;

0 commit comments

Comments
 (0)