diff --git a/include/wabt/type-checker.h b/include/wabt/type-checker.h index 3600212a83..6bff08b881 100644 --- a/include/wabt/type-checker.h +++ b/include/wabt/type-checker.h @@ -97,12 +97,16 @@ class TypeChecker { Result OnCallIndirect(const TypeVector& param_types, const TypeVector& result_types, const Limits& table_limits); - Result OnCallRef(Type); + Result OnCallRef(Type type, + const TypeVector& param_types, + const TypeVector& result_types); Result OnReturnCall(const TypeVector& param_types, const TypeVector& result_types); Result OnReturnCallIndirect(const TypeVector& param_types, const TypeVector& result_types); - Result OnReturnCallRef(Type); + Result OnReturnCallRef(Type type, + const TypeVector& param_types, + const TypeVector& result_types); Result OnCatch(const TypeVector& sig); Result OnCompare(Opcode); Result OnConst(Type); @@ -191,6 +195,8 @@ class TypeChecker { Result PopAndCheckCall(const TypeVector& param_types, const TypeVector& result_types, const char* desc); + Result PopAndCheckReturnCall(const TypeVector& result_types, + const char* desc); Result PopAndCheck1Type(Type expected, const char* desc); Result PopAndCheck2Types(Type expected1, Type expected2, const char* desc); Result PopAndCheck3Types(Type expected1, diff --git a/src/apply-names.cc b/src/apply-names.cc index ab91fa42a4..95cf20d560 100644 --- a/src/apply-names.cc +++ b/src/apply-names.cc @@ -98,6 +98,7 @@ class NameApplier : public ExprVisitor::DelegateNop { Result UseNameForDataSegmentVar(Var* var); Result UseNameForElemSegmentVar(Var* var); Result UseNameForParamAndLocalVar(Func* func, Var* var); + Result UseNameForLabelVar(Var* var); Result VisitFunc(Index func_index, Func* func); Result VisitGlobal(Global* global); Result VisitTag(Tag* tag); @@ -242,6 +243,12 @@ Result NameApplier::UseNameForParamAndLocalVar(Func* func, Var* var) { return Result::Ok; } +Result NameApplier::UseNameForLabelVar(Var* var) { + std::string_view label = FindLabelByVar(var); + UseNameForVar(label, var); + return Result::Ok; +} + Result NameApplier::BeginBlockExpr(BlockExpr* expr) { PushLabel(expr->block.label); return Result::Ok; @@ -263,117 +270,91 @@ Result NameApplier::EndLoopExpr(LoopExpr* expr) { } Result NameApplier::OnDataDropExpr(DataDropExpr* expr) { - CHECK_RESULT(UseNameForDataSegmentVar(&expr->var)); - return Result::Ok; + return UseNameForDataSegmentVar(&expr->var); } Result NameApplier::OnMemoryCopyExpr(MemoryCopyExpr* expr) { CHECK_RESULT(UseNameForMemoryVar(&expr->destmemidx)); - CHECK_RESULT(UseNameForMemoryVar(&expr->srcmemidx)); - return Result::Ok; + return UseNameForMemoryVar(&expr->srcmemidx); } Result NameApplier::OnMemoryFillExpr(MemoryFillExpr* expr) { - CHECK_RESULT(UseNameForMemoryVar(&expr->memidx)); - return Result::Ok; + return UseNameForMemoryVar(&expr->memidx); } Result NameApplier::OnMemoryGrowExpr(MemoryGrowExpr* expr) { - CHECK_RESULT(UseNameForMemoryVar(&expr->memidx)); - return Result::Ok; + return UseNameForMemoryVar(&expr->memidx); } Result NameApplier::OnMemoryInitExpr(MemoryInitExpr* expr) { CHECK_RESULT(UseNameForDataSegmentVar(&expr->var)); - CHECK_RESULT(UseNameForMemoryVar(&expr->memidx)); - return Result::Ok; + return UseNameForMemoryVar(&expr->memidx); } Result NameApplier::OnMemorySizeExpr(MemorySizeExpr* expr) { - CHECK_RESULT(UseNameForMemoryVar(&expr->memidx)); - return Result::Ok; + return UseNameForMemoryVar(&expr->memidx); } Result NameApplier::OnElemDropExpr(ElemDropExpr* expr) { - CHECK_RESULT(UseNameForElemSegmentVar(&expr->var)); - return Result::Ok; + return UseNameForElemSegmentVar(&expr->var); } Result NameApplier::OnTableCopyExpr(TableCopyExpr* expr) { CHECK_RESULT(UseNameForTableVar(&expr->dst_table)); - CHECK_RESULT(UseNameForTableVar(&expr->src_table)); - return Result::Ok; + return UseNameForTableVar(&expr->src_table); } Result NameApplier::OnTableInitExpr(TableInitExpr* expr) { CHECK_RESULT(UseNameForElemSegmentVar(&expr->segment_index)); - CHECK_RESULT(UseNameForTableVar(&expr->table_index)); - return Result::Ok; + return UseNameForTableVar(&expr->table_index); } Result NameApplier::OnTableGetExpr(TableGetExpr* expr) { - CHECK_RESULT(UseNameForTableVar(&expr->var)); - return Result::Ok; + return UseNameForTableVar(&expr->var); } Result NameApplier::OnTableSetExpr(TableSetExpr* expr) { - CHECK_RESULT(UseNameForTableVar(&expr->var)); - return Result::Ok; + return UseNameForTableVar(&expr->var); } Result NameApplier::OnTableGrowExpr(TableGrowExpr* expr) { - CHECK_RESULT(UseNameForTableVar(&expr->var)); - return Result::Ok; + return UseNameForTableVar(&expr->var); } Result NameApplier::OnTableSizeExpr(TableSizeExpr* expr) { - CHECK_RESULT(UseNameForTableVar(&expr->var)); - return Result::Ok; + return UseNameForTableVar(&expr->var); } Result NameApplier::OnTableFillExpr(TableFillExpr* expr) { - CHECK_RESULT(UseNameForTableVar(&expr->var)); - return Result::Ok; + return UseNameForTableVar(&expr->var); } Result NameApplier::OnStoreExpr(StoreExpr* expr) { - CHECK_RESULT(UseNameForMemoryVar(&expr->memidx)); - return Result::Ok; + return UseNameForMemoryVar(&expr->memidx); } Result NameApplier::OnBrExpr(BrExpr* expr) { - std::string_view label = FindLabelByVar(&expr->var); - UseNameForVar(label, &expr->var); - return Result::Ok; + return UseNameForLabelVar(&expr->var); } Result NameApplier::OnBrIfExpr(BrIfExpr* expr) { - std::string_view label = FindLabelByVar(&expr->var); - UseNameForVar(label, &expr->var); - return Result::Ok; + return UseNameForLabelVar(&expr->var); } Result NameApplier::OnBrOnNonNullExpr(BrOnNonNullExpr* expr) { - std::string_view label = FindLabelByVar(&expr->var); - UseNameForVar(label, &expr->var); - return Result::Ok; + return UseNameForLabelVar(&expr->var); } Result NameApplier::OnBrOnNullExpr(BrOnNullExpr* expr) { - std::string_view label = FindLabelByVar(&expr->var); - UseNameForVar(label, &expr->var); - return Result::Ok; + return UseNameForLabelVar(&expr->var); } Result NameApplier::OnBrTableExpr(BrTableExpr* expr) { for (Var& target : expr->targets) { - std::string_view label = FindLabelByVar(&target); - UseNameForVar(label, &target); + UseNameForLabelVar(&target); } - std::string_view label = FindLabelByVar(&expr->default_target); - UseNameForVar(label, &expr->default_target); - return Result::Ok; + return UseNameForLabelVar(&expr->default_target); } Result NameApplier::BeginTryExpr(TryExpr* expr) { @@ -391,8 +372,7 @@ Result NameApplier::BeginTryTableExpr(TryTableExpr* expr) { if (!catch_.IsCatchAll()) { CHECK_RESULT(UseNameForTagVar(&catch_.tag)); } - std::string_view label = FindLabelByVar(&catch_.target); - UseNameForVar(label, &catch_.target); + UseNameForLabelVar(&catch_.target); } PushLabel(expr->block.label); return Result::Ok; @@ -412,61 +392,49 @@ Result NameApplier::OnCatchExpr(TryExpr*, Catch* expr) { Result NameApplier::OnDelegateExpr(TryExpr* expr) { PopLabel(); - std::string_view label = FindLabelByVar(&expr->delegate_target); - UseNameForVar(label, &expr->delegate_target); - return Result::Ok; + return UseNameForLabelVar(&expr->delegate_target); } Result NameApplier::OnThrowExpr(ThrowExpr* expr) { - CHECK_RESULT(UseNameForTagVar(&expr->var)); - return Result::Ok; + return UseNameForTagVar(&expr->var); } Result NameApplier::OnRethrowExpr(RethrowExpr* expr) { - std::string_view label = FindLabelByVar(&expr->var); - UseNameForVar(label, &expr->var); - return Result::Ok; + return UseNameForLabelVar(&expr->var); } Result NameApplier::OnCallExpr(CallExpr* expr) { - CHECK_RESULT(UseNameForFuncVar(&expr->var)); - return Result::Ok; + return UseNameForFuncVar(&expr->var); } Result NameApplier::OnRefFuncExpr(RefFuncExpr* expr) { - CHECK_RESULT(UseNameForFuncVar(&expr->var)); - return Result::Ok; + return UseNameForFuncVar(&expr->var); } Result NameApplier::OnCallIndirectExpr(CallIndirectExpr* expr) { if (expr->decl.has_func_type) { CHECK_RESULT(UseNameForFuncTypeVar(&expr->decl.type_var)); } - CHECK_RESULT(UseNameForTableVar(&expr->table)); - return Result::Ok; + return UseNameForTableVar(&expr->table); } Result NameApplier::OnReturnCallExpr(ReturnCallExpr* expr) { - CHECK_RESULT(UseNameForFuncVar(&expr->var)); - return Result::Ok; + return UseNameForFuncVar(&expr->var); } Result NameApplier::OnReturnCallIndirectExpr(ReturnCallIndirectExpr* expr) { if (expr->decl.has_func_type) { CHECK_RESULT(UseNameForFuncTypeVar(&expr->decl.type_var)); } - CHECK_RESULT(UseNameForTableVar(&expr->table)); - return Result::Ok; + return UseNameForTableVar(&expr->table); } Result NameApplier::OnGlobalGetExpr(GlobalGetExpr* expr) { - CHECK_RESULT(UseNameForGlobalVar(&expr->var)); - return Result::Ok; + return UseNameForGlobalVar(&expr->var); } Result NameApplier::OnLocalGetExpr(LocalGetExpr* expr) { - CHECK_RESULT(UseNameForParamAndLocalVar(current_func_, &expr->var)); - return Result::Ok; + return UseNameForParamAndLocalVar(current_func_, &expr->var); } Result NameApplier::BeginIfExpr(IfExpr* expr) { @@ -480,33 +448,27 @@ Result NameApplier::EndIfExpr(IfExpr* expr) { } Result NameApplier::OnLoadExpr(LoadExpr* expr) { - CHECK_RESULT(UseNameForMemoryVar(&expr->memidx)); - return Result::Ok; + return UseNameForMemoryVar(&expr->memidx); } Result NameApplier::OnGlobalSetExpr(GlobalSetExpr* expr) { - CHECK_RESULT(UseNameForGlobalVar(&expr->var)); - return Result::Ok; + return UseNameForGlobalVar(&expr->var); } Result NameApplier::OnLocalSetExpr(LocalSetExpr* expr) { - CHECK_RESULT(UseNameForParamAndLocalVar(current_func_, &expr->var)); - return Result::Ok; + return UseNameForParamAndLocalVar(current_func_, &expr->var); } Result NameApplier::OnLocalTeeExpr(LocalTeeExpr* expr) { - CHECK_RESULT(UseNameForParamAndLocalVar(current_func_, &expr->var)); - return Result::Ok; + return UseNameForParamAndLocalVar(current_func_, &expr->var); } Result NameApplier::OnSimdLoadLaneExpr(SimdLoadLaneExpr* expr) { - CHECK_RESULT(UseNameForMemoryVar(&expr->memidx)); - return Result::Ok; + return UseNameForMemoryVar(&expr->memidx); } Result NameApplier::OnSimdStoreLaneExpr(SimdStoreLaneExpr* expr) { - CHECK_RESULT(UseNameForMemoryVar(&expr->memidx)); - return Result::Ok; + return UseNameForMemoryVar(&expr->memidx); } Result NameApplier::VisitFunc(Index func_index, Func* func) { @@ -524,8 +486,7 @@ Result NameApplier::VisitFunc(Index func_index, Func* func) { } Result NameApplier::VisitGlobal(Global* global) { - CHECK_RESULT(visitor_.VisitExprList(global->init_expr)); - return Result::Ok; + return visitor_.VisitExprList(global->init_expr); } Result NameApplier::VisitTag(Tag* tag) { @@ -561,8 +522,7 @@ Result NameApplier::VisitExport(Index export_index, Export* export_) { } Result NameApplier::VisitTable(Table* table) { - CHECK_RESULT(visitor_.VisitExprList(table->init_expr)); - return Result::Ok; + return visitor_.VisitExprList(table->init_expr); } Result NameApplier::VisitElemSegment(Index elem_segment_index, @@ -581,13 +541,11 @@ Result NameApplier::VisitElemSegment(Index elem_segment_index, Result NameApplier::VisitDataSegment(Index data_segment_index, DataSegment* segment) { CHECK_RESULT(UseNameForMemoryVar(&segment->memory_var)); - CHECK_RESULT(visitor_.VisitExprList(segment->offset)); - return Result::Ok; + return visitor_.VisitExprList(segment->offset); } Result NameApplier::VisitStart(Var* start_var) { - CHECK_RESULT(UseNameForFuncVar(start_var)); - return Result::Ok; + return UseNameForFuncVar(start_var); } Result NameApplier::VisitModule(Module* module) { diff --git a/src/shared-validator.cc b/src/shared-validator.cc index aa18ba4f26..cb0aa5a618 100644 --- a/src/shared-validator.cc +++ b/src/shared-validator.cc @@ -851,9 +851,9 @@ Result SharedValidator::OnCallIndirect(const Location& loc, Result SharedValidator::OnCallRef(const Location& loc, Var function_type_var) { Result result = CheckInstr(Opcode::CallRef, loc); FuncType func_type; - result |= typechecker_.OnCallRef(function_type_var.to_type()); result |= CheckFuncTypeIndex(function_type_var, &func_type); - result |= typechecker_.OnCall(func_type.params, func_type.results); + result |= typechecker_.OnCallRef(function_type_var.to_type(), + func_type.params, func_type.results); return result; } @@ -1218,9 +1218,9 @@ Result SharedValidator::OnReturnCallRef(const Location& loc, Var function_type_var) { Result result = CheckInstr(Opcode::ReturnCallRef, loc); FuncType func_type; - result |= typechecker_.OnReturnCallRef(function_type_var.to_type()); result |= CheckFuncTypeIndex(function_type_var, &func_type); - result |= typechecker_.OnReturnCall(func_type.params, func_type.results); + result |= typechecker_.OnReturnCallRef(function_type_var.to_type(), + func_type.params, func_type.results); return result; } diff --git a/src/type-checker.cc b/src/type-checker.cc index c13e3ad4de..cb280251b6 100644 --- a/src/type-checker.cc +++ b/src/type-checker.cc @@ -372,6 +372,17 @@ Result TypeChecker::PopAndCheckCall(const TypeVector& param_types, return result; } +Result TypeChecker::PopAndCheckReturnCall(const TypeVector& result_types, + const char* desc) { + Label* func_label; + CHECK_RESULT(GetThisFunctionLabel(&func_label)); + Result result = + CheckReturnSignature(result_types, func_label->result_types, desc); + + CHECK_RESULT(SetUnreachable()); + return result; +} + Result TypeChecker::PopAndCheck1Type(Type expected, const char* desc) { Result result = Result::Ok; result |= PeekAndCheckType(0, expected); @@ -658,19 +669,18 @@ Result TypeChecker::OnCallIndirect(const TypeVector& param_types, return result; } -Result TypeChecker::OnCallRef(Type type) { - return PopAndCheck1Type(type, "call_ref"); +Result TypeChecker::OnCallRef(Type type, + const TypeVector& param_types, + const TypeVector& result_types) { + Result result = PopAndCheck1Type(type, "call_ref"); + result |= PopAndCheckCall(param_types, result_types, "call_ref"); + return result; } Result TypeChecker::OnReturnCall(const TypeVector& param_types, const TypeVector& result_types) { Result result = PopAndCheckSignature(param_types, "return_call"); - Label* func_label; - CHECK_RESULT(GetThisFunctionLabel(&func_label)); - result |= CheckReturnSignature(result_types, func_label->result_types, - "return_call"); - - CHECK_RESULT(SetUnreachable()); + result |= PopAndCheckReturnCall(result_types, "return_call"); return result; } @@ -679,17 +689,18 @@ Result TypeChecker::OnReturnCallIndirect(const TypeVector& param_types, Result result = PopAndCheck1Type(Type::I32, "return_call_indirect"); result |= PopAndCheckSignature(param_types, "return_call_indirect"); - Label* func_label; - CHECK_RESULT(GetThisFunctionLabel(&func_label)); - result |= CheckReturnSignature(result_types, func_label->result_types, - "return_call_indirect"); - - CHECK_RESULT(SetUnreachable()); + result |= PopAndCheckReturnCall(result_types, "return_call_indirect"); return result; } -Result TypeChecker::OnReturnCallRef(Type type) { - return PopAndCheck1Type(type, "return_call_ref"); +Result TypeChecker::OnReturnCallRef(Type type, + const TypeVector& param_types, + const TypeVector& result_types) { + Result result = PopAndCheck1Type(type, "return_call_ref"); + + result |= PopAndCheckSignature(param_types, "return_call_ref"); + result |= PopAndCheckReturnCall(result_types, "return_call_ref"); + return result; } Result TypeChecker::OnCompare(Opcode opcode) { diff --git a/test/parse/bad-call-ref.txt b/test/parse/bad-call-ref.txt new file mode 100644 index 0000000000..24a7f08a7e --- /dev/null +++ b/test/parse/bad-call-ref.txt @@ -0,0 +1,35 @@ +;;; TOOL: wat2wasm +;;; ARGS: --enable-function-references +;;; ERROR: 1 +(module + ;; Implicit type declarations are not allowed + (type $t0 (func (param f32 f32))) + + (func $f1 + i32.const 1 + i32.const 2 + i32.const 3 + call_ref $t0 + ) + + (func $f2 + i32.const 1 + i32.const 2 + i32.const 3 + return_call_ref $t0 + ) +) +(;; STDERR ;;; +out/test/parse/bad-call-ref.txt:12:5: error: type mismatch in call_ref, expected [(ref null 0)] but got [... i32] + call_ref $t0 + ^^^^^^^^ +out/test/parse/bad-call-ref.txt:12:5: error: type mismatch in call_ref, expected [f32, f32] but got [i32, i32] + call_ref $t0 + ^^^^^^^^ +out/test/parse/bad-call-ref.txt:19:5: error: type mismatch in return_call_ref, expected [(ref null 0)] but got [... i32] + return_call_ref $t0 + ^^^^^^^^^^^^^^^ +out/test/parse/bad-call-ref.txt:19:5: error: type mismatch in return_call_ref, expected [f32, f32] but got [i32, i32] + return_call_ref $t0 + ^^^^^^^^^^^^^^^ +;;; STDERR ;;) diff --git a/test/spec/function-references/call_ref.txt b/test/spec/function-references/call_ref.txt index b664ef249c..9c58e0d411 100644 --- a/test/spec/function-references/call_ref.txt +++ b/test/spec/function-references/call_ref.txt @@ -7,7 +7,7 @@ out/test/spec/function-references/call_ref.wast:136: assert_trap passed: unreach out/test/spec/function-references/call_ref.wast:149: assert_trap passed: unreachable executed out/test/spec/function-references/call_ref.wast:165: assert_trap passed: unreachable executed out/test/spec/function-references/call_ref.wast:168: assert_invalid passed: - out/test/spec/function-references/call_ref/call_ref.4.wasm:0000042: error: type mismatch in call, expected [i32] but got [i64] + out/test/spec/function-references/call_ref/call_ref.4.wasm:0000042: error: type mismatch in call_ref, expected [i32] but got [i64] 0000042: error: OnCallRefExpr callback failed out/test/spec/function-references/call_ref.wast:184: assert_invalid passed: out/test/spec/function-references/call_ref/call_ref.5.wasm:0000044: error: type mismatch in implicit return, expected [i32] but got [i64] diff --git a/test/spec/function-references/return_call_ref.txt b/test/spec/function-references/return_call_ref.txt index 7d32cd582a..3ea8c1600f 100644 --- a/test/spec/function-references/return_call_ref.txt +++ b/test/spec/function-references/return_call_ref.txt @@ -26,7 +26,7 @@ out/test/spec/function-references/return_call_ref.wast:306: assert_trap passed: out/test/spec/function-references/return_call_ref.wast:319: assert_trap passed: unreachable executed out/test/spec/function-references/return_call_ref.wast:334: assert_trap passed: unreachable executed out/test/spec/function-references/return_call_ref.wast:337: assert_invalid passed: - out/test/spec/function-references/return_call_ref/return_call_ref.11.wasm:0000042: error: type mismatch in return_call, expected [i32] but got [i64] + out/test/spec/function-references/return_call_ref/return_call_ref.11.wasm:0000042: error: type mismatch in return_call_ref, expected [i32] but got [i64] 0000042: error: OnReturnCallRefExpr callback failed out/test/spec/function-references/return_call_ref.wast:353: assert_invalid passed: out/test/spec/function-references/return_call_ref/return_call_ref.12.wasm:0000043: error: type mismatch in implicit return, expected [i32] but got [i64]