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/api.h"
8 : #include "src/assembler-inl.h"
9 : #include "src/wasm/wasm-memory.h"
10 : #include "src/wasm/wasm-objects-inl.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 : namespace wasm {
15 :
16 37172 : TestingModuleBuilder::TestingModuleBuilder(
17 : Zone* zone, WasmExecutionMode mode,
18 : compiler::RuntimeExceptionSupport exception_support)
19 : : test_module_ptr_(&test_module_),
20 37172 : isolate_(CcTest::InitIsolateOnce()),
21 : global_offset(0),
22 : mem_start_(nullptr),
23 : mem_size_(0),
24 : interpreter_(nullptr),
25 : runtime_exception_support_(exception_support),
26 148688 : lower_simd_(mode == kExecuteSimdLowered) {
27 37172 : WasmJs::Install(isolate_, true);
28 37172 : test_module_.globals_size = kMaxGlobalsSize;
29 37172 : memset(globals_data_, 0, sizeof(globals_data_));
30 37172 : instance_object_ = InitInstanceObject();
31 37172 : if (mode == kExecuteInterpreted) {
32 17689 : interpreter_ = WasmDebugInfo::SetupForTesting(instance_object_);
33 : }
34 37172 : }
35 :
36 5780 : byte* TestingModuleBuilder::AddMemory(uint32_t size) {
37 5780 : CHECK(!test_module_.has_memory);
38 5780 : CHECK_NULL(mem_start_);
39 5780 : CHECK_EQ(0, mem_size_);
40 : DCHECK(!instance_object_->has_memory_buffer());
41 : DCHECK(!instance_object_->has_memory_object());
42 5780 : test_module_.has_memory = true;
43 : const bool enable_guard_regions =
44 5780 : trap_handler::UseTrapHandler() && test_module_.is_wasm();
45 : uint32_t alloc_size =
46 5780 : enable_guard_regions ? RoundUp(size, base::OS::CommitPageSize()) : size;
47 : Handle<JSArrayBuffer> new_buffer =
48 5780 : wasm::NewArrayBuffer(isolate_, alloc_size, enable_guard_regions);
49 5780 : CHECK(!new_buffer.is_null());
50 5780 : instance_object_->set_memory_buffer(*new_buffer);
51 5780 : mem_start_ = reinterpret_cast<byte*>(new_buffer->backing_store());
52 5780 : mem_size_ = size;
53 5780 : CHECK(size == 0 || mem_start_);
54 5780 : memset(mem_start_, 0, size);
55 :
56 : // Create the WasmMemoryObject.
57 : Handle<WasmMemoryObject> memory_object = WasmMemoryObject::New(
58 : isolate_, new_buffer,
59 5780 : (test_module_.maximum_pages != 0) ? test_module_.maximum_pages : -1);
60 5780 : instance_object_->set_memory_object(*memory_object);
61 5780 : WasmMemoryObject::AddInstance(isolate_, memory_object, instance_object_);
62 : // TODO(wasm): Delete the following two lines when test-run-wasm will use a
63 : // multiple of kPageSize as memory size. At the moment, the effect of these
64 : // two lines is used to shrink the memory for testing purposes.
65 5780 : instance_object_->wasm_context()->get()->mem_start = mem_start_;
66 5780 : instance_object_->wasm_context()->get()->mem_size = mem_size_;
67 5780 : return mem_start_;
68 : }
69 :
70 47120 : uint32_t TestingModuleBuilder::AddFunction(FunctionSig* sig, Handle<Code> code,
71 : const char* name) {
72 141360 : if (test_module_.functions.size() == 0) {
73 : // TODO(titzer): Reserving space here to avoid the underlying WasmFunction
74 : // structs from moving.
75 37172 : test_module_.functions.reserve(kMaxFunctions);
76 : }
77 47120 : uint32_t index = static_cast<uint32_t>(test_module_.functions.size());
78 : test_module_.functions.push_back(
79 141360 : {sig, index, 0, {0, 0}, {0, 0}, false, false});
80 47120 : if (name) {
81 37208 : Vector<const byte> name_vec = Vector<const byte>::cast(CStrVector(name));
82 : test_module_.functions.back().name = {
83 37208 : AddBytes(name_vec), static_cast<uint32_t>(name_vec.length())};
84 : }
85 47120 : function_code_.push_back(code);
86 47120 : if (interpreter_) {
87 22147 : interpreter_->AddFunctionForTesting(&test_module_.functions.back());
88 : }
89 : DCHECK_LT(index, kMaxFunctions); // limited for testing.
90 47120 : return index;
91 : }
92 :
93 1962 : uint32_t TestingModuleBuilder::AddJsFunction(
94 : FunctionSig* sig, const char* source, Handle<FixedArray> js_imports_table) {
95 : Handle<JSFunction> jsfunc = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
96 : *v8::Local<v8::Function>::Cast(CompileRun(source))));
97 1962 : uint32_t index = AddFunction(sig, Handle<Code>::null(), nullptr);
98 3924 : js_imports_table->set(0, *isolate_->native_context());
99 : Handle<Code> code = compiler::CompileWasmToJSWrapper(
100 3924 : isolate_, jsfunc, sig, index, test_module_.origin(), js_imports_table);
101 3924 : function_code_[index] = code;
102 1962 : return index;
103 : }
104 :
105 4092 : Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) {
106 : // Wrap the code so it can be called as a JS function.
107 8184 : Handle<Code> code = function_code_[index];
108 : byte* context_address =
109 : test_module_.has_memory
110 : ? reinterpret_cast<byte*>(instance_object_->wasm_context())
111 4092 : : nullptr;
112 : Handle<Code> ret_code = compiler::CompileJSToWasmWrapper(
113 4092 : isolate_, &test_module_, code, index, context_address);
114 : Handle<JSFunction> ret = WasmExportedFunction::New(
115 : isolate_, instance_object(), MaybeHandle<String>(),
116 : static_cast<int>(index),
117 8184 : static_cast<int>(test_module_.functions[index].sig->parameter_count()),
118 8184 : ret_code);
119 :
120 : // Add weak reference to exported functions.
121 : Handle<WasmCompiledModule> compiled_module(
122 4092 : instance_object()->compiled_module(), isolate_);
123 4092 : Handle<FixedArray> old_arr = compiled_module->weak_exported_functions();
124 : Handle<FixedArray> new_arr =
125 4092 : isolate_->factory()->NewFixedArray(old_arr->length() + 1);
126 4092 : old_arr->CopyTo(0, *new_arr, 0, old_arr->length());
127 4092 : Handle<WeakCell> weak_fn = isolate_->factory()->NewWeakCell(ret);
128 4092 : new_arr->set(old_arr->length(), *weak_fn);
129 : compiled_module->set_weak_exported_functions(new_arr);
130 :
131 4092 : return ret;
132 : }
133 :
134 1008 : void TestingModuleBuilder::AddIndirectFunctionTable(uint16_t* function_indexes,
135 : uint32_t table_size) {
136 1008 : test_module_.function_tables.emplace_back();
137 : WasmIndirectFunctionTable& table = test_module_.function_tables.back();
138 1008 : table.initial_size = table_size;
139 1008 : table.maximum_size = table_size;
140 1008 : table.has_maximum_size = true;
141 1116 : for (uint32_t i = 0; i < table_size; ++i) {
142 216 : table.values.push_back(function_indexes[i]);
143 : }
144 :
145 : function_tables_.push_back(
146 : isolate_->global_handles()
147 4032 : ->Create(*isolate_->factory()->NewFixedArray(table_size))
148 2016 : .address());
149 : signature_tables_.push_back(
150 : isolate_->global_handles()
151 3024 : ->Create(*isolate_->factory()->NewFixedArray(table_size))
152 2016 : .address());
153 1008 : }
154 :
155 36 : void TestingModuleBuilder::PopulateIndirectFunctionTable() {
156 72 : if (interpret()) return;
157 : // Initialize the fixed arrays in instance->function_tables.
158 54 : for (uint32_t i = 0; i < function_tables_.size(); i++) {
159 18 : WasmIndirectFunctionTable& table = test_module_.function_tables[i];
160 : Handle<FixedArray> function_table(
161 54 : reinterpret_cast<FixedArray**>(function_tables_[i]));
162 : Handle<FixedArray> signature_table(
163 36 : reinterpret_cast<FixedArray**>(signature_tables_[i]));
164 90 : int table_size = static_cast<int>(table.values.size());
165 72 : for (int j = 0; j < table_size; j++) {
166 108 : WasmFunction& function = test_module_.functions[table.values[j]];
167 : signature_table->set(
168 54 : j, Smi::FromInt(test_module_.signature_map.Find(function.sig)));
169 108 : function_table->set(j, *function_code_[function.func_index]);
170 : }
171 : }
172 : }
173 :
174 77470 : uint32_t TestingModuleBuilder::AddBytes(Vector<const byte> bytes) {
175 : Handle<SeqOneByteString> old_bytes(
176 77470 : instance_object_->compiled_module()->module_bytes(), isolate_);
177 77470 : uint32_t old_size = static_cast<uint32_t>(old_bytes->length());
178 : // Avoid placing strings at offset 0, this might be interpreted as "not
179 : // set", e.g. for function names.
180 77470 : uint32_t bytes_offset = old_size ? old_size : 1;
181 77470 : ScopedVector<byte> new_bytes(bytes_offset + bytes.length());
182 154940 : memcpy(new_bytes.start(), old_bytes->GetChars(), old_size);
183 77470 : memcpy(new_bytes.start() + bytes_offset, bytes.start(), bytes.length());
184 : Handle<SeqOneByteString> new_bytes_str = Handle<SeqOneByteString>::cast(
185 154940 : isolate_->factory()->NewStringFromOneByte(new_bytes).ToHandleChecked());
186 : instance_object_->compiled_module()->shared()->set_module_bytes(
187 154940 : *new_bytes_str);
188 77470 : return bytes_offset;
189 : }
190 :
191 0 : compiler::ModuleEnv TestingModuleBuilder::CreateModuleEnv() {
192 : return {&test_module_, function_tables_, signature_tables_, function_code_,
193 40262 : Handle<Code>::null()};
194 : }
195 :
196 372 : const WasmGlobal* TestingModuleBuilder::AddGlobal(ValueType type) {
197 372 : byte size = WasmOpcodes::MemSize(WasmOpcodes::MachineTypeFor(type));
198 372 : global_offset = (global_offset + size - 1) & ~(size - 1); // align
199 : test_module_.globals.push_back(
200 1116 : {type, true, WasmInitExpr(), global_offset, false, false});
201 372 : global_offset += size;
202 : // limit number of globals.
203 372 : CHECK_LT(global_offset, kMaxGlobalsSize);
204 372 : return &test_module_.globals.back();
205 : }
206 :
207 37172 : Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() {
208 : Handle<SeqOneByteString> empty_string = Handle<SeqOneByteString>::cast(
209 74344 : isolate_->factory()->NewStringFromOneByte({}).ToHandleChecked());
210 : // The lifetime of the wasm module is tied to this object's, and we cannot
211 : // rely on the mechanics of Managed<T>.
212 : Handle<Foreign> module_wrapper = isolate_->factory()->NewForeign(
213 37172 : reinterpret_cast<Address>(&test_module_ptr_));
214 : Handle<Script> script =
215 74344 : isolate_->factory()->NewScript(isolate_->factory()->empty_string());
216 : script->set_type(Script::TYPE_WASM);
217 : Handle<WasmSharedModuleData> shared_module_data =
218 : WasmSharedModuleData::New(isolate_, module_wrapper, empty_string, script,
219 37172 : Handle<ByteArray>::null());
220 37172 : Handle<FixedArray> code_table = isolate_->factory()->NewFixedArray(0);
221 37172 : Handle<FixedArray> export_wrappers = isolate_->factory()->NewFixedArray(0);
222 : Handle<WasmCompiledModule> compiled_module = WasmCompiledModule::New(
223 : isolate_, shared_module_data, code_table, export_wrappers,
224 37172 : function_tables_, signature_tables_);
225 37172 : Handle<FixedArray> weak_exported = isolate_->factory()->NewFixedArray(0);
226 : compiled_module->set_weak_exported_functions(weak_exported);
227 : DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module));
228 37172 : script->set_wasm_compiled_module(*compiled_module);
229 37172 : auto instance = WasmInstanceObject::New(isolate_, compiled_module);
230 37172 : instance->wasm_context()->get()->globals_start = globals_data_;
231 37172 : return instance;
232 : }
233 :
234 738 : void TestBuildingGraph(
235 1476 : Zone* zone, compiler::JSGraph* jsgraph, compiler::ModuleEnv* module,
236 : FunctionSig* sig, compiler::SourcePositionTable* source_position_table,
237 : const byte* start, const byte* end,
238 : compiler::RuntimeExceptionSupport runtime_exception_support) {
239 : compiler::WasmGraphBuilder builder(
240 : module, zone, jsgraph, CEntryStub(jsgraph->isolate(), 1).GetCode(), sig,
241 2214 : source_position_table, runtime_exception_support);
242 :
243 : DecodeResult result =
244 1476 : BuildTFGraph(zone->allocator(), &builder, sig, start, end);
245 738 : if (result.failed()) {
246 0 : if (!FLAG_trace_wasm_decoder) {
247 : // Retry the compilation with the tracing flag on, to help in debugging.
248 0 : FLAG_trace_wasm_decoder = true;
249 0 : result = BuildTFGraph(zone->allocator(), &builder, sig, start, end);
250 : }
251 :
252 0 : uint32_t pc = result.error_offset();
253 0 : std::ostringstream str;
254 0 : str << "Verification failed; pc = +" << pc
255 0 : << ", msg = " << result.error_msg().c_str();
256 0 : FATAL(str.str().c_str());
257 : }
258 738 : builder.LowerInt64();
259 738 : if (!CpuFeatures::SupportsWasmSimd128()) {
260 0 : builder.SimdScalarLoweringForTesting();
261 : }
262 738 : }
263 :
264 37172 : WasmFunctionWrapper::WasmFunctionWrapper(Zone* zone, int num_params)
265 : : GraphAndBuilders(zone),
266 : inner_code_node_(nullptr),
267 : context_address_(nullptr),
268 74344 : signature_(nullptr) {
269 : // One additional parameter for the pointer to the return value memory.
270 37172 : Signature<MachineType>::Builder sig_builder(zone, 1, num_params + 1);
271 :
272 : sig_builder.AddReturn(MachineType::Int32());
273 103800 : for (int i = 0; i < num_params + 1; i++) {
274 : sig_builder.AddParam(MachineType::Pointer());
275 : }
276 37172 : signature_ = sig_builder.Build();
277 37172 : }
278 :
279 19483 : void WasmFunctionWrapper::Init(CallDescriptor* descriptor,
280 : MachineType return_type,
281 : Vector<MachineType> param_types) {
282 : DCHECK_NOT_NULL(descriptor);
283 : DCHECK_EQ(signature_->parameter_count(), param_types.length() + 1);
284 :
285 : // Create the TF graph for the wrapper.
286 :
287 : // Function, context_address, effect, and control.
288 436272 : Node** parameters = zone()->NewArray<Node*>(param_types.length() + 4);
289 19483 : graph()->SetStart(graph()->NewNode(common()->Start(7)));
290 19483 : Node* effect = graph()->start();
291 : int parameter_count = 0;
292 :
293 : // Dummy node which gets replaced in SetInnerCode.
294 38966 : inner_code_node_ = graph()->NewNode(common()->Int32Constant(0));
295 19483 : parameters[parameter_count++] = inner_code_node_;
296 :
297 : // Dummy node that gets replaced in SetContextAddress.
298 38966 : context_address_ = graph()->NewNode(IntPtrConstant(0));
299 19483 : parameters[parameter_count++] = context_address_;
300 :
301 : int param_idx = 0;
302 35648 : for (MachineType t : param_types) {
303 : DCHECK_NE(MachineType::None(), t);
304 16165 : parameters[parameter_count] = graph()->NewNode(
305 : machine()->Load(t),
306 : graph()->NewNode(common()->Parameter(param_idx++), graph()->start()),
307 64660 : graph()->NewNode(common()->Int32Constant(0)), effect, graph()->start());
308 16165 : effect = parameters[parameter_count++];
309 : }
310 :
311 19483 : parameters[parameter_count++] = effect;
312 38966 : parameters[parameter_count++] = graph()->start();
313 : Node* call =
314 38966 : graph()->NewNode(common()->Call(descriptor), parameter_count, parameters);
315 :
316 19483 : if (!return_type.IsNone()) {
317 : effect = graph()->NewNode(
318 : machine()->Store(compiler::StoreRepresentation(
319 : return_type.representation(), WriteBarrierKind::kNoWriteBarrier)),
320 : graph()->NewNode(common()->Parameter(param_types.length()),
321 : graph()->start()),
322 : graph()->NewNode(common()->Int32Constant(0)), call, effect,
323 66148 : graph()->start());
324 : }
325 19483 : Node* zero = graph()->NewNode(common()->Int32Constant(0));
326 : Node* r = graph()->NewNode(
327 : common()->Return(), zero,
328 : graph()->NewNode(common()->Int32Constant(WASM_WRAPPER_RETURN_VALUE)),
329 38966 : effect, graph()->start());
330 19483 : graph()->SetEnd(graph()->NewNode(common()->End(1), r));
331 19483 : }
332 :
333 3515488 : Handle<Code> WasmFunctionWrapper::GetWrapperCode() {
334 3515488 : if (code_.is_null()) {
335 16351 : Isolate* isolate = CcTest::InitIsolateOnce();
336 :
337 : CallDescriptor* descriptor =
338 49053 : compiler::Linkage::GetSimplifiedCDescriptor(zone(), signature_, true);
339 :
340 : if (kPointerSize == 4) {
341 : size_t num_params = signature_->parameter_count();
342 : // One additional parameter for the pointer of the return value.
343 : Signature<MachineRepresentation>::Builder rep_builder(zone(), 1,
344 : num_params + 1);
345 :
346 : rep_builder.AddReturn(MachineRepresentation::kWord32);
347 : for (size_t i = 0; i < num_params + 1; i++) {
348 : rep_builder.AddParam(MachineRepresentation::kWord32);
349 : }
350 : compiler::Int64Lowering r(graph(), machine(), common(), zone(),
351 : rep_builder.Build());
352 : r.LowerGraph();
353 : }
354 :
355 : CompilationInfo info(ArrayVector("testing"), isolate, graph()->zone(),
356 16351 : Code::STUB);
357 : code_ = compiler::Pipeline::GenerateCodeForTesting(&info, descriptor,
358 16351 : graph(), nullptr);
359 16351 : CHECK(!code_.is_null());
360 : #ifdef ENABLE_DISASSEMBLER
361 : if (FLAG_print_opt_code) {
362 : OFStream os(stdout);
363 : code_->Disassemble("wasm wrapper", os);
364 : }
365 : #endif
366 : }
367 :
368 3515488 : return code_;
369 : }
370 :
371 445942 : void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
372 40262 : size_t locals_size = local_decls.Size();
373 40262 : size_t total_size = end - start + locals_size + 1;
374 40262 : byte* buffer = static_cast<byte*>(zone()->New(total_size));
375 : // Prepend the local decls to the code.
376 40262 : local_decls.Emit(buffer);
377 : // Emit the code.
378 40262 : memcpy(buffer + locals_size, start, end - start);
379 : // Append an extra end opcode.
380 40262 : buffer[total_size - 1] = kExprEnd;
381 :
382 : start = buffer;
383 40262 : end = buffer + total_size;
384 :
385 40262 : CHECK_GE(kMaxInt, end - start);
386 40262 : int len = static_cast<int>(end - start);
387 : function_->code = {builder_->AddBytes(Vector<const byte>(start, len)),
388 161048 : static_cast<uint32_t>(len)};
389 :
390 40262 : if (interpreter_) {
391 : // Add the code to the interpreter.
392 19195 : interpreter_->SetFunctionCodeForTesting(function_, start, end);
393 : }
394 :
395 : Handle<WasmCompiledModule> compiled_module(
396 : builder_->instance_object()->compiled_module(), isolate());
397 : Handle<SeqOneByteString> wire_bytes(compiled_module->module_bytes(),
398 : isolate());
399 :
400 40262 : compiler::ModuleEnv module_env = builder_->CreateModuleEnv();
401 40262 : ErrorThrower thrower(isolate(), "WasmFunctionCompiler::Build");
402 120786 : ScopedVector<uint8_t> func_wire_bytes(function_->code.length());
403 : memcpy(func_wire_bytes.start(),
404 40262 : wire_bytes->GetChars() + function_->code.offset(),
405 40262 : func_wire_bytes.length());
406 80524 : ScopedVector<char> func_name(function_->name.length());
407 40262 : memcpy(func_name.start(), wire_bytes->GetChars() + function_->name.offset(),
408 40262 : func_name.length());
409 :
410 : FunctionBody func_body{function_->sig, function_->code.offset(),
411 120786 : func_wire_bytes.start(), func_wire_bytes.end()};
412 : compiler::WasmCompilationUnit unit(
413 : isolate(), &module_env, func_body, func_name, function_->func_index,
414 : CEntryStub(isolate(), 1).GetCode(), isolate()->counters(),
415 281834 : builder_->runtime_exception_support(), builder_->lower_simd());
416 40262 : unit.ExecuteCompilation();
417 80524 : Handle<Code> code = unit.FinishCompilation(&thrower).ToHandleChecked();
418 80524 : CHECK(!thrower.error());
419 :
420 : // Manually add the deoptimization info that would otherwise be added
421 : // during instantiation. Deopt data holds <WeakCell<wasm_instance>,
422 : // func_index>.
423 : DCHECK_EQ(0, code->deoptimization_data()->length());
424 : Handle<FixedArray> deopt_data =
425 40262 : isolate()->factory()->NewFixedArray(2, TENURED);
426 : Handle<Object> weak_instance =
427 80524 : isolate()->factory()->NewWeakCell(builder_->instance_object());
428 40262 : deopt_data->set(0, *weak_instance);
429 40262 : deopt_data->set(1, Smi::FromInt(static_cast<int>(function_index())));
430 40262 : code->set_deoptimization_data(*deopt_data);
431 :
432 : // Build the TurboFan graph.
433 40262 : builder_->SetFunctionCode(function_index(), code);
434 :
435 : // Add to code table.
436 40262 : Handle<FixedArray> code_table = compiled_module->code_table();
437 80524 : if (static_cast<int>(function_index()) >= code_table->length()) {
438 : Handle<FixedArray> new_arr = isolate()->factory()->NewFixedArray(
439 74500 : static_cast<int>(function_index()) + 1);
440 37250 : code_table->CopyTo(0, *new_arr, 0, code_table->length());
441 : code_table = new_arr;
442 : compiled_module->ReplaceCodeTableForTesting(code_table);
443 : }
444 : DCHECK(code_table->get(static_cast<int>(function_index()))
445 : ->IsUndefined(isolate()));
446 80524 : code_table->set(static_cast<int>(function_index()), *code);
447 40262 : if (trap_handler::UseTrapHandler()) {
448 6072 : UnpackAndRegisterProtectedInstructions(isolate(), code_table);
449 40262 : }
450 40262 : }
451 :
452 45158 : WasmFunctionCompiler::WasmFunctionCompiler(Zone* zone, FunctionSig* sig,
453 90316 : TestingModuleBuilder* builder,
454 : const char* name)
455 : : GraphAndBuilders(zone),
456 : jsgraph(builder->isolate(), this->graph(), this->common(), nullptr,
457 : nullptr, this->machine()),
458 : sig(sig),
459 : descriptor_(nullptr),
460 : builder_(builder),
461 : local_decls(zone, sig),
462 : source_position_table_(this->graph()),
463 180632 : interpreter_(builder->interpreter()) {
464 : // Get a new function from the testing module.
465 45158 : int index = builder->AddFunction(sig, Handle<Code>::null(), name);
466 90316 : function_ = builder_->GetFunctionAt(index);
467 45158 : }
468 :
469 58118 : WasmFunctionCompiler::~WasmFunctionCompiler() {
470 52046 : if (trap_handler::UseTrapHandler() &&
471 6888 : !builder_->GetFunctionCode(function_index()).is_null()) {
472 6072 : const int handler_index = builder_->GetFunctionCode(function_index())
473 : ->trap_handler_index()
474 : ->value();
475 6072 : trap_handler::ReleaseHandlerData(handler_index);
476 : }
477 45158 : }
478 :
479 37358 : FunctionSig* WasmRunnerBase::CreateSig(MachineType return_type,
480 : Vector<MachineType> param_types) {
481 37358 : int return_count = return_type.IsNone() ? 0 : 1;
482 : int param_count = param_types.length();
483 :
484 : // Allocate storage array in zone.
485 37358 : ValueType* sig_types = zone_.NewArray<ValueType>(return_count + param_count);
486 :
487 : // Convert machine types to local types, and check that there are no
488 : // MachineType::None()'s in the parameters.
489 : int idx = 0;
490 37358 : if (return_count) sig_types[idx++] = WasmOpcodes::ValueTypeFor(return_type);
491 67006 : for (MachineType param : param_types) {
492 59296 : CHECK_NE(MachineType::None(), param);
493 29648 : sig_types[idx++] = WasmOpcodes::ValueTypeFor(param);
494 : }
495 74716 : return new (&zone_) FunctionSig(return_count, param_count, sig_types);
496 : }
497 :
498 : // static
499 : bool WasmRunnerBase::trap_happened;
500 :
501 : } // namespace wasm
502 : } // namespace internal
503 71154 : } // namespace v8
|