mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1252498 - Baldr: add Wasm object behind pref, default off (r=jorendorff)
MozReview-Commit-ID: BlhrURAX26H --HG-- extra : rebase_source : e1b540f06c2f3976f91242ac7b0b8ede29fbc5f2
This commit is contained in:
parent
1e69d4c08b
commit
b5a255ff58
@ -301,6 +301,7 @@ LoadRuntimeOptions(const char* aPrefName, void* /* aClosure */)
|
||||
// Runtime options.
|
||||
JS::RuntimeOptions runtimeOptions;
|
||||
runtimeOptions.setAsmJS(GetWorkerPref<bool>(NS_LITERAL_CSTRING("asmjs")))
|
||||
.setWasm(GetWorkerPref<bool>(NS_LITERAL_CSTRING("wasm")))
|
||||
.setThrowOnAsmJSValidationFailure(GetWorkerPref<bool>(
|
||||
NS_LITERAL_CSTRING("throw_on_asmjs_validation_failure")))
|
||||
.setBaseline(GetWorkerPref<bool>(NS_LITERAL_CSTRING("baselinejit")))
|
||||
|
@ -1333,3 +1333,80 @@ wasm::Eval(JSContext* cx, Handle<ArrayBufferObject*> code,
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
InstantiateModule(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
MOZ_ASSERT(cx->runtime()->options().wasm());
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (!args.get(0).isObject() || !args.get(0).toObject().is<ArrayBufferObject>()) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_BUF_ARG);
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedObject importObj(cx);
|
||||
if (!args.get(1).isUndefined()) {
|
||||
if (!args.get(1).isObject()) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMPORT_ARG);
|
||||
return false;
|
||||
}
|
||||
importObj = &args[1].toObject();
|
||||
}
|
||||
|
||||
Rooted<ArrayBufferObject*> code(cx, &args[0].toObject().as<ArrayBufferObject>());
|
||||
|
||||
RootedObject exportObj(cx);
|
||||
if (!Eval(cx, code, importObj, &exportObj))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*exportObj);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if JS_HAS_TOSOURCE
|
||||
static bool
|
||||
wasm_toSource(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
args.rval().setString(cx->names().Wasm);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static JSFunctionSpec wasm_static_methods[] = {
|
||||
#if JS_HAS_TOSOURCE
|
||||
JS_FN(js_toSource_str, wasm_toSource, 0, 0),
|
||||
#endif
|
||||
JS_FN("instantiateModule", InstantiateModule, 1, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
const Class js::WasmClass = {
|
||||
js_Wasm_str,
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Wasm)
|
||||
};
|
||||
|
||||
JSObject*
|
||||
js::InitWasmClass(JSContext* cx, HandleObject global)
|
||||
{
|
||||
MOZ_ASSERT(cx->runtime()->options().wasm());
|
||||
|
||||
RootedObject proto(cx, global->as<GlobalObject>().getOrCreateObjectPrototype(cx));
|
||||
if (!proto)
|
||||
return nullptr;
|
||||
|
||||
RootedObject Wasm(cx, NewObjectWithGivenProto(cx, &WasmClass, proto, SingletonObject));
|
||||
if (!Wasm)
|
||||
return nullptr;
|
||||
|
||||
if (!JS_DefineProperty(cx, global, js_Wasm_str, Wasm, JSPROP_RESOLVING))
|
||||
return nullptr;
|
||||
|
||||
if (!JS_DefineFunctions(cx, Wasm, wasm_static_methods))
|
||||
return nullptr;
|
||||
|
||||
global->as<GlobalObject>().setConstructor(JSProto_Wasm, ObjectValue(*Wasm));
|
||||
return Wasm;
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,10 @@
|
||||
#ifndef wasm_h
|
||||
#define wasm_h
|
||||
|
||||
#include "NamespaceImports.h"
|
||||
|
||||
#include "gc/Rooting.h"
|
||||
#include "js/Class.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
@ -31,8 +34,8 @@ namespace wasm {
|
||||
bool
|
||||
HasCompilerSupport(ExclusiveContext* cx);
|
||||
|
||||
// The WebAssembly spec hard-codes the virtual page size to be 64KiB and limits
|
||||
// forces the linear memory to always be a multiple of 64KiB.
|
||||
// The WebAssembly spec hard-codes the virtual page size to be 64KiB and
|
||||
// requires linear memory to always be a multiple of 64KiB.
|
||||
static const unsigned PageSize = 64 * 1024;
|
||||
|
||||
// When signal handling is used for bounds checking, MappedSize bytes are
|
||||
@ -46,10 +49,18 @@ static const uint64_t MappedSize = 2 * Uint32Range + PageSize;
|
||||
// Compiles the given binary wasm module given the ArrayBufferObject
|
||||
// and links the module's imports with the given import object.
|
||||
bool
|
||||
Eval(JSContext* cx, JS::Handle<ArrayBufferObject*> code,
|
||||
JS::HandleObject importObj, JS::MutableHandleObject exportObj);
|
||||
Eval(JSContext* cx, Handle<ArrayBufferObject*> code, HandleObject importObj,
|
||||
MutableHandleObject exportObj);
|
||||
|
||||
} // namespace wasm
|
||||
|
||||
// Initialization of the Wasm global object and its properties.
|
||||
|
||||
extern const Class WasmClass;
|
||||
|
||||
JSObject*
|
||||
InitWasmClass(JSContext* cx, HandleObject global);
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif // namespace wasm_h
|
||||
|
@ -501,42 +501,7 @@ static bool
|
||||
WasmIsSupported(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
args.rval().setBoolean(wasm::HasCompilerSupport(cx));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
WasmEval(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
RootedObject callee(cx, &args.callee());
|
||||
|
||||
if (args.length() < 1 || args.length() > 2) {
|
||||
ReportUsageError(cx, callee, "Wrong number of arguments");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!args[0].isObject() || !args[0].toObject().is<ArrayBufferObject>()) {
|
||||
ReportUsageError(cx, callee, "First argument must be an ArrayBuffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedObject importObj(cx);
|
||||
if (!args.get(1).isUndefined()) {
|
||||
if (!args.get(1).isObject()) {
|
||||
ReportUsageError(cx, callee, "Second argument, if present, must be an Object");
|
||||
return false;
|
||||
}
|
||||
importObj = &args[1].toObject();
|
||||
}
|
||||
|
||||
Rooted<ArrayBufferObject*> code(cx, &args[0].toObject().as<ArrayBufferObject>());
|
||||
|
||||
RootedObject exportObj(cx);
|
||||
if (!wasm::Eval(cx, code, importObj, &exportObj))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*exportObj);
|
||||
args.rval().setBoolean(wasm::HasCompilerSupport(cx) && cx->runtime()->options().wasm());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3711,11 +3676,6 @@ gc::ZealModeHelpText),
|
||||
"wasmIsSupported()",
|
||||
" Returns a boolean indicating whether WebAssembly is supported on the current device."),
|
||||
|
||||
JS_FN_HELP("wasmEval", WasmEval, 2, 0,
|
||||
"wasmEval(buffer, imports)",
|
||||
" Compiles the given binary wasm module given by 'buffer' (which must be an ArrayBuffer)\n"
|
||||
" and links the module's imports with the given 'imports' object."),
|
||||
|
||||
JS_FN_HELP("wasmTextToBinary", WasmTextToBinary, 1, 0,
|
||||
"wasmTextToBinary(str)",
|
||||
" Translates the given text wasm module into its binary encoding."),
|
||||
|
@ -4,7 +4,7 @@ if (!wasmIsSupported())
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
function wasmEvalText(str, imports) {
|
||||
return wasmEval(wasmTextToBinary(str), imports);
|
||||
return Wasm.instantiateModule(wasmTextToBinary(str), imports);
|
||||
}
|
||||
|
||||
function mismatchError(actual, expect) {
|
||||
|
@ -96,8 +96,8 @@ if (!hasI64) {
|
||||
// ----------------------------------------------------------------------------
|
||||
// imports
|
||||
|
||||
assertErrorMessage(() => wasmEvalText('(module (import "a" "b"))', 1), Error, /Second argument, if present, must be an Object/);
|
||||
assertErrorMessage(() => wasmEvalText('(module (import "a" "b"))', null), Error, /Second argument, if present, must be an Object/);
|
||||
assertErrorMessage(() => wasmEvalText('(module (import "a" "b"))', 1), Error, /second argument, if present, must be an object/);
|
||||
assertErrorMessage(() => wasmEvalText('(module (import "a" "b"))', null), Error, /second argument, if present, must be an object/);
|
||||
|
||||
const noImportObj = /no import object given/;
|
||||
const notObject = /import object field is not an Object/;
|
||||
|
@ -53,6 +53,8 @@ function moduleHeaderThen(...rest) {
|
||||
return [magic0, magic1, magic2, magic3, ver0, ver1, ver2, ver3, ...rest];
|
||||
}
|
||||
|
||||
const wasmEval = Wasm.instantiateModule;
|
||||
|
||||
assertErrorMessage(() => wasmEval(toBuf([])), TypeError, magicError);
|
||||
assertErrorMessage(() => wasmEval(toBuf([42])), TypeError, magicError);
|
||||
assertErrorMessage(() => wasmEval(toBuf([magic0, magic1, magic2])), TypeError, magicError);
|
||||
|
@ -366,6 +366,8 @@ MSG_DEF(JSMSG_WASM_FAIL, 1, JSEXN_TYPEERR, "wasm error: {0}")
|
||||
MSG_DEF(JSMSG_WASM_DECODE_FAIL, 2, JSEXN_TYPEERR, "wasm validation error at offset {0}: {1}")
|
||||
MSG_DEF(JSMSG_WASM_TEXT_FAIL, 1, JSEXN_SYNTAXERR, "wasm text error: {0}")
|
||||
MSG_DEF(JSMSG_WASM_BAD_IND_CALL, 0, JSEXN_ERR, "wasm indirect call signature mismatch")
|
||||
MSG_DEF(JSMSG_WASM_BAD_BUF_ARG, 0, JSEXN_TYPEERR, "first argument must be an ArrayBuffer")
|
||||
MSG_DEF(JSMSG_WASM_BAD_IMPORT_ARG, 0, JSEXN_TYPEERR, "second argument, if present, must be an object")
|
||||
|
||||
// Proxy
|
||||
MSG_DEF(JSMSG_BAD_TRAP_RETURN_VALUE, 2, JSEXN_TYPEERR,"trap {1} for {0} returned a primitive value")
|
||||
|
@ -1109,6 +1109,7 @@ class JS_PUBLIC_API(RuntimeOptions) {
|
||||
: baseline_(true),
|
||||
ion_(true),
|
||||
asmJS_(true),
|
||||
wasm_(false),
|
||||
throwOnAsmJSValidationFailure_(false),
|
||||
nativeRegExp_(true),
|
||||
unboxedArrays_(false),
|
||||
@ -1156,6 +1157,16 @@ class JS_PUBLIC_API(RuntimeOptions) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool wasm() const { return wasm_; }
|
||||
RuntimeOptions& setWasm(bool flag) {
|
||||
wasm_ = flag;
|
||||
return *this;
|
||||
}
|
||||
RuntimeOptions& toggleWasm() {
|
||||
wasm_ = !wasm_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool throwOnAsmJSValidationFailure() const { return throwOnAsmJSValidationFailure_; }
|
||||
RuntimeOptions& setThrowOnAsmJSValidationFailure(bool flag) {
|
||||
throwOnAsmJSValidationFailure_ = flag;
|
||||
@ -1236,6 +1247,7 @@ class JS_PUBLIC_API(RuntimeOptions) {
|
||||
bool baseline_ : 1;
|
||||
bool ion_ : 1;
|
||||
bool asmJS_ : 1;
|
||||
bool wasm_ : 1;
|
||||
bool throwOnAsmJSValidationFailure_ : 1;
|
||||
bool nativeRegExp_ : 1;
|
||||
bool unboxedArrays_ : 1;
|
||||
|
@ -106,9 +106,10 @@ IF_BDATA(real,imaginary)(TypedObject, 40, InitTypedObjectModuleObj
|
||||
real(Reflect, 41, InitReflect, nullptr) \
|
||||
IF_SIMD(real,imaginary)(SIMD, 42, InitSimdClass, OCLASP(Simd)) \
|
||||
real(WeakSet, 43, InitWeakSetClass, OCLASP(WeakSet)) \
|
||||
real(TypedArray, 44, InitViaClassSpec, &js::TypedArrayObject::sharedTypedArrayPrototypeClass) \
|
||||
IF_SAB(real,imaginary)(Atomics, 45, InitAtomicsClass, OCLASP(Atomics)) \
|
||||
real(SavedFrame, 46, InitViaClassSpec, &js::SavedFrame::class_) \
|
||||
real(TypedArray, 44, InitViaClassSpec, &js::TypedArrayObject::sharedTypedArrayPrototypeClass) \
|
||||
IF_SAB(real,imaginary)(Atomics, 45, InitAtomicsClass, OCLASP(Atomics)) \
|
||||
real(SavedFrame, 46, InitViaClassSpec, &js::SavedFrame::class_) \
|
||||
real(Wasm, 47, InitWasmClass, CLASP(Wasm)) \
|
||||
|
||||
#define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro)
|
||||
|
||||
|
@ -6586,6 +6586,7 @@ SetRuntimeOptions(JSRuntime* rt, const OptionParser& op)
|
||||
JS::RuntimeOptionsRef(rt).setBaseline(enableBaseline)
|
||||
.setIon(enableIon)
|
||||
.setAsmJS(enableAsmJS)
|
||||
.setWasm(true)
|
||||
.setNativeRegExp(enableNativeRegExp)
|
||||
.setUnboxedArrays(enableUnboxedArrays);
|
||||
|
||||
@ -6843,6 +6844,7 @@ SetWorkerRuntimeOptions(JSRuntime* rt)
|
||||
JS::RuntimeOptionsRef(rt).setBaseline(enableBaseline)
|
||||
.setIon(enableIon)
|
||||
.setAsmJS(enableAsmJS)
|
||||
.setWasm(true)
|
||||
.setNativeRegExp(enableNativeRegExp)
|
||||
.setUnboxedArrays(enableUnboxedArrays);
|
||||
rt->setOffthreadIonCompilationEnabled(offthreadCompilation);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "jsprototypes.h"
|
||||
#include "jsweakmap.h"
|
||||
|
||||
#include "asmjs/Wasm.h"
|
||||
#include "builtin/AtomicsObject.h"
|
||||
#include "builtin/Eval.h"
|
||||
#if EXPOSE_INTL_API
|
||||
@ -94,6 +95,9 @@ js::GlobalObject::getTypedObjectModule() const {
|
||||
/* static */ bool
|
||||
GlobalObject::skipDeselectedConstructor(JSContext* cx, JSProtoKey key)
|
||||
{
|
||||
if (key == JSProto_Wasm)
|
||||
return !cx->runtime()->options().wasm();
|
||||
|
||||
#ifdef ENABLE_SHARED_ARRAY_BUFFER
|
||||
// Return true if the given constructor has been disabled at run-time.
|
||||
switch (key) {
|
||||
|
@ -31,11 +31,11 @@ namespace js {
|
||||
*
|
||||
* (If you're wondering, 0xb973c0de is used because it looks like "bytecode".)
|
||||
*/
|
||||
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 348;
|
||||
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 349;
|
||||
static const uint32_t XDR_BYTECODE_VERSION =
|
||||
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
|
||||
|
||||
static_assert(JSErr_Limit == 445,
|
||||
static_assert(JSErr_Limit == 447,
|
||||
"GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
|
||||
"removed MSG_DEFs from js.msg, you should increment "
|
||||
"XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "
|
||||
|
@ -1542,6 +1542,7 @@ ReloadPrefsCallback(const char* pref, void* data)
|
||||
bool useBaseline = Preferences::GetBool(JS_OPTIONS_DOT_STR "baselinejit") && !safeMode;
|
||||
bool useIon = Preferences::GetBool(JS_OPTIONS_DOT_STR "ion") && !safeMode;
|
||||
bool useAsmJS = Preferences::GetBool(JS_OPTIONS_DOT_STR "asmjs") && !safeMode;
|
||||
bool useWasm = Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm") && !safeMode;
|
||||
bool throwOnAsmJSValidationFailure = Preferences::GetBool(JS_OPTIONS_DOT_STR
|
||||
"throw_on_asmjs_validation_failure");
|
||||
bool useNativeRegExp = Preferences::GetBool(JS_OPTIONS_DOT_STR "native_regexp") && !safeMode;
|
||||
@ -1576,6 +1577,7 @@ ReloadPrefsCallback(const char* pref, void* data)
|
||||
JS::RuntimeOptionsRef(rt).setBaseline(useBaseline)
|
||||
.setIon(useIon)
|
||||
.setAsmJS(useAsmJS)
|
||||
.setWasm(useWasm)
|
||||
.setThrowOnAsmJSValidationFailure(throwOnAsmJSValidationFailure)
|
||||
.setNativeRegExp(useNativeRegExp)
|
||||
.setAsyncStack(useAsyncStack)
|
||||
|
@ -984,7 +984,8 @@ ProcessArgsForCompartment(JSContext* cx, char** argv, int argc)
|
||||
break;
|
||||
case 'I':
|
||||
RuntimeOptionsRef(cx).toggleIon()
|
||||
.toggleAsmJS();
|
||||
.toggleAsmJS()
|
||||
.toggleWasm();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1143,6 +1143,7 @@ pref("javascript.options.strict.debug", false);
|
||||
pref("javascript.options.baselinejit", true);
|
||||
pref("javascript.options.ion", true);
|
||||
pref("javascript.options.asmjs", true);
|
||||
pref("javascript.options.wasm", false);
|
||||
pref("javascript.options.native_regexp", true);
|
||||
pref("javascript.options.parallel_parsing", true);
|
||||
#if !defined(RELEASE_BUILD) && !defined(ANDROID) && !defined(MOZ_B2G) && !defined(XP_IOS)
|
||||
|
Loading…
Reference in New Issue
Block a user