LCOV - code coverage report
Current view: top level - test/cctest/wasm - wasm-run-utils.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 239 242 98.8 %
Date: 2019-04-17 Functions: 22 22 100.0 %

          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.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     1094224 : 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             :       test_module_ptr_(test_module_.get()),
      24             :       isolate_(CcTest::InitIsolateOnce()),
      25             :       enabled_features_(WasmFeaturesFromIsolate(isolate_)),
      26             :       execution_tier_(tier),
      27             :       runtime_exception_support_(exception_support),
      28     3282672 :       lower_simd_(lower_simd) {
      29     1094224 :   WasmJs::Install(isolate_, true);
      30     1094224 :   test_module_->untagged_globals_buffer_size = kMaxGlobalsSize;
      31     1094224 :   memset(globals_data_, 0, sizeof(globals_data_));
      32             : 
      33             :   uint32_t maybe_import_index = 0;
      34     1094224 :   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        2028 :     maybe_import_index = AddFunction(maybe_import->sig, nullptr, kImport);
      39             :     DCHECK_EQ(0, maybe_import_index);
      40             :   }
      41             : 
      42     1094224 :   instance_object_ = InitInstanceObject();
      43     1094224 :   Handle<FixedArray> tables(isolate_->factory()->NewFixedArray(0));
      44     1094224 :   instance_object_->set_tables(*tables);
      45             : 
      46     1094224 :   if (maybe_import) {
      47             :     // Manually compile an import wrapper and insert it into the instance.
      48        6084 :     CodeSpaceMemoryModificationScope modification_scope(isolate_->heap());
      49        4056 :     auto kind = compiler::GetWasmImportCallKind(maybe_import->js_function,
      50        2028 :                                                 maybe_import->sig, false);
      51        4056 :     auto import_wrapper = native_module_->import_wrapper_cache()->GetOrCompile(
      52        4056 :         isolate_->wasm_engine(), isolate_->counters(), kind, maybe_import->sig);
      53             : 
      54             :     ImportedFunctionEntry(instance_object_, maybe_import_index)
      55        4056 :         .SetWasmToJs(isolate_, maybe_import->js_function, import_wrapper);
      56             :   }
      57             : 
      58     1094224 :   if (tier == ExecutionTier::kInterpreter) {
      59      364912 :     interpreter_ = WasmDebugInfo::SetupForTesting(instance_object_);
      60             :   }
      61     1094224 : }
      62             : 
      63       41480 : byte* TestingModuleBuilder::AddMemory(uint32_t size, SharedFlag shared) {
      64       41480 :   CHECK(!test_module_->has_memory);
      65       41480 :   CHECK_NULL(mem_start_);
      66       41480 :   CHECK_EQ(0, mem_size_);
      67             :   DCHECK(!instance_object_->has_memory_object());
      68             :   DCHECK_IMPLIES(test_module_->origin == kWasmOrigin,
      69             :                  size % kWasmPageSize == 0);
      70       41480 :   test_module_->has_memory = true;
      71             :   uint32_t max_size =
      72       41480 :       (test_module_->maximum_pages != 0) ? test_module_->maximum_pages : size;
      73             :   uint32_t alloc_size = RoundUp(size, kWasmPageSize);
      74             :   Handle<JSArrayBuffer> new_buffer;
      75       41480 :   if (shared == SharedFlag::kShared) {
      76          16 :     CHECK(NewSharedArrayBuffer(isolate_, alloc_size, max_size)
      77             :               .ToHandle(&new_buffer));
      78             :   } else {
      79       82944 :     CHECK(NewArrayBuffer(isolate_, alloc_size).ToHandle(&new_buffer));
      80             :   }
      81       41480 :   CHECK(!new_buffer.is_null());
      82       41480 :   mem_start_ = reinterpret_cast<byte*>(new_buffer->backing_store());
      83       41480 :   mem_size_ = size;
      84       41480 :   CHECK(size == 0 || mem_start_);
      85       41480 :   memset(mem_start_, 0, size);
      86             : 
      87             :   // Create the WasmMemoryObject.
      88             :   Handle<WasmMemoryObject> memory_object =
      89       41480 :       WasmMemoryObject::New(isolate_, new_buffer, max_size);
      90       41480 :   instance_object_->set_memory_object(*memory_object);
      91       41480 :   WasmMemoryObject::AddInstance(isolate_, memory_object, instance_object_);
      92             :   // TODO(wasm): Delete the following two lines when test-run-wasm will use a
      93             :   // multiple of kPageSize as memory size. At the moment, the effect of these
      94             :   // two lines is used to shrink the memory for testing purposes.
      95       82960 :   instance_object_->SetRawMemory(mem_start_, mem_size_);
      96       41480 :   return mem_start_;
      97             : }
      98             : 
      99     1105304 : uint32_t TestingModuleBuilder::AddFunction(FunctionSig* sig, const char* name,
     100             :                                            FunctionType type) {
     101     1105304 :   if (test_module_->functions.size() == 0) {
     102             :     // TODO(titzer): Reserving space here to avoid the underlying WasmFunction
     103             :     // structs from moving.
     104     1094224 :     test_module_->functions.reserve(kMaxFunctions);
     105             :   }
     106     1105304 :   uint32_t index = static_cast<uint32_t>(test_module_->functions.size());
     107     3315912 :   test_module_->functions.push_back({sig, index, 0, {0, 0}, false, false});
     108     1105304 :   if (type == kImport) {
     109             :     DCHECK_EQ(0, test_module_->num_declared_functions);
     110        2028 :     ++test_module_->num_imported_functions;
     111        2028 :     test_module_->functions.back().imported = true;
     112             :   } else {
     113     1103276 :     ++test_module_->num_declared_functions;
     114             :   }
     115             :   DCHECK_EQ(test_module_->functions.size(),
     116             :             test_module_->num_imported_functions +
     117             :                 test_module_->num_declared_functions);
     118     1105304 :   if (name) {
     119     1094772 :     Vector<const byte> name_vec = Vector<const byte>::cast(CStrVector(name));
     120     3284316 :     test_module_->AddFunctionNameForTesting(
     121     1094772 :         index, {AddBytes(name_vec), static_cast<uint32_t>(name_vec.length())});
     122             :   }
     123     1105304 :   if (interpreter_) {
     124      367596 :     interpreter_->AddFunctionForTesting(&test_module_->functions.back());
     125             :     // Patch the jump table to call the interpreter for this function.
     126             :     wasm::WasmCompilationResult result = compiler::CompileWasmInterpreterEntry(
     127      735192 :         isolate_->wasm_engine(), native_module_->enabled_features(), index,
     128      735192 :         sig);
     129      367596 :     std::unique_ptr<wasm::WasmCode> code = native_module_->AddCode(
     130             :         index, result.code_desc, result.frame_slot_count,
     131             :         result.tagged_parameter_slots, std::move(result.protected_instructions),
     132             :         std::move(result.source_positions), wasm::WasmCode::kInterpreterEntry,
     133     1837980 :         wasm::ExecutionTier::kInterpreter);
     134      367596 :     native_module_->PublishCode(std::move(code));
     135             :   }
     136             :   DCHECK_LT(index, kMaxFunctions);  // limited for testing.
     137     1105304 :   return index;
     138             : }
     139             : 
     140        4396 : Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) {
     141             :   SetExecutable();
     142        8792 :   FunctionSig* sig = test_module_->functions[index].sig;
     143             :   MaybeHandle<Code> maybe_ret_code =
     144        4396 :       compiler::CompileJSToWasmWrapper(isolate_, sig, false);
     145             :   Handle<Code> ret_code = maybe_ret_code.ToHandleChecked();
     146             :   Handle<JSFunction> ret = WasmExportedFunction::New(
     147             :       isolate_, instance_object(), MaybeHandle<String>(),
     148             :       static_cast<int>(index), static_cast<int>(sig->parameter_count()),
     149        4396 :       ret_code);
     150             : 
     151             :   // Add reference to the exported wrapper code.
     152             :   Handle<WasmModuleObject> module_object(instance_object()->module_object(),
     153        4396 :                                          isolate_);
     154        4396 :   Handle<FixedArray> old_arr(module_object->export_wrappers(), isolate_);
     155             :   Handle<FixedArray> new_arr =
     156        4396 :       isolate_->factory()->NewFixedArray(old_arr->length() + 1);
     157        4396 :   old_arr->CopyTo(0, *new_arr, 0, old_arr->length());
     158        8792 :   new_arr->set(old_arr->length(), *ret_code);
     159        4396 :   module_object->set_export_wrappers(*new_arr);
     160        4396 :   return ret;
     161             : }
     162             : 
     163        1648 : void TestingModuleBuilder::AddIndirectFunctionTable(
     164             :     const uint16_t* function_indexes, uint32_t table_size) {
     165             :   auto instance = instance_object();
     166             :   uint32_t table_index = static_cast<uint32_t>(test_module_->tables.size());
     167        1648 :   test_module_->tables.emplace_back();
     168             :   WasmTable& table = test_module_->tables.back();
     169        1648 :   table.initial_size = table_size;
     170        1648 :   table.maximum_size = table_size;
     171        1648 :   table.has_maximum_size = true;
     172        1648 :   table.type = kWasmAnyFunc;
     173             :   WasmInstanceObject::EnsureIndirectFunctionTableWithMinimumSize(
     174        1648 :       instance_object(), table_size);
     175             :   Handle<WasmTableObject> table_obj =
     176        1648 :       WasmTableObject::New(isolate_, table.type, table.initial_size,
     177        3296 :                            table.has_maximum_size, table.maximum_size, nullptr);
     178             : 
     179        1648 :   WasmTableObject::AddDispatchTable(isolate_, table_obj, instance_object_,
     180        1648 :                                     table_index);
     181             : 
     182        1648 :   if (function_indexes) {
     183         804 :     for (uint32_t i = 0; i < table_size; ++i) {
     184         340 :       WasmFunction& function = test_module_->functions[function_indexes[i]];
     185         340 :       int sig_id = test_module_->signature_map.Find(*function.sig);
     186             :       IndirectFunctionTableEntry(instance, i)
     187         680 :           .Set(sig_id, instance, function.func_index);
     188         340 :       WasmTableObject::SetFunctionTablePlaceholder(
     189         680 :           isolate_, table_obj, i, instance_object_, function_indexes[i]);
     190             :     }
     191             :   }
     192             : 
     193        1648 :   Handle<FixedArray> old_tables(instance_object_->tables(), isolate_);
     194        1648 :   Handle<FixedArray> new_tables = isolate_->factory()->CopyFixedArrayAndGrow(
     195        3296 :       old_tables, old_tables->length() + 1);
     196        3296 :   new_tables->set(old_tables->length(), *table_obj);
     197        1648 :   instance_object_->set_tables(*new_tables);
     198        1648 : }
     199             : 
     200     2192648 : uint32_t TestingModuleBuilder::AddBytes(Vector<const byte> bytes) {
     201     2192648 :   Vector<const uint8_t> old_bytes = native_module_->wire_bytes();
     202     2192648 :   uint32_t old_size = static_cast<uint32_t>(old_bytes.size());
     203             :   // Avoid placing strings at offset 0, this might be interpreted as "not
     204             :   // set", e.g. for function names.
     205     2192648 :   uint32_t bytes_offset = old_size ? old_size : 1;
     206     2192648 :   size_t new_size = bytes_offset + bytes.size();
     207             :   OwnedVector<uint8_t> new_bytes = OwnedVector<uint8_t>::New(new_size);
     208     2192648 :   if (old_size > 0) {
     209             :     memcpy(new_bytes.start(), old_bytes.start(), old_size);
     210             :   }
     211     2192648 :   memcpy(new_bytes.start() + bytes_offset, bytes.start(), bytes.length());
     212     4385296 :   native_module_->SetWireBytes(std::move(new_bytes));
     213     2192648 :   return bytes_offset;
     214             : }
     215             : 
     216          36 : uint32_t TestingModuleBuilder::AddException(FunctionSig* sig) {
     217             :   DCHECK_EQ(0, sig->return_count());
     218          36 :   uint32_t index = static_cast<uint32_t>(test_module_->exceptions.size());
     219          72 :   test_module_->exceptions.push_back(WasmException{sig});
     220          36 :   Handle<WasmExceptionTag> tag = WasmExceptionTag::New(isolate_, index);
     221          36 :   Handle<FixedArray> table(instance_object_->exceptions_table(), isolate_);
     222          36 :   table = isolate_->factory()->CopyFixedArrayAndGrow(table, 1);
     223          36 :   instance_object_->set_exceptions_table(*table);
     224          72 :   table->set(index, *tag);
     225          36 :   return index;
     226             : }
     227             : 
     228          60 : uint32_t TestingModuleBuilder::AddPassiveDataSegment(Vector<const byte> bytes) {
     229          60 :   uint32_t index = static_cast<uint32_t>(test_module_->data_segments.size());
     230             :   DCHECK_EQ(index, test_module_->data_segments.size());
     231             :   DCHECK_EQ(index, data_segment_starts_.size());
     232             :   DCHECK_EQ(index, data_segment_sizes_.size());
     233             :   DCHECK_EQ(index, dropped_data_segments_.size());
     234             : 
     235             :   // Add a passive data segment. This isn't used by function compilation, but
     236             :   // but it keeps the index in sync. The data segment's source will not be
     237             :   // correct, since we don't store data in the module wire bytes.
     238          60 :   test_module_->data_segments.emplace_back();
     239             : 
     240             :   // The num_declared_data_segments (from the DataCount section) is used
     241             :   // to validate the segment index, during function compilation.
     242          60 :   test_module_->num_declared_data_segments = index + 1;
     243             : 
     244             :   Address old_data_address =
     245          60 :       reinterpret_cast<Address>(data_segment_data_.data());
     246             :   size_t old_data_size = data_segment_data_.size();
     247          60 :   data_segment_data_.resize(old_data_size + bytes.length());
     248             :   Address new_data_address =
     249          60 :       reinterpret_cast<Address>(data_segment_data_.data());
     250             : 
     251          60 :   memcpy(data_segment_data_.data() + old_data_size, bytes.start(),
     252             :          bytes.length());
     253             : 
     254             :   // The data_segment_data_ offset may have moved, so update all the starts.
     255          60 :   for (Address& start : data_segment_starts_) {
     256           0 :     start += new_data_address - old_data_address;
     257             :   }
     258         120 :   data_segment_starts_.push_back(new_data_address + old_data_size);
     259         120 :   data_segment_sizes_.push_back(bytes.length());
     260         120 :   dropped_data_segments_.push_back(0);
     261             : 
     262             :   // The vector pointers may have moved, so update the instance object.
     263             :   instance_object_->set_data_segment_starts(data_segment_starts_.data());
     264             :   instance_object_->set_data_segment_sizes(data_segment_sizes_.data());
     265             :   instance_object_->set_dropped_data_segments(dropped_data_segments_.data());
     266          60 :   return index;
     267             : }
     268             : 
     269          48 : uint32_t TestingModuleBuilder::AddPassiveElementSegment(
     270             :     const std::vector<uint32_t>& entries) {
     271          48 :   uint32_t index = static_cast<uint32_t>(test_module_->elem_segments.size());
     272             :   DCHECK_EQ(index, dropped_elem_segments_.size());
     273             : 
     274          48 :   test_module_->elem_segments.emplace_back();
     275             :   auto& elem_segment = test_module_->elem_segments.back();
     276          48 :   elem_segment.entries = entries;
     277             : 
     278             :   // The vector pointers may have moved, so update the instance object.
     279          96 :   dropped_elem_segments_.push_back(0);
     280             :   instance_object_->set_dropped_elem_segments(dropped_elem_segments_.data());
     281          48 :   return index;
     282             : }
     283             : 
     284      731760 : CompilationEnv TestingModuleBuilder::CreateCompilationEnv() {
     285             :   // This is a hack so we don't need to call
     286             :   // trap_handler::IsTrapHandlerEnabled().
     287             :   const bool is_trap_handler_enabled =
     288      731760 :       V8_TRAP_HANDLER_SUPPORTED && i::FLAG_wasm_trap_handler;
     289      731760 :   return {test_module_ptr_,
     290             :           is_trap_handler_enabled ? kUseTrapHandler : kNoTrapHandler,
     291     1463520 :           runtime_exception_support_, enabled_features_, lower_simd()};
     292             : }
     293             : 
     294       22240 : const WasmGlobal* TestingModuleBuilder::AddGlobal(ValueType type) {
     295       22240 :   byte size = ValueTypes::MemSize(ValueTypes::MachineTypeFor(type));
     296       22240 :   global_offset = (global_offset + size - 1) & ~(size - 1);  // align
     297       66720 :   test_module_->globals.push_back(
     298             :       {type, true, WasmInitExpr(), {global_offset}, false, false});
     299       22240 :   global_offset += size;
     300             :   // limit number of globals.
     301       22240 :   CHECK_LT(global_offset, kMaxGlobalsSize);
     302       22240 :   return &test_module_->globals.back();
     303             : }
     304             : 
     305     1094224 : Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() {
     306             :   Handle<Script> script =
     307     2188448 :       isolate_->factory()->NewScript(isolate_->factory()->empty_string());
     308             :   script->set_type(Script::TYPE_WASM);
     309             :   Handle<WasmModuleObject> module_object =
     310             :       WasmModuleObject::New(isolate_, enabled_features_, test_module_, {},
     311     4376896 :                             script, Handle<ByteArray>::null());
     312             :   // This method is called when we initialize TestEnvironment. We don't
     313             :   // have a memory yet, so we won't create it here. We'll update the
     314             :   // interpreter when we get a memory. We do have globals, though.
     315     1094224 :   native_module_ = module_object->native_module();
     316     1094224 :   native_module_->ReserveCodeTableForTesting(kMaxFunctions);
     317             : 
     318     1094224 :   auto instance = WasmInstanceObject::New(isolate_, module_object);
     319     2188448 :   instance->set_exceptions_table(*isolate_->factory()->empty_fixed_array());
     320     1094224 :   instance->set_globals_start(globals_data_);
     321     1094224 :   return instance;
     322             : }
     323             : 
     324         492 : void TestBuildingGraphWithBuilder(compiler::WasmGraphBuilder* builder,
     325             :                                   Zone* zone, FunctionSig* sig,
     326             :                                   const byte* start, const byte* end) {
     327         492 :   WasmFeatures unused_detected_features;
     328             :   FunctionBody body(sig, 0, start, end);
     329             :   DecodeResult result =
     330         984 :       BuildTFGraph(zone->allocator(), kAllWasmFeatures, nullptr, builder,
     331             :                    &unused_detected_features, body, nullptr);
     332         492 :   if (result.failed()) {
     333             : #ifdef DEBUG
     334             :     if (!FLAG_trace_wasm_decoder) {
     335             :       // Retry the compilation with the tracing flag on, to help in debugging.
     336             :       FLAG_trace_wasm_decoder = true;
     337             :       result = BuildTFGraph(zone->allocator(), kAllWasmFeatures, nullptr,
     338             :                             builder, &unused_detected_features, body, nullptr);
     339             :     }
     340             : #endif
     341             : 
     342             :     FATAL("Verification failed; pc = +%x, msg = %s", result.error().offset(),
     343           0 :           result.error().message().c_str());
     344             :   }
     345         492 :   builder->LowerInt64();
     346         492 :   if (!CpuFeatures::SupportsWasmSimd128()) {
     347           0 :     builder->SimdScalarLoweringForTesting();
     348             :   }
     349         492 : }
     350             : 
     351         492 : void TestBuildingGraph(Zone* zone, compiler::JSGraph* jsgraph,
     352             :                        CompilationEnv* module, FunctionSig* sig,
     353             :                        compiler::SourcePositionTable* source_position_table,
     354             :                        const byte* start, const byte* end) {
     355             :   compiler::WasmGraphBuilder builder(module, zone, jsgraph, sig,
     356         492 :                                      source_position_table);
     357         492 :   TestBuildingGraphWithBuilder(&builder, zone, sig, start, end);
     358         492 : }
     359             : 
     360     1094224 : WasmFunctionWrapper::WasmFunctionWrapper(Zone* zone, int num_params)
     361             :     : GraphAndBuilders(zone),
     362             :       inner_code_node_(nullptr),
     363             :       context_address_(nullptr),
     364     2188448 :       signature_(nullptr) {
     365             :   // One additional parameter for the pointer to the return value memory.
     366     1094224 :   Signature<MachineType>::Builder sig_builder(zone, 1, num_params + 1);
     367             : 
     368             :   sig_builder.AddReturn(MachineType::Int32());
     369     3349216 :   for (int i = 0; i < num_params + 1; i++) {
     370             :     sig_builder.AddParam(MachineType::Pointer());
     371             :   }
     372     1094224 :   signature_ = sig_builder.Build();
     373     1094224 : }
     374             : 
     375      729312 : void WasmFunctionWrapper::Init(CallDescriptor* call_descriptor,
     376             :                                MachineType return_type,
     377             :                                Vector<MachineType> param_types) {
     378             :   DCHECK_NOT_NULL(call_descriptor);
     379             :   DCHECK_EQ(signature_->parameter_count(), param_types.length() + 1);
     380             : 
     381             :   // Create the TF graph for the wrapper.
     382             : 
     383             :   // Function, context_address, effect, and control.
     384      729312 :   Node** parameters = zone()->NewArray<Node*>(param_types.length() + 4);
     385             :   int start_value_output_count =
     386      729312 :       static_cast<int>(signature_->parameter_count()) + 1;
     387      729312 :   graph()->SetStart(
     388             :       graph()->NewNode(common()->Start(start_value_output_count)));
     389             :   Node* effect = graph()->start();
     390             :   int parameter_count = 0;
     391             : 
     392             :   // Dummy node which gets replaced in SetInnerCode.
     393     1458624 :   inner_code_node_ = graph()->NewNode(common()->Int32Constant(0));
     394      729312 :   parameters[parameter_count++] = inner_code_node_;
     395             : 
     396             :   // Dummy node that gets replaced in SetContextAddress.
     397     1458624 :   context_address_ = graph()->NewNode(IntPtrConstant(0));
     398      729312 :   parameters[parameter_count++] = context_address_;
     399             : 
     400             :   int param_idx = 0;
     401      773576 :   for (MachineType t : param_types) {
     402             :     DCHECK_NE(MachineType::None(), t);
     403       66396 :     parameters[parameter_count] = graph()->NewNode(
     404             :         machine()->Load(t),
     405             :         graph()->NewNode(common()->Parameter(param_idx++), graph()->start()),
     406       22132 :         graph()->NewNode(common()->Int32Constant(0)), effect, graph()->start());
     407       22132 :     effect = parameters[parameter_count++];
     408             :   }
     409             : 
     410      729312 :   parameters[parameter_count++] = effect;
     411      729312 :   parameters[parameter_count++] = graph()->start();
     412      729312 :   Node* call = graph()->NewNode(common()->Call(call_descriptor),
     413      729312 :                                 parameter_count, parameters);
     414             : 
     415      729312 :   if (!return_type.IsNone()) {
     416     2901536 :     effect = graph()->NewNode(
     417             :         machine()->Store(compiler::StoreRepresentation(
     418             :             return_type.representation(), WriteBarrierKind::kNoWriteBarrier)),
     419             :         graph()->NewNode(common()->Parameter(param_types.length()),
     420             :                          graph()->start()),
     421             :         graph()->NewNode(common()->Int32Constant(0)), call, effect,
     422             :         graph()->start());
     423             :   }
     424      729312 :   Node* zero = graph()->NewNode(common()->Int32Constant(0));
     425     1458624 :   Node* r = graph()->NewNode(
     426             :       common()->Return(), zero,
     427             :       graph()->NewNode(common()->Int32Constant(WASM_WRAPPER_RETURN_VALUE)),
     428             :       effect, graph()->start());
     429      729312 :   graph()->SetEnd(graph()->NewNode(common()->End(1), r));
     430      729312 : }
     431             : 
     432     9612676 : Handle<Code> WasmFunctionWrapper::GetWrapperCode() {
     433             :   Handle<Code> code;
     434     9612676 :   if (!code_.ToHandle(&code)) {
     435             :     Isolate* isolate = CcTest::InitIsolateOnce();
     436             : 
     437             :     auto call_descriptor =
     438      724944 :         compiler::Linkage::GetSimplifiedCDescriptor(zone(), signature_, true);
     439             : 
     440             :     if (kSystemPointerSize == 4) {
     441             :       size_t num_params = signature_->parameter_count();
     442             :       // One additional parameter for the pointer of the return value.
     443             :       Signature<MachineRepresentation>::Builder rep_builder(zone(), 1,
     444             :                                                             num_params + 1);
     445             : 
     446             :       rep_builder.AddReturn(MachineRepresentation::kWord32);
     447             :       for (size_t i = 0; i < num_params + 1; i++) {
     448             :         rep_builder.AddParam(MachineRepresentation::kWord32);
     449             :       }
     450             :       compiler::Int64Lowering r(graph(), machine(), common(), zone(),
     451             :                                 rep_builder.Build());
     452             :       r.LowerGraph();
     453             :     }
     454             : 
     455             :     OptimizedCompilationInfo info(ArrayVector("testing"), graph()->zone(),
     456     1449888 :                                   Code::C_WASM_ENTRY);
     457             :     code_ = compiler::Pipeline::GenerateCodeForTesting(
     458             :         &info, isolate, call_descriptor, graph(),
     459      724944 :         AssemblerOptions::Default(isolate));
     460             :     code = code_.ToHandleChecked();
     461             : #ifdef ENABLE_DISASSEMBLER
     462             :     if (FLAG_print_opt_code) {
     463             :       CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
     464             :       OFStream os(tracing_scope.file());
     465             : 
     466             :       code->Disassemble("wasm wrapper", os);
     467             :     }
     468             : #endif
     469             :   }
     470             : 
     471     9612676 :   return code;
     472             : }
     473             : 
     474     1097876 : void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
     475     1097876 :   size_t locals_size = local_decls.Size();
     476     1097876 :   size_t total_size = end - start + locals_size + 1;
     477     1097876 :   byte* buffer = static_cast<byte*>(zone()->New(total_size));
     478             :   // Prepend the local decls to the code.
     479     1097876 :   local_decls.Emit(buffer);
     480             :   // Emit the code.
     481     1097876 :   memcpy(buffer + locals_size, start, end - start);
     482             :   // Append an extra end opcode.
     483     1097876 :   buffer[total_size - 1] = kExprEnd;
     484             : 
     485             :   start = buffer;
     486     1097876 :   end = buffer + total_size;
     487             : 
     488     1097876 :   CHECK_GE(kMaxInt, end - start);
     489     1097876 :   int len = static_cast<int>(end - start);
     490     2195752 :   function_->code = {builder_->AddBytes(Vector<const byte>(start, len)),
     491     2195752 :                      static_cast<uint32_t>(len)};
     492             : 
     493     1097876 :   if (interpreter_) {
     494             :     // Add the code to the interpreter; do not generate compiled code.
     495      366116 :     interpreter_->SetFunctionCodeForTesting(function_, start, end);
     496      366116 :     return;
     497             :   }
     498             : 
     499      731760 :   Vector<const uint8_t> wire_bytes = builder_->instance_object()
     500     1463520 :                                          ->module_object()
     501             :                                          ->native_module()
     502      731760 :                                          ->wire_bytes();
     503             : 
     504      731760 :   CompilationEnv env = builder_->CreateCompilationEnv();
     505      731760 :   ScopedVector<uint8_t> func_wire_bytes(function_->code.length());
     506      731760 :   memcpy(func_wire_bytes.start(), wire_bytes.start() + function_->code.offset(),
     507             :          func_wire_bytes.length());
     508             : 
     509             :   FunctionBody func_body{function_->sig, function_->code.offset(),
     510             :                          func_wire_bytes.start(), func_wire_bytes.end()};
     511             :   NativeModule* native_module =
     512     1463520 :       builder_->instance_object()->module_object()->native_module();
     513     1463520 :   WasmCompilationUnit unit(function_->func_index, builder_->execution_tier());
     514      731760 :   WasmFeatures unused_detected_features;
     515             :   WasmCompilationResult result = unit.ExecuteCompilation(
     516             :       isolate()->wasm_engine(), &env,
     517     1463520 :       native_module->compilation_state()->GetWireBytesStorage(),
     518     1463520 :       isolate()->counters(), &unused_detected_features);
     519      731760 :   WasmCode* code = native_module->AddCompiledCode(std::move(result));
     520             :   DCHECK_NOT_NULL(code);
     521      731760 :   if (WasmCode::ShouldBeLogged(isolate())) code->LogCode(isolate());
     522             : }
     523             : 
     524     1103276 : WasmFunctionCompiler::WasmFunctionCompiler(Zone* zone, FunctionSig* sig,
     525             :                                            TestingModuleBuilder* builder,
     526             :                                            const char* name)
     527             :     : GraphAndBuilders(zone),
     528             :       jsgraph(builder->isolate(), this->graph(), this->common(), nullptr,
     529             :               nullptr, this->machine()),
     530             :       sig(sig),
     531             :       descriptor_(nullptr),
     532             :       builder_(builder),
     533             :       local_decls(zone, sig),
     534             :       source_position_table_(this->graph()),
     535     3309828 :       interpreter_(builder->interpreter()) {
     536             :   // Get a new function from the testing module.
     537     1103276 :   int index = builder->AddFunction(sig, name, TestingModuleBuilder::kWasm);
     538     2206552 :   function_ = builder_->GetFunctionAt(index);
     539     1103276 : }
     540             : 
     541             : WasmFunctionCompiler::~WasmFunctionCompiler() = default;
     542             : 
     543     1094476 : FunctionSig* WasmRunnerBase::CreateSig(MachineType return_type,
     544             :                                        Vector<MachineType> param_types) {
     545     1094476 :   int return_count = return_type.IsNone() ? 0 : 1;
     546             :   int param_count = param_types.length();
     547             : 
     548             :   // Allocate storage array in zone.
     549     1094476 :   ValueType* sig_types = zone_.NewArray<ValueType>(return_count + param_count);
     550             : 
     551             :   // Convert machine types to local types, and check that there are no
     552             :   // MachineType::None()'s in the parameters.
     553             :   int idx = 0;
     554     1094476 :   if (return_count) sig_types[idx++] = ValueTypes::ValueTypeFor(return_type);
     555     1161676 :   for (MachineType param : param_types) {
     556       33600 :     CHECK_NE(MachineType::None(), param);
     557       33600 :     sig_types[idx++] = ValueTypes::ValueTypeFor(param);
     558             :   }
     559     2188952 :   return new (&zone_) FunctionSig(return_count, param_count, sig_types);
     560             : }
     561             : 
     562             : // static
     563             : bool WasmRunnerBase::trap_happened;
     564             : 
     565             : }  // namespace wasm
     566             : }  // namespace internal
     567       79917 : }  // namespace v8

Generated by: LCOV version 1.10