summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/wasm-compiler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/wasm-compiler.cc')
-rw-r--r--deps/v8/src/compiler/wasm-compiler.cc214
1 files changed, 129 insertions, 85 deletions
diff --git a/deps/v8/src/compiler/wasm-compiler.cc b/deps/v8/src/compiler/wasm-compiler.cc
index b52f6f0640..30f9e94f1f 100644
--- a/deps/v8/src/compiler/wasm-compiler.cc
+++ b/deps/v8/src/compiler/wasm-compiler.cc
@@ -40,6 +40,7 @@
#include "src/optimized-compilation-info.h"
#include "src/tracing/trace-event.h"
#include "src/trap-handler/trap-handler.h"
+#include "src/vector.h"
#include "src/wasm/function-body-decoder.h"
#include "src/wasm/function-compiler.h"
#include "src/wasm/graph-builder-interface.h"
@@ -1063,7 +1064,9 @@ Node* WasmGraphBuilder::Return(unsigned count, Node** vals) {
}
buf[0] = mcgraph()->Int32Constant(0);
- memcpy(buf + 1, vals, sizeof(void*) * count);
+ if (count > 0) {
+ memcpy(buf + 1, vals, sizeof(void*) * count);
+ }
buf[count + 1] = Effect();
buf[count + 2] = Control();
Node* ret =
@@ -2068,59 +2071,11 @@ Node* WasmGraphBuilder::MemoryGrow(Node* input) {
call_target, input, Effect(), Control())));
}
-#ifdef DEBUG
-
-namespace {
-
-constexpr uint32_t kBytesPerExceptionValuesArrayElement = 2;
-
-size_t ComputeEncodedElementSize(wasm::ValueType type) {
- size_t byte_size =
- static_cast<size_t>(wasm::ValueTypes::ElementSizeInBytes(type));
- DCHECK_EQ(byte_size % kBytesPerExceptionValuesArrayElement, 0);
- DCHECK_LE(1, byte_size / kBytesPerExceptionValuesArrayElement);
- return byte_size / kBytesPerExceptionValuesArrayElement;
-}
-
-} // namespace
-
-#endif // DEBUG
-
-uint32_t WasmGraphBuilder::GetExceptionEncodedSize(
- const wasm::WasmException* exception) const {
- const wasm::WasmExceptionSig* sig = exception->sig;
- uint32_t encoded_size = 0;
- for (size_t i = 0; i < sig->parameter_count(); ++i) {
- switch (sig->GetParam(i)) {
- case wasm::kWasmI32:
- case wasm::kWasmF32:
- DCHECK_EQ(2, ComputeEncodedElementSize(sig->GetParam(i)));
- encoded_size += 2;
- break;
- case wasm::kWasmI64:
- case wasm::kWasmF64:
- DCHECK_EQ(4, ComputeEncodedElementSize(sig->GetParam(i)));
- encoded_size += 4;
- break;
- case wasm::kWasmS128:
- DCHECK_EQ(8, ComputeEncodedElementSize(sig->GetParam(i)));
- encoded_size += 8;
- break;
- case wasm::kWasmAnyRef:
- encoded_size += 1;
- break;
- default:
- UNREACHABLE();
- }
- }
- return encoded_size;
-}
-
Node* WasmGraphBuilder::Throw(uint32_t exception_index,
const wasm::WasmException* exception,
const Vector<Node*> values) {
needs_stack_check_ = true;
- uint32_t encoded_size = GetExceptionEncodedSize(exception);
+ uint32_t encoded_size = WasmExceptionPackage::GetEncodedSize(exception);
Node* create_parameters[] = {
LoadExceptionTagFromTable(exception_index),
BuildChangeUint31ToSmi(Uint32Constant(encoded_size))};
@@ -2308,7 +2263,7 @@ Node** WasmGraphBuilder::GetExceptionValues(
}
values[i] = value;
}
- DCHECK_EQ(index, GetExceptionEncodedSize(exception));
+ DCHECK_EQ(index, WasmExceptionPackage::GetEncodedSize(exception));
return values;
}
@@ -2737,8 +2692,16 @@ Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig, Node** args,
// Load the target from the imported_targets array at the offset of
// {func_index}.
- STATIC_ASSERT(kTaggedSize == kSystemPointerSize);
- Node* func_index_times_pointersize = func_index_times_tagged_size;
+ Node* func_index_times_pointersize;
+ if (kSystemPointerSize == kTaggedSize) {
+ func_index_times_pointersize = func_index_times_tagged_size;
+
+ } else {
+ DCHECK_EQ(kSystemPointerSize, kTaggedSize + kTaggedSize);
+ func_index_times_pointersize = graph()->NewNode(
+ mcgraph()->machine()->Int32Add(), func_index_times_tagged_size,
+ func_index_times_tagged_size);
+ }
Node* imported_targets =
LOAD_INSTANCE_FIELD(ImportedFunctionTargets, MachineType::Pointer());
Node* target_node = SetEffect(graph()->NewNode(
@@ -2820,15 +2783,14 @@ Node* WasmGraphBuilder::CallIndirect(uint32_t sig_index, Node** args,
Node* ift_instances = LOAD_INSTANCE_FIELD(IndirectFunctionTableRefs,
MachineType::TaggedPointer());
- Node* intptr_scaled_key = graph()->NewNode(
- machine->Word32Shl(), key, Int32Constant(kSystemPointerSizeLog2));
-
- Node* target = SetEffect(
- graph()->NewNode(machine->Load(MachineType::Pointer()), ift_targets,
- intptr_scaled_key, Effect(), Control()));
-
- STATIC_ASSERT(kTaggedSize == kSystemPointerSize);
- Node* tagged_scaled_key = intptr_scaled_key;
+ Node* tagged_scaled_key;
+ if (kTaggedSize == kInt32Size) {
+ tagged_scaled_key = int32_scaled_key;
+ } else {
+ DCHECK_EQ(kTaggedSize, kInt32Size * 2);
+ tagged_scaled_key = graph()->NewNode(machine->Int32Add(), int32_scaled_key,
+ int32_scaled_key);
+ }
Node* target_instance = SetEffect(graph()->NewNode(
machine->Load(MachineType::TaggedPointer()),
@@ -2836,8 +2798,20 @@ Node* WasmGraphBuilder::CallIndirect(uint32_t sig_index, Node** args,
Int32Constant(wasm::ObjectAccess::ElementOffsetInTaggedFixedArray(0)),
Effect(), Control()));
- args[0] = target;
+ Node* intptr_scaled_key;
+ if (kSystemPointerSize == kTaggedSize) {
+ intptr_scaled_key = tagged_scaled_key;
+ } else {
+ DCHECK_EQ(kSystemPointerSize, kTaggedSize + kTaggedSize);
+ intptr_scaled_key = graph()->NewNode(machine->Int32Add(), tagged_scaled_key,
+ tagged_scaled_key);
+ }
+ Node* target = SetEffect(
+ graph()->NewNode(machine->Load(MachineType::Pointer()), ift_targets,
+ intptr_scaled_key, Effect(), Control()));
+
+ args[0] = target;
return BuildWasmCall(sig, args, rets, position, target_instance,
untrusted_code_mitigations_ ? kRetpoline : kNoRetpoline);
}
@@ -3261,6 +3235,69 @@ Node* WasmGraphBuilder::SetGlobal(uint32_t index, Node* val) {
graph()->NewNode(op, base, offset, val, Effect(), Control()));
}
+void WasmGraphBuilder::GetTableBaseAndOffset(uint32_t table_index, Node* index,
+ wasm::WasmCodePosition position,
+ Node** base_node,
+ Node** offset_node) {
+ Node* tables = LOAD_INSTANCE_FIELD(Tables, MachineType::TaggedPointer());
+ Node* table = LOAD_FIXED_ARRAY_SLOT_ANY(tables, table_index);
+
+ int storage_field_size = WasmTableObject::kElementsOffsetEnd -
+ WasmTableObject::kElementsOffset + 1;
+ Node* storage = LOAD_RAW(
+ table, wasm::ObjectAccess::ToTagged(WasmTableObject::kElementsOffset),
+ assert_size(storage_field_size, MachineType::TaggedPointer()));
+
+ int length_field_size =
+ FixedArray::kLengthOffsetEnd - FixedArray::kLengthOffset + 1;
+ Node* storage_size =
+ LOAD_RAW(storage, wasm::ObjectAccess::ToTagged(FixedArray::kLengthOffset),
+ assert_size(length_field_size, MachineType::TaggedSigned()));
+
+ storage_size = BuildChangeSmiToInt32(storage_size);
+ // Bounds check against the table size.
+ Node* in_bounds = graph()->NewNode(mcgraph()->machine()->Uint32LessThan(),
+ index, storage_size);
+ TrapIfFalse(wasm::kTrapTableOutOfBounds, in_bounds, position);
+
+ // From the index, calculate the actual offset in the FixeArray. This
+ // is kHeaderSize + (index * kTaggedSize). kHeaderSize can be acquired with
+ // wasm::ObjectAccess::ElementOffsetInTaggedFixedArray(0).
+ Node* index_times_tagged_size =
+ graph()->NewNode(mcgraph()->machine()->IntMul(), Uint32ToUintptr(index),
+ mcgraph()->Int32Constant(kTaggedSize));
+
+ *offset_node = graph()->NewNode(
+ mcgraph()->machine()->IntAdd(), index_times_tagged_size,
+ mcgraph()->IntPtrConstant(
+ wasm::ObjectAccess::ElementOffsetInTaggedFixedArray(0)));
+
+ *base_node = storage;
+}
+
+Node* WasmGraphBuilder::GetTable(uint32_t table_index, Node* index,
+ wasm::WasmCodePosition position) {
+ Node* base = nullptr;
+ Node* offset = nullptr;
+ GetTableBaseAndOffset(table_index, index, position, &base, &offset);
+ return SetEffect(
+ graph()->NewNode(mcgraph()->machine()->Load(MachineType::AnyTagged()),
+ base, offset, Effect(), Control()));
+}
+
+Node* WasmGraphBuilder::SetTable(uint32_t table_index, Node* index, Node* val,
+ wasm::WasmCodePosition position) {
+ Node* base = nullptr;
+ Node* offset = nullptr;
+ GetTableBaseAndOffset(table_index, index, position, &base, &offset);
+
+ const Operator* op = mcgraph()->machine()->Store(
+ StoreRepresentation(MachineRepresentation::kTagged, kFullWriteBarrier));
+
+ Node* store = graph()->NewNode(op, base, offset, val, Effect(), Control());
+ return SetEffect(store);
+}
+
Node* WasmGraphBuilder::CheckBoundsAndAlignment(
uint8_t access_size, Node* index, uint32_t offset,
wasm::WasmCodePosition position) {
@@ -4278,7 +4315,7 @@ Node* WasmGraphBuilder::AtomicOp(wasm::WasmOpcode opcode, Node* const* inputs,
case wasm::kExprI64AtomicWait: {
Node* index = CheckBoundsAndAlignment(
- wasm::ValueTypes::MemSize(MachineType::Uint32()), inputs[0], offset,
+ wasm::ValueTypes::MemSize(MachineType::Uint64()), inputs[0], offset,
position);
// Now that we've bounds-checked, compute the effective address.
Node* address = graph()->NewNode(mcgraph()->machine()->Int32Add(),
@@ -4364,10 +4401,10 @@ Node* WasmGraphBuilder::MemoryInit(uint32_t data_segment_index, Node* dst,
// Load segment's base pointer from WasmInstanceObject::data_segment_starts.
Node* seg_start_array =
LOAD_INSTANCE_FIELD(DataSegmentStarts, MachineType::Pointer());
- STATIC_ASSERT(wasm::kV8MaxWasmDataSegments <= kMaxUInt32 >>
- kPointerSizeLog2);
+ STATIC_ASSERT(wasm::kV8MaxWasmDataSegments <=
+ kMaxUInt32 / kSystemPointerSize);
Node* scaled_index = Uint32ToUintptr(graph()->NewNode(
- m->Word32Shl(), seg_index, Int32Constant(kPointerSizeLog2)));
+ m->Word32Shl(), seg_index, Int32Constant(kSystemPointerSizeLog2)));
Node* seg_start = SetEffect(
graph()->NewNode(m->Load(MachineType::Pointer()), seg_start_array,
scaled_index, Effect(), Control()));
@@ -4384,8 +4421,8 @@ Node* WasmGraphBuilder::MemoryInit(uint32_t data_segment_index, Node* dst,
return BuildCCall(&sig, function, dst, src, size);
}
-Node* WasmGraphBuilder::MemoryDrop(uint32_t data_segment_index,
- wasm::WasmCodePosition position) {
+Node* WasmGraphBuilder::DataDrop(uint32_t data_segment_index,
+ wasm::WasmCodePosition position) {
Node* dropped_data_segments =
CheckDataSegmentIsPassiveAndNotDropped(data_segment_index, position);
const Operator* store_op = mcgraph()->machine()->Store(
@@ -4438,20 +4475,21 @@ Node* WasmGraphBuilder::TableInit(uint32_t table_index,
uint32_t elem_segment_index, Node* dst,
Node* src, Node* size,
wasm::WasmCodePosition position) {
+ CheckElemSegmentIsPassiveAndNotDropped(elem_segment_index, position);
Node* args[] = {
graph()->NewNode(mcgraph()->common()->NumberConstant(table_index)),
graph()->NewNode(mcgraph()->common()->NumberConstant(elem_segment_index)),
- BuildConvertUint32ToSmiWithSaturation(dst, wasm::kV8MaxWasmTableSize),
- BuildConvertUint32ToSmiWithSaturation(src, wasm::kV8MaxWasmTableSize),
- BuildConvertUint32ToSmiWithSaturation(size, wasm::kV8MaxWasmTableSize)};
+ BuildConvertUint32ToSmiWithSaturation(dst, FLAG_wasm_max_table_size),
+ BuildConvertUint32ToSmiWithSaturation(src, FLAG_wasm_max_table_size),
+ BuildConvertUint32ToSmiWithSaturation(size, FLAG_wasm_max_table_size)};
Node* result =
BuildCallToRuntime(Runtime::kWasmTableInit, args, arraysize(args));
return result;
}
-Node* WasmGraphBuilder::TableDrop(uint32_t elem_segment_index,
- wasm::WasmCodePosition position) {
+Node* WasmGraphBuilder::ElemDrop(uint32_t elem_segment_index,
+ wasm::WasmCodePosition position) {
Node* dropped_elem_segments =
CheckElemSegmentIsPassiveAndNotDropped(elem_segment_index, position);
const Operator* store_op = mcgraph()->machine()->Store(
@@ -4462,13 +4500,16 @@ Node* WasmGraphBuilder::TableDrop(uint32_t elem_segment_index,
mcgraph()->Int32Constant(1), Effect(), Control()));
}
-Node* WasmGraphBuilder::TableCopy(uint32_t table_index, Node* dst, Node* src,
- Node* size, wasm::WasmCodePosition position) {
+Node* WasmGraphBuilder::TableCopy(uint32_t table_src_index,
+ uint32_t table_dst_index, Node* dst,
+ Node* src, Node* size,
+ wasm::WasmCodePosition position) {
Node* args[] = {
- graph()->NewNode(mcgraph()->common()->NumberConstant(table_index)),
- BuildConvertUint32ToSmiWithSaturation(dst, wasm::kV8MaxWasmTableSize),
- BuildConvertUint32ToSmiWithSaturation(src, wasm::kV8MaxWasmTableSize),
- BuildConvertUint32ToSmiWithSaturation(size, wasm::kV8MaxWasmTableSize)};
+ graph()->NewNode(mcgraph()->common()->NumberConstant(table_src_index)),
+ graph()->NewNode(mcgraph()->common()->NumberConstant(table_dst_index)),
+ BuildConvertUint32ToSmiWithSaturation(dst, FLAG_wasm_max_table_size),
+ BuildConvertUint32ToSmiWithSaturation(src, FLAG_wasm_max_table_size),
+ BuildConvertUint32ToSmiWithSaturation(size, FLAG_wasm_max_table_size)};
Node* result =
BuildCallToRuntime(Runtime::kWasmTableCopy, args, arraysize(args));
@@ -5500,14 +5541,17 @@ WasmImportCallKind GetWasmImportCallKind(Handle<JSReceiver> target,
bool has_bigint_feature) {
if (WasmExportedFunction::IsWasmExportedFunction(*target)) {
auto imported_function = WasmExportedFunction::cast(*target);
- wasm::FunctionSig* imported_sig =
- imported_function->instance()
- ->module()
- ->functions[imported_function->function_index()]
- .sig;
+ auto func_index = imported_function->function_index();
+ auto module = imported_function->instance()->module();
+ wasm::FunctionSig* imported_sig = module->functions[func_index].sig;
if (*imported_sig != *expected_sig) {
return WasmImportCallKind::kLinkError;
}
+ if (static_cast<uint32_t>(func_index) < module->num_imported_functions) {
+ // TODO(wasm): this redirects all imported-reexported functions
+ // through the call builtin. Fall through to JS function cases below?
+ return WasmImportCallKind::kUseCallBuiltin;
+ }
return WasmImportCallKind::kWasmToWasm;
}
// Assuming we are calling to JS, check whether this would be a runtime error.