| 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 "src/api-natives.h" | 
|    5 #include "src/api.h" |    6 #include "src/api.h" | 
|    6 #include "src/api-natives.h" |  | 
|    7 #include "src/assert-scope.h" |    7 #include "src/assert-scope.h" | 
|    8 #include "src/ast/ast.h" |    8 #include "src/ast/ast.h" | 
|    9 #include "src/ast/scopes.h" |    9 #include "src/ast/scopes.h" | 
 |   10 #include "src/execution.h" | 
|   10 #include "src/factory.h" |   11 #include "src/factory.h" | 
|   11 #include "src/handles.h" |   12 #include "src/handles.h" | 
|   12 #include "src/isolate.h" |   13 #include "src/isolate.h" | 
|   13 #include "src/objects.h" |   14 #include "src/objects.h" | 
|   14 #include "src/parsing/parser.h" |   15 #include "src/parsing/parser.h" | 
|   15 #include "src/typing-asm.h" |   16 #include "src/typing-asm.h" | 
|   16  |   17  | 
|   17 #include "src/wasm/asm-wasm-builder.h" |   18 #include "src/wasm/asm-wasm-builder.h" | 
|   18 #include "src/wasm/encoder.h" |   19 #include "src/wasm/encoder.h" | 
|   19 #include "src/wasm/module-decoder.h" |   20 #include "src/wasm/module-decoder.h" | 
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  114   } |  115   } | 
|  115  |  116  | 
|  116   if (result.failed()) { |  117   if (result.failed()) { | 
|  117     thrower.Failed("", result); |  118     thrower.Failed("", result); | 
|  118   } |  119   } | 
|  119  |  120  | 
|  120   if (result.val) delete result.val; |  121   if (result.val) delete result.val; | 
|  121 } |  122 } | 
|  122  |  123  | 
|  123 v8::internal::wasm::WasmModuleIndex* TranslateAsmModule( |  124 v8::internal::wasm::WasmModuleIndex* TranslateAsmModule( | 
|  124     i::ParseInfo* info, i::Handle<i::Object> foreign, ErrorThrower* thrower) { |  125     i::ParseInfo* info, ErrorThrower* thrower, | 
 |  126     i::Handle<i::FixedArray>* foreign_args) { | 
|  125   info->set_global(); |  127   info->set_global(); | 
|  126   info->set_lazy(false); |  128   info->set_lazy(false); | 
|  127   info->set_allow_lazy_parsing(false); |  129   info->set_allow_lazy_parsing(false); | 
|  128   info->set_toplevel(true); |  130   info->set_toplevel(true); | 
|  129  |  131  | 
|  130   if (!i::Compiler::ParseAndAnalyze(info)) { |  132   if (!i::Compiler::ParseAndAnalyze(info)) { | 
|  131     return nullptr; |  133     return nullptr; | 
|  132   } |  134   } | 
|  133  |  135  | 
|  134   if (info->scope()->declarations()->length() == 0) { |  136   if (info->scope()->declarations()->length() == 0) { | 
|  135     thrower->Error("Asm.js validation failed: no declarations in scope"); |  137     thrower->Error("Asm.js validation failed: no declarations in scope"); | 
|  136     return nullptr; |  138     return nullptr; | 
|  137   } |  139   } | 
|  138  |  140  | 
|  139   info->set_literal( |  141   info->set_literal( | 
|  140       info->scope()->declarations()->at(0)->AsFunctionDeclaration()->fun()); |  142       info->scope()->declarations()->at(0)->AsFunctionDeclaration()->fun()); | 
|  141  |  143  | 
|  142   v8::internal::AsmTyper typer(info->isolate(), info->zone(), *(info->script()), |  144   v8::internal::AsmTyper typer(info->isolate(), info->zone(), *(info->script()), | 
|  143                                info->literal()); |  145                                info->literal()); | 
|  144   if (i::FLAG_enable_simd_asmjs) { |  146   if (i::FLAG_enable_simd_asmjs) { | 
|  145     typer.set_allow_simd(true); |  147     typer.set_allow_simd(true); | 
|  146   } |  148   } | 
|  147   if (!typer.Validate()) { |  149   if (!typer.Validate()) { | 
|  148     thrower->Error("Asm.js validation failed: %s", typer.error_message()); |  150     thrower->Error("Asm.js validation failed: %s", typer.error_message()); | 
|  149     return nullptr; |  151     return nullptr; | 
|  150   } |  152   } | 
|  151  |  153  | 
|  152   auto module = |  154   v8::internal::wasm::AsmWasmBuilder builder(info->isolate(), info->zone(), | 
|  153       v8::internal::wasm::AsmWasmBuilder(info->isolate(), info->zone(), |  155                                              info->literal(), &typer); | 
|  154                                          info->literal(), foreign, &typer) |  156  | 
|  155           .Run(); |  157   auto module = builder.Run(foreign_args); | 
|  156  |  158  | 
|  157   return module; |  159   return module; | 
|  158 } |  160 } | 
|  159  |  161  | 
|  160 void InstantiateModuleCommon(const v8::FunctionCallbackInfo<v8::Value>& args, |  162 i::MaybeHandle<i::JSObject> InstantiateModuleCommon( | 
|  161                              const byte* start, const byte* end, |  163     const v8::FunctionCallbackInfo<v8::Value>& args, const byte* start, | 
|  162                              ErrorThrower* thrower, |  164     const byte* end, ErrorThrower* thrower, | 
|  163                              internal::wasm::ModuleOrigin origin) { |  165     internal::wasm::ModuleOrigin origin) { | 
|  164   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |  166   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 
|  165  |  167  | 
|  166   i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); |  168   i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); | 
|  167   if (args.Length() > 2 && args[2]->IsArrayBuffer()) { |  169   if (args.Length() > 2 && args[2]->IsArrayBuffer()) { | 
|  168     Local<Object> obj = Local<Object>::Cast(args[2]); |  170     Local<Object> obj = Local<Object>::Cast(args[2]); | 
|  169     i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); |  171     i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); | 
|  170     memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); |  172     memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); | 
|  171   } |  173   } | 
|  172  |  174  | 
|  173   // Decode but avoid a redundant pass over function bodies for verification. |  175   // Decode but avoid a redundant pass over function bodies for verification. | 
|  174   // Verification will happen during compilation. |  176   // Verification will happen during compilation. | 
|  175   i::Zone zone(isolate->allocator()); |  177   i::Zone zone(isolate->allocator()); | 
|  176   internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule( |  178   internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule( | 
|  177       isolate, &zone, start, end, false, origin); |  179       isolate, &zone, start, end, false, origin); | 
|  178  |  180  | 
 |  181   i::MaybeHandle<i::JSObject> object; | 
