Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/runtime/runtime-wasm.cc')
-rw-r--r--deps/v8/src/runtime/runtime-wasm.cc238
1 files changed, 31 insertions, 207 deletions
diff --git a/deps/v8/src/runtime/runtime-wasm.cc b/deps/v8/src/runtime/runtime-wasm.cc
index f65922064f1..96c88357003 100644
--- a/deps/v8/src/runtime/runtime-wasm.cc
+++ b/deps/v8/src/runtime/runtime-wasm.cc
@@ -17,6 +17,7 @@
#include "src/runtime/runtime-utils.h"
#include "src/trap-handler/trap-handler.h"
#include "src/wasm/module-compiler.h"
+#include "src/wasm/value-type.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-constants.h"
#include "src/wasm/wasm-debug.h"
@@ -53,7 +54,7 @@ class FrameFinder {
};
WasmInstanceObject GetWasmInstanceOnStackTop(Isolate* isolate) {
- return FrameFinder<WasmCompiledFrame, StackFrame::EXIT>(isolate)
+ return FrameFinder<WasmFrame, StackFrame::EXIT>(isolate)
.frame()
->wasm_instance();
}
@@ -86,6 +87,8 @@ Object ThrowWasmError(Isolate* isolate, MessageTemplate message) {
} // namespace
RUNTIME_FUNCTION(Runtime_WasmIsValidFuncRefValue) {
+ // This code is called from wrappers, so the "thread is wasm" flag is not set.
+ DCHECK(!trap_handler::IsThreadInWasm());
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, function, 0);
@@ -100,6 +103,7 @@ RUNTIME_FUNCTION(Runtime_WasmIsValidFuncRefValue) {
}
RUNTIME_FUNCTION(Runtime_WasmMemoryGrow) {
+ ClearThreadInWasmScope flag_scope;
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
@@ -107,9 +111,6 @@ RUNTIME_FUNCTION(Runtime_WasmMemoryGrow) {
// which calls this runtime function.
CONVERT_UINT32_ARG_CHECKED(delta_pages, 1);
- // This runtime function is always being called from wasm code.
- ClearThreadInWasmScope flag_scope;
-
int ret = WasmMemoryObject::Grow(
isolate, handle(instance->memory_object(), isolate), delta_pages);
// The WasmMemoryGrow builtin which calls this runtime function expects us to
@@ -125,12 +126,17 @@ RUNTIME_FUNCTION(Runtime_ThrowWasmError) {
}
RUNTIME_FUNCTION(Runtime_ThrowWasmStackOverflow) {
+ ClearThreadInWasmScope clear_wasm_flag;
SealHandleScope shs(isolate);
DCHECK_LE(0, args.length());
return isolate->StackOverflow();
}
RUNTIME_FUNCTION(Runtime_WasmThrowTypeError) {
+ // This runtime function is called both from wasm and from e.g. js-to-js
+ // functions. Hence the "thread in wasm" flag can be either set or not. Both
+ // is OK, since throwing will trigger unwinding anyway, which sets the flag
+ // correctly depending on the handler.
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
THROW_NEW_ERROR_RETURN_FAILURE(
@@ -138,6 +144,7 @@ RUNTIME_FUNCTION(Runtime_WasmThrowTypeError) {
}
RUNTIME_FUNCTION(Runtime_WasmThrowCreate) {
+ ClearThreadInWasmScope clear_wasm_flag;
// TODO(kschimpf): Can this be replaced with equivalent TurboFan code/calls.
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
@@ -163,173 +170,10 @@ RUNTIME_FUNCTION(Runtime_WasmThrowCreate) {
return *exception;
}
-RUNTIME_FUNCTION(Runtime_WasmExceptionGetTag) {
- // TODO(kschimpf): Can this be replaced with equivalent TurboFan code/calls.
- HandleScope scope(isolate);
- DCHECK_EQ(1, args.length());
- DCHECK(isolate->context().is_null());
- isolate->set_context(GetNativeContextFromWasmInstanceOnStackTop(isolate));
- CONVERT_ARG_CHECKED(Object, except_obj_raw, 0);
- // TODO(wasm): Manually box because parameters are not visited yet.
- Handle<Object> except_obj(except_obj_raw, isolate);
- if (!except_obj->IsWasmExceptionPackage(isolate)) {
- return ReadOnlyRoots(isolate).undefined_value();
- }
- Handle<WasmExceptionPackage> exception =
- Handle<WasmExceptionPackage>::cast(except_obj);
- return *WasmExceptionPackage::GetExceptionTag(isolate, exception);
-}
-
-RUNTIME_FUNCTION(Runtime_WasmExceptionGetValues) {
- // TODO(kschimpf): Can this be replaced with equivalent TurboFan code/calls.
- HandleScope scope(isolate);
- DCHECK_EQ(1, args.length());
- DCHECK(isolate->context().is_null());
- isolate->set_context(GetNativeContextFromWasmInstanceOnStackTop(isolate));
- CONVERT_ARG_CHECKED(Object, except_obj_raw, 0);
- // TODO(wasm): Manually box because parameters are not visited yet.
- Handle<Object> except_obj(except_obj_raw, isolate);
- if (!except_obj->IsWasmExceptionPackage(isolate)) {
- return ReadOnlyRoots(isolate).undefined_value();
- }
- Handle<WasmExceptionPackage> exception =
- Handle<WasmExceptionPackage>::cast(except_obj);
- return *WasmExceptionPackage::GetExceptionValues(isolate, exception);
-}
-
-RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) {
- DCHECK_EQ(2, args.length());
- HandleScope scope(isolate);
- CONVERT_NUMBER_CHECKED(int32_t, func_index, Int32, args[0]);
- CONVERT_ARG_HANDLE_CHECKED(Object, arg_buffer_obj, 1);
-
- // The arg buffer is the raw pointer to the caller's stack. It looks like a
- // Smi (lowest bit not set, as checked by IsSmi), but is no valid Smi. We just
- // cast it back to the raw pointer.
- CHECK(!arg_buffer_obj->IsHeapObject());
- CHECK(arg_buffer_obj->IsSmi());
- Address arg_buffer = arg_buffer_obj->ptr();
-
- ClearThreadInWasmScope wasm_flag;
-
- // Find the frame pointer and instance of the interpreter frame on the stack.
- Handle<WasmInstanceObject> instance;
- Address frame_pointer = 0;
- {
- FrameFinder<WasmInterpreterEntryFrame, StackFrame::EXIT> frame_finder(
- isolate);
- instance = handle(frame_finder.frame()->wasm_instance(), isolate);
- frame_pointer = frame_finder.frame()->fp();
- }
-
- // Reserve buffers for argument and return values.
- DCHECK_GE(instance->module()->functions.size(), func_index);
- const wasm::FunctionSig* sig = instance->module()->functions[func_index].sig;
- DCHECK_GE(kMaxInt, sig->parameter_count());
- int num_params = static_cast<int>(sig->parameter_count());
- ScopedVector<wasm::WasmValue> wasm_args(num_params);
- DCHECK_GE(kMaxInt, sig->return_count());
- int num_returns = static_cast<int>(sig->return_count());
- ScopedVector<wasm::WasmValue> wasm_rets(num_returns);
-
- // Copy the arguments for the {arg_buffer} into a vector of {WasmValue}. This
- // also boxes reference types into handles, which needs to happen before any
- // methods that could trigger a GC are being called.
- Address arg_buf_ptr = arg_buffer;
- for (int i = 0; i < num_params; ++i) {
-#define CASE_ARG_TYPE(type, ctype) \
- case wasm::ValueType::type: \
- DCHECK_EQ(sig->GetParam(i).element_size_bytes(), sizeof(ctype)); \
- wasm_args[i] = \
- wasm::WasmValue(base::ReadUnalignedValue<ctype>(arg_buf_ptr)); \
- arg_buf_ptr += sizeof(ctype); \
- break;
- switch (sig->GetParam(i).kind()) {
- CASE_ARG_TYPE(kI32, uint32_t)
- CASE_ARG_TYPE(kI64, uint64_t)
- CASE_ARG_TYPE(kF32, float)
- CASE_ARG_TYPE(kF64, double)
-#undef CASE_ARG_TYPE
- case wasm::ValueType::kAnyRef:
- case wasm::ValueType::kFuncRef:
- case wasm::ValueType::kNullRef:
- case wasm::ValueType::kExnRef: {
- DCHECK_EQ(sig->GetParam(i).element_size_bytes(), kSystemPointerSize);
- Handle<Object> ref(
- Object(base::ReadUnalignedValue<Address>(arg_buf_ptr)), isolate);
- DCHECK_IMPLIES(sig->GetParam(i) == wasm::kWasmNullRef, ref->IsNull());
- wasm_args[i] = wasm::WasmValue(ref);
- arg_buf_ptr += kSystemPointerSize;
- break;
- }
- case wasm::ValueType::kStmt:
- case wasm::ValueType::kS128:
- case wasm::ValueType::kBottom:
- UNREACHABLE();
- }
- }
-
- // Set the current isolate's context.
- DCHECK(isolate->context().is_null());
- isolate->set_context(instance->native_context());
-
- // Run the function in the interpreter. Note that neither the {WasmDebugInfo}
- // nor the {InterpreterHandle} have to exist, because interpretation might
- // have been triggered by another Isolate sharing the same WasmEngine.
- Handle<WasmDebugInfo> debug_info =
- WasmInstanceObject::GetOrCreateDebugInfo(instance);
- bool success = WasmDebugInfo::RunInterpreter(
- isolate, debug_info, frame_pointer, func_index, wasm_args, wasm_rets);
-
- // Early return on failure.
- if (!success) {
- DCHECK(isolate->has_pending_exception());
- return ReadOnlyRoots(isolate).exception();
- }
-
- // Copy return values from the vector of {WasmValue} into {arg_buffer}. This
- // also un-boxes reference types from handles into raw pointers.
- arg_buf_ptr = arg_buffer;
- for (int i = 0; i < num_returns; ++i) {
-#define CASE_RET_TYPE(type, ctype) \
- case wasm::ValueType::type: \
- DCHECK_EQ(sig->GetReturn(i).element_size_bytes(), sizeof(ctype)); \
- base::WriteUnalignedValue<ctype>(arg_buf_ptr, wasm_rets[i].to<ctype>()); \
- arg_buf_ptr += sizeof(ctype); \
- break;
- switch (sig->GetReturn(i).kind()) {
- CASE_RET_TYPE(kI32, uint32_t)
- CASE_RET_TYPE(kI64, uint64_t)
- CASE_RET_TYPE(kF32, float)
- CASE_RET_TYPE(kF64, double)
-#undef CASE_RET_TYPE
- case wasm::ValueType::kAnyRef:
- case wasm::ValueType::kFuncRef:
- case wasm::ValueType::kNullRef:
- case wasm::ValueType::kExnRef: {
- DCHECK_EQ(sig->GetReturn(i).element_size_bytes(), kSystemPointerSize);
- DCHECK_IMPLIES(sig->GetReturn(i) == wasm::kWasmNullRef,
- wasm_rets[i].to_anyref()->IsNull());
- base::WriteUnalignedValue<Object>(arg_buf_ptr,
- *wasm_rets[i].to_anyref());
- arg_buf_ptr += kSystemPointerSize;
- break;
- }
- default:
- UNREACHABLE();
- }
- }
-
- return ReadOnlyRoots(isolate).undefined_value();
-}
-
RUNTIME_FUNCTION(Runtime_WasmStackGuard) {
+ ClearThreadInWasmScope wasm_flag;
SealHandleScope shs(isolate);
DCHECK_EQ(0, args.length());
- DCHECK(!trap_handler::IsTrapHandlerEnabled() ||
- trap_handler::IsThreadInWasm());
-
- ClearThreadInWasmScope wasm_flag;
// Check if this is a real stack overflow.
StackLimitCheck check(isolate);
@@ -339,14 +183,12 @@ RUNTIME_FUNCTION(Runtime_WasmStackGuard) {
}
RUNTIME_FUNCTION(Runtime_WasmCompileLazy) {
+ ClearThreadInWasmScope wasm_flag;
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
CONVERT_SMI_ARG_CHECKED(func_index, 1);
- // This runtime function is always called from wasm code.
- ClearThreadInWasmScope flag_scope;
-
#ifdef DEBUG
FrameFinder<WasmCompileLazyFrame, StackFrame::EXIT> frame_finder(isolate);
DCHECK_EQ(*instance, frame_finder.frame()->wasm_instance());
@@ -367,7 +209,7 @@ RUNTIME_FUNCTION(Runtime_WasmCompileLazy) {
}
// Should be called from within a handle scope
-Handle<JSArrayBuffer> getSharedArrayBuffer(Handle<WasmInstanceObject> instance,
+Handle<JSArrayBuffer> GetSharedArrayBuffer(Handle<WasmInstanceObject> instance,
Isolate* isolate, uint32_t address) {
DCHECK(instance->has_memory_object());
Handle<JSArrayBuffer> array_buffer(instance->memory_object().array_buffer(),
@@ -389,7 +231,7 @@ RUNTIME_FUNCTION(Runtime_WasmAtomicNotify) {
CONVERT_NUMBER_CHECKED(uint32_t, address, Uint32, args[1]);
CONVERT_NUMBER_CHECKED(uint32_t, count, Uint32, args[2]);
Handle<JSArrayBuffer> array_buffer =
- getSharedArrayBuffer(instance, isolate, address);
+ GetSharedArrayBuffer(instance, isolate, address);
return FutexEmulation::Wake(array_buffer, address, count);
}
@@ -403,7 +245,7 @@ RUNTIME_FUNCTION(Runtime_WasmI32AtomicWait) {
CONVERT_ARG_HANDLE_CHECKED(BigInt, timeout_ns, 3);
Handle<JSArrayBuffer> array_buffer =
- getSharedArrayBuffer(instance, isolate, address);
+ GetSharedArrayBuffer(instance, isolate, address);
return FutexEmulation::WaitWasm32(isolate, array_buffer, address,
expected_value, timeout_ns->AsInt64());
}
@@ -418,7 +260,7 @@ RUNTIME_FUNCTION(Runtime_WasmI64AtomicWait) {
CONVERT_ARG_HANDLE_CHECKED(BigInt, timeout_ns, 3);
Handle<JSArrayBuffer> array_buffer =
- getSharedArrayBuffer(instance, isolate, address);
+ GetSharedArrayBuffer(instance, isolate, address);
return FutexEmulation::WaitWasm64(isolate, array_buffer, address,
expected_value->AsInt64(),
timeout_ns->AsInt64());
@@ -439,15 +281,11 @@ Object ThrowTableOutOfBounds(Isolate* isolate,
} // namespace
RUNTIME_FUNCTION(Runtime_WasmRefFunc) {
- // This runtime function is always being called from wasm code.
ClearThreadInWasmScope flag_scope;
HandleScope scope(isolate);
- DCHECK_EQ(1, args.length());
- auto instance =
- Handle<WasmInstanceObject>(GetWasmInstanceOnStackTop(isolate), isolate);
- DCHECK(isolate->context().is_null());
- isolate->set_context(instance->native_context());
- CONVERT_UINT32_ARG_CHECKED(function_index, 0);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
+ CONVERT_UINT32_ARG_CHECKED(function_index, 1);
Handle<WasmExternalFunction> function =
WasmInstanceObject::GetOrCreateWasmExternalFunction(isolate, instance,
@@ -457,9 +295,7 @@ RUNTIME_FUNCTION(Runtime_WasmRefFunc) {
}
RUNTIME_FUNCTION(Runtime_WasmFunctionTableGet) {
- // This runtime function is always being called from wasm code.
ClearThreadInWasmScope flag_scope;
-
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
@@ -468,6 +304,8 @@ RUNTIME_FUNCTION(Runtime_WasmFunctionTableGet) {
DCHECK_LT(table_index, instance->tables().length());
auto table = handle(
WasmTableObject::cast(instance->tables().get(table_index)), isolate);
+ // We only use the runtime call for lazily initialized function references.
+ DCHECK_EQ(table->type(), wasm::kWasmFuncRef);
if (!WasmTableObject::IsInBounds(isolate, table, entry_index)) {
return ThrowWasmError(isolate, MessageTemplate::kWasmTrapTableOutOfBounds);
@@ -477,9 +315,7 @@ RUNTIME_FUNCTION(Runtime_WasmFunctionTableGet) {
}
RUNTIME_FUNCTION(Runtime_WasmFunctionTableSet) {
- // This runtime function is always being called from wasm code.
ClearThreadInWasmScope flag_scope;
-
HandleScope scope(isolate);
DCHECK_EQ(4, args.length());
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
@@ -491,6 +327,8 @@ RUNTIME_FUNCTION(Runtime_WasmFunctionTableSet) {
DCHECK_LT(table_index, instance->tables().length());
auto table = handle(
WasmTableObject::cast(instance->tables().get(table_index)), isolate);
+ // We only use the runtime call for function references.
+ DCHECK_EQ(table->type(), wasm::kWasmFuncRef);
if (!WasmTableObject::IsInBounds(isolate, table, entry_index)) {
return ThrowWasmError(isolate, MessageTemplate::kWasmTrapTableOutOfBounds);
@@ -500,6 +338,7 @@ RUNTIME_FUNCTION(Runtime_WasmFunctionTableSet) {
}
RUNTIME_FUNCTION(Runtime_WasmTableInit) {
+ ClearThreadInWasmScope flag_scope;
HandleScope scope(isolate);
DCHECK_EQ(6, args.length());
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
@@ -518,6 +357,7 @@ RUNTIME_FUNCTION(Runtime_WasmTableInit) {
}
RUNTIME_FUNCTION(Runtime_WasmTableCopy) {
+ ClearThreadInWasmScope flag_scope;
HandleScope scope(isolate);
DCHECK_EQ(6, args.length());
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
@@ -536,6 +376,7 @@ RUNTIME_FUNCTION(Runtime_WasmTableCopy) {
}
RUNTIME_FUNCTION(Runtime_WasmTableGrow) {
+ ClearThreadInWasmScope flag_scope;
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
auto instance =
@@ -554,6 +395,7 @@ RUNTIME_FUNCTION(Runtime_WasmTableGrow) {
}
RUNTIME_FUNCTION(Runtime_WasmTableFill) {
+ ClearThreadInWasmScope flag_scope;
HandleScope scope(isolate);
DCHECK_EQ(4, args.length());
auto instance =
@@ -585,29 +427,11 @@ RUNTIME_FUNCTION(Runtime_WasmTableFill) {
return ReadOnlyRoots(isolate).undefined_value();
}
-RUNTIME_FUNCTION(Runtime_WasmNewMultiReturnFixedArray) {
- DCHECK_EQ(1, args.length());
- HandleScope scope(isolate);
- CONVERT_INT32_ARG_CHECKED(size, 0);
- Handle<FixedArray> fixed_array = isolate->factory()->NewFixedArray(size);
- return *fixed_array;
-}
-
-RUNTIME_FUNCTION(Runtime_WasmNewMultiReturnJSArray) {
- HandleScope scope(isolate);
- DCHECK_EQ(1, args.length());
- DCHECK(!isolate->context().is_null());
- CONVERT_ARG_CHECKED(FixedArray, fixed_array, 0);
- Handle<FixedArray> fixed_array_handle(fixed_array, isolate);
- Handle<JSArray> array = isolate->factory()->NewJSArrayWithElements(
- fixed_array_handle, PACKED_ELEMENTS);
- return *array;
-}
-
RUNTIME_FUNCTION(Runtime_WasmDebugBreak) {
+ ClearThreadInWasmScope flag_scope;
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
- FrameFinder<WasmCompiledFrame, StackFrame::EXIT, StackFrame::WASM_DEBUG_BREAK>
+ FrameFinder<WasmFrame, StackFrame::EXIT, StackFrame::WASM_DEBUG_BREAK>
frame_finder(isolate);
auto instance = handle(frame_finder.frame()->wasm_instance(), isolate);
int position = frame_finder.frame()->position();
@@ -617,7 +441,7 @@ RUNTIME_FUNCTION(Runtime_WasmDebugBreak) {
DebugScope debug_scope(isolate->debug());
const auto undefined = ReadOnlyRoots(isolate).undefined_value();
- WasmCompiledFrame* frame = frame_finder.frame();
+ WasmFrame* frame = frame_finder.frame();
auto* debug_info = frame->native_module()->GetDebugInfo();
if (debug_info->IsStepping(frame)) {
debug_info->ClearStepping();