Bug 1315390 - Baldr: exported wasm functions shouldn't be constructors (r=bbouvier)

MozReview-Commit-ID: ABYBHtSQni5

--HG--
extra : rebase_source : c5e945d2e6a0315d12ac0cb61f831c8911bffc8d
This commit is contained in:
Luke Wagner 2016-11-04 18:44:56 -05:00
Родитель d585884d50
Коммит a11559c368
7 изменённых файлов: 38 добавлений и 23 удалений

Просмотреть файл

@ -2,7 +2,7 @@ load(libdir + 'wasm.js');
const WasmPage = 64 * 1024;
const emptyModule = wasmTextToBinary('(module)');
const moduleBinary = wasmTextToBinary('(module (func (export "f") (result i32) (i32.const 42)))');
// 'WebAssembly' data property on global object
const wasmDesc = Object.getOwnPropertyDescriptor(this, 'WebAssembly');
@ -70,8 +70,8 @@ assertErrorMessage(() => new Module(1), TypeError, "first argument must be an Ar
assertErrorMessage(() => new Module({}), TypeError, "first argument must be an ArrayBuffer or typed array object");
assertErrorMessage(() => new Module(new Uint8Array()), CompileError, /failed to match magic number/);
assertErrorMessage(() => new Module(new ArrayBuffer()), CompileError, /failed to match magic number/);
assertEq(new Module(emptyModule) instanceof Module, true);
assertEq(new Module(emptyModule.buffer) instanceof Module, true);
assertEq(new Module(moduleBinary) instanceof Module, true);
assertEq(new Module(moduleBinary.buffer) instanceof Module, true);
// 'WebAssembly.Module.prototype' data property
const moduleProtoDesc = Object.getOwnPropertyDescriptor(Module, 'prototype');
@ -87,7 +87,7 @@ assertEq(String(moduleProto), "[object Object]");
assertEq(Object.getPrototypeOf(moduleProto), Object.prototype);
// 'WebAssembly.Module' instance objects
const m1 = new Module(emptyModule);
const m1 = new Module(moduleBinary);
assertEq(typeof m1, "object");
assertEq(String(m1), "[object WebAssembly.Module]");
assertEq(Object.getPrototypeOf(m1), moduleProto);
@ -137,6 +137,14 @@ assertEq(exportsDesc.writable, true);
assertEq(exportsDesc.enumerable, true);
assertEq(exportsDesc.configurable, true);
// Exported WebAssembly functions
const f = i1.exports.f;
assertEq(f instanceof Function, true);
assertEq(f.length, 0);
assertEq('name' in f, true);
assertEq(Function.prototype.call.call(f), 42);
assertErrorMessage(() => new f(), TypeError, /is not a constructor/);
// 'WebAssembly.Memory' data property
const memoryDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Memory');
assertEq(typeof memoryDesc.value, "function");
@ -379,5 +387,5 @@ function assertCompileSuccess(bytes) {
drainJobQueue();
assertEq(module instanceof Module, true);
}
assertCompileSuccess(emptyModule);
assertCompileSuccess(emptyModule.buffer);
assertCompileSuccess(moduleBinary);
assertCompileSuccess(moduleBinary.buffer);

Просмотреть файл

@ -378,7 +378,7 @@ static const JSPropertySpec function_properties[] = {
static bool
ResolveInterpretedFunctionPrototype(JSContext* cx, HandleFunction fun, HandleId id)
{
MOZ_ASSERT(fun->isInterpreted() || fun->isWasmNative());
MOZ_ASSERT(fun->isInterpreted() || fun->isAsmJSNative());
MOZ_ASSERT(id == NameToId(cx->names().prototype));
// Assert that fun is not a compiler-created function object, which

Просмотреть файл

@ -40,7 +40,7 @@ class JSFunction : public js::NativeObject
ClassConstructor,
Getter,
Setter,
Wasm, /* function is wasm module or exported function */
AsmJS, /* function is an asm.js module or exported function */
FunctionKindLimit
};
@ -66,7 +66,7 @@ class JSFunction : public js::NativeObject
FUNCTION_KIND_SHIFT = 13,
FUNCTION_KIND_MASK = 0x7 << FUNCTION_KIND_SHIFT,
WASM_KIND = Wasm << FUNCTION_KIND_SHIFT,
ASMJS_KIND = AsmJS << FUNCTION_KIND_SHIFT,
ARROW_KIND = Arrow << FUNCTION_KIND_SHIFT,
METHOD_KIND = Method << FUNCTION_KIND_SHIFT,
CLASSCONSTRUCTOR_KIND = ClassConstructor << FUNCTION_KIND_SHIFT,
@ -77,8 +77,8 @@ class JSFunction : public js::NativeObject
NATIVE_FUN = 0,
NATIVE_CTOR = NATIVE_FUN | CONSTRUCTOR,
NATIVE_CLASS_CTOR = NATIVE_FUN | CONSTRUCTOR | CLASSCONSTRUCTOR_KIND,
WASM_CTOR = WASM_KIND | NATIVE_CTOR,
ASMJS_LAMBDA_CTOR = WASM_KIND | NATIVE_CTOR | LAMBDA,
ASMJS_CTOR = ASMJS_KIND | NATIVE_CTOR,
ASMJS_LAMBDA_CTOR = ASMJS_KIND | NATIVE_CTOR | LAMBDA,
INTERPRETED_METHOD = INTERPRETED | METHOD_KIND,
INTERPRETED_METHOD_GENERATOR = INTERPRETED | METHOD_KIND,
INTERPRETED_CLASS_CONSTRUCTOR = INTERPRETED | CLASSCONSTRUCTOR_KIND | CONSTRUCTOR,
@ -173,7 +173,7 @@ class JSFunction : public js::NativeObject
bool isConstructor() const { return flags() & CONSTRUCTOR; }
/* Possible attributes of a native function: */
bool isWasmNative() const { return kind() == Wasm; }
bool isAsmJSNative() const { return kind() == AsmJS; }
/* Possible attributes of an interpreted function: */
bool isExprBody() const { return flags() & EXPR_BODY; }
@ -215,7 +215,7 @@ class JSFunction : public js::NativeObject
/* Compound attributes: */
bool isBuiltin() const {
return (isNative() && !isWasmNative()) || isSelfHostedBuiltin();
return (isNative() && !isAsmJSNative()) || isSelfHostedBuiltin();
}
bool isNamedLambda() const {

Просмотреть файл

@ -791,7 +791,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
} else if (function->isInterpreted()) {
funEnclosingScope = function->nonLazyScript()->enclosingScope();
} else {
MOZ_ASSERT(function->isWasmNative());
MOZ_ASSERT(function->isAsmJSNative());
return xdr->fail(JS::TranscodeResult_Failure_AsmJSNotSupported);
}
@ -3210,7 +3210,7 @@ js::detail::CopyScript(JSContext* cx, HandleScript src, HandleScript dst,
RootedFunction innerFun(cx, &obj->as<JSFunction>());
if (innerFun->isNative()) {
if (cx->compartment() != innerFun->compartment()) {
MOZ_ASSERT(innerFun->isWasmNative());
MOZ_ASSERT(innerFun->isAsmJSNative());
JS_ReportErrorASCII(cx, "AsmJS modules do not yet support cloning.");
return false;
}

Просмотреть файл

@ -8152,7 +8152,7 @@ NewAsmJSModuleFunction(ExclusiveContext* cx, JSFunction* origFun, HandleObject m
RootedAtom name(cx, origFun->name());
JSFunction::Flags flags = origFun->isLambda() ? JSFunction::ASMJS_LAMBDA_CTOR
: JSFunction::WASM_CTOR;
: JSFunction::ASMJS_CTOR;
JSFunction* moduleFun =
NewNativeConstructor(cx, InstantiateAsmJS, origFun->nargs(), name,
gc::AllocKind::FUNCTION_EXTENDED, TenuredObject,

Просмотреть файл

@ -656,11 +656,11 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args)
return false;
}
if (args.isConstructing()) {
// By spec, when a function is called as a constructor and this function
// returns a primary type, which is the case for all wasm exported
// functions, the returned value is discarded and an empty object is
// returned instead.
if (isAsmJS() && args.isConstructing()) {
// By spec, when a JS function is called as a constructor and this
// function returns a primary type, which is the case for all asm.js
// exported functions, the returned value is discarded and an empty
// object is returned instead.
PlainObject* obj = NewBuiltinClassInstance<PlainObject>(cx);
if (!obj)
return false;

Просмотреть файл

@ -775,8 +775,15 @@ WasmInstanceObject::getExportedFunction(JSContext* cx, HandleWasmInstanceObject
return false;
unsigned numArgs = instance.metadata().lookupFuncExport(funcIndex).sig().args().length();
fun.set(NewNativeConstructor(cx, WasmCall, numArgs, name, gc::AllocKind::FUNCTION_EXTENDED,
SingletonObject, JSFunction::WASM_CTOR));
// asm.js needs to active like a normal JS function which are allowed to be
// used as constructors.
if (instance.isAsmJS()) {
fun.set(NewNativeConstructor(cx, WasmCall, numArgs, name, gc::AllocKind::FUNCTION_EXTENDED,
SingletonObject, JSFunction::ASMJS_CTOR));
} else {
fun.set(NewNativeFunction(cx, WasmCall, numArgs, name, gc::AllocKind::FUNCTION_EXTENDED));
}
if (!fun)
return false;