OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } | |
OLD | NEW |