Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/wabt/opcode.def
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe3, InterpData, "data", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe4, InterpDropKeep, "drop_keep", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe5, InterpCatchDrop, "catch_drop", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe6, InterpAdjustFrameForReturnCall, "adjust_frame_for_return_call", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe7, InterpGlobalGetRef, "global.get.ref", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe9, InterpLocalGetRef, "local.get.ref", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xea, InterpMarkRef, "mark_ref", "")

/* Saturating float-to-int opcodes (--enable-saturating-float-to-int) */
WABT_OPCODE(I32, F32, ___, ___, 0, 0xfc, 0x00, I32TruncSatF32S, "i32.trunc_sat_f32_s", "")
Expand Down
23 changes: 21 additions & 2 deletions src/interp/binary-reader-interp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,11 @@ Result BinaryReaderInterp::OnLocalDecl(Index decl_index,
Result BinaryReaderInterp::EndLocalDecls() {
if (local_count_ != 0) {
istream_.Emit(Opcode::InterpAlloca, local_count_);
for (Index i = 0; i < local_count_; i++) {
if (func_->GetLocalType(func_->type.params.size() + i).IsRef()) {
istream_.Emit(Opcode::InterpMarkRef, local_count_ - i);
}
}
}
// Continuation of the implicit func label, used for exception handling. (See
// BeginFunctionBody.)
Expand Down Expand Up @@ -1274,7 +1279,13 @@ Result BinaryReaderInterp::OnV128ConstExpr(v128 value_bits) {
Result BinaryReaderInterp::OnGlobalGetExpr(Index global_index) {
CHECK_RESULT(
validator_.OnGlobalGet(GetLocation(), Var(global_index, GetLocation())));
istream_.Emit(Opcode::GlobalGet, global_index);

Type type = global_types_.at(global_index).type;
if (type.IsRef()) {
istream_.Emit(Opcode::InterpGlobalGetRef, global_index);
} else {
istream_.Emit(Opcode::GlobalGet, global_index);
}
return Result::Ok;
}

Expand All @@ -1297,7 +1308,13 @@ Result BinaryReaderInterp::OnLocalGetExpr(Index local_index) {
Index translated_local_index = TranslateLocalIndex(local_index);
CHECK_RESULT(
validator_.OnLocalGet(GetLocation(), Var(local_index, GetLocation())));
istream_.Emit(Opcode::LocalGet, translated_local_index);

Type type = func_->GetLocalType(local_index);
if (type.IsRef()) {
istream_.Emit(Opcode::InterpLocalGetRef, translated_local_index);
} else {
istream_.Emit(Opcode::LocalGet, translated_local_index);
}
return Result::Ok;
}

Expand All @@ -1306,13 +1323,15 @@ Result BinaryReaderInterp::OnLocalSetExpr(Index local_index) {
Index translated_local_index = TranslateLocalIndex(local_index);
CHECK_RESULT(
validator_.OnLocalSet(GetLocation(), Var(local_index, GetLocation())));

istream_.Emit(Opcode::LocalSet, translated_local_index);
return Result::Ok;
}

Result BinaryReaderInterp::OnLocalTeeExpr(Index local_index) {
CHECK_RESULT(
validator_.OnLocalTee(GetLocation(), Var(local_index, GetLocation())));

istream_.Emit(Opcode::LocalTee, TranslateLocalIndex(local_index));
return Result::Ok;
}
Expand Down
20 changes: 17 additions & 3 deletions src/interp/interp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1254,16 +1254,24 @@ RunResult Thread::StepInternal(Trap::Ptr* out_trap) {
break;

case O::Select: {
// TODO: need to mark whether this is a ref.
auto cond = Pop<u32>();
auto ref = false;
// check if either is a ref
ref |= !refs_.empty() && refs_.back() == values_.size();
Value false_ = Pop();
ref |= !refs_.empty() && refs_.back() == values_.size();
Value true_ = Pop();
if (ref) {
refs_.push_back(values_.size());
}
Push(cond ? true_ : false_);
break;
}

case O::InterpLocalGetRef:
refs_.push_back(values_.size());
[[fallthrough]];
case O::LocalGet:
// TODO: need to mark whether this is a ref.
Push(Pick(instr.imm_u32));
break;

Expand All @@ -1277,8 +1285,14 @@ RunResult Thread::StepInternal(Trap::Ptr* out_trap) {
Pick(instr.imm_u32) = Pick(1);
break;

case O::InterpMarkRef:
refs_.push_back(values_.size() - instr.imm_u32);
break;

case O::InterpGlobalGetRef:
refs_.push_back(values_.size());
[[fallthrough]];
case O::GlobalGet: {
// TODO: need to mark whether this is a ref.
Global::Ptr global{store_, inst_->globals()[instr.imm_u32]};
Push(global->Get());
break;
Expand Down
3 changes: 3 additions & 0 deletions src/interp/istream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,9 @@ Instr Istream::Read(Offset* offset) const {

case Opcode::GlobalGet:
case Opcode::LocalGet:
case Opcode::InterpLocalGetRef:
case Opcode::InterpGlobalGetRef:
case Opcode::InterpMarkRef:
case Opcode::MemorySize:
case Opcode::TableSize:
case Opcode::DataDrop:
Expand Down