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

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

Issue 2454503005: [wasm] Support for restricted table imports. (Closed)
Patch Set: Fix GC stress issue; tables weren't being reset correctly Created 4 years, 1 month 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 | « src/wasm/wasm-js.h ('k') | src/wasm/wasm-module.h » ('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 11 matching lines...) Expand all
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 kWasmTableArrayFieldIndex = 0; 30 static const int kWasmTableArrayFieldIndex = 0;
31 static const int kWasmTableMaximumFieldIndex = 1; 31 static const int kWasmTableMaximumFieldIndex = 1;
32 static const int kWasmTableDispatchTablesFieldIndex = 2;
32 33
33 enum WasmMemoryObjectData { 34 enum WasmMemoryObjectData {
34 kWasmMemoryBuffer, 35 kWasmMemoryBuffer,
35 kWasmMemoryMaximum, 36 kWasmMemoryMaximum,
36 kWasmMemoryInstanceObject 37 kWasmMemoryInstanceObject
37 }; 38 };
38 39
39 enum WasmInternalFieldCountData { 40 enum WasmInternalFieldCountData {
40 kWasmTableInternalFieldCount = 2, 41 kWasmTableInternalFieldCount = 3,
41 kWasmMemoryInternalFieldCount 42 kWasmMemoryInternalFieldCount = 3
42 }; 43 };
43 44
44 namespace { 45 namespace {
45 i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) { 46 i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) {
46 return isolate->factory()->NewStringFromAsciiChecked(str); 47 return isolate->factory()->NewStringFromAsciiChecked(str);
47 } 48 }
48 Local<String> v8_str(Isolate* isolate, const char* str) { 49 Local<String> v8_str(Isolate* isolate, const char* str) {
49 return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str)); 50 return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str));
50 } 51 }
51 52
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate); 512 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate);
512 int i; 513 int i;
513 if (!args[0]->Int32Value(context).To(&i)) return; 514 if (!args[0]->Int32Value(context).To(&i)) return;
514 if (i < 0 || i >= i::Handle<i::FixedArray>::cast(array)->length()) { 515 if (i < 0 || i >= i::Handle<i::FixedArray>::cast(array)->length()) {
515 v8::Local<v8::Value> e = 516 v8::Local<v8::Value> e =
516 v8::Exception::RangeError(v8_str(isolate, "index out of bounds")); 517 v8::Exception::RangeError(v8_str(isolate, "index out of bounds"));
517 isolate->ThrowException(e); 518 isolate->ThrowException(e);
518 return; 519 return;
519 } 520 }
520 521
522 i::Handle<i::FixedArray> dispatch_tables(
523 i::FixedArray::cast(
524 receiver->GetInternalField(kWasmTableDispatchTablesFieldIndex)),
525 i_isolate);
526 if (value->IsNull(i_isolate)) {
527 i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i,
528 i::Handle<i::JSFunction>::null());
529 } else {
530 i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i,
531 i::Handle<i::JSFunction>::cast(value));
532 }
533
521 i::Handle<i::FixedArray>::cast(array)->set(i, *value); 534 i::Handle<i::FixedArray>::cast(array)->set(i, *value);
522
523 // TODO(titzer): update relevant instances.
524 } 535 }
525 536
526 void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { 537 void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
527 v8::Isolate* isolate = args.GetIsolate(); 538 v8::Isolate* isolate = args.GetIsolate();
528 Local<Context> context = isolate->GetCurrentContext(); 539 Local<Context> context = isolate->GetCurrentContext();
529 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 540 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
530 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), 541 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
531 i::Handle<i::Symbol>(i_context->wasm_memory_sym()), 542 i::Handle<i::Symbol>(i_context->wasm_memory_sym()),
532 "Receiver is not a WebAssembly.Memory")) { 543 "Receiver is not a WebAssembly.Memory")) {
533 return; 544 return;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) 616 ? static_cast<i::Object*>(i::Smi::FromInt(maximum))
606 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); 617 : static_cast<i::Object*>(i_isolate->heap()->undefined_value()));
607 i::Handle<i::Symbol> memory_sym( 618 i::Handle<i::Symbol> memory_sym(
608 i_isolate->native_context()->wasm_memory_sym()); 619 i_isolate->native_context()->wasm_memory_sym());
609 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();
610 return memory_obj; 621 return memory_obj;
611 } 622 }
612 623
613 i::Handle<i::JSObject> i::WasmJs::CreateWasmTableObject( 624 i::Handle<i::JSObject> i::WasmJs::CreateWasmTableObject(
614 i::Isolate* i_isolate, uint32_t initial, bool has_maximum, uint32_t maximum, 625 i::Isolate* i_isolate, uint32_t initial, bool has_maximum, uint32_t maximum,
615 i::Handle<i::FixedArray>* array) { 626 i::Handle<i::FixedArray>* js_functions) {
616 i::Handle<i::JSFunction> table_ctor( 627 i::Handle<i::JSFunction> table_ctor(
617 i_isolate->native_context()->wasm_table_constructor()); 628 i_isolate->native_context()->wasm_table_constructor());
618 i::Handle<i::JSObject> table_obj = 629 i::Handle<i::JSObject> table_obj =
619 i_isolate->factory()->NewJSObject(table_ctor); 630 i_isolate->factory()->NewJSObject(table_ctor);
620 *array = i_isolate->factory()->NewFixedArray(initial); 631 *js_functions = i_isolate->factory()->NewFixedArray(initial);
621 i::Object* null = i_isolate->heap()->null_value(); 632 i::Object* null = i_isolate->heap()->null_value();
622 // TODO(titzer): consider moving FixedArray to size_t. 633 // TODO(titzer): consider moving FixedArray to size_t.
623 for (int i = 0; i < static_cast<int>(initial); ++i) (*array)->set(i, null); 634 for (int i = 0; i < static_cast<int>(initial); ++i) {
624 table_obj->SetInternalField(kWasmTableArrayFieldIndex, *(*array)); 635 (*js_functions)->set(i, null);
636 }
637 table_obj->SetInternalField(kWasmTableArrayFieldIndex, *(*js_functions));
625 table_obj->SetInternalField( 638 table_obj->SetInternalField(
626 kWasmTableMaximumFieldIndex, 639 kWasmTableMaximumFieldIndex,
627 has_maximum 640 has_maximum
628 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) 641 ? static_cast<i::Object*>(i::Smi::FromInt(maximum))
629 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); 642 : static_cast<i::Object*>(i_isolate->heap()->undefined_value()));
643 Handle<FixedArray> dispatch_tables = i_isolate->factory()->NewFixedArray(0);
644 table_obj->SetInternalField(kWasmTableDispatchTablesFieldIndex,
645 *dispatch_tables);
630 i::Handle<i::Symbol> table_sym(i_isolate->native_context()->wasm_table_sym()); 646 i::Handle<i::Symbol> table_sym(i_isolate->native_context()->wasm_table_sym());
631 i::Object::SetProperty(table_obj, table_sym, table_obj, i::STRICT).Check(); 647 i::Object::SetProperty(table_obj, table_sym, table_obj, i::STRICT).Check();
632 return table_obj; 648 return table_obj;
633 } 649 }
634 650
651 i::Handle<i::FixedArray> i::WasmJs::AddWasmTableDispatchTable(
652 i::Isolate* i_isolate, i::Handle<i::JSObject> table_obj,
653 i::Handle<i::JSObject> instance, int table_index,
654 i::Handle<i::FixedArray> dispatch_table) {
655 DCHECK(IsWasmTableObject(i_isolate, table_obj));
656 i::Handle<i::FixedArray> dispatch_tables(
657 i::FixedArray::cast(
658 table_obj->GetInternalField(kWasmTableDispatchTablesFieldIndex)),
659 i_isolate);
660 DCHECK_EQ(0, dispatch_tables->length() % 3);
661
662 if (instance.is_null()) return dispatch_tables;
663 // TODO(titzer): use weak cells here to avoid leaking instances.
664
665 // Grow the dispatch table and add a new pair at the end.
666 i::Handle<i::FixedArray> new_dispatch_tables =
667 i_isolate->factory()->CopyFixedArrayAndGrow(dispatch_tables, 3);
668
669 new_dispatch_tables->set(dispatch_tables->length() + 0, *instance);
670 new_dispatch_tables->set(dispatch_tables->length() + 1,
671 Smi::FromInt(table_index));
672 new_dispatch_tables->set(dispatch_tables->length() + 2, *dispatch_table);
673
674 table_obj->SetInternalField(kWasmTableDispatchTablesFieldIndex,
675 *new_dispatch_tables);
676
677 return new_dispatch_tables;
678 }
679
635 // TODO(titzer): we use the API to create the function template because the 680 // TODO(titzer): we use the API to create the function template because the
636 // internal guts are too ugly to replicate here. 681 // internal guts are too ugly to replicate here.
637 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, 682 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate,
638 FunctionCallback func) { 683 FunctionCallback func) {
639 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); 684 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
640 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func); 685 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func);
641 return v8::Utils::OpenHandle(*local); 686 return v8::Utils::OpenHandle(*local);
642 } 687 }
643 688
644 namespace internal { 689 namespace internal {
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 &in_object_properties); 855 &in_object_properties);
811 856
812 int unused_property_fields = in_object_properties - pre_allocated; 857 int unused_property_fields = in_object_properties - pre_allocated;
813 Handle<Map> map = Map::CopyInitialMap( 858 Handle<Map> map = Map::CopyInitialMap(
814 prev_map, instance_size, in_object_properties, unused_property_fields); 859 prev_map, instance_size, in_object_properties, unused_property_fields);
815 860
816 context->set_wasm_function_map(*map); 861 context->set_wasm_function_map(*map);
817 } 862 }
818 } 863 }
819 864
820 bool WasmJs::IsWasmMemoryObject(Isolate* isolate, Handle<Object> value) { 865 static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> symbol) {
821 if (value->IsJSObject()) { 866 if (value->IsJSObject()) {
822 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value); 867 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
823 i::Handle<i::Symbol> sym(isolate->context()->wasm_memory_sym(), isolate); 868 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, symbol);
824 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
825 if (has_brand.IsNothing()) return false; 869 if (has_brand.IsNothing()) return false;
826 if (has_brand.ToChecked()) return true; 870 if (has_brand.ToChecked()) return true;
827 } 871 }
828 return false; 872 return false;
829 } 873 }
830 874
875 bool WasmJs::IsWasmMemoryObject(Isolate* isolate, Handle<Object> value) {
876 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate);
877 return HasBrand(value, symbol);
878 }
879
880 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) {
881 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate);
882 return HasBrand(value, symbol);
883 }
884
885 Handle<FixedArray> WasmJs::GetWasmTableFunctions(Isolate* isolate,
886 Handle<JSObject> value) {
887 DCHECK(IsWasmTableObject(isolate, value));
888 Handle<Object> arr(
889 JSObject::cast(*value)->GetInternalField(kWasmTableArrayFieldIndex),
890 isolate);
891 return Handle<FixedArray>::cast(arr);
892 }
893
831 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate, 894 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate,
832 Handle<Object> value) { 895 Handle<Object> value) {
833 DCHECK(IsWasmMemoryObject(isolate, value)); 896 DCHECK(IsWasmMemoryObject(isolate, value));
834 Handle<Object> buf( 897 Handle<Object> buf(
835 JSObject::cast(*value)->GetInternalField(kWasmMemoryBuffer), isolate); 898 JSObject::cast(*value)->GetInternalField(kWasmMemoryBuffer), isolate);
836 return Handle<JSArrayBuffer>::cast(buf); 899 return Handle<JSArrayBuffer>::cast(buf);
837 } 900 }
838 901
839 void WasmJs::SetWasmMemoryArrayBuffer(Isolate* isolate, Handle<Object> value, 902 void WasmJs::SetWasmMemoryArrayBuffer(Isolate* isolate, Handle<Object> value,
840 Handle<JSArrayBuffer> buffer) { 903 Handle<JSArrayBuffer> buffer) {
841 DCHECK(IsWasmMemoryObject(isolate, value)); 904 DCHECK(IsWasmMemoryObject(isolate, value));
842 JSObject::cast(*value)->SetInternalField(kWasmMemoryBuffer, *buffer); 905 JSObject::cast(*value)->SetInternalField(kWasmMemoryBuffer, *buffer);
843 } 906 }
844 907
845 uint32_t WasmJs::GetWasmMemoryMaximumSize(Isolate* isolate, 908 uint32_t WasmJs::GetWasmMemoryMaximumSize(Isolate* isolate,
846 Handle<Object> value) { 909 Handle<Object> value) {
847 DCHECK(IsWasmMemoryObject(isolate, value)); 910 DCHECK(IsWasmMemoryObject(isolate, value));
848 Object* max_mem = 911 Object* max_mem =
849 JSObject::cast(*value)->GetInternalField(kWasmMemoryMaximum); 912 JSObject::cast(*value)->GetInternalField(kWasmMemoryMaximum);
850 if (max_mem->IsUndefined(isolate)) return wasm::WasmModule::kMaxMemPages; 913 if (max_mem->IsUndefined(isolate)) return wasm::WasmModule::kV8MaxPages;
851 uint32_t max_pages = Smi::cast(max_mem)->value(); 914 uint32_t max_pages = Smi::cast(max_mem)->value();
852 return max_pages; 915 return max_pages;
853 } 916 }
854 917
855 void WasmJs::SetWasmMemoryInstance(Isolate* isolate, 918 void WasmJs::SetWasmMemoryInstance(Isolate* isolate,
856 Handle<Object> memory_object, 919 Handle<Object> memory_object,
857 Handle<JSObject> instance) { 920 Handle<JSObject> instance) {
858 if (!memory_object->IsUndefined(isolate)) { 921 if (!memory_object->IsUndefined(isolate)) {
859 DCHECK(IsWasmMemoryObject(isolate, memory_object)); 922 DCHECK(IsWasmMemoryObject(isolate, memory_object));
860 // TODO(gdeepti): This should be a weak list of instance objects 923 // TODO(gdeepti): This should be a weak list of instance objects
861 // for instances that share memory. 924 // for instances that share memory.
862 JSObject::cast(*memory_object) 925 JSObject::cast(*memory_object)
863 ->SetInternalField(kWasmMemoryInstanceObject, *instance); 926 ->SetInternalField(kWasmMemoryInstanceObject, *instance);
864 } 927 }
865 } 928 }
866 } // namespace internal 929 } // namespace internal
867 } // namespace v8 930 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/wasm-js.h ('k') | src/wasm/wasm-module.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698