diff options
-rw-r--r-- | src/interp/binary-reader-interp.cc | 1 | ||||
-rw-r--r-- | src/type-checker.cc | 26 | ||||
-rw-r--r-- | src/type-checker.h | 5 | ||||
-rw-r--r-- | src/validator.cc | 5 | ||||
-rw-r--r-- | test/spec/reference-types/br_table.txt | 72 | ||||
-rw-r--r-- | test/spec/reference-types/unreached-invalid.txt | 2 |
6 files changed, 98 insertions, 13 deletions
diff --git a/src/interp/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc index 74d4b9ef..3f270abf 100644 --- a/src/interp/binary-reader-interp.cc +++ b/src/interp/binary-reader-interp.cc @@ -369,6 +369,7 @@ BinaryReaderInterp::BinaryReaderInterp(Environment* env, errors_(errors), env_(env), module_(module), + typechecker_(features), istream_(std::move(istream)), istream_offset_(istream_.output_buffer().size()) { typechecker_.set_error_callback( diff --git a/src/type-checker.cc b/src/type-checker.cc index 5cd9330a..0ec787a5 100644 --- a/src/type-checker.cc +++ b/src/type-checker.cc @@ -51,9 +51,6 @@ TypeChecker::Label::Label(LabelType label_type, type_stack_limit(limit), unreachable(false) {} -TypeChecker::TypeChecker(const ErrorCallback& error_callback) - : error_callback_(error_callback) {} - void TypeChecker::PrintError(const char* fmt, ...) { if (error_callback_) { WABT_SNPRINTF_ALLOCA(buffer, length, fmt); @@ -436,12 +433,23 @@ Result TypeChecker::OnBrTableTarget(Index depth) { // signatures. if (br_table_sig_ == nullptr) { br_table_sig_ = &label_sig; - } - if (*br_table_sig_ != label_sig) { - result |= Result::Error; - PrintError("br_table labels have inconsistent types: expected %s, got %s", - TypesToString(*br_table_sig_).c_str(), - TypesToString(label_sig).c_str()); + } else { + if (features_.reference_types_enabled()) { + if (br_table_sig_->size() != label_sig.size()) { + result |= Result::Error; + PrintError("br_table labels have inconsistent arity: expected %" PRIzd + " got %" PRIzd, + br_table_sig_->size(), label_sig.size()); + } + } else { + if (*br_table_sig_ != label_sig) { + result |= Result::Error; + PrintError( + "br_table labels have inconsistent types: expected %s, got %s", + TypesToString(*br_table_sig_).c_str(), + TypesToString(label_sig).c_str()); + } + } } return result; diff --git a/src/type-checker.h b/src/type-checker.h index 49f1de83..d33d9b7e 100644 --- a/src/type-checker.h +++ b/src/type-checker.h @@ -21,6 +21,7 @@ #include <vector> #include "src/common.h" +#include "src/feature.h" #include "src/opcode.h" namespace wabt { @@ -46,8 +47,7 @@ class TypeChecker { bool unreachable; }; - TypeChecker() = default; - explicit TypeChecker(const ErrorCallback&); + explicit TypeChecker(const Features& features) : features_(features) {} void set_error_callback(const ErrorCallback& error_callback) { error_callback_ = error_callback; @@ -177,6 +177,7 @@ class TypeChecker { // Cache the expected br_table signature. It will be initialized to `nullptr` // to represent "any". TypeVector* br_table_sig_ = nullptr; + Features features_; }; } // namespace wabt diff --git a/src/validator.cc b/src/validator.cc index d8ac6666..5978275d 100644 --- a/src/validator.cc +++ b/src/validator.cc @@ -228,7 +228,10 @@ class Validator : public ExprVisitor::Delegate { Validator::Validator(Errors* errors, const Script* script, const ValidateOptions& options) - : options_(options), errors_(errors), script_(script) { + : options_(options), + errors_(errors), + script_(script), + typechecker_(options.features) { typechecker_.set_error_callback( [this](const char* msg) { OnTypecheckerError(msg); }); } diff --git a/test/spec/reference-types/br_table.txt b/test/spec/reference-types/br_table.txt new file mode 100644 index 00000000..34c1784a --- /dev/null +++ b/test/spec/reference-types/br_table.txt @@ -0,0 +1,72 @@ +;;; TOOL: run-interp-spec +;;; STDIN_FILE: third_party/testsuite/proposals/reference-types/br_table.wast +;;; ARGS*: --enable-reference-types +(;; STDOUT ;;; +out/test/spec/reference-types/br_table.wast:1498: assert_invalid passed: + error: type mismatch in block, expected [] but got [i32] + 0000022: error: OnEndExpr callback failed +out/test/spec/reference-types/br_table.wast:1505: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [] + 000001d: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1512: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [] + 0000020: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1518: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [i64] + 0000023: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1526: assert_invalid passed: + error: br_table labels have inconsistent arity: expected 1 got 0 + 0000026: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1538: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [] + 000001f: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1544: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [i64] + 000001e: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1550: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [] + 0000021: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1556: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [] + 0000023: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1562: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [... i64] + 0000022: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1571: assert_invalid passed: + error: type mismatch in block, expected [] but got [i32] + 0000022: error: OnEndExpr callback failed +out/test/spec/reference-types/br_table.wast:1578: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [] + 0000022: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1590: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [] + 0000024: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1602: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [] + 000001c: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1613: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [] + 000001e: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1625: assert_invalid passed: + error: type mismatch in br_table, expected [i32] but got [nullref] + 0000025: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1639: assert_invalid passed: + error: invalid depth: 2 (max 1) + 000001f: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1645: assert_invalid passed: + error: invalid depth: 5 (max 2) + 0000021: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1651: assert_invalid passed: + error: invalid depth: 268435457 (max 1) + 0000024: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1658: assert_invalid passed: + error: invalid depth: 2 (max 1) + 000001f: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1664: assert_invalid passed: + error: invalid depth: 5 (max 2) + 0000021: error: OnBrTableExpr callback failed +out/test/spec/reference-types/br_table.wast:1670: assert_invalid passed: + error: invalid depth: 268435457 (max 1) + 0000024: error: OnBrTableExpr callback failed +183/183 tests passed. +;;; STDOUT ;;) diff --git a/test/spec/reference-types/unreached-invalid.txt b/test/spec/reference-types/unreached-invalid.txt index ff00cf7f..3eadf431 100644 --- a/test/spec/reference-types/unreached-invalid.txt +++ b/test/spec/reference-types/unreached-invalid.txt @@ -262,7 +262,7 @@ out/test/spec/reference-types/unreached-invalid.wast:521: assert_invalid passed: error: type mismatch in br_table, expected [i32] but got [f32] 0000025: error: OnBrTableExpr callback failed out/test/spec/reference-types/unreached-invalid.wast:527: assert_invalid passed: - error: br_table labels have inconsistent types: expected [f32], got [] + error: br_table labels have inconsistent arity: expected 1 got 0 0000023: error: OnBrTableExpr callback failed out/test/spec/reference-types/unreached-invalid.wast:540: assert_invalid passed: error: type mismatch in block, expected [] but got [i32] |