Chromium Code Reviews| 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); |