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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 thrower->TypeError("Argument 0 must be a buffer source"); | 72 thrower->TypeError("Argument 0 must be a buffer source"); |
73 } | 73 } |
74 if (start == nullptr || end == start) { | 74 if (start == nullptr || end == start) { |
75 thrower->CompileError("BufferSource argument is empty"); | 75 thrower->CompileError("BufferSource argument is empty"); |
76 } | 76 } |
77 return {start, end}; | 77 return {start, end}; |
78 } | 78 } |
79 | 79 |
80 static i::MaybeHandle<i::WasmModuleObject> CreateModuleObject( | 80 static i::MaybeHandle<i::WasmModuleObject> CreateModuleObject( |
81 v8::Isolate* isolate, const v8::Local<v8::Value> source, | 81 v8::Isolate* isolate, const v8::Local<v8::Value> source, |
82 ErrorThrower* thrower, bool async) { | 82 ErrorThrower* thrower) { |
83 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 83 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
84 i::MaybeHandle<i::WasmModuleObject> nothing; | 84 i::MaybeHandle<i::JSObject> nothing; |
85 | |
86 AllowWasmCompileCallback callback = | |
87 reinterpret_cast<i::Isolate*>(isolate)->allow_wasm_compile_callback(); | |
88 if (callback != nullptr && !callback(source, async)) { | |
89 thrower->RangeError( | |
90 "Wasm compilation exceeds internal limits in this context for provided " | |
91 "arguments"); | |
92 return nothing; | |
93 } | |
94 | 85 |
95 RawBuffer buffer = GetRawBufferSource(source, thrower); | 86 RawBuffer buffer = GetRawBufferSource(source, thrower); |
96 if (buffer.start == nullptr) return i::MaybeHandle<i::WasmModuleObject>(); | 87 if (buffer.start == nullptr) return i::MaybeHandle<i::WasmModuleObject>(); |
97 | 88 |
98 DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); | 89 DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); |
99 return i::wasm::CreateModuleObjectFromBytes( | 90 return i::wasm::CreateModuleObjectFromBytes( |
100 i_isolate, buffer.start, buffer.end, thrower, i::wasm::kWasmOrigin, | 91 i_isolate, buffer.start, buffer.end, thrower, i::wasm::kWasmOrigin, |
101 i::Handle<i::Script>::null(), i::Vector<const byte>::empty()); | 92 i::Handle<i::Script>::null(), i::Vector<const byte>::empty()); |
102 } | 93 } |
103 | 94 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; | 132 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; |
142 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 133 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
143 return_value.Set(resolver->GetPromise()); | 134 return_value.Set(resolver->GetPromise()); |
144 | 135 |
145 if (args.Length() < 1) { | 136 if (args.Length() < 1) { |
146 thrower.TypeError("Argument 0 must be a buffer source"); | 137 thrower.TypeError("Argument 0 must be a buffer source"); |
147 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); | 138 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); |
148 return; | 139 return; |
149 } | 140 } |
150 i::MaybeHandle<i::JSObject> module_obj = | 141 i::MaybeHandle<i::JSObject> module_obj = |
151 CreateModuleObject(isolate, args[0], &thrower, true); | 142 CreateModuleObject(isolate, args[0], &thrower); |
152 | 143 |
153 if (thrower.error()) { | 144 if (thrower.error()) { |
154 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); | 145 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); |
155 } else { | 146 } else { |
156 resolver->Resolve(context, Utils::ToLocal(module_obj.ToHandleChecked())); | 147 resolver->Resolve(context, Utils::ToLocal(module_obj.ToHandleChecked())); |
157 } | 148 } |
158 } | 149 } |
159 | 150 |
160 void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) { | 151 void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) { |
161 v8::Isolate* isolate = args.GetIsolate(); | 152 v8::Isolate* isolate = args.GetIsolate(); |
(...skipping 20 matching lines...) Expand all Loading... |
182 HandleScope scope(isolate); | 173 HandleScope scope(isolate); |
183 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), | 174 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), |
184 "WebAssembly.Module()"); | 175 "WebAssembly.Module()"); |
185 | 176 |
186 if (args.Length() < 1) { | 177 if (args.Length() < 1) { |
187 thrower.TypeError("Argument 0 must be a buffer source"); | 178 thrower.TypeError("Argument 0 must be a buffer source"); |
188 return; | 179 return; |
189 } | 180 } |
190 | 181 |
191 i::MaybeHandle<i::JSObject> module_obj = | 182 i::MaybeHandle<i::JSObject> module_obj = |
192 CreateModuleObject(isolate, args[0], &thrower, false); | 183 CreateModuleObject(isolate, args[0], &thrower); |
193 if (module_obj.is_null()) return; | 184 if (module_obj.is_null()) return; |
194 | 185 |
195 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 186 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
196 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); | 187 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); |
197 } | 188 } |
198 | 189 |
199 MaybeLocal<Value> InstantiateModuleImpl( | 190 MaybeLocal<Value> InstantiateModuleImpl( |
200 i::Isolate* i_isolate, i::Handle<i::WasmModuleObject> i_module_obj, | 191 i::Isolate* i_isolate, i::Handle<i::WasmModuleObject> i_module_obj, |
201 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower, | 192 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) { |
202 bool as_promise) { | |
203 // It so happens that in both the WebAssembly.instantiate, as well as | 193 // It so happens that in both the WebAssembly.instantiate, as well as |
204 // WebAssembly.Instance ctor, the positions of the ffi object and memory | 194 // WebAssembly.Instance ctor, the positions of the ffi object and memory |
205 // are the same. If that changes later, we refactor the consts into | 195 // are the same. If that changes later, we refactor the consts into |
206 // parameters. | 196 // parameters. |
207 static const int kFfiOffset = 1; | 197 static const int kFfiOffset = 1; |
208 | 198 |
209 MaybeLocal<Value> nothing; | 199 MaybeLocal<Value> nothing; |
210 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); | 200 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); |
211 // This is a first - level validation of the argument. If present, we only | 201 // This is a first - level validation of the argument. If present, we only |
212 // check its type. {Instantiate} will further check that if the module | 202 // check its type. {Instantiate} will further check that if the module |
213 // has imports, the argument must be present, as well as piecemeal | 203 // has imports, the argument must be present, as well as piecemeal |
214 // import satisfaction. | 204 // import satisfaction. |
215 if (args.Length() > kFfiOffset && !args[kFfiOffset]->IsUndefined()) { | 205 if (args.Length() > kFfiOffset && !args[kFfiOffset]->IsUndefined()) { |
216 if (!args[kFfiOffset]->IsObject()) { | 206 if (!args[kFfiOffset]->IsObject()) { |
217 thrower->TypeError("Argument %d must be an object", kFfiOffset); | 207 thrower->TypeError("Argument %d must be an object", kFfiOffset); |
218 return nothing; | 208 return nothing; |
219 } | 209 } |
220 Local<Object> obj = Local<Object>::Cast(args[kFfiOffset]); | 210 Local<Object> obj = Local<Object>::Cast(args[kFfiOffset]); |
221 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); | 211 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); |
222 } | 212 } |
223 AllowWasmInstantiateCallback allow_instantiate = | |
224 i_isolate->allow_wasm_instantiate_callback(); | |
225 if (allow_instantiate != nullptr && | |
226 !allow_instantiate(Local<WasmCompiledModule>::Cast(Utils::ToLocal( | |
227 i::Handle<i::JSObject>::cast(i_module_obj))), | |
228 Utils::ToLocal(ffi), as_promise)) { | |
229 thrower->RangeError( | |
230 "Wasm instantiation exceeds internal limits in this context for " | |
231 "provided arguments"); | |
232 return nothing; | |
233 } | |
234 | 213 |
235 i::MaybeHandle<i::JSObject> instance = | 214 i::MaybeHandle<i::JSObject> instance = |
236 i::wasm::WasmModule::Instantiate(i_isolate, thrower, i_module_obj, ffi); | 215 i::wasm::WasmModule::Instantiate(i_isolate, thrower, i_module_obj, ffi); |
237 if (instance.is_null()) { | 216 if (instance.is_null()) { |
238 if (!thrower->error()) | 217 if (!thrower->error()) |
239 thrower->RuntimeError("Could not instantiate module"); | 218 thrower->RuntimeError("Could not instantiate module"); |
240 return nothing; | 219 return nothing; |
241 } | 220 } |
242 DCHECK(!i_isolate->has_pending_exception()); | 221 DCHECK(!i_isolate->has_pending_exception()); |
243 return Utils::ToLocal(instance.ToHandleChecked()); | 222 return Utils::ToLocal(instance.ToHandleChecked()); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { | 309 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { |
331 HandleScope scope(args.GetIsolate()); | 310 HandleScope scope(args.GetIsolate()); |
332 v8::Isolate* isolate = args.GetIsolate(); | 311 v8::Isolate* isolate = args.GetIsolate(); |
333 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 312 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
334 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); | 313 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); |
335 | 314 |
336 auto maybe_module = GetFirstArgumentAsModule(args, &thrower); | 315 auto maybe_module = GetFirstArgumentAsModule(args, &thrower); |
337 | 316 |
338 if (!maybe_module.is_null()) { | 317 if (!maybe_module.is_null()) { |
339 MaybeLocal<Value> instance = InstantiateModuleImpl( | 318 MaybeLocal<Value> instance = InstantiateModuleImpl( |
340 i_isolate, maybe_module.ToHandleChecked(), args, &thrower, false); | 319 i_isolate, maybe_module.ToHandleChecked(), args, &thrower); |
341 | 320 |
342 if (instance.IsEmpty()) { | 321 if (instance.IsEmpty()) { |
343 DCHECK(thrower.error()); | 322 DCHECK(thrower.error()); |
344 return; | 323 return; |
345 } | 324 } |
346 args.GetReturnValue().Set(instance.ToLocalChecked()); | 325 args.GetReturnValue().Set(instance.ToLocalChecked()); |
347 } | 326 } |
348 } | 327 } |
349 | 328 |
350 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { | 329 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { |
(...skipping 24 matching lines...) Expand all Loading... |
375 thrower.TypeError( | 354 thrower.TypeError( |
376 "Argument 0 must be a buffer source or a WebAssembly.Module object"); | 355 "Argument 0 must be a buffer source or a WebAssembly.Module object"); |
377 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); | 356 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); |
378 return; | 357 return; |
379 } | 358 } |
380 bool want_pair = | 359 bool want_pair = |
381 !HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym())); | 360 !HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym())); |
382 i::Handle<i::WasmModuleObject> module_obj; | 361 i::Handle<i::WasmModuleObject> module_obj; |
383 if (want_pair) { | 362 if (want_pair) { |
384 i::MaybeHandle<i::WasmModuleObject> maybe_module_obj = | 363 i::MaybeHandle<i::WasmModuleObject> maybe_module_obj = |
385 CreateModuleObject(isolate, args[0], &thrower, true); | 364 CreateModuleObject(isolate, args[0], &thrower); |
386 if (!maybe_module_obj.ToHandle(&module_obj)) { | 365 if (!maybe_module_obj.ToHandle(&module_obj)) { |
387 DCHECK(thrower.error()); | 366 DCHECK(thrower.error()); |
388 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); | 367 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); |
389 return; | 368 return; |
390 } | 369 } |
391 } else { | 370 } else { |
392 module_obj = i::Handle<i::WasmModuleObject>::cast(first_arg); | 371 module_obj = i::Handle<i::WasmModuleObject>::cast(first_arg); |
393 } | 372 } |
394 DCHECK(!module_obj.is_null()); | 373 DCHECK(!module_obj.is_null()); |
395 MaybeLocal<Value> instance = | 374 MaybeLocal<Value> instance = |
396 InstantiateModuleImpl(i_isolate, module_obj, args, &thrower, true); | 375 InstantiateModuleImpl(i_isolate, module_obj, args, &thrower); |
397 if (instance.IsEmpty()) { | 376 if (instance.IsEmpty()) { |
398 DCHECK(thrower.error()); | 377 DCHECK(thrower.error()); |
399 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); | 378 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); |
400 } else { | 379 } else { |
401 DCHECK(!thrower.error()); | 380 DCHECK(!thrower.error()); |
402 Local<Value> retval; | 381 Local<Value> retval; |
403 if (want_pair) { | 382 if (want_pair) { |
404 i::Handle<i::JSFunction> object_function = i::Handle<i::JSFunction>( | 383 i::Handle<i::JSFunction> object_function = i::Handle<i::JSFunction>( |
405 i_isolate->native_context()->object_function(), i_isolate); | 384 i_isolate->native_context()->object_function(), i_isolate); |
406 | 385 |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); | 935 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); |
957 return HasBrand(value, symbol); | 936 return HasBrand(value, symbol); |
958 } | 937 } |
959 | 938 |
960 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { | 939 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { |
961 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); | 940 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); |
962 return HasBrand(value, symbol); | 941 return HasBrand(value, symbol); |
963 } | 942 } |
964 } // namespace internal | 943 } // namespace internal |
965 } // namespace v8 | 944 } // namespace v8 |
OLD | NEW |