Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: src/wasm/wasm-module.cc

Issue 2695813005: [wasm] Split the compilation and instantiation API into sync and async methods. (Closed)
Patch Set: [wasm] Split the compilation and instantiation API into sync and async methods. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/wasm/wasm-module.h ('k') | test/cctest/wasm/test-run-wasm-module.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <memory> 5 #include <memory>
6 6
7 #include "src/assembler-inl.h" 7 #include "src/assembler-inl.h"
8 #include "src/base/adapters.h" 8 #include "src/base/adapters.h"
9 #include "src/base/atomic-utils.h" 9 #include "src/base/atomic-utils.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 } 891 }
892 892
893 int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module, 893 int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module,
894 int func_index) { 894 int func_index) {
895 return GetFunctionOffsetAndLength(compiled_module, func_index).first; 895 return GetFunctionOffsetAndLength(compiled_module, func_index).first;
896 } 896 }
897 897
898 WasmModule::WasmModule(Zone* owned) 898 WasmModule::WasmModule(Zone* owned)
899 : owned_zone(owned), pending_tasks(new base::Semaphore(0)) {} 899 : owned_zone(owned), pending_tasks(new base::Semaphore(0)) {}
900 900
901 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( 901 MaybeHandle<WasmModuleObject> CompileToModuleObject(
902 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper, 902 Isolate* isolate, WasmModule* m, ErrorThrower* thrower,
903 ErrorThrower* thrower, const ModuleWireBytes& wire_bytes, 903 const ModuleWireBytes& wire_bytes, Handle<Script> asm_js_script,
904 Handle<Script> asm_js_script, 904 Vector<const byte> asm_js_offset_table_bytes) {
905 Vector<const byte> asm_js_offset_table_bytes) const {
906 Factory* factory = isolate->factory(); 905 Factory* factory = isolate->factory();
907 906 MaybeHandle<WasmModuleObject> nothing;
908 MaybeHandle<WasmCompiledModule> nothing; 907 // The {module_wrapper} will take ownership of the {WasmModule} object,
909 908 // and it will be destroyed when the GC reclaims the wrapper object.
910 WasmInstance temp_instance(this); 909 Handle<WasmModuleWrapper> module_wrapper = WasmModuleWrapper::New(isolate, m);
910 WasmInstance temp_instance(m);
911 temp_instance.context = isolate->native_context(); 911 temp_instance.context = isolate->native_context();
912 temp_instance.mem_size = WasmModule::kPageSize * min_mem_pages; 912 temp_instance.mem_size = WasmModule::kPageSize * m->min_mem_pages;
913 temp_instance.mem_start = nullptr; 913 temp_instance.mem_start = nullptr;
914 temp_instance.globals_start = nullptr; 914 temp_instance.globals_start = nullptr;
915 915
916 // Initialize the indirect tables with placeholders. 916 // Initialize the indirect tables with placeholders.
917 int function_table_count = static_cast<int>(function_tables.size()); 917 int function_table_count = static_cast<int>(m->function_tables.size());
918 Handle<FixedArray> function_tables = 918 Handle<FixedArray> function_tables =
919 factory->NewFixedArray(function_table_count, TENURED); 919 factory->NewFixedArray(function_table_count, TENURED);
920 Handle<FixedArray> signature_tables = 920 Handle<FixedArray> signature_tables =
921 factory->NewFixedArray(function_table_count, TENURED); 921 factory->NewFixedArray(function_table_count, TENURED);
922 for (int i = 0; i < function_table_count; ++i) { 922 for (int i = 0; i < function_table_count; ++i) {
923 temp_instance.function_tables[i] = factory->NewFixedArray(1, TENURED); 923 temp_instance.function_tables[i] = factory->NewFixedArray(1, TENURED);
924 temp_instance.signature_tables[i] = factory->NewFixedArray(1, TENURED); 924 temp_instance.signature_tables[i] = factory->NewFixedArray(1, TENURED);
925 function_tables->set(i, *temp_instance.function_tables[i]); 925 function_tables->set(i, *temp_instance.function_tables[i]);
926 signature_tables->set(i, *temp_instance.signature_tables[i]); 926 signature_tables->set(i, *temp_instance.signature_tables[i]);
927 } 927 }
928 928
929 HistogramTimerScope wasm_compile_module_time_scope( 929 HistogramTimerScope wasm_compile_module_time_scope(
930 isolate->counters()->wasm_compile_module_time()); 930 isolate->counters()->wasm_compile_module_time());
931 931
932 ModuleBytesEnv module_env(this, &temp_instance, wire_bytes); 932 ModuleBytesEnv module_env(m, &temp_instance, wire_bytes);
933 933
934 // The {code_table} array contains import wrappers and functions (which 934 // The {code_table} array contains import wrappers and functions (which
935 // are both included in {functions.size()}, and export wrappers. 935 // are both included in {functions.size()}, and export wrappers.
936 int code_table_size = 936 int code_table_size =
937 static_cast<int>(functions.size() + num_exported_functions); 937 static_cast<int>(m->functions.size() + m->num_exported_functions);
938 Handle<FixedArray> code_table = 938 Handle<FixedArray> code_table =
939 factory->NewFixedArray(static_cast<int>(code_table_size), TENURED); 939 factory->NewFixedArray(static_cast<int>(code_table_size), TENURED);
940 940
941 // Initialize the code table with the illegal builtin. All call sites will be 941 // Initialize the code table with the illegal builtin. All call sites will be
942 // patched at instantiation. 942 // patched at instantiation.
943 Handle<Code> illegal_builtin = isolate->builtins()->Illegal(); 943 Handle<Code> illegal_builtin = isolate->builtins()->Illegal();
944 for (uint32_t i = 0; i < functions.size(); ++i) { 944 for (uint32_t i = 0; i < m->functions.size(); ++i) {
945 code_table->set(static_cast<int>(i), *illegal_builtin); 945 code_table->set(static_cast<int>(i), *illegal_builtin);
946 temp_instance.function_code[i] = illegal_builtin; 946 temp_instance.function_code[i] = illegal_builtin;
947 } 947 }
948 948
949 isolate->counters()->wasm_functions_per_module()->AddSample( 949 isolate->counters()->wasm_functions_per_module()->AddSample(
950 static_cast<int>(functions.size())); 950 static_cast<int>(m->functions.size()));
951 if (!FLAG_trace_wasm_decoder && FLAG_wasm_num_compilation_tasks != 0) { 951 if (!FLAG_trace_wasm_decoder && FLAG_wasm_num_compilation_tasks != 0) {
952 // Avoid a race condition by collecting results into a second vector. 952 // Avoid a race condition by collecting results into a second vector.
953 std::vector<Handle<Code>> results(temp_instance.function_code); 953 std::vector<Handle<Code>> results(temp_instance.function_code);
954 CompileInParallel(isolate, &module_env, results, thrower); 954 CompileInParallel(isolate, &module_env, results, thrower);
955 temp_instance.function_code.swap(results); 955 temp_instance.function_code.swap(results);
956 } else { 956 } else {
957 CompileSequentially(isolate, &module_env, temp_instance.function_code, 957 CompileSequentially(isolate, &module_env, temp_instance.function_code,
958 thrower); 958 thrower);
959 } 959 }
960 if (thrower->error()) return nothing; 960 if (thrower->error()) return nothing;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 // breakpoints on a (potentially empty) subset of the instances. 995 // breakpoints on a (potentially empty) subset of the instances.
996 996
997 Handle<WasmSharedModuleData> shared = WasmSharedModuleData::New( 997 Handle<WasmSharedModuleData> shared = WasmSharedModuleData::New(
998 isolate, module_wrapper, Handle<SeqOneByteString>::cast(module_bytes), 998 isolate, module_wrapper, Handle<SeqOneByteString>::cast(module_bytes),
999 script, asm_js_offset_table); 999 script, asm_js_offset_table);
1000 1000
1001 // Create the compiled module object, and populate with compiled functions 1001 // Create the compiled module object, and populate with compiled functions
1002 // and information needed at instantiation time. This object needs to be 1002 // and information needed at instantiation time. This object needs to be
1003 // serializable. Instantiation may occur off a deserialized version of this 1003 // serializable. Instantiation may occur off a deserialized version of this
1004 // object. 1004 // object.
1005 Handle<WasmCompiledModule> ret = WasmCompiledModule::New(isolate, shared); 1005 Handle<WasmCompiledModule> compiled_module =
1006 ret->set_num_imported_functions(num_imported_functions); 1006 WasmCompiledModule::New(isolate, shared);
1007 ret->set_code_table(code_table); 1007 compiled_module->set_num_imported_functions(m->num_imported_functions);
1008 ret->set_min_mem_pages(min_mem_pages); 1008 compiled_module->set_code_table(code_table);
1009 ret->set_max_mem_pages(max_mem_pages); 1009 compiled_module->set_min_mem_pages(m->min_mem_pages);
1010 compiled_module->set_max_mem_pages(m->max_mem_pages);
1010 if (function_table_count > 0) { 1011 if (function_table_count > 0) {
1011 ret->set_function_tables(function_tables); 1012 compiled_module->set_function_tables(function_tables);
1012 ret->set_signature_tables(signature_tables); 1013 compiled_module->set_signature_tables(signature_tables);
1013 ret->set_empty_function_tables(function_tables); 1014 compiled_module->set_empty_function_tables(function_tables);
1014 } 1015 }
1015 1016
1016 // If we created a wasm script, finish it now and make it public to the 1017 // If we created a wasm script, finish it now and make it public to the
1017 // debugger. 1018 // debugger.
1018 if (asm_js_script.is_null()) { 1019 if (asm_js_script.is_null()) {
1019 script->set_wasm_compiled_module(*ret); 1020 script->set_wasm_compiled_module(*compiled_module);
1020 isolate->debug()->OnAfterCompile(script); 1021 isolate->debug()->OnAfterCompile(script);
1021 } 1022 }
1022 1023
1023 // Compile JS->WASM wrappers for exported functions. 1024 // Compile JS->WASM wrappers for exported functions.
1024 int func_index = 0; 1025 int func_index = 0;
1025 for (auto exp : export_table) { 1026 for (auto exp : m->export_table) {
1026 if (exp.kind != kExternalFunction) continue; 1027 if (exp.kind != kExternalFunction) continue;
1027 Handle<Code> wasm_code = 1028 Handle<Code> wasm_code =
1028 code_table->GetValueChecked<Code>(isolate, exp.index); 1029 code_table->GetValueChecked<Code>(isolate, exp.index);
1029 Handle<Code> wrapper_code = 1030 Handle<Code> wrapper_code =
1030 compiler::CompileJSToWasmWrapper(isolate, this, wasm_code, exp.index); 1031 compiler::CompileJSToWasmWrapper(isolate, m, wasm_code, exp.index);
1031 int export_index = static_cast<int>(functions.size() + func_index); 1032 int export_index = static_cast<int>(m->functions.size() + func_index);
1032 code_table->set(export_index, *wrapper_code); 1033 code_table->set(export_index, *wrapper_code);
1033 RecordStats(isolate, *wrapper_code); 1034 RecordStats(isolate, *wrapper_code);
1034 func_index++; 1035 func_index++;
1035 } 1036 }
1036 1037
1037 return ret; 1038 return WasmModuleObject::New(isolate, compiled_module);
1038 } 1039 }
1039 1040
1040 static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate, 1041 static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate,
1041 Handle<Object> target) { 1042 Handle<Object> target) {
1042 if (target->IsJSFunction()) { 1043 if (target->IsJSFunction()) {
1043 Handle<JSFunction> func = Handle<JSFunction>::cast(target); 1044 Handle<JSFunction> func = Handle<JSFunction>::cast(target);
1044 if (func->code()->kind() == Code::JS_TO_WASM_FUNCTION) { 1045 if (func->code()->kind() == Code::JS_TO_WASM_FUNCTION) {
1045 auto exported = Handle<WasmExportedFunction>::cast(func); 1046 auto exported = Handle<WasmExportedFunction>::cast(func);
1046 Handle<WasmInstanceObject> other_instance(exported->instance(), isolate); 1047 Handle<WasmInstanceObject> other_instance(exported->instance(), isolate);
1047 int func_index = exported->function_index(); 1048 int func_index = exported->function_index();
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 UpdateDispatchTablesInternal( 1133 UpdateDispatchTablesInternal(
1133 isolate, dispatch_tables, index, 1134 isolate, dispatch_tables, index,
1134 GetWasmFunctionForImportWrapper(isolate, function), 1135 GetWasmFunctionForImportWrapper(isolate, function),
1135 UnwrapImportWrapper(function)); 1136 UnwrapImportWrapper(function));
1136 } 1137 }
1137 } 1138 }
1138 1139
1139 // A helper class to simplify instantiating a module from a compiled module. 1140 // A helper class to simplify instantiating a module from a compiled module.
1140 // It closes over the {Isolate}, the {ErrorThrower}, the {WasmCompiledModule}, 1141 // It closes over the {Isolate}, the {ErrorThrower}, the {WasmCompiledModule},
1141 // etc. 1142 // etc.
1142 class WasmInstanceBuilder { 1143 class InstantiationHelper {
1143 public: 1144 public:
1144 WasmInstanceBuilder(Isolate* isolate, ErrorThrower* thrower, 1145 InstantiationHelper(Isolate* isolate, ErrorThrower* thrower,
1145 Handle<WasmModuleObject> module_object, 1146 Handle<WasmModuleObject> module_object,
1146 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) 1147 MaybeHandle<JSReceiver> ffi,
1148 MaybeHandle<JSArrayBuffer> memory)
1147 : isolate_(isolate), 1149 : isolate_(isolate),
1148 module_(module_object->compiled_module()->module()), 1150 module_(module_object->compiled_module()->module()),
1149 thrower_(thrower), 1151 thrower_(thrower),
1150 module_object_(module_object), 1152 module_object_(module_object),
1151 ffi_(ffi), 1153 ffi_(ffi.is_null() ? Handle<JSReceiver>::null()
1152 memory_(memory) {} 1154 : ffi.ToHandleChecked()),
1155 memory_(memory.is_null() ? Handle<JSArrayBuffer>::null()
1156 : memory.ToHandleChecked()) {}
1153 1157
1154 // Build an instance, in all of its glory. 1158 // Build an instance, in all of its glory.
1155 MaybeHandle<WasmInstanceObject> Build() { 1159 MaybeHandle<WasmInstanceObject> Build() {
1156 MaybeHandle<WasmInstanceObject> nothing; 1160 MaybeHandle<WasmInstanceObject> nothing;
1157 1161
1158 // Check that an imports argument was provided, if the module requires it. 1162 // Check that an imports argument was provided, if the module requires it.
1159 // No point in continuing otherwise. 1163 // No point in continuing otherwise.
1160 if (!module_->import_table.empty() && ffi_.is_null()) { 1164 if (!module_->import_table.empty() && ffi_.is_null()) {
1161 thrower_->TypeError( 1165 thrower_->TypeError(
1162 "Imports argument must be present and must be an object"); 1166 "Imports argument must be present and must be an object");
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 Handle<WasmTableObject> table_object; // WebAssembly.Table instance 1523 Handle<WasmTableObject> table_object; // WebAssembly.Table instance
1520 Handle<FixedArray> js_wrappers; // JSFunctions exported 1524 Handle<FixedArray> js_wrappers; // JSFunctions exported
1521 Handle<FixedArray> function_table; // internal code array 1525 Handle<FixedArray> function_table; // internal code array
1522 Handle<FixedArray> signature_table; // internal sig array 1526 Handle<FixedArray> signature_table; // internal sig array
1523 }; 1527 };
1524 1528
1525 Isolate* isolate_; 1529 Isolate* isolate_;
1526 WasmModule* const module_; 1530 WasmModule* const module_;
1527 ErrorThrower* thrower_; 1531 ErrorThrower* thrower_;
1528 Handle<WasmModuleObject> module_object_; 1532 Handle<WasmModuleObject> module_object_;
1529 Handle<JSReceiver> ffi_; 1533 Handle<JSReceiver> ffi_; // TODO(titzer): Use MaybeHandle
1530 Handle<JSArrayBuffer> memory_; 1534 Handle<JSArrayBuffer> memory_; // TODO(titzer): Use MaybeHandle
1531 Handle<JSArrayBuffer> globals_; 1535 Handle<JSArrayBuffer> globals_;
1532 Handle<WasmCompiledModule> compiled_module_; 1536 Handle<WasmCompiledModule> compiled_module_;
1533 std::vector<TableInstance> table_instances_; 1537 std::vector<TableInstance> table_instances_;
1534 std::vector<Handle<JSFunction>> js_wrappers_; 1538 std::vector<Handle<JSFunction>> js_wrappers_;
1535 1539
1536 // Helper routines to print out errors with imports. 1540 // Helper routines to print out errors with imports.
1537 void ReportLinkError(const char* error, uint32_t index, 1541 void ReportLinkError(const char* error, uint32_t index,
1538 Handle<String> module_name, Handle<String> import_name) { 1542 Handle<String> module_name, Handle<String> import_name) {
1539 thrower_->LinkError( 1543 thrower_->LinkError(
1540 "Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", index, 1544 "Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", index,
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
2236 if (!table_instance.table_object.is_null()) { 2240 if (!table_instance.table_object.is_null()) {
2237 // Add the new dispatch table to the WebAssembly.Table object. 2241 // Add the new dispatch table to the WebAssembly.Table object.
2238 all_dispatch_tables = WasmTableObject::AddDispatchTable( 2242 all_dispatch_tables = WasmTableObject::AddDispatchTable(
2239 isolate_, table_instance.table_object, instance, index, 2243 isolate_, table_instance.table_object, instance, index,
2240 table_instance.function_table, table_instance.signature_table); 2244 table_instance.function_table, table_instance.signature_table);
2241 } 2245 }
2242 } 2246 }
2243 } 2247 }
2244 }; 2248 };
2245 2249
2246 // Instantiates a WASM module, creating a WebAssembly.Instance from a
2247 // WebAssembly.Module.
2248 MaybeHandle<WasmInstanceObject> WasmModule::Instantiate(
2249 Isolate* isolate, ErrorThrower* thrower,
2250 Handle<WasmModuleObject> wasm_module, Handle<JSReceiver> ffi,
2251 Handle<JSArrayBuffer> memory) {
2252 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory);
2253 return builder.Build();
2254 }
2255
2256 bool wasm::IsWasmInstance(Object* object) { 2250 bool wasm::IsWasmInstance(Object* object) {
2257 return WasmInstanceObject::IsWasmInstanceObject(object); 2251 return WasmInstanceObject::IsWasmInstanceObject(object);
2258 } 2252 }
2259 2253
2260 Handle<Script> wasm::GetScript(Handle<JSObject> instance) { 2254 Handle<Script> wasm::GetScript(Handle<JSObject> instance) {
2261 WasmCompiledModule* compiled_module = 2255 WasmCompiledModule* compiled_module =
2262 WasmInstanceObject::cast(*instance)->compiled_module(); 2256 WasmInstanceObject::cast(*instance)->compiled_module();
2263 return handle(compiled_module->script()); 2257 return handle(compiled_module->script());
2264 } 2258 }
2265 2259
2266 bool wasm::IsWasmCodegenAllowed(Isolate* isolate, Handle<Context> context) { 2260 bool wasm::IsWasmCodegenAllowed(Isolate* isolate, Handle<Context> context) {
2267 return isolate->allow_code_gen_callback() == nullptr || 2261 return isolate->allow_code_gen_callback() == nullptr ||
2268 isolate->allow_code_gen_callback()(v8::Utils::ToLocal(context)); 2262 isolate->allow_code_gen_callback()(v8::Utils::ToLocal(context));
2269 } 2263 }
2270 2264
2271 // TODO(clemensh): origin can be inferred from asm_js_script; remove it.
2272 MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes(
2273 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower,
2274 ModuleOrigin origin, Handle<Script> asm_js_script,
2275 Vector<const byte> asm_js_offset_table_bytes) {
2276 MaybeHandle<WasmModuleObject> nothing;
2277
2278 if (origin != kAsmJsOrigin &&
2279 !IsWasmCodegenAllowed(isolate, isolate->native_context())) {
2280 thrower->CompileError("Wasm code generation disallowed in this context");
2281 return nothing;
2282 }
2283
2284 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin);
2285 if (result.failed()) {
2286 if (result.val) delete result.val;
2287 thrower->CompileFailed("Wasm decoding failed", result);
2288 return nothing;
2289 }
2290
2291 // The {module_wrapper} will take ownership of the {WasmModule} object,
2292 // and it will be destroyed when the GC reclaims the wrapper object.
2293 Handle<WasmModuleWrapper> module_wrapper =
2294 WasmModuleWrapper::New(isolate, const_cast<WasmModule*>(result.val));
2295
2296 // Compile the functions of the module, producing a compiled module.
2297 MaybeHandle<WasmCompiledModule> maybe_compiled_module =
2298 result.val->CompileFunctions(isolate, module_wrapper, thrower,
2299 ModuleWireBytes(start, end), asm_js_script,
2300 asm_js_offset_table_bytes);
2301
2302 if (maybe_compiled_module.is_null()) return nothing;
2303
2304 Handle<WasmCompiledModule> compiled_module =
2305 maybe_compiled_module.ToHandleChecked();
2306
2307 return WasmModuleObject::New(isolate, compiled_module);
2308 }
2309
2310 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start,
2311 const byte* end, ErrorThrower* thrower,
2312 ModuleOrigin origin) {
2313 ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin);
2314 if (result.val) {
2315 delete result.val;
2316 } else {
2317 DCHECK(!result.ok());
2318 }
2319 return result.ok();
2320 }
2321
2322 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory( 2265 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(
2323 Isolate* isolate, Handle<WasmInstanceObject> object) { 2266 Isolate* isolate, Handle<WasmInstanceObject> object) {
2324 auto instance = Handle<WasmInstanceObject>::cast(object); 2267 auto instance = Handle<WasmInstanceObject>::cast(object);
2325 if (instance->has_memory_buffer()) { 2268 if (instance->has_memory_buffer()) {
2326 return Handle<JSArrayBuffer>(instance->memory_buffer(), isolate); 2269 return Handle<JSArrayBuffer>(instance->memory_buffer(), isolate);
2327 } 2270 }
2328 return MaybeHandle<JSArrayBuffer>(); 2271 return MaybeHandle<JSArrayBuffer>();
2329 } 2272 }
2330 2273
2331 void SetInstanceMemory(Handle<WasmInstanceObject> instance, 2274 void SetInstanceMemory(Handle<WasmInstanceObject> instance,
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
2818 Handle<FixedArray> storage = factory->NewFixedArray(num_custom_sections); 2761 Handle<FixedArray> storage = factory->NewFixedArray(num_custom_sections);
2819 JSArray::SetContent(array_object, storage); 2762 JSArray::SetContent(array_object, storage);
2820 array_object->set_length(Smi::FromInt(num_custom_sections)); 2763 array_object->set_length(Smi::FromInt(num_custom_sections));
2821 2764
2822 for (int i = 0; i < num_custom_sections; i++) { 2765 for (int i = 0; i < num_custom_sections; i++) {
2823 storage->set(i, *matching_sections[i]); 2766 storage->set(i, *matching_sections[i]);
2824 } 2767 }
2825 2768
2826 return array_object; 2769 return array_object;
2827 } 2770 }
2771
2772 bool wasm::SyncValidate(Isolate* isolate, ErrorThrower* thrower,
2773 const ModuleWireBytes& bytes) {
2774 if (bytes.start() == nullptr || bytes.length() == 0) return false;
2775 ModuleResult result =
2776 DecodeWasmModule(isolate, bytes.start(), bytes.end(), true, kWasmOrigin);
2777 if (result.val) delete result.val;
2778 return result.ok();
2779 }
2780
2781 MaybeHandle<WasmModuleObject> wasm::SyncCompileTranslatedAsmJs(
2782 Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
2783 Handle<Script> asm_js_script,
2784 Vector<const byte> asm_js_offset_table_bytes) {
2785 MaybeHandle<WasmModuleObject> nothing;
2786
2787 ModuleResult result = DecodeWasmModule(isolate, bytes.start(), bytes.end(),
2788 false, kAsmJsOrigin);
2789 if (result.failed()) {
2790 // TODO(titzer): use Result<std::unique_ptr<const WasmModule*>>?
2791 if (result.val) delete result.val;
2792 thrower->CompileFailed("Wasm decoding failed", result);
2793 return nothing;
2794 }
2795
2796 return CompileToModuleObject(isolate, const_cast<WasmModule*>(result.val),
2797 thrower, bytes, asm_js_script,
2798 asm_js_offset_table_bytes);
2799 }
2800
2801 MaybeHandle<WasmModuleObject> wasm::SyncCompile(Isolate* isolate,
2802 ErrorThrower* thrower,
2803 const ModuleWireBytes& bytes) {
2804 MaybeHandle<WasmModuleObject> nothing;
2805
2806 if (!IsWasmCodegenAllowed(isolate, isolate->native_context())) {
2807 thrower->CompileError("Wasm code generation disallowed in this context");
2808 return nothing;
2809 }
2810
2811 ModuleResult result =
2812 DecodeWasmModule(isolate, bytes.start(), bytes.end(), false, kWasmOrigin);
2813 if (result.failed()) {
2814 if (result.val) delete result.val;
2815 thrower->CompileFailed("Wasm decoding failed", result);
2816 return nothing;
2817 }
2818
2819 return CompileToModuleObject(isolate, const_cast<WasmModule*>(result.val),
2820 thrower, bytes, Handle<Script>(),
2821 Vector<const byte>());
2822 }
2823
2824 MaybeHandle<WasmInstanceObject> wasm::SyncInstantiate(
2825 Isolate* isolate, ErrorThrower* thrower,
2826 Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
2827 MaybeHandle<JSArrayBuffer> memory) {
2828 InstantiationHelper helper(isolate, thrower, module_object, imports, memory);
2829 return helper.Build();
2830 }
2831
2832 void RejectPromise(Isolate* isolate, ErrorThrower* thrower,
2833 Handle<JSPromise> promise) {
2834 v8::Local<v8::Promise::Resolver> resolver =
2835 v8::Utils::PromiseToLocal(promise).As<v8::Promise::Resolver>();
2836 Handle<Context> context(isolate->context(), isolate);
2837 resolver->Reject(v8::Utils::ToLocal(context),
2838 v8::Utils::ToLocal(thrower->Reify()));
2839 }
2840
2841 void ResolvePromise(Isolate* isolate, Handle<JSPromise> promise,
2842 Handle<Object> result) {
2843 v8::Local<v8::Promise::Resolver> resolver =
2844 v8::Utils::PromiseToLocal(promise).As<v8::Promise::Resolver>();
2845 Handle<Context> context(isolate->context(), isolate);
2846 resolver->Resolve(v8::Utils::ToLocal(context), v8::Utils::ToLocal(result));
2847 }
2848
2849 void wasm::AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
2850 const ModuleWireBytes& bytes) {
2851 ErrorThrower thrower(isolate, nullptr);
2852 MaybeHandle<WasmModuleObject> module_object =
2853 SyncCompile(isolate, &thrower, bytes);
2854 if (thrower.error()) {
2855 RejectPromise(isolate, &thrower, promise);
2856 return;
2857 }
2858 ResolvePromise(isolate, promise, module_object.ToHandleChecked());
2859 }
2860
2861 void wasm::AsyncInstantiate(Isolate* isolate, Handle<JSPromise> promise,
2862 Handle<WasmModuleObject> module_object,
2863 MaybeHandle<JSReceiver> imports) {
2864 ErrorThrower thrower(isolate, nullptr);
2865 MaybeHandle<WasmInstanceObject> instance_object = SyncInstantiate(
2866 isolate, &thrower, module_object, imports, Handle<JSArrayBuffer>::null());
2867 if (thrower.error()) {
2868 RejectPromise(isolate, &thrower, promise);
2869 return;
2870 }
2871 ResolvePromise(isolate, promise, instance_object.ToHandleChecked());
2872 }
2873
2874 void wasm::AsyncCompileAndInstantiate(Isolate* isolate,
2875 Handle<JSPromise> promise,
2876 const ModuleWireBytes& bytes,
2877 MaybeHandle<JSReceiver> imports) {
2878 ErrorThrower thrower(isolate, nullptr);
2879
2880 // Compile the module.
2881 MaybeHandle<WasmModuleObject> module_object =
2882 SyncCompile(isolate, &thrower, bytes);
2883 if (thrower.error()) {
2884 RejectPromise(isolate, &thrower, promise);
2885 return;
2886 }
2887 Handle<WasmModuleObject> module = module_object.ToHandleChecked();
2888
2889 // Instantiate the module.
2890 MaybeHandle<WasmInstanceObject> instance_object = SyncInstantiate(
2891 isolate, &thrower, module, imports, Handle<JSArrayBuffer>::null());
2892 if (thrower.error()) {
2893 RejectPromise(isolate, &thrower, promise);
2894 return;
2895 }
2896
2897 Handle<JSFunction> object_function =
2898 Handle<JSFunction>(isolate->native_context()->object_function(), isolate);
2899 Handle<JSObject> ret =
2900 isolate->factory()->NewJSObject(object_function, TENURED);
2901 Handle<String> module_property_name =
2902 isolate->factory()->InternalizeUtf8String("module");
2903 Handle<String> instance_property_name =
2904 isolate->factory()->InternalizeUtf8String("instance");
2905 JSObject::AddProperty(ret, module_property_name, module, NONE);
2906 JSObject::AddProperty(ret, instance_property_name,
2907 instance_object.ToHandleChecked(), NONE);
2908
2909 ResolvePromise(isolate, promise, ret);
2910 }
OLDNEW
« no previous file with comments | « src/wasm/wasm-module.h ('k') | test/cctest/wasm/test-run-wasm-module.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698