summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/wasm/wasm-run-utils.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest/wasm/wasm-run-utils.cc')
-rw-r--r--deps/v8/test/cctest/wasm/wasm-run-utils.cc130
1 files changed, 58 insertions, 72 deletions
diff --git a/deps/v8/test/cctest/wasm/wasm-run-utils.cc b/deps/v8/test/cctest/wasm/wasm-run-utils.cc
index d6aacab5c3..ee0f88ab82 100644
--- a/deps/v8/test/cctest/wasm/wasm-run-utils.cc
+++ b/deps/v8/test/cctest/wasm/wasm-run-utils.cc
@@ -18,6 +18,7 @@
#include "src/wasm/wasm-import-wrapper-cache.h"
#include "src/wasm/wasm-objects-inl.h"
#include "src/wasm/wasm-opcodes.h"
+#include "src/wasm/wasm-subtyping.h"
namespace v8 {
namespace internal {
@@ -44,10 +45,10 @@ bool IsSameNan(double expected, double actual) {
}
TestingModuleBuilder::TestingModuleBuilder(
- Zone* zone, ManuallyImportedJSFunction* maybe_import,
+ Zone* zone, ModuleOrigin origin, ManuallyImportedJSFunction* maybe_import,
TestExecutionTier tier, RuntimeExceptionSupport exception_support,
TestingModuleMemoryType mem_type, Isolate* isolate)
- : test_module_(std::make_shared<WasmModule>()),
+ : test_module_(std::make_shared<WasmModule>(origin)),
isolate_(isolate ? isolate : CcTest::InitIsolateOnce()),
enabled_features_(WasmFeatures::FromIsolate(isolate_)),
execution_tier_(tier),
@@ -75,15 +76,14 @@ TestingModuleBuilder::TestingModuleBuilder(
if (maybe_import) {
// Manually compile an import wrapper and insert it into the instance.
- auto resolved = compiler::ResolveWasmImportCall(
- maybe_import->js_function, maybe_import->sig,
- instance_object_->module(), enabled_features_);
- compiler::WasmImportCallKind kind = resolved.kind;
- Handle<JSReceiver> callable = resolved.callable;
- WasmImportWrapperCache::ModificationScope cache_scope(
- native_module_->import_wrapper_cache());
uint32_t canonical_type_index =
GetTypeCanonicalizer()->AddRecursiveGroup(maybe_import->sig);
+ WasmImportData resolved(maybe_import->js_function, maybe_import->sig,
+ canonical_type_index);
+ ImportCallKind kind = resolved.kind();
+ Handle<JSReceiver> callable = resolved.callable();
+ WasmImportWrapperCache::ModificationScope cache_scope(
+ native_module_->import_wrapper_cache());
WasmImportWrapperCache::CacheKey key(
kind, canonical_type_index,
static_cast<int>(maybe_import->sig->parameter_count()), kNoSuspend);
@@ -98,7 +98,7 @@ TestingModuleBuilder::TestingModuleBuilder(
}
ImportedFunctionEntry(instance_object_, maybe_import_index)
- .SetWasmToJs(isolate_, callable, import_wrapper, resolved.suspend);
+ .SetWasmToJs(isolate_, callable, import_wrapper, resolved.suspend());
}
if (tier == TestExecutionTier::kInterpreter) {
@@ -125,6 +125,8 @@ byte* TestingModuleBuilder::AddMemory(uint32_t size, SharedFlag shared) {
? test_module_->maximum_pages
: initial_pages;
test_module_->has_memory = true;
+ test_module_->min_memory_size = initial_pages * kWasmPageSize;
+ test_module_->max_memory_size = maximum_pages * kWasmPageSize;
// Create the WasmMemoryObject.
Handle<WasmMemoryObject> memory_object =
@@ -155,6 +157,12 @@ uint32_t TestingModuleBuilder::AddFunction(const FunctionSig* sig,
DCHECK_NULL(test_module_->validated_functions);
test_module_->validated_functions =
std::make_unique<std::atomic<uint8_t>[]>((kMaxFunctions + 7) / 8);
+ if (is_asmjs_module(test_module_.get())) {
+ // All asm.js functions are valid by design.
+ std::fill_n(test_module_->validated_functions.get(),
+ (kMaxFunctions + 7) / 8, 0xff);
+ }
+ test_module_->type_feedback.well_known_imports.Initialize(kMaxFunctions);
}
uint32_t index = static_cast<uint32_t>(test_module_->functions.size());
test_module_->functions.push_back({sig, // sig
@@ -185,7 +193,7 @@ uint32_t TestingModuleBuilder::AddFunction(const FunctionSig* sig,
}
DCHECK_LT(index, kMaxFunctions); // limited for testing.
if (!instance_object_.is_null()) {
- Handle<FixedArray> funcs = isolate_->factory()->NewFixedArray(
+ Handle<FixedArray> funcs = isolate_->factory()->NewFixedArrayWithZeroes(
static_cast<int>(test_module_->functions.size()));
instance_object_->set_wasm_internal_functions(*funcs);
}
@@ -235,10 +243,12 @@ void TestingModuleBuilder::AddIndirectFunctionTable(
WasmInstanceObject::EnsureIndirectFunctionTableWithMinimumSize(
instance_object(), table_index, table_size);
- Handle<WasmTableObject> table_obj =
- WasmTableObject::New(isolate_, instance, table.type, table.initial_size,
- table.has_maximum_size, table.maximum_size, nullptr,
- isolate_->factory()->null_value());
+ Handle<WasmTableObject> table_obj = WasmTableObject::New(
+ isolate_, instance, table.type, table.initial_size,
+ table.has_maximum_size, table.maximum_size, nullptr,
+ IsSubtypeOf(table.type, kWasmExternRef, test_module_.get())
+ ? Handle<Object>::cast(isolate_->factory()->null_value())
+ : Handle<Object>::cast(isolate_->factory()->wasm_null()));
WasmTableObject::AddDispatchTable(isolate_, table_obj, instance_object_,
table_index);
@@ -273,13 +283,13 @@ uint32_t TestingModuleBuilder::AddBytes(base::Vector<const byte> bytes) {
base::OwnedVector<uint8_t> new_bytes =
base::OwnedVector<uint8_t>::New(new_size);
if (old_size > 0) {
- memcpy(new_bytes.start(), old_bytes.begin(), old_size);
+ memcpy(new_bytes.begin(), old_bytes.begin(), old_size);
} else {
// Set the unused byte. It is never decoded, but the bytes are used as the
// key in the native module cache.
new_bytes[0] = 0;
}
- memcpy(new_bytes.start() + bytes_offset, bytes.begin(), bytes.length());
+ memcpy(new_bytes.begin() + bytes_offset, bytes.begin(), bytes.length());
native_module_->SetWireBytes(std::move(new_bytes));
return bytes_offset;
}
@@ -287,7 +297,7 @@ uint32_t TestingModuleBuilder::AddBytes(base::Vector<const byte> bytes) {
uint32_t TestingModuleBuilder::AddException(const FunctionSig* sig) {
DCHECK_EQ(0, sig->return_count());
uint32_t index = static_cast<uint32_t>(test_module_->tags.size());
- test_module_->tags.push_back(WasmTag{sig});
+ test_module_->tags.emplace_back(sig, AddSignature(sig));
Handle<WasmExceptionTag> tag = WasmExceptionTag::New(isolate_, index);
Handle<FixedArray> table(instance_object_->tags_table(), isolate_);
table = isolate_->factory()->CopyFixedArrayAndGrow(table, 1);
@@ -346,29 +356,6 @@ uint32_t TestingModuleBuilder::AddPassiveDataSegment(
return index;
}
-uint32_t TestingModuleBuilder::AddPassiveElementSegment(
- const std::vector<uint32_t>& entries) {
- uint32_t index = static_cast<uint32_t>(test_module_->elem_segments.size());
- DCHECK_EQ(index, dropped_elem_segments_.size());
-
- test_module_->elem_segments.emplace_back(
- kWasmFuncRef, WasmElemSegment::kStatusPassive,
- WasmElemSegment::kFunctionIndexElements);
- auto& elem_segment = test_module_->elem_segments.back();
- for (uint32_t entry : entries) {
- elem_segment.entries.emplace_back(ConstantExpression::RefFunc(entry));
- }
-
- // The vector pointers may have moved, so update the instance object.
- dropped_elem_segments_.push_back(0);
- uint32_t size = static_cast<uint32_t>(dropped_elem_segments_.size());
- Handle<FixedUInt8Array> dropped_elem_segments =
- FixedUInt8Array::New(isolate_, size);
- dropped_elem_segments->copy_in(0, dropped_elem_segments_.data(), size);
- instance_object_->set_dropped_elem_segments(*dropped_elem_segments);
- return index;
-}
-
CompilationEnv TestingModuleBuilder::CreateCompilationEnv() {
return {test_module_.get(), native_module_->bounds_checks(),
runtime_exception_support_, enabled_features_, kNoDynamicTiering};
@@ -408,8 +395,11 @@ Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() {
native_module_->ReserveCodeTableForTesting(kMaxFunctions);
auto instance = WasmInstanceObject::New(isolate_, module_object);
- instance->set_tags_table(*isolate_->factory()->empty_fixed_array());
+ instance->set_tags_table(ReadOnlyRoots{isolate_}.empty_fixed_array());
instance->set_globals_start(globals_data_);
+ Handle<FixedArray> feedback_vector =
+ isolate_->factory()->NewFixedArrayWithZeroes(kMaxFunctions);
+ instance->set_feedback_vectors(*feedback_vector);
return instance;
}
@@ -419,23 +409,9 @@ void TestBuildingGraphWithBuilder(compiler::WasmGraphBuilder* builder,
WasmFeatures unused_detected_features;
FunctionBody body(sig, 0, start, end);
std::vector<compiler::WasmLoopInfo> loops;
- DecodeResult result = BuildTFGraph(
- zone->allocator(), WasmFeatures::All(), nullptr, builder,
- &unused_detected_features, body, &loops, nullptr, 0, kRegularFunction);
- if (result.failed()) {
-#ifdef DEBUG
- if (!v8_flags.trace_wasm_decoder) {
- // Retry the compilation with the tracing flag on, to help in debugging.
- v8_flags.trace_wasm_decoder = true;
- result = BuildTFGraph(zone->allocator(), WasmFeatures::All(), nullptr,
- builder, &unused_detected_features, body, &loops,
- nullptr, 0, kRegularFunction);
- }
-#endif
-
- FATAL("Verification failed; pc = +%x, msg = %s", result.error().offset(),
- result.error().message().c_str());
- }
+ BuildTFGraph(zone->allocator(), WasmFeatures::All(), nullptr, builder,
+ &unused_detected_features, body, &loops, nullptr, nullptr, 0,
+ nullptr, kRegularFunction);
builder->LowerInt64(compiler::WasmGraphBuilder::kCalledFromWasm);
}
@@ -544,7 +520,7 @@ Handle<Code> WasmFunctionWrapper::GetWrapperCode(Isolate* isolate) {
rep_builder.AddParam(MachineRepresentation::kWord32);
}
compiler::Int64Lowering r(graph(), machine(), common(), simplified(),
- zone(), nullptr, rep_builder.Build());
+ zone(), rep_builder.Build());
r.LowerGraph();
}
@@ -570,28 +546,26 @@ Handle<Code> WasmFunctionWrapper::GetWrapperCode(Isolate* isolate) {
// This struct is just a type tag for Zone::NewArray<T>(size_t) call.
struct WasmFunctionCompilerBuffer {};
-void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
+void WasmFunctionCompiler::Build(base::Vector<const uint8_t> bytes) {
size_t locals_size = local_decls.Size();
- size_t total_size = end - start + locals_size + 1;
+ size_t total_size = bytes.size() + locals_size + 1;
byte* buffer = zone()->NewArray<byte, WasmFunctionCompilerBuffer>(total_size);
// Prepend the local decls to the code.
local_decls.Emit(buffer);
// Emit the code.
- memcpy(buffer + locals_size, start, end - start);
+ memcpy(buffer + locals_size, bytes.begin(), bytes.size());
// Append an extra end opcode.
buffer[total_size - 1] = kExprEnd;
- start = buffer;
- end = buffer + total_size;
+ bytes = base::VectorOf(buffer, total_size);
- CHECK_GE(kMaxInt, end - start);
- int len = static_cast<int>(end - start);
- function_->code = {builder_->AddBytes(base::Vector<const byte>(start, len)),
- static_cast<uint32_t>(len)};
+ function_->code = {builder_->AddBytes(bytes),
+ static_cast<uint32_t>(bytes.size())};
if (interpreter_) {
// Add the code to the interpreter; do not generate compiled code.
- interpreter_->SetFunctionCodeForTesting(function_, start, end);
+ interpreter_->SetFunctionCodeForTesting(function_, bytes.begin(),
+ bytes.end());
return;
}
@@ -610,7 +584,19 @@ void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
NativeModule* native_module =
builder_->instance_object()->module_object().native_module();
ForDebugging for_debugging =
- native_module->IsTieredDown() ? kForDebugging : kNoDebugging;
+ native_module->IsInDebugState() ? kForDebugging : kNotForDebugging;
+
+ WasmFeatures unused_detected_features;
+ // Validate Wasm modules; asm.js is assumed to be always valid.
+ if (env.module->origin == kWasmOrigin) {
+ DecodeResult validation_result = ValidateFunctionBody(
+ env.enabled_features, env.module, &unused_detected_features, func_body);
+ if (validation_result.failed()) {
+ FATAL("Validation failed: %s",
+ validation_result.error().message().c_str());
+ }
+ env.module->set_function_validated(function_->func_index);
+ }
base::Optional<WasmCompilationResult> result;
if (builder_->test_execution_tier() ==
@@ -625,11 +611,11 @@ void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
} else {
WasmCompilationUnit unit(function_->func_index, builder_->execution_tier(),
for_debugging);
- WasmFeatures unused_detected_features;
result.emplace(unit.ExecuteCompilation(
&env, native_module->compilation_state()->GetWireBytesStorage().get(),
nullptr, nullptr, &unused_detected_features));
}
+ CHECK(result->succeeded());
WasmCode* code = native_module->PublishCode(
native_module->AddCompiledCode(std::move(*result)));
DCHECK_NOT_NULL(code);