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 |