summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interp/binary-reader-interp.cc1
-rw-r--r--src/type-checker.cc26
-rw-r--r--src/type-checker.h5
-rw-r--r--src/validator.cc5
-rw-r--r--test/spec/reference-types/br_table.txt72
-rw-r--r--test/spec/reference-types/unreached-invalid.txt2
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]