|  179   if (result.failed() && origin == internal::wasm::kAsmJsOrigin) { |  182   if (result.failed() && origin == internal::wasm::kAsmJsOrigin) { | 
|  180     thrower->Error("Asm.js converted module failed to decode"); |  183     thrower->Error("Asm.js converted module failed to decode"); | 
|  181   } else if (result.failed()) { |  184   } else if (result.failed()) { | 
|  182     thrower->Failed("", result); |  185     thrower->Failed("", result); | 
|  183   } else { |  186   } else { | 
|  184     // Success. Instantiate the module and return the object. |  187     // Success. Instantiate the module and return the object. | 
|  185     i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); |  188     i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); | 
|  186     if (args.Length() > 1 && args[1]->IsObject()) { |  189     if (args.Length() > 1 && args[1]->IsObject()) { | 
|  187       Local<Object> obj = Local<Object>::Cast(args[1]); |  190       Local<Object> obj = Local<Object>::Cast(args[1]); | 
|  188       ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); |  191       ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); | 
|  189     } |  192     } | 
|  190  |  193  | 
|  191     i::MaybeHandle<i::JSObject> object = |  194     object = result.val->Instantiate(isolate, ffi, memory); | 
|  192         result.val->Instantiate(isolate, ffi, memory); |  | 
|  193  |  195  | 
|  194     if (!object.is_null()) { |  196     if (!object.is_null()) { | 
|  195       args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); |  197       args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); | 
|  196     } |  198     } | 
|  197   } |  199   } | 
|  198  |  200  | 
|  199   if (result.val) delete result.val; |  201   if (result.val) delete result.val; | 
 |  202   return object; | 
