diff options
Diffstat (limited to 'src/passes/InstrumentLocals.cpp')
-rw-r--r-- | src/passes/InstrumentLocals.cpp | 167 |
1 files changed, 65 insertions, 102 deletions
diff --git a/src/passes/InstrumentLocals.cpp b/src/passes/InstrumentLocals.cpp index 3bf23b61c..761aac2a9 100644 --- a/src/passes/InstrumentLocals.cpp +++ b/src/passes/InstrumentLocals.cpp @@ -58,9 +58,6 @@ Name get_f64("get_f64"); Name get_v128("get_v128"); Name get_funcref("get_funcref"); Name get_anyref("get_anyref"); -Name get_eqref("get_eqref"); -Name get_i31ref("get_i31ref"); -Name get_dataref("get_dataref"); Name set_i32("set_i32"); Name set_i64("set_i64"); @@ -69,48 +66,41 @@ Name set_f64("set_f64"); Name set_v128("set_v128"); Name set_funcref("set_funcref"); Name set_anyref("set_anyref"); -Name set_eqref("set_eqref"); -Name set_i31ref("set_i31ref"); -Name set_dataref("set_dataref"); struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> { void visitLocalGet(LocalGet* curr) { Builder builder(*getModule()); Name import; - TODO_SINGLE_COMPOUND(curr->type); - switch (curr->type.getBasic()) { - case Type::i32: - import = get_i32; - break; - case Type::i64: - return; // TODO - case Type::f32: - import = get_f32; - break; - case Type::f64: - import = get_f64; - break; - case Type::v128: - import = get_v128; - break; - case Type::funcref: + if (curr->type.isRef()) { + auto heapType = curr->type.getHeapType(); + if (heapType == HeapType::func && curr->type.isNullable()) { import = get_funcref; - break; - case Type::anyref: + } else if (heapType == HeapType::any && curr->type.isNullable()) { import = get_anyref; - break; - case Type::eqref: - import = get_eqref; - break; - case Type::i31ref: - import = get_i31ref; - break; - case Type::dataref: - import = get_dataref; - break; - case Type::none: - case Type::unreachable: - WASM_UNREACHABLE("unexpected type"); + } else { + WASM_UNREACHABLE("TODO: general reference types"); + } + } else { + TODO_SINGLE_COMPOUND(curr->type); + switch (curr->type.getBasic()) { + case Type::i32: + import = get_i32; + break; + case Type::i64: + return; // TODO + case Type::f32: + import = get_f32; + break; + case Type::f64: + import = get_f64; + break; + case Type::v128: + import = get_v128; + break; + case Type::none: + case Type::unreachable: + WASM_UNREACHABLE("unexpected type"); + } } replaceCurrent(builder.makeCall(import, {builder.makeConst(int32_t(id++)), @@ -130,45 +120,41 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> { Builder builder(*getModule()); Name import; auto type = curr->value->type; - if (type.isFunction() && type != Type::funcref) { + if (type.isFunction() && type.getHeapType() != HeapType::func) { // FIXME: support typed function references return; } - TODO_SINGLE_COMPOUND(curr->value->type); - switch (type.getBasic()) { - case Type::i32: - import = set_i32; - break; - case Type::i64: - return; // TODO - case Type::f32: - import = set_f32; - break; - case Type::f64: - import = set_f64; - break; - case Type::v128: - import = set_v128; - break; - case Type::funcref: + if (type.isRef()) { + auto heapType = type.getHeapType(); + if (heapType == HeapType::func && type.isNullable()) { import = set_funcref; - break; - case Type::anyref: + } else if (heapType == HeapType::any && type.isNullable()) { import = set_anyref; - break; - case Type::eqref: - import = set_eqref; - break; - case Type::i31ref: - import = set_i31ref; - break; - case Type::dataref: - import = set_dataref; - break; - case Type::unreachable: - return; // nothing to do here - default: - WASM_UNREACHABLE("unexpected type"); + } else { + WASM_UNREACHABLE("TODO: general reference types"); + } + } else { + TODO_SINGLE_COMPOUND(curr->value->type); + switch (type.getBasic()) { + case Type::i32: + import = set_i32; + break; + case Type::i64: + return; // TODO + case Type::f32: + import = set_f32; + break; + case Type::f64: + import = set_f64; + break; + case Type::v128: + import = set_v128; + break; + case Type::unreachable: + return; // nothing to do here + case Type::none: + WASM_UNREACHABLE("unexpected type"); + } } curr->value = builder.makeCall(import, {builder.makeConst(int32_t(id++)), @@ -188,36 +174,13 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> { addImport(curr, set_f64, {Type::i32, Type::i32, Type::f64}, Type::f64); if (curr->features.hasReferenceTypes()) { - addImport(curr, - get_funcref, - {Type::i32, Type::i32, Type::funcref}, - Type::funcref); - addImport(curr, - set_funcref, - {Type::i32, Type::i32, Type::funcref}, - Type::funcref); - addImport( - curr, get_anyref, {Type::i32, Type::i32, Type::anyref}, Type::anyref); - addImport( - curr, set_anyref, {Type::i32, Type::i32, Type::anyref}, Type::anyref); - if (curr->features.hasGC()) { - addImport( - curr, get_eqref, {Type::i32, Type::i32, Type::eqref}, Type::eqref); - addImport( - curr, set_eqref, {Type::i32, Type::i32, Type::eqref}, Type::eqref); - addImport( - curr, get_i31ref, {Type::i32, Type::i32, Type::i31ref}, Type::i31ref); - addImport( - curr, set_i31ref, {Type::i32, Type::i32, Type::i31ref}, Type::i31ref); - addImport(curr, - get_dataref, - {Type::i32, Type::i32, Type::dataref}, - Type::dataref); - addImport(curr, - set_dataref, - {Type::i32, Type::i32, Type::dataref}, - Type::dataref); - } + Type func = Type(HeapType::func, Nullable); + Type any = Type(HeapType::any, Nullable); + + addImport(curr, get_funcref, {Type::i32, Type::i32, func}, func); + addImport(curr, set_funcref, {Type::i32, Type::i32, func}, func); + addImport(curr, get_anyref, {Type::i32, Type::i32, any}, any); + addImport(curr, set_anyref, {Type::i32, Type::i32, any}, any); } if (curr->features.hasSIMD()) { addImport(curr, get_v128, {Type::i32, Type::i32, Type::v128}, Type::v128); |