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