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

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

Issue 2411963003: Implement Table#length and Table#get (Closed)
Patch Set: Git format nonsense 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') | no next file with comments »
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 10 matching lines...) Expand all
21 #include "src/wasm/wasm-module.h" 21 #include "src/wasm/wasm-module.h"
22 #include "src/wasm/wasm-result.h" 22 #include "src/wasm/wasm-result.h"
23 23
24 typedef uint8_t byte; 24 typedef uint8_t byte;
25 25
26 using v8::internal::wasm::ErrorThrower; 26 using v8::internal::wasm::ErrorThrower;
27 27
28 namespace v8 { 28 namespace v8 {
29 29
30 static const int kWasmMemoryBufferFieldIndex = 0; 30 static const int kWasmMemoryBufferFieldIndex = 0;
31 static const int kWasmMemoryMaximumFieldIndex = 1;
32 static const int kWasmTableArrayFieldIndex = 0;
33 static const int kWasmTableMaximumFieldIndex = 1;
31 34
32 namespace { 35 namespace {
33 i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) { 36 i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) {
34 return isolate->factory()->NewStringFromAsciiChecked(str); 37 return isolate->factory()->NewStringFromAsciiChecked(str);
35 } 38 }
36 Local<String> v8_str(Isolate* isolate, const char* str) { 39 Local<String> v8_str(Isolate* isolate, const char* str) {
37 return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str)); 40 return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str));
38 } 41 }
39 42
40 struct RawBuffer { 43 struct RawBuffer {
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 306
304 Local<Context> context = isolate->GetCurrentContext(); 307 Local<Context> context = isolate->GetCurrentContext();
305 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 308 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
306 if (!BrandCheck(isolate, Utils::OpenHandle(*args[0]), 309 if (!BrandCheck(isolate, Utils::OpenHandle(*args[0]),
307 i::Handle<i::Symbol>(i_context->wasm_module_sym()), 310 i::Handle<i::Symbol>(i_context->wasm_module_sym()),
308 "Argument 0 must be a WebAssembly.Module")) { 311 "Argument 0 must be a WebAssembly.Module")) {
309 return; 312 return;
310 } 313 }
311 314
312 Local<Object> obj = Local<Object>::Cast(args[0]); 315 Local<Object> obj = Local<Object>::Cast(args[0]);
313 316 i::Handle<i::JSObject> i_obj =
314 i::Handle<i::JSObject> module_obj =
315 i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj)); 317 i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj));
316 if (module_obj->GetInternalFieldCount() < 1 ||
317 !module_obj->GetInternalField(0)->IsFixedArray()) {
318 thrower.TypeError("Argument 0 is an invalid WebAssembly.Module");
319 return;
320 }
321 318
322 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); 319 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null();
323 if (args.Length() > 1 && args[1]->IsObject()) { 320 if (args.Length() > 1 && args[1]->IsObject()) {
324 Local<Object> obj = Local<Object>::Cast(args[1]); 321 Local<Object> obj = Local<Object>::Cast(args[1]);
325 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); 322 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
326 } 323 }
327 324
328 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); 325 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null();
329 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { 326 if (args.Length() > 2 && args[2]->IsArrayBuffer()) {
330 Local<Object> obj = Local<Object>::Cast(args[2]); 327 Local<Object> obj = Local<Object>::Cast(args[2]);
331 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); 328 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj);
332 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); 329 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj));
333 } 330 }
334 i::MaybeHandle<i::JSObject> instance = i::wasm::WasmModule::Instantiate( 331 i::MaybeHandle<i::JSObject> instance =
335 i_isolate, &thrower, module_obj, ffi, memory); 332 i::wasm::WasmModule::Instantiate(i_isolate, &thrower, i_obj, ffi, memory);
336 if (instance.is_null()) { 333 if (instance.is_null()) {
337 if (!thrower.error()) thrower.Error("Could not instantiate module"); 334 if (!thrower.error()) thrower.Error("Could not instantiate module");
338 return; 335 return;
339 } 336 }
340 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 337 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
341 return_value.Set(Utils::ToLocal(instance.ToHandleChecked())); 338 return_value.Set(Utils::ToLocal(instance.ToHandleChecked()));
342 } 339 }
343 340
344 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, 341 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
345 Local<Context> context, Local<v8::Object> object, 342 Local<Context> context, Local<v8::Object> object,
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 417
421 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 418 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
422 i::Handle<i::JSFunction> table_ctor( 419 i::Handle<i::JSFunction> table_ctor(
423 i_isolate->native_context()->wasm_table_constructor()); 420 i_isolate->native_context()->wasm_table_constructor());
424 i::Handle<i::JSObject> table_obj = 421 i::Handle<i::JSObject> table_obj =
425 i_isolate->factory()->NewJSObject(table_ctor); 422 i_isolate->factory()->NewJSObject(table_ctor);
426 i::Handle<i::FixedArray> fixed_array = 423 i::Handle<i::FixedArray> fixed_array =
427 i_isolate->factory()->NewFixedArray(initial); 424 i_isolate->factory()->NewFixedArray(initial);
428 i::Object* null = i_isolate->heap()->null_value(); 425 i::Object* null = i_isolate->heap()->null_value();
429 for (int i = 0; i < initial; ++i) fixed_array->set(i, null); 426 for (int i = 0; i < initial; ++i) fixed_array->set(i, null);
430 table_obj->SetInternalField(0, *fixed_array); 427 table_obj->SetInternalField(kWasmTableArrayFieldIndex, *fixed_array);
431 table_obj->SetInternalField( 428 table_obj->SetInternalField(
432 1, has_maximum.FromJust() 429 kWasmTableMaximumFieldIndex,
433 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) 430 has_maximum.FromJust()
434 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); 431 ? static_cast<i::Object*>(i::Smi::FromInt(maximum))
432 : static_cast<i::Object*>(i_isolate->heap()->undefined_value()));
435 i::Handle<i::Symbol> table_sym(i_isolate->native_context()->wasm_table_sym()); 433 i::Handle<i::Symbol> table_sym(i_isolate->native_context()->wasm_table_sym());
436 i::Object::SetProperty(table_obj, table_sym, table_obj, i::STRICT).Check(); 434 i::Object::SetProperty(table_obj, table_sym, table_obj, i::STRICT).Check();
437 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 435 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
438 return_value.Set(Utils::ToLocal(table_obj)); 436 return_value.Set(Utils::ToLocal(table_obj));
439 } 437 }
440 438
441 void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { 439 void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
442 v8::Isolate* isolate = args.GetIsolate(); 440 v8::Isolate* isolate = args.GetIsolate();
443 HandleScope scope(isolate); 441 HandleScope scope(isolate);
444 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 442 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
445 "WebAssembly.Module()"); 443 "WebAssembly.Module()");
446 if (args.Length() < 1 || !args[0]->IsObject()) { 444 if (args.Length() < 1 || !args[0]->IsObject()) {
447 thrower.TypeError("Argument 0 must be a table descriptor"); 445 thrower.TypeError("Argument 0 must be a memory descriptor");
448 return; 446 return;
449 } 447 }
450 Local<Context> context = isolate->GetCurrentContext(); 448 Local<Context> context = isolate->GetCurrentContext();
451 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); 449 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked();
452 // The descriptor's 'initial'. 450 // The descriptor's 'initial'.
453 int initial; 451 int initial;
454 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, 452 if (!GetIntegerProperty(isolate, &thrower, context, descriptor,
455 v8_str(isolate, "initial"), &initial, 0, 65536)) { 453 v8_str(isolate, "initial"), &initial, 0, 65536)) {
456 return; 454 return;
457 } 455 }
(...skipping 17 matching lines...) Expand all
475 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared); 473 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
476 size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) * 474 size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) *
477 static_cast<size_t>(initial); 475 static_cast<size_t>(initial);
478 i::JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, size); 476 i::JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, size);
479 477
480 i::Handle<i::JSObject> memory_obj = i::WasmJs::CreateWasmMemoryObject( 478 i::Handle<i::JSObject> memory_obj = i::WasmJs::CreateWasmMemoryObject(
481 i_isolate, buffer, has_maximum.FromJust(), maximum); 479 i_isolate, buffer, has_maximum.FromJust(), maximum);
482 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 480 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
483 return_value.Set(Utils::ToLocal(memory_obj)); 481 return_value.Set(Utils::ToLocal(memory_obj));
484 } 482 }
483
485 void WebAssemblyTableGetLength( 484 void WebAssemblyTableGetLength(
486 const v8::FunctionCallbackInfo<v8::Value>& args) { 485 const v8::FunctionCallbackInfo<v8::Value>& args) {
487 // TODO(rossberg) 486 v8::Isolate* isolate = args.GetIsolate();
487 Local<Context> context = isolate->GetCurrentContext();
488 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
489 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
490 i::Handle<i::Symbol>(i_context->wasm_table_sym()),
491 "Receiver is not a WebAssembly.Table")) {
492 return;
493 }
494 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
495 i::Handle<i::JSObject> receiver =
496 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This()));
497 i::Handle<i::Object> array(
498 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate);
499 int length = i::Handle<i::FixedArray>::cast(array)->length();
500 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
501 return_value.Set(v8::Number::New(isolate, length));
488 } 502 }
503
489 void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { 504 void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
490 // TODO(rossberg) 505 v8::Isolate* isolate = args.GetIsolate();
506 Local<Context> context = isolate->GetCurrentContext();
507 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
508 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
509 i::Handle<i::Symbol>(i_context->wasm_table_sym()),
510 "Receiver is not a WebAssembly.Table")) {
511 return;
512 }
513 // TODO(rossberg): grow table and update relevant instances.
514 v8::Local<v8::Value> e =
515 v8::Exception::TypeError(v8_str(isolate, "Table#grow unimplemented"));
516 isolate->ThrowException(e);
491 } 517 }
518
492 void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) { 519 void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
493 // TODO(rossberg) 520 v8::Isolate* isolate = args.GetIsolate();
521 Local<Context> context = isolate->GetCurrentContext();
522 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
523 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
524 i::Handle<i::Symbol>(i_context->wasm_table_sym()),
525 "Receiver is not a WebAssembly.Table")) {
526 return;
527 }
528
529 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
530 i::Handle<i::JSObject> receiver =
531 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This()));
532 i::Handle<i::Object> array(
533 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate);
534 int i = 0;
535 if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return;
536 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
537 if (i >= 0 && i < i::Handle<i::FixedArray>::cast(array)->length()) {
538 i::Handle<i::Object> value(i::Handle<i::FixedArray>::cast(array)->get(i),
539 i_isolate);
540 return_value.Set(Utils::ToLocal(value));
541 }
494 } 542 }
543
495 void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) { 544 void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
496 // TODO(rossberg) 545 v8::Isolate* isolate = args.GetIsolate();
546 Local<Context> context = isolate->GetCurrentContext();
547 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
548 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
549 i::Handle<i::Symbol>(i_context->wasm_table_sym()),
550 "Receiver is not a WebAssembly.Table")) {
551 return;
552 }
553 if (args.Length() < 2 ||
554 !(args[1]->IsNull() ||
555 (args[1]->IsObject() && v8::Object::Cast(*args[1])->IsCallable()))) {
556 v8::Local<v8::Value> e = v8::Exception::TypeError(
557 v8_str(isolate, "Argument 1 must be null or a function"));
558 isolate->ThrowException(e);
559 return;
560 }
561
562 // TODO(rossberg): set table element and update relevent instances.
563 v8::Local<v8::Value> e =
564 v8::Exception::TypeError(v8_str(isolate, "Table#set unimplemented"));
565 isolate->ThrowException(e);
497 } 566 }
567
498 void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { 568 void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
499 // TODO(rossberg) 569 v8::Isolate* isolate = args.GetIsolate();
570 Local<Context> context = isolate->GetCurrentContext();
571 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
572 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
573 i::Handle<i::Symbol>(i_context->wasm_memory_sym()),
574 "Receiver is not a WebAssembly.Memory")) {
575 return;
576 }
577
578 // TODO(rossberg): grow memory.
579 v8::Local<v8::Value> e =
580 v8::Exception::TypeError(v8_str(isolate, "Memory#grow unimplemented"));
581 isolate->ThrowException(e);
500 } 582 }
583
501 void WebAssemblyMemoryGetBuffer( 584 void WebAssemblyMemoryGetBuffer(
502 const v8::FunctionCallbackInfo<v8::Value>& args) { 585 const v8::FunctionCallbackInfo<v8::Value>& args) {
503 v8::Isolate* isolate = args.GetIsolate(); 586 v8::Isolate* isolate = args.GetIsolate();
504 Local<Context> context = isolate->GetCurrentContext(); 587 Local<Context> context = isolate->GetCurrentContext();
505 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 588 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
506 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), 589 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
507 i::Handle<i::Symbol>(i_context->wasm_memory_sym()), 590 i::Handle<i::Symbol>(i_context->wasm_memory_sym()),
508 "Receiver is not a WebAssembly.Memory")) { 591 "Receiver is not a WebAssembly.Memory")) {
509 return; 592 return;
510 } 593 }
(...skipping 10 matching lines...) Expand all
521 604
522 i::Handle<i::JSObject> i::WasmJs::CreateWasmMemoryObject( 605 i::Handle<i::JSObject> i::WasmJs::CreateWasmMemoryObject(
523 i::Isolate* i_isolate, i::Handle<i::JSArrayBuffer> buffer, bool has_maximum, 606 i::Isolate* i_isolate, i::Handle<i::JSArrayBuffer> buffer, bool has_maximum,
524 int maximum) { 607 int maximum) {
525 i::Handle<i::JSFunction> memory_ctor( 608 i::Handle<i::JSFunction> memory_ctor(
526 i_isolate->native_context()->wasm_memory_constructor()); 609 i_isolate->native_context()->wasm_memory_constructor());
527 i::Handle<i::JSObject> memory_obj = 610 i::Handle<i::JSObject> memory_obj =
528 i_isolate->factory()->NewJSObject(memory_ctor); 611 i_isolate->factory()->NewJSObject(memory_ctor);
529 memory_obj->SetInternalField(kWasmMemoryBufferFieldIndex, *buffer); 612 memory_obj->SetInternalField(kWasmMemoryBufferFieldIndex, *buffer);
530 memory_obj->SetInternalField( 613 memory_obj->SetInternalField(
531 1, has_maximum 614 kWasmMemoryMaximumFieldIndex,
532 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) 615 has_maximum
533 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); 616 ? static_cast<i::Object*>(i::Smi::FromInt(maximum))
617 : static_cast<i::Object*>(i_isolate->heap()->undefined_value()));
534 i::Handle<i::Symbol> memory_sym( 618 i::Handle<i::Symbol> memory_sym(
535 i_isolate->native_context()->wasm_memory_sym()); 619 i_isolate->native_context()->wasm_memory_sym());
536 i::Object::SetProperty(memory_obj, memory_sym, memory_obj, i::STRICT).Check(); 620 i::Object::SetProperty(memory_obj, memory_sym, memory_obj, i::STRICT).Check();
537 return memory_obj; 621 return memory_obj;
538 } 622 }
539 623
540 // TODO(titzer): we use the API to create the function template because the 624 // TODO(titzer): we use the API to create the function template because the
541 // internal guts are too ugly to replicate here. 625 // internal guts are too ugly to replicate here.
542 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, 626 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate,
543 FunctionCallback func) { 627 FunctionCallback func) {
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate, 838 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate,
755 Handle<Object> value) { 839 Handle<Object> value) {
756 DCHECK(IsWasmMemoryObject(isolate, value)); 840 DCHECK(IsWasmMemoryObject(isolate, value));
757 Handle<Object> buf( 841 Handle<Object> buf(
758 JSObject::cast(*value)->GetInternalField(kWasmMemoryBufferFieldIndex), 842 JSObject::cast(*value)->GetInternalField(kWasmMemoryBufferFieldIndex),
759 isolate); 843 isolate);
760 return Handle<JSArrayBuffer>::cast(buf); 844 return Handle<JSArrayBuffer>::cast(buf);
761 } 845 }
762 } // namespace internal 846 } // namespace internal
763 } // namespace v8 847 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/wasm/table.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698