Commit 71ffee95 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Fix operation functions to not be constructors.

This fixes the operation functions (i.e. WebIDL interface member and
namespace member operations) for WebAssembly to not have 'prototype'
properties and not be marked as constructors.

R=ahaas@chromium.org
TEST=mjsunit/wasm/js-api
BUG=chromium:1027945

Change-Id: I4db753a9ca570b95c45cb033c36de65bcafafe8f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1950483Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65329}
parent b85500e1
......@@ -1906,14 +1906,12 @@ Handle<JSFunction> CreateFunc(Isolate* isolate, Handle<String> name,
return function;
}
// TODO(mstarzinger): Pass {has_prototype} as an argument and audit all calls
// for whether a "prototype" property is expected. Also add respective tests.
Handle<JSFunction> InstallFunc(Isolate* isolate, Handle<JSObject> object,
const char* str, FunctionCallback func,
int length = 0,
int length, bool has_prototype = false,
PropertyAttributes attributes = NONE) {
Handle<String> name = v8_str(isolate, str);
Handle<JSFunction> function = CreateFunc(isolate, name, func, true);
Handle<JSFunction> function = CreateFunc(isolate, name, func, has_prototype);
function->shared().set_length(length);
JSObject::AddProperty(isolate, object, name, function, attributes);
return function;
......@@ -1923,7 +1921,7 @@ Handle<JSFunction> InstallConstructorFunc(Isolate* isolate,
Handle<JSObject> object,
const char* str,
FunctionCallback func) {
return InstallFunc(isolate, object, str, func, 1, DONT_ENUM);
return InstallFunc(isolate, object, str, func, 1, true, DONT_ENUM);
}
Handle<String> GetterName(Isolate* isolate, Handle<String> name) {
......@@ -1957,11 +1955,9 @@ void InstallGetterSetter(Isolate* isolate, Handle<JSObject> object,
CreateFunc(isolate, SetterName(isolate, name), setter, false);
setter_func->shared().set_length(1);
v8::PropertyAttribute attributes = v8::None;
Utils::ToLocal(object)->SetAccessorProperty(
Utils::ToLocal(name), Utils::ToLocal(getter_func),
Utils::ToLocal(setter_func), attributes);
Utils::ToLocal(setter_func), v8::None);
}
// Assigns a dummy instance template to the given constructor function. Used to
......
......@@ -18,6 +18,15 @@ function assertArrayBuffer(val, expected) {
}
}
function isConstructor(value) {
var p = new Proxy(value, { construct: () => ({}) });
try {
return new p, true;
} catch(e) {
return false;
}
}
let emptyModuleBinary = (() => {
var builder = new WasmModuleBuilder();
return new Int8Array(builder.toBuffer());
......@@ -77,6 +86,7 @@ let CompileError = WebAssembly.CompileError;
assertEq(CompileError, compileErrorDesc.value);
assertEq(CompileError.length, 1);
assertEq(CompileError.name, 'CompileError');
assertTrue(isConstructor(CompileError));
let compileError = new CompileError;
assertTrue(compileError instanceof CompileError);
assertTrue(compileError instanceof Error);
......@@ -95,6 +105,7 @@ let RuntimeError = WebAssembly.RuntimeError;
assertEq(RuntimeError, runtimeErrorDesc.value);
assertEq(RuntimeError.length, 1);
assertEq(RuntimeError.name, 'RuntimeError');
assertTrue(isConstructor(RuntimeError));
let runtimeError = new RuntimeError;
assertTrue(runtimeError instanceof RuntimeError);
assertTrue(runtimeError instanceof Error);
......@@ -112,6 +123,7 @@ let LinkError = WebAssembly.LinkError;
assertEq(LinkError, linkErrorDesc.value);
assertEq(LinkError.length, 1);
assertEq(LinkError.name, 'LinkError');
assertTrue(isConstructor(LinkError));
let linkError = new LinkError;
assertTrue(linkError instanceof LinkError);
assertTrue(linkError instanceof Error);
......@@ -131,6 +143,7 @@ let Module = WebAssembly.Module;
assertEq(Module, moduleDesc.value);
assertEq(Module.length, 1);
assertEq(Module.name, 'Module');
assertTrue(isConstructor(Module));
assertThrows(
() => Module(), TypeError, /must be invoked with 'new'/);
assertThrows(
......@@ -184,6 +197,7 @@ assertTrue(moduleImportsDesc.configurable);
// 'WebAssembly.Module.imports' method
let moduleImports = moduleImportsDesc.value;
assertEq(moduleImports.length, 1);
assertFalse(isConstructor(moduleImports));
assertThrows(
() => moduleImports(), TypeError, /Argument 0 must be a WebAssembly.Module/);
assertThrows(
......@@ -231,6 +245,7 @@ assertTrue(moduleExportsDesc.configurable);
// 'WebAssembly.Module.exports' method
let moduleExports = moduleExportsDesc.value;
assertEq(moduleExports.length, 1);
assertFalse(isConstructor(moduleExports));
assertThrows(
() => moduleExports(), TypeError, /Argument 0 must be a WebAssembly.Module/);
assertThrows(
......@@ -274,8 +289,10 @@ assertTrue(moduleCustomSectionsDesc.writable);
assertTrue(moduleCustomSectionsDesc.enumerable);
assertTrue(moduleCustomSectionsDesc.configurable);
// 'WebAssembly.Module.customSections' method
let moduleCustomSections = moduleCustomSectionsDesc.value;
assertEq(moduleCustomSections.length, 2);
assertFalse(isConstructor(moduleCustomSections));
assertThrows(
() => moduleCustomSections(), TypeError, /Argument 0 must be a WebAssembly.Module/);
assertThrows(
......@@ -334,7 +351,7 @@ let Instance = WebAssembly.Instance;
assertEq(Instance, instanceDesc.value);
assertEq(Instance.length, 1);
assertEq(Instance.name, 'Instance');
assertTrue(isConstructor(Instance));
assertThrows(
() => Instance(), TypeError, /must be invoked with 'new'/);
assertThrows(
......@@ -382,6 +399,7 @@ let instanceExportsDesc =
assertEq(typeof instanceExportsDesc.get, 'function');
assertEq(instanceExportsDesc.get.name, 'get exports');
assertEq(instanceExportsDesc.get.length, 0);
assertFalse(isConstructor(instanceExportsDesc.get));
assertFalse('prototype' in instanceExportsDesc.get);
assertEq(instanceExportsDesc.set, undefined);
assertTrue(instanceExportsDesc.enumerable);
......@@ -413,6 +431,7 @@ let Memory = WebAssembly.Memory;
assertEq(Memory, memoryDesc.value);
assertEq(Memory.length, 1);
assertEq(Memory.name, 'Memory');
assertTrue(isConstructor(Memory));
assertThrows(
() => Memory(), TypeError, /must be invoked with 'new'/);
assertThrows(
......@@ -461,6 +480,7 @@ let bufferDesc = Object.getOwnPropertyDescriptor(memoryProto, 'buffer');
assertEq(typeof bufferDesc.get, 'function');
assertEq(bufferDesc.get.name, 'get buffer');
assertEq(bufferDesc.get.length, 0);
assertFalse(isConstructor(bufferDesc.get));
assertFalse('prototype' in bufferDesc.get);
assertEq(bufferDesc.set, undefined);
assertTrue(bufferDesc.enumerable);
......@@ -484,6 +504,7 @@ assertTrue(memGrowDesc.configurable);
// 'WebAssembly.Memory.prototype.grow' method
let memGrow = memGrowDesc.value;
assertEq(memGrow.length, 1);
assertFalse(isConstructor(memGrow));
assertThrows(
() => memGrow.call(), TypeError, /Receiver is not a WebAssembly.Memory/);
assertThrows(
......@@ -555,6 +576,7 @@ let Table = WebAssembly.Table;
assertEq(Table, tableDesc.value);
assertEq(Table.length, 1);
assertEq(Table.name, 'Table');
assertTrue(isConstructor(Table));
assertThrows(
() => Table(), TypeError, /must be invoked with 'new'/);
assertThrows(
......@@ -615,6 +637,7 @@ let lengthDesc = Object.getOwnPropertyDescriptor(tableProto, 'length');
assertEq(typeof lengthDesc.get, 'function');
assertEq(lengthDesc.get.name, 'get length');
assertEq(lengthDesc.get.length, 0);
assertFalse(isConstructor(lengthDesc.get));
assertFalse('prototype' in lengthDesc.get);
assertEq(lengthDesc.set, undefined);
assertTrue(lengthDesc.enumerable);
......@@ -639,6 +662,7 @@ assertTrue(getDesc.configurable);
// 'WebAssembly.Table.prototype.get' method
let get = getDesc.value;
assertEq(get.length, 1);
assertFalse(isConstructor(get));
assertThrows(
() => get.call(), TypeError, /Receiver is not a WebAssembly.Table/);
assertThrows(
......@@ -668,6 +692,7 @@ assertTrue(setDesc.configurable);
// 'WebAssembly.Table.prototype.set' method
let set = setDesc.value;
assertEq(set.length, 2);
assertFalse(isConstructor(set));
assertThrows(
() => set.call(), TypeError, /Receiver is not a WebAssembly.Table/);
assertThrows(
......@@ -722,6 +747,7 @@ assertTrue(tblGrowDesc.configurable);
// 'WebAssembly.Table.prototype.grow' method
let tblGrow = tblGrowDesc.value;
assertEq(tblGrow.length, 1);
assertFalse(isConstructor(tblGrow));
assertThrows(
() => tblGrow.call(), TypeError, /Receiver is not a WebAssembly.Table/);
assertThrows(
......@@ -768,6 +794,7 @@ let compile = WebAssembly.compile;
assertEq(compile, compileDesc.value);
assertEq(compile.length, 1);
assertEq(compile.name, 'compile');
assertFalse(isConstructor(compile));
function assertCompileError(args, err, msg) {
assertThrowsAsync(compile(...args), err /* TODO , msg */);
}
......@@ -810,6 +837,7 @@ let instantiate = WebAssembly.instantiate;
assertEq(instantiate, instantiateDesc.value);
assertEq(instantiate.length, 1);
assertEq(instantiate.name, 'instantiate');
assertFalse(isConstructor(instantiate));
function assertInstantiateError(args, err, msg) {
assertThrowsAsync(instantiate(...args), err /* TODO , msg */);
}
......@@ -923,14 +951,6 @@ assertInstantiateSuccess(
})();
(function TestAccessorFunctions() {
function isConstructor(value) {
var p = new Proxy(value, { construct: () => ({}) });
try {
return new p, true;
} catch(e) {
return false;
}
};
function testAccessorFunction(obj, prop, accessor) {
var desc = Object.getOwnPropertyDescriptor(obj, prop);
assertSame('function', typeof desc[accessor]);
......
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