Commit 61c2a0f4 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm] Remove interpreter entry code

This removes the interpreter entry stubs, which are used to redirect
specific wasm functions to the interpreter. It is only needed when
mixing JS code with interpreted Wasm code, otherwise the test functions
just call the interpreter directly.
Thus a lot of tests that contain such interaction between JS and Wasm
need to be restricted to execute in Liftoff and TurboFan only.

After this CL, the WASM_INTERPRETER_ENTRY frame type and the
corresponding WasmInterpreterEntryFrame are dead, and will be removed in
a follow-up CL.

R=thibaudm@chromium.org

Bug: v8:10389
Change-Id: I8e50d350dbc2afcc1cddaeb98baf23711117af2d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2172962
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67559}
parent 843c8de8
......@@ -5917,78 +5917,6 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
if (ContainsInt64(sig_)) LowerInt64(kCalledFromWasm);
}
void BuildWasmInterpreterEntry(int func_index) {
int param_count = static_cast<int>(sig_->parameter_count());
// Build the start and the parameter nodes.
SetEffectControl(Start(param_count + 3));
// Create the instance_node from the passed parameter.
instance_node_.set(Param(wasm::kWasmInstanceParameterIndex));
// Compute size for the argument buffer.
int args_size_bytes = 0;
for (wasm::ValueType type : sig_->parameters()) {
args_size_bytes += type.element_size_bytes();
}
// The return value is also passed via this buffer:
int return_size_bytes = 0;
for (wasm::ValueType type : sig_->returns()) {
return_size_bytes += type.element_size_bytes();
}
// Get a stack slot for the arguments.
Node* arg_buffer =
args_size_bytes == 0 && return_size_bytes == 0
? mcgraph()->IntPtrConstant(0)
: graph()->NewNode(mcgraph()->machine()->StackSlot(
std::max(args_size_bytes, return_size_bytes), 8));
// Now store all our arguments to the buffer.
int offset = 0;
for (int i = 0; i < param_count; ++i) {
wasm::ValueType type = sig_->GetParam(i);
// Start from the parameter with index 1 to drop the instance_node.
SetEffect(graph()->NewNode(GetSafeStoreOperator(offset, type), arg_buffer,
Int32Constant(offset), Param(i + 1), effect(),
control()));
offset += type.element_size_bytes();
}
DCHECK_EQ(args_size_bytes, offset);
// We are passing the raw arg_buffer here. To the GC and other parts, it
// looks like a Smi (lowest bit not set). In the runtime function however,
// don't call Smi::value on it, but just cast it to a byte pointer.
Node* parameters[] = {
graph()->NewNode(mcgraph()->common()->NumberConstant(func_index)),
arg_buffer};
BuildCallToRuntime(Runtime::kWasmRunInterpreter, parameters,
arraysize(parameters));
// Read back the return value.
DCHECK_LT(sig_->return_count(), wasm::kV8MaxWasmFunctionMultiReturns);
size_t return_count = sig_->return_count();
if (return_count == 0) {
Return(Int32Constant(0));
} else {
base::SmallVector<Node*, 8> returns(return_count);
offset = 0;
for (size_t i = 0; i < return_count; ++i) {
wasm::ValueType type = sig_->GetReturn(i);
Node* val = SetEffect(
graph()->NewNode(GetSafeLoadOperator(offset, type), arg_buffer,
Int32Constant(offset), effect(), control()));
returns[i] = val;
offset += type.element_size_bytes();
}
Return(VectorOf(returns));
}
if (ContainsInt64(sig_)) LowerInt64(kCalledFromWasm);
}
void BuildJSToJSWrapper(Isolate* isolate) {
int wasm_count = static_cast<int>(sig_->parameter_count());
......@@ -6535,46 +6463,6 @@ wasm::WasmCode* CompileWasmCapiCallWrapper(wasm::WasmEngine* wasm_engine,
return native_module->PublishCode(std::move(wasm_code));
}
wasm::WasmCompilationResult CompileWasmInterpreterEntry(
wasm::WasmEngine* wasm_engine, const wasm::WasmFeatures& enabled_features,
uint32_t func_index, const wasm::FunctionSig* sig) {
//----------------------------------------------------------------------------
// Create the Graph
//----------------------------------------------------------------------------
Zone zone(wasm_engine->allocator(), ZONE_NAME);
Graph* graph = new (&zone) Graph(&zone);
CommonOperatorBuilder* common = new (&zone) CommonOperatorBuilder(&zone);
MachineOperatorBuilder* machine = new (&zone) MachineOperatorBuilder(
&zone, MachineType::PointerRepresentation(),
InstructionSelector::SupportedMachineOperatorFlags(),
InstructionSelector::AlignmentRequirements());
MachineGraph* mcgraph = new (&zone) MachineGraph(graph, common, machine);
WasmWrapperGraphBuilder builder(&zone, mcgraph, sig, nullptr,
StubCallMode::kCallWasmRuntimeStub,
enabled_features);
builder.BuildWasmInterpreterEntry(func_index);
// Schedule and compile to machine code.
CallDescriptor* incoming = GetWasmCallDescriptor(&zone, sig);
if (machine->Is32()) {
incoming = GetI32WasmCallDescriptor(&zone, incoming);
}
EmbeddedVector<char, 32> func_name;
func_name.Truncate(
SNPrintF(func_name, "wasm-interpreter-entry#%d", func_index));
wasm::WasmCompilationResult result = Pipeline::GenerateCodeForWasmNativeStub(
wasm_engine, incoming, mcgraph, Code::WASM_INTERPRETER_ENTRY,
wasm::WasmCode::kInterpreterEntry, func_name.begin(),
WasmStubAssemblerOptions());
result.result_tier = wasm::ExecutionTier::kInterpreter;
result.kind = wasm::WasmCompilationResult::kInterpreterEntry;
return result;
}
MaybeHandle<Code> CompileJSToJSWrapper(Isolate* isolate,
const wasm::FunctionSig* sig) {
std::unique_ptr<Zone> zone =
......@@ -6800,25 +6688,6 @@ wasm::WasmCompilationResult ExecuteTurbofanWasmCompilation(
return std::move(*result);
}
wasm::WasmCompilationResult ExecuteInterpreterEntryCompilation(
wasm::WasmEngine* wasm_engine, wasm::CompilationEnv* env,
const wasm::FunctionBody& func_body, int func_index, Counters* counters,
wasm::WasmFeatures* detected) {
Zone zone(wasm_engine->allocator(), ZONE_NAME);
const wasm::WasmModule* module = env ? env->module : nullptr;
wasm::WasmFullDecoder<wasm::Decoder::kValidate, wasm::EmptyInterface> decoder(
&zone, module, env->enabled_features, detected, func_body);
decoder.Decode();
if (decoder.failed()) return wasm::WasmCompilationResult{};
wasm::WasmCompilationResult result = CompileWasmInterpreterEntry(
wasm_engine, env->enabled_features, func_index, func_body.sig);
DCHECK(result.succeeded());
DCHECK_EQ(wasm::ExecutionTier::kInterpreter, result.result_tier);
return result;
}
namespace {
// Helper for allocating either an GP or FP reg, or the next stack slot.
class LinkageLocationAllocator {
......
......@@ -54,10 +54,6 @@ wasm::WasmCompilationResult ExecuteTurbofanWasmCompilation(
wasm::WasmEngine*, wasm::CompilationEnv*, const wasm::FunctionBody&,
int func_index, Counters*, wasm::WasmFeatures* detected);
wasm::WasmCompilationResult ExecuteInterpreterEntryCompilation(
wasm::WasmEngine*, wasm::CompilationEnv*, const wasm::FunctionBody&,
int func_index, Counters*, wasm::WasmFeatures* detected);
// Calls to Wasm imports are handled in several different ways, depending on the
// type of the target function/callable and whether the signature matches the
// argument arity.
......@@ -126,12 +122,6 @@ std::unique_ptr<OptimizedCompilationJob> NewJSToWasmCompilationJob(
const wasm::FunctionSig* sig, bool is_import,
const wasm::WasmFeatures& enabled_features);
// Compiles a stub that redirects a call to a wasm function to the wasm
// interpreter. It's ABI compatible with the compiled wasm function.
V8_EXPORT_PRIVATE wasm::WasmCompilationResult CompileWasmInterpreterEntry(
wasm::WasmEngine*, const wasm::WasmFeatures& enabled_features,
uint32_t func_index, const wasm::FunctionSig*);
// Compiles a stub with JS linkage that serves as an adapter for function
// objects constructed via {WebAssembly.Function}. It performs a round-trip
// simulating a JS-to-Wasm-to-JS coercion of parameter and return values.
......
......@@ -170,134 +170,6 @@ RUNTIME_FUNCTION(Runtime_WasmThrowCreate) {
return *exception;
}
RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) {
ClearThreadInWasmScope wasm_flag;
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
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();
// 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:
case wasm::ValueType::kRef:
case wasm::ValueType::kOptRef:
case wasm::ValueType::kEqRef: {
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);
......
......@@ -559,7 +559,6 @@ namespace internal {
F(WasmI64AtomicWait, 5, 1) \
F(WasmAtomicNotify, 3, 1) \
F(WasmMemoryGrow, 2, 1) \
F(WasmRunInterpreter, 2, 1) \
F(WasmStackGuard, 0, 1) \
F(WasmThrowCreate, 2, 1) \
F(WasmThrowTypeError, 0, 1) \
......
......@@ -205,9 +205,7 @@ WasmCompilationResult WasmCompilationUnit::ExecuteFunctionCompilation(
break;
case ExecutionTier::kInterpreter:
result = compiler::ExecuteInterpreterEntryCompilation(
wasm_engine, env, func_body, func_index_, counters, detected);
break;
UNREACHABLE();
}
return result;
......
......@@ -899,24 +899,8 @@ void DebugInfo::RemoveDebugSideTables(Vector<WasmCode* const> code) {
namespace {
wasm::InterpreterHandle* GetOrCreateInterpreterHandle(
Isolate* isolate, Handle<WasmDebugInfo> debug_info) {
Handle<Object> handle(debug_info->interpreter_handle(), isolate);
if (handle->IsUndefined(isolate)) {
// Use the maximum stack size to estimate the maximum size of the
// interpreter. The interpreter keeps its own stack internally, and the size
// of the stack should dominate the overall size of the interpreter. We
// multiply by '2' to account for the growing strategy for the backing store
// of the stack.
size_t interpreter_size = FLAG_stack_size * KB * 2;
handle = Managed<wasm::InterpreterHandle>::Allocate(
isolate, interpreter_size, isolate, debug_info);
debug_info->set_interpreter_handle(*handle);
}
return Handle<Managed<wasm::InterpreterHandle>>::cast(handle)->raw();
}
// TODO(clemensb): This method is indirectly dead. It can be removed once the
// WasmInterpreterEntryFrame is deleted.
wasm::InterpreterHandle* GetInterpreterHandle(WasmDebugInfo debug_info) {
Object handle_obj = debug_info.interpreter_handle();
DCHECK(!handle_obj.IsUndefined());
......@@ -952,20 +936,6 @@ wasm::WasmInterpreter* WasmDebugInfo::SetupForTesting(
return interp_handle->raw()->interpreter();
}
// static
bool WasmDebugInfo::RunInterpreter(Isolate* isolate,
Handle<WasmDebugInfo> debug_info,
Address frame_pointer, int func_index,
Vector<wasm::WasmValue> argument_values,
Vector<wasm::WasmValue> return_values) {
DCHECK_LE(0, func_index);
auto* handle = GetOrCreateInterpreterHandle(isolate, debug_info);
Handle<WasmInstanceObject> instance(debug_info->wasm_instance(), isolate);
return handle->Execute(instance, frame_pointer,
static_cast<uint32_t>(func_index), argument_values,
return_values);
}
std::vector<std::pair<uint32_t, int>> WasmDebugInfo::GetInterpretedStack(
Address frame_pointer) {
return GetInterpreterHandle(*this)->GetInterpretedStack(frame_pointer);
......
......@@ -843,16 +843,8 @@ class WasmDebugInfo : public Struct {
V8_EXPORT_PRIVATE static wasm::WasmInterpreter* SetupForTesting(
Handle<WasmInstanceObject>);
// Execute the specified function in the interpreter. Read arguments from the
// {argument_values} vector and write to {return_values} on regular exit.
// The frame_pointer will be used to identify the new activation of the
// interpreter for unwinding and frame inspection.
// Returns true if exited regularly, false if a trap occurred. In the latter
// case, a pending exception will have been set on the isolate.
static bool RunInterpreter(Isolate* isolate, Handle<WasmDebugInfo>,
Address frame_pointer, int func_index,
Vector<wasm::WasmValue> argument_values,
Vector<wasm::WasmValue> return_values);
// TODO(clemensb): The next three methods will become dead once the
// WasmInterpreterEntryFrame is deleted.
// Get the stack of the wasm interpreter as pairs of <function index, byte
// offset>. The list is ordered bottom-to-top, i.e. caller before callee.
......
......@@ -367,21 +367,21 @@ void TestTableCopyInbounds(ExecutionTier execution_tier, int table_dst,
}
}
WASM_EXEC_TEST(TableCopyInboundsFrom0To0) {
WASM_COMPILED_EXEC_TEST(TableCopyInboundsFrom0To0) {
TestTableCopyInbounds(execution_tier, 0, 0);
}
WASM_EXEC_TEST(TableCopyInboundsFrom3To0) {
WASM_COMPILED_EXEC_TEST(TableCopyInboundsFrom3To0) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyInbounds(execution_tier, 3, 0);
}
WASM_EXEC_TEST(TableCopyInboundsFrom5To9) {
WASM_COMPILED_EXEC_TEST(TableCopyInboundsFrom5To9) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyInbounds(execution_tier, 5, 9);
}
WASM_EXEC_TEST(TableCopyInboundsFrom6To6) {
WASM_COMPILED_EXEC_TEST(TableCopyInboundsFrom6To6) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyInbounds(execution_tier, 6, 6);
}
......@@ -476,12 +476,14 @@ void TestTableInitElems(ExecutionTier execution_tier, int table_index) {
CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 3, 4);
}
WASM_EXEC_TEST(TableInitElems0) { TestTableInitElems(execution_tier, 0); }
WASM_EXEC_TEST(TableInitElems7) {
WASM_COMPILED_EXEC_TEST(TableInitElems0) {
TestTableInitElems(execution_tier, 0);
}
WASM_COMPILED_EXEC_TEST(TableInitElems7) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableInitElems(execution_tier, 7);
}
WASM_EXEC_TEST(TableInitElems9) {
WASM_COMPILED_EXEC_TEST(TableInitElems9) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableInitElems(execution_tier, 9);
}
......@@ -555,12 +557,12 @@ void TestTableInitOob(ExecutionTier execution_tier, int table_index) {
r.CheckCallViaJS(0xDEADBEEF, 0, 10, 1);
}
WASM_EXEC_TEST(TableInitOob0) { TestTableInitOob(execution_tier, 0); }
WASM_EXEC_TEST(TableInitOob7) {
WASM_COMPILED_EXEC_TEST(TableInitOob0) { TestTableInitOob(execution_tier, 0); }
WASM_COMPILED_EXEC_TEST(TableInitOob7) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableInitOob(execution_tier, 7);
}
WASM_EXEC_TEST(TableInitOob9) {
WASM_COMPILED_EXEC_TEST(TableInitOob9) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableInitOob(execution_tier, 9);
}
......@@ -628,21 +630,21 @@ void TestTableCopyElems(ExecutionTier execution_tier, int table_dst,
}
}
WASM_EXEC_TEST(TableCopyElemsFrom0To0) {
WASM_COMPILED_EXEC_TEST(TableCopyElemsFrom0To0) {
TestTableCopyElems(execution_tier, 0, 0);
}
WASM_EXEC_TEST(TableCopyElemsFrom3To0) {
WASM_COMPILED_EXEC_TEST(TableCopyElemsFrom3To0) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyElems(execution_tier, 3, 0);
}
WASM_EXEC_TEST(TableCopyElemsFrom5To9) {
WASM_COMPILED_EXEC_TEST(TableCopyElemsFrom5To9) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyElems(execution_tier, 5, 9);
}
WASM_EXEC_TEST(TableCopyElemsFrom6To6) {
WASM_COMPILED_EXEC_TEST(TableCopyElemsFrom6To6) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyElems(execution_tier, 6, 6);
}
......@@ -703,21 +705,21 @@ void TestTableCopyCalls(ExecutionTier execution_tier, int table_dst,
}
}
WASM_EXEC_TEST(TableCopyCallsFrom0To0) {
WASM_COMPILED_EXEC_TEST(TableCopyCallsFrom0To0) {
TestTableCopyCalls(execution_tier, 0, 0);
}
WASM_EXEC_TEST(TableCopyCallsFrom3To0) {
WASM_COMPILED_EXEC_TEST(TableCopyCallsFrom3To0) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyCalls(execution_tier, 3, 0);
}
WASM_EXEC_TEST(TableCopyCallsFrom5To9) {
WASM_COMPILED_EXEC_TEST(TableCopyCallsFrom5To9) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyCalls(execution_tier, 5, 9);
}
WASM_EXEC_TEST(TableCopyCallsFrom6To6) {
WASM_COMPILED_EXEC_TEST(TableCopyCallsFrom6To6) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyCalls(execution_tier, 6, 6);
}
......@@ -779,21 +781,21 @@ void TestTableCopyOobWrites(ExecutionTier execution_tier, int table_dst,
CheckTable(isolate, table, f0, f1, f2, f3, f4);
}
WASM_EXEC_TEST(TableCopyOobWritesFrom0To0) {
WASM_COMPILED_EXEC_TEST(TableCopyOobWritesFrom0To0) {
TestTableCopyOobWrites(execution_tier, 0, 0);
}
WASM_EXEC_TEST(TableCopyOobWritesFrom3To0) {
WASM_COMPILED_EXEC_TEST(TableCopyOobWritesFrom3To0) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyOobWrites(execution_tier, 3, 0);
}
WASM_EXEC_TEST(TableCopyOobWritesFrom5To9) {
WASM_COMPILED_EXEC_TEST(TableCopyOobWritesFrom5To9) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyOobWrites(execution_tier, 5, 9);
}
WASM_EXEC_TEST(TableCopyOobWritesFrom6To6) {
WASM_COMPILED_EXEC_TEST(TableCopyOobWritesFrom6To6) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyOobWrites(execution_tier, 6, 6);
}
......@@ -838,26 +840,26 @@ void TestTableCopyOob1(ExecutionTier execution_tier, int table_dst,
}
}
WASM_EXEC_TEST(TableCopyOob1From0To0) {
WASM_COMPILED_EXEC_TEST(TableCopyOob1From0To0) {
TestTableCopyOob1(execution_tier, 0, 0);
}
WASM_EXEC_TEST(TableCopyOob1From3To0) {
WASM_COMPILED_EXEC_TEST(TableCopyOob1From3To0) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyOob1(execution_tier, 3, 0);
}
WASM_EXEC_TEST(TableCopyOob1From5To9) {
WASM_COMPILED_EXEC_TEST(TableCopyOob1From5To9) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyOob1(execution_tier, 5, 9);
}
WASM_EXEC_TEST(TableCopyOob1From6To6) {
WASM_COMPILED_EXEC_TEST(TableCopyOob1From6To6) {
EXPERIMENTAL_FLAG_SCOPE(anyref);
TestTableCopyOob1(execution_tier, 6, 6);
}
WASM_EXEC_TEST(ElemDropTwice) {
WASM_COMPILED_EXEC_TEST(ElemDropTwice) {
EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t> r(execution_tier);
r.builder().AddIndirectFunctionTable(nullptr, 1);
......@@ -868,7 +870,7 @@ WASM_EXEC_TEST(ElemDropTwice) {
r.CheckCallViaJS(0);
}
WASM_EXEC_TEST(ElemDropThenTableInit) {
WASM_COMPILED_EXEC_TEST(ElemDropThenTableInit) {
EXPERIMENTAL_FLAG_SCOPE(bulk_memory);
WasmRunner<uint32_t, uint32_t> r(execution_tier);
r.builder().AddIndirectFunctionTable(nullptr, 1);
......
......@@ -12,7 +12,7 @@ namespace internal {
namespace wasm {
namespace test_run_wasm_exceptions {
WASM_EXEC_TEST(TryCatchThrow) {
WASM_COMPILED_EXEC_TEST(TryCatchThrow) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
WasmRunner<uint32_t, uint32_t> r(execution_tier);
......@@ -32,7 +32,7 @@ WASM_EXEC_TEST(TryCatchThrow) {
r.CheckCallViaJS(kResult1, 1);
}
WASM_EXEC_TEST(TryCatchCallDirect) {
WASM_COMPILED_EXEC_TEST(TryCatchCallDirect) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
WasmRunner<uint32_t, uint32_t> r(execution_tier);
......@@ -60,7 +60,7 @@ WASM_EXEC_TEST(TryCatchCallDirect) {
r.CheckCallViaJS(kResult1, 1);
}
WASM_EXEC_TEST(TryCatchCallIndirect) {
WASM_COMPILED_EXEC_TEST(TryCatchCallIndirect) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
WasmRunner<uint32_t, uint32_t> r(execution_tier);
......@@ -97,7 +97,7 @@ WASM_EXEC_TEST(TryCatchCallIndirect) {
r.CheckCallViaJS(kResult1, 1);
}
WASM_EXEC_TEST(TryCatchCallExternal) {
WASM_COMPILED_EXEC_TEST(TryCatchCallExternal) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
HandleScope scope(CcTest::InitIsolateOnce());
......@@ -127,7 +127,7 @@ WASM_EXEC_TEST(TryCatchCallExternal) {
r.CheckCallViaJS(kResult1, 1);
}
WASM_EXEC_TEST(TryCatchTrapTypeError) {
WASM_COMPILED_EXEC_TEST(TryCatchTrapTypeError) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
HandleScope scope(CcTest::InitIsolateOnce());
......@@ -189,22 +189,22 @@ void TestTrapNotCaught(byte* code, size_t code_size,
} // namespace
WASM_EXEC_TEST(TryCatchTrapUnreachable) {
WASM_COMPILED_EXEC_TEST(TryCatchTrapUnreachable) {
byte code[] = {WASM_UNREACHABLE};
TestTrapNotCaught(code, arraysize(code), execution_tier);
}
WASM_EXEC_TEST(TryCatchTrapMemOutOfBounds) {
WASM_COMPILED_EXEC_TEST(TryCatchTrapMemOutOfBounds) {
byte code[] = {WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V_1(-1))};
TestTrapNotCaught(code, arraysize(code), execution_tier);
}
WASM_EXEC_TEST(TryCatchTrapDivByZero) {
WASM_COMPILED_EXEC_TEST(TryCatchTrapDivByZero) {
byte code[] = {WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I32V_1(0))};
TestTrapNotCaught(code, arraysize(code), execution_tier);
}
WASM_EXEC_TEST(TryCatchTrapRemByZero) {
WASM_COMPILED_EXEC_TEST(TryCatchTrapRemByZero) {
byte code[] = {WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_I32V_1(0))};
TestTrapNotCaught(code, arraysize(code), execution_tier);
}
......
......@@ -71,7 +71,7 @@ ManuallyImportedJSFunction CreateJSSelector(FunctionSig* sig, int which) {
}
} // namespace
WASM_EXEC_TEST(Run_Int32Sub_jswrapped) {
WASM_COMPILED_EXEC_TEST(Run_Int32Sub_jswrapped) {
WasmRunner<int, int, int> r(execution_tier);
BUILD(r, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
......@@ -79,7 +79,7 @@ WASM_EXEC_TEST(Run_Int32Sub_jswrapped) {
r.CheckCallViaJS(-8723487, -8000000, 723487);
}
WASM_EXEC_TEST(Run_Float32Div_jswrapped) {
WASM_COMPILED_EXEC_TEST(Run_Float32Div_jswrapped) {
WasmRunner<float, float, float> r(execution_tier);
BUILD(r, WASM_F32_DIV(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
......@@ -87,7 +87,7 @@ WASM_EXEC_TEST(Run_Float32Div_jswrapped) {
r.CheckCallViaJS(64, -16, -0.25);
}
WASM_EXEC_TEST(Run_Float64Add_jswrapped) {
WASM_COMPILED_EXEC_TEST(Run_Float64Add_jswrapped) {
WasmRunner<double, double, double> r(execution_tier);
BUILD(r, WASM_F64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
......@@ -95,7 +95,7 @@ WASM_EXEC_TEST(Run_Float64Add_jswrapped) {
r.CheckCallViaJS(-5.5, -5.25, -0.25);
}
WASM_EXEC_TEST(Run_I32Popcount_jswrapped) {
WASM_COMPILED_EXEC_TEST(Run_I32Popcount_jswrapped) {
WasmRunner<int, int> r(execution_tier);
BUILD(r, WASM_I32_POPCNT(WASM_GET_LOCAL(0)));
......@@ -104,7 +104,7 @@ WASM_EXEC_TEST(Run_I32Popcount_jswrapped) {
r.CheckCallViaJS(6, 0x3F);
}
WASM_EXEC_TEST(Run_CallJS_Add_jswrapped) {
WASM_COMPILED_EXEC_TEST(Run_CallJS_Add_jswrapped) {
TestSignatures sigs;
HandleScope scope(CcTest::InitIsolateOnce());
const char* source = "(function(a) { return a + 99; })";
......@@ -121,7 +121,7 @@ WASM_EXEC_TEST(Run_CallJS_Add_jswrapped) {
r.CheckCallViaJS(-666666801, -666666900);
}
WASM_EXEC_TEST(Run_IndirectCallJSFunction) {
WASM_COMPILED_EXEC_TEST(Run_IndirectCallJSFunction) {
Isolate* isolate = CcTest::InitIsolateOnce();
HandleScope scope(isolate);
TestSignatures sigs;
......@@ -192,42 +192,42 @@ void RunJSSelectTest(ExecutionTier tier, int which) {
}
}
WASM_EXEC_TEST(Run_JSSelect_0) {
WASM_COMPILED_EXEC_TEST(Run_JSSelect_0) {
CcTest::InitializeVM();
RunJSSelectTest(execution_tier, 0);
}
WASM_EXEC_TEST(Run_JSSelect_1) {
WASM_COMPILED_EXEC_TEST(Run_JSSelect_1) {
CcTest::InitializeVM();
RunJSSelectTest(execution_tier, 1);
}
WASM_EXEC_TEST(Run_JSSelect_2) {
WASM_COMPILED_EXEC_TEST(Run_JSSelect_2) {
CcTest::InitializeVM();
RunJSSelectTest(execution_tier, 2);
}
WASM_EXEC_TEST(Run_JSSelect_3) {
WASM_COMPILED_EXEC_TEST(Run_JSSelect_3) {
CcTest::InitializeVM();
RunJSSelectTest(execution_tier, 3);
}
WASM_EXEC_TEST(Run_JSSelect_4) {
WASM_COMPILED_EXEC_TEST(Run_JSSelect_4) {
CcTest::InitializeVM();
RunJSSelectTest(execution_tier, 4);
}
WASM_EXEC_TEST(Run_JSSelect_5) {
WASM_COMPILED_EXEC_TEST(Run_JSSelect_5) {
CcTest::InitializeVM();
RunJSSelectTest(execution_tier, 5);
}
WASM_EXEC_TEST(Run_JSSelect_6) {
WASM_COMPILED_EXEC_TEST(Run_JSSelect_6) {
CcTest::InitializeVM();
RunJSSelectTest(execution_tier, 6);
}
WASM_EXEC_TEST(Run_JSSelect_7) {
WASM_COMPILED_EXEC_TEST(Run_JSSelect_7) {
CcTest::InitializeVM();
RunJSSelectTest(execution_tier, 7);
}
......@@ -262,42 +262,42 @@ void RunWASMSelectTest(ExecutionTier tier, int which) {
}
}
WASM_EXEC_TEST(Run_WASMSelect_0) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_0) {
CcTest::InitializeVM();
RunWASMSelectTest(execution_tier, 0);
}
WASM_EXEC_TEST(Run_WASMSelect_1) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_1) {
CcTest::InitializeVM();
RunWASMSelectTest(execution_tier, 1);
}
WASM_EXEC_TEST(Run_WASMSelect_2) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_2) {
CcTest::InitializeVM();
RunWASMSelectTest(execution_tier, 2);
}
WASM_EXEC_TEST(Run_WASMSelect_3) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_3) {
CcTest::InitializeVM();
RunWASMSelectTest(execution_tier, 3);
}
WASM_EXEC_TEST(Run_WASMSelect_4) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_4) {
CcTest::InitializeVM();
RunWASMSelectTest(execution_tier, 4);
}
WASM_EXEC_TEST(Run_WASMSelect_5) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_5) {
CcTest::InitializeVM();
RunWASMSelectTest(execution_tier, 5);
}
WASM_EXEC_TEST(Run_WASMSelect_6) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_6) {
CcTest::InitializeVM();
RunWASMSelectTest(execution_tier, 6);
}
WASM_EXEC_TEST(Run_WASMSelect_7) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_7) {
CcTest::InitializeVM();
RunWASMSelectTest(execution_tier, 7);
}
......@@ -334,44 +334,44 @@ void RunWASMSelectAlignTest(ExecutionTier tier, int num_args, int num_params) {
}
}
WASM_EXEC_TEST(Run_WASMSelectAlign_0) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_0) {
CcTest::InitializeVM();
RunWASMSelectAlignTest(execution_tier, 0, 1);
RunWASMSelectAlignTest(execution_tier, 0, 2);
}
WASM_EXEC_TEST(Run_WASMSelectAlign_1) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_1) {
CcTest::InitializeVM();
RunWASMSelectAlignTest(execution_tier, 1, 2);
RunWASMSelectAlignTest(execution_tier, 1, 3);
}
WASM_EXEC_TEST(Run_WASMSelectAlign_2) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_2) {
CcTest::InitializeVM();
RunWASMSelectAlignTest(execution_tier, 2, 3);
RunWASMSelectAlignTest(execution_tier, 2, 4);
}
WASM_EXEC_TEST(Run_WASMSelectAlign_3) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_3) {
CcTest::InitializeVM();
RunWASMSelectAlignTest(execution_tier, 3, 3);
RunWASMSelectAlignTest(execution_tier, 3, 4);
}
WASM_EXEC_TEST(Run_WASMSelectAlign_4) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_4) {
CcTest::InitializeVM();
RunWASMSelectAlignTest(execution_tier, 4, 3);
RunWASMSelectAlignTest(execution_tier, 4, 4);
}
WASM_EXEC_TEST(Run_WASMSelectAlign_7) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_7) {
CcTest::InitializeVM();
RunWASMSelectAlignTest(execution_tier, 7, 5);
RunWASMSelectAlignTest(execution_tier, 7, 6);
RunWASMSelectAlignTest(execution_tier, 7, 7);
}
WASM_EXEC_TEST(Run_WASMSelectAlign_8) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_8) {
CcTest::InitializeVM();
RunWASMSelectAlignTest(execution_tier, 8, 5);
RunWASMSelectAlignTest(execution_tier, 8, 6);
......@@ -379,7 +379,7 @@ WASM_EXEC_TEST(Run_WASMSelectAlign_8) {
RunWASMSelectAlignTest(execution_tier, 8, 8);
}
WASM_EXEC_TEST(Run_WASMSelectAlign_9) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_9) {
CcTest::InitializeVM();
RunWASMSelectAlignTest(execution_tier, 9, 6);
RunWASMSelectAlignTest(execution_tier, 9, 7);
......@@ -387,7 +387,7 @@ WASM_EXEC_TEST(Run_WASMSelectAlign_9) {
RunWASMSelectAlignTest(execution_tier, 9, 9);
}
WASM_EXEC_TEST(Run_WASMSelectAlign_10) {
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_10) {
CcTest::InitializeVM();
RunWASMSelectAlignTest(execution_tier, 10, 7);
RunWASMSelectAlignTest(execution_tier, 10, 8);
......@@ -449,37 +449,37 @@ void RunJSSelectAlignTest(ExecutionTier tier, int num_args, int num_params) {
}
}
WASM_EXEC_TEST(Run_JSSelectAlign_0) {
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_0) {
CcTest::InitializeVM();
RunJSSelectAlignTest(execution_tier, 0, 1);
RunJSSelectAlignTest(execution_tier, 0, 2);
}
WASM_EXEC_TEST(Run_JSSelectAlign_1) {
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_1) {
CcTest::InitializeVM();
RunJSSelectAlignTest(execution_tier, 1, 2);
RunJSSelectAlignTest(execution_tier, 1, 3);
}
WASM_EXEC_TEST(Run_JSSelectAlign_2) {
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_2) {
CcTest::InitializeVM();
RunJSSelectAlignTest(execution_tier, 2, 3);
RunJSSelectAlignTest(execution_tier, 2, 4);
}
WASM_EXEC_TEST(Run_JSSelectAlign_3) {
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_3) {
CcTest::InitializeVM();
RunJSSelectAlignTest(execution_tier, 3, 3);
RunJSSelectAlignTest(execution_tier, 3, 4);
}
WASM_EXEC_TEST(Run_JSSelectAlign_4) {
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_4) {
CcTest::InitializeVM();
RunJSSelectAlignTest(execution_tier, 4, 3);
RunJSSelectAlignTest(execution_tier, 4, 4);
}
WASM_EXEC_TEST(Run_JSSelectAlign_7) {
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_7) {
CcTest::InitializeVM();
RunJSSelectAlignTest(execution_tier, 7, 3);
RunJSSelectAlignTest(execution_tier, 7, 4);
......@@ -487,7 +487,7 @@ WASM_EXEC_TEST(Run_JSSelectAlign_7) {
RunJSSelectAlignTest(execution_tier, 7, 4);
}
WASM_EXEC_TEST(Run_JSSelectAlign_8) {
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_8) {
CcTest::InitializeVM();
RunJSSelectAlignTest(execution_tier, 8, 5);
RunJSSelectAlignTest(execution_tier, 8, 6);
......@@ -495,7 +495,7 @@ WASM_EXEC_TEST(Run_JSSelectAlign_8) {
RunJSSelectAlignTest(execution_tier, 8, 8);
}
WASM_EXEC_TEST(Run_JSSelectAlign_9) {
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_9) {
CcTest::InitializeVM();
RunJSSelectAlignTest(execution_tier, 9, 6);
RunJSSelectAlignTest(execution_tier, 9, 7);
......@@ -503,7 +503,7 @@ WASM_EXEC_TEST(Run_JSSelectAlign_9) {
RunJSSelectAlignTest(execution_tier, 9, 9);
}
WASM_EXEC_TEST(Run_JSSelectAlign_10) {
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_10) {
CcTest::InitializeVM();
RunJSSelectAlignTest(execution_tier, 10, 7);
RunJSSelectAlignTest(execution_tier, 10, 8);
......@@ -560,11 +560,11 @@ void RunPickerTest(ExecutionTier tier, bool indirect) {
r.CheckCallApplyViaJS(right, rc_fn.function_index(), args_right, 1);
}
WASM_EXEC_TEST(Run_ReturnCallImportedFunction) {
WASM_COMPILED_EXEC_TEST(Run_ReturnCallImportedFunction) {
RunPickerTest(execution_tier, false);
}
WASM_EXEC_TEST(Run_ReturnCallIndirectImportedFunction) {
WASM_COMPILED_EXEC_TEST(Run_ReturnCallIndirectImportedFunction) {
RunPickerTest(execution_tier, true);
}
......
......@@ -104,7 +104,7 @@ void CheckComputeLocation(v8::internal::Isolate* i_isolate, Handle<Object> exc,
} // namespace
// Call from JS to wasm to JS and throw an Error from JS.
WASM_EXEC_TEST(CollectDetailedWasmStack_ExplicitThrowFromJs) {
WASM_COMPILED_EXEC_TEST(CollectDetailedWasmStack_ExplicitThrowFromJs) {
TestSignatures sigs;
HandleScope scope(CcTest::InitIsolateOnce());
const char* source =
......@@ -153,7 +153,7 @@ WASM_EXEC_TEST(CollectDetailedWasmStack_ExplicitThrowFromJs) {
}
// Trigger a trap in wasm, stack should contain a source url.
WASM_EXEC_TEST(CollectDetailedWasmStack_WasmUrl) {
WASM_COMPILED_EXEC_TEST(CollectDetailedWasmStack_WasmUrl) {
// Create a WasmRunner with stack checks and traps enabled.
WasmRunner<int> r(execution_tier, nullptr, "main", kRuntimeExceptionSupport);
......@@ -210,7 +210,7 @@ WASM_EXEC_TEST(CollectDetailedWasmStack_WasmUrl) {
}
// Trigger a trap in wasm, stack should be JS -> wasm -> wasm.
WASM_EXEC_TEST(CollectDetailedWasmStack_WasmError) {
WASM_COMPILED_EXEC_TEST(CollectDetailedWasmStack_WasmError) {
for (int pos_shift = 0; pos_shift < 3; ++pos_shift) {
// Test a position with 1, 2 or 3 bytes needed to represent it.
int unreachable_pos = 1 << (8 * pos_shift);
......
......@@ -66,7 +66,7 @@ void CheckExceptionInfos(v8::internal::Isolate* i_isolate, Handle<Object> exc,
} // namespace
// Trigger a trap for executing unreachable.
WASM_EXEC_TEST(Unreachable) {
WASM_COMPILED_EXEC_TEST(Unreachable) {
// Create a WasmRunner with stack checks and traps enabled.
WasmRunner<void> r(execution_tier, nullptr, "main", kRuntimeExceptionSupport);
TestSignatures sigs;
......@@ -100,7 +100,7 @@ WASM_EXEC_TEST(Unreachable) {
}
// Trigger a trap for loading from out-of-bounds.
WASM_EXEC_TEST(IllegalLoad) {
WASM_COMPILED_EXEC_TEST(IllegalLoad) {
WasmRunner<void> r(execution_tier, nullptr, "main", kRuntimeExceptionSupport);
TestSignatures sigs;
......
......@@ -174,17 +174,6 @@ uint32_t TestingModuleBuilder::AddFunction(const FunctionSig* sig,
}
if (interpreter_) {
interpreter_->AddFunctionForTesting(&test_module_->functions.back());
// Patch the jump table to call the interpreter for this function.
wasm::WasmCompilationResult result = compiler::CompileWasmInterpreterEntry(
isolate_->wasm_engine(), native_module_->enabled_features(), index,
sig);
std::unique_ptr<wasm::WasmCode> code = native_module_->AddCode(
index, result.code_desc, result.frame_slot_count,
result.tagged_parameter_slots,
result.protected_instructions_data.as_vector(),
result.source_positions.as_vector(), wasm::WasmCode::kInterpreterEntry,
wasm::ExecutionTier::kInterpreter, wasm::kNoDebugging);
native_module_->PublishCode(std::move(code));
}
DCHECK_LT(index, kMaxFunctions); // limited for testing.
return index;
......@@ -200,6 +189,7 @@ void TestingModuleBuilder::FreezeSignatureMapAndInitializeWrapperCache() {
}
Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) {
CHECK(!interpreter_);
FreezeSignatureMapAndInitializeWrapperCache();
SetExecutable();
return WasmInstanceObject::GetOrCreateWasmExternalFunction(
......
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