Index: src/wasm/wasm-module.cc |
diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc |
index 80e3700eff40ad01760e20e45293b7f6a8710767..79b99fe04d90f0618cfdf557ff3dd10f14809d34 100644 |
--- a/src/wasm/wasm-module.cc |
+++ b/src/wasm/wasm-module.cc |
@@ -51,6 +51,8 @@ MaybeHandle<String> ExtractStringFromModuleBytes( |
uint32_t offset, uint32_t size) { |
// TODO(wasm): cache strings from modules if it's a performance win. |
Handle<SeqOneByteString> module_bytes = compiled_module->module_bytes(); |
+ DCHECK_GE(static_cast<size_t>(module_bytes->length()), offset); |
+ DCHECK_GE(static_cast<size_t>(module_bytes->length() - offset), size); |
Address raw = module_bytes->GetCharsAddress() + offset; |
if (!unibrow::Utf8::Validate(reinterpret_cast<const byte*>(raw), size)) |
return {}; // UTF8 decoding error for name. |
@@ -583,6 +585,18 @@ static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) { |
TRACE("}\n"); |
} |
+std::pair<int, int> GetFunctionOffsetAndLength( |
+ Handle<WasmCompiledModule> compiled_module, int func_index) { |
+ WasmModule* module = compiled_module->module(); |
+ if (func_index < 0 || |
+ static_cast<size_t>(func_index) > module->functions.size()) { |
+ return {0, 0}; |
+ } |
+ WasmFunction& func = module->functions[func_index]; |
+ return {static_cast<int>(func.code_start_offset), |
+ static_cast<int>(func.code_end_offset - func.code_start_offset)}; |
+} |
+ |
} // namespace |
const char* wasm::SectionName(WasmSectionCode code) { |
@@ -664,10 +678,38 @@ Object* wasm::GetOwningWasmInstance(Code* code) { |
return cell->value(); |
} |
-int wasm::GetNumImportedFunctions(Handle<JSObject> object) { |
- return static_cast<int>(Handle<WasmInstanceObject>::cast(object) |
- ->module() |
- ->num_imported_functions); |
+int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module, |
+ int func_index) { |
+ return GetFunctionOffsetAndLength(compiled_module, func_index).first; |
+} |
+ |
+bool wasm::GetPositionInfo(Handle<WasmCompiledModule> compiled_module, |
+ uint32_t position, Script::PositionInfo* info) { |
+ std::vector<WasmFunction>& functions = compiled_module->module()->functions; |
+ |
+ // Binary search for a function containing the given position. |
+ int left = 0; // inclusive |
+ int right = static_cast<int>(functions.size()); // exclusive |
+ if (right == 0) return false; |
+ while (right - left > 1) { |
+ int mid = left + (right - left) / 2; |
+ if (functions[mid].code_start_offset <= position) { |
+ left = mid; |
+ } else { |
+ right = mid; |
+ } |
+ } |
+ // If the found entry does not contains the given position, return false. |
+ WasmFunction& func = functions[left]; |
+ if (position < func.code_start_offset || position >= func.code_end_offset) { |
+ return false; |
+ } |
+ |
+ info->line = left; |
+ info->column = position - func.code_start_offset; |
+ info->line_start = func.code_start_offset; |
+ info->line_end = func.code_end_offset; |
+ return true; |
} |
WasmModule::WasmModule(Zone* owned, const byte* module_start) |
@@ -1800,29 +1842,16 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, |
return builder.Build(); |
} |
-Handle<Object> wasm::GetWasmFunctionNameOrNull(Isolate* isolate, |
- Handle<Object> object, |
- uint32_t func_index) { |
- if (!object->IsUndefined(isolate)) { |
- auto instance = Handle<WasmInstanceObject>::cast(object); |
- WasmModule* module = instance->module(); |
- WasmFunction& function = module->functions[func_index]; |
- Handle<WasmCompiledModule> compiled_module(instance->get_compiled_module(), |
- isolate); |
- MaybeHandle<String> string = ExtractStringFromModuleBytes( |
- isolate, compiled_module, function.name_offset, function.name_length); |
- if (!string.is_null()) return string.ToHandleChecked(); |
- } |
- return isolate->factory()->null_value(); |
-} |
- |
Handle<String> wasm::GetWasmFunctionName(Isolate* isolate, |
- Handle<Object> instance, |
+ Handle<Object> instance_or_undef, |
uint32_t func_index) { |
- Handle<Object> name_or_null = |
- GetWasmFunctionNameOrNull(isolate, instance, func_index); |
- if (!name_or_null->IsNull(isolate)) { |
- return Handle<String>::cast(name_or_null); |
+ if (!instance_or_undef->IsUndefined(isolate)) { |
+ Handle<WasmCompiledModule> compiled_module( |
+ Handle<WasmInstanceObject>::cast(instance_or_undef) |
+ ->get_compiled_module()); |
+ MaybeHandle<String> maybe_name = |
+ WasmCompiledModule::GetFunctionName(compiled_module, func_index); |
+ if (!maybe_name.is_null()) return maybe_name.ToHandleChecked(); |
} |
return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); |
} |
@@ -1835,17 +1864,21 @@ WasmCompiledModule* wasm::GetCompiledModule(Object* object) { |
return WasmInstanceObject::cast(object)->get_compiled_module(); |
} |
-bool wasm::WasmIsAsmJs(Object* object, Isolate* isolate) { |
- return IsWasmInstance(object) && |
- WasmInstanceObject::cast(object) |
- ->get_compiled_module() |
- ->has_asm_js_script(); |
+bool wasm::WasmIsAsmJs(Object* instance, Isolate* isolate) { |
+ if (instance->IsUndefined(isolate)) return false; |
+ DCHECK(IsWasmInstance(instance)); |
+ WasmCompiledModule* compiled_module = |
+ GetCompiledModule(JSObject::cast(instance)); |
+ DCHECK_EQ(compiled_module->has_asm_js_offset_tables(), |
+ compiled_module->script()->type() == Script::TYPE_NORMAL); |
+ return compiled_module->has_asm_js_offset_tables(); |
} |
-Handle<Script> wasm::GetAsmWasmScript(Handle<JSObject> object) { |
- return Handle<WasmInstanceObject>::cast(object) |
- ->get_compiled_module() |
- ->asm_js_script(); |
+Handle<Script> wasm::GetScript(Handle<JSObject> instance) { |
+ DCHECK(IsWasmInstance(*instance)); |
+ WasmCompiledModule* compiled_module = GetCompiledModule(*instance); |
+ DCHECK(compiled_module->has_script()); |
+ return compiled_module->script(); |
} |
int wasm::GetAsmWasmSourcePosition(Handle<JSObject> instance, int func_index, |
@@ -1905,10 +1938,12 @@ MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes( |
maybe_compiled_module.ToHandleChecked(); |
DCHECK_EQ(origin == kAsmJsOrigin, !asm_js_script.is_null()); |
- DCHECK(!compiled_module->has_asm_js_script()); |
+ DCHECK(!compiled_module->has_script()); |
DCHECK(!compiled_module->has_asm_js_offset_tables()); |
if (origin == kAsmJsOrigin) { |
- compiled_module->set_asm_js_script(asm_js_script); |
+ // Set script for the asm.js source, and the offset table mapping wasm byte |
+ // offsets to source positions. |
+ compiled_module->set_script(asm_js_script); |
size_t offset_tables_len = |
asm_js_offset_tables_end - asm_js_offset_tables_start; |
DCHECK_GE(static_cast<size_t>(kMaxInt), offset_tables_len); |
@@ -1917,6 +1952,37 @@ MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes( |
memcpy(offset_tables->GetDataStartAddress(), asm_js_offset_tables_start, |
offset_tables_len); |
compiled_module->set_asm_js_offset_tables(offset_tables); |
+ } else { |
+ // Create a new Script object representing this wasm module, store it in the |
+ // compiled wasm module, and register it at the debugger. |
+ Handle<Script> script = |
+ isolate->factory()->NewScript(isolate->factory()->empty_string()); |
+ script->set_type(Script::TYPE_WASM); |
+ |
+ DCHECK_GE(kMaxInt, end - start); |
+ int hash = StringHasher::HashSequentialString( |
+ reinterpret_cast<const char*>(start), static_cast<int>(end - start), |
+ kZeroHashSeed); |
+ |
+ const int kBufferSize = 50; |
+ char buffer[kBufferSize]; |
+ int url_chars = SNPrintF(ArrayVector(buffer), "wasm://wasm/%08x", hash); |
+ DCHECK(url_chars >= 0 && url_chars < kBufferSize); |
+ MaybeHandle<String> url_str = isolate->factory()->NewStringFromOneByte( |
+ Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), url_chars), |
+ TENURED); |
+ script->set_source_url(*url_str.ToHandleChecked()); |
+ |
+ int name_chars = SNPrintF(ArrayVector(buffer), "wasm-%08x", hash); |
+ DCHECK(name_chars >= 0 && name_chars < kBufferSize); |
+ MaybeHandle<String> name_str = isolate->factory()->NewStringFromOneByte( |
+ Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), name_chars), |
+ TENURED); |
+ script->set_name(*name_str.ToHandleChecked()); |
+ |
+ script->set_wasm_compiled_module(*compiled_module); |
+ compiled_module->set_script(script); |
+ isolate->debug()->OnAfterCompile(script); |
} |
return WasmModuleObject::New(isolate, compiled_module); |
@@ -2109,3 +2175,14 @@ void WasmCompiledModule::RecreateModuleWrapper(Isolate* isolate, |
compiled_module->set_module_wrapper(module_wrapper); |
DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); |
} |
+ |
+MaybeHandle<String> WasmCompiledModule::GetFunctionName( |
+ Handle<WasmCompiledModule> compiled_module, uint32_t func_index) { |
+ DCHECK_LT(func_index, compiled_module->module()->functions.size()); |
+ WasmFunction& function = compiled_module->module()->functions[func_index]; |
+ Isolate* isolate = compiled_module->GetIsolate(); |
+ MaybeHandle<String> string = ExtractStringFromModuleBytes( |
+ isolate, compiled_module, function.name_offset, function.name_length); |
+ if (!string.is_null()) return string.ToHandleChecked(); |
+ return {}; |
+} |