Merge inbound to mozilla-central. a=merge

This commit is contained in:
Brindusan Cristian 2019-03-26 02:26:12 +02:00
Родитель 139cb1eebf 676cfa3d56
Коммит c4f15a4dae
23 изменённых файлов: 363 добавлений и 205 удалений

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

@ -41,6 +41,7 @@ export function willNavigate(event: Object) {
clearASTs();
clearScopes();
clearSources();
client.detachWorkers();
dispatch(navigate(event.url));
};
}

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

@ -27,7 +27,8 @@ const threadClient = {
source: "function foo1() {\n const foo = 5; return foo;\n}",
contentType: "text/javascript"
}),
getBreakpointPositions: async () => ({})
getBreakpointPositions: async () => ({}),
detachWorkers: () => {}
};
describe("navigation", () => {
@ -67,7 +68,7 @@ describe("navigation", () => {
});
it("navigation removes activeSearch 'project' value", async () => {
const { dispatch, getState } = createStore();
const { dispatch, getState } = createStore(threadClient);
dispatch(actions.setActiveSearch("project"));
expect(getActiveSearch(getState())).toBe("project");
@ -76,7 +77,7 @@ describe("navigation", () => {
});
it("navigation clears the file-search query", async () => {
const { dispatch, getState } = createStore();
const { dispatch, getState } = createStore(threadClient);
dispatch(actions.setFileSearchQuery("foobar"));
expect(getFileSearchQuery(getState())).toBe("foobar");
@ -87,7 +88,7 @@ describe("navigation", () => {
});
it("navigation clears the file-search results", async () => {
const { dispatch, getState } = createStore();
const { dispatch, getState } = createStore(threadClient);
const searchResults = [{ line: 1, ch: 3 }, { line: 3, ch: 2 }];
dispatch(actions.updateSearchResults(2, 3, searchResults));
@ -109,7 +110,7 @@ describe("navigation", () => {
});
it("navigation removes activeSearch 'file' value", async () => {
const { dispatch, getState } = createStore();
const { dispatch, getState } = createStore(threadClient);
dispatch(actions.setActiveSearch("file"));
expect(getActiveSearch(getState())).toBe("file");

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

@ -187,6 +187,12 @@ function waitForWorkers(shouldWait: boolean) {
shouldWaitForWorkers = shouldWait;
}
function detachWorkers() {
for (const thread of listWorkerThreadClients()) {
thread.detach();
}
}
function maybeGenerateLogGroupId(options) {
if (options.logValue && tabTarget.traits && tabTarget.traits.canRewind) {
return { ...options, logGroupId: `logGroup-${Math.random()}` };
@ -485,7 +491,8 @@ const clientCommands = {
sendPacket,
setSkipPausing,
setEventListenerBreakpoints,
waitForWorkers
waitForWorkers,
detachWorkers
};
export { setupCommands, clientCommands };

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

@ -479,6 +479,15 @@ class OffThreadPromiseRuntimeState;
// OffThreadPromiseTask for the promise, and let the embedding's network I/O
// threads call dispatchResolveAndDestroy.
//
// OffThreadPromiseTask may also be used purely on the main thread, as a way to
// "queue a task" in HTML terms. Note that a "task" is not the same as a
// "microtask" and there are separate queues for tasks and microtasks that are
// drained at separate times in the browser. The task queue is implemented by
// the browser's main event loop. The microtask queue is implemented
// by JS::JobQueue, used for promises and gets drained before returning to
// the event loop. Thus OffThreadPromiseTask can only be used when the spec
// says "queue a task", as the WebAssembly APIs do.
//
// An OffThreadPromiseTask has a JSContext, and must be constructed and have its
// 'init' method called on that JSContext's thread. Once initialized, its
// dispatchResolveAndDestroy method may be called from any thread. This is the

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

@ -0,0 +1,47 @@
const { Module, Instance, Global, instantiate, instantiateStreaming } = WebAssembly;
const g = new Global({value: "i32", mutable:true}, 0);
const code = wasmTextToBinary(`(module
(global $g (import "" "g") (mut i32))
(func $start (set_global $g (i32.add (get_global $g) (i32.const 1))))
(start $start)
)`);
const module = new Module(code);
const importObj = { '': { get g() { g.value++; return g } } };
g.value = 0;
new Instance(module, importObj);
assertEq(g.value, 2);
g.value = 0;
instantiate(module, importObj).then(i => {
assertEq(i instanceof Instance, true);
assertEq(g.value, 2);
g.value++;
});
assertEq(g.value, 1);
drainJobQueue();
assertEq(g.value, 3);
g.value = 0;
instantiate(code, importObj).then(({module,instance}) => {
assertEq(module instanceof Module, true);
assertEq(instance instanceof Instance, true);
assertEq(g.value, 2); g.value++; }
);
drainJobQueue();
assertEq(g.value, 3);
if (wasmStreamingIsSupported()) {
g.value = 0;
instantiateStreaming(code, importObj).then(({module,instance}) => {
assertEq(module instanceof Module, true);
assertEq(instance instanceof Instance, true);
assertEq(g.value, 2);
g.value++;
});
drainJobQueue();
assertEq(g.value, 3);
}

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

@ -2147,6 +2147,9 @@ namespace JS {
* as when it is later consumed.
*/
using OptimizedEncodingBytes = js::Vector<uint8_t, 0, js::SystemAllocPolicy>;
using UniqueOptimizedEncodingBytes = js::UniquePtr<OptimizedEncodingBytes>;
class OptimizedEncodingListener {
protected:
virtual ~OptimizedEncodingListener() {}
@ -2159,7 +2162,7 @@ class OptimizedEncodingListener {
// SpiderMonkey may optionally call storeOptimizedEncoding() after it has
// finished processing a streamed resource.
virtual void storeOptimizedEncoding(const uint8_t* bytes, size_t length) = 0;
virtual void storeOptimizedEncoding(UniqueOptimizedEncodingBytes bytes) = 0;
};
class JS_PUBLIC_API StreamConsumer {

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

@ -6909,9 +6909,8 @@ class StreamCacheEntry : public AtomicRefCounted<StreamCacheEntry>,
const Uint8Vector& bytes() const { return bytes_; }
void storeOptimizedEncoding(const uint8_t* srcBytes,
size_t srcLength) override {
MOZ_ASSERT(srcLength > 0);
void storeOptimizedEncoding(JS::UniqueOptimizedEncodingBytes src) override {
MOZ_ASSERT(src->length() > 0);
// Tolerate races since a single StreamCacheEntry object can be used as
// the source of multiple streaming compilations.
@ -6920,10 +6919,10 @@ class StreamCacheEntry : public AtomicRefCounted<StreamCacheEntry>,
return;
}
if (!dstBytes->resize(srcLength)) {
if (!dstBytes->resize(src->length())) {
return;
}
memcpy(dstBytes->begin(), srcBytes, srcLength);
memcpy(dstBytes->begin(), src->begin(), src->length());
}
bool hasOptimizedEncoding() const { return !optimized_.lock()->empty(); }

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

@ -6779,8 +6779,7 @@ static bool CheckBuffer(JSContext* cx, const AsmJSMetadata& metadata,
static bool GetImports(JSContext* cx, const AsmJSMetadata& metadata,
HandleValue globalVal, HandleValue importVal,
MutableHandle<FunctionVector> funcImports,
MutableHandleValVector valImports) {
ImportValues* imports) {
Rooted<FunctionVector> ffis(cx, FunctionVector(cx));
if (!ffis.resize(metadata.numFFIs)) {
return false;
@ -6793,7 +6792,7 @@ static bool GetImports(JSContext* cx, const AsmJSMetadata& metadata,
if (!ValidateGlobalVariable(cx, global, importVal, &litVal)) {
return false;
}
if (!valImports.append(Val(litVal->asLitVal()))) {
if (!imports->globalValues.append(Val(litVal->asLitVal()))) {
return false;
}
break;
@ -6823,7 +6822,7 @@ static bool GetImports(JSContext* cx, const AsmJSMetadata& metadata,
}
for (const AsmJSImport& import : metadata.asmJSImports) {
if (!funcImports.append(ffis[import.ffiIndex()])) {
if (!imports->funcs.append(ffis[import.ffiIndex()])) {
return false;
}
}
@ -6845,30 +6844,27 @@ static bool TryInstantiate(JSContext* cx, CallArgs args, const Module& module,
return LinkFail(cx, "no compiler support");
}
RootedArrayBufferObjectMaybeShared buffer(cx);
RootedWasmMemoryObject memory(cx);
Rooted<ImportValues> imports(cx);
if (module.metadata().usesMemory()) {
RootedArrayBufferObjectMaybeShared buffer(cx);
if (!CheckBuffer(cx, metadata, bufferVal, &buffer)) {
return false;
}
memory = WasmMemoryObject::create(cx, buffer, nullptr);
if (!memory) {
imports.get().memory = WasmMemoryObject::create(cx, buffer, nullptr);
if (!imports.get().memory) {
return false;
}
}
RootedValVector valImports(cx);
Rooted<FunctionVector> funcs(cx, FunctionVector(cx));
if (!GetImports(cx, metadata, globalVal, importVal, &funcs, &valImports)) {
if (!GetImports(cx, metadata, globalVal, importVal, imports.address())) {
return false;
}
Rooted<WasmGlobalObjectVector> globalObjs(cx);
Rooted<WasmTableObjectVector> tables(cx);
if (!module.instantiate(cx, funcs, tables.get(), memory, valImports,
globalObjs.get(), nullptr, instanceObj))
if (!module.instantiate(cx, imports.get(), nullptr, instanceObj)) {
return false;
}
exportObj.set(&instanceObj->exportsObj());
return true;

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

@ -1223,7 +1223,7 @@ static Maybe<ABIFunctionType> ToBuiltinABIFunctionType(
return Some(ABIFunctionType(abiType));
}
void* wasm::MaybeGetBuiltinThunk(HandleFunction f, const FuncType& funcType) {
void* wasm::MaybeGetBuiltinThunk(JSFunction* f, const FuncType& funcType) {
MOZ_ASSERT(builtinThunks);
if (!f->isNative() || !f->hasJitInfo() ||

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

@ -93,7 +93,7 @@ void* HandleThrow(JSContext* cx, WasmFrameIter& iter);
void* SymbolicAddressTarget(SymbolicAddress sym);
void* MaybeGetBuiltinThunk(HandleFunction f, const FuncType& funcType);
void* MaybeGetBuiltinThunk(JSFunction* f, const FuncType& funcType);
void ReleaseBuiltinThunks();

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

@ -1078,8 +1078,8 @@ Instance::Instance(JSContext* cx, Handle<WasmInstanceObject*> object,
SharedCode code, UniqueTlsData tlsDataIn,
HandleWasmMemoryObject memory, SharedTableVector&& tables,
StructTypeDescrVector&& structTypeDescrs,
Handle<FunctionVector> funcImports,
HandleValVector globalImportValues,
const JSFunctionVector& funcImports,
const ValVector& globalImportValues,
const WasmGlobalObjectVector& globalObjs,
UniqueDebugState maybeDebug)
: realm_(cx->realm()),
@ -1120,7 +1120,7 @@ Instance::Instance(JSContext* cx, Handle<WasmInstanceObject*> object,
Tier callerTier = code_->bestTier();
for (size_t i = 0; i < metadata(callerTier).funcImports.length(); i++) {
HandleFunction f = funcImports[i];
JSFunction* f = funcImports[i];
const FuncImport& fi = metadata(callerTier).funcImports[i];
FuncImportTls& import = funcImportTls(fi);
import.fun = f;
@ -1171,7 +1171,7 @@ Instance::Instance(JSContext* cx, Handle<WasmInstanceObject*> object,
if (global.isIndirect()) {
*(void**)globalAddr = globalObjs[imported]->cell();
} else {
CopyValPostBarriered(globalAddr, globalImportValues[imported].get());
CopyValPostBarriered(globalAddr, globalImportValues[imported]);
}
break;
}
@ -1193,8 +1193,7 @@ Instance::Instance(JSContext* cx, Handle<WasmInstanceObject*> object,
// the source global should never be indirect.
MOZ_ASSERT(!imported.isIndirect());
RootedVal dest(cx,
globalImportValues[imported.importIndex()].get());
RootedVal dest(cx, globalImportValues[imported.importIndex()]);
if (global.isIndirect()) {
void* address = globalObjs[i]->cell();
*(void**)globalAddr = address;

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

@ -74,8 +74,8 @@ class Instance {
Instance(JSContext* cx, HandleWasmInstanceObject object, SharedCode code,
UniqueTlsData tlsData, HandleWasmMemoryObject memory,
SharedTableVector&& tables, StructTypeDescrVector&& structTypeDescrs,
Handle<FunctionVector> funcImports,
HandleValVector globalImportValues,
const JSFunctionVector& funcImports,
const ValVector& globalImportValues,
const WasmGlobalObjectVector& globalObjs,
UniqueDebugState maybeDebug);
~Instance();

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

@ -241,14 +241,8 @@ static bool GetProperty(JSContext* cx, HandleObject obj, const char* chars,
}
static bool GetImports(JSContext* cx, const Module& module,
HandleObject importObj,
MutableHandle<FunctionVector> funcImports,
WasmTableObjectVector& tableImports,
MutableHandleWasmMemoryObject memoryImport,
WasmGlobalObjectVector& globalObjs,
MutableHandleValVector globalImportValues) {
const ImportVector& imports = module.imports();
if (!imports.empty() && !importObj) {
HandleObject importObj, ImportValues* imports) {
if (!module.imports().empty() && !importObj) {
return ThrowBadImportArg(cx);
}
@ -258,7 +252,7 @@ static bool GetImports(JSContext* cx, const Module& module,
const GlobalDescVector& globals = metadata.globals;
uint32_t tableIndex = 0;
const TableDescVector& tables = metadata.tables;
for (const Import& import : imports) {
for (const Import& import : module.imports()) {
RootedValue v(cx);
if (!GetProperty(cx, importObj, import.module.get(), &v)) {
return false;
@ -282,7 +276,7 @@ static bool GetImports(JSContext* cx, const Module& module,
return ThrowBadImportType(cx, import.field.get(), "Function");
}
if (!funcImports.append(&v.toObject().as<JSFunction>())) {
if (!imports->funcs.append(&v.toObject().as<JSFunction>())) {
return false;
}
@ -301,7 +295,7 @@ static bool GetImports(JSContext* cx, const Module& module,
return false;
}
if (!tableImports.append(obj)) {
if (!imports->tables.append(obj)) {
return false;
}
break;
@ -311,8 +305,8 @@ static bool GetImports(JSContext* cx, const Module& module,
return ThrowBadImportType(cx, import.field.get(), "Memory");
}
MOZ_ASSERT(!memoryImport);
memoryImport.set(&v.toObject().as<WasmMemoryObject>());
MOZ_ASSERT(!imports->memory);
imports->memory = &v.toObject().as<WasmMemoryObject>();
break;
}
case DefinitionKind::Global: {
@ -335,11 +329,12 @@ static bool GetImports(JSContext* cx, const Module& module,
return false;
}
if (globalObjs.length() <= index && !globalObjs.resize(index + 1)) {
if (imports->globalObjs.length() <= index &&
!imports->globalObjs.resize(index + 1)) {
ReportOutOfMemory(cx);
return false;
}
globalObjs[index] = obj;
imports->globalObjs[index] = obj;
obj->val(&val);
} else {
if (IsNumberType(global.type())) {
@ -371,7 +366,7 @@ static bool GetImports(JSContext* cx, const Module& module,
}
}
if (!globalImportValues.append(val)) {
if (!imports->globalValues.append(val)) {
return false;
}
@ -450,19 +445,12 @@ bool wasm::Eval(JSContext* cx, Handle<TypedArrayObject*> code,
return false;
}
Rooted<FunctionVector> funcs(cx, FunctionVector(cx));
Rooted<WasmTableObjectVector> tables(cx);
RootedWasmMemoryObject memory(cx);
Rooted<WasmGlobalObjectVector> globalObjs(cx);
RootedValVector globals(cx);
if (!GetImports(cx, *module, importObj, &funcs, tables.get(), &memory,
globalObjs.get(), &globals)) {
Rooted<ImportValues> imports(cx);
if (!GetImports(cx, *module, importObj, imports.address())) {
return false;
}
return module->instantiate(cx, funcs, tables.get(), memory, globals,
globalObjs.get(), nullptr, instanceObj);
return module->instantiate(cx, imports.get(), nullptr, instanceObj);
}
struct MOZ_STACK_CLASS SerializeListener : JS::OptimizedEncodingListener {
@ -474,11 +462,11 @@ struct MOZ_STACK_CLASS SerializeListener : JS::OptimizedEncodingListener {
Bytes* serialized;
explicit SerializeListener(Bytes* serialized) : serialized(serialized) {}
void storeOptimizedEncoding(const uint8_t* bytes, size_t length) override {
void storeOptimizedEncoding(JS::UniqueOptimizedEncodingBytes bytes) override {
MOZ_ASSERT(!called);
called = true;
if (serialized->resize(length)) {
memcpy(serialized->begin(), bytes, length);
if (serialized->resize(bytes->length())) {
memcpy(serialized->begin(), bytes->begin(), bytes->length());
}
}
};
@ -1250,8 +1238,8 @@ WasmInstanceObject* WasmInstanceObject::create(
const ElemSegmentVector& elemSegments, UniqueTlsData tlsData,
HandleWasmMemoryObject memory, SharedTableVector&& tables,
StructTypeDescrVector&& structTypeDescrs,
Handle<FunctionVector> funcImports, const GlobalDescVector& globals,
HandleValVector globalImportValues,
const JSFunctionVector& funcImports, const GlobalDescVector& globals,
const ValVector& globalImportValues,
const WasmGlobalObjectVector& globalObjs, HandleObject proto,
UniqueDebugState maybeDebug) {
UniquePtr<ExportMap> exports = js::MakeUnique<ExportMap>();
@ -1345,27 +1333,6 @@ static bool GetImportArg(JSContext* cx, CallArgs callArgs,
return true;
}
static bool Instantiate(JSContext* cx, const Module& module,
HandleObject importObj,
MutableHandleWasmInstanceObject instanceObj) {
RootedObject instanceProto(
cx, &cx->global()->getPrototype(JSProto_WasmInstance).toObject());
Rooted<FunctionVector> funcs(cx, FunctionVector(cx));
Rooted<WasmTableObjectVector> tables(cx);
RootedWasmMemoryObject memory(cx);
Rooted<WasmGlobalObjectVector> globalObjs(cx);
RootedValVector globals(cx);
if (!GetImports(cx, module, importObj, &funcs, tables.get(), &memory,
globalObjs.get(), &globals)) {
return false;
}
return module.instantiate(cx, funcs, tables.get(), memory, globals,
globalObjs.get(), instanceProto, instanceObj);
}
/* static */
bool WasmInstanceObject::construct(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
@ -1392,8 +1359,16 @@ bool WasmInstanceObject::construct(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
RootedObject instanceProto(
cx, &cx->global()->getPrototype(JSProto_WasmInstance).toObject());
Rooted<ImportValues> imports(cx);
if (!GetImports(cx, *module, importObj, imports.address())) {
return false;
}
RootedWasmInstanceObject instanceObj(cx);
if (!Instantiate(cx, *module, importObj, &instanceObj)) {
if (!module->instantiate(cx, imports.get(), instanceProto, &instanceObj)) {
return false;
}
@ -2866,30 +2841,47 @@ static bool Reject(JSContext* cx, const CompileArgs& args,
return PromiseObject::reject(cx, promise, rejectionValue);
}
static bool Resolve(JSContext* cx, const Module& module,
Handle<PromiseObject*> promise, bool instantiate,
HandleObject importObj, const UniqueCharsVector& warnings,
const char* methodSuffix = "") {
if (!ReportCompileWarnings(cx, warnings)) {
return false;
}
enum class Ret { Pair, Instance };
RootedObject proto(
cx, &cx->global()->getPrototype(JSProto_WasmModule).toObject());
RootedObject moduleObj(cx, WasmModuleObject::create(cx, module, proto));
if (!moduleObj) {
class AsyncInstantiateTask : public OffThreadPromiseTask {
SharedModule module_;
PersistentRooted<ImportValues> imports_;
Ret ret_;
public:
AsyncInstantiateTask(JSContext* cx, const Module& module, Ret ret,
Handle<PromiseObject*> promise)
: OffThreadPromiseTask(cx, promise),
module_(&module),
imports_(cx),
ret_(ret) {}
ImportValues& imports() { return imports_.get(); }
bool resolve(JSContext* cx, Handle<PromiseObject*> promise) override {
RootedObject instanceProto(
cx, &cx->global()->getPrototype(JSProto_WasmInstance).toObject());
RootedWasmInstanceObject instanceObj(cx);
if (!module_->instantiate(cx, imports_.get(), instanceProto,
&instanceObj)) {
return RejectWithPendingException(cx, promise);
}
RootedValue resolutionValue(cx);
if (instantiate) {
RootedWasmInstanceObject instanceObj(cx);
if (!Instantiate(cx, module, importObj, &instanceObj)) {
if (ret_ == Ret::Instance) {
resolutionValue = ObjectValue(*instanceObj);
} else {
RootedObject resultObj(cx, JS_NewPlainObject(cx));
if (!resultObj) {
return RejectWithPendingException(cx, promise);
}
RootedObject resultObj(cx, JS_NewPlainObject(cx));
if (!resultObj) {
RootedObject moduleProto(
cx, &cx->global()->getPrototype(JSProto_WasmModule).toObject());
RootedObject moduleObj(
cx, WasmModuleObject::create(cx, *module_, moduleProto));
if (!moduleObj) {
return RejectWithPendingException(cx, promise);
}
@ -2899,23 +2891,54 @@ static bool Resolve(JSContext* cx, const Module& module,
}
val = ObjectValue(*instanceObj);
if (!JS_DefineProperty(cx, resultObj, "instance", val, JSPROP_ENUMERATE)) {
if (!JS_DefineProperty(cx, resultObj, "instance", val,
JSPROP_ENUMERATE)) {
return RejectWithPendingException(cx, promise);
}
resolutionValue = ObjectValue(*resultObj);
} else {
MOZ_ASSERT(!importObj);
resolutionValue = ObjectValue(*moduleObj);
}
if (!PromiseObject::resolve(cx, promise, resolutionValue)) {
return RejectWithPendingException(cx, promise);
}
Log(cx, "async %s%s() succeeded", (instantiate ? "instantiate" : "compile"),
methodSuffix);
Log(cx, "async instantiate succeeded");
return true;
}
};
static bool AsyncInstantiate(JSContext* cx, const Module& module,
HandleObject importObj, Ret ret,
Handle<PromiseObject*> promise) {
auto task = js::MakeUnique<AsyncInstantiateTask>(cx, module, ret, promise);
if (!task || !task->init(cx)) {
return false;
}
if (!GetImports(cx, module, importObj, &task->imports())) {
return RejectWithPendingException(cx, promise);
}
task.release()->dispatchResolveAndDestroy();
return true;
}
static bool ResolveCompile(JSContext* cx, const Module& module,
Handle<PromiseObject*> promise) {
RootedObject proto(
cx, &cx->global()->getPrototype(JSProto_WasmModule).toObject());
RootedObject moduleObj(cx, WasmModuleObject::create(cx, module, proto));
if (!moduleObj) {
return RejectWithPendingException(cx, promise);
}
RootedValue resolutionValue(cx, ObjectValue(*moduleObj));
if (!PromiseObject::resolve(cx, promise, resolutionValue)) {
return RejectWithPendingException(cx, promise);
}
Log(cx, "async compile succeeded");
return true;
}
@ -2950,9 +2973,16 @@ struct CompileBufferTask : PromiseHelperTask {
}
bool resolve(JSContext* cx, Handle<PromiseObject*> promise) override {
return module
? Resolve(cx, *module, promise, instantiate, importObj, warnings)
: Reject(cx, *compileArgs, promise, error);
if (!module) {
return Reject(cx, *compileArgs, promise, error);
}
if (!ReportCompileWarnings(cx, warnings)) {
return false;
}
if (instantiate) {
return AsyncInstantiate(cx, *module, importObj, Ret::Pair, promise);
}
return ResolveCompile(cx, *module, promise);
}
};
@ -3063,17 +3093,9 @@ static bool WebAssembly_instantiate(JSContext* cx, unsigned argc, Value* vp) {
const Module* module;
if (IsModuleObject(firstArg, &module)) {
RootedWasmInstanceObject instanceObj(cx);
if (!Instantiate(cx, *module, importObj, &instanceObj)) {
return RejectWithPendingException(cx, promise, callArgs);
}
RootedValue resolutionValue(cx, ObjectValue(*instanceObj));
if (!PromiseObject::resolve(cx, promise, resolutionValue)) {
if (!AsyncInstantiate(cx, *module, importObj, Ret::Instance, promise)) {
return false;
}
Log(cx, "async instantiate() succeeded");
} else {
auto task = cx->make_unique<CompileBufferTask>(cx, promise, importObj);
if (!task || !task->init(cx, "WebAssembly.instantiate")) {
@ -3410,8 +3432,13 @@ class CompileStreamTask : public PromiseHelperTask, public JS::StreamConsumer {
if (module_) {
MOZ_ASSERT(!streamFailed_ && !streamError_ && !compileError_);
return Resolve(cx, *module_, promise, instantiate_, importObj_, warnings_,
"Streaming");
if (!ReportCompileWarnings(cx, warnings_)) {
return false;
}
if (instantiate_) {
return AsyncInstantiate(cx, *module_, importObj_, Ret::Pair, promise);
}
return ResolveCompile(cx, *module_, promise);
}
if (streamError_) {

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

@ -245,8 +245,9 @@ class WasmInstanceObject : public NativeObject {
Vector<RefPtr<wasm::Table>, 0, SystemAllocPolicy>&& tables,
GCVector<HeapPtr<StructTypeDescr*>, 0, SystemAllocPolicy>&&
structTypeDescrs,
Handle<FunctionVector> funcImports, const wasm::GlobalDescVector& globals,
wasm::HandleValVector globalImportValues,
const JSFunctionVector& funcImports,
const wasm::GlobalDescVector& globals,
const wasm::ValVector& globalImportValues,
const WasmGlobalObjectVector& globalObjs, HandleObject proto,
UniquePtr<wasm::DebugState> maybeDebug);
void initExportsObj(JSObject& exportsObj);

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

@ -310,14 +310,14 @@ MutableModule Module::deserialize(const uint8_t* begin, size_t size,
void Module::serialize(const LinkData& linkData,
JS::OptimizedEncodingListener& listener) const {
Vector<uint8_t, 0, SystemAllocPolicy> bytes;
if (!bytes.resize(serializedSize(linkData))) {
auto bytes = MakeUnique<JS::OptimizedEncodingBytes>();
if (!bytes || !bytes->resize(serializedSize(linkData))) {
return;
}
serialize(linkData, bytes.begin(), bytes.length());
serialize(linkData, bytes->begin(), bytes->length());
listener.storeOptimizedEncoding(bytes.begin(), bytes.length());
listener.storeOptimizedEncoding(std::move(bytes));
}
/* virtual */
@ -560,22 +560,22 @@ bool Module::extractCode(JSContext* cx, Tier tier,
return true;
}
static uint32_t EvaluateInitExpr(HandleValVector globalImportValues,
static uint32_t EvaluateInitExpr(const ValVector& globalImportValues,
InitExpr initExpr) {
switch (initExpr.kind()) {
case InitExpr::Kind::Constant:
return initExpr.val().i32();
case InitExpr::Kind::GetGlobal:
return globalImportValues[initExpr.globalIndex()].get().i32();
return globalImportValues[initExpr.globalIndex()].i32();
}
MOZ_CRASH("bad initializer expression");
}
bool Module::initSegments(JSContext* cx, HandleWasmInstanceObject instanceObj,
Handle<FunctionVector> funcImports,
const JSFunctionVector& funcImports,
HandleWasmMemoryObject memoryObj,
HandleValVector globalImportValues) const {
const ValVector& globalImportValues) const {
MOZ_ASSERT_IF(!memoryObj, dataSegments_.empty());
Instance& instance = instanceObj->instance();
@ -707,7 +707,7 @@ static const Import& FindImportForFuncImport(const ImportVector& imports,
}
bool Module::instantiateFunctions(JSContext* cx,
Handle<FunctionVector> funcImports) const {
const JSFunctionVector& funcImports) const {
#ifdef DEBUG
for (auto t : code().tiers()) {
MOZ_ASSERT(funcImports.length() == metadata(t).funcImports.length());
@ -721,7 +721,7 @@ bool Module::instantiateFunctions(JSContext* cx,
Tier tier = code().stableTier();
for (size_t i = 0; i < metadata(tier).funcImports.length(); i++) {
HandleFunction f = funcImports[i];
JSFunction* f = funcImports[i];
if (!IsExportedFunction(f) || ExportedFunctionToInstance(f).isAsmJS()) {
continue;
}
@ -904,7 +904,7 @@ bool Module::instantiateLocalTable(JSContext* cx, const TableDesc& td,
}
bool Module::instantiateTables(JSContext* cx,
WasmTableObjectVector& tableImports,
const WasmTableObjectVector& tableImports,
MutableHandle<WasmTableObjectVector> tableObjs,
SharedTableVector* tables) const {
uint32_t tableIndex = 0;
@ -925,7 +925,7 @@ bool Module::instantiateTables(JSContext* cx,
return true;
}
static void ExtractGlobalValue(HandleValVector globalImportValues,
static void ExtractGlobalValue(const ValVector& globalImportValues,
uint32_t globalIndex, const GlobalDesc& global,
MutableHandleVal result) {
switch (global.kind()) {
@ -954,7 +954,7 @@ static void ExtractGlobalValue(HandleValVector globalImportValues,
}
static bool EnsureGlobalObject(JSContext* cx,
HandleValVector globalImportValues,
const ValVector& globalImportValues,
size_t globalIndex, const GlobalDesc& global,
WasmGlobalObjectVector& globalObjs) {
if (globalIndex < globalObjs.length() && globalObjs[globalIndex]) {
@ -980,7 +980,7 @@ static bool EnsureGlobalObject(JSContext* cx,
}
bool Module::instantiateGlobals(JSContext* cx,
HandleValVector globalImportValues,
const ValVector& globalImportValues,
WasmGlobalObjectVector& globalObjs) const {
// If there are exported globals that aren't in globalObjs because they
// originate in this module or because they were immutable imports that came
@ -1083,7 +1083,7 @@ SharedCode Module::getDebugEnabledCode() const {
static bool GetFunctionExport(JSContext* cx,
HandleWasmInstanceObject instanceObj,
Handle<FunctionVector> funcImports,
const JSFunctionVector& funcImports,
const Export& exp, MutableHandleValue val) {
if (exp.funcIndex() < funcImports.length() &&
IsExportedWasmFunction(funcImports[exp.funcIndex()])) {
@ -1103,7 +1103,7 @@ static bool GetFunctionExport(JSContext* cx,
static bool CreateExportObject(JSContext* cx,
HandleWasmInstanceObject instanceObj,
Handle<FunctionVector> funcImports,
const JSFunctionVector& funcImports,
const WasmTableObjectVector& tableObjs,
HandleWasmMemoryObject memoryObj,
const WasmGlobalObjectVector& globalObjs,
@ -1335,20 +1335,16 @@ bool Module::makeStructTypeDescrs(
#endif
}
bool Module::instantiate(JSContext* cx, Handle<FunctionVector> funcImports,
WasmTableObjectVector& tableImports,
HandleWasmMemoryObject memoryImport,
HandleValVector globalImportValues,
WasmGlobalObjectVector& globalObjs,
bool Module::instantiate(JSContext* cx, ImportValues& imports,
HandleObject instanceProto,
MutableHandleWasmInstanceObject instance) const {
MOZ_RELEASE_ASSERT(cx->wasmHaveSignalHandlers);
if (!instantiateFunctions(cx, funcImports)) {
if (!instantiateFunctions(cx, imports.funcs)) {
return false;
}
RootedWasmMemoryObject memory(cx, memoryImport);
RootedWasmMemoryObject memory(cx, imports.memory);
if (!instantiateMemory(cx, &memory)) {
return false;
}
@ -1358,11 +1354,11 @@ bool Module::instantiate(JSContext* cx, Handle<FunctionVector> funcImports,
Rooted<WasmTableObjectVector> tableObjs(cx);
SharedTableVector tables;
if (!instantiateTables(cx, tableImports, &tableObjs, &tables)) {
if (!instantiateTables(cx, imports.tables, &tableObjs, &tables)) {
return false;
}
if (!instantiateGlobals(cx, globalImportValues, globalObjs)) {
if (!instantiateGlobals(cx, imports.globalValues, imports.globalObjs)) {
return false;
}
@ -1398,15 +1394,15 @@ bool Module::instantiate(JSContext* cx, Handle<FunctionVector> funcImports,
instance.set(WasmInstanceObject::create(
cx, code, dataSegments_, elemSegments_, std::move(tlsData), memory,
std::move(tables), std::move(structTypeDescrs.get()), funcImports,
metadata().globals, globalImportValues, globalObjs, instanceProto,
std::move(maybeDebug)));
std::move(tables), std::move(structTypeDescrs.get()), imports.funcs,
metadata().globals, imports.globalValues, imports.globalObjs,
instanceProto, std::move(maybeDebug)));
if (!instance) {
return false;
}
if (!CreateExportObject(cx, instance, funcImports, tableObjs.get(), memory,
globalObjs, exports_)) {
if (!CreateExportObject(cx, instance, imports.funcs, tableObjs.get(), memory,
imports.globalObjs, exports_)) {
return false;
}
@ -1423,7 +1419,8 @@ bool Module::instantiate(JSContext* cx, Handle<FunctionVector> funcImports,
// constructed since this can make the instance live to content (even if the
// start function fails).
if (!initSegments(cx, instance, funcImports, memory, globalImportValues)) {
if (!initSegments(cx, instance, imports.funcs, memory,
imports.globalValues)) {
return false;
}

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

@ -34,6 +34,31 @@ struct CompileArgs;
typedef RefPtr<JS::OptimizedEncodingListener> Tier2Listener;
// A struct containing the typed, imported values that are harvested from the
// import object and passed to Module::instantiate(). This struct must be
// stored in a (Persistent)Rooted, not in the heap due to its use of TraceRoot()
// and complete lack of barriers.
struct ImportValues {
JSFunctionVector funcs;
WasmTableObjectVector tables;
WasmMemoryObject* memory;
WasmGlobalObjectVector globalObjs;
ValVector globalValues;
ImportValues() : memory(nullptr) {}
void trace(JSTracer* trc) {
funcs.trace(trc);
tables.trace(trc);
if (memory) {
TraceRoot(trc, &memory, "import values memory");
}
globalObjs.trace(trc);
globalValues.trace(trc);
}
};
// Module represents a compiled wasm module and primarily provides three
// operations: instantiation, tiered compilation, serialization. A Module can be
// instantiated any number of times to produce new Instance objects. A Module
@ -82,7 +107,7 @@ class Module : public JS::WasmModule {
mutable Atomic<bool> testingTier2Active_;
bool instantiateFunctions(JSContext* cx,
Handle<FunctionVector> funcImports) const;
const JSFunctionVector& funcImports) const;
bool instantiateMemory(JSContext* cx,
MutableHandleWasmMemoryObject memory) const;
bool instantiateImportedTable(JSContext* cx, const TableDesc& td,
@ -92,15 +117,16 @@ class Module : public JS::WasmModule {
bool instantiateLocalTable(JSContext* cx, const TableDesc& td,
WasmTableObjectVector* tableObjs,
SharedTableVector* tables) const;
bool instantiateTables(JSContext* cx, WasmTableObjectVector& tableImports,
bool instantiateTables(JSContext* cx,
const WasmTableObjectVector& tableImports,
MutableHandle<WasmTableObjectVector> tableObjs,
SharedTableVector* tables) const;
bool instantiateGlobals(JSContext* cx, HandleValVector globalImportValues,
bool instantiateGlobals(JSContext* cx, const ValVector& globalImportValues,
WasmGlobalObjectVector& globalObjs) const;
bool initSegments(JSContext* cx, HandleWasmInstanceObject instance,
Handle<FunctionVector> funcImports,
const JSFunctionVector& funcImports,
HandleWasmMemoryObject memory,
HandleValVector globalImportValues) const;
const ValVector& globalImportValues) const;
SharedCode getDebugEnabledCode() const;
bool makeStructTypeDescrs(
JSContext* cx,
@ -144,11 +170,7 @@ class Module : public JS::WasmModule {
// Instantiate this module with the given imports:
bool instantiate(JSContext* cx, Handle<FunctionVector> funcImports,
WasmTableObjectVector& tableImport,
HandleWasmMemoryObject memoryImport,
HandleValVector globalImportValues,
WasmGlobalObjectVector& globalObjs,
bool instantiate(JSContext* cx, ImportValues& imports,
HandleObject instanceProto,
MutableHandleWasmInstanceObject instanceObj) const;

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

@ -49,6 +49,8 @@ enum class RoundingMode;
// This is a widespread header, so lets keep out the core wasm impl types.
typedef GCVector<JSFunction*, 0, SystemAllocPolicy> JSFunctionVector;
class WasmMemoryObject;
typedef GCPtr<WasmMemoryObject*> GCPtrWasmMemoryObject;
typedef Rooted<WasmMemoryObject*> RootedWasmMemoryObject;
@ -748,11 +750,10 @@ class LitVal {
}
};
// A Val is a LitVal that can contain pointers to JSObjects, thanks to their
// trace implementation. Since a Val is able to store a pointer to a JSObject,
// it needs to be traced during compilation in case the pointee is moved.
// The classic shorthands for Rooted things are defined after this class, for
// easier usage.
// A Val is a LitVal that can contain (non-null) pointers to GC things. All Vals
// must be stored in Rooteds so that their trace() methods are called during
// stack marking. Vals do not implement barriers and thus may not be stored on
// the heap.
class MOZ_NON_PARAM Val : public LitVal {
public:
@ -773,10 +774,10 @@ typedef Rooted<Val> RootedVal;
typedef Handle<Val> HandleVal;
typedef MutableHandle<Val> MutableHandleVal;
typedef GCVector<Val, 0, SystemAllocPolicy> GCVectorVal;
typedef Rooted<GCVectorVal> RootedValVector;
typedef Handle<GCVectorVal> HandleValVector;
typedef MutableHandle<GCVectorVal> MutableHandleValVector;
typedef GCVector<Val, 0, SystemAllocPolicy> ValVector;
typedef Rooted<ValVector> RootedValVector;
typedef Handle<ValVector> HandleValVector;
typedef MutableHandle<ValVector> MutableHandleValVector;
// The FuncType class represents a WebAssembly function signature which takes a
// list of value types and returns an expression type. The engine uses two

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

@ -42,3 +42,6 @@ pref("browser.safebrowsing.features.malware.update", true);
// Enable Tracking Protection blocklist updates
pref("browser.safebrowsing.features.trackingAnnotation.update", true);
pref("browser.safebrowsing.features.trackingProtection.update", true);
// Enable cryptomining protection blocklist updates
pref("browser.safebrowsing.features.cryptomining.update", true);

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

@ -12,6 +12,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
GeckoViewTelemetryController: "resource://gre/modules/GeckoViewTelemetryController.jsm",
L10nRegistry: "resource://gre/modules/L10nRegistry.jsm",
Preferences: "resource://gre/modules/Preferences.jsm",
SafeBrowsing: "resource://gre/modules/SafeBrowsing.jsm",
Services: "resource://gre/modules/Services.jsm",
});
@ -125,6 +126,10 @@ GeckoViewStartup.prototype = {
ChromeUtils.import("resource://gre/modules/NotificationDB.jsm");
// Initialize safe browsing module. This is required for content
// blocking features and manages blocklist downloads and updates.
SafeBrowsing.init();
// Listen for global EventDispatcher messages
EventDispatcher.instance.registerListener(this,
["GeckoView:ResetUserPrefs",

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

@ -43,9 +43,10 @@ package org.mozilla.geckoview {
@android.support.annotation.AnyThread public class ContentBlocking {
ctor public ContentBlocking();
field public static final int AT_AD = 2;
field public static final int AT_ALL = 62;
field public static final int AT_ALL = 126;
field public static final int AT_ANALYTIC = 4;
field public static final int AT_CONTENT = 16;
field public static final int AT_CRYPTOMINING = 64;
field public static final int AT_SOCIAL = 8;
field public static final int AT_TEST = 32;
field public static final int COOKIE_ACCEPT_ALL = 0;

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

@ -75,6 +75,12 @@ public class ContentBlocking {
"urlclassifier.trackingTable",
ContentBlocking.catToAtPref(
AT_TEST | AT_ANALYTIC | AT_SOCIAL | AT_AD));
/* package */ final Pref<Boolean> mCm = new Pref<Boolean>(
"privacy.trackingprotection.cryptomining.enabled", false);
/* package */ final Pref<String> mCmList = new Pref<String>(
"urlclassifier.features.cryptomining.blacklistTables",
ContentBlocking.catToCmListPref(NONE));
/* package */ final Pref<Boolean> mSbMalware = new Pref<Boolean>(
"browser.safebrowsing.malware.enabled", true);
/* package */ final Pref<Boolean> mSbPhishing = new Pref<Boolean>(
@ -130,6 +136,10 @@ public class ContentBlocking {
*/
public @NonNull Settings setCategories(final @Category int cat) {
mAt.commit(ContentBlocking.catToAtPref(cat));
mCm.commit(ContentBlocking.catToCmPref(cat));
mCmList.commit(ContentBlocking.catToCmListPref(cat));
mSbMalware.commit(ContentBlocking.catToSbMalware(cat));
mSbPhishing.commit(ContentBlocking.catToSbPhishing(cat));
return this;
@ -141,7 +151,8 @@ public class ContentBlocking {
* @return The categories of resources to be blocked.
*/
public @Category int getCategories() {
return ContentBlocking.listToCat(mAt.get())
return ContentBlocking.atListToCat(mAt.get())
| ContentBlocking.cmListToCat(mCmList.get())
| ContentBlocking.sbMalwareToCat(mSbMalware.get())
| ContentBlocking.sbPhishingToCat(mSbPhishing.get());
}
@ -195,7 +206,7 @@ public class ContentBlocking {
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true,
value = { NONE, AT_AD, AT_ANALYTIC, AT_SOCIAL, AT_CONTENT,
AT_ALL, AT_TEST,
AT_ALL, AT_TEST, AT_CRYPTOMINING,
SB_MALWARE, SB_UNWANTED,
SB_HARMFUL, SB_PHISHING })
/* package */ @interface Category {}
@ -228,11 +239,17 @@ public class ContentBlocking {
*/
public static final int AT_TEST = 1 << 5;
/**
* Block cryptocurrency miners.
*/
public static final int AT_CRYPTOMINING = 1 << 6;
/**
* Block all known trackers.
* Blocks all {@link #AT_AD AT_*} types.
*/
public static final int AT_ALL =
AT_AD | AT_ANALYTIC | AT_SOCIAL | AT_CONTENT | AT_TEST;
AT_AD | AT_ANALYTIC | AT_SOCIAL | AT_CONTENT | AT_TEST | AT_CRYPTOMINING;
// Safe browsing
/**
@ -350,7 +367,8 @@ public class ContentBlocking {
@Category int cats = NONE;
if (matchedList != null) {
cats = ContentBlocking.listToCat(matchedList);
cats = ContentBlocking.atListToCat(matchedList) |
ContentBlocking.cmListToCat(matchedList);
} else if (error != 0L) {
cats = ContentBlocking.errorToCat(error);
}
@ -383,6 +401,8 @@ public class ContentBlocking {
private static final String ANALYTIC = "analytics-track-digest256";
private static final String SOCIAL = "social-track-digest256";
private static final String CONTENT = "content-track-digest256";
private static final String CRYPTOMINING =
"base-cryptomining-track-digest256";
/* package */ static @Category int sbMalwareToCat(final boolean enabled) {
return enabled ? (SB_MALWARE | SB_UNWANTED | SB_HARMFUL)
@ -427,7 +447,20 @@ public class ContentBlocking {
return builder.substring(0, builder.length() - 1);
}
/* package */ static @Category int listToCat(final String list) {
/* package */ static boolean catToCmPref(@Category final int cat) {
return (cat & AT_CRYPTOMINING) != 0;
}
/* package */ static String catToCmListPref(@Category final int cat) {
StringBuilder builder = new StringBuilder();
if ((cat & AT_CRYPTOMINING) != 0) {
builder.append(CRYPTOMINING);
}
return builder.toString();
}
/* package */ static @Category int atListToCat(final String list) {
int cat = 0;
if (list.indexOf(TEST) != -1) {
cat |= AT_TEST;
@ -447,6 +480,14 @@ public class ContentBlocking {
return cat;
}
/* package */ static @Category int cmListToCat(final String list) {
int cat = 0;
if (list.indexOf(CRYPTOMINING) != -1) {
cat |= AT_CRYPTOMINING;
}
return cat;
}
/* package */ static @Category int errorToCat(final long error) {
// Match flags with XPCOM ErrorList.h.
if (error == 0x805D001FL) {

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

@ -18,6 +18,10 @@ exclude: true
[68.2]: ../GeckoSession.ProgressDelegate.html
- Added [`ContentBlocking#AT_CRYPTOMINING`][68.3] for cryptocurrency miner blocking.
[68.3]: ../ContentBlocking.html#AT_CRYPTOMINING
## v67
- Added [`setAutomaticFontSizeAdjustment`][67.2] to
[`GeckoRuntimeSettings`][67.3] for automatically adjusting font size settings
@ -224,4 +228,4 @@ exclude: true
[65.24]: ../CrashReporter.html#sendCrashReport-android.content.Context-android.os.Bundle-java.lang.String-
[65.25]: ../GeckoResult.html
[api-version]: e8fa4ed799e78f64fddd3f2c463202942811de11
[api-version]: e48935ac13c3a907d46d50bb2b00f5e84d30ef4b

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

@ -9,10 +9,6 @@ var EXPORTED_SYMBOLS = ["GeckoViewSettings"];
const {GeckoViewModule} = ChromeUtils.import("resource://gre/modules/GeckoViewModule.jsm");
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetters(this, {
SafeBrowsing: "resource://gre/modules/SafeBrowsing.jsm",
});
XPCOMUtils.defineLazyGetter(
this, "MOBILE_USER_AGENT",
function() {
@ -45,11 +41,9 @@ const USER_AGENT_MODE_VR = 2;
class GeckoViewSettings extends GeckoViewModule {
onInit() {
debug `onInit`;
this._useTrackingProtection = false;
this._userAgentMode = USER_AGENT_MODE_MOBILE;
this._userAgentOverride = null;
// Required for safe browsing and tracking protection.
SafeBrowsing.init();
this.registerListener([
"GeckoView:GetUserAgent",