Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: src/wasm/wasm-js.cc

Issue 2414053002: [wasm] Implement Table#set and Table#grow (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/mjsunit/wasm/table.js » ('j') | test/mjsunit/wasm/table.js » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 " is above the upper bound %d", 358 " is above the upper bound %d",
359 number, upper_bound); 359 number, upper_bound);
360 return false; 360 return false;
361 } 361 }
362 *result = static_cast<int>(number); 362 *result = static_cast<int>(number);
363 return true; 363 return true;
364 } 364 }
365 return false; 365 return false;
366 } 366 }
367 367
368 const int max_table_size = 1 << 26;
369
368 void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) { 370 void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
369 v8::Isolate* isolate = args.GetIsolate(); 371 v8::Isolate* isolate = args.GetIsolate();
370 HandleScope scope(isolate); 372 HandleScope scope(isolate);
371 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 373 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
372 "WebAssembly.Module()"); 374 "WebAssembly.Module()");
373 if (args.Length() < 1 || !args[0]->IsObject()) { 375 if (args.Length() < 1 || !args[0]->IsObject()) {
374 thrower.TypeError("Argument 0 must be a table descriptor"); 376 thrower.TypeError("Argument 0 must be a table descriptor");
375 return; 377 return;
376 } 378 }
377 Local<Context> context = isolate->GetCurrentContext(); 379 Local<Context> context = isolate->GetCurrentContext();
378 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); 380 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked();
379 // The descriptor's 'element'. 381 // The descriptor's 'element'.
380 { 382 {
381 v8::MaybeLocal<v8::Value> maybe = 383 v8::MaybeLocal<v8::Value> maybe =
382 descriptor->Get(context, v8_str(isolate, "element")); 384 descriptor->Get(context, v8_str(isolate, "element"));
383 v8::Local<v8::Value> value; 385 v8::Local<v8::Value> value;
384 if (!maybe.ToLocal(&value)) return; 386 if (!maybe.ToLocal(&value)) return;
385 v8::Local<v8::String> string; 387 v8::Local<v8::String> string;
386 if (!value->ToString(context).ToLocal(&string)) return; 388 if (!value->ToString(context).ToLocal(&string)) return;
387 bool equal; 389 bool equal;
388 if (!string->Equals(context, v8_str(isolate, "anyfunc")).To(&equal)) return; 390 if (!string->Equals(context, v8_str(isolate, "anyfunc")).To(&equal)) return;
389 if (!equal) { 391 if (!equal) {
390 thrower.TypeError("Descriptor property 'element' must be 'anyfunc'"); 392 thrower.TypeError("Descriptor property 'element' must be 'anyfunc'");
391 return; 393 return;
392 } 394 }
393 } 395 }
394 const int max_table_size = 1 << 26;
395 // The descriptor's 'initial'. 396 // The descriptor's 'initial'.
396 int initial; 397 int initial;
397 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, 398 if (!GetIntegerProperty(isolate, &thrower, context, descriptor,
398 v8_str(isolate, "initial"), &initial, 0, 399 v8_str(isolate, "initial"), &initial, 0,
399 max_table_size)) { 400 max_table_size)) {
400 return; 401 return;
401 } 402 }
402 // The descriptor's 'maximum'. 403 // The descriptor's 'maximum'.
403 int maximum = 0; 404 int maximum = 0;
404 Local<String> maximum_key = v8_str(isolate, "maximum"); 405 Local<String> maximum_key = v8_str(isolate, "maximum");
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 503
503 void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { 504 void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
504 v8::Isolate* isolate = args.GetIsolate(); 505 v8::Isolate* isolate = args.GetIsolate();
505 Local<Context> context = isolate->GetCurrentContext(); 506 Local<Context> context = isolate->GetCurrentContext();
506 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 507 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
507 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), 508 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
508 i::Handle<i::Symbol>(i_context->wasm_table_sym()), 509 i::Handle<i::Symbol>(i_context->wasm_table_sym()),
509 "Receiver is not a WebAssembly.Table")) { 510 "Receiver is not a WebAssembly.Table")) {
510 return; 511 return;
511 } 512 }
512 // TODO(rossberg): grow table and update relevant instances. 513
513 v8::Local<v8::Value> e = 514 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
514 v8::Exception::TypeError(v8_str(isolate, "Table#grow unimplemented")); 515 i::Handle<i::JSObject> receiver =
515 isolate->ThrowException(e); 516 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This()));
517 i::Handle<i::FixedArray> old_array(
518 i::FixedArray::cast(
519 receiver->GetInternalField(kWasmTableArrayFieldIndex)),
520 i_isolate);
521 int64_t old_size = old_array->length();
522 int64_t new_size = 0;
523 if (args.Length() > 0 && !args[0]->IntegerValue(context).To(&new_size)) {
524 return;
525 }
526
527 i::Handle<i::Object> max_val(
528 receiver->GetInternalField(kWasmTableMaximumFieldIndex), i_isolate);
529 int64_t max_size =
530 max_val->IsSmi() ? i::Smi::cast(*max_val)->value() : max_table_size;
531 if (new_size < old_size || new_size > max_size) {
532 v8::Local<v8::Value> e = v8::Exception::RangeError(
533 v8_str(isolate, new_size < old_size
534 ? "trying to shrink table"
535 : "maximum table size exceeded"));
536 isolate->ThrowException(e);
537 return;
538 }
539
540 if (new_size != old_size) {
541 i::Handle<i::FixedArray> new_array =
542 i_isolate->factory()->NewFixedArray(new_size);
543 for (int i = 0; i < old_size; ++i) new_array->set(i, old_array->get(i));
544 i::Object* null = i_isolate->heap()->null_value();
545 for (int i = old_size; i < new_size; ++i) new_array->set(i, null);
546 receiver->SetInternalField(kWasmTableArrayFieldIndex, *new_array);
547 }
548
549 // TODO(titzer): update relevant instances.
516 } 550 }
517 551
518 void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) { 552 void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
519 v8::Isolate* isolate = args.GetIsolate(); 553 v8::Isolate* isolate = args.GetIsolate();
520 Local<Context> context = isolate->GetCurrentContext(); 554 Local<Context> context = isolate->GetCurrentContext();
521 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 555 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
522 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), 556 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
523 i::Handle<i::Symbol>(i_context->wasm_table_sym()), 557 i::Handle<i::Symbol>(i_context->wasm_table_sym()),
524 "Receiver is not a WebAssembly.Table")) { 558 "Receiver is not a WebAssembly.Table")) {
525 return; 559 return;
526 } 560 }
527 561
528 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 562 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
529 i::Handle<i::JSObject> receiver = 563 i::Handle<i::JSObject> receiver =
530 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); 564 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This()));
531 i::Handle<i::Object> array( 565 i::Handle<i::Object> array(
532 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate); 566 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate);
533 int i = 0; 567 int i = 0;
534 if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return; 568 if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return;
535 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 569 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
536 if (i >= 0 && i < i::Handle<i::FixedArray>::cast(array)->length()) { 570 if (i >= 0 && i < i::Handle<i::FixedArray>::cast(array)->length()) {
537 i::Handle<i::Object> value( 571 i::Handle<i::Object> value(
538 i::Handle<i::FixedArray>::cast(array)->get(i), i_isolate); 572 i::Handle<i::FixedArray>::cast(array)->get(i), i_isolate);
539 return_value.Set(Utils::ToLocal(value)); 573 return_value.Set(Utils::ToLocal(value));
540 } 574 }
541 } 575 }
542 576
543 void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) { 577 void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
544 v8::Isolate* isolate = args.GetIsolate(); 578 v8::Isolate* isolate = args.GetIsolate();
579 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
545 Local<Context> context = isolate->GetCurrentContext(); 580 Local<Context> context = isolate->GetCurrentContext();
546 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 581 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
547 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), 582 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
548 i::Handle<i::Symbol>(i_context->wasm_table_sym()), 583 i::Handle<i::Symbol>(i_context->wasm_table_sym()),
549 "Receiver is not a WebAssembly.Table")) { 584 "Receiver is not a WebAssembly.Table")) {
550 return; 585 return;
551 } 586 }
552 if (args.Length() < 2 || 587 if (args.Length() < 2) {
553 !(args[1]->IsNull() ||
554 (args[1]->IsObject() && v8::Object::Cast(*args[1])->IsCallable()))) {
555 v8::Local<v8::Value> e = v8::Exception::TypeError( 588 v8::Local<v8::Value> e = v8::Exception::TypeError(
556 v8_str(isolate, "Argument 1 must be null or a function")); 589 v8_str(isolate, "Argument 1 must be null or a function"));
557 isolate->ThrowException(e); 590 isolate->ThrowException(e);
558 return; 591 return;
559 } 592 }
593 i::Handle<i::Object> value = Utils::OpenHandle(*args[1]);
594 if (!value->IsNull(i_isolate) &&
595 (!value->IsJSFunction() ||
596 i::Handle<i::JSFunction>::cast(value)->code()->kind()
597 != i::Code::JS_TO_WASM_FUNCTION)) {
598 v8::Local<v8::Value> e = v8::Exception::TypeError(
599 v8_str(isolate, "Argument 1 must be null or a WebAssembly function"));
600 isolate->ThrowException(e);
601 return;
602 }
560 603
561 // TODO(rossberg): set table element and update relevent instances. 604 i::Handle<i::JSObject> receiver =
562 v8::Local<v8::Value> e = 605 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This()));
563 v8::Exception::TypeError(v8_str(isolate, "Table#set unimplemented")); 606 i::Handle<i::Object> array(
564 isolate->ThrowException(e); 607 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate);
608 int i;
609 if (!args[0]->Int32Value(context).To(&i)) return;
610 if (i >= 0 && i < i::Handle<i::FixedArray>::cast(array)->length()) {
611 i::Handle<i::FixedArray>::cast(array)->set(i, *value);
612 }
613
614 // TODO(titzer): update relevant instances.
565 } 615 }
566 616
567 void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { 617 void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
568 v8::Isolate* isolate = args.GetIsolate(); 618 v8::Isolate* isolate = args.GetIsolate();
569 Local<Context> context = isolate->GetCurrentContext(); 619 Local<Context> context = isolate->GetCurrentContext();
570 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 620 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
571 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), 621 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
572 i::Handle<i::Symbol>(i_context->wasm_memory_sym()), 622 i::Handle<i::Symbol>(i_context->wasm_memory_sym()),
573 "Receiver is not a WebAssembly.Memory")) { 623 "Receiver is not a WebAssembly.Memory")) {
574 return; 624 return;
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate, 886 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate,
837 Handle<Object> value) { 887 Handle<Object> value) {
838 DCHECK(IsWasmMemoryObject(isolate, value)); 888 DCHECK(IsWasmMemoryObject(isolate, value));
839 Handle<Object> buf( 889 Handle<Object> buf(
840 JSObject::cast(*value)->GetInternalField(kWasmMemoryBufferFieldIndex), 890 JSObject::cast(*value)->GetInternalField(kWasmMemoryBufferFieldIndex),
841 isolate); 891 isolate);
842 return Handle<JSArrayBuffer>::cast(buf); 892 return Handle<JSArrayBuffer>::cast(buf);
843 } 893 }
844 } // namespace internal 894 } // namespace internal
845 } // namespace v8 895 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/wasm/table.js » ('j') | test/mjsunit/wasm/table.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698