Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "test/cctest/wasm/wasm-run-utils.h"
6 :
7 : #include "src/assembler-inl.h"
8 : #include "src/code-tracer.h"
9 : #include "src/heap/heap-inl.h"
10 : #include "src/wasm/graph-builder-interface.h"
11 : #include "src/wasm/wasm-import-wrapper-cache-inl.h"
12 : #include "src/wasm/wasm-memory.h"
13 : #include "src/wasm/wasm-objects-inl.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 : namespace wasm {
18 :
19 1093612 : TestingModuleBuilder::TestingModuleBuilder(
20 : Zone* zone, ManuallyImportedJSFunction* maybe_import, ExecutionTier tier,
21 : RuntimeExceptionSupport exception_support, LowerSimd lower_simd)
22 : : test_module_(std::make_shared<WasmModule>()),
23 2187224 : test_module_ptr_(test_module_.get()),
24 1093612 : isolate_(CcTest::InitIsolateOnce()),
25 : enabled_features_(WasmFeaturesFromIsolate(isolate_)),
26 : execution_tier_(tier),
27 : runtime_exception_support_(exception_support),
28 3280836 : lower_simd_(lower_simd) {
29 1093612 : WasmJs::Install(isolate_, true);
30 1093612 : test_module_->untagged_globals_buffer_size = kMaxGlobalsSize;
31 1093612 : memset(globals_data_, 0, sizeof(globals_data_));
32 :
33 : uint32_t maybe_import_index = 0;
34 1093612 : if (maybe_import) {
35 : // Manually add an imported function before any other functions.
36 : // This must happen before the instance object is created, since the
37 : // instance object allocates import entries.
38 1992 : maybe_import_index = AddFunction(maybe_import->sig, nullptr, kImport);
39 : DCHECK_EQ(0, maybe_import_index);
40 : }
41 :
42 1093612 : instance_object_ = InitInstanceObject();
43 :
44 1093612 : if (maybe_import) {
45 : // Manually compile an import wrapper and insert it into the instance.
46 1992 : CodeSpaceMemoryModificationScope modification_scope(isolate_->heap());
47 : auto kind = compiler::GetWasmImportCallKind(maybe_import->js_function,
48 3984 : maybe_import->sig, false);
49 : auto import_wrapper = native_module_->import_wrapper_cache()->GetOrCompile(
50 5976 : isolate_->wasm_engine(), isolate_->counters(), kind, maybe_import->sig);
51 :
52 : ImportedFunctionEntry(instance_object_, maybe_import_index)
53 3984 : .SetWasmToJs(isolate_, maybe_import->js_function, import_wrapper);
54 : }
55 :
56 1093612 : if (tier == ExecutionTier::kInterpreter) {
57 364660 : interpreter_ = WasmDebugInfo::SetupForTesting(instance_object_);
58 : }
59 1093612 : }
60 :
61 41232 : byte* TestingModuleBuilder::AddMemory(uint32_t size) {
62 82464 : CHECK(!test_module_->has_memory);
63 41232 : CHECK_NULL(mem_start_);
64 41232 : CHECK_EQ(0, mem_size_);
65 : DCHECK(!instance_object_->has_memory_object());
66 : DCHECK_IMPLIES(test_module_->origin == kWasmOrigin,
67 : size % kWasmPageSize == 0);
68 41232 : test_module_->has_memory = true;
69 : uint32_t alloc_size = RoundUp(size, kWasmPageSize);
70 : Handle<JSArrayBuffer> new_buffer;
71 82464 : CHECK(NewArrayBuffer(isolate_, alloc_size).ToHandle(&new_buffer));
72 41232 : CHECK(!new_buffer.is_null());
73 41232 : mem_start_ = reinterpret_cast<byte*>(new_buffer->backing_store());
74 41232 : mem_size_ = size;
75 41232 : CHECK(size == 0 || mem_start_);
76 41232 : memset(mem_start_, 0, size);
77 :
78 : // Create the WasmMemoryObject.
79 : Handle<WasmMemoryObject> memory_object = WasmMemoryObject::New(
80 : isolate_, new_buffer,
81 82464 : (test_module_->maximum_pages != 0) ? test_module_->maximum_pages : -1);
82 41232 : instance_object_->set_memory_object(*memory_object);
83 41232 : WasmMemoryObject::AddInstance(isolate_, memory_object, instance_object_);
84 : // TODO(wasm): Delete the following two lines when test-run-wasm will use a
85 : // multiple of kPageSize as memory size. At the moment, the effect of these
86 : // two lines is used to shrink the memory for testing purposes.
87 82464 : instance_object_->SetRawMemory(mem_start_, mem_size_);
88 41232 : return mem_start_;
89 : }
90 :
91 1104164 : uint32_t TestingModuleBuilder::AddFunction(FunctionSig* sig, const char* name,
92 : FunctionType type) {
93 5879488 : if (test_module_->functions.size() == 0) {
94 : // TODO(titzer): Reserving space here to avoid the underlying WasmFunction
95 : // structs from moving.
96 1093612 : test_module_->functions.reserve(kMaxFunctions);
97 : }
98 2208328 : uint32_t index = static_cast<uint32_t>(test_module_->functions.size());
99 3312492 : test_module_->functions.push_back({sig, index, 0, {0, 0}, false, false});
100 1104164 : if (type == kImport) {
101 : DCHECK_EQ(0, test_module_->num_declared_functions);
102 1992 : ++test_module_->num_imported_functions;
103 1992 : test_module_->functions.back().imported = true;
104 : } else {
105 1102172 : ++test_module_->num_declared_functions;
106 : }
107 : DCHECK_EQ(test_module_->functions.size(),
108 : test_module_->num_imported_functions +
109 : test_module_->num_declared_functions);
110 1104164 : if (name) {
111 1093668 : Vector<const byte> name_vec = Vector<const byte>::cast(CStrVector(name));
112 : test_module_->AddFunctionNameForTesting(
113 3281004 : index, {AddBytes(name_vec), static_cast<uint32_t>(name_vec.length())});
114 : }
115 1104164 : if (interpreter_) {
116 367172 : interpreter_->AddFunctionForTesting(&test_module_->functions.back());
117 : }
118 : DCHECK_LT(index, kMaxFunctions); // limited for testing.
119 1104164 : return index;
120 : }
121 :
122 4208 : Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) {
123 : SetExecutable();
124 12624 : FunctionSig* sig = test_module_->functions[index].sig;
125 : MaybeHandle<Code> maybe_ret_code =
126 4208 : compiler::CompileJSToWasmWrapper(isolate_, sig, false);
127 : Handle<Code> ret_code = maybe_ret_code.ToHandleChecked();
128 : Handle<JSFunction> ret = WasmExportedFunction::New(
129 : isolate_, instance_object(), MaybeHandle<String>(),
130 : static_cast<int>(index), static_cast<int>(sig->parameter_count()),
131 4208 : ret_code);
132 :
133 : // Add reference to the exported wrapper code.
134 : Handle<WasmModuleObject> module_object(instance_object()->module_object(),
135 12624 : isolate_);
136 12624 : Handle<FixedArray> old_arr(module_object->export_wrappers(), isolate_);
137 : Handle<FixedArray> new_arr =
138 4208 : isolate_->factory()->NewFixedArray(old_arr->length() + 1);
139 4208 : old_arr->CopyTo(0, *new_arr, 0, old_arr->length());
140 8416 : new_arr->set(old_arr->length(), *ret_code);
141 4208 : module_object->set_export_wrappers(*new_arr);
142 :
143 4208 : if (interpreter_) {
144 : // Patch the jump table to call the interpreter for this function. This is
145 : // only needed for functions with a wrapper. Other functions never get
146 : // called through the jump table.
147 : wasm::WasmCode* wasm_new_code = compiler::CompileWasmInterpreterEntry(
148 2752 : isolate_->wasm_engine(), native_module_, index, sig);
149 1376 : native_module_->PublishInterpreterEntry(wasm_new_code, index);
150 : }
151 4208 : return ret;
152 : }
153 :
154 1500 : void TestingModuleBuilder::AddIndirectFunctionTable(
155 : const uint16_t* function_indexes, uint32_t table_size) {
156 1500 : test_module_->tables.emplace_back();
157 : WasmTable& table = test_module_->tables.back();
158 1500 : table.initial_size = table_size;
159 1500 : table.maximum_size = table_size;
160 1500 : table.has_maximum_size = true;
161 1620 : for (uint32_t i = 0; i < table_size; ++i) {
162 240 : table.values.push_back(function_indexes[i]);
163 : }
164 : WasmInstanceObject::EnsureIndirectFunctionTableWithMinimumSize(
165 1500 : instance_object(), table_size);
166 1500 : }
167 :
168 48 : void TestingModuleBuilder::PopulateIndirectFunctionTable() {
169 96 : if (interpret()) return;
170 : auto instance = instance_object();
171 : uint32_t num_tables = 1; // TODO(titzer): multiple tables.
172 64 : for (uint32_t i = 0; i < num_tables; i++) {
173 112 : WasmTable& table = test_module_->tables[i];
174 32 : int table_size = static_cast<int>(instance->indirect_function_table_size());
175 112 : for (int j = 0; j < table_size; j++) {
176 240 : WasmFunction& function = test_module_->functions[table.values[j]];
177 80 : int sig_id = test_module_->signature_map.Find(*function.sig);
178 : IndirectFunctionTableEntry(instance, j)
179 160 : .Set(sig_id, instance, function.func_index);
180 : }
181 : }
182 : }
183 :
184 2190476 : uint32_t TestingModuleBuilder::AddBytes(Vector<const byte> bytes) {
185 2190476 : Vector<const uint8_t> old_bytes = native_module_->wire_bytes();
186 2190476 : uint32_t old_size = static_cast<uint32_t>(old_bytes.size());
187 : // Avoid placing strings at offset 0, this might be interpreted as "not
188 : // set", e.g. for function names.
189 2190476 : uint32_t bytes_offset = old_size ? old_size : 1;
190 2190476 : size_t new_size = bytes_offset + bytes.size();
191 : OwnedVector<uint8_t> new_bytes = OwnedVector<uint8_t>::New(new_size);
192 2190476 : if (old_size > 0) {
193 1096864 : memcpy(new_bytes.start(), old_bytes.start(), old_size);
194 : }
195 2190476 : memcpy(new_bytes.start() + bytes_offset, bytes.start(), bytes.length());
196 4380952 : native_module_->SetWireBytes(std::move(new_bytes));
197 2190476 : return bytes_offset;
198 : }
199 :
200 36 : uint32_t TestingModuleBuilder::AddException(FunctionSig* sig) {
201 : DCHECK_EQ(0, sig->return_count());
202 72 : uint32_t index = static_cast<uint32_t>(test_module_->exceptions.size());
203 72 : test_module_->exceptions.push_back(WasmException{sig});
204 36 : Handle<WasmExceptionTag> tag = WasmExceptionTag::New(isolate_, index);
205 108 : Handle<FixedArray> table(instance_object_->exceptions_table(), isolate_);
206 36 : table = isolate_->factory()->CopyFixedArrayAndGrow(table, 1);
207 36 : instance_object_->set_exceptions_table(*table);
208 72 : table->set(index, *tag);
209 36 : return index;
210 : }
211 :
212 731104 : CompilationEnv TestingModuleBuilder::CreateCompilationEnv() {
213 : return {
214 : test_module_ptr_,
215 : trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler : kNoTrapHandler,
216 2193312 : runtime_exception_support_, enabled_features_, lower_simd()};
217 : }
218 :
219 19088 : const WasmGlobal* TestingModuleBuilder::AddGlobal(ValueType type) {
220 19088 : byte size = ValueTypes::MemSize(ValueTypes::MachineTypeFor(type));
221 19088 : global_offset = (global_offset + size - 1) & ~(size - 1); // align
222 38176 : test_module_->globals.push_back(
223 76352 : {type, true, WasmInitExpr(), {global_offset}, false, false});
224 19088 : global_offset += size;
225 : // limit number of globals.
226 19088 : CHECK_LT(global_offset, kMaxGlobalsSize);
227 19088 : return &test_module_->globals.back();
228 : }
229 :
230 1093612 : Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() {
231 : Handle<Script> script =
232 2187224 : isolate_->factory()->NewScript(isolate_->factory()->empty_string());
233 : script->set_type(Script::TYPE_WASM);
234 : Handle<WasmModuleObject> module_object =
235 : WasmModuleObject::New(isolate_, enabled_features_, test_module_, {},
236 4374448 : script, Handle<ByteArray>::null());
237 : // This method is called when we initialize TestEnvironment. We don't
238 : // have a memory yet, so we won't create it here. We'll update the
239 : // interpreter when we get a memory. We do have globals, though.
240 1093612 : native_module_ = module_object->native_module();
241 1093612 : native_module_->ReserveCodeTableForTesting(kMaxFunctions);
242 :
243 1093612 : auto instance = WasmInstanceObject::New(isolate_, module_object);
244 2187224 : instance->set_exceptions_table(*isolate_->factory()->empty_fixed_array());
245 1093612 : instance->set_globals_start(globals_data_);
246 1093612 : return instance;
247 : }
248 :
249 492 : void TestBuildingGraphWithBuilder(compiler::WasmGraphBuilder* builder,
250 492 : Zone* zone, FunctionSig* sig,
251 : const byte* start, const byte* end) {
252 492 : WasmFeatures unused_detected_features;
253 : FunctionBody body(sig, 0, start, end);
254 : DecodeResult result =
255 : BuildTFGraph(zone->allocator(), kAllWasmFeatures, nullptr, builder,
256 984 : &unused_detected_features, body, nullptr);
257 492 : if (result.failed()) {
258 : #ifdef DEBUG
259 : if (!FLAG_trace_wasm_decoder) {
260 : // Retry the compilation with the tracing flag on, to help in debugging.
261 : FLAG_trace_wasm_decoder = true;
262 : result = BuildTFGraph(zone->allocator(), kAllWasmFeatures, nullptr,
263 : builder, &unused_detected_features, body, nullptr);
264 : }
265 : #endif
266 :
267 : FATAL("Verification failed; pc = +%x, msg = %s", result.error().offset(),
268 0 : result.error().message().c_str());
269 : }
270 492 : builder->LowerInt64();
271 492 : if (!CpuFeatures::SupportsWasmSimd128()) {
272 0 : builder->SimdScalarLoweringForTesting();
273 : }
274 492 : }
275 :
276 492 : void TestBuildingGraph(Zone* zone, compiler::JSGraph* jsgraph,
277 : CompilationEnv* module, FunctionSig* sig,
278 : compiler::SourcePositionTable* source_position_table,
279 : const byte* start, const byte* end) {
280 : compiler::WasmGraphBuilder builder(module, zone, jsgraph, sig,
281 492 : source_position_table);
282 492 : TestBuildingGraphWithBuilder(&builder, zone, sig, start, end);
283 492 : }
284 :
285 1093612 : WasmFunctionWrapper::WasmFunctionWrapper(Zone* zone, int num_params)
286 : : GraphAndBuilders(zone),
287 : inner_code_node_(nullptr),
288 : context_address_(nullptr),
289 1093612 : signature_(nullptr) {
290 : // One additional parameter for the pointer to the return value memory.
291 1093612 : Signature<MachineType>::Builder sig_builder(zone, 1, num_params + 1);
292 :
293 : sig_builder.AddReturn(MachineType::Int32());
294 2222636 : for (int i = 0; i < num_params + 1; i++) {
295 : sig_builder.AddParam(MachineType::Pointer());
296 : }
297 1093612 : signature_ = sig_builder.Build();
298 1093612 : }
299 :
300 728952 : void WasmFunctionWrapper::Init(CallDescriptor* call_descriptor,
301 : MachineType return_type,
302 : Vector<MachineType> param_types) {
303 : DCHECK_NOT_NULL(call_descriptor);
304 : DCHECK_EQ(signature_->parameter_count(), param_types.length() + 1);
305 :
306 : // Create the TF graph for the wrapper.
307 :
308 : // Function, context_address, effect, and control.
309 13948568 : Node** parameters = zone()->NewArray<Node*>(param_types.length() + 4);
310 : int start_value_output_count =
311 728952 : static_cast<int>(signature_->parameter_count()) + 1;
312 : graph()->SetStart(
313 728952 : graph()->NewNode(common()->Start(start_value_output_count)));
314 728952 : Node* effect = graph()->start();
315 : int parameter_count = 0;
316 :
317 : // Dummy node which gets replaced in SetInnerCode.
318 1457904 : inner_code_node_ = graph()->NewNode(common()->Int32Constant(0));
319 728952 : parameters[parameter_count++] = inner_code_node_;
320 :
321 : // Dummy node that gets replaced in SetContextAddress.
322 1457904 : context_address_ = graph()->NewNode(IntPtrConstant(0));
323 728952 : parameters[parameter_count++] = context_address_;
324 :
325 : int param_idx = 0;
326 752576 : for (MachineType t : param_types) {
327 : DCHECK_NE(MachineType::None(), t);
328 23624 : parameters[parameter_count] = graph()->NewNode(
329 : machine()->Load(t),
330 : graph()->NewNode(common()->Parameter(param_idx++), graph()->start()),
331 94496 : graph()->NewNode(common()->Int32Constant(0)), effect, graph()->start());
332 23624 : effect = parameters[parameter_count++];
333 : }
334 :
335 728952 : parameters[parameter_count++] = effect;
336 1457904 : parameters[parameter_count++] = graph()->start();
337 : Node* call = graph()->NewNode(common()->Call(call_descriptor),
338 1457904 : parameter_count, parameters);
339 :
340 728952 : if (!return_type.IsNone()) {
341 : effect = graph()->NewNode(
342 : machine()->Store(compiler::StoreRepresentation(
343 : return_type.representation(), WriteBarrierKind::kNoWriteBarrier)),
344 : graph()->NewNode(common()->Parameter(param_types.length()),
345 : graph()->start()),
346 : graph()->NewNode(common()->Int32Constant(0)), call, effect,
347 2900096 : graph()->start());
348 : }
349 728952 : Node* zero = graph()->NewNode(common()->Int32Constant(0));
350 : Node* r = graph()->NewNode(
351 : common()->Return(), zero,
352 : graph()->NewNode(common()->Int32Constant(WASM_WRAPPER_RETURN_VALUE)),
353 1457904 : effect, graph()->start());
354 728952 : graph()->SetEnd(graph()->NewNode(common()->End(1), r));
355 728952 : }
356 :
357 9255320 : Handle<Code> WasmFunctionWrapper::GetWrapperCode() {
358 : Handle<Code> code;
359 9255320 : if (!code_.ToHandle(&code)) {
360 724724 : Isolate* isolate = CcTest::InitIsolateOnce();
361 :
362 : auto call_descriptor =
363 2174172 : compiler::Linkage::GetSimplifiedCDescriptor(zone(), signature_, true);
364 :
365 : if (kSystemPointerSize == 4) {
366 : size_t num_params = signature_->parameter_count();
367 : // One additional parameter for the pointer of the return value.
368 : Signature<MachineRepresentation>::Builder rep_builder(zone(), 1,
369 : num_params + 1);
370 :
371 : rep_builder.AddReturn(MachineRepresentation::kWord32);
372 : for (size_t i = 0; i < num_params + 1; i++) {
373 : rep_builder.AddParam(MachineRepresentation::kWord32);
374 : }
375 : compiler::Int64Lowering r(graph(), machine(), common(), zone(),
376 : rep_builder.Build());
377 : r.LowerGraph();
378 : }
379 :
380 : OptimizedCompilationInfo info(ArrayVector("testing"), graph()->zone(),
381 724724 : Code::C_WASM_ENTRY);
382 : code_ = compiler::Pipeline::GenerateCodeForTesting(
383 : &info, isolate, call_descriptor, graph(),
384 1449448 : AssemblerOptions::Default(isolate));
385 724724 : code = code_.ToHandleChecked();
386 : #ifdef ENABLE_DISASSEMBLER
387 : if (FLAG_print_opt_code) {
388 : CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
389 : OFStream os(tracing_scope.file());
390 :
391 : code->Disassemble("wasm wrapper", os);
392 : }
393 : #endif
394 : }
395 :
396 9255320 : return code;
397 : }
398 :
399 2559016 : void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
400 1096808 : size_t locals_size = local_decls.Size();
401 1096808 : size_t total_size = end - start + locals_size + 1;
402 1096808 : byte* buffer = static_cast<byte*>(zone()->New(total_size));
403 : // Prepend the local decls to the code.
404 1096808 : local_decls.Emit(buffer);
405 : // Emit the code.
406 1096808 : memcpy(buffer + locals_size, start, end - start);
407 : // Append an extra end opcode.
408 1096808 : buffer[total_size - 1] = kExprEnd;
409 :
410 : start = buffer;
411 1096808 : end = buffer + total_size;
412 :
413 1096808 : CHECK_GE(kMaxInt, end - start);
414 1096808 : int len = static_cast<int>(end - start);
415 : function_->code = {builder_->AddBytes(Vector<const byte>(start, len)),
416 2924720 : static_cast<uint32_t>(len)};
417 :
418 1096808 : if (interpreter_) {
419 : // Add the code to the interpreter; do not generate compiled code.
420 365704 : interpreter_->SetFunctionCodeForTesting(function_, start, end);
421 1462512 : return;
422 : }
423 :
424 731104 : Vector<const uint8_t> wire_bytes = builder_->instance_object()
425 1462208 : ->module_object()
426 : ->native_module()
427 1462208 : ->wire_bytes();
428 :
429 731104 : CompilationEnv env = builder_->CreateCompilationEnv();
430 1462208 : ScopedVector<uint8_t> func_wire_bytes(function_->code.length());
431 1462208 : memcpy(func_wire_bytes.start(), wire_bytes.start() + function_->code.offset(),
432 731104 : func_wire_bytes.length());
433 :
434 : FunctionBody func_body{function_->sig, function_->code.offset(),
435 : func_wire_bytes.start(), func_wire_bytes.end()};
436 : NativeModule* native_module =
437 1462208 : builder_->instance_object()->module_object()->native_module();
438 : WasmCompilationUnit unit(isolate()->wasm_engine(), function_->func_index,
439 2924416 : builder_->execution_tier());
440 731104 : WasmFeatures unused_detected_features;
441 : WasmCompilationResult result = unit.ExecuteCompilation(
442 : &env, native_module->compilation_state()->GetWireBytesStorage(),
443 2193312 : isolate()->counters(), &unused_detected_features);
444 731104 : WasmCode* code = unit.Publish(std::move(result), native_module);
445 : DCHECK_NOT_NULL(code);
446 731104 : if (WasmCode::ShouldBeLogged(isolate())) code->LogCode(isolate());
447 : }
448 :
449 1102172 : WasmFunctionCompiler::WasmFunctionCompiler(Zone* zone, FunctionSig* sig,
450 2204344 : TestingModuleBuilder* builder,
451 : const char* name)
452 : : GraphAndBuilders(zone),
453 : jsgraph(builder->isolate(), this->graph(), this->common(), nullptr,
454 : nullptr, this->machine()),
455 : sig(sig),
456 : descriptor_(nullptr),
457 : builder_(builder),
458 : local_decls(zone, sig),
459 : source_position_table_(this->graph()),
460 4408688 : interpreter_(builder->interpreter()) {
461 : // Get a new function from the testing module.
462 1102172 : int index = builder->AddFunction(sig, name, TestingModuleBuilder::kWasm);
463 2204344 : function_ = builder_->GetFunctionAt(index);
464 1102172 : }
465 :
466 : WasmFunctionCompiler::~WasmFunctionCompiler() = default;
467 :
468 1093796 : FunctionSig* WasmRunnerBase::CreateSig(MachineType return_type,
469 : Vector<MachineType> param_types) {
470 1093796 : int return_count = return_type.IsNone() ? 0 : 1;
471 : int param_count = param_types.length();
472 :
473 : // Allocate storage array in zone.
474 1093796 : ValueType* sig_types = zone_.NewArray<ValueType>(return_count + param_count);
475 :
476 : // Convert machine types to local types, and check that there are no
477 : // MachineType::None()'s in the parameters.
478 : int idx = 0;
479 1093796 : if (return_count) sig_types[idx++] = ValueTypes::ValueTypeFor(return_type);
480 1129376 : for (MachineType param : param_types) {
481 71160 : CHECK_NE(MachineType::None(), param);
482 35580 : sig_types[idx++] = ValueTypes::ValueTypeFor(param);
483 : }
484 2187592 : return new (&zone_) FunctionSig(return_count, param_count, sig_types);
485 : }
486 :
487 : // static
488 : bool WasmRunnerBase::trap_happened;
489 :
490 : } // namespace wasm
491 : } // namespace internal
492 77625 : } // namespace v8
|