Skip to content

Commit

Permalink
[gc] Update binary encoding for function references and GC
Browse files Browse the repository at this point in the history
  • Loading branch information
titzer committed Sep 9, 2023
1 parent 436ddf1 commit 0d6926f
Show file tree
Hide file tree
Showing 21 changed files with 964 additions and 241 deletions.
13 changes: 8 additions & 5 deletions issues.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,34 @@ Prio Component Issue
spc Load hot locals before loop
spc Analyze loop for read/written locals
spc Allocate registers for transfer values
spc Lazy tagging for locals
spc Lazy zeroing of value stacks
spc instr-combine for cmp+branch
spc Function filter for debugging
spc unit-test SpcState
spc unit-test regalloc
spc lazy-zeroing of frame
spc lazy value tags for locals
interpreter implement simd
interpreter implement atomics
tiering implement tier-down (upon value stack modification)
eh implement catch in fast int
eh implement catch in SPC

gc Final types
gc array.fill, array.new_data, array.new_elem
gc tests for binary iso-rec canonicalization
gc tests for verifying supertype decls

fast-int Use sign-extend / negative check for decoding LEBs
fast-int implement simd

host Add host execution env to outgoing host calls
ctlxfer more tests for greater depths
interpreter compress ctlxfer entries (4 byte cases)
wizeng basic profiler
wizeng repl for loading and running modules
test Improve ease of matching / equality checking in unit tests
validator more br tests
validator typecheck whole signatures at a time
spec is it legal to have 0-count funcs and no code section?
parse Tracing of indexes/offsets is all wrong
parse Tracing of indexes/offsets might be wrong
parse Simplify BinParser state machine
util Improve objdump utility
util Dump module into text format
Expand Down Expand Up @@ -224,6 +224,9 @@ Inline WasmObject.values array

