[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:
parent
1b3fbeaae1
commit
f9db82ab33
@ -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
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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 {};
|
||||
|
@ -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)),
|
||||
|
Loading…
Reference in New Issue
Block a user