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

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

Issue 2410763002: [wasm] GrowMemory should use maximum size declared in WebAssembly.Memory (Closed)
Patch Set: Fix trybots, Brad's review 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 | « src/wasm/wasm-js.h ('k') | src/wasm/wasm-module.cc » ('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"
11 #include "src/ast/ast.h" 11 #include "src/ast/ast.h"
12 #include "src/execution.h" 12 #include "src/execution.h"
13 #include "src/factory.h" 13 #include "src/factory.h"
14 #include "src/handles.h" 14 #include "src/handles.h"
15 #include "src/isolate.h" 15 #include "src/isolate.h"
16 #include "src/objects.h" 16 #include "src/objects.h"
17 #include "src/parsing/parse-info.h" 17 #include "src/parsing/parse-info.h"
18 18
19 #include "src/wasm/module-decoder.h" 19 #include "src/wasm/module-decoder.h"
20 #include "src/wasm/wasm-js.h" 20 #include "src/wasm/wasm-js.h"
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;
31 static const int kWasmMemoryMaximumFieldIndex = 1;
32 static const int kWasmTableArrayFieldIndex = 0; 30 static const int kWasmTableArrayFieldIndex = 0;
33 static const int kWasmTableMaximumFieldIndex = 1; 31 static const int kWasmTableMaximumFieldIndex = 1;
34 32
33 enum WasmMemoryObjectData {
34 kWasmMemoryBuffer,
35 kWasmMemoryMaximum,
36 kWasmMemoryInstanceObject
37 };
38
39 enum WasmInternalFieldCountData {
40 kWasmTableInternalFieldCount = 2,
41 kWasmMemoryInternalFieldCount
42 };
43
35 namespace { 44 namespace {
36 i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) { 45 i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) {
37 return isolate->factory()->NewStringFromAsciiChecked(str); 46 return isolate->factory()->NewStringFromAsciiChecked(str);
38 } 47 }
39 Local<String> v8_str(Isolate* isolate, const char* str) { 48 Local<String> v8_str(Isolate* isolate, const char* str) {
40 return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str)); 49 return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str));
41 } 50 }
42 51
43 struct RawBuffer { 52 struct RawBuffer {
44 const byte* start; 53 const byte* start;
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 638
630 void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { 639 void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
631 v8::Isolate* isolate = args.GetIsolate(); 640 v8::Isolate* isolate = args.GetIsolate();
632 Local<Context> context = isolate->GetCurrentContext(); 641 Local<Context> context = isolate->GetCurrentContext();
633 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 642 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
634 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), 643 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
635 i::Handle<i::Symbol>(i_context->wasm_memory_sym()), 644 i::Handle<i::Symbol>(i_context->wasm_memory_sym()),
636 "Receiver is not a WebAssembly.Memory")) { 645 "Receiver is not a WebAssembly.Memory")) {
637 return; 646 return;
638 } 647 }
648 if (args.Length() < 1) {
649 v8::Local<v8::Value> e = v8::Exception::TypeError(
650 v8_str(isolate, "Argument 0 required, must be numeric value of pages"));
651 isolate->ThrowException(e);
652 return;
653 }
639 654
640 // TODO(rossberg): grow memory. 655 uint32_t delta = args[0]->Uint32Value(context).FromJust();
641 v8::Local<v8::Value> e = 656 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
642 v8::Exception::TypeError(v8_str(isolate, "Memory#grow unimplemented")); 657 i::Handle<i::JSObject> receiver =
643 isolate->ThrowException(e); 658 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This()));
659 i::Handle<i::Object> instance_object(
660 receiver->GetInternalField(kWasmMemoryInstanceObject), i_isolate);
661 i::Handle<i::JSObject> instance(
662 i::Handle<i::JSObject>::cast(instance_object));
663
664 // TODO(gdeepti) Implement growing memory when shared by different
665 // instances.
666 int32_t ret = internal::wasm::GrowInstanceMemory(i_isolate, instance, delta);
667 if (ret == -1) {
668 v8::Local<v8::Value> e = v8::Exception::Error(
669 v8_str(isolate, "Unable to grow instance memory."));
670 isolate->ThrowException(e);
671 return;
672 }
673 i::MaybeHandle<i::JSArrayBuffer> buffer =
674 internal::wasm::GetInstanceMemory(i_isolate, instance);
675 if (buffer.is_null()) {
676 v8::Local<v8::Value> e = v8::Exception::Error(
677 v8_str(isolate, "WebAssembly.Memory buffer object not set."));
678 isolate->ThrowException(e);
679 return;
680 }
681 receiver->SetInternalField(kWasmMemoryBuffer, *buffer.ToHandleChecked());
682 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
683 return_value.Set(ret);
644 } 684 }
645 685
646 void WebAssemblyMemoryGetBuffer( 686 void WebAssemblyMemoryGetBuffer(
647 const v8::FunctionCallbackInfo<v8::Value>& args) { 687 const v8::FunctionCallbackInfo<v8::Value>& args) {
648 v8::Isolate* isolate = args.GetIsolate(); 688 v8::Isolate* isolate = args.GetIsolate();
649 Local<Context> context = isolate->GetCurrentContext(); 689 Local<Context> context = isolate->GetCurrentContext();
650 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 690 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
651 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), 691 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()),
652 i::Handle<i::Symbol>(i_context->wasm_memory_sym()), 692 i::Handle<i::Symbol>(i_context->wasm_memory_sym()),
653 "Receiver is not a WebAssembly.Memory")) { 693 "Receiver is not a WebAssembly.Memory")) {
654 return; 694 return;
655 } 695 }
656 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 696 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
657 i::Handle<i::JSObject> receiver = 697 i::Handle<i::JSObject> receiver =
658 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); 698 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This()));
659 i::Handle<i::Object> buffer( 699 i::Handle<i::Object> buffer(receiver->GetInternalField(kWasmMemoryBuffer),
660 receiver->GetInternalField(kWasmMemoryBufferFieldIndex), i_isolate); 700 i_isolate);
661 DCHECK(buffer->IsJSArrayBuffer()); 701 DCHECK(buffer->IsJSArrayBuffer());
662 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 702 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
663 return_value.Set(Utils::ToLocal(buffer)); 703 return_value.Set(Utils::ToLocal(buffer));
664 } 704 }
665 } // namespace 705 } // namespace
666 706
667 i::Handle<i::JSObject> i::WasmJs::CreateWasmMemoryObject( 707 i::Handle<i::JSObject> i::WasmJs::CreateWasmMemoryObject(
668 i::Isolate* i_isolate, i::Handle<i::JSArrayBuffer> buffer, bool has_maximum, 708 i::Isolate* i_isolate, i::Handle<i::JSArrayBuffer> buffer, bool has_maximum,
669 int maximum) { 709 int maximum) {
670 i::Handle<i::JSFunction> memory_ctor( 710 i::Handle<i::JSFunction> memory_ctor(
671 i_isolate->native_context()->wasm_memory_constructor()); 711 i_isolate->native_context()->wasm_memory_constructor());
672 i::Handle<i::JSObject> memory_obj = 712 i::Handle<i::JSObject> memory_obj =
673 i_isolate->factory()->NewJSObject(memory_ctor); 713 i_isolate->factory()->NewJSObject(memory_ctor);
674 memory_obj->SetInternalField(kWasmMemoryBufferFieldIndex, *buffer); 714 memory_obj->SetInternalField(kWasmMemoryBuffer, *buffer);
675 memory_obj->SetInternalField( 715 memory_obj->SetInternalField(
676 kWasmMemoryMaximumFieldIndex, 716 kWasmMemoryMaximum,
677 has_maximum 717 has_maximum
678 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) 718 ? static_cast<i::Object*>(i::Smi::FromInt(maximum))
679 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); 719 : static_cast<i::Object*>(i_isolate->heap()->undefined_value()));
680 i::Handle<i::Symbol> memory_sym( 720 i::Handle<i::Symbol> memory_sym(
681 i_isolate->native_context()->wasm_memory_sym()); 721 i_isolate->native_context()->wasm_memory_sym());
682 i::Object::SetProperty(memory_obj, memory_sym, memory_obj, i::STRICT).Check(); 722 i::Object::SetProperty(memory_obj, memory_sym, memory_obj, i::STRICT).Check();
683 return memory_obj; 723 return memory_obj;
684 } 724 }
685 725
686 // TODO(titzer): we use the API to create the function template because the 726 // TODO(titzer): we use the API to create the function template because the
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 InstallFunc(isolate, wasm_object, "Instance", WebAssemblyInstance); 821 InstallFunc(isolate, wasm_object, "Instance", WebAssemblyInstance);
782 context->set_wasm_instance_constructor(*instance_constructor); 822 context->set_wasm_instance_constructor(*instance_constructor);
783 823
784 // Setup Table 824 // Setup Table
785 Handle<JSFunction> table_constructor = 825 Handle<JSFunction> table_constructor =
786 InstallFunc(isolate, wasm_object, "Table", WebAssemblyTable); 826 InstallFunc(isolate, wasm_object, "Table", WebAssemblyTable);
787 context->set_wasm_table_constructor(*table_constructor); 827 context->set_wasm_table_constructor(*table_constructor);
788 Handle<JSObject> table_proto = 828 Handle<JSObject> table_proto =
789 factory->NewJSObject(table_constructor, TENURED); 829 factory->NewJSObject(table_constructor, TENURED);
790 map = isolate->factory()->NewMap( 830 map = isolate->factory()->NewMap(
791 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + 2 * i::kPointerSize); 831 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize +
832 kWasmTableInternalFieldCount * i::kPointerSize);
792 JSFunction::SetInitialMap(table_constructor, map, table_proto); 833 JSFunction::SetInitialMap(table_constructor, map, table_proto);
793 JSObject::AddProperty(table_proto, isolate->factory()->constructor_string(), 834 JSObject::AddProperty(table_proto, isolate->factory()->constructor_string(),
794 table_constructor, DONT_ENUM); 835 table_constructor, DONT_ENUM);
795 InstallGetter(isolate, table_proto, "length", WebAssemblyTableGetLength); 836 InstallGetter(isolate, table_proto, "length", WebAssemblyTableGetLength);
796 InstallFunc(isolate, table_proto, "grow", WebAssemblyTableGrow); 837 InstallFunc(isolate, table_proto, "grow", WebAssemblyTableGrow);
797 InstallFunc(isolate, table_proto, "get", WebAssemblyTableGet); 838 InstallFunc(isolate, table_proto, "get", WebAssemblyTableGet);
798 InstallFunc(isolate, table_proto, "set", WebAssemblyTableSet); 839 InstallFunc(isolate, table_proto, "set", WebAssemblyTableSet);
799 840
800 // Setup Memory 841 // Setup Memory
801 Handle<JSFunction> memory_constructor = 842 Handle<JSFunction> memory_constructor =
802 InstallFunc(isolate, wasm_object, "Memory", WebAssemblyMemory); 843 InstallFunc(isolate, wasm_object, "Memory", WebAssemblyMemory);
803 context->set_wasm_memory_constructor(*memory_constructor); 844 context->set_wasm_memory_constructor(*memory_constructor);
804 Handle<JSObject> memory_proto = 845 Handle<JSObject> memory_proto =
805 factory->NewJSObject(memory_constructor, TENURED); 846 factory->NewJSObject(memory_constructor, TENURED);
806 map = isolate->factory()->NewMap( 847 map = isolate->factory()->NewMap(
807 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + 2 * i::kPointerSize); 848 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize +
849 kWasmMemoryInternalFieldCount * i::kPointerSize);
808 JSFunction::SetInitialMap(memory_constructor, map, memory_proto); 850 JSFunction::SetInitialMap(memory_constructor, map, memory_proto);
809 JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(), 851 JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(),
810 memory_constructor, DONT_ENUM); 852 memory_constructor, DONT_ENUM);
811 InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow); 853 InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow);
812 InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer); 854 InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer);
813 855
814 // Setup errors 856 // Setup errors
815 attributes = static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); 857 attributes = static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
816 Handle<JSFunction> compile_error( 858 Handle<JSFunction> compile_error(
817 isolate->native_context()->wasm_compile_error_function()); 859 isolate->native_context()->wasm_compile_error_function());
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 if (has_brand.IsNothing()) return false; 947 if (has_brand.IsNothing()) return false;
906 if (has_brand.ToChecked()) return true; 948 if (has_brand.ToChecked()) return true;
907 } 949 }
908 return false; 950 return false;
909 } 951 }
910 952
911 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate, 953 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate,
912 Handle<Object> value) { 954 Handle<Object> value) {
913 DCHECK(IsWasmMemoryObject(isolate, value)); 955 DCHECK(IsWasmMemoryObject(isolate, value));
914 Handle<Object> buf( 956 Handle<Object> buf(
915 JSObject::cast(*value)->GetInternalField(kWasmMemoryBufferFieldIndex), 957 JSObject::cast(*value)->GetInternalField(kWasmMemoryBuffer), isolate);
916 isolate);
917 return Handle<JSArrayBuffer>::cast(buf); 958 return Handle<JSArrayBuffer>::cast(buf);
918 } 959 }
960
961 uint32_t WasmJs::GetWasmMemoryMaximumSize(Isolate* isolate,
962 Handle<Object> value) {
963 DCHECK(IsWasmMemoryObject(isolate, value));
964 Object* max_mem =
965 JSObject::cast(*value)->GetInternalField(kWasmMemoryMaximum);
966 if (max_mem->IsUndefined(isolate)) return wasm::WasmModule::kMaxMemPages;
967 uint32_t max_pages = Smi::cast(max_mem)->value();
968 return max_pages;
969 }
970
971 void WasmJs::SetWasmMemoryInstance(Isolate* isolate,
972 Handle<Object> memory_object,
973 Handle<JSObject> instance) {
974 if (!memory_object->IsUndefined(isolate)) {
975 DCHECK(IsWasmMemoryObject(isolate, memory_object));
976 // TODO(gdeepti): This should be a weak list of instance objects
977 // for instances that share memory.
978 JSObject::cast(*memory_object)
979 ->SetInternalField(kWasmMemoryInstanceObject, *instance);
980 }
981 }
919 } // namespace internal 982 } // namespace internal
920 } // namespace v8 983 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/wasm-js.h ('k') | src/wasm/wasm-module.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698