Done
--------------------------------
wizeng basic profiler
fast-int implement simd
spc implement simd
wizeng wizeng module: rdtsc call
spc trap locations and stacktraces
spc allow register to be used for more than one slot
Expand Down
50 changes: 25 additions & 25 deletions src/engine/BpConstants.v3
Original file line number Diff line number Diff line change
Expand Up @@ -37,35 +37,35 @@ enum BpTypeCode(code: byte, val: i7) {
F32 (0x7D, -3),
F64 (0x7C, -4),
V128 (0x7B, -5),
I8 (0x7A, -6), // ext:gc
I16 (0x79, -7), // ext:gc
FUNCREF (0x70, -16),
EXTERNREF (0x6F, -17),
ANYREF (0x6E, -18), // ext:gc
EQREF (0x6D, -19), // ext:gc
REF_NULL (0x6C, -20), // ext:gc
REF (0x6B, -21), // ext:gc
I31REF (0x6A, -22), // ext:gc
NULLFUNCREF (0x69, -23), // ext:gc
NULLEXTERNREF (0x68, -24), // ext:gc
STRUCTREF (0x67, -25), // ext:gc
ARRAYREF (0x66, -26), // ext:gc
NULLREF (0x65, -27), // ext:gc
ABS (0x5A, -38), // ext:type-imports
I8 (0x78, -8),
I16 (0x77, -9),
NULLFUNCREF (0x73, -13), //
NULLEXTERNREF (0x72, -14), //
NULLREF (0x71, -15), //
FUNCREF (0x70, -16), //
EXTERNREF (0x6F, -17), //
ANYREF (0x6E, -18), //
EQREF (0x6D, -19), //
I31REF (0x6C, -20), //
STRUCTREF (0x6B, -21), //
ARRAYREF (0x6A, -22), //
REF (0x64, -28), //
REF_NULL (0x63, -29), //
ABS (0x5A, -38), //
EmptyBlock (0x40, -64) // XXX: move?
}
// Heap type codes.
enum BpHeapTypeCode(code: byte, val: i7) {
FUNC (0x70, -16),
EXTERN (0x6F, -17),
ANY (0x6E, -18),
EQ (0x6D, -19),
I31 (0x6A, -22),
NOFUNC (0x69, -23),
NOEXTERN (0x68, -24),
STRUCT (0x67, -25),
ARRAY (0x66, -26),
NONE (0x65, -27)
FUNC (0x70, -16), // -0x10
EXTERN (0x6F, -17), // -0x11
ANY (0x6E, -18), // -0x12
EQ (0x6D, -19), // -0x13
I31 (0x6C, -20), // -0x14
NOFUNC (0x73, -13), // -0x0d
NOEXTERN (0x72, -14), // -0x0e
STRUCT (0x6B, -21), // -0x15
ARRAY (0x6A, -22), // -0x16
NONE (0x71, -15) // -0x0f
}
// Memory flag masks.
enum BpMemoryFlag(mask: byte) {
Expand Down
69 changes: 35 additions & 34 deletions src/engine/Opcodes.v3
Original file line number Diff line number Diff line change
Expand Up @@ -221,42 +221,43 @@ enum Opcode(prefix: u8, code: u8, mnemonic: string, imms: Array<ImmKind>, sig: S
REF_NULL (0x00, 0xD0, "ref.null", imm.HEAPT, null),
REF_IS_NULL (0x00, 0xD1, "ref.is_null", imm.NONE, null),
REF_FUNC (0x00, 0xD2, "ref.func", imm.FUNC, null),
REF_AS_NON_NULL (0x00, 0xD3, "ref.as_non_null", imm.NONE, null),
BR_ON_NULL (0x00, 0xD4, "br_on_null", imm.LABEL, null),
REF_EQ (0x00, 0xD5, "ref.eq", imm.NONE, null),
REF_EQ (0x00, 0xD3, "ref.eq", imm.NONE, null),
REF_AS_NON_NULL (0x00, 0xD4, "ref.as_non_null", imm.NONE, null),
BR_ON_NULL (0x00, 0xD5, "br_on_null", imm.LABEL, null),
BR_ON_NON_NULL (0x00, 0xD6, "br_on_non_null", imm.LABEL, null),
// 0xFB prefix: gc proposal opcodes.
STRUCT_NEW (0xFB, 0x01, "struct.new", imm.STRUCTT, null),
STRUCT_NEW_DEFAULT (0xFB, 0x02, "struct.new_default", imm.STRUCTT, null),
STRUCT_GET (0xFB, 0x03, "struct.get", imm.STRUCTT_FIELD, null),
STRUCT_GET_S (0xFB, 0x04, "struct.get_s", imm.STRUCTT_FIELD, null),
STRUCT_GET_U (0xFB, 0x05, "struct.get_u", imm.STRUCTT_FIELD, null),
STRUCT_SET (0xFB, 0x06, "struct.set", imm.STRUCTT_FIELD, null),
ARRAY_FILL (0xFB, 0x0F, "array.fill", imm.ARRAYT, null),
ARRAY_NEW (0xFB, 0x11, "array.new", imm.ARRAYT, null),
ARRAY_NEW_DEFAULT (0xFB, 0x12, "array.new_default", imm.ARRAYT, null),
ARRAY_GET (0xFB, 0x13, "array.get", imm.ARRAYT, null),
ARRAY_GET_S (0xFB, 0x14, "array.get_s", imm.ARRAYT, null),
ARRAY_GET_U (0xFB, 0x15, "array.get_u", imm.ARRAYT, null),
ARRAY_SET (0xFB, 0x16, "array.set", imm.ARRAYT, null),
ARRAY_LEN (0xFB, 0x17, "array.len", imm.NONE, null),
ARRAY_COPY (0xFB, 0x18, "array.copy", imm.ARRAYT_ARRAYT, null),
ARRAY_NEW_FIXED (0xFB, 0x19, "array.new_fixed", imm.ARRAYT_U32, null),
ARRAY_NEW_DATA (0xFB, 0x1B, "array.new_data", imm.ARRAYT_DATA, null),
ARRAY_NEW_ELEM (0xFB, 0x1C, "array.new_elem", imm.ARRAYT_ELEM, null),
I31_NEW (0xFB, 0x20, "i31.new", imm.NONE, null),
I31_GET_S (0xFB, 0x21, "i31.get_s", imm.NONE, null),
I31_GET_U (0xFB, 0x22, "i31.get_u", imm.NONE, null),
REF_TEST (0xFB, 0x40, "ref.test", imm.HEAPT, null),
REF_CAST (0xFB, 0x41, "ref.cast", imm.HEAPT, null),
REF_TEST_NULL (0xFB, 0x48, "ref.test null", imm.HEAPT, null),
REF_CAST_NULL (0xFB, 0x49, "ref.cast null", imm.HEAPT, null),
BR_ON_CAST (0xFB, 0x4E, "br_on_cast", imm.BR_CAST_ARG, null),
BR_ON_CAST_FAIL (0xFB, 0x4F, "br_on_cast_fail", imm.BR_CAST_ARG, null),
ARRAY_INIT_DATA (0xFB, 0x54, "array.init_data", imm.ARRAYT_DATA, null),
ARRAY_INIT_ELEM (0xFB, 0x55, "array.init_elem", imm.ARRAYT_ELEM, null),
EXTERN_INTERNALIZE (0xFB, 0x70, "extern.internalize", imm.NONE, null),
EXTERN_EXTERNALIZE (0xFB, 0x71, "extern.externalize", imm.NONE, null),
STRUCT_NEW (0xFB, 0x00, "struct.new", imm.STRUCTT, null),
STRUCT_NEW_DEFAULT (0xFB, 0x01, "struct.new_default", imm.STRUCTT, null),
STRUCT_GET (0xFB, 0x02, "struct.get", imm.STRUCTT_FIELD, null),
STRUCT_GET_S (0xFB, 0x03, "struct.get_s", imm.STRUCTT_FIELD, null),
STRUCT_GET_U (0xFB, 0x04, "struct.get_u", imm.STRUCTT_FIELD, null),
STRUCT_SET (0xFB, 0x05, "struct.set", imm.STRUCTT_FIELD, null),
ARRAY_NEW (0xFB, 0x06, "array.new", imm.ARRAYT, null),
ARRAY_NEW_DEFAULT (0xFB, 0x07, "array.new_default", imm.ARRAYT, null),
ARRAY_NEW_FIXED (0xFB, 0x08, "array.new_fixed", imm.ARRAYT_U32, null),
ARRAY_NEW_DATA (0xFB, 0x09, "array.new_data", imm.ARRAYT_DATA, null),
ARRAY_NEW_ELEM (0xFB, 0x0A, "array.new_elem", imm.ARRAYT_ELEM, null),

ARRAY_GET (0xFB, 0x0B, "array.get", imm.ARRAYT, null),
ARRAY_GET_S (0xFB, 0x0C, "array.get_s", imm.ARRAYT, null),
ARRAY_GET_U (0xFB, 0x0D, "array.get_u", imm.ARRAYT, null),
ARRAY_SET (0xFB, 0x0E, "array.set", imm.ARRAYT, null),
ARRAY_LEN (0xFB, 0x0F, "array.len", imm.NONE, null),
ARRAY_FILL (0xFB, 0x10, "array.fill", imm.ARRAYT, null),
ARRAY_COPY (0xFB, 0x11, "array.copy", imm.ARRAYT_ARRAYT, null),
ARRAY_INIT_DATA (0xFB, 0x12, "array.init_data", imm.ARRAYT_DATA, null),
ARRAY_INIT_ELEM (0xFB, 0x13, "array.init_elem", imm.ARRAYT_ELEM, null),
REF_TEST (0xFB, 0x14, "ref.test", imm.HEAPT, null),
REF_TEST_NULL (0xFB, 0x15, "ref.test null", imm.HEAPT, null),
REF_CAST (0xFB, 0x16, "ref.cast", imm.HEAPT, null),
REF_CAST_NULL (0xFB, 0x17, "ref.cast null", imm.HEAPT, null),
BR_ON_CAST (0xFB, 0x18, "br_on_cast", imm.BR_CAST_ARG, null),
BR_ON_CAST_FAIL (0xFB, 0x19, "br_on_cast_fail", imm.BR_CAST_ARG, null),
EXTERN_INTERNALIZE (0xFB, 0x1A, "extern.internalize", imm.NONE, null),
EXTERN_EXTERNALIZE (0xFB, 0x1B, "extern.externalize", imm.NONE, null),
I31_NEW (0xFB, 0x1C, "i31.new", imm.NONE, null),
I31_GET_S (0xFB, 0x1D, "i31.get_s", imm.NONE, null),
I31_GET_U (0xFB, 0x1E, "i31.get_u", imm.NONE, null),
// 0xFC prefix: saturating truncations.
I32_TRUNC_SAT_F32_S (0xFC, 0x00, "i32.trunc_sat_f32_s", imm.NONE, sig.f_i),
I32_TRUNC_SAT_F32_U (0xFC, 0x01, "i32.trunc_sat_f32_u", imm.NONE, sig.f_i),
Expand Down
3 changes: 0 additions & 3 deletions src/engine/v3/V3Interpreter.v3
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,6 @@ component V3Interpreter {
}
val_stack.pushn(val, int.!(count));
}
// Execute the given opcode and return {0} if successfully executed. If a breakpoint
// is hit and the state is {RUNNING}, then {-1} is returned. If the state is {RESUME},
// then, the original opcode is returned, encoded into the (nonzero) return value.
def execOp(pc: int, opcode: Opcode) {
match (opcode) {
UNREACHABLE => {
Expand Down
20 changes: 20 additions & 0 deletions src/monitors/IfMonitor.v3
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2023 Wizard Authors. All rights reserved.
// See LICENSE for details of Apache 2.0 license.

// Simply instruments ifs.
class IfMonitor extends Monitor {
def onParse(m: Module) {
var p = CountProbe.new();
var it = BytecodeIterator.new();

for (i < m.functions.length) {
var f = m.functions[i];
if (f.imp != null) continue; // skip imported functions

for (bi = it.reset(f); bi.more(); bi.next()) {
if (bi.current() == Opcode.IF)
Instrumentation.insertProbeAt(m, f.func_index, bi.pc, p);
}
}
}
}
7 changes: 3 additions & 4 deletions test/regress/ext:gc/array_new_fixed.bin.wast
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
(module binary
"\00\61\73\6d\01\00\00\00\01\8c\80\80\80\00\03\5e"
"\7d\00\5e\7d\01\60\00\01\6b\00\03\82\80\80\80\00"
"\7d\00\5e\7d\01\60\00\01\64\00\03\82\80\80\80\00"
"\01\02\07\87\80\80\80\00\01\03\6e\65\77\00\00\0a"
"\9c\80\80\80\00\01\96\80\80\80\00\00\43\00\00\80"
"\3f\43\00\00\00\40\fb\30\00\fb\19\00\02\00\00\00"
"\0b"
"\96\80\80\80\00\01\90\80\80\80\00\00\43\00\00\80"
"\3f\43\00\00\00\40\fb\08\00\02\0b"
)
(assert_return (invoke "new") (ref.array))
2 changes: 1 addition & 1 deletion test/regress/ext:gc/array_new_fixed.wast
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
(type $mvec (array (mut f32)))

(func $new (export "new") (result (ref $vec))
(array.new_fixed $vec 2 (f32.const 1) (f32.const 2) (rtt.canon $vec))
(array.new_fixed $vec 2 (f32.const 1) (f32.const 2))
)
)

Expand Down
142 changes: 142 additions & 0 deletions test/regress/ext:gc/br_on_cast.bin.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
(module binary
"\00\61\73\6d\01\00\00\00\01\a1\80\80\80\00\07\60"
"\00\01\7f\5f\01\77\00\5e\78\00\60\01\6f\00\60\01"
"\7f\01\7f\60\01\6b\01\64\02\60\01\6b\01\64\01\03"
"\88\80\80\80\00\07\00\03\04\04\04\04\04\04\84\80"
"\80\80\00\01\6e\00\0a\07\ca\80\80\80\00\06\04\69"
"\6e\69\74\00\01\0a\62\72\5f\6f\6e\5f\6e\75\6c\6c"
"\00\02\09\62\72\5f\6f\6e\5f\69\33\31\00\03\0c\62"
"\72\5f\6f\6e\5f\73\74\72\75\63\74\00\04\0b\62\72"
"\5f\6f\6e\5f\61\72\72\61\79\00\05\09\6e\75\6c\6c"
"\2d\64\69\66\66\00\06\09\85\80\80\80\00\01\03\00"
"\01\00\0a\d9\81\80\80\00\07\84\80\80\80\00\00\41"
"\09\0b\ac\80\80\80\00\00\41\00\d0\6e\26\00\41\01"
"\41\07\fb\1c\26\00\41\02\41\06\fb\00\01\26\00\41"
"\03\41\05\41\03\fb\06\02\26\00\41\04\20\00\fb\1a"
"\26\00\0b\90\80\80\80\00\00\02\40\20\00\25\00\d5"
"\00\41\7f\0f\0b\41\00\0b\95\80\80\80\00\00\02\64"
"\6c\20\00\25\00\fb\18\01\00\6e\6c\41\7f\0f\0b\fb"
"\1e\0b\b2\80\80\80\00\00\02\64\6b\20\00\25\00\fb"
"\18\01\00\6e\6b\41\7f\0f\0b\02\06\02\05\fb\18\01"
"\01\6b\01\fb\18\01\00\6e\02\41\7e\0f\0b\41\00\fb"
"\0d\02\0f\0b\fb\03\01\00\0b\95\80\80\80\00\00\02"
"\64\6a\20\00\25\00\fb\18\01\00\6e\6a\41\7f\0f\0b"
"\fb\0f\0b\99\80\80\80\00\00\02\6b\02\64\6e\20\00"
"\25\00\fb\18\03\01\6e\6b\0b\41\00\0f\0b\41\01\0f"
"\0b"
)
(invoke "init" (ref.extern 0))
(assert_return (invoke "br_on_null" (i32.const 0x0)) (i32.const 0x0))
(assert_return (invoke "br_on_null" (i32.const 0x1)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_null" (i32.const 0x2)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_null" (i32.const 0x3)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_null" (i32.const 0x4)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_i31" (i32.const 0x0)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_i31" (i32.const 0x1)) (i32.const 0x7))
(assert_return (invoke "br_on_i31" (i32.const 0x2)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_i31" (i32.const 0x3)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_i31" (i32.const 0x4)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_struct" (i32.const 0x0)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_struct" (i32.const 0x1)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_struct" (i32.const 0x2)) (i32.const 0x6))
(assert_return (invoke "br_on_struct" (i32.const 0x3)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_struct" (i32.const 0x4)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_array" (i32.const 0x0)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_array" (i32.const 0x1)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_array" (i32.const 0x2)) (i32.const 0xffff_ffff))
(assert_return (invoke "br_on_array" (i32.const 0x3)) (i32.const 0x3))
(assert_return (invoke "br_on_array" (i32.const 0x4)) (i32.const 0xffff_ffff))
(assert_return (invoke "null-diff" (i32.const 0x0)) (i32.const 0x1))
(assert_return (invoke "null-diff" (i32.const 0x1)) (i32.const 0x0))
(assert_return (invoke "null-diff" (i32.const 0x2)) (i32.const 0x1))
(assert_return (invoke "null-diff" (i32.const 0x3)) (i32.const 0x0))
(assert_return (invoke "null-diff" (i32.const 0x4)) (i32.const 0x0))
(module binary
"\00\61\73\6d\01\00\00\00\01\bf\80\80\80\00\09\50"
"\00\5f\00\50\01\00\5f\01\7f\00\50\01\00\5f\01\7f"
"\00\50\01\01\5f\02\7f\00\7f\00\50\01\02\5f\02\7f"
"\00\7f\00\50\01\00\5f\02\7f\00\7f\00\50\01\00\5f"
"\00\50\01\06\5f\02\7f\00\7f\00\60\00\00\03\84\80"
"\80\80\00\03\08\08\08\04\84\80\80\80\00\01\6b\00"
"\14\07\99\80\80\80\00\02\08\74\65\73\74\2d\73\75"
"\62\00\01\0a\74\65\73\74\2d\63\61\6e\6f\6e\00\02"
"\0a\fe\84\80\80\00\03\ba\80\80\80\00\00\41\00\fb"
"\01\00\26\00\41\0a\fb\01\06\26\00\41\01\fb\01\01"
"\26\00\41\0b\fb\01\02\26\00\41\02\fb\01\03\26\00"
"\41\0c\fb\01\04\26\00\41\03\fb\01\05\26\00\41\04"
"\fb\01\07\26\00\0b\e7\82\80\80\00\00\10\00\02\6b"
"\02\6b\d0\6b\fb\18\01\00\6b\00\0b\1a\02\6b\41\00"
"\25\00\fb\18\01\00\6b\00\0b\1a\02\6b\41\01\25\00"
"\fb\18\01\00\6b\00\0b\1a\02\6b\41\02\25\00\fb\18"
"\01\00\6b\00\0b\1a\02\6b\41\03\25\00\fb\18\01\00"
"\6b\00\0b\1a\02\6b\41\04\25\00\fb\18\01\00\6b\00"
"\0b\1a\02\6b\d0\6b\fb\18\01\00\6b\01\0b\1a\02\6b"
"\41\01\25\00\fb\18\01\00\6b\01\0b\1a\02\6b\41\02"
"\25\00\fb\18\01\00\6b\01\0b\1a\02\6b\d0\6b\fb\18"
"\01\00\6b\03\0b\1a\02\6b\41\02\25\00\fb\18\01\00"
"\6b\03\0b\1a\02\6b\d0\6b\fb\18\01\00\6b\05\0b\1a"
"\02\6b\41\03\25\00\fb\18\01\00\6b\05\0b\1a\02\6b"
"\d0\6b\fb\18\01\00\6b\07\0b\1a\02\6b\41\04\25\00"
"\fb\18\01\00\6b\07\0b\1a\41\00\25\00\fb\18\01\00"
"\6e\01\41\03\25\00\fb\18\01\00\6e\01\41\04\25\00"
"\fb\18\01\00\6e\01\41\00\25\00\fb\18\01\00\6e\03"
"\41\01\25\00\fb\18\01\00\6e\03\41\03\25\00\fb\18"
"\01\00\6e\03\41\04\25\00\fb\18\01\00\6e\03\41\00"
"\25\00\fb\18\01\00\6e\05\41\01\25\00\fb\18\01\00"
"\6e\05\41\02\25\00\fb\18\01\00\6e\05\41\04\25\00"
"\fb\18\01\00\6e\05\41\00\25\00\fb\18\01\00\6e\07"
"\41\01\25\00\fb\18\01\00\6e\07\41\02\25\00\fb\18"
"\01\00\6e\07\41\03\25\00\fb\18\01\00\6e\07\0f\0b"
"\00\0b\cd\81\80\80\00\00\10\00\02\40\02\6b\41\00"
"\25\00\fb\18\01\00\6b\06\0b\1a\02\6b\41\01\25\00"
"\fb\18\01\00\6b\06\0b\1a\02\6b\41\02\25\00\fb\18"
"\01\00\6b\06\0b\1a\02\6b\41\03\25\00\fb\18\01\00"
"\6b\06\0b\1a\02\6b\41\04\25\00\fb\18\01\00\6b\06"
"\0b\1a\02\6b\41\0a\25\00\fb\18\01\00\6b\00\0b\1a"
"\02\6b\41\0b\25\00\fb\18\01\00\6b\00\0b\1a\02\6b"
"\41\0c\25\00\fb\18\01\00\6b\00\0b\1a\02\6b\41\01"
"\25\00\fb\18\01\00\6b\02\0b\1a\02\6b\41\02\25\00"
"\fb\18\01\00\6b\02\0b\1a\02\6b\41\0b\25\00\fb\18"
"\01\00\6b\01\0b\1a\02\6b\41\0c\25\00\fb\18\01\00"
"\6b\01\0b\1a\02\6b\41\02\25\00\fb\18\01\00\6b\04"
"\0b\1a\02\6b\41\0c\25\00\fb\18\01\00\6b\03\0b\1a"
"\0f\0b\00\0b"
)
(invoke "test-sub")
(invoke "test-canon")
(module binary
"\00\61\73\6d\01\00\00\00\01\96\80\80\80\00\04\5f"
"\00\60\01\64\6e\01\64\00\60\01\6e\01\64\00\60\01"
"\6e\01\63\00\03\84\80\80\80\00\03\01\02\03\0a\bb"
"\80\80\80\00\03\8f\80\80\80\00\00\02\64\6e\20\00"
"\fb\18\00\01\6e\00\0b\00\0b\8e\80\80\80\00\00\02"
"\6e\20\00\fb\18\01\01\6e\00\0b\00\0b\8e\80\80\80"
"\00\00\02\6e\20\00\fb\18\03\01\6e\00\0b\00\0b"
)
(assert_invalid
(module binary
"\00\61\73\6d\01\00\00\00\01\8a\80\80\80\00\02\5f"
"\00\60\01\64\6e\01\64\00\03\82\80\80\80\00\01\01"
"\0a\95\80\80\80\00\01\8f\80\80\80\00\00\02\64\6e"
"\20\00\fb\18\03\01\6e\00\0b\00\0b"
)
"type mismatch"
)
(assert_invalid
(module binary
"\00\61\73\6d\01\00\00\00\01\8a\80\80\80\00\02\5f"
"\00\60\01\64\6e\01\63\00\03\82\80\80\80\00\01\01"
"\0a\95\80\80\80\00\01\8f\80\80\80\00\00\02\64\6e"
"\20\00\fb\18\02\01\6e\00\0b\00\0b"
)
"type mismatch"
)
(assert_invalid
(module binary
"\00\61\73\6d\01\00\00\00\01\89\80\80\80\00\02\5f"
"\00\60\01\6e\01\64\00\03\82\80\80\80\00\01\01\0a"
"\95\80\80\80\00\01\8f\80\80\80\00\00\02\64\6e\20"
"\00\fb\18\01\01\6e\00\0b\00\0b"
)
"type mismatch"
)
Loading

0 comments on commit 0d6926f

Please sign in to comment.