Index: src/wasm/wasm-module.cc |
diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc |
index 4fbfa22f5f41550a5386167052f5d4ae3127db77..67f6ff906b31e04ba0415ba2e657373cf61a8ef7 100644 |
--- a/src/wasm/wasm-module.cc |
+++ b/src/wasm/wasm-module.cc |
@@ -629,6 +629,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->cpp_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) { |
@@ -729,13 +741,43 @@ Object* wasm::GetOwningWasmInstance(Code* code) { |
WasmModule* GetCppModule(Handle<JSObject> instance) { |
DCHECK(IsWasmInstance(*instance)); |
- return reinterpret_cast<WasmModuleWrapper*>( |
- *GetCompiledModule(*instance)->module_wrapper()) |
+ return Handle<WasmModuleWrapper>::cast( |
+ GetCompiledModule(*instance)->module_wrapper()) |
->get(); |
} |
-int wasm::GetNumImportedFunctions(Handle<JSObject> instance) { |
- return static_cast<int>(GetCppModule(instance)->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) { |
+ WasmModule* module = compiled_module->cpp_module(); |
+ |
+ // Binary search for a function containing the given position. |
+ int left = 0; // inclusive |
+ int right = static_cast<int>(module->functions.size()); // exclusive |
+ if (right == 0) return false; |
+ while (right - left > 1) { |
+ int mid = left + (right - left) / 2; |
+ if (module->functions[mid].code_start_offset <= position) { |
+ left = mid; |
+ } else { |
+ right = mid; |
+ } |
+ } |
+ // If the found entry does not contains the given position, return false. |
Yang
2016/11/15 07:42:26
Can this actually happen, if we check upfront that
Clemens Hammacher
2016/11/15 15:04:06
There is a slight gap between functions, precisely
|
+ WasmFunction& func = module->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) |
@@ -1920,29 +1962,29 @@ void WasmCompiledModule::PrintInstancesChain() { |
#endif |
} |
-Handle<Object> wasm::GetWasmFunctionNameOrNull(Isolate* isolate, |
- Handle<Object> instance, |
- uint32_t func_index) { |
- if (!instance->IsUndefined(isolate)) { |
- DCHECK(IsWasmInstance(*instance)); |
- WasmModule* module = GetCppModule(Handle<JSObject>::cast(instance)); |
- WasmFunction& function = module->functions[func_index]; |
- Handle<WasmCompiledModule> compiled_module(GetCompiledModule(*instance), |
- isolate); |
- MaybeHandle<String> string = ExtractStringFromModuleBytes( |
- isolate, compiled_module, function.name_offset, function.name_length); |
- if (!string.is_null()) return string.ToHandleChecked(); |
- } |
+Handle<Object> wasm::GetWasmFunctionNameOrNull( |
+ Isolate* isolate, Handle<WasmCompiledModule> compiled_module, |
+ uint32_t func_index) { |
+ WasmModule* module = |
+ Handle<WasmModuleWrapper>::cast(compiled_module->module_wrapper())->get(); |
+ DCHECK_LT(func_index, module->functions.size()); |
+ WasmFunction& function = module->functions[func_index]; |
+ 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, |
- 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); |
+Handle<String> wasm::GetWasmFunctionName( |
+ Isolate* isolate, Handle<Object> compiled_module_or_undef, |
+ uint32_t func_index) { |
+ if (!compiled_module_or_undef->IsUndefined(isolate)) { |
+ Handle<Object> name_or_null = GetWasmFunctionNameOrNull( |
+ isolate, Handle<WasmCompiledModule>::cast(compiled_module_or_undef), |
+ func_index); |
+ if (!name_or_null->IsNull(isolate)) { |
+ return Handle<String>::cast(name_or_null); |
+ } |
} |
return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); |
} |
@@ -1974,14 +2016,20 @@ WasmCompiledModule* wasm::GetCompiledModule(Object* instance) { |
} |
bool wasm::WasmIsAsmJs(Object* instance, Isolate* isolate) { |
- return IsWasmInstance(instance) && |
- GetCompiledModule(JSObject::cast(instance))->has_asm_js_script(); |
+ 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> instance) { |
+Handle<Script> wasm::GetScript(Handle<JSObject> instance) { |
DCHECK(IsWasmInstance(*instance)); |
WasmCompiledModule* compiled_module = GetCompiledModule(*instance); |
- return compiled_module->asm_js_script(); |
+ DCHECK(compiled_module->has_script()); |
+ return compiled_module->script(); |
} |
int wasm::GetAsmWasmSourcePosition(Handle<JSObject> instance, int func_index, |
@@ -2063,10 +2111,12 @@ MaybeHandle<JSObject> 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); |
@@ -2075,6 +2125,36 @@ MaybeHandle<JSObject> 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); |
+ |
+ char buffer[50]; |
+ int url_chars = SNPrintF(ArrayVector(buffer), "wasm://wasm/%08x", hash); |
+ DCHECK(url_chars >= 0 && url_chars < arraysize(buffer)); |
+ 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 < arraysize(buffer)); |
+ 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 CreateWasmModuleObject(isolate, compiled_module, origin); |