Upgrade V8 to 5.1.281.57 DO NOT MERGE
FPIIM-449
Change-Id: Id981b686b4d587ac31697662eb98bb34be42ad90
(cherry picked from commit 3b9bc31999c9787eb726ecdbfd5796bfdec32a18)
diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc
index 02d197c..a1c2a7a 100644
--- a/src/wasm/wasm-module.cc
+++ b/src/wasm/wasm-module.cc
@@ -19,13 +19,43 @@
namespace internal {
namespace wasm {
+static const char* wasmSections[] = {
+#define F(enumerator, string) string,
+ FOR_EACH_WASM_SECTION_TYPE(F)
+#undef F
+};
+
+static uint8_t wasmSectionsLengths[]{
+#define F(enumerator, string) sizeof(string) - 1,
+ FOR_EACH_WASM_SECTION_TYPE(F)
+#undef F
+};
+
+static_assert(sizeof(wasmSections) / sizeof(wasmSections[0]) ==
+ (size_t)WasmSection::Code::Max,
+ "expected enum WasmSection::Code to be monotonic from 0");
+
+WasmSection::Code WasmSection::begin() { return (WasmSection::Code)0; }
+WasmSection::Code WasmSection::end() { return WasmSection::Code::Max; }
+WasmSection::Code WasmSection::next(WasmSection::Code code) {
+ return (WasmSection::Code)(1 + (uint32_t)code);
+}
+
+const char* WasmSection::getName(WasmSection::Code code) {
+ return wasmSections[(size_t)code];
+}
+
+size_t WasmSection::getNameLength(WasmSection::Code code) {
+ return wasmSectionsLengths[(size_t)code];
+}
+
std::ostream& operator<<(std::ostream& os, const WasmModule& module) {
os << "WASM module with ";
- os << (1 << module.min_mem_size_log2) << " min mem";
- os << (1 << module.max_mem_size_log2) << " max mem";
- if (module.functions) os << module.functions->size() << " functions";
- if (module.globals) os << module.functions->size() << " globals";
- if (module.data_segments) os << module.functions->size() << " data segments";
+ os << (module.min_mem_pages * module.kPageSize) << " min mem";
+ os << (module.max_mem_pages * module.kPageSize) << " max mem";
+ os << module.functions.size() << " functions";
+ os << module.functions.size() << " globals";
+ os << module.functions.size() << " data segments";
return os;
}
@@ -48,7 +78,9 @@
os << "#" << pair.function_->func_index << ":";
if (pair.function_->name_offset > 0) {
if (pair.module_) {
- os << pair.module_->GetName(pair.function_->name_offset);
+ WasmName name = pair.module_->GetName(pair.function_->name_offset,
+ pair.function_->name_length);
+ os.write(name.name, name.length);
} else {
os << "+" << pair.function_->func_index;
}
@@ -91,15 +123,15 @@
}
void Link(Handle<FixedArray> function_table,
- std::vector<uint16_t>* functions) {
+ std::vector<uint16_t>& functions) {
for (size_t i = 0; i < function_code_.size(); i++) {
LinkFunction(function_code_[i]);
}
- if (functions && !function_table.is_null()) {
- int table_size = static_cast<int>(functions->size());
+ if (!function_table.is_null()) {
+ int table_size = static_cast<int>(functions.size());
DCHECK_EQ(function_table->length(), table_size * 2);
for (int i = 0; i < table_size; i++) {
- function_table->set(i + table_size, *function_code_[functions->at(i)]);
+ function_table->set(i + table_size, *function_code_[functions[i]]);
}
}
}
@@ -151,11 +183,10 @@
const int kWasmMemArrayBuffer = 2;
const int kWasmGlobalsArrayBuffer = 3;
-
-size_t AllocateGlobalsOffsets(std::vector<WasmGlobal>* globals) {
+size_t AllocateGlobalsOffsets(std::vector<WasmGlobal>& globals) {
uint32_t offset = 0;
- if (!globals) return 0;
- for (WasmGlobal& global : *globals) {
+ if (globals.size() == 0) return 0;
+ for (WasmGlobal& global : globals) {
byte size = WasmOpcodes::MemSize(global.type);
offset = (offset + size - 1) & ~(size - 1); // align
global.offset = offset;
@@ -166,8 +197,9 @@
void LoadDataSegments(WasmModule* module, byte* mem_addr, size_t mem_size) {
- for (const WasmDataSegment& segment : *module->data_segments) {
+ for (const WasmDataSegment& segment : module->data_segments) {
if (!segment.init) continue;
+ if (!segment.source_size) continue;
CHECK_LT(segment.dest_addr, mem_size);
CHECK_LE(segment.source_size, mem_size);
CHECK_LE(segment.dest_addr + segment.source_size, mem_size);
@@ -179,14 +211,13 @@
Handle<FixedArray> BuildFunctionTable(Isolate* isolate, WasmModule* module) {
- if (!module->function_table || module->function_table->size() == 0) {
+ if (module->function_table.size() == 0) {
return Handle<FixedArray>::null();
}
- int table_size = static_cast<int>(module->function_table->size());
+ int table_size = static_cast<int>(module->function_table.size());
Handle<FixedArray> fixed = isolate->factory()->NewFixedArray(2 * table_size);
for (int i = 0; i < table_size; i++) {
- WasmFunction* function =
- &module->functions->at(module->function_table->at(i));
+ WasmFunction* function = &module->functions[module->function_table[i]];
fixed->set(i, Smi::FromInt(function->sig_index));
}
return fixed;
@@ -194,7 +225,7 @@
Handle<JSArrayBuffer> NewArrayBuffer(Isolate* isolate, size_t size,
byte** backing_store) {
- if (size > (1 << WasmModule::kMaxMemSize)) {
+ if (size > (WasmModule::kMaxMemPages * WasmModule::kPageSize)) {
// TODO(titzer): lift restriction on maximum memory allocated here.
*backing_store = nullptr;
return Handle<JSArrayBuffer>::null();
@@ -236,12 +267,11 @@
DCHECK(instance->module);
DCHECK(instance->mem_buffer.is_null());
- if (instance->module->min_mem_size_log2 > WasmModule::kMaxMemSize) {
+ if (instance->module->min_mem_pages > WasmModule::kMaxMemPages) {
thrower->Error("Out of memory: wasm memory too large");
return false;
}
- instance->mem_size = static_cast<size_t>(1)
- << instance->module->min_mem_size_log2;
+ instance->mem_size = WasmModule::kPageSize * instance->module->min_mem_pages;
instance->mem_buffer =
NewArrayBuffer(isolate, instance->mem_size, &instance->mem_start);
if (!instance->mem_start) {
@@ -273,50 +303,75 @@
: shared_isolate(nullptr),
module_start(nullptr),
module_end(nullptr),
- min_mem_size_log2(0),
- max_mem_size_log2(0),
+ min_mem_pages(0),
+ max_mem_pages(0),
mem_export(false),
mem_external(false),
start_function_index(-1),
- globals(nullptr),
- signatures(nullptr),
- functions(nullptr),
- data_segments(nullptr),
- function_table(nullptr),
- import_table(nullptr) {}
+ origin(kWasmOrigin) {}
-WasmModule::~WasmModule() {
- if (globals) delete globals;
- if (signatures) delete signatures;
- if (functions) delete functions;
- if (data_segments) delete data_segments;
- if (function_table) delete function_table;
- if (import_table) delete import_table;
+static MaybeHandle<JSFunction> ReportFFIError(ErrorThrower& thrower,
+ const char* error, uint32_t index,
+ wasm::WasmName module_name,
+ wasm::WasmName function_name) {
+ if (function_name.name) {
+ thrower.Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s",
+ index, module_name.length, module_name.name,
+ function_name.length, function_name.name, error);
+ } else {
+ thrower.Error("Import #%d module=\"%.*s\" error: %s", index,
+ module_name.length, module_name.name, error);
+ }
+ thrower.Error("Import ");
+ return MaybeHandle<JSFunction>();
}
-static MaybeHandle<JSFunction> LookupFunction(ErrorThrower& thrower,
- Handle<JSObject> ffi,
- uint32_t index,
- Handle<String> name,
- const char* cstr) {
- if (!ffi.is_null()) {
- MaybeHandle<Object> result = Object::GetProperty(ffi, name);
- if (!result.is_null()) {
- Handle<Object> obj = result.ToHandleChecked();
- if (obj->IsJSFunction()) {
- return Handle<JSFunction>::cast(obj);
- } else {
- thrower.Error("FFI function #%d:%s is not a JSFunction.", index, cstr);
- return MaybeHandle<JSFunction>();
- }
- } else {
- thrower.Error("FFI function #%d:%s not found.", index, cstr);
- return MaybeHandle<JSFunction>();
- }
- } else {
- thrower.Error("FFI table is not an object.");
- return MaybeHandle<JSFunction>();
+static MaybeHandle<JSFunction> LookupFunction(
+ ErrorThrower& thrower, Factory* factory, Handle<JSObject> ffi,
+ uint32_t index, wasm::WasmName module_name, wasm::WasmName function_name) {
+ if (ffi.is_null()) {
+ return ReportFFIError(thrower, "FFI is not an object", index, module_name,
+ function_name);
}
+
+ // Look up the module first.
+ Handle<String> name = factory->InternalizeUtf8String(
+ Vector<const char>(module_name.name, module_name.length));
+ MaybeHandle<Object> result = Object::GetProperty(ffi, name);
+ if (result.is_null()) {
+ return ReportFFIError(thrower, "module not found", index, module_name,
+ function_name);
+ }
+
+ Handle<Object> module = result.ToHandleChecked();
+
+ if (!module->IsJSReceiver()) {
+ return ReportFFIError(thrower, "module is not an object or function", index,
+ module_name, function_name);
+ }
+
+ Handle<Object> function;
+ if (function_name.name) {
+ // Look up the function in the module.
+ Handle<String> name = factory->InternalizeUtf8String(
+ Vector<const char>(function_name.name, function_name.length));
+ MaybeHandle<Object> result = Object::GetProperty(module, name);
+ if (result.is_null()) {
+ return ReportFFIError(thrower, "function not found", index, module_name,
+ function_name);
+ }
+ function = result.ToHandleChecked();
+ } else {
+ // No function specified. Use the "default export".
+ function = module;
+ }
+
+ if (!function->IsJSFunction()) {
+ return ReportFFIError(thrower, "not a function", index, module_name,
+ function_name);
+ }
+
+ return Handle<JSFunction>::cast(function);
}
// Instantiates a wasm module as a JSObject.
@@ -338,11 +393,10 @@
JS_OBJECT_TYPE,
JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
WasmModuleInstance instance(this);
- std::vector<Handle<Code>> import_code;
instance.context = isolate->native_context();
instance.js_object = factory->NewJSObjectFromMap(map, TENURED);
Handle<FixedArray> code_table =
- factory->NewFixedArray(static_cast<int>(functions->size()), TENURED);
+ factory->NewFixedArray(static_cast<int>(functions.size()), TENURED);
instance.js_object->SetInternalField(kWasmModuleCodeTable, *code_table);
//-------------------------------------------------------------------------
@@ -359,13 +413,6 @@
*instance.mem_buffer);
LoadDataSegments(this, instance.mem_start, instance.mem_size);
- if (mem_export) {
- // Export the memory as a named property.
- Handle<String> name = factory->InternalizeUtf8String("memory");
- JSObject::AddProperty(instance.js_object, name, instance.mem_buffer,
- READ_ONLY);
- }
-
//-------------------------------------------------------------------------
// Allocate the globals area if necessary.
//-------------------------------------------------------------------------
@@ -382,25 +429,27 @@
//-------------------------------------------------------------------------
uint32_t index = 0;
instance.function_table = BuildFunctionTable(isolate, this);
- WasmLinker linker(isolate, functions->size());
+ WasmLinker linker(isolate, functions.size());
ModuleEnv module_env;
module_env.module = this;
module_env.instance = &instance;
module_env.linker = &linker;
- module_env.asm_js = false;
+ module_env.origin = origin;
- if (import_table->size() > 0) {
- instance.import_code = &import_code;
- instance.import_code->reserve(import_table->size());
- for (const WasmImport& import : *import_table) {
- const char* cstr = GetName(import.function_name_offset);
- Handle<String> name = factory->InternalizeUtf8String(cstr);
- MaybeHandle<JSFunction> function =
- LookupFunction(thrower, ffi, index, name, cstr);
+ if (import_table.size() > 0) {
+ instance.import_code.reserve(import_table.size());
+ for (const WasmImport& import : import_table) {
+ WasmName module_name =
+ GetNameOrNull(import.module_name_offset, import.module_name_length);
+ WasmName function_name = GetNameOrNull(import.function_name_offset,
+ import.function_name_length);
+ MaybeHandle<JSFunction> function = LookupFunction(
+ thrower, factory, ffi, index, module_name, function_name);
if (function.is_null()) return MaybeHandle<JSObject>();
Handle<Code> code = compiler::CompileWasmToJSWrapper(
- isolate, &module_env, function.ToHandleChecked(), import.sig, cstr);
- instance.import_code->push_back(code);
+ isolate, &module_env, function.ToHandleChecked(), import.sig,
+ module_name, function_name);
+ instance.import_code.push_back(code);
index++;
}
}
@@ -410,27 +459,32 @@
//-------------------------------------------------------------------------
// First pass: compile each function and initialize the code table.
- index = 0;
- for (const WasmFunction& func : *functions) {
+ index = FLAG_skip_compiling_wasm_funcs;
+ while (index < functions.size()) {
+ const WasmFunction& func = functions[index];
if (thrower.error()) break;
DCHECK_EQ(index, func.func_index);
- const char* cstr = GetName(func.name_offset);
- Handle<String> name = factory->InternalizeUtf8String(cstr);
+ WasmName str = GetName(func.name_offset, func.name_length);
+ WasmName str_null = {nullptr, 0};
+ Handle<String> name = factory->InternalizeUtf8String(
+ Vector<const char>(str.name, str.length));
Handle<Code> code = Handle<Code>::null();
Handle<JSFunction> function = Handle<JSFunction>::null();
if (func.external) {
// Lookup external function in FFI object.
MaybeHandle<JSFunction> function =
- LookupFunction(thrower, ffi, index, name, cstr);
+ LookupFunction(thrower, factory, ffi, index, str, str_null);
if (function.is_null()) return MaybeHandle<JSObject>();
- code = compiler::CompileWasmToJSWrapper(
- isolate, &module_env, function.ToHandleChecked(), func.sig, cstr);
+ code = compiler::CompileWasmToJSWrapper(isolate, &module_env,
+ function.ToHandleChecked(),
+ func.sig, str, str_null);
} else {
// Compile the function.
code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func);
if (code.is_null()) {
- thrower.Error("Compilation of #%d:%s failed.", index, cstr);
+ thrower.Error("Compilation of #%d:%.*s failed.", index, str.length,
+ str.name);
return MaybeHandle<JSObject>();
}
if (func.exported) {
@@ -455,6 +509,40 @@
instance.js_object->SetInternalField(kWasmModuleFunctionTable,
Smi::FromInt(0));
+ //-------------------------------------------------------------------------
+ // Create and populate the exports object.
+ //-------------------------------------------------------------------------
+ if (export_table.size() > 0 || mem_export) {
+ index = 0;
+ // Create the "exports" object.
+ Handle<JSFunction> object_function = Handle<JSFunction>(
+ isolate->native_context()->object_function(), isolate);
+ Handle<JSObject> exports_object =
+ factory->NewJSObject(object_function, TENURED);
+ Handle<String> exports_name = factory->InternalizeUtf8String("exports");
+ JSObject::AddProperty(instance.js_object, exports_name, exports_object,
+ READ_ONLY);
+
+ // Compile wrappers and add them to the exports object.
+ for (const WasmExport& exp : export_table) {
+ if (thrower.error()) break;
+ WasmName str = GetName(exp.name_offset, exp.name_length);
+ Handle<String> name = factory->InternalizeUtf8String(
+ Vector<const char>(str.name, str.length));
+ Handle<Code> code = linker.GetFunctionCode(exp.func_index);
+ Handle<JSFunction> function = compiler::CompileJSToWasmWrapper(
+ isolate, &module_env, name, code, instance.js_object, exp.func_index);
+ JSObject::AddProperty(exports_object, name, function, READ_ONLY);
+ }
+
+ if (mem_export) {
+ // Export the memory as a named property.
+ Handle<String> name = factory->InternalizeUtf8String("memory");
+ JSObject::AddProperty(exports_object, name, instance.mem_buffer,
+ READ_ONLY);
+ }
+ }
+
// Run the start function if one was specified.
if (this->start_function_index >= 0) {
HandleScope scope(isolate);
@@ -480,18 +568,12 @@
Handle<Code> ModuleEnv::GetFunctionCode(uint32_t index) {
DCHECK(IsValidFunction(index));
if (linker) return linker->GetFunctionCode(index);
- if (instance && instance->function_code) {
- return instance->function_code->at(index);
- }
- return Handle<Code>::null();
+ return instance ? instance->function_code[index] : Handle<Code>::null();
}
Handle<Code> ModuleEnv::GetImportCode(uint32_t index) {
DCHECK(IsValidImport(index));
- if (instance && instance->import_code) {
- return instance->import_code->at(index);
- }
- return Handle<Code>::null();
+ return instance ? instance->import_code[index] : Handle<Code>::null();
}
compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone,
@@ -499,7 +581,7 @@
DCHECK(IsValidFunction(index));
// Always make a direct call to whatever is in the table at that location.
// A wrapper will be generated for FFI calls.
- WasmFunction* function = &module->functions->at(index);
+ WasmFunction* function = &module->functions[index];
return GetWasmCallDescriptor(zone, function->sig);
}
@@ -507,12 +589,15 @@
int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
const byte* module_end, bool asm_js) {
HandleScope scope(isolate);
- Zone zone;
+ Zone zone(isolate->allocator());
// Decode the module, but don't verify function bodies, since we'll
// be compiling them anyway.
- ModuleResult result =
- DecodeWasmModule(isolate, &zone, module_start, module_end, false, false);
+ ModuleResult result = DecodeWasmModule(isolate, &zone, module_start,
+ module_end, false, kWasmOrigin);
if (result.failed()) {
+ if (result.val) {
+ delete result.val;
+ }
// Module verification failed. throw.
std::ostringstream str;
str << "WASM.compileRun() failed: " << result;
@@ -546,18 +631,18 @@
instance.function_table = BuildFunctionTable(isolate, module);
// Create module environment.
- WasmLinker linker(isolate, module->functions->size());
+ WasmLinker linker(isolate, module->functions.size());
ModuleEnv module_env;
module_env.module = module;
module_env.instance = &instance;
module_env.linker = &linker;
- module_env.asm_js = false;
+ module_env.origin = module->origin;
// Compile all functions.
Handle<Code> main_code = Handle<Code>::null(); // record last code.
uint32_t 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) {
// Compile the function and install it in the code table.