Commit 07f94555 authored by Aseem Garg's avatar Aseem Garg Committed by Commit Bot

[wasm] Add minimum to MemoryDescriptor and TableDescriptor

This CL allows for either of 'minimum' or 'initial' for MemoryDescriptor
and TableDescriptor. It also adds a flag for the reflection features.

R=binji@chromium.org,adamk@chromium.org
Bug=v8:7742

Change-Id: Icfd4825f63e1eb784a39d10f740d55e81489eba7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1485243
Commit-Queue: Aseem Garg <aseemgarg@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Reviewed-by: 's avatarBen Smith <binji@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60256}
parent ba00d8b7
......@@ -967,30 +967,6 @@ bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
return true;
}
bool GetRequiredIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
Local<Context> context,
Local<v8::Object> object,
Local<String> property, int64_t* result,
int64_t lower_bound, uint64_t upper_bound) {
v8::Local<v8::Value> value;
if (!object->Get(context, property).ToLocal(&value)) {
return false;
}
i::Handle<i::String> property_name = v8::Utils::OpenHandle(*property);
// Web IDL: dictionary presence
// https://heycam.github.io/webidl/#dfn-present
if (value->IsUndefined()) {
thrower->TypeError("Property '%s' is required",
property_name->ToCString().get());
return false;
}
return GetIntegerProperty(isolate, thrower, context, value, property_name,
result, lower_bound, upper_bound);
}
bool GetOptionalIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
Local<Context> context,
Local<v8::Object> object,
......@@ -1016,6 +992,36 @@ bool GetOptionalIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
result, lower_bound, upper_bound);
}
// Fetch 'initial' or 'minimum' property from object. If both are provided,
// 'initial' is used.
// TODO(aseemgarg): change behavior when the following bug is resolved:
// https://github.com/WebAssembly/js-types/issues/6
bool GetInitialOrMinimumProperty(v8::Isolate* isolate, ErrorThrower* thrower,
Local<Context> context,
Local<v8::Object> object, int64_t* result,
int64_t lower_bound, uint64_t upper_bound) {
bool has_initial = false;
if (!GetOptionalIntegerProperty(isolate, thrower, context, object,
v8_str(isolate, "initial"), &has_initial,
result, lower_bound, upper_bound)) {
return false;
}
auto enabled_features = i::wasm::WasmFeaturesFromFlags();
if (!has_initial && enabled_features.type_reflection) {
if (!GetOptionalIntegerProperty(isolate, thrower, context, object,
v8_str(isolate, "minimum"), &has_initial,
result, lower_bound, upper_bound)) {
return false;
}
}
if (!has_initial) {
// TODO(aseemgarg): update error message when the spec issue is resolved.
thrower->TypeError("Property 'initial' is required");
return false;
}
return true;
}
// new WebAssembly.Table(args) -> WebAssembly.Table
void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
......@@ -1052,11 +1058,11 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
return;
}
}
// The descriptor's 'initial'.
int64_t initial = 0;
if (!GetRequiredIntegerProperty(isolate, &thrower, context, descriptor,
v8_str(isolate, "initial"), &initial, 0,
i::wasm::max_table_init_entries())) {
if (!GetInitialOrMinimumProperty(isolate, &thrower, context, descriptor,
&initial, 0,
i::wasm::max_table_init_entries())) {
return;
}
// The descriptor's 'maximum'.
......@@ -1091,11 +1097,10 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
}
Local<Context> context = isolate->GetCurrentContext();
Local<v8::Object> descriptor = Local<Object>::Cast(args[0]);
// The descriptor's 'initial'.
int64_t initial = 0;
if (!GetRequiredIntegerProperty(isolate, &thrower, context, descriptor,
v8_str(isolate, "initial"), &initial, 0,
i::wasm::max_mem_pages())) {
if (!GetInitialOrMinimumProperty(isolate, &thrower, context, descriptor,
&initial, 0, i::wasm::max_mem_pages())) {
return;
}
// The descriptor's 'maximum'.
......
......@@ -96,3 +96,64 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
assertEquals(false, type.mutable);
assertEquals(2, Object.getOwnPropertyNames(type).length);
})();
(function TestMemoryConstructorWithMinimum() {
let mem = new WebAssembly.Memory({minimum: 1});
assertTrue(mem instanceof WebAssembly.Memory);
let type = WebAssembly.Memory.type(mem);
assertEquals(1, type.minimum);
assertEquals(1, Object.getOwnPropertyNames(type).length);
mem = new WebAssembly.Memory({minimum: 1, maximum: 5});
assertTrue(mem instanceof WebAssembly.Memory);
type = WebAssembly.Memory.type(mem);
assertEquals(1, type.minimum);
assertEquals(5, type.maximum);
assertEquals(2, Object.getOwnPropertyNames(type).length);
mem = new WebAssembly.Memory({minimum: 1, initial: 2});
assertTrue(mem instanceof WebAssembly.Memory);
type = WebAssembly.Memory.type(mem);
assertEquals(2, type.minimum);
assertEquals(1, Object.getOwnPropertyNames(type).length);
mem = new WebAssembly.Memory({minimum: 1, initial: 2, maximum: 5});
assertTrue(mem instanceof WebAssembly.Memory);
type = WebAssembly.Memory.type(mem);
assertEquals(2, type.minimum);
assertEquals(5, type.maximum);
assertEquals(2, Object.getOwnPropertyNames(type).length);
})();
(function TestTableConstructorWithMinimum() {
let table = new WebAssembly.Table({minimum: 1, element: 'anyfunc'});
assertTrue(table instanceof WebAssembly.Table);
let type = WebAssembly.Table.type(table);
assertEquals(1, type.minimum);
assertEquals('anyfunc', type.element);
assertEquals(2, Object.getOwnPropertyNames(type).length);
table = new WebAssembly.Table({minimum: 1, element: 'anyfunc', maximum: 5});
assertTrue(table instanceof WebAssembly.Table);
type = WebAssembly.Table.type(table);
assertEquals(1, type.minimum);
assertEquals(5, type.maximum);
assertEquals('anyfunc', type.element);
assertEquals(3, Object.getOwnPropertyNames(type).length);
table = new WebAssembly.Table({minimum: 1, initial: 2, element: 'anyfunc'});
assertTrue(table instanceof WebAssembly.Table);
type = WebAssembly.Table.type(table);
assertEquals(2, type.minimum);
assertEquals('anyfunc', type.element);
assertEquals(2, Object.getOwnPropertyNames(type).length);
table = new WebAssembly.Table({minimum: 1, initial: 2, element: 'anyfunc',
maximum: 5});
assertTrue(table instanceof WebAssembly.Table);
type = WebAssembly.Table.type(table);
assertEquals(2, type.minimum);
assertEquals(5, type.maximum);
assertEquals('anyfunc', type.element);
assertEquals(3, Object.getOwnPropertyNames(type).length);
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment