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