[wasm] Simplify Immediates in decoder

Changes:
- Merge all immediates which read a u32_v index into IndexImmediate.
  Refactor overloaded Validate(const byte*, [Type]Immediate) functions
  to Validate[Type](const byte*, IndexImmediate).
- Move MemoryIndexImmediate/MemoryAccessImmediate validation into their
  own Validate functions. Remove CheckHasMemory(), move its
  functionality into these Validate() functions.
- Refactor MemoryInitImmediate, TableInitImmediate and
  CallIndirectImmediate as composite immediates.
- Change field initializations for some Immediates to constructor
  initializers. This helps us drop some useless default constructors.
- Use the correct pc in StackEffect for struct.new_default.

Bug: v8:11831
Change-Id: I878f69a33f8473dc275184995b3b7b88fe0dfc8a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2928498
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74948}
This commit is contained in:
Manos Koukoutos 2021-06-04 06:05:07 +00:00 committed by V8 LUCI CQ
parent 1b3fbeaae1
commit f9db82ab33
6 changed files with 536 additions and 601 deletions

View File

@ -2079,7 +2079,7 @@ class LiftoffCompiler {
}
void LocalGet(FullDecoder* decoder, Value* result,
const LocalIndexImmediate<validate>& imm) {
const IndexImmediate<validate>& imm) {
auto local_slot = __ cache_state()->stack_state[imm.index];
__ cache_state()->stack_state.emplace_back(
local_slot.kind(), __ NextSpillOffset(local_slot.kind()));
@ -2143,12 +2143,12 @@ class LiftoffCompiler {
}
void LocalSet(FullDecoder* decoder, const Value& value,
const LocalIndexImmediate<validate>& imm) {
const IndexImmediate<validate>& imm) {
LocalSet(imm.index, false);
}
void LocalTee(FullDecoder* decoder, const Value& value, Value* result,
const LocalIndexImmediate<validate>& imm) {
const IndexImmediate<validate>& imm) {
LocalSet(imm.index, true);
}
@ -2293,7 +2293,7 @@ class LiftoffCompiler {
}
void TableGet(FullDecoder* decoder, const Value&, Value*,
const TableIndexImmediate<validate>& imm) {
const IndexImmediate<validate>& imm) {
LiftoffRegList pinned;
LiftoffRegister table_index_reg =
@ -2317,7 +2317,7 @@ class LiftoffCompiler {
}
void TableSet(FullDecoder* decoder, const Value&, const Value&,
const TableIndexImmediate<validate>& imm) {
const IndexImmediate<validate>& imm) {
LiftoffRegList pinned;
LiftoffRegister table_index_reg =
@ -4624,7 +4624,7 @@ class LiftoffCompiler {
LiftoffRegister segment_index =
pinned.set(__ GetUnusedRegister(kGpReg, pinned));
__ LoadConstant(segment_index, WasmValue(imm.data_segment_index));
__ LoadConstant(segment_index, WasmValue(imm.data_segment.index));
ExternalReference ext_ref = ExternalReference::wasm_memory_init();
auto sig =
@ -4640,7 +4640,7 @@ class LiftoffCompiler {
__ emit_cond_jump(kEqual, trap_label, kI32, result.gp());
}
void DataDrop(FullDecoder* decoder, const DataDropImmediate<validate>& imm) {
void DataDrop(FullDecoder* decoder, const IndexImmediate<validate>& imm) {
LiftoffRegList pinned;
Register seg_size_array =
@ -4719,7 +4719,7 @@ class LiftoffCompiler {
LiftoffRegister segment_index_reg =
pinned.set(__ GetUnusedRegister(kGpReg, pinned));
LoadSmi(segment_index_reg, imm.elem_segment_index);
LoadSmi(segment_index_reg, imm.element_segment.index);
LiftoffAssembler::VarState segment_index(kPointerKind, segment_index_reg,
0);
@ -4738,7 +4738,7 @@ class LiftoffCompiler {
RegisterDebugSideTableEntry(decoder, DebugSideTableBuilder::kDidSpill);
}
void ElemDrop(FullDecoder* decoder, const ElemDropImmediate<validate>& imm) {
void ElemDrop(FullDecoder* decoder, const IndexImmediate<validate>& imm) {
LiftoffRegList pinned;
Register dropped_elem_segments =
pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
@ -4788,7 +4788,7 @@ class LiftoffCompiler {
RegisterDebugSideTableEntry(decoder, DebugSideTableBuilder::kDidSpill);
}
void TableGrow(FullDecoder* decoder, const TableIndexImmediate<validate>& imm,
void TableGrow(FullDecoder* decoder, const IndexImmediate<validate>& imm,
const Value&, const Value&, Value* result) {
LiftoffRegList pinned;
@ -4813,7 +4813,7 @@ class LiftoffCompiler {
__ PushRegister(kI32, LiftoffRegister(kReturnRegister0));
}
void TableSize(FullDecoder* decoder, const TableIndexImmediate<validate>& imm,
void TableSize(FullDecoder* decoder, const IndexImmediate<validate>& imm,
Value*) {
// We have to look up instance->tables[table_index].length.
@ -4840,7 +4840,7 @@ class LiftoffCompiler {
__ PushRegister(kI32, LiftoffRegister(result));
}
void TableFill(FullDecoder* decoder, const TableIndexImmediate<validate>& imm,
void TableFill(FullDecoder* decoder, const IndexImmediate<validate>& imm,
const Value&, const Value&, const Value&) {
LiftoffRegList pinned;
@ -4912,12 +4912,12 @@ class LiftoffCompiler {
}
void StructGet(FullDecoder* decoder, const Value& struct_obj,
const FieldIndexImmediate<validate>& field, bool is_signed,
const FieldImmediate<validate>& field, bool is_signed,
Value* result) {
const StructType* struct_type = field.struct_index.struct_type;
ValueKind field_kind = struct_type->field(field.index).kind();
const StructType* struct_type = field.struct_imm.struct_type;
ValueKind field_kind = struct_type->field(field.field_imm.index).kind();
if (!CheckSupportedType(decoder, field_kind, "field load")) return;
int offset = StructFieldOffset(struct_type, field.index);
int offset = StructFieldOffset(struct_type, field.field_imm.index);
LiftoffRegList pinned;
LiftoffRegister obj = pinned.set(__ PopToRegister(pinned));
MaybeEmitNullCheck(decoder, obj.gp(), pinned, struct_obj.type);
@ -4929,11 +4929,11 @@ class LiftoffCompiler {
}
void StructSet(FullDecoder* decoder, const Value& struct_obj,
const FieldIndexImmediate<validate>& field,
const FieldImmediate<validate>& field,
const Value& field_value) {
const StructType* struct_type = field.struct_index.struct_type;
ValueKind field_kind = struct_type->field(field.index).kind();
int offset = StructFieldOffset(struct_type, field.index);
const StructType* struct_type = field.struct_imm.struct_type;
ValueKind field_kind = struct_type->field(field.field_imm.index).kind();
int offset = StructFieldOffset(struct_type, field.field_imm.index);
LiftoffRegList pinned;
LiftoffRegister value = pinned.set(__ PopToRegister(pinned));
LiftoffRegister obj = pinned.set(__ PopToRegister(pinned));
@ -5628,7 +5628,7 @@ class LiftoffCompiler {
Register tmp_const = pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
Register scratch = pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
Register indirect_function_table = no_reg;
if (imm.table_index != 0) {
if (imm.table_imm.index != 0) {
Register indirect_function_tables =
pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
LOAD_TAGGED_PTR_INSTANCE_FIELD(indirect_function_tables,
@ -5637,7 +5637,7 @@ class LiftoffCompiler {
indirect_function_table = indirect_function_tables;
__ LoadTaggedPointer(
indirect_function_table, indirect_function_tables, no_reg,
ObjectAccess::ElementOffsetInTaggedFixedArray(imm.table_index),
ObjectAccess::ElementOffsetInTaggedFixedArray(imm.table_imm.index),
pinned);
}
@ -5646,13 +5646,13 @@ class LiftoffCompiler {
AddOutOfLineTrap(decoder, WasmCode::kThrowWasmTrapTableOutOfBounds);
uint32_t canonical_sig_num =
env_->module->canonicalized_type_ids[imm.sig_index];
env_->module->canonicalized_type_ids[imm.sig_imm.index];
DCHECK_GE(canonical_sig_num, 0);
DCHECK_GE(kMaxInt, canonical_sig_num);
// Compare against table size stored in
// {instance->indirect_function_table_size}.
if (imm.table_index == 0) {
if (imm.table_imm.index == 0) {
LOAD_INSTANCE_FIELD(tmp_const, IndirectFunctionTableSize, kUInt32Size,
pinned);
} else {
@ -5688,7 +5688,7 @@ class LiftoffCompiler {
DEBUG_CODE_COMMENT("Check indirect call signature");
// Load the signature from {instance->ift_sig_ids[key]}
if (imm.table_index == 0) {
if (imm.table_imm.index == 0) {
LOAD_INSTANCE_FIELD(table, IndirectFunctionTableSigIds,
kSystemPointerSize, pinned);
} else {
@ -5721,7 +5721,7 @@ class LiftoffCompiler {
// At this point {index} has already been multiplied by kTaggedSize.
// Load the instance from {instance->ift_instances[key]}
if (imm.table_index == 0) {
if (imm.table_imm.index == 0) {
LOAD_TAGGED_PTR_INSTANCE_FIELD(table, IndirectFunctionTableRefs, pinned);
} else {
__ LoadTaggedPointer(
@ -5743,7 +5743,7 @@ class LiftoffCompiler {
Register* explicit_instance = &tmp_const;
// Load the target from {instance->ift_targets[key]}
if (imm.table_index == 0) {
if (imm.table_imm.index == 0) {
LOAD_INSTANCE_FIELD(table, IndirectFunctionTableTargets,
kSystemPointerSize, pinned);
} else {

File diff suppressed because it is too large Load Diff

View File

@ -253,7 +253,7 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
BlockTypeImmediate<Decoder::kNoValidation> imm(WasmFeatures::All(), &i,
i.pc() + 1, module);
os << " @" << i.pc_offset();
CHECK(decoder.Validate(i.pc(), imm));
CHECK(decoder.Validate(i.pc() + 1, imm));
for (uint32_t i = 0; i < imm.out_arity(); i++) {
os << " " << imm.out_type(i).name();
}
@ -280,17 +280,16 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
break;
}
case kExprCallIndirect: {
CallIndirectImmediate<Decoder::kNoValidation> imm(WasmFeatures::All(),
&i, i.pc() + 1);
os << " sig #" << imm.sig_index;
CHECK(decoder.Validate(i.pc(), imm));
CallIndirectImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
os << " sig #" << imm.sig_imm.index;
CHECK(decoder.Validate(i.pc() + 1, imm));
os << ": " << *imm.sig;
break;
}
case kExprCallFunction: {
CallFunctionImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
os << " function #" << imm.index;
CHECK(decoder.Validate(i.pc(), imm));
CHECK(decoder.Validate(i.pc() + 1, imm));
os << ": " << *imm.sig;
break;
}

View File

@ -364,17 +364,17 @@ class WasmGraphBuildingInterface {
void Drop(FullDecoder* decoder) {}
void LocalGet(FullDecoder* decoder, Value* result,
const LocalIndexImmediate<validate>& imm) {
const IndexImmediate<validate>& imm) {
result->node = ssa_env_->locals[imm.index];
}
void LocalSet(FullDecoder* decoder, const Value& value,
const LocalIndexImmediate<validate>& imm) {
const IndexImmediate<validate>& imm) {
ssa_env_->locals[imm.index] = value.node;
}
void LocalTee(FullDecoder* decoder, const Value& value, Value* result,
const LocalIndexImmediate<validate>& imm) {
const IndexImmediate<validate>& imm) {
result->node = value.node;
ssa_env_->locals[imm.index] = value.node;
}
@ -403,13 +403,13 @@ class WasmGraphBuildingInterface {
}
void TableGet(FullDecoder* decoder, const Value& index, Value* result,
const TableIndexImmediate<validate>& imm) {
const IndexImmediate<validate>& imm) {
result->node =
builder_->TableGet(imm.index, index.node, decoder->position());
}
void TableSet(FullDecoder* decoder, const Value& index, const Value& value,
const TableIndexImmediate<validate>& imm) {
const IndexImmediate<validate>& imm) {
builder_->TableSet(imm.index, index.node, value.node, decoder->position());
}
@ -625,17 +625,17 @@ class WasmGraphBuildingInterface {
void CallIndirect(FullDecoder* decoder, const Value& index,
const CallIndirectImmediate<validate>& imm,
const Value args[], Value returns[]) {
DoCall(decoder, kCallIndirect, imm.table_index,
CheckForNull::kWithoutNullCheck, index.node, imm.sig, imm.sig_index,
args, returns);
DoCall(decoder, kCallIndirect, imm.table_imm.index,
CheckForNull::kWithoutNullCheck, index.node, imm.sig,
imm.sig_imm.index, args, returns);
}
void ReturnCallIndirect(FullDecoder* decoder, const Value& index,
const CallIndirectImmediate<validate>& imm,
const Value args[]) {
DoReturnCall(decoder, kCallIndirect, imm.table_index,
CheckForNull::kWithoutNullCheck, index, imm.sig, imm.sig_index,
args);
DoReturnCall(decoder, kCallIndirect, imm.table_imm.index,
CheckForNull::kWithoutNullCheck, index, imm.sig,
imm.sig_imm.index, args);
}
void CallRef(FullDecoder* decoder, const Value& func_ref,
@ -837,11 +837,11 @@ class WasmGraphBuildingInterface {
void MemoryInit(FullDecoder* decoder,
const MemoryInitImmediate<validate>& imm, const Value& dst,
const Value& src, const Value& size) {
builder_->MemoryInit(imm.data_segment_index, dst.node, src.node, size.node,
builder_->MemoryInit(imm.data_segment.index, dst.node, src.node, size.node,
decoder->position());
}
void DataDrop(FullDecoder* decoder, const DataDropImmediate<validate>& imm) {
void DataDrop(FullDecoder* decoder, const IndexImmediate<validate>& imm) {
builder_->DataDrop(imm.index, decoder->position());
}
@ -859,11 +859,12 @@ class WasmGraphBuildingInterface {
void TableInit(FullDecoder* decoder, const TableInitImmediate<validate>& imm,
Vector<Value> args) {
builder_->TableInit(imm.table.index, imm.elem_segment_index, args[0].node,
args[1].node, args[2].node, decoder->position());
builder_->TableInit(imm.table.index, imm.element_segment.index,
args[0].node, args[1].node, args[2].node,
decoder->position());
}
void ElemDrop(FullDecoder* decoder, const ElemDropImmediate<validate>& imm) {
void ElemDrop(FullDecoder* decoder, const IndexImmediate<validate>& imm) {
builder_->ElemDrop(imm.index, decoder->position());
}
@ -873,17 +874,17 @@ class WasmGraphBuildingInterface {
args[1].node, args[2].node, decoder->position());
}
void TableGrow(FullDecoder* decoder, const TableIndexImmediate<validate>& imm,
void TableGrow(FullDecoder* decoder, const IndexImmediate<validate>& imm,
const Value& value, const Value& delta, Value* result) {
result->node = builder_->TableGrow(imm.index, value.node, delta.node);
}
void TableSize(FullDecoder* decoder, const TableIndexImmediate<validate>& imm,
void TableSize(FullDecoder* decoder, const IndexImmediate<validate>& imm,
Value* result) {
result->node = builder_->TableSize(imm.index);
}
void TableFill(FullDecoder* decoder, const TableIndexImmediate<validate>& imm,
void TableFill(FullDecoder* decoder, const IndexImmediate<validate>& imm,
const Value& start, const Value& value, const Value& count) {
builder_->TableFill(imm.index, start.node, value.node, count.node);
}
@ -912,24 +913,24 @@ class WasmGraphBuildingInterface {
}
void StructGet(FullDecoder* decoder, const Value& struct_object,
const FieldIndexImmediate<validate>& field, bool is_signed,
const FieldImmediate<validate>& field, bool is_signed,
Value* result) {
CheckForNull null_check = struct_object.type.is_nullable()
? CheckForNull::kWithNullCheck
: CheckForNull::kWithoutNullCheck;
result->node = builder_->StructGet(
struct_object.node, field.struct_index.struct_type, field.index,
struct_object.node, field.struct_imm.struct_type, field.field_imm.index,
null_check, is_signed, decoder->position());
}
void StructSet(FullDecoder* decoder, const Value& struct_object,
const FieldIndexImmediate<validate>& field,
const FieldImmediate<validate>& field,
const Value& field_value) {
CheckForNull null_check = struct_object.type.is_nullable()
? CheckForNull::kWithNullCheck
: CheckForNull::kWithoutNullCheck;
builder_->StructSet(struct_object.node, field.struct_index.struct_type,
field.index, field_value.node, null_check,
builder_->StructSet(struct_object.node, field.struct_imm.struct_type,
field.field_imm.index, field_value.node, null_check,
decoder->position());
}

View File

@ -1813,7 +1813,8 @@ class ModuleDecoderImpl : public Decoder {
return {};
}
FunctionIndexImmediate<Decoder::kFullValidation> imm(this, pc() + 1);
IndexImmediate<Decoder::kFullValidation> imm(this, pc() + 1,
"function index");
len = 1 + imm.length;
if (V8_UNLIKELY(module->functions.size() <= imm.index)) {
errorf(pc(), "invalid function index: %u", imm.index);
@ -1847,7 +1848,7 @@ class ModuleDecoderImpl : public Decoder {
opcode = read_prefixed_opcode<validate>(pc(), &len);
switch (opcode) {
case kExprRttCanon: {
TypeIndexImmediate<validate> imm(this, pc() + 2);
IndexImmediate<validate> imm(this, pc() + 2, "type index");
if (V8_UNLIKELY(imm.index >= module_->types.capacity())) {
errorf(pc() + 2, "type index %u is out of bounds", imm.index);
return {};
@ -1864,7 +1865,7 @@ class ModuleDecoderImpl : public Decoder {
}
V8_FALLTHROUGH;
case kExprRttSub: {
TypeIndexImmediate<validate> imm(this, pc() + 2);
IndexImmediate<validate> imm(this, pc() + 2, "type index");
if (V8_UNLIKELY(imm.index >= module_->types.capacity())) {
errorf(pc() + 2, "type index %u is out of bounds", imm.index);
return {};

View File

@ -1540,8 +1540,8 @@ class WasmInterpreterInternals {
return pc + 1 + imm.length;
}
case kExprCallIndirect: {
CallIndirectImmediate<Decoder::kNoValidation> imm(
WasmFeatures::All(), decoder, code->at(pc + 1));
CallIndirectImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 1));
return pc + 1 + imm.length;
}
default:
@ -1835,29 +1835,29 @@ class WasmInterpreterInternals {
code->at(pc + *len));
// The data segment index must be in bounds since it is required by
// validation.
DCHECK_LT(imm.data_segment_index, module()->num_declared_data_segments);
DCHECK_LT(imm.data_segment.index, module()->num_declared_data_segments);
*len += imm.length;
uint64_t size = ToMemType(Pop());
uint64_t src = ToMemType(Pop());
uint64_t dst = ToMemType(Pop());
Address dst_addr;
uint64_t src_max =
instance_object_->data_segment_sizes()[imm.data_segment_index];
instance_object_->data_segment_sizes()[imm.data_segment.index];
if (!BoundsCheckMemRange(dst, &size, &dst_addr) ||
!base::IsInBounds(src, size, src_max)) {
DoTrap(kTrapMemOutOfBounds, pc);
return false;
}
Address src_addr =
instance_object_->data_segment_starts()[imm.data_segment_index] +
instance_object_->data_segment_starts()[imm.data_segment.index] +
src;
std::memmove(reinterpret_cast<void*>(dst_addr),
reinterpret_cast<void*>(src_addr), size);
return true;
}
case kExprDataDrop: {
DataDropImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + *len));
IndexImmediate<Decoder::kNoValidation> imm(decoder, code->at(pc + *len),
"data segment index");
// The data segment index must be in bounds since it is required by
// validation.
DCHECK_LT(imm.index, module()->num_declared_data_segments);
@ -1909,13 +1909,13 @@ class WasmInterpreterInternals {
HandleScope scope(isolate_); // Avoid leaking handles.
bool ok = WasmInstanceObject::InitTableEntries(
instance_object_->GetIsolate(), instance_object_, imm.table.index,
imm.elem_segment_index, dst, src, size);
imm.element_segment.index, dst, src, size);
if (!ok) DoTrap(kTrapTableOutOfBounds, pc);
return ok;
}
case kExprElemDrop: {
ElemDropImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + *len));
IndexImmediate<Decoder::kNoValidation> imm(decoder, code->at(pc + *len),
"element segment index");
*len += imm.length;
instance_object_->dropped_elem_segments()[imm.index] = 1;
return true;
@ -1935,8 +1935,8 @@ class WasmInterpreterInternals {
return ok;
}
case kExprTableGrow: {
TableIndexImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + *len));
IndexImmediate<Decoder::kNoValidation> imm(decoder, code->at(pc + *len),
"table index");
HandleScope handle_scope(isolate_);
auto table = handle(
WasmTableObject::cast(instance_object_->tables().get(imm.index)),
@ -1949,8 +1949,8 @@ class WasmInterpreterInternals {
return true;
}
case kExprTableSize: {
TableIndexImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + *len));
IndexImmediate<Decoder::kNoValidation> imm(decoder, code->at(pc + *len),
"table index");
HandleScope handle_scope(isolate_);
auto table = handle(
WasmTableObject::cast(instance_object_->tables().get(imm.index)),
@ -1961,8 +1961,8 @@ class WasmInterpreterInternals {
return true;
}
case kExprTableFill: {
TableIndexImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + *len));
IndexImmediate<Decoder::kNoValidation> imm(decoder, code->at(pc + *len),
"table index");
HandleScope handle_scope(isolate_);
auto count = Pop().to<uint32_t>();
auto value = Pop().to_ref();
@ -3560,8 +3560,8 @@ class WasmInterpreterInternals {
break;
}
case kExprRefFunc: {
FunctionIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
IndexImmediate<Decoder::kNoValidation> imm(&decoder, code->at(pc + 1),
"function index");
HandleScope handle_scope(isolate_); // Avoid leaking handles.
Handle<WasmExternalFunction> function =
@ -3572,16 +3572,16 @@ class WasmInterpreterInternals {
break;
}
case kExprLocalGet: {
LocalIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
IndexImmediate<Decoder::kNoValidation> imm(&decoder, code->at(pc + 1),
"local index");
HandleScope handle_scope(isolate_); // Avoid leaking handles.
Push(GetStackValue(frames_.back().sp + imm.index));
len = 1 + imm.length;
break;
}
case kExprLocalSet: {
LocalIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
IndexImmediate<Decoder::kNoValidation> imm(&decoder, code->at(pc + 1),
"local index");
HandleScope handle_scope(isolate_); // Avoid leaking handles.
WasmValue val = Pop();
SetStackValue(frames_.back().sp + imm.index, val);
@ -3589,8 +3589,8 @@ class WasmInterpreterInternals {
break;
}
case kExprLocalTee: {
LocalIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
IndexImmediate<Decoder::kNoValidation> imm(&decoder, code->at(pc + 1),
"local index");
HandleScope handle_scope(isolate_); // Avoid leaking handles.
WasmValue val = Pop();
SetStackValue(frames_.back().sp + imm.index, val);
@ -3614,12 +3614,12 @@ class WasmInterpreterInternals {
} break;
case kExprCallIndirect: {
CallIndirectImmediate<Decoder::kNoValidation> imm(
WasmFeatures::All(), &decoder, code->at(pc + 1));
CallIndirectImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
uint32_t entry_index = Pop().to<uint32_t>();
CommitPc(pc); // TODO(wasm): Be more disciplined about committing PC.
CallResult result =
CallIndirectFunction(imm.table_index, entry_index, imm.sig_index);
CallResult result = CallIndirectFunction(
imm.table_imm.index, entry_index, imm.sig_imm.index);
switch (result.type) {
case CallResult::INTERNAL:
// The import is a function of this instance. Call it directly.
@ -3653,15 +3653,15 @@ class WasmInterpreterInternals {
// Make return calls more expensive, so that return call recursions
// don't cause a timeout.
if (max > 0) max = std::max(0, max - 100);
CallIndirectImmediate<Decoder::kNoValidation> imm(
WasmFeatures::All(), &decoder, code->at(pc + 1));
CallIndirectImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
uint32_t entry_index = Pop().to<uint32_t>();
CommitPc(pc); // TODO(wasm): Be more disciplined about committing PC.
// TODO(wasm): Calling functions needs some refactoring to avoid
// multi-exit code like this.
CallResult result =
CallIndirectFunction(imm.table_index, entry_index, imm.sig_index);
CallResult result = CallIndirectFunction(
imm.table_imm.index, entry_index, imm.sig_imm.index);
switch (result.type) {
case CallResult::INTERNAL: {
InterpreterCode* target = result.interpreter_code;
@ -3729,8 +3729,8 @@ class WasmInterpreterInternals {
break;
}
case kExprTableGet: {
TableIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
IndexImmediate<Decoder::kNoValidation> imm(&decoder, code->at(pc + 1),
"table index");
HandleScope handle_scope(isolate_);
auto table = handle(
WasmTableObject::cast(instance_object_->tables().get(imm.index)),
@ -3747,8 +3747,8 @@ class WasmInterpreterInternals {
break;
}
case kExprTableSet: {
TableIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
IndexImmediate<Decoder::kNoValidation> imm(&decoder, code->at(pc + 1),
"table index");
HandleScope handle_scope(isolate_);
auto table = handle(
WasmTableObject::cast(instance_object_->tables().get(imm.index)),