| 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 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 " is above the upper bound %d", | 359 " is above the upper bound %d", |
| 360 number, upper_bound); | 360 number, upper_bound); |
| 361 return false; | 361 return false; |
| 362 } | 362 } |
| 363 *result = static_cast<int>(number); | 363 *result = static_cast<int>(number); |
| 364 return true; | 364 return true; |
| 365 } | 365 } |
| 366 return false; | 366 return false; |
| 367 } | 367 } |
| 368 | 368 |
| 369 const int max_table_size = 1 << 26; |
| 370 |
| 369 void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) { | 371 void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 370 v8::Isolate* isolate = args.GetIsolate(); | 372 v8::Isolate* isolate = args.GetIsolate(); |
| 371 HandleScope scope(isolate); | 373 HandleScope scope(isolate); |
| 372 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), | 374 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), |
| 373 "WebAssembly.Module()"); | 375 "WebAssembly.Module()"); |
| 374 if (args.Length() < 1 || !args[0]->IsObject()) { | 376 if (args.Length() < 1 || !args[0]->IsObject()) { |
| 375 thrower.TypeError("Argument 0 must be a table descriptor"); | 377 thrower.TypeError("Argument 0 must be a table descriptor"); |
| 376 return; | 378 return; |
| 377 } | 379 } |
| 378 Local<Context> context = isolate->GetCurrentContext(); | 380 Local<Context> context = isolate->GetCurrentContext(); |
| 379 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); | 381 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); |
| 380 // The descriptor's 'element'. | 382 // The descriptor's 'element'. |
| 381 { | 383 { |
| 382 v8::MaybeLocal<v8::Value> maybe = | 384 v8::MaybeLocal<v8::Value> maybe = |
| 383 descriptor->Get(context, v8_str(isolate, "element")); | 385 descriptor->Get(context, v8_str(isolate, "element")); |
| 384 v8::Local<v8::Value> value; | 386 v8::Local<v8::Value> value; |
| 385 if (!maybe.ToLocal(&value)) return; | 387 if (!maybe.ToLocal(&value)) return; |
| 386 v8::Local<v8::String> string; | 388 v8::Local<v8::String> string; |
| 387 if (!value->ToString(context).ToLocal(&string)) return; | 389 if (!value->ToString(context).ToLocal(&string)) return; |
| 388 bool equal; | 390 bool equal; |
| 389 if (!string->Equals(context, v8_str(isolate, "anyfunc")).To(&equal)) return; | 391 if (!string->Equals(context, v8_str(isolate, "anyfunc")).To(&equal)) return; |
| 390 if (!equal) { | 392 if (!equal) { |
| 391 thrower.TypeError("Descriptor property 'element' must be 'anyfunc'"); | 393 thrower.TypeError("Descriptor property 'element' must be 'anyfunc'"); |
| 392 return; | 394 return; |
| 393 } | 395 } |
| 394 } | 396 } |
| 395 const int max_table_size = 1 << 26; | |
| 396 // The descriptor's 'initial'. | 397 // The descriptor's 'initial'. |
| 397 int initial; | 398 int initial; |
| 398 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, | 399 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, |
| 399 v8_str(isolate, "initial"), &initial, 0, | 400 v8_str(isolate, "initial"), &initial, 0, |
| 400 max_table_size)) { | 401 max_table_size)) { |
| 401 return; | 402 return; |
| 402 } | 403 } |
| 403 // The descriptor's 'maximum'. | 404 // The descriptor's 'maximum'. |
| 404 int maximum = 0; | 405 int maximum = 0; |
| 405 Local<String> maximum_key = v8_str(isolate, "maximum"); | 406 Local<String> maximum_key = v8_str(isolate, "maximum"); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 | 505 |
| 505 void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { | 506 void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 506 v8::Isolate* isolate = args.GetIsolate(); | 507 v8::Isolate* isolate = args.GetIsolate(); |
| 507 Local<Context> context = isolate->GetCurrentContext(); | 508 Local<Context> context = isolate->GetCurrentContext(); |
| 508 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); | 509 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
| 509 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), | 510 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), |
| 510 i::Handle<i::Symbol>(i_context->wasm_table_sym()), | 511 i::Handle<i::Symbol>(i_context->wasm_table_sym()), |
| 511 "Receiver is not a WebAssembly.Table")) { | 512 "Receiver is not a WebAssembly.Table")) { |
| 512 return; | 513 return; |
| 513 } | 514 } |
| 514 // TODO(rossberg): grow table and update relevant instances. | 515 |
| 515 v8::Local<v8::Value> e = | 516 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 516 v8::Exception::TypeError(v8_str(isolate, "Table#grow unimplemented")); | 517 i::Handle<i::JSObject> receiver = |
| 517 isolate->ThrowException(e); | 518 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); |
| 519 i::Handle<i::FixedArray> old_array( |
| 520 i::FixedArray::cast( |
| 521 receiver->GetInternalField(kWasmTableArrayFieldIndex)), |
| 522 i_isolate); |
| 523 int old_size = old_array->length(); |
| 524 int64_t new_size64 = 0; |
| 525 if (args.Length() > 0 && !args[0]->IntegerValue(context).To(&new_size64)) { |
| 526 return; |
| 527 } |
| 528 new_size64 += old_size; |
| 529 |
| 530 i::Handle<i::Object> max_val( |
| 531 receiver->GetInternalField(kWasmTableMaximumFieldIndex), i_isolate); |
| 532 int max_size = |
| 533 max_val->IsSmi() ? i::Smi::cast(*max_val)->value() : max_table_size; |
| 534 if (new_size64 < old_size || new_size64 > max_size) { |
| 535 v8::Local<v8::Value> e = v8::Exception::RangeError( |
| 536 v8_str(isolate, new_size64 < old_size ? "trying to shrink table" |
| 537 : "maximum table size exceeded")); |
| 538 isolate->ThrowException(e); |
| 539 return; |
| 540 } |
| 541 int new_size = static_cast<int>(new_size64); |
| 542 |
| 543 if (new_size != old_size) { |
| 544 i::Handle<i::FixedArray> new_array = |
| 545 i_isolate->factory()->NewFixedArray(new_size); |
| 546 for (int i = 0; i < old_size; ++i) new_array->set(i, old_array->get(i)); |
| 547 i::Object* null = i_isolate->heap()->null_value(); |
| 548 for (int i = old_size; i < new_size; ++i) new_array->set(i, null); |
| 549 receiver->SetInternalField(kWasmTableArrayFieldIndex, *new_array); |
| 550 } |
| 551 |
| 552 // TODO(titzer): update relevant instances. |
| 518 } | 553 } |
| 519 | 554 |
| 520 void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) { | 555 void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 521 v8::Isolate* isolate = args.GetIsolate(); | 556 v8::Isolate* isolate = args.GetIsolate(); |
| 522 Local<Context> context = isolate->GetCurrentContext(); | 557 Local<Context> context = isolate->GetCurrentContext(); |
| 523 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); | 558 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
| 524 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), | 559 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), |
| 525 i::Handle<i::Symbol>(i_context->wasm_table_sym()), | 560 i::Handle<i::Symbol>(i_context->wasm_table_sym()), |
| 526 "Receiver is not a WebAssembly.Table")) { | 561 "Receiver is not a WebAssembly.Table")) { |
| 527 return; | 562 return; |
| 528 } | 563 } |
| 529 | 564 |
| 530 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 565 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 531 i::Handle<i::JSObject> receiver = | 566 i::Handle<i::JSObject> receiver = |
| 532 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); | 567 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); |
| 533 i::Handle<i::Object> array( | 568 i::Handle<i::Object> array( |
| 534 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate); | 569 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate); |
| 535 int i = 0; | 570 int i = 0; |
| 536 if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return; | 571 if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return; |
| 537 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 572 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
| 538 if (i >= 0 && i < i::Handle<i::FixedArray>::cast(array)->length()) { | 573 if (i < 0 || i >= i::Handle<i::FixedArray>::cast(array)->length()) { |
| 539 i::Handle<i::Object> value(i::Handle<i::FixedArray>::cast(array)->get(i), | 574 v8::Local<v8::Value> e = |
| 540 i_isolate); | 575 v8::Exception::RangeError(v8_str(isolate, "index out of bounds")); |
| 541 return_value.Set(Utils::ToLocal(value)); | 576 isolate->ThrowException(e); |
| 577 return; |
| 542 } | 578 } |
| 579 |
| 580 i::Handle<i::Object> value(i::Handle<i::FixedArray>::cast(array)->get(i), |
| 581 i_isolate); |
| 582 return_value.Set(Utils::ToLocal(value)); |
| 543 } | 583 } |
| 544 | 584 |
| 545 void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) { | 585 void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 546 v8::Isolate* isolate = args.GetIsolate(); | 586 v8::Isolate* isolate = args.GetIsolate(); |
| 587 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 547 Local<Context> context = isolate->GetCurrentContext(); | 588 Local<Context> context = isolate->GetCurrentContext(); |
| 548 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); | 589 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
| 549 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), | 590 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), |
| 550 i::Handle<i::Symbol>(i_context->wasm_table_sym()), | 591 i::Handle<i::Symbol>(i_context->wasm_table_sym()), |
| 551 "Receiver is not a WebAssembly.Table")) { | 592 "Receiver is not a WebAssembly.Table")) { |
| 552 return; | 593 return; |
| 553 } | 594 } |
| 554 if (args.Length() < 2 || | 595 if (args.Length() < 2) { |
| 555 !(args[1]->IsNull() || | |
| 556 (args[1]->IsObject() && v8::Object::Cast(*args[1])->IsCallable()))) { | |
| 557 v8::Local<v8::Value> e = v8::Exception::TypeError( | 596 v8::Local<v8::Value> e = v8::Exception::TypeError( |
| 558 v8_str(isolate, "Argument 1 must be null or a function")); | 597 v8_str(isolate, "Argument 1 must be null or a function")); |
| 559 isolate->ThrowException(e); | 598 isolate->ThrowException(e); |
| 560 return; | 599 return; |
| 561 } | 600 } |
| 601 i::Handle<i::Object> value = Utils::OpenHandle(*args[1]); |
| 602 if (!value->IsNull(i_isolate) && |
| 603 (!value->IsJSFunction() || |
| 604 i::Handle<i::JSFunction>::cast(value)->code()->kind() != |
| 605 i::Code::JS_TO_WASM_FUNCTION)) { |
| 606 v8::Local<v8::Value> e = v8::Exception::TypeError( |
| 607 v8_str(isolate, "Argument 1 must be null or a WebAssembly function")); |
| 608 isolate->ThrowException(e); |
| 609 return; |
| 610 } |
| 562 | 611 |
| 563 // TODO(rossberg): set table element and update relevent instances. | 612 i::Handle<i::JSObject> receiver = |
| 564 v8::Local<v8::Value> e = | 613 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); |
| 565 v8::Exception::TypeError(v8_str(isolate, "Table#set unimplemented")); | 614 i::Handle<i::Object> array( |
| 566 isolate->ThrowException(e); | 615 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate); |
| 616 int i; |
| 617 if (!args[0]->Int32Value(context).To(&i)) return; |
| 618 if (i < 0 || i >= i::Handle<i::FixedArray>::cast(array)->length()) { |
| 619 v8::Local<v8::Value> e = |
| 620 v8::Exception::RangeError(v8_str(isolate, "index out of bounds")); |
| 621 isolate->ThrowException(e); |
| 622 return; |
| 623 } |
| 624 |
| 625 i::Handle<i::FixedArray>::cast(array)->set(i, *value); |
| 626 |
| 627 // TODO(titzer): update relevant instances. |
| 567 } | 628 } |
| 568 | 629 |
| 569 void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { | 630 void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 570 v8::Isolate* isolate = args.GetIsolate(); | 631 v8::Isolate* isolate = args.GetIsolate(); |
| 571 Local<Context> context = isolate->GetCurrentContext(); | 632 Local<Context> context = isolate->GetCurrentContext(); |
| 572 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); | 633 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
| 573 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), | 634 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), |
| 574 i::Handle<i::Symbol>(i_context->wasm_memory_sym()), | 635 i::Handle<i::Symbol>(i_context->wasm_memory_sym()), |
| 575 "Receiver is not a WebAssembly.Memory")) { | 636 "Receiver is not a WebAssembly.Memory")) { |
| 576 return; | 637 return; |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 850 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate, | 911 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate, |
| 851 Handle<Object> value) { | 912 Handle<Object> value) { |
| 852 DCHECK(IsWasmMemoryObject(isolate, value)); | 913 DCHECK(IsWasmMemoryObject(isolate, value)); |
| 853 Handle<Object> buf( | 914 Handle<Object> buf( |
| 854 JSObject::cast(*value)->GetInternalField(kWasmMemoryBufferFieldIndex), | 915 JSObject::cast(*value)->GetInternalField(kWasmMemoryBufferFieldIndex), |
| 855 isolate); | 916 isolate); |
| 856 return Handle<JSArrayBuffer>::cast(buf); | 917 return Handle<JSArrayBuffer>::cast(buf); |
| 857 } | 918 } |
| 858 } // namespace internal | 919 } // namespace internal |
| 859 } // namespace v8 | 920 } // namespace v8 |
| OLD | NEW |