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

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
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,
Clemens Hammacher 2017/02/16 20:36:57 The C++11 way to communicate that we take ownershi
ahaas 2017/02/17 13:02:29 We do use unique_ptr. Do you mean we should use th
Clemens Hammacher 2017/02/17 13:10:30 Exactly. The caller gives up ownership, and we eit
titzer 2017/02/17 13:17:54 Erg, yeah, that would be bad, because the ownershi
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 DCHECK(!compiled_module.is_null());
Clemens Hammacher 2017/02/16 20:36:57 Seems unnecessary, compiled_module is unconditiall
titzer 2017/02/17 13:17:54 Done.
1039 return WasmModuleObject::New(isolate, compiled_module);
1038 } 1040 }
1039 1041
1040 static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate, 1042 static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate,
1041 Handle<Object> target) { 1043 Handle<Object> target) {
1042 if (target->IsJSFunction()) { 1044 if (target->IsJSFunction()) {
1043 Handle<JSFunction> func = Handle<JSFunction>::cast(target); 1045 Handle<JSFunction> func = Handle<JSFunction>::cast(target);
1044 if (func->code()->kind() == Code::JS_TO_WASM_FUNCTION) { 1046 if (func->code()->kind() == Code::JS_TO_WASM_FUNCTION) {
1045 auto exported = Handle<WasmExportedFunction>::cast(func); 1047 auto exported = Handle<WasmExportedFunction>::cast(func);
1046 Handle<WasmInstanceObject> other_instance(exported->instance(), isolate); 1048 Handle<WasmInstanceObject> other_instance(exported->instance(), isolate);
1047 int func_index = exported->function_index(); 1049 int func_index = exported->function_index();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 } 1138 }
1137 } 1139 }
1138 1140
1139 // A helper class to simplify instantiating a module from a compiled module. 1141 // A helper class to simplify instantiating a module from a compiled module.
1140 // It closes over the {Isolate}, the {ErrorThrower}, the {WasmCompiledModule}, 1142 // It closes over the {Isolate}, the {ErrorThrower}, the {WasmCompiledModule},
1141 // etc. 1143 // etc.
1142 class WasmInstanceBuilder { 1144 class WasmInstanceBuilder {
1143 public: 1145 public:
1144 WasmInstanceBuilder(Isolate* isolate, ErrorThrower* thrower, 1146 WasmInstanceBuilder(Isolate* isolate, ErrorThrower* thrower,
1145 Handle<WasmModuleObject> module_object, 1147 Handle<WasmModuleObject> module_object,
1146 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) 1148 MaybeHandle<JSReceiver> ffi,
1149 MaybeHandle<JSArrayBuffer> memory)
1147 : isolate_(isolate), 1150 : isolate_(isolate),
1148 module_(module_object->compiled_module()->module()), 1151 module_(module_object->compiled_module()->module()),
1149 thrower_(thrower), 1152 thrower_(thrower),
1150 module_object_(module_object), 1153 module_object_(module_object),
1151 ffi_(ffi), 1154 ffi_(ffi.is_null() ? Handle<JSReceiver>::null()
Clemens Hammacher 2017/02/16 20:36:57 Maybe we should also store it as MaybeHandle. That
titzer 2017/02/17 13:17:53 The only reason I avoided doing that is the noise
1152 memory_(memory) {} 1155 : ffi.ToHandleChecked()),
1156 memory_(memory.is_null() ? Handle<JSArrayBuffer>::null()
1157 : memory.ToHandleChecked()) {}
1153 1158
1154 // Build an instance, in all of its glory. 1159 // Build an instance, in all of its glory.
1155 MaybeHandle<WasmInstanceObject> Build() { 1160 MaybeHandle<WasmInstanceObject> Build() {
1156 MaybeHandle<WasmInstanceObject> nothing; 1161 MaybeHandle<WasmInstanceObject> nothing;
1157 1162
1158 // Check that an imports argument was provided, if the module requires it. 1163 // Check that an imports argument was provided, if the module requires it.
1159 // No point in continuing otherwise. 1164 // No point in continuing otherwise.
1160 if (!module_->import_table.empty() && ffi_.is_null()) { 1165 if (!module_->import_table.empty() && ffi_.is_null()) {
1161 thrower_->TypeError( 1166 thrower_->TypeError(
1162 "Imports argument must be present and must be an object"); 1167 "Imports argument must be present and must be an object");
(...skipping 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after
2236 if (!table_instance.table_object.is_null()) { 2241 if (!table_instance.table_object.is_null()) {
2237 // Add the new dispatch table to the WebAssembly.Table object. 2242 // Add the new dispatch table to the WebAssembly.Table object.
2238 all_dispatch_tables = WasmTableObject::AddDispatchTable( 2243 all_dispatch_tables = WasmTableObject::AddDispatchTable(
2239 isolate_, table_instance.table_object, instance, index, 2244 isolate_, table_instance.table_object, instance, index,
2240 table_instance.function_table, table_instance.signature_table); 2245 table_instance.function_table, table_instance.signature_table);
2241 } 2246 }
2242 } 2247 }
2243 } 2248 }
2244 }; 2249 };
2245 2250
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) { 2251 bool wasm::IsWasmInstance(Object* object) {
2257 return WasmInstanceObject::IsWasmInstanceObject(object); 2252 return WasmInstanceObject::IsWasmInstanceObject(object);
2258 } 2253 }
2259 2254
2260 Handle<Script> wasm::GetScript(Handle<JSObject> instance) { 2255 Handle<Script> wasm::GetScript(Handle<JSObject> instance) {
2261 WasmCompiledModule* compiled_module = 2256 WasmCompiledModule* compiled_module =
2262 WasmInstanceObject::cast(*instance)->compiled_module(); 2257 WasmInstanceObject::cast(*instance)->compiled_module();
2263 return handle(compiled_module->script()); 2258 return handle(compiled_module->script());
2264 } 2259 }
2265 2260
2266 bool wasm::IsWasmCodegenAllowed(Isolate* isolate, Handle<Context> context) { 2261 bool wasm::IsWasmCodegenAllowed(Isolate* isolate, Handle<Context> context) {
2267 return isolate->allow_code_gen_callback() == nullptr || 2262 return isolate->allow_code_gen_callback() == nullptr ||
2268 isolate->allow_code_gen_callback()(v8::Utils::ToLocal(context)); 2263 isolate->allow_code_gen_callback()(v8::Utils::ToLocal(context));
2269 } 2264 }
2270 2265
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( 2266 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(
2323 Isolate* isolate, Handle<WasmInstanceObject> object) { 2267 Isolate* isolate, Handle<WasmInstanceObject> object) {
2324 auto instance = Handle<WasmInstanceObject>::cast(object); 2268 auto instance = Handle<WasmInstanceObject>::cast(object);
2325 if (instance->has_memory_buffer()) { 2269 if (instance->has_memory_buffer()) {
2326 return Handle<JSArrayBuffer>(instance->memory_buffer(), isolate); 2270 return Handle<JSArrayBuffer>(instance->memory_buffer(), isolate);
2327 } 2271 }
2328 return MaybeHandle<JSArrayBuffer>(); 2272 return MaybeHandle<JSArrayBuffer>();
2329 } 2273 }
2330 2274
2331 void SetInstanceMemory(Handle<WasmInstanceObject> instance, 2275 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); 2762 Handle<FixedArray> storage = factory->NewFixedArray(num_custom_sections);
2819 JSArray::SetContent(array_object, storage); 2763 JSArray::SetContent(array_object, storage);
2820 array_object->set_length(Smi::FromInt(num_custom_sections)); 2764 array_object->set_length(Smi::FromInt(num_custom_sections));
2821 2765
2822 for (int i = 0; i < num_custom_sections; i++) { 2766 for (int i = 0; i < num_custom_sections; i++) {
2823 storage->set(i, *matching_sections[i]); 2767 storage->set(i, *matching_sections[i]);
2824 } 2768 }
2825 2769
2826 return array_object; 2770 return array_object;
2827 } 2771 }
2772
2773 bool wasm::SyncValidate(Isolate* isolate, ErrorThrower* thrower,
2774 const ModuleWireBytes& bytes) {
2775 if (bytes.start() == nullptr || bytes.length() == 0) return false;
2776 ModuleResult result =
2777 DecodeWasmModule(isolate, bytes.start(), bytes.end(), true, kWasmOrigin);
2778 if (result.val) {
2779 delete result.val;
2780 } else {
2781 DCHECK(!result.ok());
Clemens Hammacher 2017/02/16 20:36:57 "DCHECK_IMPLIES(result.ok(), result.val);" before
ahaas 2017/02/17 13:02:29 The check here is the other way around: if !result
Clemens Hammacher 2017/02/17 13:10:30 It's semantically equivalent, and my version reads
titzer 2017/02/17 13:17:54 Initially I added the DCHECK, but now I just remov
2782 }
2783 return result.ok();
2784 }
2785
2786 MaybeHandle<WasmModuleObject> wasm::SyncCompileTranslatedAsmJs(
2787 Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
2788 Handle<Script> asm_js_script,
2789 Vector<const byte> asm_js_offset_table_bytes) {
2790 MaybeHandle<WasmModuleObject> nothing;
2791
2792 ModuleResult result = DecodeWasmModule(isolate, bytes.start(), bytes.end(),
2793 false, kAsmJsOrigin);
2794 if (result.failed()) {
2795 if (result.val) delete result.val;
Clemens Hammacher 2017/02/16 20:36:57 This pattern repeats several times in this file. W
ahaas 2017/02/17 13:02:29 I agree, storing a std::unique_ptr in the result w
titzer 2017/02/17 13:17:53 Added TODO.
2796 thrower->CompileFailed("Wasm decoding failed", result);
2797 return nothing;
2798 }
2799
2800 return CompileToModuleObject(isolate, const_cast<WasmModule*>(result.val),
2801 thrower, bytes, asm_js_script,
2802 asm_js_offset_table_bytes);
2803 }
2804
2805 MaybeHandle<WasmModuleObject> wasm::SyncCompile(Isolate* isolate,
2806 ErrorThrower* thrower,
2807 const ModuleWireBytes& bytes) {
2808 MaybeHandle<WasmModuleObject> nothing;
2809
2810 if (!IsWasmCodegenAllowed(isolate, isolate->native_context())) {
2811 thrower->CompileError("Wasm code generation disallowed in this context");
2812 return nothing;
2813 }
2814
2815 ModuleResult result =
2816 DecodeWasmModule(isolate, bytes.start(), bytes.end(), false, kWasmOrigin);
2817 if (result.failed()) {
2818 if (result.val) delete result.val;
2819 thrower->CompileFailed("Wasm decoding failed", result);
2820 return nothing;
2821 }
2822
2823 return CompileToModuleObject(isolate, const_cast<WasmModule*>(result.val),
2824 thrower, bytes, Handle<Script>(),
2825 Vector<const byte>());
2826 }
2827
2828 MaybeHandle<WasmInstanceObject> wasm::SyncInstantiate(
2829 Isolate* isolate, ErrorThrower* thrower,
2830 Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
2831 MaybeHandle<JSArrayBuffer> memory) {
2832 WasmInstanceBuilder builder(isolate, thrower, module_object, imports, memory);
2833 return builder.Build();
2834 }
2835
2836 void RejectPromise(Isolate* isolate, ErrorThrower* thrower,
2837 Handle<JSPromise> promise) {
2838 v8::Local<v8::Promise::Resolver> resolver =
2839 v8::Utils::Convert<i::JSPromise, v8::Promise::Resolver>(promise);
Clemens Hammacher 2017/02/16 20:36:57 This is the only location outside of api.h that us
titzer 2017/02/17 13:17:53 Done.
2840 Handle<Context> context(isolate->context(), isolate);
2841 resolver->Reject(v8::Utils::ToLocal(context),
2842 v8::Utils::ToLocal(thrower->Reify()));
ahaas 2017/02/17 13:02:29 I think a DCHECK(thrower->error()); would be inter
2843 }
2844
2845 void ResolvePromise(Isolate* isolate, Handle<JSPromise> promise,
2846 Handle<Object> result) {
2847 v8::Local<v8::Promise::Resolver> resolver =
2848 v8::Utils::Convert<i::JSPromise, v8::Promise::Resolver>(promise);
Clemens Hammacher 2017/02/16 20:36:57 Same here.
titzer 2017/02/17 13:17:53 Done.
2849 Handle<Context> context(isolate->context(), isolate);
2850 resolver->Resolve(v8::Utils::ToLocal(context), v8::Utils::ToLocal(result));
2851 }
2852
2853 void wasm::AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
2854 const ModuleWireBytes& bytes) {
2855 ErrorThrower thrower(isolate, "");
Clemens Hammacher 2017/02/16 20:36:57 Better pass null pointer here. Otherwise ": " will
ahaas 2017/02/17 13:02:29 Why does the thrower not get a proper name?
titzer 2017/02/17 13:17:53 Good catch. Done.
2856 MaybeHandle<WasmModuleObject> module_object =
2857 SyncCompile(isolate, &thrower, bytes);
2858 if (thrower.error()) {
2859 RejectPromise(isolate, &thrower, promise);
2860 return;
2861 }
2862 ResolvePromise(isolate, promise, module_object.ToHandleChecked());
2863 }
2864
2865 void wasm::AsyncInstantiate(Isolate* isolate, Handle<JSPromise> promise,
2866 Handle<WasmModuleObject> module_object,
2867 MaybeHandle<JSReceiver> imports) {
2868 ErrorThrower thrower(isolate, "");
Clemens Hammacher 2017/02/16 20:36:57 Same here.
titzer 2017/02/17 13:17:53 Done.
2869 MaybeHandle<WasmInstanceObject> instance_object = SyncInstantiate(
2870 isolate, &thrower, module_object, imports, Handle<JSArrayBuffer>::null());
2871 if (thrower.error()) {
2872 RejectPromise(isolate, &thrower, promise);
2873 return;
2874 }
2875 ResolvePromise(isolate, promise, instance_object.ToHandleChecked());
2876 }
2877
2878 void wasm::AsyncCompileAndInstantiate(Isolate* isolate,
2879 Handle<JSPromise> promise,
2880 const ModuleWireBytes& bytes,
2881 void* unused,
2882 MaybeHandle<JSReceiver> imports) {
2883 ErrorThrower thrower(isolate, "");
Clemens Hammacher 2017/02/16 20:36:57 And here.
titzer 2017/02/17 13:17:53 Done.
2884
2885 // Compile the module.
2886 MaybeHandle<WasmModuleObject> module_object =
2887 SyncCompile(isolate, &thrower, bytes);
2888 if (thrower.error()) {
2889 RejectPromise(isolate, &thrower, promise);
2890 return;
2891 }
2892
2893 AsyncCompileAndInstantiate(isolate, promise, module_object.ToHandleChecked(),
2894 imports);
2895 }
2896
2897 void wasm::AsyncCompileAndInstantiate(Isolate* isolate,
ahaas 2017/02/17 13:02:29 Where is the compilation happening in this functio
titzer 2017/02/17 13:17:54 Dude, you're absolutely right. This method was red
2898 Handle<JSPromise> promise,
2899 Handle<WasmModuleObject> module,
2900 MaybeHandle<JSReceiver> imports) {
2901 ErrorThrower thrower(isolate, "");
Clemens Hammacher 2017/02/16 20:36:57 And here.
titzer 2017/02/17 13:17:54 Done.
2902
2903 // Instantiate the module.
2904 MaybeHandle<WasmInstanceObject> instance_object = SyncInstantiate(
2905 isolate, &thrower, module, imports, Handle<JSArrayBuffer>::null());
2906 if (thrower.error()) {
2907 RejectPromise(isolate, &thrower, promise);
2908 return;
2909 }
2910
2911 Handle<JSFunction> object_function =
2912 Handle<JSFunction>(isolate->native_context()->object_function(), isolate);
2913 Handle<JSObject> ret =
2914 isolate->factory()->NewJSObject(object_function, TENURED);
2915 Handle<String> module_property_name =
2916 isolate->factory()->InternalizeUtf8String("module");
2917 Handle<String> instance_property_name =
2918 isolate->factory()->InternalizeUtf8String("instance");
2919 JSObject::AddProperty(ret, module_property_name, module, NONE);
2920 JSObject::AddProperty(ret, instance_property_name,
2921 instance_object.ToHandleChecked(), NONE);
2922
2923 ResolvePromise(isolate, promise, ret);
2924 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698