summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binary-reader-ir.cc8
-rw-r--r--src/binary-reader-logging.cc9
-rw-r--r--src/binary-reader-logging.h2
-rw-r--r--src/binary-reader-nop.h4
-rw-r--r--src/binary-reader.cc25
-rw-r--r--src/binary-reader.h2
-rw-r--r--src/interp/binary-reader-interp.cc7
-rw-r--r--src/shared-validator.cc12
-rw-r--r--src/shared-validator.h2
-rw-r--r--src/type-checker.cc9
-rw-r--r--src/type-checker.h2
-rw-r--r--src/validator.cc9
12 files changed, 55 insertions, 36 deletions
diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc
index 58636e88..b59598c4 100644
--- a/src/binary-reader-ir.cc
+++ b/src/binary-reader-ir.cc
@@ -189,7 +189,7 @@ class BinaryReaderIR : public BinaryReaderNop {
Result OnNopExpr() override;
Result OnRethrowExpr() override;
Result OnReturnExpr() override;
- Result OnSelectExpr(Type result_type) override;
+ Result OnSelectExpr(Index result_count, Type* result_types) override;
Result OnStoreExpr(Opcode opcode,
Address alignment_log2,
Address offset) override;
@@ -937,8 +937,10 @@ Result BinaryReaderIR::OnReturnExpr() {
return AppendExpr(MakeUnique<ReturnExpr>());
}
-Result BinaryReaderIR::OnSelectExpr(Type result_type) {
- return AppendExpr(MakeUnique<SelectExpr>(result_type.GetInlineVector()));
+Result BinaryReaderIR::OnSelectExpr(Index result_count, Type* result_types) {
+ TypeVector results;
+ results.assign(result_types, result_types + result_count);
+ return AppendExpr(MakeUnique<SelectExpr>(results));
}
Result BinaryReaderIR::OnGlobalSetExpr(Index global_index) {
diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc
index 841fab75..8090c95b 100644
--- a/src/binary-reader-logging.cc
+++ b/src/binary-reader-logging.cc
@@ -375,9 +375,12 @@ Result BinaryReaderLogging::OnLoopExpr(Type sig_type) {
return reader_->OnLoopExpr(sig_type);
}
-Result BinaryReaderLogging::OnSelectExpr(Type return_type) {
- LOGF("OnSelectExpr(return_type: %s)\n", return_type.GetName());
- return reader_->OnSelectExpr(return_type);
+Result BinaryReaderLogging::OnSelectExpr(Index result_count,
+ Type* result_types) {
+ LOGF("OnSelectExpr(return_type: ");
+ LogTypes(result_count, result_types);
+ LOGF_NOINDENT(")\n");
+ return reader_->OnSelectExpr(result_count, result_types);
}
Result BinaryReaderLogging::OnTryExpr(Type sig_type) {
diff --git a/src/binary-reader-logging.h b/src/binary-reader-logging.h
index bd1b7242..909b0ce7 100644
--- a/src/binary-reader-logging.h
+++ b/src/binary-reader-logging.h
@@ -209,7 +209,7 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
Result OnReturnCallExpr(Index func_index) override;
Result OnReturnCallIndirectExpr(Index sig_index, Index table_index) override;
Result OnReturnExpr() override;
- Result OnSelectExpr(Type result_type) override;
+ Result OnSelectExpr(Index result_count, Type* result_types) override;
Result OnStoreExpr(Opcode opcode,
Address alignment_log2,
Address offset) override;
diff --git a/src/binary-reader-nop.h b/src/binary-reader-nop.h
index 7f28f619..72cd1b2b 100644
--- a/src/binary-reader-nop.h
+++ b/src/binary-reader-nop.h
@@ -286,7 +286,9 @@ class BinaryReaderNop : public BinaryReaderDelegate {
Result OnReturnCallExpr(Index sig_index) override { return Result::Ok; }
Result OnReturnCallIndirectExpr(Index sig_index, Index table_index) override { return Result::Ok; }
Result OnReturnExpr() override { return Result::Ok; }
- Result OnSelectExpr(Type result_type) override { return Result::Ok; }
+ Result OnSelectExpr(Index result_count, Type* result_types) override {
+ return Result::Ok;
+ }
Result OnStoreExpr(Opcode opcode,
Address alignment_log2,
Address offset) override {
diff --git a/src/binary-reader.cc b/src/binary-reader.cc
index 487cd489..daeeeff1 100644
--- a/src/binary-reader.cc
+++ b/src/binary-reader.cc
@@ -686,21 +686,28 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) {
break;
case Opcode::SelectT: {
- Index count;
- CHECK_RESULT(ReadCount(&count, "num result types"));
- if (count != 1) {
- PrintError("invalid arity in select instrcution: %u", count);
- return Result::Error;
+ Index num_results;
+ CHECK_RESULT(ReadCount(&num_results, "num result types"));
+
+ result_types_.resize(num_results);
+ for (Index i = 0; i < num_results; ++i) {
+ Type result_type;
+ CHECK_RESULT(ReadType(&result_type, "select result type"));
+ ERROR_UNLESS(IsConcreteType(result_type),
+ "expected valid select result type (got " PRItypecode
+ ")",
+ WABT_PRINTF_TYPE_CODE(result_type));
+ result_types_[i] = result_type;
}
- Type result_type;
- CHECK_RESULT(ReadType(&result_type, "select result type"));
- CALLBACK(OnSelectExpr, result_type);
+
+ Type* result_types = num_results ? result_types_.data() : nullptr;
+ CALLBACK(OnSelectExpr, num_results, result_types);
CALLBACK0(OnOpcodeBare);
break;
}
case Opcode::Select:
- CALLBACK(OnSelectExpr, Type::Void);
+ CALLBACK(OnSelectExpr, 0, nullptr);
CALLBACK0(OnOpcodeBare);
break;
diff --git a/src/binary-reader.h b/src/binary-reader.h
index cb27edbe..a7fa7842 100644
--- a/src/binary-reader.h
+++ b/src/binary-reader.h
@@ -276,7 +276,7 @@ class BinaryReaderDelegate {
virtual Result OnReturnCallExpr(Index func_index) = 0;
virtual Result OnReturnCallIndirectExpr(Index sig_index,
Index table_index) = 0;
- virtual Result OnSelectExpr(Type result_type) = 0;
+ virtual Result OnSelectExpr(Index result_count, Type* result_types) = 0;
virtual Result OnStoreExpr(Opcode opcode,
Address alignment_log2,
Address offset) = 0;
diff --git a/src/interp/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc
index 9d5eb90c..0cd9c523 100644
--- a/src/interp/binary-reader-interp.cc
+++ b/src/interp/binary-reader-interp.cc
@@ -195,7 +195,7 @@ class BinaryReaderInterp : public BinaryReaderNop {
Result OnRefIsNullExpr() override;
Result OnNopExpr() override;
Result OnReturnExpr() override;
- Result OnSelectExpr(Type result_type) override;
+ Result OnSelectExpr(Index result_count, Type* result_types) override;
Result OnStoreExpr(Opcode opcode,
Address alignment_log2,
Address offset) override;
@@ -1260,8 +1260,9 @@ Result BinaryReaderInterp::OnReturnExpr() {
return Result::Ok;
}
-Result BinaryReaderInterp::OnSelectExpr(Type result_type) {
- CHECK_RESULT(validator_.OnSelect(loc, result_type));
+Result BinaryReaderInterp::OnSelectExpr(Index result_count,
+ Type* result_types) {
+ CHECK_RESULT(validator_.OnSelect(loc, result_count, result_types));
istream_.Emit(Opcode::Select);
return Result::Ok;
}
diff --git a/src/shared-validator.cc b/src/shared-validator.cc
index 0cc08344..9b928c04 100644
--- a/src/shared-validator.cc
+++ b/src/shared-validator.cc
@@ -1036,10 +1036,18 @@ Result SharedValidator::OnReturn(const Location& loc) {
return result;
}
-Result SharedValidator::OnSelect(const Location& loc, Type result_type) {
+Result SharedValidator::OnSelect(const Location& loc,
+ Index result_count,
+ Type* result_types) {
Result result = Result::Ok;
expr_loc_ = &loc;
- result |= typechecker_.OnSelect(result_type);
+ if (result_count > 1) {
+ result |=
+ PrintError(loc, "invalid arity in select instruction: %" PRIindex ".",
+ result_count);
+ } else {
+ result |= typechecker_.OnSelect(ToTypeVector(result_count, result_types));
+ }
return result;
}
diff --git a/src/shared-validator.h b/src/shared-validator.h
index 3f77c403..f0f9a84b 100644
--- a/src/shared-validator.h
+++ b/src/shared-validator.h
@@ -156,7 +156,7 @@ class SharedValidator {
Result OnReturnCall(const Location&, Var func_var);
Result OnReturnCallIndirect(const Location&, Var sig_var, Var table_var);
Result OnReturn(const Location&);
- Result OnSelect(const Location&, Type result_type);
+ Result OnSelect(const Location&, Index result_count, Type* result_types);
Result OnSimdLaneOp(const Location&, Opcode, uint64_t lane_idx);
Result OnSimdShuffleOp(const Location&, Opcode, v128 lane_idx);
Result OnStore(const Location&, Opcode, Address align);
diff --git a/src/type-checker.cc b/src/type-checker.cc
index f9528344..a93d2b60 100644
--- a/src/type-checker.cc
+++ b/src/type-checker.cc
@@ -730,7 +730,7 @@ Result TypeChecker::OnReturn() {
return result;
}
-Result TypeChecker::OnSelect(Type expected) {
+Result TypeChecker::OnSelect(const TypeVector& expected) {
Result result = Result::Ok;
Type type1 = Type::Any;
Type type2 = Type::Any;
@@ -738,7 +738,7 @@ Result TypeChecker::OnSelect(Type expected) {
result |= PeekAndCheckType(0, Type::I32);
result |= PeekType(1, &type1);
result |= PeekType(2, &type2);
- if (expected == Type::Void) {
+ if (expected.empty()) {
if (type1.IsRef() || type2.IsRef()) {
result = Result::Error;
} else {
@@ -746,8 +746,9 @@ Result TypeChecker::OnSelect(Type expected) {
result_type = type1;
}
} else {
- result |= CheckType(type1, expected);
- result |= CheckType(type2, expected);
+ assert(expected.size() == 1);
+ result |= CheckType(type1, expected[0]);
+ result |= CheckType(type2, expected[0]);
}
PrintStackIfFailed(result, "select", result_type, result_type, Type::I32);
result |= DropTypes(3);
diff --git a/src/type-checker.h b/src/type-checker.h
index 1225ff18..66b9b2e2 100644
--- a/src/type-checker.h
+++ b/src/type-checker.h
@@ -113,7 +113,7 @@ class TypeChecker {
Result OnRefIsNullExpr();
Result OnRethrow();
Result OnReturn();
- Result OnSelect(Type expected);
+ Result OnSelect(const TypeVector& result_types);
Result OnSimdLaneOp(Opcode, uint64_t);
Result OnSimdShuffleOp(Opcode, v128);
Result OnStore(Opcode, const Limits& limits);
diff --git a/src/validator.cc b/src/validator.cc
index 58e32e9d..e7f7b5a5 100644
--- a/src/validator.cc
+++ b/src/validator.cc
@@ -464,13 +464,8 @@ Result Validator::OnReturnCallIndirectExpr(ReturnCallIndirectExpr* expr) {
}
Result Validator::OnSelectExpr(SelectExpr* expr) {
- Type result_type;
- if (expr->result_type.empty()) {
- result_type = Type::Void;
- } else {
- result_type = expr->result_type[0];
- }
- result_ |= validator_.OnSelect(expr->loc, result_type);
+ result_ |= validator_.OnSelect(expr->loc, expr->result_type.size(),
+ expr->result_type.data());
// TODO: Existing behavior fails when select fails.
#if 0
return Result::Ok;