|  200 } |  203 } | 
|  201  |  204  | 
|  202 void InstantiateModuleFromAsm(const v8::FunctionCallbackInfo<v8::Value>& args) { |  205 void InstantiateModuleFromAsm(const v8::FunctionCallbackInfo<v8::Value>& args) { | 
|  203   HandleScope scope(args.GetIsolate()); |  206   HandleScope scope(args.GetIsolate()); | 
|  204   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |  207   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 
|  205   ErrorThrower thrower(isolate, "WASM.instantiateModuleFromAsm()"); |  208   ErrorThrower thrower(isolate, "WASM.instantiateModuleFromAsm()"); | 
|  206  |  209  | 
|  207   if (!args[0]->IsString()) { |  210   if (!args[0]->IsString()) { | 
|  208     thrower.Error("Asm module text should be a string"); |  211     thrower.Error("Asm module text should be a string"); | 
|  209     return; |  212     return; | 
|  210   } |  213   } | 
|  211  |  214  | 
|  212   i::Factory* factory = isolate->factory(); |  215   i::Factory* factory = isolate->factory(); | 
|  213   i::Zone zone(isolate->allocator()); |  216   i::Zone zone(isolate->allocator()); | 
|  214   Local<String> source = Local<String>::Cast(args[0]); |  217   Local<String> source = Local<String>::Cast(args[0]); | 
|  215   i::Handle<i::Script> script = factory->NewScript(Utils::OpenHandle(*source)); |  218   i::Handle<i::Script> script = factory->NewScript(Utils::OpenHandle(*source)); | 
|  216   i::ParseInfo info(&zone, script); |  219   i::ParseInfo info(&zone, script); | 
|  217  |  220  | 
|  218   i::Handle<i::Object> foreign; |  221   i::Handle<i::Object> foreign; | 
|  219   if (args.Length() > 1 && args[1]->IsObject()) { |  222   if (args.Length() > 1 && args[1]->IsObject()) { | 
|  220     Local<Object> local_foreign = Local<Object>::Cast(args[1]); |  223     Local<Object> local_foreign = Local<Object>::Cast(args[1]); | 
|  221     foreign = v8::Utils::OpenHandle(*local_foreign); |  224     foreign = v8::Utils::OpenHandle(*local_foreign); | 
|  222   } |  225   } | 
|  223  |  226  | 
|  224   auto module = TranslateAsmModule(&info, foreign, &thrower); |  227   i::Handle<i::FixedArray> foreign_args; | 
 |  228   auto module = TranslateAsmModule(&info, &thrower, &foreign_args); | 
|  225   if (module == nullptr) { |  229   if (module == nullptr) { | 
|  226     return; |  230     return; | 
|  227   } |  231   } | 
|  228  |  232  | 
|  229   InstantiateModuleCommon(args, module->Begin(), module->End(), &thrower, |  233   i::MaybeHandle<i::Object> maybe_module_object = | 
|  230                           internal::wasm::kAsmJsOrigin); |  234       InstantiateModuleCommon(args, module->Begin(), module->End(), &thrower, | 
 |  235                               internal::wasm::kAsmJsOrigin); | 
 |  236   if (maybe_module_object.is_null()) { | 
 |  237     return; | 
 |  238   } | 
 |  239  | 
 |  240   i::Handle<i::Name> name = | 
 |  241       factory->NewStringFromStaticChars("__foreign_init__"); | 
 |  242  | 
 |  243   i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked(); | 
 |  244   i::MaybeHandle<i::Object> maybe_init = | 
 |  245       i::Object::GetProperty(module_object, name); | 
 |  246   DCHECK(!maybe_init.is_null()); | 
 |  247  | 
 |  248   i::Handle<i::Object> init = maybe_init.ToHandleChecked(); | 
 |  249   i::Handle<i::Object> undefined(isolate->heap()->undefined_value(), isolate); | 
 |  250   i::Handle<i::Object>* foreign_args_array = | 
 |  251       new i::Handle<i::Object>[foreign_args->length()]; | 
 |  252   for (int j = 0; j < foreign_args->length(); j++) { | 
 |  253     if (!foreign.is_null()) { | 
 |  254       i::MaybeHandle<i::Name> name = i::Object::ToName( | 
 |  255           isolate, i::Handle<i::Object>(foreign_args->get(j), isolate)); | 
 |  256       if (!name.is_null()) { | 
 |  257         i::MaybeHandle<i::Object> val = | 
 |  258             i::Object::GetProperty(foreign, name.ToHandleChecked()); | 
 |  259         if (!val.is_null()) { | 
 |  260           foreign_args_array[j] = val.ToHandleChecked(); | 
 |  261           continue; | 
 |  262         } | 
 |  263       } | 
 |  264     } | 
 |  265     foreign_args_array[j] = undefined; | 
 |  266   } | 
 |  267   i::MaybeHandle<i::Object> retval = i::Execution::Call( | 
 |  268       isolate, init, undefined, foreign_args->length(), foreign_args_array); | 
 |  269   delete[] foreign_args_array; | 
 |  270  | 
 |  271   if (retval.is_null()) { | 
 |  272     thrower.Error( | 
 |  273         "WASM.instantiateModuleFromAsm(): foreign init function failed"); | 
 |  274   } | 
|  231 } |  275 } | 
|  232  |  276  | 
|  233 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |  277 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 
|  234   HandleScope scope(args.GetIsolate()); |  278   HandleScope scope(args.GetIsolate()); | 
|  235   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |  279   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 
|  236   ErrorThrower thrower(isolate, "WASM.instantiateModule()"); |  280   ErrorThrower thrower(isolate, "WASM.instantiateModule()"); | 
|  237  |  281  | 
|  238   RawBuffer buffer = GetRawBufferArgument(thrower, args); |  282   RawBuffer buffer = GetRawBufferArgument(thrower, args); | 
|  239   if (buffer.start == nullptr) return; |  283   if (buffer.start == nullptr) return; | 
|  240  |  284  | 
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  321     int unused_property_fields = in_object_properties - pre_allocated; |  365     int unused_property_fields = in_object_properties - pre_allocated; | 
|  322     Handle<Map> map = Map::CopyInitialMap( |  366     Handle<Map> map = Map::CopyInitialMap( | 
|  323         prev_map, instance_size, in_object_properties, unused_property_fields); |  367         prev_map, instance_size, in_object_properties, unused_property_fields); | 
|  324  |  368  | 
|  325     context->set_wasm_function_map(*map); |  369     context->set_wasm_function_map(*map); | 
|  326   } |  370   } | 
|  327 } |  371 } | 
|  328  |  372  | 
|  329 }  // namespace internal |  373 }  // namespace internal | 
|  330 }  // namespace v8 |  374 }  // namespace v8 | 
| OLD | NEW |