Commit 2ab7143e authored by Manos Koukoutos's avatar Manos Koukoutos Committed by Commit Bot

[wasm-gc] Add signedness argument to struct/array get

This change is needed to implement {struct,array}.get_{s,u}.

Some functionality in wasm-compiler was factored out to helper functions
LoadWithAlignment and StoreWithValueType.

Bug: v8:7748
Change-Id: I2a04d09d40532f2389cc82b4c9ee3d8e003c5101
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2231347Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68215}
parent 0d6270ca
......@@ -5091,9 +5091,10 @@ Node* WasmGraphBuilder::TableFill(uint32_t table_index, Node* start,
namespace {
MachineType FieldType(const wasm::StructType* type, uint32_t field_index) {
MachineType FieldType(const wasm::StructType* type, uint32_t field_index,
bool is_signed) {
return MachineType::TypeForRepresentation(
type->field(field_index).machine_representation());
type->field(field_index).machine_representation(), is_signed);
}
Node* FieldOffset(MachineGraph* graph, const wasm::StructType* type,
......@@ -5103,19 +5104,43 @@ Node* FieldOffset(MachineGraph* graph, const wasm::StructType* type,
return graph->IntPtrConstant(offset);
}
// It's guaranteed that struct/array fields are aligned to min(field_size,
// kTaggedSize), with the latter being 4 or 8 depending on platform and
// pointer compression. So on our most common configurations, 8-byte types
// must use unaligned loads/stores.
Node* LoadWithTaggedAlignment(WasmGraphAssembler* gasm, MachineType type,
Node* base, Node* offset) {
if (ElementSizeInBytes(type.representation()) > kTaggedSize) {
return gasm->LoadUnaligned(type, base, offset);
} else {
return gasm->Load(type, base, offset);
}
}
// Same alignment considerations as above.
Node* StoreWithTaggedAlignment(WasmGraphAssembler* gasm, Node* base,
Node* offset, Node* value,
wasm::ValueType type) {
MachineRepresentation rep = type.machine_representation();
if (ElementSizeInBytes(rep) > kTaggedSize) {
return gasm->StoreUnaligned(rep, base, offset, value);
} else {
WriteBarrierKind write_barrier =
type.IsReferenceType() ? kPointerWriteBarrier : kNoWriteBarrier;
StoreRepresentation store_rep(rep, write_barrier);
return gasm->Store(store_rep, base, offset, value);
}
}
// Set a field of a struct, without checking if the struct is null.
// Helper method for StructNew and StructSet.
Node* StoreStructFieldUnchecked(MachineGraph* graph, WasmGraphAssembler* gasm,
Node* struct_object,
const wasm::StructType* type,
uint32_t field_index, Node* value) {
WriteBarrierKind write_barrier = type->field(field_index).IsReferenceType()
? kPointerWriteBarrier
: kNoWriteBarrier;
StoreRepresentation rep(type->field(field_index).machine_representation(),
write_barrier);
Node* offset = FieldOffset(graph, type, field_index);
return gasm->Store(rep, struct_object, offset, value);
return StoreWithTaggedAlignment(gasm, struct_object,
FieldOffset(graph, type, field_index), value,
type->field(field_index));
}
Node* ArrayElementOffset(GraphAssembler* gasm, Node* index,
......@@ -5179,10 +5204,6 @@ Node* WasmGraphBuilder::ArrayNew(uint32_t array_index,
graph()->NewNode(mcgraph()->common()->NumberConstant(
element_type.element_size_bytes())),
LOAD_INSTANCE_FIELD(NativeContext, MachineType::TaggedPointer()));
WriteBarrierKind write_barrier =
element_type.IsReferenceType() ? kPointerWriteBarrier : kNoWriteBarrier;
StoreRepresentation rep(element_type.machine_representation(), write_barrier);
auto loop = gasm_->MakeLoopLabel(MachineRepresentation::kWord32);
auto done = gasm_->MakeLabel();
Node* start_offset =
......@@ -5202,7 +5223,8 @@ Node* WasmGraphBuilder::ArrayNew(uint32_t array_index,
Node* offset = loop.PhiAt(0);
Node* check = gasm_->Uint32LessThan(offset, end_offset);
gasm_->GotoIfNot(check, &done);
gasm_->Store(rep, a, offset, initial_value);
StoreWithTaggedAlignment(gasm_.get(), a, offset, initial_value,
type->element_type());
offset = gasm_->Int32Add(offset, element_size);
gasm_->Goto(&loop, offset);
}
......@@ -5213,14 +5235,16 @@ Node* WasmGraphBuilder::ArrayNew(uint32_t array_index,
Node* WasmGraphBuilder::StructGet(Node* struct_object,
const wasm::StructType* struct_type,
uint32_t field_index, CheckForNull null_check,
bool is_signed,
wasm::WasmCodePosition position) {
if (null_check == kWithNullCheck) {
TrapIfTrue(wasm::kTrapNullDereference,
gasm_->WordEqual(struct_object, RefNull()), position);
}
MachineType machine_type = FieldType(struct_type, field_index);
MachineType machine_type = FieldType(struct_type, field_index, is_signed);
Node* offset = FieldOffset(mcgraph(), struct_type, field_index);
return gasm_->Load(machine_type, struct_object, offset);
return LoadWithTaggedAlignment(gasm_.get(), machine_type, struct_object,
offset);
}
Node* WasmGraphBuilder::StructSet(Node* struct_object,
......@@ -5245,14 +5269,16 @@ void WasmGraphBuilder::BoundsCheck(Node* array, Node* index,
Node* WasmGraphBuilder::ArrayGet(Node* array_object,
const wasm::ArrayType* type, Node* index,
bool is_signed,
wasm::WasmCodePosition position) {
TrapIfTrue(wasm::kTrapNullDereference,
gasm_->WordEqual(array_object, RefNull()), position);
BoundsCheck(array_object, index, position);
MachineType machine_type = MachineType::TypeForRepresentation(
type->element_type().machine_representation());
type->element_type().machine_representation(), is_signed);
Node* offset = ArrayElementOffset(gasm_.get(), index, type->element_type());
return gasm_->Load(machine_type, array_object, offset);
return LoadWithTaggedAlignment(gasm_.get(), machine_type, array_object,
offset);
}
Node* WasmGraphBuilder::ArraySet(Node* array_object,
......@@ -5261,13 +5287,9 @@ Node* WasmGraphBuilder::ArraySet(Node* array_object,
TrapIfTrue(wasm::kTrapNullDereference,
gasm_->WordEqual(array_object, RefNull()), position);
BoundsCheck(array_object, index, position);
WriteBarrierKind write_barrier = type->element_type().IsReferenceType()
? kPointerWriteBarrier
: kNoWriteBarrier;
StoreRepresentation rep(type->element_type().machine_representation(),
write_barrier);
Node* offset = ArrayElementOffset(gasm_.get(), index, type->element_type());
return gasm_->Store(rep, array_object, offset, value);
return StoreWithTaggedAlignment(gasm_.get(), array_object, offset, value,
type->element_type());
}
Node* WasmGraphBuilder::ArrayLen(Node* array_object,
......
......@@ -379,7 +379,7 @@ class WasmGraphBuilder {
Node* StructNew(uint32_t struct_index, const wasm::StructType* type,
Vector<Node*> fields);
Node* StructGet(Node* struct_object, const wasm::StructType* struct_type,
uint32_t field_index, CheckForNull null_check,
uint32_t field_index, CheckForNull null_check, bool is_signed,
wasm::WasmCodePosition position);
Node* StructSet(Node* struct_object, const wasm::StructType* struct_type,
uint32_t field_index, Node* value, CheckForNull null_check,
......@@ -388,7 +388,7 @@ class WasmGraphBuilder {
Node* length, Node* initial_value);
void BoundsCheck(Node* array, Node* index, wasm::WasmCodePosition position);
Node* ArrayGet(Node* array_object, const wasm::ArrayType* type, Node* index,
wasm::WasmCodePosition position);
bool is_signed, wasm::WasmCodePosition position);
Node* ArraySet(Node* array_object, const wasm::ArrayType* type, Node* index,
Node* value, wasm::WasmCodePosition position);
Node* ArrayLen(Node* array_object, wasm::WasmCodePosition position);
......
......@@ -3560,7 +3560,8 @@ class LiftoffCompiler {
unsupported(decoder, kGC, "struct.new");
}
void StructGet(FullDecoder* decoder, const Value& struct_obj,
const FieldIndexImmediate<validate>& field, Value* result) {
const FieldIndexImmediate<validate>& field, bool is_signed,
Value* result) {
// TODO(7748): Implement.
unsupported(decoder, kGC, "struct.get");
}
......@@ -3579,7 +3580,7 @@ class LiftoffCompiler {
}
void ArrayGet(FullDecoder* decoder, const Value& array_obj,
const ArrayIndexImmediate<validate>& imm, const Value& index,
Value* result) {
bool is_signed, Value* result) {
// TODO(7748): Implement.
unsupported(decoder, kGC, "array.get");
}
......
This diff is collapsed.
......@@ -649,14 +649,15 @@ class WasmGraphBuildingInterface {
}
void StructGet(FullDecoder* decoder, const Value& struct_object,
const FieldIndexImmediate<validate>& field, Value* result) {
const FieldIndexImmediate<validate>& field, bool is_signed,
Value* result) {
using CheckForNull = compiler::WasmGraphBuilder::CheckForNull;
CheckForNull null_check = struct_object.type.kind() == ValueType::kRef
? CheckForNull::kWithoutNullCheck
: CheckForNull::kWithNullCheck;
result->node =
BUILD(StructGet, struct_object.node, field.struct_index.struct_type,
field.index, null_check, decoder->position());
field.index, null_check, is_signed, decoder->position());
}
void StructSet(FullDecoder* decoder, const Value& struct_object,
......@@ -679,9 +680,9 @@ class WasmGraphBuildingInterface {
void ArrayGet(FullDecoder* decoder, const Value& array_obj,
const ArrayIndexImmediate<validate>& imm, const Value& index,
Value* result) {
bool is_signed, Value* result) {
result->node = BUILD(ArrayGet, array_obj.node, imm.array_type, index.node,
decoder->position());
is_signed, decoder->position());
}
void ArraySet(FullDecoder* decoder, const Value& array_obj,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment