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