mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 11:57:32 +09:00
Issue #1691 - Part 8: Fix --enable-debug builds and continue dynamic module import changes. https://bugzilla.mozilla.org/show_bug.cgi?id=1342012 Support import from timeout handlers by associating the initiating script with the compiled JSScript. Fix error message that covers all import() failures that don't throw a JS exception. https://bugzilla.mozilla.org/show_bug.cgi?id=1331662 Partial - Replace nsJSUtils::EvaluateString calls by ExecutionContext scopes. Left EvaluateString() in nsXBLProtoImplField.cpp until ExecutionContext errors can be fixed.
(cherry picked from commit 22fcfc77971a9bb204df664c474681f4dcf54211)
This commit is contained in:
parent
c69a47c393
commit
1109559a5d
20 changed files with 166 additions and 24 deletions
|
|
@ -224,6 +224,7 @@
|
|||
#include "mozilla/dom/PrimitiveConversions.h"
|
||||
#include "mozilla/dom/WindowBinding.h"
|
||||
#include "nsITabChild.h"
|
||||
#include "mozilla/dom/ModuleScript.h"
|
||||
#include "mozilla/dom/MediaQueryList.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/NavigatorBinding.h"
|
||||
|
|
@ -12937,9 +12938,6 @@ nsGlobalWindow::RunTimeoutHandler(Timeout* aTimeout,
|
|||
RefPtr<Function> callback = handler->GetCallback();
|
||||
|
||||
if (!callback) {
|
||||
// Evaluate the timeout expression.
|
||||
const nsAString& script = handler->GetHandlerText();
|
||||
|
||||
const char* filename = nullptr;
|
||||
uint32_t lineNo = 0, dummyColumn = 0;
|
||||
handler->GetLocation(&filename, &lineNo, &dummyColumn);
|
||||
|
|
@ -12950,9 +12948,22 @@ nsGlobalWindow::RunTimeoutHandler(Timeout* aTimeout,
|
|||
AutoEntryScript aes(this, reason, true);
|
||||
JS::CompileOptions options(aes.cx());
|
||||
options.setFileAndLine(filename, lineNo).setVersion(JSVERSION_DEFAULT);
|
||||
options.setNoScriptRval(true);
|
||||
JS::Rooted<JSObject*> global(aes.cx(), FastGetGlobalJSObject());
|
||||
nsresult rv =
|
||||
nsJSUtils::EvaluateString(aes.cx(), script, global, options);
|
||||
nsresult rv;
|
||||
{
|
||||
nsJSUtils::ExecutionContext exec(aes.cx(), global);
|
||||
rv = exec.Compile(options, handler->GetHandlerText());
|
||||
|
||||
if (rv == NS_OK) {
|
||||
LoadedScript* initiatingScript = handler->GetInitiatingScript();
|
||||
if (initiatingScript) {
|
||||
initiatingScript->AssociateWithScript(exec.GetScript());
|
||||
}
|
||||
|
||||
rv = exec.ExecScript();
|
||||
}
|
||||
}
|
||||
if (rv == NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE) {
|
||||
abortIntervalHandler = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Function;
|
||||
class LoadedScript;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
@ -44,6 +45,9 @@ public:
|
|||
|
||||
// If we have a Function, get the arguments for passing to it.
|
||||
virtual const nsTArray<JS::Value>& GetArgs() = 0;
|
||||
|
||||
// If we have an expression, get the initiating script.
|
||||
virtual mozilla::dom::LoadedScript* GetInitiatingScript() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptTimeoutHandler,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
#include "mozilla/dom/ModuleScript.h"
|
||||
#include "nsAXPCNativeCallContext.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
|
@ -44,6 +45,7 @@ public:
|
|||
nsTArray<JS::Heap<JS::Value>>&& aArguments,
|
||||
ErrorResult& aError);
|
||||
nsJSScriptTimeoutHandler(JSContext* aCx, nsGlobalWindow* aWindow,
|
||||
LoadedScript* aInitiatingScript,
|
||||
const nsAString& aExpression, bool* aAllowEval,
|
||||
ErrorResult& aError);
|
||||
nsJSScriptTimeoutHandler(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
|
|
@ -77,6 +79,10 @@ public:
|
|||
*aColumn = mColumn;
|
||||
}
|
||||
|
||||
virtual LoadedScript* GetInitiatingScript() override {
|
||||
return mInitiatingScript;
|
||||
}
|
||||
|
||||
virtual void MarkForCC() override
|
||||
{
|
||||
if (mFunction) {
|
||||
|
|
@ -104,6 +110,9 @@ private:
|
|||
// it should be used, else use mExpr.
|
||||
nsString mExpr;
|
||||
RefPtr<Function> mFunction;
|
||||
|
||||
// Initiating script for use when evaluating mExpr on the main thread.
|
||||
RefPtr<LoadedScript> mInitiatingScript;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -112,6 +121,8 @@ private:
|
|||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSScriptTimeoutHandler)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSScriptTimeoutHandler)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFunction)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mInitiatingScript)
|
||||
tmp->ReleaseJSObjects();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSScriptTimeoutHandler)
|
||||
|
|
@ -151,6 +162,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSScriptTimeoutHandler)
|
|||
if (tmp->mFunction) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFunction)
|
||||
}
|
||||
if (tmp->mInitiatingScript) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInitiatingScript)
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSScriptTimeoutHandler)
|
||||
|
|
@ -243,12 +257,14 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
|
|||
|
||||
nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
|
||||
nsGlobalWindow *aWindow,
|
||||
LoadedScript* aInitiatingScript,
|
||||
const nsAString& aExpression,
|
||||
bool* aAllowEval,
|
||||
ErrorResult& aError)
|
||||
: mLineNo(0)
|
||||
, mColumn(0)
|
||||
, mExpr(aExpression)
|
||||
, mInitiatingScript(aInitiatingScript)
|
||||
{
|
||||
if (!aWindow->GetContextInternal() || !aWindow->FastGetGlobalJSObject()) {
|
||||
// This window was already closed, or never properly initialized,
|
||||
|
|
@ -352,9 +368,11 @@ already_AddRefed<nsIScriptTimeoutHandler>
|
|||
NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow,
|
||||
const nsAString& aExpression, ErrorResult& aError)
|
||||
{
|
||||
LoadedScript* script = ScriptLoader::GetActiveScript(aCx);
|
||||
|
||||
bool allowEval = false;
|
||||
RefPtr<nsJSScriptTimeoutHandler> handler =
|
||||
new nsJSScriptTimeoutHandler(aCx, aWindow, aExpression, &allowEval, aError);
|
||||
new nsJSScriptTimeoutHandler(aCx, aWindow, script, aExpression, &allowEval, aError);
|
||||
if (aError.Failed() || !allowEval) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
|
|||
, mRv(NS_OK)
|
||||
, mSkip(false)
|
||||
, mCoerceToString(false)
|
||||
, mEncodeBytecode(false)
|
||||
#ifdef DEBUG
|
||||
, mWantsReturnValue(false)
|
||||
, mExpectScopeChain(false)
|
||||
|
|
@ -150,7 +151,6 @@ nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
|
|||
{
|
||||
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(nsContentUtils::IsInMicroTask());
|
||||
MOZ_ASSERT(mRetValue.isUndefined());
|
||||
|
||||
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aGlobal) == aGlobal);
|
||||
|
|
@ -207,7 +207,7 @@ nsJSUtils::ExecutionContext::JoinCompile(void** aOffThreadToken)
|
|||
return mRv;
|
||||
}
|
||||
|
||||
if (!StartIncrementalEncoding(mCx, mScript)) {
|
||||
if (mEncodeBytecode && !StartIncrementalEncoding(mCx, mScript)) {
|
||||
mSkip = true;
|
||||
mRv = EvaluationExceptionToNSResult(mCx);
|
||||
return mRv;
|
||||
|
|
@ -246,7 +246,7 @@ nsJSUtils::ExecutionContext::Compile(JS::CompileOptions& aCompileOptions,
|
|||
return mRv;
|
||||
}
|
||||
|
||||
if (!StartIncrementalEncoding(mCx, mScript)) {
|
||||
if (mEncodeBytecode && !StartIncrementalEncoding(mCx, mScript)) {
|
||||
mSkip = true;
|
||||
mRv = EvaluationExceptionToNSResult(mCx);
|
||||
return mRv;
|
||||
|
|
@ -340,6 +340,19 @@ nsresult nsJSUtils::ExecutionContext::ExecScript() {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool IsPromiseValue(JSContext* aCx, JS::Handle<JS::Value> aValue) {
|
||||
if (!aValue.isObject()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, js::CheckedUnwrap(&aValue.toObject()));
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return JS::IsPromiseObject(obj);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSUtils::ExecutionContext::ExecScript(JS::MutableHandle<JS::Value> aRetValue)
|
||||
{
|
||||
|
|
@ -359,6 +372,15 @@ nsJSUtils::ExecutionContext::ExecScript(JS::MutableHandle<JS::Value> aRetValue)
|
|||
#ifdef DEBUG
|
||||
mWantsReturnValue = false;
|
||||
#endif
|
||||
if (mCoerceToString && IsPromiseValue(mCx, aRetValue)) {
|
||||
// We're a javascript: url and we should treat Promise return values as
|
||||
// undefined.
|
||||
//
|
||||
// Once bug 1477821 is fixed this code might be able to go away, or will
|
||||
// become enshrined in the spec, depending.
|
||||
aRetValue.setUndefined();
|
||||
}
|
||||
|
||||
if (mCoerceToString && !aRetValue.isUndefined()) {
|
||||
JSString* str = JS::ToString(mCx, aRetValue);
|
||||
if (!str) {
|
||||
|
|
|
|||
|
|
@ -90,6 +90,9 @@ public:
|
|||
// Should the result be serialized before being returned.
|
||||
bool mCoerceToString;
|
||||
|
||||
// Encode the bytecode before it is being executed.
|
||||
bool mEncodeBytecode;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Should we set the return value.
|
||||
bool mWantsReturnValue;
|
||||
|
|
|
|||
|
|
@ -275,10 +275,14 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
|
|||
JS::CompileOptions options(cx);
|
||||
options.setFileAndLine(mURL.get(), 1)
|
||||
.setVersion(JSVERSION_DEFAULT);
|
||||
nsJSUtils::EvaluateOptions evalOptions(cx);
|
||||
evalOptions.setCoerceToString(true);
|
||||
rv = nsJSUtils::EvaluateString(cx, NS_ConvertUTF8toUTF16(script),
|
||||
globalJSObject, options, evalOptions, &v);
|
||||
{
|
||||
nsJSUtils::ExecutionContext exec(cx, globalJSObject);
|
||||
exec.SetCoerceToString(true);
|
||||
exec.Compile(options, NS_ConvertUTF8toUTF16(script));
|
||||
rv = exec.ExecScript(&v);
|
||||
}
|
||||
|
||||
js::AssertSameCompartment(cx, v);
|
||||
|
||||
if (NS_FAILED(rv) || !(v.isString() || v.isUndefined())) {
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
|
|
|
|||
|
|
@ -1388,14 +1388,23 @@ _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result)
|
|||
options.setFileAndLine(spec, 0)
|
||||
.setVersion(JSVERSION_DEFAULT);
|
||||
JS::Rooted<JS::Value> rval(cx);
|
||||
nsJSUtils::EvaluateOptions evalOptions(cx);
|
||||
JS::AutoObjectVector scopeChain(cx);
|
||||
if (obj != js::GetGlobalForObjectCrossCompartment(obj) &&
|
||||
!evalOptions.scopeChain.append(obj)) {
|
||||
!scopeChain.append(obj)) {
|
||||
return false;
|
||||
}
|
||||
obj = js::GetGlobalForObjectCrossCompartment(obj);
|
||||
nsresult rv = nsJSUtils::EvaluateString(cx, utf16script, obj, options,
|
||||
evalOptions, &rval);
|
||||
nsresult rv = NS_OK;
|
||||
{
|
||||
nsJSUtils::ExecutionContext exec(cx, obj);
|
||||
exec.SetScopeChain(scopeChain);
|
||||
exec.Compile(options, utf16script);
|
||||
rv = exec.ExecScript(&rval);
|
||||
}
|
||||
|
||||
if (!JS_WrapValue(cx, &rval)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return NS_SUCCEEDED(rv) &&
|
||||
(!result || JSValToNPVariant(npp, cx, rval, result));
|
||||
|
|
|
|||
|
|
@ -1072,7 +1072,7 @@ void ScriptLoader::FinishDynamicImport(JSContext* aCx,
|
|||
if (NS_FAILED(aResult)) {
|
||||
MOZ_ASSERT(!JS_IsExceptionPending(aCx));
|
||||
JS_ReportErrorNumberUC(aCx, js::GetErrorMessage, nullptr,
|
||||
JSMSG_IMPORT_SCRIPT_NOT_FOUND);
|
||||
JSMSG_DYNAMIC_IMPORT_FAILED);
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> referencingScript(aCx,
|
||||
|
|
@ -2374,6 +2374,15 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
|
|||
return rv;
|
||||
}
|
||||
|
||||
/* static */ LoadedScript* ScriptLoader::GetActiveScript(JSContext* aCx) {
|
||||
JS::Value value = JS::GetScriptedCallerPrivate(aCx);
|
||||
if (value.isUndefined()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return static_cast<LoadedScript*>(value.toPrivate());
|
||||
}
|
||||
|
||||
void
|
||||
ScriptLoader::ProcessPendingRequestsAsync()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
|
||||
class AutoJSAPI;
|
||||
class LoadedScript;
|
||||
class ModuleLoadRequest;
|
||||
class ModuleScript;
|
||||
class ScriptLoadRequestList;
|
||||
|
|
@ -586,6 +587,12 @@ public:
|
|||
void FinishDynamicImport(JSContext* aCx, ModuleLoadRequest* aRequest,
|
||||
nsresult aResult);
|
||||
|
||||
/*
|
||||
* Get the currently active script. This is used as the initiating script when
|
||||
* executing timeout handler scripts.
|
||||
*/
|
||||
static LoadedScript* GetActiveScript(JSContext* aCx);
|
||||
|
||||
nsIDocument* GetDocument() const { return mDocument; }
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ XPIDL_MODULE = 'dom'
|
|||
EXPORTS += ['nsIScriptElement.h']
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'ModuleScript.h',
|
||||
'ScriptElement.h',
|
||||
'ScriptLoader.h',
|
||||
'ScriptSettings.h',
|
||||
|
|
|
|||
|
|
@ -202,8 +202,6 @@ public:
|
|||
compileOptions.setVersion(JSVERSION_DEFAULT);
|
||||
compileOptions.setIsRunOnce(true);
|
||||
|
||||
// We only need the setNoScriptRval bit when compiling off-thread here,
|
||||
// since otherwise nsJSUtils::EvaluateString will set it up for us.
|
||||
compileOptions.setNoScriptRval(true);
|
||||
|
||||
JS::Rooted<JS::Value> unused(cx);
|
||||
|
|
|
|||
|
|
@ -434,6 +434,7 @@ nsXBLProtoImplField::InstallField(JS::Handle<JSObject*> aBoundNode,
|
|||
JS::CompileOptions options(cx);
|
||||
options.setFileAndLine(uriSpec.get(), mLineNumber)
|
||||
.setVersion(JSVERSION_LATEST);
|
||||
#if 1
|
||||
nsJSUtils::EvaluateOptions evalOptions(cx);
|
||||
if (!nsJSUtils::GetScopeChainForElement(cx, boundElement,
|
||||
evalOptions.scopeChain)) {
|
||||
|
|
@ -442,6 +443,21 @@ nsXBLProtoImplField::InstallField(JS::Handle<JSObject*> aBoundNode,
|
|||
rv = nsJSUtils::EvaluateString(cx, nsDependentString(mFieldText,
|
||||
mFieldTextLength),
|
||||
scopeObject, options, evalOptions, &result);
|
||||
#endif
|
||||
#if 0
|
||||
JS::AutoObjectVector scopeChain(cx);
|
||||
if (!nsJSUtils::GetScopeChainForElement(cx, boundElement, scopeChain)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
rv = NS_OK;
|
||||
{
|
||||
nsJSUtils::ExecutionContext exec(cx, scopeObject);
|
||||
exec.SetScopeChain(scopeChain);
|
||||
exec.Compile(options, nsDependentString(mFieldText, mFieldTextLength));
|
||||
rv = exec.ExecScript(&result);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5220,7 +5220,7 @@ template <class ParseHandler>
|
|||
inline typename ParseHandler::Node
|
||||
Parser<ParseHandler>::importDeclarationOrImportExpr(YieldHandling yieldHandling)
|
||||
{
|
||||
MOZ_ASSERT(anyChars.isCurrentTokenType(TOK_IMPORT));
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_IMPORT));
|
||||
|
||||
TokenKind tt;
|
||||
if (!tokenStream.peekToken(&tt))
|
||||
|
|
@ -10480,7 +10480,7 @@ template <typename ParseHandler>
|
|||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::importExpr(YieldHandling yieldHandling)
|
||||
{
|
||||
MOZ_ASSERT(anyChars.isCurrentTokenType(TOK_IMPORT));
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_IMPORT));
|
||||
|
||||
Node importHolder = handler.newPosHolder(pos());
|
||||
if (!importHolder)
|
||||
|
|
|
|||
|
|
@ -592,7 +592,7 @@ MSG_DEF(JSMSG_MISSING_NAMESPACE_EXPORT, 0, JSEXN_SYNTAXERR, "export not found f
|
|||
MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found")
|
||||
MSG_DEF(JSMSG_BAD_MODULE_STATUS, 0, JSEXN_INTERNALERR, "module record has unexpected status")
|
||||
MSG_DEF(JSMSG_NO_DYNAMIC_IMPORT, 0, JSEXN_SYNTAXERR, "dynamic module import is not implemented")
|
||||
MSG_DEF(JSMSG_IMPORT_SCRIPT_NOT_FOUND, 0, JSEXN_TYPEERR, "can't find referencing script for dynamic module import")
|
||||
MSG_DEF(JSMSG_DYNAMIC_IMPORT_FAILED, 0, JSEXN_TYPEERR, "error loading dynamically imported module")
|
||||
MSG_DEF(JSMSG_BAD_MODULE_SPECIFIER, 1, JSEXN_TYPEERR, "error resolving module specifier '{0}'")
|
||||
|
||||
// Promise
|
||||
|
|
|
|||
|
|
@ -366,6 +366,12 @@ js::AssertSameCompartment(JSContext* cx, JSObject* obj)
|
|||
assertSameCompartment(cx, obj);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::AssertSameCompartment(JSContext* cx, JS::HandleValue v)
|
||||
{
|
||||
assertSameCompartment(cx, v);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
JS_FRIEND_API(void)
|
||||
js::AssertSameCompartment(JSObject* objA, JSObject* objB)
|
||||
|
|
|
|||
|
|
@ -659,6 +659,9 @@ GetPrototypeNoProxy(JSObject* obj);
|
|||
JS_FRIEND_API(void)
|
||||
AssertSameCompartment(JSContext* cx, JSObject* obj);
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
AssertSameCompartment(JSContext* cx, JS::HandleValue v);
|
||||
|
||||
#ifdef JS_DEBUG
|
||||
JS_FRIEND_API(void)
|
||||
AssertSameCompartment(JSObject* objA, JSObject* objB);
|
||||
|
|
|
|||
|
|
@ -1401,7 +1401,7 @@ const Class ScriptSourceObject::class_ = {
|
|||
};
|
||||
|
||||
ScriptSourceObject*
|
||||
ScriptSourceObject::create(ExclusiveContext* cx, ScriptSource* source)
|
||||
ScriptSourceObject::createInternal(ExclusiveContext* cx, ScriptSource* source, HandleObject canonical)
|
||||
{
|
||||
RootedObject object(cx, NewObjectWithGivenProto(cx, &class_, nullptr));
|
||||
if (!object)
|
||||
|
|
@ -1411,6 +1411,12 @@ ScriptSourceObject::create(ExclusiveContext* cx, ScriptSource* source)
|
|||
source->incref(); // The matching decref is in ScriptSourceObject::finalize.
|
||||
sourceObject->initReservedSlot(SOURCE_SLOT, PrivateValue(source));
|
||||
|
||||
if (canonical) {
|
||||
sourceObject->initReservedSlot(CANONICAL_SLOT, ObjectValue(*canonical));
|
||||
} else {
|
||||
sourceObject->initReservedSlot(CANONICAL_SLOT, ObjectValue(*sourceObject));
|
||||
}
|
||||
|
||||
// The remaining slots should eventually be populated by a call to
|
||||
// initFromOptions. Poison them until that point.
|
||||
sourceObject->initReservedSlot(ELEMENT_SLOT, MagicValue(JS_GENERIC_MAGIC));
|
||||
|
|
@ -1420,6 +1426,20 @@ ScriptSourceObject::create(ExclusiveContext* cx, ScriptSource* source)
|
|||
return sourceObject;
|
||||
}
|
||||
|
||||
ScriptSourceObject*
|
||||
ScriptSourceObject::create(ExclusiveContext* cx, ScriptSource* source)
|
||||
{
|
||||
return createInternal(cx, source, nullptr);
|
||||
}
|
||||
|
||||
ScriptSourceObject* ScriptSourceObject::unwrappedCanonical() const
|
||||
{
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtimeFromAnyThread()));
|
||||
|
||||
JSObject* obj = &getReservedSlot(CANONICAL_SLOT).toObject();
|
||||
return &UncheckedUnwrap(obj)->as<ScriptSourceObject>();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
ScriptSourceObject::initFromOptions(JSContext* cx, HandleScriptSource source,
|
||||
const ReadOnlyCompileOptions& options)
|
||||
|
|
|
|||
|
|
@ -637,6 +637,14 @@ class ScriptSourceObject : public NativeObject
|
|||
{
|
||||
static const ClassOps classOps_;
|
||||
|
||||
static ScriptSourceObject* createInternal(ExclusiveContext* cx, ScriptSource* source,
|
||||
HandleObject canonical);
|
||||
|
||||
bool isCanonical() const {
|
||||
return &getReservedSlot(CANONICAL_SLOT).toObject() == this;
|
||||
}
|
||||
ScriptSourceObject* unwrappedCanonical() const;
|
||||
|
||||
public:
|
||||
static const Class class_;
|
||||
|
||||
|
|
@ -684,6 +692,7 @@ class ScriptSourceObject : public NativeObject
|
|||
private:
|
||||
enum {
|
||||
SOURCE_SLOT = 0,
|
||||
CANONICAL_SLOT,
|
||||
ELEMENT_SLOT,
|
||||
ELEMENT_PROPERTY_SLOT,
|
||||
INTRODUCTION_SCRIPT_SLOT,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "MDNSResponderReply.h"
|
||||
#include "mozilla/EndianUtils.h"
|
||||
#include "private/pprio.h"
|
||||
#include "nsSocketTransportService2.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "nsICancelable.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "private/pprio.h"
|
||||
#include "MainThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue