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.