Chromium Code Reviews| 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 |