Commit 3a0377a4 authored by titzer's avatar titzer Committed by Commit bot

[wasm] Clean up handling of function names.

R=ahaas@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1698133002

Cr-Commit-Position: refs/heads/master@{#33999}
parent 5aa2cb3b
...@@ -2072,15 +2072,11 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module, ...@@ -2072,15 +2072,11 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module,
// Helper function to compile a single function. // Helper function to compile a single function.
Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
wasm::ModuleEnv* module_env, wasm::ModuleEnv* module_env,
const wasm::WasmFunction& function, const wasm::WasmFunction& function) {
int index) {
if (FLAG_trace_wasm_compiler || FLAG_trace_wasm_decode_time) { if (FLAG_trace_wasm_compiler || FLAG_trace_wasm_decode_time) {
// TODO(titzer): clean me up a bit.
OFStream os(stdout); OFStream os(stdout);
os << "Compiling WASM function #" << index << ":"; os << "Compiling WASM function "
if (function.name_offset > 0) { << wasm::WasmFunctionName(&function, module_env) << std::endl;
os << module_env->module->GetName(function.name_offset);
}
os << std::endl; os << std::endl;
} }
// Initialize the function environment for decoding. // Initialize the function environment for decoding.
...@@ -2115,7 +2111,8 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, ...@@ -2115,7 +2111,8 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
} }
// Add the function as another context for the exception // Add the function as another context for the exception
ScopedVector<char> buffer(128); ScopedVector<char> buffer(128);
SNPrintF(buffer, "Compiling WASM function #%d:%s failed:", index, SNPrintF(buffer, "Compiling WASM function #%d:%s failed:",
function.func_index,
module_env->module->GetName(function.name_offset)); module_env->module->GetName(function.name_offset));
thrower.Failed(buffer.start(), result); thrower.Failed(buffer.start(), result);
return Handle<Code>::null(); return Handle<Code>::null();
...@@ -2132,7 +2129,7 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, ...@@ -2132,7 +2129,7 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
Vector<char> buffer; Vector<char> buffer;
if (debugging) { if (debugging) {
buffer = Vector<char>::New(128); buffer = Vector<char>::New(128);
SNPrintF(buffer, "WASM_function_#%d:%s", index, SNPrintF(buffer, "WASM_function_#%d:%s", function.func_index,
module_env->module->GetName(function.name_offset)); module_env->module->GetName(function.name_offset));
func_name = buffer.start(); func_name = buffer.start();
} }
...@@ -2145,7 +2142,7 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, ...@@ -2145,7 +2142,7 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
} }
if (!code.is_null()) { if (!code.is_null()) {
RecordFunctionCompilation( RecordFunctionCompilation(
Logger::FUNCTION_TAG, &info, "WASM_function", index, Logger::FUNCTION_TAG, &info, "WASM_function", function.func_index,
module_env->module->GetName(function.name_offset)); module_env->module->GetName(function.name_offset));
} }
......
...@@ -35,7 +35,7 @@ namespace compiler { ...@@ -35,7 +35,7 @@ namespace compiler {
// Compiles a single function, producing a code object. // Compiles a single function, producing a code object.
Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
wasm::ModuleEnv* module_env, wasm::ModuleEnv* module_env,
const wasm::WasmFunction& function, int index); const wasm::WasmFunction& function);
// Wraps a JS function, producing a code object that can be called from WASM. // Wraps a JS function, producing a code object that can be called from WASM.
Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module, Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module,
......
...@@ -111,7 +111,7 @@ class ModuleDecoder : public Decoder { ...@@ -111,7 +111,7 @@ class ModuleDecoder : public Decoder {
static_cast<int>(pc_ - start_)); static_cast<int>(pc_ - start_));
module->functions->push_back( module->functions->push_back(
{nullptr, 0, 0, 0, 0, 0, 0, false, false}); {nullptr, i, 0, 0, 0, 0, 0, 0, false, false});
WasmFunction* function = &module->functions->back(); WasmFunction* function = &module->functions->back();
DecodeFunctionInModule(module, function, false); DecodeFunctionInModule(module, function, false);
} }
...@@ -400,12 +400,9 @@ class ModuleDecoder : public Decoder { ...@@ -400,12 +400,9 @@ class ModuleDecoder : public Decoder {
void VerifyFunctionBody(uint32_t func_num, ModuleEnv* menv, void VerifyFunctionBody(uint32_t func_num, ModuleEnv* menv,
WasmFunction* function) { WasmFunction* function) {
if (FLAG_trace_wasm_decode_time) { if (FLAG_trace_wasm_decode_time) {
// TODO(titzer): clean me up a bit.
OFStream os(stdout); OFStream os(stdout);
os << "Verifying WASM function:"; os << "Verifying WASM function " << WasmFunctionName(function, menv)
if (function->name_offset > 0) { << std::endl;
os << menv->module->GetName(function->name_offset);
}
os << std::endl; os << std::endl;
} }
FunctionEnv fenv; FunctionEnv fenv;
...@@ -423,8 +420,7 @@ class ModuleDecoder : public Decoder { ...@@ -423,8 +420,7 @@ class ModuleDecoder : public Decoder {
if (result.failed()) { if (result.failed()) {
// Wrap the error message from the function decoder. // Wrap the error message from the function decoder.
std::ostringstream str; std::ostringstream str;
str << "in function #" << func_num << ": "; str << "in function " << WasmFunctionName(function, menv) << ": ";
// TODO(titzer): add function name for the user?
str << result; str << result;
std::string strval = str.str(); std::string strval = str.str();
const char* raw = strval.c_str(); const char* raw = strval.c_str();
......
...@@ -44,6 +44,19 @@ std::ostream& operator<<(std::ostream& os, const WasmFunction& function) { ...@@ -44,6 +44,19 @@ std::ostream& operator<<(std::ostream& os, const WasmFunction& function) {
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, const WasmFunctionName& pair) {
os << "#" << pair.function_->func_index << ":";
if (pair.function_->name_offset > 0) {
if (pair.module_) {
os << pair.module_->GetName(pair.function_->name_offset);
} else {
os << "+" << pair.function_->func_index;
}
} else {
os << "?";
}
return os;
}
// A helper class for compiling multiple wasm functions that offers // A helper class for compiling multiple wasm functions that offers
// placeholder code objects for calling functions that are not yet compiled. // placeholder code objects for calling functions that are not yet compiled.
...@@ -341,7 +354,7 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, ...@@ -341,7 +354,7 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
// Compile all functions in the module. // Compile all functions in the module.
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
instance.function_table = BuildFunctionTable(isolate, this); instance.function_table = BuildFunctionTable(isolate, this);
int index = 0; uint32_t index = 0;
WasmLinker linker(isolate, functions->size()); WasmLinker linker(isolate, functions->size());
ModuleEnv module_env; ModuleEnv module_env;
module_env.module = this; module_env.module = this;
...@@ -352,6 +365,7 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, ...@@ -352,6 +365,7 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
// First pass: compile each function and initialize the code table. // First pass: compile each function and initialize the code table.
for (const WasmFunction& func : *functions) { for (const WasmFunction& func : *functions) {
if (thrower.error()) break; if (thrower.error()) break;
DCHECK_EQ(index, func.func_index);
const char* cstr = GetName(func.name_offset); const char* cstr = GetName(func.name_offset);
Handle<String> name = factory->InternalizeUtf8String(cstr); Handle<String> name = factory->InternalizeUtf8String(cstr);
...@@ -382,8 +396,7 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, ...@@ -382,8 +396,7 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
} }
} else { } else {
// Compile the function. // Compile the function.
code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func, code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func);
index);
if (code.is_null()) { if (code.is_null()) {
thrower.Error("Compilation of #%d:%s failed.", index, cstr); thrower.Error("Compilation of #%d:%s failed.", index, cstr);
return MaybeHandle<JSObject>(); return MaybeHandle<JSObject>();
...@@ -503,13 +516,14 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, WasmModule* module) { ...@@ -503,13 +516,14 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, WasmModule* module) {
// Compile all functions. // Compile all functions.
Handle<Code> main_code = Handle<Code>::null(); // record last code. Handle<Code> main_code = Handle<Code>::null(); // record last code.
int index = 0; uint32_t index = 0;
int main_index = 0; int main_index = 0;
for (const WasmFunction& func : *module->functions) { for (const WasmFunction& func : *module->functions) {
DCHECK_EQ(index, func.func_index);
if (!func.external) { if (!func.external) {
// Compile the function and install it in the code table. // Compile the function and install it in the code table.
Handle<Code> code = compiler::CompileWasmFunction( Handle<Code> code =
thrower, isolate, &module_env, func, index); compiler::CompileWasmFunction(thrower, isolate, &module_env, func);
if (!code.is_null()) { if (!code.is_null()) {
if (func.exported) { if (func.exported) {
main_code = code; main_code = code;
......
...@@ -52,6 +52,7 @@ static const size_t kDeclDataSegmentSize = 13; ...@@ -52,6 +52,7 @@ static const size_t kDeclDataSegmentSize = 13;
// Static representation of a wasm function. // Static representation of a wasm function.
struct WasmFunction { struct WasmFunction {
FunctionSig* sig; // signature of the function. FunctionSig* sig; // signature of the function.
uint32_t func_index; // index into the function table.
uint16_t sig_index; // index into the signature table. uint16_t sig_index; // index into the signature table.
uint32_t name_offset; // offset in the module bytes of the name, if any. uint32_t name_offset; // offset in the module bytes of the name, if any.
uint32_t code_start_offset; // offset in the module bytes of code start. uint32_t code_start_offset; // offset in the module bytes of code start.
...@@ -106,14 +107,14 @@ struct WasmModule { ...@@ -106,14 +107,14 @@ struct WasmModule {
~WasmModule(); ~WasmModule();
// Get a pointer to a string stored in the module bytes representing a name. // Get a pointer to a string stored in the module bytes representing a name.
const char* GetName(uint32_t offset) { const char* GetName(uint32_t offset) const {
if (offset == 0) return "<?>"; // no name. if (offset == 0) return "<?>"; // no name.
CHECK(BoundsCheck(offset, offset + 1)); CHECK(BoundsCheck(offset, offset + 1));
return reinterpret_cast<const char*>(module_start + offset); return reinterpret_cast<const char*>(module_start + offset);
} }
// Checks the given offset range is contained within the module bytes. // Checks the given offset range is contained within the module bytes.
bool BoundsCheck(uint32_t start, uint32_t end) { bool BoundsCheck(uint32_t start, uint32_t end) const {
size_t size = module_end - module_start; size_t size = module_end - module_start;
return start < size && end < size; return start < size && end < size;
} }
...@@ -193,8 +194,17 @@ struct ModuleEnv { ...@@ -193,8 +194,17 @@ struct ModuleEnv {
compiler::CallDescriptor* GetCallDescriptor(Zone* zone, uint32_t index); compiler::CallDescriptor* GetCallDescriptor(Zone* zone, uint32_t index);
}; };
// A helper for printing out the names of functions.
struct WasmFunctionName {
const WasmFunction* function_;
const WasmModule* module_;
WasmFunctionName(const WasmFunction* function, const ModuleEnv* menv)
: function_(function), module_(menv ? menv->module : nullptr) {}
};
std::ostream& operator<<(std::ostream& os, const WasmModule& module); std::ostream& operator<<(std::ostream& os, const WasmModule& module);
std::ostream& operator<<(std::ostream& os, const WasmFunction& function); std::ostream& operator<<(std::ostream& os, const WasmFunction& function);
std::ostream& operator<<(std::ostream& os, const WasmFunctionName& name);
typedef Result<WasmModule*> ModuleResult; typedef Result<WasmModule*> ModuleResult;
typedef Result<WasmFunction*> FunctionResult; typedef Result<WasmFunction*> FunctionResult;
...@@ -207,6 +217,7 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, ...@@ -207,6 +217,7 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
// For testing. Decode, verify, and run the last exported function in the // For testing. Decode, verify, and run the last exported function in the
// given decoded module. // given decoded module.
int32_t CompileAndRunWasmModule(Isolate* isolate, WasmModule* module); int32_t CompileAndRunWasmModule(Isolate* isolate, WasmModule* module);
} // namespace wasm } // namespace wasm
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -164,7 +164,9 @@ class TestingModule : public ModuleEnv { ...@@ -164,7 +164,9 @@ class TestingModule : public ModuleEnv {
module->functions = new std::vector<WasmFunction>(); module->functions = new std::vector<WasmFunction>();
instance->function_code = new std::vector<Handle<Code>>(); instance->function_code = new std::vector<Handle<Code>>();
} }
module->functions->push_back({sig, 0, 0, 0, 0, 0, 0, 0, false, false}); uint32_t index = static_cast<uint32_t>(module->functions->size());
module->functions->push_back(
{sig, index, 0, 0, 0, 0, 0, 0, 0, false, false});
instance->function_code->push_back(code); instance->function_code->push_back(code);
return &module->functions->back(); return &module->functions->back();
} }
......
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