| 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-natives.h" |
| 6 #include "src/api.h" | 6 #include "src/api.h" |
| 7 #include "src/asmjs/asm-js.h" | 7 #include "src/asmjs/asm-js.h" |
| 8 #include "src/asmjs/asm-typer.h" | 8 #include "src/asmjs/asm-typer.h" |
| 9 #include "src/asmjs/asm-wasm-builder.h" | 9 #include "src/asmjs/asm-wasm-builder.h" |
| 10 #include "src/assert-scope.h" | 10 #include "src/assert-scope.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 i::handle(i_context->wasm_module_sym()), thrower, | 67 i::handle(i_context->wasm_module_sym()), thrower, |
| 68 "Argument 0 must be a WebAssembly.Module")) { | 68 "Argument 0 must be a WebAssembly.Module")) { |
| 69 return {}; | 69 return {}; |
| 70 } | 70 } |
| 71 | 71 |
| 72 Local<Object> module_obj = Local<Object>::Cast(args[0]); | 72 Local<Object> module_obj = Local<Object>::Cast(args[0]); |
| 73 return i::Handle<i::WasmModuleObject>::cast( | 73 return i::Handle<i::WasmModuleObject>::cast( |
| 74 v8::Utils::OpenHandle(*module_obj)); | 74 v8::Utils::OpenHandle(*module_obj)); |
| 75 } | 75 } |
| 76 | 76 |
| 77 bool IsCompilationAllowed(i::Isolate* isolate, ErrorThrower* thrower, | |
| 78 v8::Local<v8::Value> source, bool is_async) { | |
| 79 // Allow caller to do one final check on thrower state, rather than | |
| 80 // one at each step. No information is lost - failure reason is captured | |
| 81 // in the thrower state. | |
| 82 if (thrower->error()) return false; | |
| 83 | |
| 84 AllowWasmCompileCallback callback = isolate->allow_wasm_compile_callback(); | |
| 85 if (callback != nullptr && | |
| 86 !callback(reinterpret_cast<v8::Isolate*>(isolate), source, is_async)) { | |
| 87 thrower->RangeError( | |
| 88 "%ssynchronous compilation disallowed due to module size limit set by " | |
| 89 "embedder", | |
| 90 is_async ? "a" : ""); | |
| 91 return false; | |
| 92 } | |
| 93 return true; | |
| 94 } | |
| 95 | |
| 96 bool IsInstantiationAllowed(i::Isolate* isolate, ErrorThrower* thrower, | |
| 97 v8::Local<v8::Value> module_or_bytes, | |
| 98 i::MaybeHandle<i::JSReceiver> ffi, bool is_async) { | |
| 99 // Allow caller to do one final check on thrower state, rather than | |
| 100 // one at each step. No information is lost - failure reason is captured | |
| 101 // in the thrower state. | |
| 102 if (thrower->error()) return false; | |
| 103 v8::MaybeLocal<v8::Value> v8_ffi; | |
| 104 if (!ffi.is_null()) { | |
| 105 v8_ffi = v8::Local<v8::Value>::Cast(Utils::ToLocal(ffi.ToHandleChecked())); | |
| 106 } | |
| 107 AllowWasmInstantiateCallback callback = | |
| 108 isolate->allow_wasm_instantiate_callback(); | |
| 109 if (callback != nullptr && | |
| 110 !callback(reinterpret_cast<v8::Isolate*>(isolate), module_or_bytes, | |
| 111 v8_ffi, is_async)) { | |
| 112 thrower->RangeError( | |
| 113 "%ssynchronous instantiation disallowed due to module size limit set " | |
| 114 "by embedder", | |
| 115 is_async ? "a" : ""); | |
| 116 return false; | |
| 117 } | |
| 118 return true; | |
| 119 } | |
| 120 | |
| 121 i::wasm::ModuleWireBytes GetFirstArgumentAsBytes( | 77 i::wasm::ModuleWireBytes GetFirstArgumentAsBytes( |
| 122 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) { | 78 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) { |
| 123 if (args.Length() < 1) { | 79 if (args.Length() < 1) { |
| 124 thrower->TypeError("Argument 0 must be a buffer source"); | 80 thrower->TypeError("Argument 0 must be a buffer source"); |
| 125 return i::wasm::ModuleWireBytes(nullptr, nullptr); | 81 return i::wasm::ModuleWireBytes(nullptr, nullptr); |
| 126 } | 82 } |
| 127 | 83 |
| 128 const byte* start = nullptr; | 84 const byte* start = nullptr; |
| 129 size_t length = 0; | 85 size_t length = 0; |
| 130 v8::Local<v8::Value> source = args[0]; | 86 v8::Local<v8::Value> source = args[0]; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 HandleScope scope(isolate); | 139 HandleScope scope(isolate); |
| 184 ErrorThrower thrower(i_isolate, "WebAssembly.compile()"); | 140 ErrorThrower thrower(i_isolate, "WebAssembly.compile()"); |
| 185 | 141 |
| 186 Local<Context> context = isolate->GetCurrentContext(); | 142 Local<Context> context = isolate->GetCurrentContext(); |
| 187 v8::Local<v8::Promise::Resolver> resolver; | 143 v8::Local<v8::Promise::Resolver> resolver; |
| 188 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; | 144 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; |
| 189 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 145 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
| 190 return_value.Set(resolver->GetPromise()); | 146 return_value.Set(resolver->GetPromise()); |
| 191 | 147 |
| 192 auto bytes = GetFirstArgumentAsBytes(args, &thrower); | 148 auto bytes = GetFirstArgumentAsBytes(args, &thrower); |
| 193 if (!IsCompilationAllowed(i_isolate, &thrower, args[0], true)) { | 149 if (thrower.error()) { |
| 194 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify())); | 150 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify())); |
| 195 CHECK(!maybe.IsNothing()); | 151 CHECK(!maybe.IsNothing()); |
| 196 return; | 152 return; |
| 197 } | 153 } |
| 198 DCHECK(!thrower.error()); | |
| 199 i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise()); | 154 i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise()); |
| 200 i::wasm::AsyncCompile(i_isolate, promise, bytes); | 155 i::wasm::AsyncCompile(i_isolate, promise, bytes); |
| 201 } | 156 } |
| 202 | 157 |
| 203 // WebAssembly.validate(bytes) -> bool | 158 // WebAssembly.validate(bytes) -> bool |
| 204 void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) { | 159 void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 205 v8::Isolate* isolate = args.GetIsolate(); | 160 v8::Isolate* isolate = args.GetIsolate(); |
| 206 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 161 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 207 HandleScope scope(isolate); | 162 HandleScope scope(isolate); |
| 208 ErrorThrower thrower(i_isolate, "WebAssembly.validate()"); | 163 ErrorThrower thrower(i_isolate, "WebAssembly.validate()"); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 223 // new WebAssembly.Module(bytes) -> WebAssembly.Module | 178 // new WebAssembly.Module(bytes) -> WebAssembly.Module |
| 224 void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 179 void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 225 v8::Isolate* isolate = args.GetIsolate(); | 180 v8::Isolate* isolate = args.GetIsolate(); |
| 226 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 181 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 227 if (i_isolate->wasm_module_callback()(args)) return; | 182 if (i_isolate->wasm_module_callback()(args)) return; |
| 228 | 183 |
| 229 HandleScope scope(isolate); | 184 HandleScope scope(isolate); |
| 230 ErrorThrower thrower(i_isolate, "WebAssembly.Module()"); | 185 ErrorThrower thrower(i_isolate, "WebAssembly.Module()"); |
| 231 | 186 |
| 232 auto bytes = GetFirstArgumentAsBytes(args, &thrower); | 187 auto bytes = GetFirstArgumentAsBytes(args, &thrower); |
| 233 if (!IsCompilationAllowed(i_isolate, &thrower, args[0], false)) return; | |
| 234 | 188 |
| 235 DCHECK(!thrower.error()); | 189 if (thrower.error()) { |
| 190 return; |
| 191 } |
| 236 i::MaybeHandle<i::Object> module_obj = | 192 i::MaybeHandle<i::Object> module_obj = |
| 237 i::wasm::SyncCompile(i_isolate, &thrower, bytes); | 193 i::wasm::SyncCompile(i_isolate, &thrower, bytes); |
| 238 if (module_obj.is_null()) return; | 194 if (module_obj.is_null()) return; |
| 239 | 195 |
| 240 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 196 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
| 241 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); | 197 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); |
| 242 } | 198 } |
| 243 | 199 |
| 244 // WebAssembly.Module.imports(module) -> Array<Import> | 200 // WebAssembly.Module.imports(module) -> Array<Import> |
| 245 void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) { | 201 void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 v8::Isolate* isolate = args.GetIsolate(); | 258 v8::Isolate* isolate = args.GetIsolate(); |
| 303 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 259 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 304 if (i_isolate->wasm_instance_callback()(args)) return; | 260 if (i_isolate->wasm_instance_callback()(args)) return; |
| 305 | 261 |
| 306 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); | 262 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); |
| 307 | 263 |
| 308 auto maybe_module = GetFirstArgumentAsModule(args, &thrower); | 264 auto maybe_module = GetFirstArgumentAsModule(args, &thrower); |
| 309 if (thrower.error()) return; | 265 if (thrower.error()) return; |
| 310 | 266 |
| 311 auto maybe_imports = GetSecondArgumentAsImports(args, &thrower); | 267 auto maybe_imports = GetSecondArgumentAsImports(args, &thrower); |
| 312 if (!IsInstantiationAllowed(i_isolate, &thrower, args[0], maybe_imports, | 268 if (thrower.error()) return; |
| 313 false)) { | |
| 314 return; | |
| 315 } | |
| 316 DCHECK(!thrower.error()); | |
| 317 | 269 |
| 318 i::MaybeHandle<i::Object> instance_object = i::wasm::SyncInstantiate( | 270 i::MaybeHandle<i::Object> instance_object = i::wasm::SyncInstantiate( |
| 319 i_isolate, &thrower, maybe_module.ToHandleChecked(), maybe_imports, | 271 i_isolate, &thrower, maybe_module.ToHandleChecked(), maybe_imports, |
| 320 i::MaybeHandle<i::JSArrayBuffer>()); | 272 i::MaybeHandle<i::JSArrayBuffer>()); |
| 321 if (instance_object.is_null()) return; | 273 if (instance_object.is_null()) return; |
| 322 args.GetReturnValue().Set(Utils::ToLocal(instance_object.ToHandleChecked())); | 274 args.GetReturnValue().Set(Utils::ToLocal(instance_object.ToHandleChecked())); |
| 323 } | 275 } |
| 324 | 276 |
| 325 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance | 277 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance |
| 326 // WebAssembly.instantiate(bytes, imports) -> | 278 // WebAssembly.instantiate(bytes, imports) -> |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 CHECK(!maybe.IsNothing()); | 311 CHECK(!maybe.IsNothing()); |
| 360 return; | 312 return; |
| 361 } | 313 } |
| 362 | 314 |
| 363 auto maybe_imports = GetSecondArgumentAsImports(args, &thrower); | 315 auto maybe_imports = GetSecondArgumentAsImports(args, &thrower); |
| 364 if (thrower.error()) { | 316 if (thrower.error()) { |
| 365 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify())); | 317 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify())); |
| 366 CHECK(!maybe.IsNothing()); | 318 CHECK(!maybe.IsNothing()); |
| 367 return; | 319 return; |
| 368 } | 320 } |
| 369 if (!IsInstantiationAllowed(i_isolate, &thrower, args[0], maybe_imports, | |
| 370 true)) { | |
| 371 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify())); | |
| 372 CHECK(!maybe.IsNothing()); | |
| 373 return; | |
| 374 } | |
| 375 i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise()); | 321 i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise()); |
| 376 if (HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()))) { | 322 if (HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()))) { |
| 377 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance | 323 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance |
| 378 auto module_object = GetFirstArgumentAsModule(args, &thrower); | 324 auto module_object = GetFirstArgumentAsModule(args, &thrower); |
| 379 i::wasm::AsyncInstantiate(i_isolate, promise, | 325 i::wasm::AsyncInstantiate(i_isolate, promise, |
| 380 module_object.ToHandleChecked(), maybe_imports); | 326 module_object.ToHandleChecked(), maybe_imports); |
| 381 } else { | 327 } else { |
| 382 // WebAssembly.instantiate(bytes, imports) -> {module, instance} | 328 // WebAssembly.instantiate(bytes, imports) -> {module, instance} |
| 383 auto bytes = GetFirstArgumentAsBytes(args, &thrower); | 329 auto bytes = GetFirstArgumentAsBytes(args, &thrower); |
| 384 if (thrower.error()) { | 330 if (thrower.error()) { |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); | 879 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); |
| 934 return HasBrand(value, symbol); | 880 return HasBrand(value, symbol); |
| 935 } | 881 } |
| 936 | 882 |
| 937 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { | 883 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { |
| 938 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); | 884 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); |
| 939 return HasBrand(value, symbol); | 885 return HasBrand(value, symbol); |
| 940 } | 886 } |
| 941 } // namespace internal | 887 } // namespace internal |
| 942 } // namespace v8 | 888 } // namespace v8 |
| OLD | NEW |