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 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 305 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
306 return_value.Set(Utils::ToLocal(instance.ToHandleChecked())); | 306 return_value.Set(Utils::ToLocal(instance.ToHandleChecked())); |
307 } | 307 } |
308 | 308 |
309 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, | 309 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, |
310 Local<Context> context, Local<v8::Object> object, | 310 Local<Context> context, Local<v8::Object> object, |
311 Local<String> property, int* result, int lower_bound, | 311 Local<String> property, int* result, int lower_bound, |
312 int upper_bound) { | 312 int upper_bound) { |
313 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property); | 313 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property); |
314 v8::Local<v8::Value> value; | 314 v8::Local<v8::Value> value; |
315 if (maybe.ToLocal(&value) && !value->IsUndefined()) { | 315 if (maybe.ToLocal(&value)) { |
316 int64_t number; | 316 int64_t number; |
317 if (!value->IntegerValue(context).To(&number)) return false; | 317 if (!value->IntegerValue(context).To(&number)) return false; |
318 if (number < static_cast<int64_t>(lower_bound)) { | 318 if (number < static_cast<int64_t>(lower_bound)) { |
319 thrower->RangeError("Property value %" PRId64 | 319 thrower->RangeError("Property value %" PRId64 |
320 " is below the lower bound %d", | 320 " is below the lower bound %d", |
321 number, lower_bound); | 321 number, lower_bound); |
322 return false; | 322 return false; |
323 } | 323 } |
324 if (number > static_cast<int64_t>(std::numeric_limits<int>::max())) { | 324 if (number > static_cast<int64_t>(upper_bound)) { |
325 thrower->RangeError("Property value %" PRId64 " is out of integer range", | |
326 number); | |
327 return false; | |
328 } | |
329 int num = static_cast<int>(number); | |
330 if (num > upper_bound) { | |
331 thrower->RangeError("Property value %" PRId64 | 325 thrower->RangeError("Property value %" PRId64 |
332 " is above the upper bound %d", | 326 " is above the upper bound %d", |
333 number, upper_bound); | 327 number, upper_bound); |
334 return false; | 328 return false; |
335 } | 329 } |
336 *result = num; | 330 *result = static_cast<int>(number); |
337 return true; | 331 return true; |
338 } | 332 } |
339 return false; | 333 return false; |
340 } | 334 } |
341 | 335 |
342 void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) { | 336 void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) { |
343 v8::Isolate* isolate = args.GetIsolate(); | 337 v8::Isolate* isolate = args.GetIsolate(); |
344 HandleScope scope(isolate); | 338 HandleScope scope(isolate); |
345 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), | 339 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), |
346 "WebAssembly.Module()"); | 340 "WebAssembly.Module()"); |
(...skipping 21 matching lines...) Expand all Loading... |
368 const int max_table_size = 1 << 26; | 362 const int max_table_size = 1 << 26; |
369 // The descriptor's 'initial'. | 363 // The descriptor's 'initial'. |
370 int initial; | 364 int initial; |
371 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, | 365 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, |
372 v8_str(isolate, "initial"), &initial, 0, | 366 v8_str(isolate, "initial"), &initial, 0, |
373 max_table_size)) { | 367 max_table_size)) { |
374 return; | 368 return; |
375 } | 369 } |
376 // The descriptor's 'maximum'. | 370 // The descriptor's 'maximum'. |
377 int maximum; | 371 int maximum; |
378 bool has_maximum = true; | 372 Local<String> maximum_key = v8_str(isolate, "maximum"); |
379 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, | 373 Maybe<bool> has_maximum = descriptor->Has(context, maximum_key); |
380 v8_str(isolate, "maximum"), &maximum, initial, | 374 |
381 max_table_size)) { | 375 if (has_maximum.IsNothing()) { |
382 if (reinterpret_cast<i::Isolate*>(isolate)->has_pending_exception() || | 376 // There has been an exception, just return. |
383 thrower.error()) { | 377 return; |
| 378 } |
| 379 if (has_maximum.FromJust()) { |
| 380 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key, |
| 381 &maximum, initial, max_table_size)) { |
384 return; | 382 return; |
385 } else { | |
386 // There was no error, the property just does not exist. | |
387 has_maximum = false; | |
388 } | 383 } |
389 } | 384 } |
390 | 385 |
391 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 386 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
392 i::Handle<i::JSFunction> table_cons( | 387 i::Handle<i::JSFunction> table_cons( |
393 i_isolate->native_context()->wasm_table_constructor()); | 388 i_isolate->native_context()->wasm_table_constructor()); |
394 i::Handle<i::JSObject> table_obj = | 389 i::Handle<i::JSObject> table_obj = |
395 i_isolate->factory()->NewJSObject(table_cons); | 390 i_isolate->factory()->NewJSObject(table_cons); |
396 i::Handle<i::FixedArray> fixed_array = | 391 i::Handle<i::FixedArray> fixed_array = |
397 i_isolate->factory()->NewFixedArray(initial); | 392 i_isolate->factory()->NewFixedArray(initial); |
398 i::Object* null = i_isolate->heap()->null_value(); | 393 i::Object* null = i_isolate->heap()->null_value(); |
399 for (int i = 0; i < initial; ++i) fixed_array->set(i, null); | 394 for (int i = 0; i < initial; ++i) fixed_array->set(i, null); |
400 table_obj->SetInternalField(0, *fixed_array); | 395 table_obj->SetInternalField(0, *fixed_array); |
401 table_obj->SetInternalField( | 396 table_obj->SetInternalField( |
402 1, has_maximum | 397 1, has_maximum.FromJust() |
403 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) | 398 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) |
404 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); | 399 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); |
405 i::Handle<i::Symbol> table_sym(i_isolate->native_context()->wasm_table_sym()); | 400 i::Handle<i::Symbol> table_sym(i_isolate->native_context()->wasm_table_sym()); |
406 i::Object::SetProperty(table_obj, table_sym, table_obj, i::STRICT).Check(); | 401 i::Object::SetProperty(table_obj, table_sym, table_obj, i::STRICT).Check(); |
407 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 402 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
408 return_value.Set(Utils::ToLocal(table_obj)); | 403 return_value.Set(Utils::ToLocal(table_obj)); |
409 } | 404 } |
410 void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { | 405 void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { |
411 v8::Isolate* isolate = args.GetIsolate(); | 406 v8::Isolate* isolate = args.GetIsolate(); |
412 HandleScope scope(isolate); | 407 HandleScope scope(isolate); |
413 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), | 408 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), |
414 "WebAssembly.Module()"); | 409 "WebAssembly.Module()"); |
415 if (args.Length() < 1 || !args[0]->IsObject()) { | 410 if (args.Length() < 1 || !args[0]->IsObject()) { |
416 thrower.TypeError("Argument 0 must be a table descriptor"); | 411 thrower.TypeError("Argument 0 must be a table descriptor"); |
417 return; | 412 return; |
418 } | 413 } |
419 Local<Context> context = isolate->GetCurrentContext(); | 414 Local<Context> context = isolate->GetCurrentContext(); |
420 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); | 415 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); |
421 // The descriptor's 'initial'. | 416 // The descriptor's 'initial'. |
422 int initial; | 417 int initial; |
423 GetIntegerProperty(isolate, &thrower, context, descriptor, | 418 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, |
424 v8_str(isolate, "initial"), &initial, 0, 65536); | 419 v8_str(isolate, "initial"), &initial, 0, 65536)) { |
| 420 return; |
| 421 } |
425 // The descriptor's 'maximum'. | 422 // The descriptor's 'maximum'. |
426 int maximum; | 423 int maximum; |
427 bool has_maximum = true; | 424 Local<String> maximum_key = v8_str(isolate, "maximum"); |
428 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, | 425 Maybe<bool> has_maximum = descriptor->Has(context, maximum_key); |
429 v8_str(isolate, "maximum"), &maximum, initial, | 426 |
430 65536)) { | 427 if (has_maximum.IsNothing()) { |
431 if (reinterpret_cast<i::Isolate*>(isolate)->has_pending_exception() || | 428 // There has been an exception, just return. |
432 thrower.error()) { | 429 return; |
| 430 } |
| 431 if (has_maximum.FromJust()) { |
| 432 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key, |
| 433 &maximum, initial, 65536)) { |
433 return; | 434 return; |
434 } else { | |
435 // There was no error, the property just does not exist. | |
436 has_maximum = false; | |
437 } | 435 } |
438 } | 436 } |
439 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 437 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
440 i::Handle<i::JSFunction> memory_cons( | 438 i::Handle<i::JSFunction> memory_cons( |
441 i_isolate->native_context()->wasm_memory_constructor()); | 439 i_isolate->native_context()->wasm_memory_constructor()); |
442 i::Handle<i::JSObject> memory_obj = | 440 i::Handle<i::JSObject> memory_obj = |
443 i_isolate->factory()->NewJSObject(memory_cons); | 441 i_isolate->factory()->NewJSObject(memory_cons); |
444 i::Handle<i::JSArrayBuffer> buffer = | 442 i::Handle<i::JSArrayBuffer> buffer = |
445 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared); | 443 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared); |
446 size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) * | 444 size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) * |
447 static_cast<size_t>(initial); | 445 static_cast<size_t>(initial); |
448 i::JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, size); | 446 i::JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, size); |
449 memory_obj->SetInternalField(0, *buffer); | 447 memory_obj->SetInternalField(0, *buffer); |
450 memory_obj->SetInternalField( | 448 memory_obj->SetInternalField( |
451 1, has_maximum | 449 1, has_maximum.FromJust() |
452 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) | 450 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) |
453 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); | 451 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); |
454 i::Handle<i::Symbol> memory_sym( | 452 i::Handle<i::Symbol> memory_sym( |
455 i_isolate->native_context()->wasm_memory_sym()); | 453 i_isolate->native_context()->wasm_memory_sym()); |
456 i::Object::SetProperty(memory_obj, memory_sym, memory_obj, i::STRICT).Check(); | 454 i::Object::SetProperty(memory_obj, memory_sym, memory_obj, i::STRICT).Check(); |
457 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 455 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
458 return_value.Set(Utils::ToLocal(memory_obj)); | 456 return_value.Set(Utils::ToLocal(memory_obj)); |
459 } | 457 } |
460 void WebAssemblyTableGetLength( | 458 void WebAssemblyTableGetLength( |
461 const v8::FunctionCallbackInfo<v8::Value>& args) { | 459 const v8::FunctionCallbackInfo<v8::Value>& args) { |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 int unused_property_fields = in_object_properties - pre_allocated; | 686 int unused_property_fields = in_object_properties - pre_allocated; |
689 Handle<Map> map = Map::CopyInitialMap( | 687 Handle<Map> map = Map::CopyInitialMap( |
690 prev_map, instance_size, in_object_properties, unused_property_fields); | 688 prev_map, instance_size, in_object_properties, unused_property_fields); |
691 | 689 |
692 context->set_wasm_function_map(*map); | 690 context->set_wasm_function_map(*map); |
693 } | 691 } |
694 } | 692 } |
695 | 693 |
696 } // namespace internal | 694 } // namespace internal |
697 } // namespace v8 | 695 } // namespace v8 |
OLD | NEW |