Commit f13c807e authored by Z Nguyen-Huu's avatar Z Nguyen-Huu Committed by Commit Bot

[wasm] WAT-compatible naming for memory

Currently, only one memory is supported.

For memory, we would use name as follows.
1. If import: use <import_module>.<field_name> from WasmImport.
2. If export: use <field_name> from WasmExport.
3. Use memory<index>.

Doc: https://docs.google.com/document/d/1XoXWONLBgZWQ9dhtoMpQPvD0fnnWA50OorsuSXfME3g
Bug: v8:10242
Change-Id: Ifd342bcd86ac302f5b43f2ee88a8ea21a28b5a0f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2132724
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarKim-Anh Tran <kimanh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67020}
parent 1766012c
...@@ -2257,17 +2257,18 @@ void DecodeFunctionNames(const byte* module_start, const byte* module_end, ...@@ -2257,17 +2257,18 @@ void DecodeFunctionNames(const byte* module_start, const byte* module_end,
} }
} }
void DecodeGlobalNames( void GenerateNamesFromImportsAndExports(
const Vector<const WasmImport> import_table, ImportExportKindCode kind, const Vector<const WasmImport> import_table,
const Vector<const WasmExport> export_table, const Vector<const WasmExport> export_table,
std::unordered_map<uint32_t, std::pair<WireBytesRef, WireBytesRef>>* std::unordered_map<uint32_t, std::pair<WireBytesRef, WireBytesRef>>*
names) { names) {
DCHECK_NOT_NULL(names); DCHECK_NOT_NULL(names);
DCHECK(names->empty()); DCHECK(names->empty());
DCHECK(kind == kExternalGlobal || kind == kExternalMemory);
// Extract from import table. // Extract from import table.
for (const WasmImport& imp : import_table) { for (const WasmImport& imp : import_table) {
if (imp.kind != kExternalGlobal) continue; if (imp.kind != kind) continue;
if (!imp.module_name.is_set() || !imp.field_name.is_set()) continue; if (!imp.module_name.is_set() || !imp.field_name.is_set()) continue;
if (names->count(imp.index) == 0) { if (names->count(imp.index) == 0) {
names->insert(std::make_pair( names->insert(std::make_pair(
...@@ -2277,7 +2278,7 @@ void DecodeGlobalNames( ...@@ -2277,7 +2278,7 @@ void DecodeGlobalNames(
// Extract from export table. // Extract from export table.
for (const WasmExport& exp : export_table) { for (const WasmExport& exp : export_table) {
if (exp.kind != kExternalGlobal) continue; if (exp.kind != kind) continue;
if (!exp.name.is_set()) continue; if (!exp.name.is_set()) continue;
if (names->count(exp.index) == 0) { if (names->count(exp.index) == 0) {
names->insert( names->insert(
......
...@@ -168,10 +168,10 @@ void DecodeFunctionNames(const byte* module_start, const byte* module_end, ...@@ -168,10 +168,10 @@ void DecodeFunctionNames(const byte* module_start, const byte* module_end,
std::unordered_map<uint32_t, WireBytesRef>* names, std::unordered_map<uint32_t, WireBytesRef>* names,
const Vector<const WasmExport> export_table); const Vector<const WasmExport> export_table);
// Decode the global names from import table and export table. Returns the // Decode the global or memory names from import table and export table. Returns
// result as an unordered map. // the result as an unordered map.
void DecodeGlobalNames( void GenerateNamesFromImportsAndExports(
const Vector<const WasmImport> import_table, ImportExportKindCode kind, const Vector<const WasmImport> import_table,
const Vector<const WasmExport> export_table, const Vector<const WasmExport> export_table,
std::unordered_map<uint32_t, std::pair<WireBytesRef, WireBytesRef>>* names); std::unordered_map<uint32_t, std::pair<WireBytesRef, WireBytesRef>>* names);
......
...@@ -195,8 +195,10 @@ void WasmCode::LogCode(Isolate* isolate) const { ...@@ -195,8 +195,10 @@ void WasmCode::LogCode(Isolate* isolate) const {
if (IsAnonymous()) return; if (IsAnonymous()) return;
ModuleWireBytes wire_bytes(native_module()->wire_bytes()); ModuleWireBytes wire_bytes(native_module()->wire_bytes());
WireBytesRef name_ref = native_module()->module()->function_names.Lookup( WireBytesRef name_ref =
wire_bytes, index(), VectorOf(native_module()->module()->export_table)); native_module()->module()->lazily_generated_names.LookupFunctionName(
wire_bytes, index(),
VectorOf(native_module()->module()->export_table));
WasmName name = wire_bytes.GetNameOrNull(name_ref); WasmName name = wire_bytes.GetNameOrNull(name_ref);
const std::string& source_map_url = native_module()->module()->source_map_url; const std::string& source_map_url = native_module()->module()->source_map_url;
......
...@@ -162,8 +162,9 @@ static bool VerifyEvaluatorInterface(const WasmModule* raw_module, ...@@ -162,8 +162,9 @@ static bool VerifyEvaluatorInterface(const WasmModule* raw_module,
const ModuleWireBytes& bytes, const ModuleWireBytes& bytes,
ErrorThrower* thrower) { ErrorThrower* thrower) {
for (const WasmFunction& F : raw_module->functions) { for (const WasmFunction& F : raw_module->functions) {
WireBytesRef name_ref = raw_module->function_names.Lookup( WireBytesRef name_ref =
bytes, F.func_index, VectorOf(raw_module->export_table)); raw_module->lazily_generated_names.LookupFunctionName(
bytes, F.func_index, VectorOf(raw_module->export_table));
std::string name(bytes.start() + name_ref.offset(), std::string name(bytes.start() + name_ref.offset(),
bytes.start() + name_ref.end_offset()); bytes.start() + name_ref.end_offset());
if (F.exported && name == "wasm_format") { if (F.exported && name == "wasm_format") {
......
...@@ -519,8 +519,15 @@ Handle<JSObject> GetGlobalScopeObject(Handle<WasmInstanceObject> instance) { ...@@ -519,8 +519,15 @@ Handle<JSObject> GetGlobalScopeObject(Handle<WasmInstanceObject> instance) {
Handle<JSObject> global_scope_object = Handle<JSObject> global_scope_object =
isolate->factory()->NewJSObjectWithNullProto(); isolate->factory()->NewJSObjectWithNullProto();
if (instance->has_memory_object()) { if (instance->has_memory_object()) {
Handle<String> name = Handle<String> name;
isolate->factory()->InternalizeString(StaticCharVector("memory")); // TODO(duongn): extend the logic when multiple memories are supported.
const uint32_t memory_index = 0;
if (!WasmInstanceObject::GetMemoryNameOrNull(isolate, instance,
memory_index)
.ToHandle(&name)) {
const char* label = "memory%d";
name = PrintFToOneByteString<true>(isolate, label, memory_index);
}
Handle<JSArrayBuffer> memory_buffer( Handle<JSArrayBuffer> memory_buffer(
instance->memory_object().array_buffer(), isolate); instance->memory_object().array_buffer(), isolate);
Handle<JSTypedArray> uint8_array = isolate->factory()->NewJSTypedArray( Handle<JSTypedArray> uint8_array = isolate->factory()->NewJSTypedArray(
......
...@@ -30,7 +30,7 @@ namespace wasm { ...@@ -30,7 +30,7 @@ namespace wasm {
// static // static
const uint32_t WasmElemSegment::kNullIndex; const uint32_t WasmElemSegment::kNullIndex;
WireBytesRef DecodedFunctionNames::Lookup( WireBytesRef LazilyGeneratedNames::LookupFunctionName(
const ModuleWireBytes& wire_bytes, uint32_t function_index, const ModuleWireBytes& wire_bytes, uint32_t function_index,
Vector<const WasmExport> export_table) const { Vector<const WasmExport> export_table) const {
base::MutexGuard lock(&mutex_); base::MutexGuard lock(&mutex_);
...@@ -44,18 +44,23 @@ WireBytesRef DecodedFunctionNames::Lookup( ...@@ -44,18 +44,23 @@ WireBytesRef DecodedFunctionNames::Lookup(
return it->second; return it->second;
} }
std::pair<WireBytesRef, WireBytesRef> DecodedGlobalNames::Lookup( std::pair<WireBytesRef, WireBytesRef>
uint32_t global_index, Vector<const WasmImport> import_table, LazilyGeneratedNames::LookupNameFromImportsAndExports(
ImportExportKindCode kind, uint32_t index,
Vector<const WasmImport> import_table,
Vector<const WasmExport> export_table) const { Vector<const WasmExport> export_table) const {
base::MutexGuard lock(&mutex_); base::MutexGuard lock(&mutex_);
if (!global_names_) { DCHECK(kind == kExternalGlobal || kind == kExternalMemory);
global_names_.reset( auto& names = kind == kExternalGlobal ? global_names_ : memory_names_;
if (!names) {
names.reset(
new std::unordered_map<uint32_t, new std::unordered_map<uint32_t,
std::pair<WireBytesRef, WireBytesRef>>()); std::pair<WireBytesRef, WireBytesRef>>());
DecodeGlobalNames(import_table, export_table, global_names_.get()); GenerateNamesFromImportsAndExports(kind, import_table, export_table,
names.get());
} }
auto it = global_names_->find(global_index); auto it = names->find(index);
if (it == global_names_->end()) return {}; if (it == names->end()) return {};
return it->second; return it->second;
} }
...@@ -118,7 +123,7 @@ int GetContainingWasmFunction(const WasmModule* module, uint32_t byte_offset) { ...@@ -118,7 +123,7 @@ int GetContainingWasmFunction(const WasmModule* module, uint32_t byte_offset) {
return func_index; return func_index;
} }
void DecodedFunctionNames::AddForTesting(int function_index, void LazilyGeneratedNames::AddForTesting(int function_index,
WireBytesRef name) { WireBytesRef name) {
base::MutexGuard lock(&mutex_); base::MutexGuard lock(&mutex_);
if (!function_names_) { if (!function_names_) {
...@@ -192,7 +197,7 @@ WasmName ModuleWireBytes::GetNameOrNull(WireBytesRef ref) const { ...@@ -192,7 +197,7 @@ WasmName ModuleWireBytes::GetNameOrNull(WireBytesRef ref) const {
// Get a string stored in the module bytes representing a function name. // Get a string stored in the module bytes representing a function name.
WasmName ModuleWireBytes::GetNameOrNull(const WasmFunction* function, WasmName ModuleWireBytes::GetNameOrNull(const WasmFunction* function,
const WasmModule* module) const { const WasmModule* module) const {
return GetNameOrNull(module->function_names.Lookup( return GetNameOrNull(module->lazily_generated_names.LookupFunctionName(
*this, function->func_index, VectorOf(module->export_table))); *this, function->func_index, VectorOf(module->export_table)));
} }
......
...@@ -191,34 +191,33 @@ enum ModuleOrigin : uint8_t { ...@@ -191,34 +191,33 @@ enum ModuleOrigin : uint8_t {
struct ModuleWireBytes; struct ModuleWireBytes;
class V8_EXPORT_PRIVATE DecodedFunctionNames { class V8_EXPORT_PRIVATE LazilyGeneratedNames {
public: public:
WireBytesRef Lookup(const ModuleWireBytes& wire_bytes, WireBytesRef LookupFunctionName(const ModuleWireBytes& wire_bytes,
uint32_t function_index, uint32_t function_index,
Vector<const WasmExport> export_table) const; Vector<const WasmExport> export_table) const;
// For memory and global.
std::pair<WireBytesRef, WireBytesRef> LookupNameFromImportsAndExports(
ImportExportKindCode kind, uint32_t index,
const Vector<const WasmImport> import_table,
const Vector<const WasmExport> export_table) const;
void AddForTesting(int function_index, WireBytesRef name); void AddForTesting(int function_index, WireBytesRef name);
private: private:
// {function_names_} is populated lazily after decoding, and therefore needs a // {function_names_}, {global_names_} and {memory_names_} are
// mutex to protect concurrent modifications from multiple {WasmModuleObject}. // populated lazily after decoding, and therefore need a mutex to protect
// concurrent modifications from multiple {WasmModuleObject}.
mutable base::Mutex mutex_; mutable base::Mutex mutex_;
mutable std::unique_ptr<std::unordered_map<uint32_t, WireBytesRef>> mutable std::unique_ptr<std::unordered_map<uint32_t, WireBytesRef>>
function_names_; function_names_;
};
class V8_EXPORT_PRIVATE DecodedGlobalNames {
public:
std::pair<WireBytesRef, WireBytesRef> Lookup(
uint32_t global_index, Vector<const WasmImport> import_table,
Vector<const WasmExport> export_table) const;
private:
// {global_names_} is populated lazily after decoding, and therefore needs a
// mutex to protect concurrent modifications from multiple {WasmModuleObject}.
mutable base::Mutex mutex_;
mutable std::unique_ptr< mutable std::unique_ptr<
std::unordered_map<uint32_t, std::pair<WireBytesRef, WireBytesRef>>> std::unordered_map<uint32_t, std::pair<WireBytesRef, WireBytesRef>>>
global_names_; global_names_;
mutable std::unique_ptr<
std::unordered_map<uint32_t, std::pair<WireBytesRef, WireBytesRef>>>
memory_names_;
}; };
class V8_EXPORT_PRIVATE AsmJsOffsetInformation { class V8_EXPORT_PRIVATE AsmJsOffsetInformation {
...@@ -286,8 +285,7 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -286,8 +285,7 @@ struct V8_EXPORT_PRIVATE WasmModule {
SignatureMap signature_map; // canonicalizing map for signature indexes. SignatureMap signature_map; // canonicalizing map for signature indexes.
ModuleOrigin origin = kWasmOrigin; // origin of the module ModuleOrigin origin = kWasmOrigin; // origin of the module
DecodedFunctionNames function_names; LazilyGeneratedNames lazily_generated_names;
DecodedGlobalNames global_names;
std::string source_map_url; std::string source_map_url;
// Asm.js source position information. Only available for modules compiled // Asm.js source position information. Only available for modules compiled
......
...@@ -241,9 +241,10 @@ MaybeHandle<String> WasmModuleObject::GetFunctionNameOrNull( ...@@ -241,9 +241,10 @@ MaybeHandle<String> WasmModuleObject::GetFunctionNameOrNull(
Isolate* isolate, Handle<WasmModuleObject> module_object, Isolate* isolate, Handle<WasmModuleObject> module_object,
uint32_t func_index) { uint32_t func_index) {
DCHECK_LT(func_index, module_object->module()->functions.size()); DCHECK_LT(func_index, module_object->module()->functions.size());
wasm::WireBytesRef name = module_object->module()->function_names.Lookup( wasm::WireBytesRef name =
wasm::ModuleWireBytes(module_object->native_module()->wire_bytes()), module_object->module()->lazily_generated_names.LookupFunctionName(
func_index, VectorOf(module_object->module()->export_table)); wasm::ModuleWireBytes(module_object->native_module()->wire_bytes()),
func_index, VectorOf(module_object->module()->export_table));
if (!name.is_set()) return {}; if (!name.is_set()) return {};
return ExtractUtf8StringFromModuleBytes(isolate, module_object, name, return ExtractUtf8StringFromModuleBytes(isolate, module_object, name,
kNoInternalize); kNoInternalize);
...@@ -267,8 +268,9 @@ Vector<const uint8_t> WasmModuleObject::GetRawFunctionName( ...@@ -267,8 +268,9 @@ Vector<const uint8_t> WasmModuleObject::GetRawFunctionName(
uint32_t func_index) { uint32_t func_index) {
DCHECK_GT(module()->functions.size(), func_index); DCHECK_GT(module()->functions.size(), func_index);
wasm::ModuleWireBytes wire_bytes(native_module()->wire_bytes()); wasm::ModuleWireBytes wire_bytes(native_module()->wire_bytes());
wasm::WireBytesRef name_ref = module()->function_names.Lookup( wasm::WireBytesRef name_ref =
wire_bytes, func_index, VectorOf(module()->export_table)); module()->lazily_generated_names.LookupFunctionName(
wire_bytes, func_index, VectorOf(module()->export_table));
wasm::WasmName name = wire_bytes.GetNameOrNull(name_ref); wasm::WasmName name = wire_bytes.GetNameOrNull(name_ref);
return Vector<const uint8_t>::cast(name); return Vector<const uint8_t>::cast(name);
} }
...@@ -1523,27 +1525,48 @@ WasmInstanceObject::GetGlobalBufferAndIndex(Handle<WasmInstanceObject> instance, ...@@ -1523,27 +1525,48 @@ WasmInstanceObject::GetGlobalBufferAndIndex(Handle<WasmInstanceObject> instance,
MaybeHandle<String> WasmInstanceObject::GetGlobalNameOrNull( MaybeHandle<String> WasmInstanceObject::GetGlobalNameOrNull(
Isolate* isolate, Handle<WasmInstanceObject> instance, Isolate* isolate, Handle<WasmInstanceObject> instance,
uint32_t global_index) { uint32_t global_index) {
return WasmInstanceObject::GetNameFromImportsAndExportsOrNull(
isolate, instance, wasm::ImportExportKindCode::kExternalGlobal,
global_index);
}
// static
MaybeHandle<String> WasmInstanceObject::GetMemoryNameOrNull(
Isolate* isolate, Handle<WasmInstanceObject> instance,
uint32_t global_index) {
return WasmInstanceObject::GetNameFromImportsAndExportsOrNull(
isolate, instance, wasm::ImportExportKindCode::kExternalMemory,
global_index);
}
// static
MaybeHandle<String> WasmInstanceObject::GetNameFromImportsAndExportsOrNull(
Isolate* isolate, Handle<WasmInstanceObject> instance,
wasm::ImportExportKindCode kind, uint32_t index) {
DCHECK(kind == wasm::ImportExportKindCode::kExternalGlobal ||
kind == wasm::ImportExportKindCode::kExternalMemory);
wasm::ModuleWireBytes wire_bytes( wasm::ModuleWireBytes wire_bytes(
instance->module_object().native_module()->wire_bytes()); instance->module_object().native_module()->wire_bytes());
// This is pair of <module_name, field_name>. // This is pair of <module_name, field_name>.
// If field_name is not set then we don't generate a name. Else if module_name // If field_name is not set then we don't generate a name. Else if module_name
// is set then it is imported global. Otherwise it is exported global. // is set then it is an imported one. Otherwise it is an exported one.
std::pair<wasm::WireBytesRef, wasm::WireBytesRef> name_ref = std::pair<wasm::WireBytesRef, wasm::WireBytesRef> name_ref =
instance->module()->global_names.Lookup( instance->module()
global_index, VectorOf(instance->module()->import_table), ->lazily_generated_names.LookupNameFromImportsAndExports(
VectorOf(instance->module()->export_table)); kind, index, VectorOf(instance->module()->import_table),
VectorOf(instance->module()->export_table));
if (!name_ref.second.is_set()) return {}; if (!name_ref.second.is_set()) return {};
Vector<const char> field_name = wire_bytes.GetNameOrNull(name_ref.second); Vector<const char> field_name = wire_bytes.GetNameOrNull(name_ref.second);
if (!name_ref.first.is_set()) { if (!name_ref.first.is_set()) {
return isolate->factory()->NewStringFromUtf8(VectorOf(field_name)); return isolate->factory()->NewStringFromUtf8(VectorOf(field_name));
} }
Vector<const char> module_name = wire_bytes.GetNameOrNull(name_ref.first); Vector<const char> module_name = wire_bytes.GetNameOrNull(name_ref.first);
std::string global_name; std::string full_name;
global_name.append(module_name.begin(), module_name.end()); full_name.append(module_name.begin(), module_name.end());
global_name.append("."); full_name.append(".");
global_name.append(field_name.begin(), field_name.end()); full_name.append(field_name.begin(), field_name.end());
return isolate->factory()->NewStringFromUtf8(VectorOf(global_name)); return isolate->factory()->NewStringFromUtf8(VectorOf(full_name));
} }
// static // static
......
...@@ -572,9 +572,19 @@ class WasmInstanceObject : public JSObject { ...@@ -572,9 +572,19 @@ class WasmInstanceObject : public JSObject {
Handle<WasmInstanceObject>, Handle<WasmInstanceObject>,
uint32_t global_index); uint32_t global_index);
// Get the name of a memory in the given instance by index.
static MaybeHandle<String> GetMemoryNameOrNull(Isolate*,
Handle<WasmInstanceObject>,
uint32_t memory_index);
OBJECT_CONSTRUCTORS(WasmInstanceObject, JSObject); OBJECT_CONSTRUCTORS(WasmInstanceObject, JSObject);
private: private:
// Get the name in the given instance by index and kind.
static MaybeHandle<String> GetNameFromImportsAndExportsOrNull(
Isolate*, Handle<WasmInstanceObject>, wasm::ImportExportKindCode kind,
uint32_t index);
static void InitDataSegmentArrays(Handle<WasmInstanceObject>, static void InitDataSegmentArrays(Handle<WasmInstanceObject>,
Handle<WasmModuleObject>); Handle<WasmModuleObject>);
static void InitElemSegmentArrays(Handle<WasmInstanceObject>, static void InitElemSegmentArrays(Handle<WasmInstanceObject>,
......
...@@ -164,7 +164,7 @@ uint32_t TestingModuleBuilder::AddFunction(const FunctionSig* sig, ...@@ -164,7 +164,7 @@ uint32_t TestingModuleBuilder::AddFunction(const FunctionSig* sig,
test_module_->num_declared_functions); test_module_->num_declared_functions);
if (name) { if (name) {
Vector<const byte> name_vec = Vector<const byte>::cast(CStrVector(name)); Vector<const byte> name_vec = Vector<const byte>::cast(CStrVector(name));
test_module_->function_names.AddForTesting( test_module_->lazily_generated_names.AddForTesting(
index, {AddBytes(name_vec), static_cast<uint32_t>(name_vec.length())}); index, {AddBytes(name_vec), static_cast<uint32_t>(name_vec.length())});
} }
if (interpreter_) { if (interpreter_) {
......
Test wasm memory names
Waiting for wasm script to be parsed.
Setting breakpoint in wasm.
Running main.
Paused in debugger.
name: memory0
Finished.
Waiting for wasm script to be parsed.
Setting breakpoint in wasm.
Running main.
Paused in debugger.
name: exported_memory
Finished.
Waiting for wasm script to be parsed.
Setting breakpoint in wasm.
Running main.
Paused in debugger.
name: module_name.imported_mem
Finished.
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} =
InspectorTest.start('Test wasm memory names');
utils.load('test/mjsunit/wasm/wasm-module-builder.js');
let func;
// No name memory.
function createModuleBytesUnnamedMemory() {
let builder = new WasmModuleBuilder();
builder.addMemory(1, 1);
func = builder.addFunction('main', kSig_i_i)
.addBody([kExprI32Const, 0, kExprI32LoadMem, 0, 0])
.exportAs('main');
return JSON.stringify(builder.toArray());
}
// Exported memory.
function createModuleBytesExportedMemory() {
let builder = new WasmModuleBuilder();
var memory = builder.addMemory(1, 1);
builder.addExportOfKind('exported_memory', kExternalMemory);
func = builder.addFunction('main', kSig_i_i)
.addBody([kExprI32Const, 0, kExprI32LoadMem, 0, 0])
.exportAs('main');
return JSON.stringify(builder.toArray());
}
// Imported memory.
function createModuleBytesImportedMemory() {
let builder = new WasmModuleBuilder();
builder.addImportedMemory('module_name', 'imported_mem', 0, 1);
func = builder.addFunction('main', kSig_i_i)
.addBody([kExprI32Const, 0, kExprI32LoadMem, 0, 0])
.exportAs('main');
return JSON.stringify(builder.toArray());
}
function createInstance(moduleBytes) {
let module = new WebAssembly.Module((new Uint8Array(moduleBytes)).buffer);
let memory = new WebAssembly.Memory({initial: 1, maximum: 1});
instance =
new WebAssembly.Instance(module, {module_name: {imported_mem: memory}});
}
async function logMemoryName(msg, Protocol) {
let callFrames = msg.params.callFrames;
InspectorTest.log('Paused in debugger.');
let scopeChain = callFrames[0].scopeChain;
for (let scope of scopeChain) {
if (scope.type != 'global') continue;
let globalObjectProps = (await Protocol.Runtime.getProperties({
'objectId': scope.object.objectId
})).result.result;
for (let prop of globalObjectProps) {
InspectorTest.log(`name: ${prop.name}`);
}
}
}
async function check(moduleBytes) {
Protocol.Runtime.evaluate({
expression: `
createInstance(${moduleBytes});`
});
InspectorTest.log('Waiting for wasm script to be parsed.');
let scriptId;
while (true) {
let msg = await Protocol.Debugger.onceScriptParsed();
if (msg.params.url.startsWith('wasm://')) {
scriptId = msg.params.scriptId;
break;
}
}
InspectorTest.log('Setting breakpoint in wasm.');
await Protocol.Debugger.setBreakpoint(
{location: {scriptId, lineNumber: 0, columnNumber: func.body_offset}});
InspectorTest.log('Running main.');
Protocol.Runtime.evaluate({expression: 'instance.exports.main()'});
let msg = await Protocol.Debugger.oncePaused();
await logMemoryName(msg, Protocol);
await Protocol.Debugger.resume();
InspectorTest.log('Finished.');
}
contextGroup.addScript(`
let instance;
${createInstance.toString()}`);
(async function test() {
try {
Protocol.Debugger.enable();
await check(createModuleBytesUnnamedMemory());
await check(createModuleBytesExportedMemory());
await check(createModuleBytesImportedMemory());
} catch (exc) {
InspectorTest.log(`Failed with exception: ${exc}.`);
} finally {
InspectorTest.completeTest();
}
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment