merge mozilla-inbound to mozilla-central

This commit is contained in:
Carsten "Tomcat" Book 2014-05-07 14:07:44 +02:00
Родитель 23829ee157 71e1eceed8
Коммит b0b24241b4
186 изменённых файлов: 2076 добавлений и 1577 удалений

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

@ -50,7 +50,7 @@ let inputTests = [
{
input: "testDOMException()",
output: 'DOMException [SyntaxError: "An invalid or illegal string was specified"',
printOutput: '[Exception... "An invalid or illegal string was specified"',
printOutput: '[object XrayWrapper [object DOMException]]"',
inspectable: true,
variablesViewLabel: "SyntaxError",
},

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

@ -44,8 +44,9 @@ else
;;
esac
ac_add_options "--with-compiler-wrapper=python2.7 $topsrcdir/sccache/sccache.py"
mk_add_options MOZ_PREFLIGHT+=build/sccache.mk
mk_add_options MOZ_POSTFLIGHT+=build/sccache.mk
mk_add_options MOZ_PREFLIGHT_ALL+=build/sccache.mk
mk_add_options MOZ_POSTFLIGHT_ALL+=build/sccache.mk
UPLOAD_EXTRA_FILES="sccache.log.gz"
case "$platform" in
win*)
# sccache supports a special flag to create depfiles.

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

@ -1,7 +1,18 @@
preflight:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
ifdef OBJDIR
BASE_DIR = $(OBJDIR)
else
# OSX Universal builds only do upload in the first MOZ_BUILD_PROJECTS
BASE_DIR = $(MOZ_OBJDIR)/$(firstword $(MOZ_BUILD_PROJECTS))
endif
preflight_all:
# Terminate any sccache server that might still be around
-python2.7 $(TOPSRCDIR)/sccache/sccache.py > /dev/null 2>&1
postflight:
postflight_all:
# Terminate sccache server. This prints sccache stats.
-python2.7 $(TOPSRCDIR)/sccache/sccache.py
-python2.7 $(TOPSRCDIR)/sccache/sccache.py 2>&1 | gzip > $(BASE_DIR)/dist/sccache.log.gz

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

@ -11,7 +11,7 @@ interface nsIChannel;
interface nsIDocShell;
interface nsIDomainPolicy;
[scriptable, uuid(4c087cc3-e0cc-4ec3-88df-8d68f3023b45)]
[scriptable, uuid(2565769a-eaec-47a1-a076-605f5294d286)]
interface nsIScriptSecurityManager : nsIXPCSecurityManager
{
/**
@ -99,12 +99,6 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
[noscript,notxpcom] boolean scriptAllowed(in JSObjectPtr aGlobal);
///////////////// Principals ///////////////////////
/**
* Return the principal of the innermost frame of the currently
* executing script. Will return null if there is no script
* currently executing.
*/
[noscript] nsIPrincipal getSubjectPrincipal();
/**
* Return the all-powerful system principal.
@ -150,12 +144,6 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
*/
[deprecated] nsIPrincipal getCodebasePrincipal(in nsIURI uri);
/**
* Returns true if the principal of the currently running script is the
* system principal, false otherwise.
*/
[noscript] boolean subjectPrincipalIsSystem();
/**
* Returns OK if aJSContext and target have the same "origin"
* (scheme, host, and port).
@ -193,14 +181,6 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
}
%}
/**
* Same as getSubjectPrincipal(), only faster. cx must *never* be
* passed null, and it must be the context on the top of the
* context stack. Does *not* reference count the returned
* principal.
*/
[noscript,notxpcom] nsIPrincipal getCxSubjectPrincipal(in JSContextPtr cx);
const unsigned long NO_APP_ID = 0;
const unsigned long UNKNOWN_APP_ID = 4294967295; // UINT32_MAX
const unsigned long SAFEBROWSING_APP_ID = 4294967294; // UINT32_MAX - 1

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

@ -52,6 +52,9 @@ public:
static nsScriptSecurityManager*
GetScriptSecurityManager();
// Invoked exactly once, by XPConnect.
static void InitStatics();
static nsSystemPrincipal*
SystemPrincipalSingletonConstructor();
@ -118,11 +121,6 @@ private:
// should error out at that point.
static nsIPrincipal* doGetObjectPrincipal(JSObject* obj);
// Returns null if a principal cannot be found. Note that rv can be NS_OK
// when this happens -- this means that there was no JS running.
nsIPrincipal*
doGetSubjectPrincipal(nsresult* rv);
nsresult
GetCodebasePrincipalInternal(nsIURI* aURI, uint32_t aAppId,
bool aInMozBrowser,
@ -132,12 +130,6 @@ private:
CreateCodebasePrincipal(nsIURI* aURI, uint32_t aAppId, bool aInMozBrowser,
nsIPrincipal** result);
// Returns null if a principal cannot be found. Note that rv can be NS_OK
// when this happens -- this means that there was no script for the
// context. Callers MUST pass in a non-null rv here.
nsIPrincipal*
GetSubjectPrincipal(JSContext* cx, nsresult* rv);
nsresult
Init();

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

@ -81,11 +81,7 @@ bool nsScriptSecurityManager::sStrictFileOriginPolicy = true;
bool
nsScriptSecurityManager::SubjectIsPrivileged()
{
JSContext *cx = GetCurrentJSContext();
if (cx && xpc::IsUniversalXPConnectEnabled(cx))
return true;
bool isSystem = false;
return NS_SUCCEEDED(SubjectPrincipalIsSystem(&isSystem)) && isSystem;
return nsContentUtils::IsCallerChrome();
}
///////////////////////////
@ -318,20 +314,6 @@ nsScriptSecurityManager::IsSystemPrincipal(nsIPrincipal* aPrincipal,
return NS_OK;
}
NS_IMETHODIMP_(nsIPrincipal *)
nsScriptSecurityManager::GetCxSubjectPrincipal(JSContext *cx)
{
NS_ASSERTION(cx == GetCurrentJSContext(),
"Uh, cx is not the current JS context!");
nsresult rv = NS_ERROR_FAILURE;
nsIPrincipal *principal = GetSubjectPrincipal(cx, &rv);
if (NS_FAILED(rv))
return nullptr;
return principal;
}
/////////////////////////////
// nsScriptSecurityManager //
/////////////////////////////
@ -354,26 +336,10 @@ NS_IMPL_ISUPPORTS(nsScriptSecurityManager,
bool
nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
{
// Get the security manager
nsScriptSecurityManager *ssm =
nsScriptSecurityManager::GetScriptSecurityManager();
NS_ASSERTION(ssm, "Failed to get security manager service");
if (!ssm)
return false;
nsresult rv;
nsIPrincipal* subjectPrincipal = ssm->GetSubjectPrincipal(cx, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv), "CSP: Failed to get nsIPrincipal from js context");
if (NS_FAILED(rv))
return false; // Not just absence of principal, but failure.
if (!subjectPrincipal)
return true;
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
nsCOMPtr<nsIPrincipal> subjectPrincipal = nsContentUtils::GetSubjectPrincipal();
nsCOMPtr<nsIContentSecurityPolicy> csp;
rv = subjectPrincipal->GetCsp(getter_AddRefs(csp));
nsresult rv = subjectPrincipal->GetCsp(getter_AddRefs(csp));
NS_ASSERTION(NS_SUCCEEDED(rv), "CSP: Failed to get CSP from principal.");
// don't do anything unless there's a CSP
@ -424,27 +390,10 @@ NS_IMETHODIMP
nsScriptSecurityManager::CheckSameOrigin(JSContext* cx,
nsIURI* aTargetURI)
{
nsresult rv;
// Get a context if necessary
if (!cx)
{
cx = GetCurrentJSContext();
if (!cx)
return NS_OK; // No JS context, so allow access
}
MOZ_ASSERT_IF(cx, cx == nsContentUtils::GetCurrentJSContext());
// Get a principal from the context
nsIPrincipal* sourcePrincipal = GetSubjectPrincipal(cx, &rv);
if (NS_FAILED(rv))
return rv;
if (!sourcePrincipal)
{
NS_WARNING("CheckSameOrigin called on script w/o principals; should this happen?");
return NS_OK;
}
nsIPrincipal* sourcePrincipal = nsContentUtils::GetSubjectPrincipal();
if (sourcePrincipal == mSystemPrincipal)
{
// This is a system (chrome) script, so allow access
@ -520,17 +469,10 @@ NS_IMETHODIMP
nsScriptSecurityManager::CheckLoadURIFromScript(JSContext *cx, nsIURI *aURI)
{
// Get principal of currently executing script.
nsresult rv;
nsIPrincipal* principal = GetSubjectPrincipal(cx, &rv);
if (NS_FAILED(rv))
return rv;
// Native code can load all URIs.
if (!principal)
return NS_OK;
rv = CheckLoadURIWithPrincipal(principal, aURI,
nsIScriptSecurityManager::STANDARD);
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
nsIPrincipal* principal = nsContentUtils::GetSubjectPrincipal();
nsresult rv = CheckLoadURIWithPrincipal(principal, aURI,
nsIScriptSecurityManager::STANDARD);
if (NS_SUCCEEDED(rv)) {
// OK to load
return NS_OK;
@ -939,28 +881,6 @@ nsScriptSecurityManager::ScriptAllowed(JSObject *aGlobal)
}
///////////////// Principals ///////////////////////
NS_IMETHODIMP
nsScriptSecurityManager::GetSubjectPrincipal(nsIPrincipal **aSubjectPrincipal)
{
nsresult rv;
*aSubjectPrincipal = doGetSubjectPrincipal(&rv);
if (NS_SUCCEEDED(rv))
NS_IF_ADDREF(*aSubjectPrincipal);
return rv;
}
nsIPrincipal*
nsScriptSecurityManager::doGetSubjectPrincipal(nsresult* rv)
{
NS_PRECONDITION(rv, "Null out param");
JSContext *cx = GetCurrentJSContext();
if (!cx)
{
*rv = NS_OK;
return nullptr;
}
return GetSubjectPrincipal(cx, rv);
}
NS_IMETHODIMP
nsScriptSecurityManager::GetSystemPrincipal(nsIPrincipal **result)
@ -970,31 +890,6 @@ nsScriptSecurityManager::GetSystemPrincipal(nsIPrincipal **result)
return NS_OK;
}
NS_IMETHODIMP
nsScriptSecurityManager::SubjectPrincipalIsSystem(bool* aIsSystem)
{
NS_ENSURE_ARG_POINTER(aIsSystem);
*aIsSystem = false;
if (!mSystemPrincipal)
return NS_OK;
nsCOMPtr<nsIPrincipal> subject;
nsresult rv = GetSubjectPrincipal(getter_AddRefs(subject));
if (NS_FAILED(rv))
return rv;
if(!subject)
{
// No subject principal means no JS is running;
// this is the equivalent of system principal code
*aIsSystem = true;
return NS_OK;
}
return mSystemPrincipal->Equals(subject, aIsSystem);
}
nsresult
nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, uint32_t aAppId,
bool aInMozBrowser,
@ -1103,21 +998,6 @@ nsScriptSecurityManager::GetCodebasePrincipalInternal(nsIURI *aURI,
return NS_OK;
}
nsIPrincipal*
nsScriptSecurityManager::GetSubjectPrincipal(JSContext *cx,
nsresult* rv)
{
*rv = NS_OK;
JSCompartment *compartment = js::GetContextCompartment(cx);
// The context should always be in a compartment, either one it has entered
// or the one associated with its global.
MOZ_ASSERT(!!compartment);
JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
return nsJSPrincipals::get(principals);
}
// static
nsIPrincipal*
nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj)
@ -1158,11 +1038,8 @@ nsScriptSecurityManager::CanCreateWrapper(JSContext *cx,
//-- Access denied, report an error
NS_ConvertUTF8toUTF16 strName("CreateWrapperDenied");
nsAutoCString origin;
nsresult rv2;
nsIPrincipal* subjectPrincipal = doGetSubjectPrincipal(&rv2);
if (NS_SUCCEEDED(rv2) && subjectPrincipal) {
GetPrincipalDomainOrigin(subjectPrincipal, origin);
}
nsIPrincipal* subjectPrincipal = nsContentUtils::GetSubjectPrincipal();
GetPrincipalDomainOrigin(subjectPrincipal, origin);
NS_ConvertUTF8toUTF16 originUnicode(origin);
NS_ConvertUTF8toUTF16 classInfoName(objClassInfo.GetName());
const char16_t* formatStrings[] = {
@ -1176,14 +1053,11 @@ nsScriptSecurityManager::CanCreateWrapper(JSContext *cx,
strName.AppendLiteral("ForOrigin");
}
nsXPIDLString errorMsg;
// We need to keep our existing failure rv and not override it
// with a likely success code from the following string bundle
// call in order to throw the correct security exception later.
rv2 = sStrBundle->FormatStringFromName(strName.get(),
formatStrings,
length,
getter_Copies(errorMsg));
NS_ENSURE_SUCCESS(rv2, rv2);
nsresult rv = sStrBundle->FormatStringFromName(strName.get(),
formatStrings,
length,
getter_Copies(errorMsg));
NS_ENSURE_SUCCESS(rv, rv);
SetPendingException(cx, errorMsg.get());
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
@ -1368,29 +1242,22 @@ nsScriptSecurityManager::Shutdown()
nsScriptSecurityManager *
nsScriptSecurityManager::GetScriptSecurityManager()
{
if (!gScriptSecMan && nsXPConnect::XPConnect())
{
nsRefPtr<nsScriptSecurityManager> ssManager = new nsScriptSecurityManager();
nsresult rv;
rv = ssManager->Init();
if (NS_FAILED(rv)) {
return nullptr;
}
rv = nsXPConnect::XPConnect()->
SetDefaultSecurityManager(ssManager);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to install xpconnect security manager!");
return nullptr;
}
ClearOnShutdown(&gScriptSecMan);
gScriptSecMan = ssManager;
}
return gScriptSecMan;
}
/* static */ void
nsScriptSecurityManager::InitStatics()
{
nsRefPtr<nsScriptSecurityManager> ssManager = new nsScriptSecurityManager();
nsresult rv = ssManager->Init();
if (NS_FAILED(rv)) {
MOZ_CRASH();
}
ClearOnShutdown(&gScriptSecMan);
gScriptSecMan = ssManager;
}
// Currently this nsGenericFactory constructor is used only from FastLoad
// (XPCOM object deserialization) code, when "creating" the system principal
// singleton.

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

@ -1305,12 +1305,6 @@ DIST_FILES_FLAGS := $(XULAPP_DEFINES)
PP_TARGETS += DIST_FILES
endif
ifneq ($(DIST_FILES_NO_PP),)
_DIST_FILES := $(DIST_FILES_NO_PP)
_DIST_DEST := $(FINAL_TARGET)
INSTALL_TARGETS += _DIST
endif
ifneq ($(XPI_PKGNAME),)
tools realchrome::
ifdef STRIP_XPI

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

@ -164,7 +164,13 @@ all.h
alloca.h
alloc.h
alsa/asoundlib.h
#ifdef ANDROID
android/ashmem.h
android/log.h
android/looper.h
android/native_window.h
android_audio/AudioSystem.h
#endif
ansi_parms.h
a.out.h
app/Cursor.h
@ -177,6 +183,7 @@ app/Message.h
app/MessageRunner.h
arpa/inet.h
arpa/nameser.h
asm/page.h
asm/sigcontext.h
asm/signal.h
ASRegistry.h
@ -192,6 +199,12 @@ atlimpl.cpp
atlwin.cpp
ATSTypes.h
ATSUnicode.h
#ifdef ANDROID
AudioParameter.h
AudioSystem.h
AudioTrack.h
avc_utils.h
#endif
Balloons.h
base/pblock.h
base/PCR_Base.h
@ -202,6 +215,18 @@ Beep.h
be/kernel/image.h
be/kernel/OS.h
bfd.h
#ifdef ANDROID
binder/Binder.h
binder/BinderService.h
binder/IBinder.h
binder/IInterface.h
binder/IMemory.h
binder/IPCThreadState.h
binder/IPermissionController.h
binder/IServiceManager.h
binder/Parcel.h
binder/ProcessState.h
#endif
Bitmap.h
bitset
blapi.h
@ -283,6 +308,10 @@ dfb_types.h
directfb_strings.h
directfb_keyboard.h
callconv.h
#ifdef ANDROID
camera/Camera.h
camera/CameraParameters.h
#endif
Carbon/Carbon.h
CarbonEvents.h
Carbon.h
@ -308,6 +337,9 @@ Clipboard.h
cmplrs/stsupport.h
Cocoa/Cocoa.h
CodeFragments.h
#ifdef ANDROID
ColorConverter.h
#endif
comdef.h
commctrl.h
COMMCTRL.H
@ -340,6 +372,15 @@ ctype.h
curl/curl.h
curl/easy.h
curses.h
#ifdef ANDROID
cutils/android_reboot.h
cutils/atomic.h
cutils/compiler.h
cutils/log.h
cutils/native_handle.h
cutils/properties.h
cutils/sockets.h
#endif
cxxabi.h
DateTimeUtils.h
dbus/dbus.h
@ -366,6 +407,9 @@ DriverServices.h
DriverSynchronization.h
DropInPanel.h
dvidef.h
#ifdef ANDROID
EffectApi.h
#endif
elf.h
endian.h
Entry.h
@ -396,6 +440,19 @@ fontconfig/fontconfig.h
fontconfig/fcfreetype.h
Font.h
Fonts.h
#ifdef ANDROID
foundation/ABase.h
foundation/ABitReader.h
foundation/ABuffer.h
foundation/ADebug.h
foundation/AHandler.h
foundation/AHandlerReflector.h
foundation/ALooper.h
foundation/AMessage.h
foundation/AString.h
foundation/base64.h
foundation/hexdump.h
#endif
fp.h
fpieee.h
frame/log.h
@ -458,9 +515,41 @@ gtk/gtkx.h
gtk/gtkprinter.h
gtk/gtkprintjob.h
gtk/gtkprintunixdialog.h
#ifdef ANDROID
gui/GraphicBufferAlloc.h
gui/IConsumerListener.h
gui/IGraphicBufferAlloc.h
gui/IGraphicBufferProducer.h
gui/ISurfaceComposer.h
gui/ISurfaceComposerClient.h
gui/ISurfaceTexture.h
gui/Surface.h
gui/SurfaceComposerClient.h
gui/SurfaceTextureClient.h
hardware/audio.h
hardware/gralloc.h
hardware/hardware.h
hardware/hwcomposer.h
hardware/lights.h
hardware/power.h
hardware_legacy/power.h
hardware_legacy/uevent.h
hardware_legacy/vibrator.h
#endif
HIToolbox/HIToolbox.h
hlink.h
#ifdef ANDROID
HTTPBase.h
#endif
ia64/sys/inline.h
#ifdef ANDROID
IAudioFlingerClient.h
IAudioFlinger.h
IAudioRecord.h
IAudioTrack.h
IEffect.h
IEffectClient.h
#endif
Icons.h
iconv.h
ieeefp.h
@ -560,6 +649,11 @@ lib$routines.h
limits
limits.h
link.h
#ifdef ANDROID
linux/android_alarm.h
linux/ashmem.h
#endif
linux/ioprio.h
linux/kernel.h
linux/limits.h
linux/rtc.h
@ -646,6 +740,47 @@ mapix.h
Math64.h
math.h
mbstring.h
#ifdef ANDROID
media/ICrypto.h
media/IOMX.h
media/MediaProfiles.h
media/MediaRecorderBase.h
media/openmax/OMX_Audio.h
media/stagefright/AACWriter.h
media/stagefright/AMRWriter.h
media/stagefright/AudioSource.h
media/stagefright/DataSource.h
media/stagefright/foundation/ABase.h
media/stagefright/foundation/ABitReader.h
media/stagefright/foundation/ABuffer.h
media/stagefright/foundation/ADebug.h
media/stagefright/foundation/AHandler.h
media/stagefright/foundation/AHandlerReflector.h
media/stagefright/foundation/ALooper.h
media/stagefright/foundation/AMessage.h
media/stagefright/foundation/AString.h
media/stagefright/foundation/base64.h
media/stagefright/foundation/hexdump.h
media/stagefright/MediaBuffer.h
media/stagefright/MediaBufferGroup.h
media/stagefright/MediaCodec.h
media/stagefright/MediaDefs.h
media/stagefright/MediaErrors.h
media/stagefright/MediaExtractor.h
media/stagefright/MediaSource.h
media/stagefright/MediaWriter.h
media/stagefright/MetaData.h
media/stagefright/MPEG2TSWriter.h
media/stagefright/MPEG4Writer.h
media/stagefright/OMXClient.h
media/stagefright/OMXCodec.h
media/stagefright/openmax/OMX_Core.h
media/stagefright/openmax/OMX_Index.h
media/stagefright/openmax/OMX_IVCommon.h
media/stagefright/openmax/OMX_Types.h
media/stagefright/openmax/OMX_Video.h
media/stagefright/Utils.h
#endif
mem.h
memory
memory.h
@ -687,6 +822,10 @@ Objsafe.h
ojiapitests.h
ole2.h
oleidl.h
#ifdef ANDROID
OMX.h
OMX_Component.h
#endif
OpenGL/OpenGL.h
OpenTptInternet.h
OpenTransport.h
@ -733,7 +872,10 @@ PP_Resources.h
PP_Types.h
Printing.h
Print/PMPrintingDialogExtensions.h
#ifdef ANDROID
private/android_filesystem_config.h
private/qucomextra_p.h
#endif
Processes.h
process.h
Process.h
@ -783,6 +925,7 @@ set
setjmp.h
SFNTLayoutTypes.h
SFNTTypes.h
sha1.h
share.h
shellapi.h
shlguid.h
@ -800,6 +943,43 @@ sqlite3.h
ssdef.h
sstream
stack
#ifdef ANDROID
stagefright/AACWriter.h
stagefright/AMRWriter.h
stagefright/AudioSource.h
stagefright/DataSource.h
stagefright/foundation/ABase.h
stagefright/foundation/ABitReader.h
stagefright/foundation/ABuffer.h
stagefright/foundation/ADebug.h
stagefright/foundation/AHandler.h
stagefright/foundation/AHandlerReflector.h
stagefright/foundation/ALooper.h
stagefright/foundation/AMessage.h
stagefright/foundation/AString.h
stagefright/foundation/base64.h
stagefright/foundation/hexdump.h
stagefright/MediaBuffer.h
stagefright/MediaBufferGroup.h
stagefright/MediaCodec.h
stagefright/MediaDefs.h
stagefright/MediaErrors.h
stagefright/MediaExtractor.h
stagefright/MediaSource.h
stagefright/MediaWriter.h
stagefright/MetaData.h
stagefright/MPEG2TSWriter.h
stagefright/MPEG4Writer.h
stagefright/OMXCodec.h
stagefright/OMXClient.h
stagefright/openmax/OMX_Component.h
stagefright/openmax/OMX_Core.h
stagefright/openmax/OMX_Index.h
stagefright/openmax/OMX_IVCommon.h
stagefright/openmax/OMX_Types.h
stagefright/openmax/OMX_Video.h
stagefright/Utils.h
#endif
StandardFile.h
starlet.h
stat.h
@ -828,6 +1008,9 @@ SupportDefs.h
support/String.h
support/SupportDefs.h
support/TLS.h
#ifdef ANDROID
suspend/autosuspend.h
#endif
svrcore.h
symconst.h
sym.h
@ -841,6 +1024,7 @@ sys/cdefs.h
sys/cfgodm.h
sys/elf.h
sys/endian.h
sys/epoll.h
sys/errno.h
sys/fault.h
sys/fcntl.h
@ -848,10 +1032,12 @@ sys/file.h
sys/filio.h
sys/frame.h
sys/immu.h
sys/inotify.h
sys/inttypes.h
sys/ioccom.h
sys/ioctl.h
sys/ipc.h
sys/klog.h
sys/ldr.h
sys/link.h
sys/locking.h
@ -910,6 +1096,12 @@ sys/unistd.h
sys/utsname.h
sys/vfs.h
sys/wait.h
#ifdef ANDROID
sysutils/NetlinkEvent.h
system/audio.h
system/graphics.h
system/window.h
#endif
tables.h
TArray.h
TArrayIterator.h
@ -952,6 +1144,15 @@ UEventMgr.h
UException.h
UExtractFromAEDesc.h
UGWorld.h
#ifdef ANDROID
ui/ANativeObjectBase.h
ui/egl/android_natives.h
ui/Fence.h
ui/FramebufferNativeWindow.h
ui/GraphicBuffer.h
ui/Rect.h
ui/Region.h
#endif
UKeyFilters.h
ulocks.h
ulserrno.h
@ -975,6 +1176,28 @@ URegions.h
URegistrar.h
UResourceMgr.h
utility
#ifdef ANDROID
utils/BitSet.h
utils/CallStack.h
utils/Errors.h
utils/FileMap.h
utils/KeyedVector.h
utils/List.h
utils/Log.h
utils/Looper.h
utils/PropertyMap.h
utils/RefBase.h
utils/String16.h
utils/String8.h
utils/threads.h
utils/TextOutput.h
utils/Timers.h
utils/Trace.h
utils/TypeHelpers.h
utils/Unicode.h
utils/Vector.h
utils/VectorImpl.h
#endif
urlhist.h
urlmon.h
UScrap.h

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

@ -8983,6 +8983,8 @@ else
fi
AC_SUBST(JS_SHARED_LIBRARY)
AC_SUBST(UPLOAD_EXTRA_FILES)
MOZ_CREATE_CONFIG_STATUS()
# No need to run subconfigures when building with LIBXUL_SDK_DIR

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

@ -2170,6 +2170,7 @@ private:
static nsIXPConnect *sXPConnect;
static nsIScriptSecurityManager *sSecurityManager;
static nsIPrincipal *sSystemPrincipal;
static nsIParserService *sParserService;

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

@ -386,29 +386,10 @@ DOMParser::Constructor(const GlobalObject& aOwner,
DOMParser::Constructor(const GlobalObject& aOwner,
ErrorResult& rv)
{
nsCOMPtr<nsIPrincipal> prin;
nsCOMPtr<nsIURI> documentURI;
nsCOMPtr<nsIURI> baseURI;
// No arguments; use the subject principal
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
if (!secMan) {
rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
rv = secMan->GetSubjectPrincipal(getter_AddRefs(prin));
if (rv.Failed()) {
return nullptr;
}
// We're called from JS; there better be a subject principal, really.
if (!prin) {
rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<DOMParser> domParser = new DOMParser(aOwner.GetAsSupports());
rv = domParser->InitInternal(aOwner.GetAsSupports(), prin, documentURI, baseURI);
rv = domParser->InitInternal(aOwner.GetAsSupports(),
nsContentUtils::GetSubjectPrincipal(),
nullptr, nullptr);
if (rv.Failed()) {
return nullptr;
}
@ -464,24 +445,8 @@ DOMParser::Init(nsIPrincipal* aPrincipal, nsIURI* aDocumentURI,
nsIScriptContext* scriptContext = GetScriptContextFromJSContext(cx);
nsCOMPtr<nsIPrincipal> principal = aPrincipal;
if (!principal && !aDocumentURI) {
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
if (!secMan) {
rv.Throw(NS_ERROR_UNEXPECTED);
return;
}
rv = secMan->GetSubjectPrincipal(getter_AddRefs(principal));
if (rv.Failed()) {
return;
}
// We're called from JS; there better be a subject principal, really.
if (!principal) {
rv.Throw(NS_ERROR_UNEXPECTED);
return;
}
principal = nsContentUtils::GetSubjectPrincipal();
}
rv = Init(principal, aDocumentURI, aBaseURI,

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

@ -195,6 +195,7 @@ const char kLoadAsData[] = "loadAsData";
nsIXPConnect *nsContentUtils::sXPConnect;
nsIScriptSecurityManager *nsContentUtils::sSecurityManager;
nsIPrincipal *nsContentUtils::sSystemPrincipal;
nsIParserService *nsContentUtils::sParserService = nullptr;
nsNameSpaceManager *nsContentUtils::sNameSpaceManager;
nsIIOService *nsContentUtils::sIOService;
@ -376,8 +377,8 @@ nsContentUtils::Init()
return NS_ERROR_FAILURE;
NS_ADDREF(sSecurityManager);
// Getting the first context can trigger GC, so do this non-lazily.
sXPConnect->InitSafeJSContext();
sSecurityManager->GetSystemPrincipal(&sSystemPrincipal);
MOZ_ASSERT(sSystemPrincipal);
nsresult rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
if (NS_FAILED(rv)) {
@ -1434,6 +1435,7 @@ nsContentUtils::Shutdown()
NS_IF_RELEASE(sConsoleService);
sXPConnect = nullptr;
NS_IF_RELEASE(sSecurityManager);
NS_IF_RELEASE(sSystemPrincipal);
NS_IF_RELEASE(sParserService);
NS_IF_RELEASE(sIOService);
NS_IF_RELEASE(sLineBreaker);
@ -1514,14 +1516,7 @@ nsContentUtils::CheckSameOrigin(const nsINode* aTrustedNode,
{
MOZ_ASSERT(aTrustedNode);
MOZ_ASSERT(unTrustedNode);
bool isSystem = false;
nsresult rv = sSecurityManager->SubjectPrincipalIsSystem(&isSystem);
NS_ENSURE_SUCCESS(rv, rv);
if (isSystem) {
// we're running as system, grant access to the node.
if (IsCallerChrome()) {
return NS_OK;
}
@ -1578,45 +1573,19 @@ nsContentUtils::CanCallerAccess(nsIDOMNode *aNode)
bool
nsContentUtils::CanCallerAccess(nsINode* aNode)
{
// XXXbz why not check the IsCapabilityEnabled thing up front, and not bother
// with the system principal games? But really, there should be a simpler
// API here, dammit.
nsCOMPtr<nsIPrincipal> subjectPrincipal;
nsresult rv = sSecurityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
NS_ENSURE_SUCCESS(rv, false);
if (!subjectPrincipal) {
// we're running as system, grant access to the node.
return true;
}
return CanCallerAccess(subjectPrincipal, aNode->NodePrincipal());
return CanCallerAccess(GetSubjectPrincipal(), aNode->NodePrincipal());
}
// static
bool
nsContentUtils::CanCallerAccess(nsPIDOMWindow* aWindow)
{
// XXXbz why not check the IsCapabilityEnabled thing up front, and not bother
// with the system principal games? But really, there should be a simpler
// API here, dammit.
nsCOMPtr<nsIPrincipal> subjectPrincipal;
nsresult rv = sSecurityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
NS_ENSURE_SUCCESS(rv, false);
if (!subjectPrincipal) {
// we're running as system, grant access to the node.
return true;
}
nsCOMPtr<nsIScriptObjectPrincipal> scriptObject =
do_QueryInterface(aWindow->IsOuterWindow() ?
aWindow->GetCurrentInnerWindow() : aWindow);
NS_ENSURE_TRUE(scriptObject, false);
return CanCallerAccess(subjectPrincipal, scriptObject->GetPrincipal());
return CanCallerAccess(GetSubjectPrincipal(), scriptObject->GetPrincipal());
}
//static
@ -1718,12 +1687,7 @@ bool
nsContentUtils::IsCallerChrome()
{
MOZ_ASSERT(NS_IsMainThread());
bool is_caller_chrome = false;
nsresult rv = sSecurityManager->SubjectPrincipalIsSystem(&is_caller_chrome);
if (NS_FAILED(rv)) {
return false;
}
if (is_caller_chrome) {
if (GetSubjectPrincipal() == sSystemPrincipal) {
return true;
}
@ -2353,14 +2317,15 @@ nsContentUtils::GenerateStateKey(nsIContent* aContent,
nsIPrincipal*
nsContentUtils::GetSubjectPrincipal()
{
nsCOMPtr<nsIPrincipal> subject;
sSecurityManager->GetSubjectPrincipal(getter_AddRefs(subject));
JSContext* cx = GetCurrentJSContext();
if (!cx) {
return GetSystemPrincipal();
}
// When the ssm says the subject is null, that means system principal.
if (!subject)
sSecurityManager->GetSystemPrincipal(getter_AddRefs(subject));
return subject;
JSCompartment* compartment = js::GetContextCompartment(cx);
MOZ_ASSERT(compartment);
JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
return nsJSPrincipals::get(principals);
}
// static
@ -3141,11 +3106,7 @@ nsContentUtils::IsChromeDoc(nsIDocument *aDocument)
if (!aDocument) {
return false;
}
nsCOMPtr<nsIPrincipal> systemPrincipal;
sSecurityManager->GetSystemPrincipal(getter_AddRefs(systemPrincipal));
return aDocument->NodePrincipal() == systemPrincipal;
return aDocument->NodePrincipal() == sSystemPrincipal;
}
bool
@ -4351,10 +4312,7 @@ nsContentUtils::CheckSecurityBeforeLoad(nsIURI* aURIToLoad,
{
NS_PRECONDITION(aLoadingPrincipal, "Must have a loading principal here");
bool isSystemPrin = false;
if (NS_SUCCEEDED(sSecurityManager->IsSystemPrincipal(aLoadingPrincipal,
&isSystemPrin)) &&
isSystemPrin) {
if (aLoadingPrincipal == sSystemPrincipal) {
return NS_OK;
}
@ -4393,9 +4351,7 @@ nsContentUtils::CheckSecurityBeforeLoad(nsIURI* aURIToLoad,
bool
nsContentUtils::IsSystemPrincipal(nsIPrincipal* aPrincipal)
{
bool isSystem;
nsresult rv = sSecurityManager->IsSystemPrincipal(aPrincipal, &isSystem);
return NS_SUCCEEDED(rv) && isSystem;
return aPrincipal == sSystemPrincipal;
}
bool
@ -4408,11 +4364,7 @@ nsContentUtils::IsExpandedPrincipal(nsIPrincipal* aPrincipal)
nsIPrincipal*
nsContentUtils::GetSystemPrincipal()
{
nsCOMPtr<nsIPrincipal> sysPrin;
DebugOnly<nsresult> rv =
sSecurityManager->GetSystemPrincipal(getter_AddRefs(sysPrin));
MOZ_ASSERT(NS_SUCCEEDED(rv) && sysPrin);
return sysPrin;
return sSystemPrincipal;
}
bool
@ -4434,7 +4386,7 @@ nsContentUtils::CombineResourcePrincipals(nsCOMPtr<nsIPrincipal>* aResourcePrinc
subsumes) {
return false;
}
sSecurityManager->GetSystemPrincipal(getter_AddRefs(*aResourcePrincipal));
*aResourcePrincipal = sSystemPrincipal;
return true;
}
@ -6106,20 +6058,10 @@ nsContentUtils::GetContentSecurityPolicy(JSContext* aCx,
nsIContentSecurityPolicy** aCSP)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
// Get the security manager
nsCOMPtr<nsIScriptSecurityManager> ssm = nsContentUtils::GetSecurityManager();
if (!ssm) {
NS_ERROR("Failed to get security manager service");
return false;
}
nsCOMPtr<nsIPrincipal> subjectPrincipal = ssm->GetCxSubjectPrincipal(aCx);
NS_ASSERTION(subjectPrincipal, "Failed to get subjectPrincipal");
MOZ_ASSERT(aCx == GetCurrentJSContext());
nsCOMPtr<nsIContentSecurityPolicy> csp;
nsresult rv = subjectPrincipal->GetCsp(getter_AddRefs(csp));
nsresult rv = GetSubjectPrincipal()->GetCsp(getter_AddRefs(csp));
if (NS_FAILED(rv)) {
NS_ERROR("CSP: Failed to get CSP from principal.");
return false;

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

@ -6335,23 +6335,13 @@ nsIDocument::LoadBindingDocument(const nsAString& aURI, ErrorResult& rv)
return;
}
// Figure out the right principal to use
nsCOMPtr<nsIPrincipal> subject;
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
if (secMan) {
rv = secMan->GetSubjectPrincipal(getter_AddRefs(subject));
if (rv.Failed()) {
return;
}
}
if (!subject) {
// Fall back to our principal. Or should we fall back to the null
// principal? The latter would just mean no binding loads....
subject = NodePrincipal();
}
BindingManager()->LoadBindingDocument(this, uri, subject);
// Note - This computation of subjectPrincipal isn't necessarily sensical.
// It's just designed to preserve the old semantics during a mass-conversion
// patch.
nsCOMPtr<nsIPrincipal> subjectPrincipal =
nsContentUtils::GetCurrentJSContext() ? nsContentUtils::GetSubjectPrincipal()
: NodePrincipal();
BindingManager()->LoadBindingDocument(this, uri, subjectPrincipal);
}
NS_IMETHODIMP

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

@ -118,7 +118,7 @@ function next_text() {
}
function frame_loaded() {
// We must delay to wait for the plugin sources to be loaded :(
SimpleTest.requestFlakyTimeout("We must delay to wait for the plugin sources to be loaded :(");
setTimeout(next_text, 500);
}

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

@ -17,6 +17,7 @@
<script class="testbody" type="application/javascript;version=1.7">
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("This test needs to generate artificial pauses, hence it uses timeouts. There is no way around it, unfortunately. :(");
window.addEventListener("message", function(e) {
gen.send(e.data);

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

@ -179,7 +179,7 @@ function forcegc()
setTimeout(function()
{
SpecialPowers.gc();
}, 1);
}, 0);
}
function doTest(number)
@ -1498,6 +1498,8 @@ function testWebSocket ()
doTest(first_test);
}
SimpleTest.requestFlakyTimeout("The web socket tests are really fragile, but avoiding timeouts might be hard, since it's testing stuff on the network. " +
"Expect all sorts of flakiness in this test...");
SimpleTest.waitForExplicitFinish();
</script>

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

@ -467,6 +467,7 @@ function start() {
}
SimpleTest.requestLongerTimeout(requestLongerTimeoutLen);
SimpleTest.requestFlakyTimeout("We're embedding the WebGL test harness, which uses timeouts internally, so we have to abide. :(");
var statusElem = document.getElementById("status");
var statusTextNode = document.createTextNode('');

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

@ -243,6 +243,25 @@ HTMLOptionElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
return NS_OK;
}
nsresult
HTMLOptionElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue, bool aNotify)
{
if (aNameSpaceID == kNameSpaceID_None &&
aName == nsGkAtoms::value && Selected()) {
// Since this option is selected, changing value
// may have changed missing validity state of the
// Select element
HTMLSelectElement* select = GetSelect();
if (select) {
select->UpdateValueMissingValidityState();
}
}
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName,
aValue, aNotify);
}
NS_IMETHODIMP
HTMLOptionElement::GetText(nsAString& aText)
{

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

@ -51,6 +51,8 @@ public:
virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
const nsAttrValueOrString* aValue,
bool aNotify) MOZ_OVERRIDE;
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue, bool aNotify) MOZ_OVERRIDE;
void SetSelectedInternal(bool aValue, bool aNotify);

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

@ -395,6 +395,7 @@ public:
nsresult GetValidationMessage(nsAString& aValidationMessage,
ValidityStateType aType) MOZ_OVERRIDE;
void UpdateValueMissingValidityState();
/**
* Insert aElement before the node given by aBefore
*/
@ -511,7 +512,6 @@ protected:
// nsIConstraintValidation
void UpdateBarredFromConstraintValidation();
bool IsValueMissing();
void UpdateValueMissingValidityState();
/**
* Find out how deep this content is from the select (1=direct child)

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

@ -74,6 +74,7 @@ skip-if = e10s
[test_restore_form_elements.html]
[test_save_restore_radio_groups.html]
[test_select_selectedOptions.html]
[test_select_validation.html]
[test_set_range_text.html]
[test_step_attribute.html]
skip-if = e10s

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

@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=942321
-->
<head>
<title>Test for Bug 942321</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=942321">Mozilla Bug 942321</a>
<p id="display"></p>
<form id="form" href="">
<select required id="testselect">
<option id="placeholder" value="" selected>placeholder</option>
<option value="test" id="actualvalue">test</option>
<select>
<input type="submit" />
</form>
<script class="testbody" type="text/javascript">
/** Test for Bug 942321 **/
var option = document.getElementById("actualvalue");
option.selected = true;
is(form.checkValidity(), true, "Select is required and should be valid");
var placeholder = document.getElementById("placeholder");
placeholder.selected = true;
is(form.checkValidity(), false, "Select is required and should be invalid");
placeholder.value = "not-invalid-anymore";
is(form.checkValidity(), true, "Select is required and should be valid when option's value is changed by javascript");
</script>
</pre>
</body>
</html>

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

@ -2849,27 +2849,10 @@ nsHTMLDocument::SetDesignMode(const nsAString & aDesignMode)
void
nsHTMLDocument::SetDesignMode(const nsAString& aDesignMode, ErrorResult& rv)
{
if (!nsContentUtils::IsCallerChrome()) {
nsCOMPtr<nsIPrincipal> subject;
nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
rv = secMan->GetSubjectPrincipal(getter_AddRefs(subject));
if (rv.Failed()) {
return;
}
if (subject) {
bool subsumes;
rv = subject->Subsumes(NodePrincipal(), &subsumes);
if (rv.Failed()) {
return;
}
if (!subsumes) {
rv.Throw(NS_ERROR_DOM_PROP_ACCESS_DENIED);
return;
}
}
if (!nsContentUtils::GetSubjectPrincipal()->Subsumes(NodePrincipal())) {
rv.Throw(NS_ERROR_DOM_PROP_ACCESS_DENIED);
return;
}
bool editableMode = HasFlag(NODE_IS_EDITABLE);
if (aDesignMode.LowerCaseEqualsASCII(editableMode ? "off" : "on")) {
SetEditableFlag(!editableMode);

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

@ -1449,7 +1449,7 @@ void MediaDecoderStateMachine::Seek(const SeekTarget& aTarget)
mSeekTarget = SeekTarget(seekTime, aTarget.mType);
mBasePosition = seekTime - mStartTime;
DECODER_LOG(PR_LOG_DEBUG, "Changed state to SEEKING (to %ld)", mSeekTarget.mTime);
DECODER_LOG(PR_LOG_DEBUG, "Changed state to SEEKING (to %lld)", mSeekTarget.mTime);
mState = DECODER_STATE_SEEKING;
if (mDecoder->GetDecodedStream()) {
mDecoder->RecreateDecodedStream(seekTime - mStartTime);

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

@ -15,7 +15,7 @@
namespace android {
class OmxDecoder;
class MediaExtractor;
class MOZ_EXPORT MediaExtractor;
}
namespace mozilla {

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

@ -8,7 +8,7 @@
#include <android/native_window.h>
#include <IOMX.h>
#include <media/IOMX.h>
#include <stagefright/MediaBuffer.h>
#include <stagefright/MediaSource.h>
#include <utils/threads.h>

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

@ -323,8 +323,8 @@ nsresult MediaPluginReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aE
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
mVideoQueue.Erase();
mAudioQueue.Erase();
mVideoQueue.Reset();
mAudioQueue.Reset();
mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget;

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

@ -248,7 +248,7 @@ nsresult RawReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, in
nsresult rv = resource->Seek(nsISeekableStream::NS_SEEK_SET, offset.value());
NS_ENSURE_SUCCESS(rv, rv);
mVideoQueue.Erase();
mVideoQueue.Reset();
while(mVideoQueue.GetSize() == 0) {
bool keyframeSkip = false;

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

@ -1555,8 +1555,7 @@ nsDocShell::LoadURI(nsIURI * aURI,
}
if (!owner && !inheritOwner && !ownerIsExplicit) {
// See if there's system or chrome JS code running
inheritOwner = nsContentUtils::IsSystemPrincipal(
nsContentUtils::GetSubjectPrincipal());
inheritOwner = nsContentUtils::IsCallerChrome();
}
if (aLoadFlags & LOAD_FLAGS_DISALLOW_INHERIT_OWNER) {
@ -8645,7 +8644,7 @@ nsDocShell::CheckLoadingPermissions()
// frames in the new window through window.frames[] (which is
// allAccess for historic reasons), so we still need to do this
// check on load.
nsresult rv = NS_OK, sameOrigin = NS_OK;
nsresult rv = NS_OK;
if (!gValidateOrigin || !IsFrame()) {
// Origin validation was turned off, or we're not a frame.
@ -8654,16 +8653,10 @@ nsDocShell::CheckLoadingPermissions()
return rv;
}
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// We're a frame. Check that the caller has write permission to
// the parent before allowing it to load anything into this
// docshell.
nsCOMPtr<nsIPrincipal> subjPrincipal;
rv = securityManager->GetSubjectPrincipal(getter_AddRefs(subjPrincipal));
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && subjPrincipal, rv);
// Note - The check for a current JSContext here isn't necessarily sensical.
// It's just designed to preserve the old semantics during a mass-conversion
// patch.
NS_ENSURE_TRUE(nsContentUtils::GetCurrentJSContext(), NS_OK);
// Check if the caller is from the same origin as this docshell,
// or any of its ancestors.
@ -8677,17 +8670,9 @@ nsDocShell::CheckLoadingPermissions()
return NS_ERROR_UNEXPECTED;
}
// Compare origins
bool subsumes;
sameOrigin = subjPrincipal->Subsumes(p, &subsumes);
if (NS_SUCCEEDED(sameOrigin)) {
if (subsumes) {
// Same origin, permit load
return sameOrigin;
}
sameOrigin = NS_ERROR_DOM_PROP_ACCESS_DENIED;
if (nsContentUtils::GetSubjectPrincipal()->Subsumes(p)) {
// Same origin, permit load
return NS_OK;
}
nsCOMPtr<nsIDocShellTreeItem> tmp;
@ -8695,7 +8680,7 @@ nsDocShell::CheckLoadingPermissions()
item.swap(tmp);
} while (item);
return sameOrigin;
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
}
//*****************************************************************************

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

@ -1629,8 +1629,7 @@ OpenEntryForRead(nsIPrincipal* aPrincipal,
}
void
CloseEntryForRead(JS::Handle<JSObject*> global,
size_t aSize,
CloseEntryForRead(size_t aSize,
const uint8_t* aMemory,
intptr_t aFile)
{
@ -1683,8 +1682,7 @@ OpenEntryForWrite(nsIPrincipal* aPrincipal,
}
void
CloseEntryForWrite(JS::Handle<JSObject*> global,
size_t aSize,
CloseEntryForWrite(size_t aSize,
uint8_t* aMemory,
intptr_t aFile)
{

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

@ -109,8 +109,7 @@ OpenEntryForRead(nsIPrincipal* aPrincipal,
const uint8_t** aMemory,
intptr_t *aHandle);
void
CloseEntryForRead(JS::Handle<JSObject*> aGlobal,
size_t aSize,
CloseEntryForRead(size_t aSize,
const uint8_t* aMemory,
intptr_t aHandle);
bool
@ -122,8 +121,7 @@ OpenEntryForWrite(nsIPrincipal* aPrincipal,
uint8_t** aMemory,
intptr_t* aHandle);
void
CloseEntryForWrite(JS::Handle<JSObject*> aGlobal,
size_t aSize,
CloseEntryForWrite(size_t aSize,
uint8_t* aMemory,
intptr_t aHandle);

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

@ -231,7 +231,7 @@ URL::SetHref(const nsAString& aHref, ErrorResult& aRv)
return;
}
aRv = mURI->SetSpec(href);
mURI = uri;
UpdateURLSearchParams();
}

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

@ -2014,9 +2014,6 @@ nsGlobalWindow::SetInitialPrincipalToSubject()
// First, grab the subject principal.
nsCOMPtr<nsIPrincipal> newWindowPrincipal = nsContentUtils::GetSubjectPrincipal();
if (!newWindowPrincipal) {
newWindowPrincipal = nsContentUtils::GetSystemPrincipal();
}
// Now, if we're about to use the system principal or an nsExpandedPrincipal,
// make sure we're not using it for a content docshell.
@ -6055,53 +6052,42 @@ nsGlobalWindow::MakeScriptDialogTitle(nsAString &aOutTitle)
// Try to get a host from the running principal -- this will do the
// right thing for javascript: and data: documents.
nsresult rv = NS_OK;
NS_ASSERTION(nsContentUtils::GetSecurityManager(),
"Global Window has no security manager!");
if (nsContentUtils::GetSecurityManager()) {
nsCOMPtr<nsIPrincipal> principal;
rv = nsContentUtils::GetSecurityManager()->
GetSubjectPrincipal(getter_AddRefs(principal));
nsCOMPtr<nsIPrincipal> principal = nsContentUtils::GetSubjectPrincipal();
nsCOMPtr<nsIURI> uri;
nsresult rv = principal->GetURI(getter_AddRefs(uri));
// Note - The check for the current JSContext here isn't necessarily sensical.
// It's just designed to preserve existing behavior during a mass-conversion
// patch.
if (NS_SUCCEEDED(rv) && uri && nsContentUtils::GetCurrentJSContext()) {
// remove user:pass for privacy and spoof prevention
if (NS_SUCCEEDED(rv) && principal) {
nsCOMPtr<nsIURI> uri;
rv = principal->GetURI(getter_AddRefs(uri));
nsCOMPtr<nsIURIFixup> fixup(do_GetService(NS_URIFIXUP_CONTRACTID));
if (fixup) {
nsCOMPtr<nsIURI> fixedURI;
rv = fixup->CreateExposableURI(uri, getter_AddRefs(fixedURI));
if (NS_SUCCEEDED(rv) && fixedURI) {
nsAutoCString host;
fixedURI->GetHost(host);
if (NS_SUCCEEDED(rv) && uri) {
// remove user:pass for privacy and spoof prevention
if (!host.IsEmpty()) {
// if this URI has a host we'll show it. For other
// schemes (e.g. file:) we fall back to the localized
// generic string
nsCOMPtr<nsIURIFixup> fixup(do_GetService(NS_URIFIXUP_CONTRACTID));
if (fixup) {
nsCOMPtr<nsIURI> fixedURI;
rv = fixup->CreateExposableURI(uri, getter_AddRefs(fixedURI));
if (NS_SUCCEEDED(rv) && fixedURI) {
nsAutoCString host;
fixedURI->GetHost(host);
nsAutoCString prepath;
fixedURI->GetPrePath(prepath);
if (!host.IsEmpty()) {
// if this URI has a host we'll show it. For other
// schemes (e.g. file:) we fall back to the localized
// generic string
nsAutoCString prepath;
fixedURI->GetPrePath(prepath);
NS_ConvertUTF8toUTF16 ucsPrePath(prepath);
const char16_t *formatStrings[] = { ucsPrePath.get() };
nsXPIDLString tempString;
nsContentUtils::FormatLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
"ScriptDlgHeading",
formatStrings,
tempString);
aOutTitle = tempString;
}
}
NS_ConvertUTF8toUTF16 ucsPrePath(prepath);
const char16_t *formatStrings[] = { ucsPrePath.get() };
nsXPIDLString tempString;
nsContentUtils::FormatLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
"ScriptDlgHeading",
formatStrings,
tempString);
aOutTitle = tempString;
}
}
}
else { // failed to get subject principal
NS_WARNING("No script principal? Who is calling alert/confirm/prompt?!");
}
}
if (aOutTitle.IsEmpty()) {
@ -11693,28 +11679,14 @@ nsGlobalWindow::SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
// If our principals subsume the subject principal then use the subject
// principal. Otherwise, use our principal to avoid running script in
// elevated principals.
nsCOMPtr<nsIPrincipal> subjectPrincipal;
nsresult rv;
rv = nsContentUtils::GetSecurityManager()->
GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
bool subsumes = false;
nsCOMPtr<nsIPrincipal> ourPrincipal = GetPrincipal();
//
// Note the direction of this test: We don't allow setTimeouts running with
// chrome privileges on content windows, but we do allow setTimeouts running
// with content privileges on chrome windows (where they can't do very much,
// of course).
rv = ourPrincipal->Subsumes(subjectPrincipal, &subsumes);
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
if (subsumes) {
nsCOMPtr<nsIPrincipal> subjectPrincipal = nsContentUtils::GetSubjectPrincipal();
nsCOMPtr<nsIPrincipal> ourPrincipal = GetPrincipal();
if (ourPrincipal->Subsumes(subjectPrincipal)) {
timeout->mPrincipal = subjectPrincipal;
} else {
timeout->mPrincipal = ourPrincipal;
@ -11730,6 +11702,7 @@ nsGlobalWindow::SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
timeout->mWhen = TimeStamp::Now() + delta;
nsresult rv;
timeout->mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
if (NS_FAILED(rv)) {
return rv;

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

@ -2089,12 +2089,12 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults)
}
NS_NAMED_MULTILINE_LITERAL_STRING(kFmt,
MOZ_UTF16("CC(T+%.1f) max pause: %lums, total time: %lums, suspected: %lu, visited: %lu RCed and %lu%s GCed, collected: %lu RCed and %lu GCed (%lu|%lu waiting for GC)%s\n")
MOZ_UTF16("CC(T+%.1f) max pause: %lums, total time: %lums, slices: %lu, suspected: %lu, visited: %lu RCed and %lu%s GCed, collected: %lu RCed and %lu GCed (%lu|%lu waiting for GC)%s\n")
MOZ_UTF16("ForgetSkippable %lu times before CC, min: %lu ms, max: %lu ms, avg: %lu ms, total: %lu ms, max sync: %lu ms, removed: %lu"));
nsString msg;
msg.Adopt(nsTextFormatter::smprintf(kFmt.get(), double(delta) / PR_USEC_PER_SEC,
gCCStats.mMaxSliceTime, gCCStats.mTotalSliceTime,
gCCStats.mSuspected,
aResults.mNumSlices, gCCStats.mSuspected,
aResults.mVisitedRefCounted, aResults.mVisitedGCed, mergeMsg.get(),
aResults.mFreedRefCounted, aResults.mFreedGCed,
sCCollectedWaitingForGC, sLikelyShortLivingObjectsNeedingGC,

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

@ -160,7 +160,7 @@ nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo)
}
}
owner = do_QueryInterface(ssm->GetCxSubjectPrincipal(cx));
owner = nsContentUtils::GetSubjectPrincipal();
}
// Create load info

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

@ -2328,6 +2328,8 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
parentProtoType = "Rooted"
if self.descriptor.interface.getExtendedAttribute("ArrayClass"):
getParentProto = "aCx, JS_GetArrayPrototype(aCx, aGlobal)"
elif self.descriptor.interface.getExtendedAttribute("ExceptionClass"):
getParentProto = "aCx, JS_GetErrorPrototype(aCx)"
else:
getParentProto = "aCx, JS_GetObjectPrototype(aCx, aGlobal)"
else:

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

@ -18,26 +18,6 @@
#include "WorkerPrivate.h"
#include "nsContentUtils.h"
namespace {
// We can't use nsContentUtils::IsCallerChrome because it might not exist in
// xpcshell.
bool
IsCallerChrome()
{
nsCOMPtr<nsIScriptSecurityManager> secMan;
secMan = XPCWrapper::GetSecurityManager();
if (!secMan) {
return false;
}
bool isChrome;
return NS_SUCCEEDED(secMan->SubjectPrincipalIsSystem(&isChrome)) && isChrome;
}
} // anonymous namespace
namespace mozilla {
namespace dom {
@ -80,7 +60,7 @@ ThrowExceptionObject(JSContext* aCx, Exception* aException)
// (i.e., not chrome), rethrow the original value. This only applies to JS
// implemented components so we only need to check for this on the main
// thread.
if (NS_IsMainThread() && !IsCallerChrome() &&
if (NS_IsMainThread() && !nsContentUtils::IsCallerChrome() &&
aException->StealJSVal(thrown.address())) {
if (!JS_WrapValue(aCx, &thrown)) {
return false;
@ -173,14 +153,8 @@ GetCurrentJSStack()
JSContext* cx = nullptr;
if (NS_IsMainThread()) {
// Note, in xpcshell nsContentUtils is never initialized, but we still need
// to report exceptions.
if (nsContentUtils::XPConnect()) {
cx = nsContentUtils::XPConnect()->GetCurrentJSContext();
} else {
nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
cx = xpc->GetCurrentJSContext();
}
MOZ_ASSERT(nsContentUtils::XPConnect());
cx = nsContentUtils::GetCurrentJSContext();
} else {
cx = workers::GetCurrentThreadJSContext();
}

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

@ -269,6 +269,14 @@ class IDLScope(IDLObject):
% (identifier.name,
originalObject.location, newObject.location), [])
if (isinstance(originalObject, IDLDictionary) or
isinstance(newObject, IDLDictionary)):
raise WebIDLError(
"Name collision between dictionary declarations for "
"identifier '%s'.\n%s\n%s"
% (identifier.name,
originalObject.location, newObject.location), [])
# We do the merging of overloads here as opposed to in IDLInterface
# because we need to merge overloads of NamedConstructors and we need to
# detect conflicts in those across interfaces. See also the comment in
@ -968,6 +976,14 @@ class IDLInterface(IDLObjectWithScope):
raise WebIDLError("[ArrayClass] must not be specified on "
"an interface with inherited interfaces",
[attr.location, self.location])
elif (identifier == "ExceptionClass"):
if not attr.noArguments():
raise WebIDLError("[ExceptionClass] must take no arguments",
[attr.location])
if self.parent:
raise WebIDLError("[ExceptionClass] must not be specified on "
"an interface with inherited interfaces",
[attr.location, self.location])
elif identifier == "Global":
if not attr.noArguments():
raise WebIDLError("[Global] must take no arguments",

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

@ -31,11 +31,11 @@
namespace android {
class GonkCameraSource;
struct MediaSource;
struct MediaWriter;
class MetaData;
struct AudioSource;
class MediaProfiles;
struct MOZ_EXPORT MediaSource;
struct MOZ_EXPORT MediaWriter;
class MOZ_EXPORT MetaData;
struct MOZ_EXPORT AudioSource;
class MOZ_EXPORT MediaProfiles;
class GonkCameraHardware;
struct GonkRecorder {

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

@ -594,9 +594,7 @@ DataTransfer::MozGetDataAt(const nsAString& aFormat, uint32_t aIndex,
(mEventType != NS_DRAGDROP_DROP && mEventType != NS_DRAGDROP_DRAGDROP &&
mEventType != NS_PASTE &&
!nsContentUtils::IsCallerChrome())) {
nsresult rv = NS_OK;
principal = GetCurrentPrincipal(&rv);
NS_ENSURE_SUCCESS(rv, rv);
principal = nsContentUtils::GetSubjectPrincipal();
}
uint32_t count = item.Length();
@ -625,9 +623,9 @@ DataTransfer::MozGetDataAt(const nsAString& aFormat, uint32_t aIndex,
MOZ_ASSERT(sp, "This cannot fail on the main thread.");
nsIPrincipal* dataPrincipal = sp->GetPrincipal();
NS_ENSURE_TRUE(dataPrincipal, NS_ERROR_DOM_SECURITY_ERR);
NS_ENSURE_TRUE(principal || (principal = GetCurrentPrincipal(&rv)),
NS_ERROR_DOM_SECURITY_ERR);
NS_ENSURE_SUCCESS(rv, rv);
if (!principal) {
principal = nsContentUtils::GetSubjectPrincipal();
}
bool equals = false;
NS_ENSURE_TRUE(NS_SUCCEEDED(principal->Equals(dataPrincipal, &equals)) && equals,
NS_ERROR_DOM_SECURITY_ERR);
@ -697,11 +695,8 @@ DataTransfer::MozSetDataAt(const nsAString& aFormat, nsIVariant* aData,
return NS_ERROR_DOM_SECURITY_ERR;
}
nsresult rv = NS_OK;
nsIPrincipal* principal = GetCurrentPrincipal(&rv);
NS_ENSURE_SUCCESS(rv, rv);
return SetDataWithPrincipal(aFormat, aData, aIndex, principal);
return SetDataWithPrincipal(aFormat, aData, aIndex,
nsContentUtils::GetSubjectPrincipal());
}
void
@ -754,12 +749,7 @@ DataTransfer::MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
nsAutoString format;
GetRealFormat(aFormat, format);
nsresult rv = NS_OK;
nsIPrincipal* principal = GetCurrentPrincipal(&rv);
if (NS_FAILED(rv)) {
aRv = rv;
return;
}
nsIPrincipal* principal = nsContentUtils::GetSubjectPrincipal();
// if the format is empty, clear all formats
bool clearall = format.IsEmpty();
@ -1089,21 +1079,6 @@ DataTransfer::SetDataWithPrincipal(const nsAString& aFormat,
return NS_OK;
}
nsIPrincipal*
DataTransfer::GetCurrentPrincipal(nsresult* rv)
{
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
nsCOMPtr<nsIPrincipal> currentPrincipal;
*rv = ssm->GetSubjectPrincipal(getter_AddRefs(currentPrincipal));
NS_ENSURE_SUCCESS(*rv, nullptr);
if (!currentPrincipal)
ssm->GetSystemPrincipal(getter_AddRefs(currentPrincipal));
return currentPrincipal.get();
}
void
DataTransfer::GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat)
{

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

@ -219,9 +219,6 @@ public:
protected:
// returns a weak reference to the current principal
nsIPrincipal* GetCurrentPrincipal(nsresult* rv);
// converts some formats used for compatibility in aInFormat into aOutFormat.
// Text and text/unicode become text/plain, and URL becomes text/uri-list
void GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat);

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

@ -1,5 +1,4 @@
{
"DOMException exception: existence and properties of exception interface prototype object": true,
"DOMException exception: existence and properties of exception interface prototype object's \"name\" property": true,
"CustomEvent interface: existence and properties of interface object": true,
"EventListener interface: existence and properties of interface prototype object": true,

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

@ -3,11 +3,8 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DIST_FILES = \
install.rdf \
$(NULL)
DIST_FILES_NO_PP = \
bootstrap.js \
install.rdf \
$(NULL)
TEST_EXTENSIONS_DIR = $(DEPTH)/_tests/testing/mochitest/extensions

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

@ -121,6 +121,7 @@ TabChildBase::TabChildBase()
NS_IMPL_CYCLE_COLLECTING_ADDREF(TabChildBase)
NS_IMPL_CYCLE_COLLECTING_RELEASE(TabChildBase)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TabChildBase)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION(TabChildBase, mTabChildGlobal, mGlobal)
@ -975,8 +976,7 @@ TabChild::NotifyTabContextUpdated()
}
}
NS_INTERFACE_MAP_BEGIN(TabChild)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChild)
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
@ -989,10 +989,10 @@ NS_INTERFACE_MAP_BEGIN(TabChild)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsITooltipListener)
NS_INTERFACE_MAP_END
NS_INTERFACE_MAP_END_INHERITING(TabChildBase)
NS_IMPL_ADDREF(TabChild)
NS_IMPL_RELEASE(TabChild)
NS_IMPL_ADDREF_INHERITED(TabChild, TabChildBase);
NS_IMPL_RELEASE_INHERITED(TabChild, TabChildBase);
NS_IMETHODIMP
TabChild::SetStatus(uint32_t aStatusType, const char16_t* aStatus)

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

@ -220,7 +220,8 @@ protected:
mozilla::layout::ScrollingBehavior mScrolling;
};
class TabChild : public PBrowserChild,
class TabChild : public TabChildBase,
public PBrowserChild,
public nsIWebBrowserChrome2,
public nsIEmbeddingSiteWindow,
public nsIWebBrowserChromeFocus,
@ -232,8 +233,7 @@ class TabChild : public PBrowserChild,
public nsITabChild,
public nsIObserver,
public TabContext,
public nsITooltipListener,
public TabChildBase
public nsITooltipListener
{
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
@ -256,7 +256,7 @@ public:
bool IsRootContentDocument();
NS_DECL_ISUPPORTS
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIWEBBROWSERCHROME
NS_DECL_NSIWEBBROWSERCHROME2
NS_DECL_NSIEMBEDDINGSITEWINDOW

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

@ -241,18 +241,12 @@ DOMStorage::CanUseStorage(DOMStorage* aStorage)
}
// chrome can always use aStorage regardless of permission preferences
if (nsContentUtils::IsCallerChrome()) {
nsCOMPtr<nsIPrincipal> subjectPrincipal =
nsContentUtils::GetSubjectPrincipal();
if (nsContentUtils::IsSystemPrincipal(subjectPrincipal)) {
return true;
}
nsCOMPtr<nsIPrincipal> subjectPrincipal;
nsresult rv = nsContentUtils::GetSecurityManager()->
GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
NS_ENSURE_SUCCESS(rv, false);
// if subjectPrincipal were null we'd have returned after
// IsCallerChrome().
nsCOMPtr<nsIPermissionManager> permissionManager =
services::GetPermissionManager();
if (!permissionManager) {

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

@ -18,13 +18,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=
<script type="application/javascript">
<![CDATA[
/** Test for Bug **/
let Ci = Components.interfaces;
var obs = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
.getService(Ci.nsIObserverService);
var didCall = false;
var observer = {
QueryInterface: function QueryInterface(aIID) {
if (aIID.equals(Components.interfaces.nsIObserver) ||
aIID.equals(Components.interfaces.nsISupports))
if (aIID.equals(Ci.nsIObserver) ||
aIID.equals(Ci.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
},
@ -35,9 +36,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=
}
};
// Make sure that we call the observer even if we're in the middle
// of an ICC when we add the observer. See bug 981033.
// XXX This will assert if we try to start an ICC during a IGC.
//SpecialPowers.finishCC();
//SpecialPowers.ccSlice(1);
obs.addObserver(observer, "cycle-collector-begin", false);
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils).cycleCollect();
SpecialPowers.DOMWindowUtils.cycleCollect();
ok(didCall, "Observer should have been called!");
]]>

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

@ -18,11 +18,18 @@ interface StackFrame;
[NoInterfaceObject]
interface ExceptionMembers
{
// A custom message set by the thrower.
// A custom message set by the thrower. LenientThis so it can be
// gotten on the prototype, which Error.prototype.toString will do
// if someone tries to stringify DOMException.prototype.
[LenientThis]
readonly attribute DOMString message;
// The nsresult associated with this exception.
readonly attribute unsigned long result;
// The name of the error code (ie, a string repr of |result|)
// The name of the error code (ie, a string repr of |result|).
// LenientThis so it can be gotten on the prototype, which
// Error.prototype.toString will do if someone tries to stringify
// DOMException.prototype.
[LenientThis]
readonly attribute DOMString name;
// Filename location. This is the location that caused the
@ -49,19 +56,19 @@ interface ExceptionMembers
// Arbitary data for the implementation.
readonly attribute nsISupports? data;
// A generic formatter - make it suitable to print, etc.
stringifier;
};
[NoInterfaceObject]
interface Exception {
// A generic formatter - make it suitable to print, etc.
stringifier;
};
Exception implements ExceptionMembers;
// XXXkhuey this is an 'exception', not an interface, but we don't have any
// parser or codegen mechanisms for dealing with exceptions.
[ExceptionClass]
interface DOMException {
const unsigned short INDEX_SIZE_ERR = 1;
const unsigned short DOMSTRING_SIZE_ERR = 2; // historical

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

@ -3717,6 +3717,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
using namespace mozilla::dom::workers::scriptloader;
MOZ_ASSERT(aCx);
MOZ_ASSERT_IF(NS_IsMainThread(), aCx == nsContentUtils::GetCurrentJSContext());
if (aWindow) {
AssertIsOnMainThread();
@ -3913,10 +3914,6 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
MOZ_ASSERT(loadInfo.mPrincipal);
MOZ_ASSERT(isChrome || !loadInfo.mDomain.IsEmpty());
// XXXbent Use subject principal here instead of the one we already have?
nsCOMPtr<nsIPrincipal> subjectPrincipal = ssm->GetCxSubjectPrincipal(aCx);
MOZ_ASSERT(subjectPrincipal);
if (!nsContentUtils::GetContentSecurityPolicy(aCx,
getter_AddRefs(loadInfo.mCSP))) {
NS_WARNING("Failed to get CSP!");

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

@ -3,11 +3,8 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DIST_FILES = \
install.rdf \
$(NULL)
DIST_FILES_NO_PP = \
bootstrap.js \
install.rdf \
worker.js \
$(NULL)

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

@ -4,9 +4,6 @@
DIST_FILES = \
install.rdf \
$(NULL)
DIST_FILES_NO_PP = \
worker.js \
$(NULL)

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

@ -1252,15 +1252,8 @@ NS_IMETHODIMP
txMozillaXSLTProcessor::Initialize(nsISupports* aOwner, JSContext* cx,
JSObject* obj, const JS::CallArgs& args)
{
nsCOMPtr<nsIPrincipal> prin;
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
NS_ENSURE_TRUE(secMan, NS_ERROR_UNEXPECTED);
nsresult rv = secMan->GetSubjectPrincipal(getter_AddRefs(prin));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(prin, NS_ERROR_UNEXPECTED);
return Init(prin);
MOZ_ASSERT(nsContentUtils::GetCurrentJSContext());
return Init(nsContentUtils::GetSubjectPrincipal());
}
NS_IMETHODIMP

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

@ -14,6 +14,7 @@
#include "nsServiceManagerUtils.h"
#include "nsIScriptSecurityManager.h"
#include "nsContentUtils.h"
#include "nsIDOMWindow.h"
#include "nsPIDOMWindow.h"
#include "nsPIWindowRoot.h"
@ -236,22 +237,6 @@ nsCommandManager::DoCommand(const char *aCommandName,
return rv;
}
nsresult
nsCommandManager::IsCallerChrome(bool *is_caller_chrome)
{
*is_caller_chrome = false;
nsresult rv = NS_OK;
nsCOMPtr<nsIScriptSecurityManager> secMan =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
if (!secMan)
return NS_ERROR_FAILURE;
rv = secMan->SubjectPrincipalIsSystem(is_caller_chrome);
return rv;
}
nsresult
nsCommandManager::GetControllerForCommand(const char *aCommand,
nsIDOMWindow *aTargetWindow,
@ -262,12 +247,7 @@ nsCommandManager::GetControllerForCommand(const char *aCommand,
// check if we're in content or chrome
// if we're not chrome we must have a target window or we bail
bool isChrome = false;
rv = IsCallerChrome(&isChrome);
if (NS_FAILED(rv))
return rv;
if (!isChrome) {
if (!nsContentUtils::IsCallerChrome()) {
if (!aTargetWindow)
return rv;

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

@ -43,8 +43,6 @@ public:
protected:
nsresult IsCallerChrome(bool *aIsCallerChrome);
nsresult GetControllerForCommand(const char * aCommand,
nsIDOMWindow *aDirectedToThisWindow,
nsIController** outController);

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

@ -39,6 +39,7 @@
#include "mozilla/Services.h"
#include "mozilla/dom/Element.h"
#include "nsISimpleEnumerator.h"
#include "nsContentUtils.h"
#if DEBUG
#include "nsIWebNavigation.h"
@ -660,21 +661,8 @@ nsresult nsWebBrowserFind::SearchInFrame(nsIDOMWindow* aWindow,
nsCOMPtr<nsIDocument> theDoc = do_QueryInterface(domDoc);
if (!theDoc) return NS_ERROR_FAILURE;
nsCOMPtr<nsIScriptSecurityManager> secMan =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> subject;
rv = secMan->GetSubjectPrincipal(getter_AddRefs(subject));
NS_ENSURE_SUCCESS(rv, rv);
if (subject) {
bool subsumes;
rv = subject->Subsumes(theDoc->NodePrincipal(), &subsumes);
NS_ENSURE_SUCCESS(rv, rv);
if (!subsumes) {
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
}
if (!nsContentUtils::GetSubjectPrincipal()->Subsumes(theDoc->NodePrincipal())) {
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
}
nsCOMPtr<nsIFind> find = do_CreateInstance(NS_FIND_CONTRACTID, &rv);

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

@ -785,15 +785,14 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
// Now we have to set the right opener principal on the new window. Note
// that we have to do this _before_ starting any URI loads, thanks to the
// sync nature of javascript: loads. Since this is the only place where we
// set said opener principal, we need to do it for all URIs, including
// chrome ones. So to deal with the mess that is bug 79775, just press on in
// a reasonable way even if GetSubjectPrincipal fails. In that case, just
// use a null subjectPrincipal.
nsCOMPtr<nsIPrincipal> subjectPrincipal;
if (NS_FAILED(sm->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal)))) {
subjectPrincipal = nullptr;
}
// sync nature of javascript: loads.
//
// Note: The check for the current JSContext isn't necessarily sensical.
// It's just designed to preserve old semantics during a mass-conversion
// patch.
nsCOMPtr<nsIPrincipal> subjectPrincipal =
nsContentUtils::GetCurrentJSContext() ? nsContentUtils::GetSubjectPrincipal()
: nullptr;
if (windowIsNew) {
// Now set the opener principal on the new window. Note that we need to do

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

@ -303,6 +303,19 @@ GLContext::~GLContext() {
#endif
}
/*static*/ void
GLContext::StaticDebugCallback(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const GLvoid* userParam)
{
GLContext* gl = (GLContext*)userParam;
gl->DebugCallback(source, type, id, severity, length, message);
}
bool
GLContext::InitWithPrefix(const char *prefix, bool trygl)
{
@ -1159,6 +1172,17 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
mTexGarbageBin = new TextureGarbageBin(this);
MOZ_ASSERT(IsCurrent());
if (DebugMode() && IsExtensionSupported(KHR_debug)) {
fEnable(LOCAL_GL_DEBUG_OUTPUT);
fDisable(LOCAL_GL_DEBUG_OUTPUT_SYNCHRONOUS);
fDebugMessageCallback(&StaticDebugCallback, (void*)this);
fDebugMessageControl(LOCAL_GL_DONT_CARE,
LOCAL_GL_DONT_CARE,
LOCAL_GL_DONT_CARE,
0, nullptr,
true);
}
}
if (mInitialized)
@ -1174,6 +1198,95 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
return mInitialized;
}
void
GLContext::DebugCallback(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message)
{
nsAutoCString sourceStr;
switch (source) {
case LOCAL_GL_DEBUG_SOURCE_API:
sourceStr = NS_LITERAL_CSTRING("SOURCE_API");
break;
case LOCAL_GL_DEBUG_SOURCE_WINDOW_SYSTEM:
sourceStr = NS_LITERAL_CSTRING("SOURCE_WINDOW_SYSTEM");
break;
case LOCAL_GL_DEBUG_SOURCE_SHADER_COMPILER:
sourceStr = NS_LITERAL_CSTRING("SOURCE_SHADER_COMPILER");
break;
case LOCAL_GL_DEBUG_SOURCE_THIRD_PARTY:
sourceStr = NS_LITERAL_CSTRING("SOURCE_THIRD_PARTY");
break;
case LOCAL_GL_DEBUG_SOURCE_APPLICATION:
sourceStr = NS_LITERAL_CSTRING("SOURCE_APPLICATION");
break;
case LOCAL_GL_DEBUG_SOURCE_OTHER:
sourceStr = NS_LITERAL_CSTRING("SOURCE_OTHER");
break;
default:
sourceStr = nsPrintfCString("<source 0x%04x>", source);
break;
}
nsAutoCString typeStr;
switch (type) {
case LOCAL_GL_DEBUG_TYPE_ERROR:
typeStr = NS_LITERAL_CSTRING("TYPE_ERROR");
break;
case LOCAL_GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
typeStr = NS_LITERAL_CSTRING("TYPE_DEPRECATED_BEHAVIOR");
break;
case LOCAL_GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
typeStr = NS_LITERAL_CSTRING("TYPE_UNDEFINED_BEHAVIOR");
break;
case LOCAL_GL_DEBUG_TYPE_PORTABILITY:
typeStr = NS_LITERAL_CSTRING("TYPE_PORTABILITY");
break;
case LOCAL_GL_DEBUG_TYPE_PERFORMANCE:
typeStr = NS_LITERAL_CSTRING("TYPE_PERFORMANCE");
break;
case LOCAL_GL_DEBUG_TYPE_OTHER:
typeStr = NS_LITERAL_CSTRING("TYPE_OTHER");
break;
case LOCAL_GL_DEBUG_TYPE_MARKER:
typeStr = NS_LITERAL_CSTRING("TYPE_MARKER");
break;
default:
typeStr = nsPrintfCString("<type 0x%04x>", type);
break;
}
nsAutoCString sevStr;
switch (severity) {
case LOCAL_GL_DEBUG_SEVERITY_HIGH:
sevStr = NS_LITERAL_CSTRING("SEVERITY_HIGH");
break;
case LOCAL_GL_DEBUG_SEVERITY_MEDIUM:
sevStr = NS_LITERAL_CSTRING("SEVERITY_MEDIUM");
break;
case LOCAL_GL_DEBUG_SEVERITY_LOW:
sevStr = NS_LITERAL_CSTRING("SEVERITY_LOW");
break;
case LOCAL_GL_DEBUG_SEVERITY_NOTIFICATION:
sevStr = NS_LITERAL_CSTRING("SEVERITY_NOTIFICATION");
break;
default:
sevStr = nsPrintfCString("<severity 0x%04x>", severity);
break;
}
printf_stderr("[KHR_debug: 0x%x] ID %u: %s %s %s:\n %s",
(uintptr_t)this,
id,
sourceStr.BeginReading(),
typeStr.BeginReading(),
sevStr.BeginReading(),
message);
}
void
GLContext::InitExtensions()
{

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

@ -582,6 +582,20 @@ private:
GLenum mGLError;
#endif // DEBUG
static void GLAPIENTRY StaticDebugCallback(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const GLvoid* userParam);
void DebugCallback(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message);
// -----------------------------------------------------------------------------
// MOZ_GL_DEBUG implementation

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

@ -205,6 +205,14 @@ public:
return mCompositionBounds / GetZoomToParent();
}
CSSSize CalculateBoundedCompositedSizeInCssPixels() const
{
CSSSize size = CalculateCompositedSizeInCssPixels();
size.width = std::min(size.width, mRootCompositionSize.width);
size.height = std::min(size.height, mRootCompositionSize.height);
return size;
}
void ScrollBy(const CSSPoint& aPoint)
{
mScrollOffset += aPoint;

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

@ -1485,11 +1485,7 @@ const LayerMargin AsyncPanZoomController::CalculatePendingDisplayPort(
const ScreenPoint& aVelocity,
double aEstimatedPaintDuration)
{
CSSSize compositionBounds = aFrameMetrics.CalculateCompositedSizeInCssPixels();
CSSSize compositionSize = aFrameMetrics.GetRootCompositionSize();
compositionSize =
CSSSize(std::min(compositionBounds.width, compositionSize.width),
std::min(compositionBounds.height, compositionSize.height));
CSSSize compositionSize = aFrameMetrics.CalculateBoundedCompositedSizeInCssPixels();
CSSPoint velocity = aVelocity / aFrameMetrics.GetZoom();
CSSPoint scrollOffset = aFrameMetrics.GetScrollOffset();
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
@ -1595,10 +1591,7 @@ GetDisplayPortRect(const FrameMetrics& aFrameMetrics)
// This computation is based on what happens in CalculatePendingDisplayPort. If that
// changes then this might need to change too
CSSRect baseRect(aFrameMetrics.GetScrollOffset(),
CSSSize(std::min(aFrameMetrics.CalculateCompositedSizeInCssPixels().width,
aFrameMetrics.GetRootCompositionSize().width),
std::min(aFrameMetrics.CalculateCompositedSizeInCssPixels().height,
aFrameMetrics.GetRootCompositionSize().height)));
aFrameMetrics.CalculateBoundedCompositedSizeInCssPixels());
baseRect.Inflate(aFrameMetrics.GetDisplayPortMargins() / aFrameMetrics.LayersPixelsPerCSSPixel());
return baseRect;
}

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

@ -241,7 +241,11 @@ bool
SharedFrameMetricsHelper::AboutToCheckerboard(const FrameMetrics& aContentMetrics,
const FrameMetrics& aCompositorMetrics)
{
return !aContentMetrics.mDisplayPort.Contains(aCompositorMetrics.CalculateCompositedRectInCssPixels() - aCompositorMetrics.GetScrollOffset());
CSSRect painted =
(aContentMetrics.mCriticalDisplayPort.IsEmpty() ? aContentMetrics.mDisplayPort : aContentMetrics.mCriticalDisplayPort)
+ aContentMetrics.GetScrollOffset();
CSSRect showing = CSSRect(aCompositorMetrics.GetScrollOffset(), aCompositorMetrics.CalculateBoundedCompositedSizeInCssPixels());
return !painted.Contains(showing);
}
ClientTiledLayerBuffer::ClientTiledLayerBuffer(ClientTiledThebesLayer* aThebesLayer,

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

@ -33,11 +33,10 @@ struct nsIntRect;
* loaded data fire before the call returns. If FLAG_SYNC_DECODE is not passed,
* all, some, or none of the notifications may fire before the call returns.
*/
class imgDecoderObserver : public mozilla::RefCounted<imgDecoderObserver>
class imgDecoderObserver
{
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(imgDecoderObserver)
virtual ~imgDecoderObserver() = 0;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(imgDecoderObserver);
/**
* Load notification.
@ -126,6 +125,9 @@ public:
* Called when an image is realized to be in error state.
*/
virtual void OnError() = 0;
protected:
virtual ~imgDecoderObserver() = 0;
};
// We must define a destructor because derived classes call our destructor from

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

@ -29,8 +29,6 @@ public:
MOZ_ASSERT(aTracker);
}
virtual ~imgStatusTrackerObserver() {}
void SetTracker(imgStatusTracker* aTracker)
{
MOZ_ASSERT(aTracker);
@ -143,6 +141,9 @@ public:
tracker->RecordError();
}
protected:
virtual ~imgStatusTrackerObserver() {}
private:
WeakPtr<imgStatusTracker> mTracker;
};

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

@ -0,0 +1,20 @@
var lfcode = new Array();
lfcode.push = loadFile;
lfcode.push("\
var g = newGlobal();\
g.debuggeeGlobal = this;\
g.eval(\"(\" + function () {\
dbg = new Debugger(debuggeeGlobal);\
} + \")();\");\
");
lfcode.push("gc();");
lfcode.push("\
var g = newGlobal();\
g.debuggeeGlobal = this;\
g.eval(\"(\" + function () {\
dbg = new Debugger(debuggeeGlobal);\
} + \")();\");\
");
function loadFile(lfVarx) {
function newFunc(x) { new Function(x)(); }; newFunc(lfVarx);
}

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

@ -25,9 +25,10 @@ withJitOptions(Opts_Ion2NoParallelCompilation, function () {
}
};
g.eval("" + function f(d, x) { g(d, x); });
g.eval("" + function f(d, x) { "use strict"; g(d, x); });
g.eval("" + function g(d, x) {
"use strict";
for (var i = 0; i < 200; i++);
// Hack to prevent inlining.
function inner() { i = 42; };

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

@ -0,0 +1,10 @@
var i = 0;
var expectedmatch = '';
var expectedmatches = new Array();
addThis();
expectedmatch = null;
addThis();
function addThis() {
Array(-2147483648, -2147483648);
expectedmatches[i] = expectedmatch;
}

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

@ -0,0 +1,5 @@
(function(x) {
for (var y = 0; y < 1; y++) {
assertEq(Array.prototype.shift.call(arguments.callee.arguments), 0);
}
})(0)

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

@ -167,10 +167,10 @@ InvokeFromAsmJS_ToNumber(JSContext *cx, int32_t exitIndex, int32_t argc, Value *
#if defined(JS_CODEGEN_ARM)
extern "C" {
extern int64_t
extern MOZ_EXPORT int64_t
__aeabi_idivmod(int, int);
extern int64_t
extern MOZ_EXPORT int64_t
__aeabi_uidivmod(int, int);
}
@ -1246,7 +1246,7 @@ struct ScopedCacheEntryOpenedForWrite
~ScopedCacheEntryOpenedForWrite() {
if (memory)
cx->asmJSCacheOps().closeEntryForWrite(cx->global(), serializedSize, memory, handle);
cx->asmJSCacheOps().closeEntryForWrite(serializedSize, memory, handle);
}
};
@ -1303,7 +1303,7 @@ struct ScopedCacheEntryOpenedForRead
~ScopedCacheEntryOpenedForRead() {
if (memory)
cx->asmJSCacheOps().closeEntryForRead(cx->global(), serializedSize, memory, handle);
cx->asmJSCacheOps().closeEntryForRead(serializedSize, memory, handle);
}
};

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

@ -93,6 +93,10 @@ struct DebugModeOSREntry
frameKind == ICEntry::Kind_DebugEpilogue);
}
bool recompiled() const {
return oldBaselineScript != script->baselineScript();
}
BaselineDebugModeOSRInfo *takeRecompInfo() {
MOZ_ASSERT(recompInfo);
BaselineDebugModeOSRInfo *tmp = recompInfo;
@ -208,9 +212,8 @@ SpewPatchBaselineFrame(uint8_t *oldReturnAddress, uint8_t *newReturnAddress,
JSScript *script, ICEntry::Kind frameKind, jsbytecode *pc)
{
IonSpew(IonSpew_BaselineDebugModeOSR,
"Patch return %#016llx -> %#016llx to BaselineJS (%s:%d) from %s at %s",
uintptr_t(oldReturnAddress), uintptr_t(newReturnAddress),
script->filename(), script->lineno(),
"Patch return %p -> %p on BaselineJS frame (%s:%d) from %s at %s",
oldReturnAddress, newReturnAddress, script->filename(), script->lineno(),
ICEntryKindToString(frameKind), js_CodeName[(JSOp)*pc]);
}
@ -218,8 +221,8 @@ static void
SpewPatchStubFrame(ICStub *oldStub, ICStub *newStub)
{
IonSpew(IonSpew_BaselineDebugModeOSR,
"Patch stub %#016llx -> %#016llx to BaselineStub (%s)",
uintptr_t(oldStub), uintptr_t(newStub), ICStub::KindString(newStub->kind()));
"Patch stub %p -> %p on BaselineStub frame (%s)",
oldStub, newStub, ICStub::KindString(newStub->kind()));
}
static void
@ -254,8 +257,15 @@ PatchBaselineFramesForDebugMode(JSContext *cx, const JitActivationIterator &acti
for (JitFrameIterator iter(activation); !iter.done(); ++iter) {
DebugModeOSREntry &entry = entries[entryIndex];
switch (iter.type()) {
case JitFrame_BaselineJS: {
// If the script wasn't recompiled, there's nothing to patch.
if (!entry.recompiled()) {
entryIndex++;
break;
}
JSScript *script = entry.script;
uint32_t pcOffset = entry.pcOffset;
jsbytecode *pc = script->offsetToPC(pcOffset);
@ -351,6 +361,10 @@ PatchBaselineFramesForDebugMode(JSContext *cx, const JitActivationIterator &acti
}
case JitFrame_BaselineStub: {
// If the script wasn't recompiled, there's nothing to patch.
if (!entry.recompiled())
break;
IonBaselineStubFrameLayout *layout =
reinterpret_cast<IonBaselineStubFrameLayout *>(iter.fp());
MOZ_ASSERT(entry.script->baselineScript()->debugMode() == expectedDebugMode);
@ -539,7 +553,7 @@ UndoRecompileBaselineScriptsForDebugMode(JSContext *cx,
for (size_t i = 0; i < entries.length(); i++) {
JSScript *script = entries[i].script;
BaselineScript *baselineScript = script->baselineScript();
if (baselineScript != entries[i].oldBaselineScript) {
if (entries[i].recompiled()) {
script->setBaselineScript(cx, entries[i].oldBaselineScript);
BaselineScript::Destroy(cx->runtime()->defaultFreeOp(), baselineScript);
}
@ -587,8 +601,10 @@ jit::RecompileOnStackBaselineScriptsForDebugMode(JSContext *cx, JSCompartment *c
//
// After this point the function must be infallible.
for (size_t i = 0; i < entries.length(); i++)
BaselineScript::Destroy(cx->runtime()->defaultFreeOp(), entries[i].oldBaselineScript);
for (size_t i = 0; i < entries.length(); i++) {
if (entries[i].recompiled())
BaselineScript::Destroy(cx->runtime()->defaultFreeOp(), entries[i].oldBaselineScript);
}
size_t processed = 0;
for (JitActivationIterator iter(cx->runtime()); !iter.done(); ++iter) {

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

@ -1271,6 +1271,14 @@ static bool
DoTypeMonitorFallback(JSContext *cx, BaselineFrame *frame, ICTypeMonitor_Fallback *stub,
HandleValue value, MutableHandleValue res)
{
// It's possible that we arrived here from bailing out of Ion, and that
// Ion proved that the value is dead and optimized out. In such cases, do
// nothing.
if (value.isMagic(JS_OPTIMIZED_OUT)) {
res.set(value);
return true;
}
RootedScript script(cx, frame->script());
jsbytecode *pc = stub->icEntry()->pc(script);
TypeFallbackICSpew(cx, stub, "TypeMonitor");

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

@ -6834,6 +6834,7 @@ CodeGenerator::visitCallsiteCloneCache(LCallsiteCloneCache *ins)
Register output = ToRegister(ins->output());
CallsiteCloneIC cache(callee, mir->block()->info().script(), mir->callPc(), output);
cache.setProfilerLeavePC(mir->profilerLeavePc());
return addCache(ins, allocateCache(cache));
}
@ -6867,6 +6868,7 @@ CodeGenerator::visitGetNameCache(LGetNameCache *ins)
bool isTypeOf = ins->mir()->accessKind() != MGetNameCache::NAME;
NameIC cache(liveRegs, isTypeOf, scopeChain, ins->mir()->name(), output);
cache.setProfilerLeavePC(ins->mir()->profilerLeavePc());
return addCache(ins, allocateCache(cache));
}
@ -6893,15 +6895,17 @@ CodeGenerator::visitNameIC(OutOfLineUpdateCache *ool, DataPtr<NameIC> &ic)
bool
CodeGenerator::addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
PropertyName *name, TypedOrValueRegister output,
bool monitoredResult)
bool monitoredResult, jsbytecode *profilerLeavePc)
{
switch (gen->info().executionMode()) {
case SequentialExecution: {
GetPropertyIC cache(liveRegs, objReg, name, output, monitoredResult);
cache.setProfilerLeavePC(profilerLeavePc);
return addCache(ins, allocateCache(cache));
}
case ParallelExecution: {
GetPropertyParIC cache(objReg, name, output);
cache.setProfilerLeavePC(profilerLeavePc);
return addCache(ins, allocateCache(cache));
}
default:
@ -6912,15 +6916,17 @@ CodeGenerator::addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Regi
bool
CodeGenerator::addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
PropertyName *name, ConstantOrRegister value, bool strict,
bool needsTypeBarrier)
bool needsTypeBarrier, jsbytecode *profilerLeavePc)
{
switch (gen->info().executionMode()) {
case SequentialExecution: {
SetPropertyIC cache(liveRegs, objReg, name, value, strict, needsTypeBarrier);
cache.setProfilerLeavePC(profilerLeavePc);
return addCache(ins, allocateCache(cache));
}
case ParallelExecution: {
SetPropertyParIC cache(objReg, name, value, strict, needsTypeBarrier);
cache.setProfilerLeavePC(profilerLeavePc);
return addCache(ins, allocateCache(cache));
}
default:
@ -6931,17 +6937,20 @@ CodeGenerator::addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Regi
bool
CodeGenerator::addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex,
Register temp, FloatRegister tempFloat, ValueOperand index,
ConstantOrRegister value, bool strict, bool guardHoles)
ConstantOrRegister value, bool strict, bool guardHoles,
jsbytecode *profilerLeavePc)
{
switch (gen->info().executionMode()) {
case SequentialExecution: {
SetElementIC cache(obj, unboxIndex, temp, tempFloat, index, value, strict,
guardHoles);
cache.setProfilerLeavePC(profilerLeavePc);
return addCache(ins, allocateCache(cache));
}
case ParallelExecution: {
SetElementParIC cache(obj, unboxIndex, temp, tempFloat, index, value, strict,
guardHoles);
cache.setProfilerLeavePC(profilerLeavePc);
return addCache(ins, allocateCache(cache));
}
default:
@ -6958,7 +6967,8 @@ CodeGenerator::visitGetPropertyCacheV(LGetPropertyCacheV *ins)
bool monitoredResult = ins->mir()->monitoredResult();
TypedOrValueRegister output = TypedOrValueRegister(GetValueOutput(ins));
return addGetPropertyCache(ins, liveRegs, objReg, name, output, monitoredResult);
return addGetPropertyCache(ins, liveRegs, objReg, name, output, monitoredResult,
ins->mir()->profilerLeavePc());
}
bool
@ -6970,7 +6980,8 @@ CodeGenerator::visitGetPropertyCacheT(LGetPropertyCacheT *ins)
bool monitoredResult = ins->mir()->monitoredResult();
TypedOrValueRegister output(ins->mir()->type(), ToAnyRegister(ins->getDef(0)));
return addGetPropertyCache(ins, liveRegs, objReg, name, output, monitoredResult);
return addGetPropertyCache(ins, liveRegs, objReg, name, output, monitoredResult,
ins->mir()->profilerLeavePc());
}
typedef bool (*GetPropertyICFn)(JSContext *, size_t, HandleObject, MutableHandleValue);
@ -7026,16 +7037,18 @@ CodeGenerator::visitGetPropertyParIC(OutOfLineUpdateCache *ool, DataPtr<GetPrope
bool
CodeGenerator::addGetElementCache(LInstruction *ins, Register obj, ConstantOrRegister index,
TypedOrValueRegister output, bool monitoredResult,
bool allowDoubleResult)
bool allowDoubleResult, jsbytecode *profilerLeavePc)
{
switch (gen->info().executionMode()) {
case SequentialExecution: {
RegisterSet liveRegs = ins->safepoint()->liveRegs();
GetElementIC cache(liveRegs, obj, index, output, monitoredResult, allowDoubleResult);
cache.setProfilerLeavePC(profilerLeavePc);
return addCache(ins, allocateCache(cache));
}
case ParallelExecution: {
GetElementParIC cache(obj, index, output, monitoredResult, allowDoubleResult);
cache.setProfilerLeavePC(profilerLeavePc);
return addCache(ins, allocateCache(cache));
}
default:
@ -7051,7 +7064,8 @@ CodeGenerator::visitGetElementCacheV(LGetElementCacheV *ins)
TypedOrValueRegister output = TypedOrValueRegister(GetValueOutput(ins));
const MGetElementCache *mir = ins->mir();
return addGetElementCache(ins, obj, index, output, mir->monitoredResult(), mir->allowDoubleResult());
return addGetElementCache(ins, obj, index, output, mir->monitoredResult(),
mir->allowDoubleResult(), mir->profilerLeavePc());
}
bool
@ -7062,7 +7076,8 @@ CodeGenerator::visitGetElementCacheT(LGetElementCacheT *ins)
TypedOrValueRegister output(ins->mir()->type(), ToAnyRegister(ins->output()));
const MGetElementCache *mir = ins->mir();
return addGetElementCache(ins, obj, index, output, mir->monitoredResult(), mir->allowDoubleResult());
return addGetElementCache(ins, obj, index, output, mir->monitoredResult(),
mir->allowDoubleResult(), mir->profilerLeavePc());
}
typedef bool (*GetElementICFn)(JSContext *, size_t, HandleObject, HandleValue, MutableHandleValue);
@ -7098,7 +7113,8 @@ CodeGenerator::visitSetElementCacheV(LSetElementCacheV *ins)
ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LSetElementCacheV::Value));
return addSetElementCache(ins, obj, unboxIndex, temp, tempFloat, index, value,
ins->mir()->strict(), ins->mir()->guardHoles());
ins->mir()->strict(), ins->mir()->guardHoles(),
ins->mir()->profilerLeavePc());
}
bool
@ -7117,7 +7133,8 @@ CodeGenerator::visitSetElementCacheT(LSetElementCacheT *ins)
value = TypedOrValueRegister(ins->mir()->value()->type(), ToAnyRegister(tmp));
return addSetElementCache(ins, obj, unboxIndex, temp, tempFloat, index, value,
ins->mir()->strict(), ins->mir()->guardHoles());
ins->mir()->strict(), ins->mir()->guardHoles(),
ins->mir()->profilerLeavePc());
}
typedef bool (*SetElementICFn)(JSContext *, size_t, HandleObject, HandleValue, HandleValue);
@ -7193,6 +7210,7 @@ CodeGenerator::visitBindNameCache(LBindNameCache *ins)
Register scopeChain = ToRegister(ins->scopeChain());
Register output = ToRegister(ins->output());
BindNameIC cache(scopeChain, ins->mir()->name(), output);
cache.setProfilerLeavePC(ins->mir()->profilerLeavePc());
return addCache(ins, allocateCache(cache));
}
@ -7287,7 +7305,8 @@ CodeGenerator::visitSetPropertyCacheV(LSetPropertyCacheV *ins)
ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LSetPropertyCacheV::Value));
return addSetPropertyCache(ins, liveRegs, objReg, ins->mir()->name(), value,
ins->mir()->strict(), ins->mir()->needsTypeBarrier());
ins->mir()->strict(), ins->mir()->needsTypeBarrier(),
ins->mir()->profilerLeavePc());
}
bool
@ -7303,7 +7322,8 @@ CodeGenerator::visitSetPropertyCacheT(LSetPropertyCacheT *ins)
value = TypedOrValueRegister(ins->valueType(), ToAnyRegister(ins->getOperand(1)));
return addSetPropertyCache(ins, liveRegs, objReg, ins->mir()->name(), value,
ins->mir()->strict(), ins->mir()->needsTypeBarrier());
ins->mir()->strict(), ins->mir()->needsTypeBarrier(),
ins->mir()->profilerLeavePc());
}
typedef bool (*SetPropertyICFn)(JSContext *, size_t, HandleObject, HandleValue);

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

@ -353,16 +353,16 @@ class CodeGenerator : public CodeGeneratorSpecific
private:
bool addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
PropertyName *name, TypedOrValueRegister output,
bool monitoredResult);
bool monitoredResult, jsbytecode *profilerLeavePc);
bool addGetElementCache(LInstruction *ins, Register obj, ConstantOrRegister index,
TypedOrValueRegister output, bool monitoredResult,
bool allowDoubleResult);
bool allowDoubleResult, jsbytecode *profilerLeavePc);
bool addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
PropertyName *name, ConstantOrRegister value, bool strict,
bool needsTypeBarrier);
bool needsTypeBarrier, jsbytecode *profilerLeavePc);
bool addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex, Register temp,
FloatRegister tempFloat, ValueOperand index, ConstantOrRegister value,
bool strict, bool guardHoles);
bool strict, bool guardHoles, jsbytecode *profilerLeavePc);
bool checkForAbortPar(LInstruction *lir);
bool generateBranchV(const ValueOperand &value, Label *ifTrue, Label *ifFalse, FloatRegister fr);

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

@ -80,6 +80,15 @@ class InlineScriptTree {
return caller_;
}
bool isOutermostCaller() const {
return caller_ == nullptr;
}
InlineScriptTree *outermostCaller() {
if (isOutermostCaller())
return this;
return caller_->outermostCaller();
}
jsbytecode *callerPc() const {
return callerPc_;
}
@ -392,6 +401,15 @@ class CompileInfo
return executionMode_ == ParallelExecution;
}
bool canOptimizeOutSlot(uint32_t i) const {
if (script()->strict())
return true;
// Function.arguments can be used to access all arguments in
// non-strict scripts, so we can't optimize out any arguments.
return !(firstArgSlot() <= i && i - firstArgSlot() < nargs());
}
private:
unsigned nimplicit_;
unsigned nargs_;

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

@ -143,16 +143,12 @@ jit::EliminateDeadResumePointOperands(MIRGenerator *mir, MIRGraph &graph)
continue;
}
// Function.arguments can be used to access all arguments in
// non-strict scripts, so we can't optimize out any arguments.
CompileInfo &info = block->info();
if (!info.script()->strict()) {
uint32_t slot = uses->index();
uint32_t firstArgSlot = info.firstArgSlot();
if (firstArgSlot <= slot && slot - firstArgSlot < info.nargs()) {
uses++;
continue;
}
// The operand is an uneliminable slot. This currently
// includes argument slots in non-strict scripts (due to being
// observable via Function.arguments).
if (!block->info().canOptimizeOutSlot(uses->index())) {
uses++;
continue;
}
// Store an optimized out magic value in place of all dead
@ -254,18 +250,11 @@ IsPhiObservable(MPhi *phi, Observability observe)
return true;
}
// If the Phi is one of the formal argument, and we are using an argument
// object in the function. The phi might be observable after a bailout.
// For inlined frames this is not needed, as they are captured in the inlineResumePoint.
if (fun && info.hasArguments()) {
uint32_t first = info.firstArgSlot();
if (first <= slot && slot - first < info.nargs()) {
// If arguments obj aliases formals, then the arg slots will never be used.
if (info.argsObjAliasesFormals())
return false;
return true;
}
}
// The Phi is an uneliminable slot. Currently this includes argument slots
// in non-strict scripts (due to being observable via Function.arguments).
if (fun && !info.canOptimizeOutSlot(slot))
return true;
return false;
}

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

@ -32,6 +32,8 @@ using namespace js::jit;
using mozilla::tl::FloorLog2;
typedef Rooted<TypedArrayObject *> RootedTypedArrayObject;
void
CodeLocationJump::repoint(JitCode *code, MacroAssembler *masm)
{
@ -1195,11 +1197,13 @@ GetPropertyIC::allowArrayLength(Context cx, HandleObject obj) const
}
bool
GetPropertyIC::tryAttachNative(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, void *returnAddr, bool *emitted)
GetPropertyIC::tryAttachNative(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name,
void *returnAddr, bool *emitted)
{
JS_ASSERT(canAttachStub());
JS_ASSERT(!*emitted);
JS_ASSERT(outerScript->ionScript() == ion);
RootedShape shape(cx);
RootedObject holder(cx);
@ -1211,7 +1215,7 @@ GetPropertyIC::tryAttachNative(JSContext *cx, IonScript *ion, HandleObject obj,
*emitted = true;
MacroAssembler masm(cx, ion, script_, pc_);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
const char *attachKind;
@ -1244,8 +1248,8 @@ GetPropertyIC::tryAttachNative(JSContext *cx, IonScript *ion, HandleObject obj,
}
bool
GetPropertyIC::tryAttachTypedArrayLength(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, bool *emitted)
GetPropertyIC::tryAttachTypedArrayLength(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name, bool *emitted)
{
JS_ASSERT(canAttachStub());
JS_ASSERT(!*emitted);
@ -1270,7 +1274,7 @@ GetPropertyIC::tryAttachTypedArrayLength(JSContext *cx, IonScript *ion, HandleOb
*emitted = true;
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
GenerateTypedArrayLength(cx, masm, attacher, obj, object(), output());
@ -1353,7 +1357,7 @@ EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
}
bool
GetPropertyIC::tryAttachDOMProxyShadowed(JSContext *cx, IonScript *ion,
GetPropertyIC::tryAttachDOMProxyShadowed(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, void *returnAddr,
bool *emitted)
{
@ -1369,7 +1373,7 @@ GetPropertyIC::tryAttachDOMProxyShadowed(JSContext *cx, IonScript *ion,
*emitted = true;
Label failures;
MacroAssembler masm(cx, ion, script_, pc_);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
// Guard on the shape of the object.
@ -1399,9 +1403,9 @@ GetPropertyIC::tryAttachDOMProxyShadowed(JSContext *cx, IonScript *ion,
}
bool
GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, bool resetNeeded,
void *returnAddr, bool *emitted)
GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name,
bool resetNeeded, void *returnAddr, bool *emitted)
{
JS_ASSERT(canAttachStub());
JS_ASSERT(!*emitted);
@ -1438,7 +1442,7 @@ GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, Handle
}
Label failures;
MacroAssembler masm(cx, ion, script_, pc_);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
// Guard on the shape of the object.
@ -1499,9 +1503,9 @@ GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, Handle
}
bool
GetPropertyIC::tryAttachProxy(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, void *returnAddr,
bool *emitted)
GetPropertyIC::tryAttachProxy(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name,
void *returnAddr, bool *emitted)
{
JS_ASSERT(canAttachStub());
JS_ASSERT(!*emitted);
@ -1521,13 +1525,13 @@ GetPropertyIC::tryAttachProxy(JSContext *cx, IonScript *ion, HandleObject obj,
if (shadows == ShadowCheckFailed)
return false;
if (shadows == Shadows)
return tryAttachDOMProxyShadowed(cx, ion, obj, returnAddr, emitted);
return tryAttachDOMProxyShadowed(cx, outerScript, ion, obj, returnAddr, emitted);
return tryAttachDOMProxyUnshadowed(cx, ion, obj, name, shadows == DoesntShadowUnique,
returnAddr, emitted);
return tryAttachDOMProxyUnshadowed(cx, outerScript, ion, obj, name,
shadows == DoesntShadowUnique, returnAddr, emitted);
}
return tryAttachGenericProxy(cx, ion, obj, name, returnAddr, emitted);
return tryAttachGenericProxy(cx, outerScript, ion, obj, name, returnAddr, emitted);
}
static void
@ -1541,8 +1545,8 @@ GenerateProxyClassGuards(MacroAssembler &masm, Register object, Register scratch
}
bool
GetPropertyIC::tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, void *returnAddr,
GetPropertyIC::tryAttachGenericProxy(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name, void *returnAddr,
bool *emitted)
{
JS_ASSERT(canAttachStub());
@ -1560,7 +1564,7 @@ GetPropertyIC::tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject
*emitted = true;
Label failures;
MacroAssembler masm(cx, ion, script_, pc_);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
Register scratchReg = output().valueReg().scratchReg();
@ -1590,8 +1594,8 @@ GetPropertyIC::tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject
}
bool
GetPropertyIC::tryAttachArgumentsLength(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, bool *emitted)
GetPropertyIC::tryAttachArgumentsLength(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name, bool *emitted)
{
JS_ASSERT(canAttachStub());
JS_ASSERT(!*emitted);
@ -1613,7 +1617,7 @@ GetPropertyIC::tryAttachArgumentsLength(JSContext *cx, IonScript *ion, HandleObj
JS_ASSERT(!idempotent());
Label failures;
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
Register tmpReg;
@ -1660,24 +1664,25 @@ GetPropertyIC::tryAttachArgumentsLength(JSContext *cx, IonScript *ion, HandleObj
}
bool
GetPropertyIC::tryAttachStub(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, void *returnAddr, bool *emitted)
GetPropertyIC::tryAttachStub(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name,
void *returnAddr, bool *emitted)
{
JS_ASSERT(!*emitted);
if (!canAttachStub())
return true;
if (!*emitted && !tryAttachArgumentsLength(cx, ion, obj, name, emitted))
if (!*emitted && !tryAttachArgumentsLength(cx, outerScript, ion, obj, name, emitted))
return false;
if (!*emitted && !tryAttachProxy(cx, ion, obj, name, returnAddr, emitted))
if (!*emitted && !tryAttachProxy(cx, outerScript, ion, obj, name, returnAddr, emitted))
return false;
if (!*emitted && !tryAttachNative(cx, ion, obj, name, returnAddr, emitted))
if (!*emitted && !tryAttachNative(cx, outerScript, ion, obj, name, returnAddr, emitted))
return false;
if (!*emitted && !tryAttachTypedArrayLength(cx, ion, obj, name, emitted))
if (!*emitted && !tryAttachTypedArrayLength(cx, outerScript, ion, obj, name, emitted))
return false;
return true;
@ -1688,8 +1693,8 @@ GetPropertyIC::update(JSContext *cx, size_t cacheIndex,
HandleObject obj, MutableHandleValue vp)
{
void *returnAddr;
RootedScript topScript(cx, GetTopIonJSScript(cx, &returnAddr));
IonScript *ion = topScript->ionScript();
RootedScript outerScript(cx, GetTopIonJSScript(cx, &returnAddr));
IonScript *ion = outerScript->ionScript();
GetPropertyIC &cache = ion->getCache(cacheIndex).toGetProperty();
RootedPropertyName name(cx, cache.name());
@ -1707,7 +1712,7 @@ GetPropertyIC::update(JSContext *cx, size_t cacheIndex,
// limit. Once we can make calls from within generated stubs, a new call
// stub will be generated instead and the previous stubs unlinked.
bool emitted = false;
if (!cache.tryAttachStub(cx, ion, obj, name, returnAddr, &emitted))
if (!cache.tryAttachStub(cx, outerScript, ion, obj, name, returnAddr, &emitted))
return false;
if (cache.idempotent() && !emitted) {
@ -1718,15 +1723,15 @@ GetPropertyIC::update(JSContext *cx, size_t cacheIndex,
// be complicated since (due to GVN) there can be multiple pc's
// associated with a single idempotent cache.
IonSpew(IonSpew_InlineCaches, "Invalidating from idempotent cache %s:%d",
topScript->filename(), topScript->lineno());
outerScript->filename(), outerScript->lineno());
topScript->setInvalidatedIdempotentCache();
outerScript->setInvalidatedIdempotentCache();
// Do not re-invalidate if the lookup already caused invalidation.
if (!topScript->hasIonScript())
if (!outerScript->hasIonScript())
return true;
return Invalidate(cx, topScript);
return Invalidate(cx, outerScript);
}
RootedId id(cx, NameToId(name));
@ -1814,8 +1819,8 @@ GetPropertyParIC::reset()
}
bool
GetPropertyParIC::attachReadSlot(LockedJSContext &cx, IonScript *ion, JSObject *obj,
JSObject *holder, Shape *shape)
GetPropertyParIC::attachReadSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj,
HandleObject holder, HandleShape shape)
{
// Ready to generate the read slot stub.
DispatchStubPrepender attacher(*this);
@ -1826,7 +1831,7 @@ GetPropertyParIC::attachReadSlot(LockedJSContext &cx, IonScript *ion, JSObject *
}
bool
GetPropertyParIC::attachArrayLength(LockedJSContext &cx, IonScript *ion, JSObject *obj)
GetPropertyParIC::attachArrayLength(LockedJSContext &cx, IonScript *ion, HandleObject obj)
{
MacroAssembler masm(cx, ion);
DispatchStubPrepender attacher(*this);
@ -1837,7 +1842,7 @@ GetPropertyParIC::attachArrayLength(LockedJSContext &cx, IonScript *ion, JSObjec
}
bool
GetPropertyParIC::attachTypedArrayLength(LockedJSContext &cx, IonScript *ion, JSObject *obj)
GetPropertyParIC::attachTypedArrayLength(LockedJSContext &cx, IonScript *ion, HandleObject obj)
{
MacroAssembler masm(cx, ion);
DispatchStubPrepender attacher(*this);
@ -2005,10 +2010,10 @@ GenerateSetSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &att
}
bool
SetPropertyIC::attachSetSlot(JSContext *cx, IonScript *ion, HandleObject obj,
HandleShape shape, bool checkTypeset)
SetPropertyIC::attachSetSlot(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleShape shape, bool checkTypeset)
{
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
GenerateSetSlot(cx, masm, attacher, obj, shape, object(), value(), needsTypeBarrier(),
checkTypeset);
@ -2124,11 +2129,12 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
}
bool
SetPropertyIC::attachGenericProxy(JSContext *cx, IonScript *ion, void *returnAddr)
SetPropertyIC::attachGenericProxy(JSContext *cx, HandleScript outerScript, IonScript *ion,
void *returnAddr)
{
JS_ASSERT(!hasGenericProxyStub());
MacroAssembler masm(cx, ion, script_, pc_);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
Label failures;
@ -2179,13 +2185,13 @@ SetPropertyIC::attachGenericProxy(JSContext *cx, IonScript *ion, void *returnAdd
}
bool
SetPropertyIC::attachDOMProxyShadowed(JSContext *cx, IonScript *ion, HandleObject obj,
void *returnAddr)
SetPropertyIC::attachDOMProxyShadowed(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, void *returnAddr)
{
JS_ASSERT(IsCacheableDOMProxy(obj));
Label failures;
MacroAssembler masm(cx, ion, script_, pc_);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
// Guard on the shape of the object.
@ -2406,13 +2412,13 @@ IsCacheableDOMProxyUnshadowedSetterCall(JSContext *cx, HandleObject obj, HandleP
}
bool
SetPropertyIC::attachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, HandleObject obj,
void *returnAddr)
SetPropertyIC::attachDOMProxyUnshadowed(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, void *returnAddr)
{
JS_ASSERT(IsCacheableDOMProxy(obj));
Label failures;
MacroAssembler masm(cx, ion, script_, pc_);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
// Guard on the shape of the object.
@ -2461,13 +2467,13 @@ SetPropertyIC::attachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, HandleObj
}
bool
SetPropertyIC::attachCallSetter(JSContext *cx, IonScript *ion,
SetPropertyIC::attachCallSetter(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleObject holder, HandleShape shape,
void *returnAddr)
{
JS_ASSERT(obj->isNative());
MacroAssembler masm(cx, ion, script_, pc_);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
Label failure;
@ -2574,12 +2580,12 @@ GenerateAddSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &att
}
bool
SetPropertyIC::attachAddSlot(JSContext *cx, IonScript *ion, JSObject *obj, HandleShape oldShape,
bool checkTypeset)
SetPropertyIC::attachAddSlot(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleShape oldShape, bool checkTypeset)
{
JS_ASSERT_IF(!needsTypeBarrier(), !checkTypeset);
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
GenerateAddSlot(cx, masm, attacher, obj, oldShape, object(), value(), checkTypeset);
return linkAndAttachStub(cx, masm, attacher, ion, "adding");
@ -2770,21 +2776,21 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
if (shadows == ShadowCheckFailed)
return false;
if (shadows == Shadows) {
if (!cache.attachDOMProxyShadowed(cx, ion, obj, returnAddr))
if (!cache.attachDOMProxyShadowed(cx, script, ion, obj, returnAddr))
return false;
addedSetterStub = true;
} else {
JS_ASSERT(shadows == DoesntShadow || shadows == DoesntShadowUnique);
if (shadows == DoesntShadowUnique)
cache.reset();
if (!cache.attachDOMProxyUnshadowed(cx, ion, obj, returnAddr))
if (!cache.attachDOMProxyUnshadowed(cx, script, ion, obj, returnAddr))
return false;
addedSetterStub = true;
}
}
if (!addedSetterStub && !cache.hasGenericProxyStub()) {
if (!cache.attachGenericProxy(cx, ion, returnAddr))
if (!cache.attachGenericProxy(cx, script, ion, returnAddr))
return false;
addedSetterStub = true;
}
@ -2803,13 +2809,13 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
&holder, &shape, &checkTypeset);
if (!addedSetterStub && canCache == CanAttachSetSlot) {
if (!cache.attachSetSlot(cx, ion, obj, shape, checkTypeset))
if (!cache.attachSetSlot(cx, script, ion, obj, shape, checkTypeset))
return false;
addedSetterStub = true;
}
if (!addedSetterStub && canCache == CanAttachCallSetter) {
if (!cache.attachCallSetter(cx, ion, obj, holder, shape, returnAddr))
if (!cache.attachCallSetter(cx, script, ion, obj, holder, shape, returnAddr))
return false;
addedSetterStub = true;
}
@ -2828,7 +2834,7 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
IsPropertyAddInlineable(obj, id, cache.value(), oldSlots, oldShape, cache.needsTypeBarrier(),
&checkTypeset))
{
if (!cache.attachAddSlot(cx, ion, obj, oldShape, checkTypeset))
if (!cache.attachAddSlot(cx, script, ion, obj, oldShape, checkTypeset))
return false;
}
@ -2921,8 +2927,8 @@ SetPropertyParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject ob
}
bool
SetPropertyParIC::attachSetSlot(LockedJSContext &cx, IonScript *ion, JSObject *obj, Shape *shape,
bool checkTypeset)
SetPropertyParIC::attachSetSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj,
HandleShape shape, bool checkTypeset)
{
MacroAssembler masm(cx, ion);
DispatchStubPrepender attacher(*this);
@ -2932,8 +2938,8 @@ SetPropertyParIC::attachSetSlot(LockedJSContext &cx, IonScript *ion, JSObject *o
}
bool
SetPropertyParIC::attachAddSlot(LockedJSContext &cx, IonScript *ion, JSObject *obj, Shape *oldShape,
bool checkTypeset)
SetPropertyParIC::attachAddSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj,
HandleShape oldShape, bool checkTypeset)
{
JS_ASSERT_IF(!needsTypeBarrier(), !checkTypeset);
@ -2969,8 +2975,8 @@ EqualStringsHelper(JSString *str1, JSString *str2)
}
bool
GetElementIC::attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj,
const Value &idval, HandlePropertyName name,
GetElementIC::attachGetProp(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, const Value &idval, HandlePropertyName name,
void *returnAddr)
{
JS_ASSERT(index().reg().hasValue());
@ -2995,7 +3001,7 @@ GetElementIC::attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj,
JS_ASSERT(idval.toString()->length() == name->length());
Label failures;
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
// Ensure the index is a string.
ValueOperand val = index().reg().valueReg();
@ -3128,9 +3134,10 @@ GenerateDenseElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher
}
bool
GetElementIC::attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, const Value &idval)
GetElementIC::attachDenseElement(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, const Value &idval)
{
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
if (!GenerateDenseElement(cx, masm, attacher, obj, idval, object(), index(), output()))
return false;
@ -3179,7 +3186,7 @@ GetElementIC::canAttachTypedArrayElement(JSObject *obj, const Value &idval,
static void
GenerateGetTypedArrayElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
TypedArrayObject *tarr, const Value &idval, Register object,
HandleTypedArrayObject tarr, const Value &idval, Register object,
ConstantOrRegister index, TypedOrValueRegister output,
bool allowDoubleResult)
{
@ -3282,10 +3289,10 @@ GenerateGetTypedArrayElement(JSContext *cx, MacroAssembler &masm, IonCache::Stub
}
bool
GetElementIC::attachTypedArrayElement(JSContext *cx, IonScript *ion, TypedArrayObject *tarr,
const Value &idval)
GetElementIC::attachTypedArrayElement(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleTypedArrayObject tarr, const Value &idval)
{
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
GenerateGetTypedArrayElement(cx, masm, attacher, tarr, idval, object(), index(), output(),
allowDoubleResult());
@ -3293,12 +3300,13 @@ GetElementIC::attachTypedArrayElement(JSContext *cx, IonScript *ion, TypedArrayO
}
bool
GetElementIC::attachArgumentsElement(JSContext *cx, IonScript *ion, JSObject *obj)
GetElementIC::attachArgumentsElement(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj)
{
JS_ASSERT(obj->is<ArgumentsObject>());
Label failures;
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
Register tmpReg = output().scratchReg().gpr();
@ -3406,7 +3414,8 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
HandleValue idval, MutableHandleValue res)
{
void *returnAddr;
IonScript *ion = GetTopIonJSScript(cx, &returnAddr)->ionScript();
RootedScript outerScript(cx, GetTopIonJSScript(cx, &returnAddr));
IonScript *ion = outerScript->ionScript();
GetElementIC &cache = ion->getCache(cacheIndex).toGetElement();
RootedScript script(cx);
jsbytecode *pc;
@ -3438,24 +3447,24 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
cache.index().reg().type() == MIRType_Int32) &&
(cache.output().hasValue() || !cache.output().typedReg().isFloat()))
{
if (!cache.attachArgumentsElement(cx, ion, obj))
if (!cache.attachArgumentsElement(cx, outerScript, ion, obj))
return false;
attachedStub = true;
}
if (!attachedStub && cache.monitoredResult() && canAttachGetProp(obj, idval, id)) {
RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName());
if (!cache.attachGetProp(cx, ion, obj, idval, name, returnAddr))
if (!cache.attachGetProp(cx, outerScript, ion, obj, idval, name, returnAddr))
return false;
attachedStub = true;
}
if (!attachedStub && !cache.hasDenseStub() && canAttachDenseElement(obj, idval)) {
if (!cache.attachDenseElement(cx, ion, obj, idval))
if (!cache.attachDenseElement(cx, outerScript, ion, obj, idval))
return false;
attachedStub = true;
}
if (!attachedStub && canAttachTypedArrayElement(obj, idval, cache.output())) {
Rooted<TypedArrayObject*> tarr(cx, &obj->as<TypedArrayObject>());
if (!cache.attachTypedArrayElement(cx, ion, tarr, idval))
if (!cache.attachTypedArrayElement(cx, outerScript, ion, tarr, idval))
return false;
attachedStub = true;
}
@ -3677,9 +3686,10 @@ GenerateSetDenseElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttac
}
bool
SetElementIC::attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, const Value &idval)
SetElementIC::attachDenseElement(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, const Value &idval)
{
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
if (!GenerateSetDenseElement(cx, masm, attacher, obj, idval,
guardHoles(), object(), index(),
@ -3698,7 +3708,7 @@ SetElementIC::attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, c
static bool
GenerateSetTypedArrayElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
TypedArrayObject *tarr, Register object,
HandleTypedArrayObject tarr, Register object,
ValueOperand indexVal, ConstantOrRegister value,
Register tempUnbox, Register temp, FloatRegister tempFloat)
{
@ -3780,9 +3790,10 @@ GenerateSetTypedArrayElement(JSContext *cx, MacroAssembler &masm, IonCache::Stub
}
bool
SetElementIC::attachTypedArrayElement(JSContext *cx, IonScript *ion, TypedArrayObject *tarr)
SetElementIC::attachTypedArrayElement(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleTypedArrayObject tarr)
{
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
if (!GenerateSetTypedArrayElement(cx, masm, attacher, tarr,
object(), index(), value(),
@ -3798,19 +3809,20 @@ bool
SetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
HandleValue idval, HandleValue value)
{
IonScript *ion = GetTopIonJSScript(cx)->ionScript();
RootedScript outerScript(cx, GetTopIonJSScript(cx));
IonScript *ion = outerScript->ionScript();
SetElementIC &cache = ion->getCache(cacheIndex).toSetElement();
bool attachedStub = false;
if (cache.canAttachStub()) {
if (!cache.hasDenseStub() && IsDenseElementSetInlineable(obj, idval)) {
if (!cache.attachDenseElement(cx, ion, obj, idval))
if (!cache.attachDenseElement(cx, outerScript, ion, obj, idval))
return false;
attachedStub = true;
}
if (!attachedStub && IsTypedArrayElementSetInlineable(obj, idval, value)) {
TypedArrayObject *tarr = &obj->as<TypedArrayObject>();
if (!cache.attachTypedArrayElement(cx, ion, tarr))
RootedTypedArrayObject tarr(cx, &obj->as<TypedArrayObject>());
if (!cache.attachTypedArrayElement(cx, outerScript, ion, tarr))
return false;
}
}
@ -3828,7 +3840,7 @@ SetElementIC::reset()
}
bool
SetElementParIC::attachDenseElement(LockedJSContext &cx, IonScript *ion, JSObject *obj,
SetElementParIC::attachDenseElement(LockedJSContext &cx, IonScript *ion, HandleObject obj,
const Value &idval)
{
MacroAssembler masm(cx, ion);
@ -3850,7 +3862,7 @@ SetElementParIC::attachDenseElement(LockedJSContext &cx, IonScript *ion, JSObjec
bool
SetElementParIC::attachTypedArrayElement(LockedJSContext &cx, IonScript *ion,
TypedArrayObject *tarr)
HandleTypedArrayObject tarr)
{
MacroAssembler masm(cx, ion);
DispatchStubPrepender attacher(*this);
@ -3892,7 +3904,7 @@ SetElementParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj
attachedStub = true;
}
if (!attachedStub && IsTypedArrayElementSetInlineable(obj, idval, value)) {
TypedArrayObject *tarr = &obj->as<TypedArrayObject>();
RootedTypedArrayObject tarr(cx, &obj->as<TypedArrayObject>());
if (!cache.attachTypedArrayElement(ncx, ion, tarr))
return cx->setPendingAbortFatal(ParallelBailoutFailedIC);
}
@ -3903,9 +3915,9 @@ SetElementParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj
}
bool
GetElementParIC::attachReadSlot(LockedJSContext &cx, IonScript *ion, JSObject *obj,
const Value &idval, PropertyName *name, JSObject *holder,
Shape *shape)
GetElementParIC::attachReadSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj,
const Value &idval, HandlePropertyName name, HandleObject holder,
HandleShape shape)
{
MacroAssembler masm(cx, ion);
DispatchStubPrepender attacher(*this);
@ -3922,7 +3934,7 @@ GetElementParIC::attachReadSlot(LockedJSContext &cx, IonScript *ion, JSObject *o
}
bool
GetElementParIC::attachDenseElement(LockedJSContext &cx, IonScript *ion, JSObject *obj,
GetElementParIC::attachDenseElement(LockedJSContext &cx, IonScript *ion, HandleObject obj,
const Value &idval)
{
MacroAssembler masm(cx, ion);
@ -3935,7 +3947,7 @@ GetElementParIC::attachDenseElement(LockedJSContext &cx, IonScript *ion, JSObjec
bool
GetElementParIC::attachTypedArrayElement(LockedJSContext &cx, IonScript *ion,
TypedArrayObject *tarr, const Value &idval)
HandleTypedArrayObject tarr, const Value &idval)
{
MacroAssembler masm(cx, ion);
DispatchStubPrepender attacher(*this);
@ -4004,7 +4016,8 @@ GetElementParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj
if (!attachedStub &&
GetElementIC::canAttachTypedArrayElement(obj, idval, cache.output()))
{
if (!cache.attachTypedArrayElement(ncx, ion, &obj->as<TypedArrayObject>(), idval))
RootedTypedArrayObject tarr(cx, &obj->as<TypedArrayObject>());
if (!cache.attachTypedArrayElement(ncx, ion, tarr, idval))
return cx->setPendingAbortFatal(ParallelBailoutFailedIC);
attachedStub = true;
}
@ -4015,11 +4028,12 @@ GetElementParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj
}
bool
BindNameIC::attachGlobal(JSContext *cx, IonScript *ion, JSObject *scopeChain)
BindNameIC::attachGlobal(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject scopeChain)
{
JS_ASSERT(scopeChain->is<GlobalObject>());
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
// Guard on the scope chain.
@ -4090,11 +4104,12 @@ GenerateScopeChainGuards(MacroAssembler &masm, JSObject *scopeChain, JSObject *h
}
bool
BindNameIC::attachNonGlobal(JSContext *cx, IonScript *ion, JSObject *scopeChain, JSObject *holder)
BindNameIC::attachNonGlobal(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject scopeChain, HandleObject holder)
{
JS_ASSERT(IsCacheableNonGlobalScope(scopeChain));
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
// Guard on the shape of the scope chain.
@ -4153,7 +4168,8 @@ BindNameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain)
{
AutoFlushCache afc ("BindNameCache", cx->runtime()->jitRuntime());
IonScript *ion = GetTopIonJSScript(cx)->ionScript();
RootedScript outerScript(cx, GetTopIonJSScript(cx));
IonScript *ion = outerScript->ionScript();
BindNameIC &cache = ion->getCache(cacheIndex).toBindName();
HandlePropertyName name = cache.name();
@ -4169,10 +4185,10 @@ BindNameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain)
// GetPropertyCache.
if (cache.canAttachStub()) {
if (scopeChain->is<GlobalObject>()) {
if (!cache.attachGlobal(cx, ion, scopeChain))
if (!cache.attachGlobal(cx, outerScript, ion, scopeChain))
return nullptr;
} else if (IsCacheableScopeChain(scopeChain, holder)) {
if (!cache.attachNonGlobal(cx, ion, scopeChain, holder))
if (!cache.attachNonGlobal(cx, outerScript, ion, scopeChain, holder))
return nullptr;
} else {
IonSpew(IonSpew_InlineCaches, "BINDNAME uncacheable scope chain");
@ -4183,11 +4199,11 @@ BindNameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain)
}
bool
NameIC::attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain,
HandleObject holderBase, HandleObject holder,
HandleShape shape)
NameIC::attachReadSlot(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject scopeChain, HandleObject holderBase,
HandleObject holder, HandleShape shape)
{
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
Label failures;
RepatchStubAppender attacher(*this);
@ -4247,10 +4263,11 @@ IsCacheableNameReadSlot(JSContext *cx, HandleObject scopeChain, HandleObject obj
}
bool
NameIC::attachCallGetter(JSContext *cx, IonScript *ion, JSObject *obj, JSObject *holder,
HandleShape shape, void *returnAddr)
NameIC::attachCallGetter(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleObject holder, HandleShape shape,
void *returnAddr)
{
MacroAssembler masm(cx, ion, script_, pc_);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
if (!GenerateCallGetter(cx, ion, masm, attacher, obj, name(), holder, shape, liveRegs_,
@ -4283,7 +4300,8 @@ NameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain,
AutoFlushCache afc ("GetNameCache", cx->runtime()->jitRuntime());
void *returnAddr;
IonScript *ion = GetTopIonJSScript(cx, &returnAddr)->ionScript();
RootedScript outerScript(cx, GetTopIonJSScript(cx, &returnAddr));
IonScript *ion = outerScript->ionScript();
NameIC &cache = ion->getCache(cacheIndex).toName();
RootedPropertyName name(cx, cache.name());
@ -4300,10 +4318,10 @@ NameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain,
if (cache.canAttachStub()) {
if (IsCacheableNameReadSlot(cx, scopeChain, obj, holder, shape, pc, cache.outputReg())) {
if (!cache.attachReadSlot(cx, ion, scopeChain, obj, holder, shape))
if (!cache.attachReadSlot(cx, outerScript, ion, scopeChain, obj, holder, shape))
return false;
} else if (IsCacheableNameCallGetter(scopeChain, obj, holder, shape)) {
if (!cache.attachCallGetter(cx, ion, obj, holder, shape, returnAddr))
if (!cache.attachCallGetter(cx, outerScript, ion, obj, holder, shape, returnAddr))
return false;
}
}
@ -4323,10 +4341,10 @@ NameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain,
}
bool
CallsiteCloneIC::attach(JSContext *cx, IonScript *ion, HandleFunction original,
HandleFunction clone)
CallsiteCloneIC::attach(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleFunction original, HandleFunction clone)
{
MacroAssembler masm(cx, ion);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
// Guard against object identity on the original.
@ -4351,7 +4369,8 @@ CallsiteCloneIC::update(JSContext *cx, size_t cacheIndex, HandleObject callee)
if (!fun->hasScript() || !fun->nonLazyScript()->shouldCloneAtCallsite())
return fun;
IonScript *ion = GetTopIonJSScript(cx)->ionScript();
RootedScript outerScript(cx, GetTopIonJSScript(cx));
IonScript *ion = outerScript->ionScript();
CallsiteCloneIC &cache = ion->getCache(cacheIndex).toCallsiteClone();
RootedFunction clone(cx, CloneFunctionAtCallsite(cx, fun, cache.callScript(), cache.callPc()));
@ -4359,7 +4378,7 @@ CallsiteCloneIC::update(JSContext *cx, size_t cacheIndex, HandleObject callee)
return nullptr;
if (cache.canAttachStub()) {
if (!cache.attach(cx, ion, fun, clone))
if (!cache.attach(cx, outerScript, ion, fun, clone))
return nullptr;
}

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

@ -20,6 +20,8 @@ namespace js {
class LockedJSContext;
class TypedArrayObject;
typedef Handle<TypedArrayObject *> HandleTypedArrayObject;
namespace jit {
#define IONCACHE_KIND_LIST(_) \
@ -168,6 +170,10 @@ class IonCache
JSScript *script_;
jsbytecode *pc_;
// Location to use when updating profiler pseudostack when leaving this
// IC code to enter a callee.
jsbytecode *profilerLeavePc_;
private:
static const size_t MAX_STUBS;
void incrementStubCount() {
@ -185,7 +191,8 @@ class IonCache
stubCount_(0),
fallbackLabel_(),
script_(nullptr),
pc_(nullptr)
pc_(nullptr),
profilerLeavePc_(nullptr)
{
}
@ -201,6 +208,11 @@ class IonCache
fallbackLabel_ = fallbackLabel;
}
void setProfilerLeavePC(jsbytecode *pc) {
JS_ASSERT(pc != nullptr);
profilerLeavePc_ = pc;
}
virtual void emitInitialJump(MacroAssembler &masm, AddCacheState &addState) = 0;
virtual void bindInitialJump(MacroAssembler &masm, AddCacheState &addState) = 0;
virtual void updateBaseAddress(JitCode *code, MacroAssembler &masm);
@ -614,24 +626,34 @@ class GetPropertyIC : public RepatchIonCache
}
// Attach the proper stub, if possible
bool tryAttachStub(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, void *returnAddr, bool *emitted);
bool tryAttachProxy(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, void *returnAddr, bool *emitted);
bool tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, void *returnAddr, bool *emitted);
bool tryAttachDOMProxyShadowed(JSContext *cx, IonScript *ion, HandleObject obj,
void *returnAddr, bool *emitted);
bool tryAttachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, bool resetNeeded,
void *returnAddr, bool *emitted);
bool tryAttachNative(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, void *returnAddr, bool *emitted);
bool tryAttachTypedArrayLength(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, bool *emitted);
bool tryAttachStub(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name,
void *returnAddr, bool *emitted);
bool tryAttachArgumentsLength(JSContext *cx, IonScript *ion, HandleObject obj,
HandlePropertyName name, bool *emitted);
bool tryAttachProxy(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name,
void *returnAddr, bool *emitted);
bool tryAttachGenericProxy(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name,
void *returnAddr, bool *emitted);
bool tryAttachDOMProxyShadowed(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, void *returnAddr, bool *emitted);
bool tryAttachDOMProxyUnshadowed(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name, bool resetNeeded,
void *returnAddr, bool *emitted);
bool tryAttachNative(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name,
void *returnAddr, bool *emitted);
bool tryAttachTypedArrayLength(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name, bool *emitted);
bool tryAttachArgumentsLength(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandlePropertyName name, bool *emitted);
static bool update(JSContext *cx, size_t cacheIndex, HandleObject obj, MutableHandleValue vp);
};
@ -694,20 +716,26 @@ class SetPropertyIC : public RepatchIonCache
CanAttachCallSetter
};
bool attachSetSlot(JSContext *cx, IonScript *ion, HandleObject obj, HandleShape shape,
bool checkTypeset);
bool attachCallSetter(JSContext *cx, IonScript *ion, HandleObject obj,
HandleObject holder, HandleShape shape, void *returnAddr);
bool attachAddSlot(JSContext *cx, IonScript *ion, JSObject *obj, HandleShape oldShape,
bool checkTypeset);
bool attachGenericProxy(JSContext *cx, IonScript *ion, void *returnAddr);
bool attachDOMProxyShadowed(JSContext *cx, IonScript *ion, HandleObject obj,
void *returnAddr);
bool attachDOMProxyUnshadowed(JSContext *cx, IonScript *ion, HandleObject obj,
void *returnAddr);
bool attachSetSlot(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleShape shape, bool checkTypeset);
static bool
update(JSContext *cx, size_t cacheIndex, HandleObject obj, HandleValue value);
bool attachCallSetter(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleObject holder, HandleShape shape,
void *returnAddr);
bool attachAddSlot(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleShape oldShape, bool checkTypeset);
bool attachGenericProxy(JSContext *cx, HandleScript outerScript, IonScript *ion,
void *returnAddr);
bool attachDOMProxyShadowed(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, void *returnAddr);
bool attachDOMProxyUnshadowed(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, void *returnAddr);
static bool update(JSContext *cx, size_t cacheIndex, HandleObject obj, HandleValue value);
};
class GetElementIC : public RepatchIonCache
@ -788,12 +816,18 @@ class GetElementIC : public RepatchIonCache
static bool canAttachTypedArrayElement(JSObject *obj, const Value &idval,
TypedOrValueRegister output);
bool attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj, const Value &idval,
HandlePropertyName name, void *returnAddr);
bool attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, const Value &idval);
bool attachTypedArrayElement(JSContext *cx, IonScript *ion, TypedArrayObject *tarr,
const Value &idval);
bool attachArgumentsElement(JSContext *cx, IonScript *ion, JSObject *obj);
bool attachGetProp(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, const Value &idval, HandlePropertyName name,
void *returnAddr);
bool attachDenseElement(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, const Value &idval);
bool attachTypedArrayElement(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleTypedArrayObject tarr, const Value &idval);
bool attachArgumentsElement(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj);
static bool
update(JSContext *cx, size_t cacheIndex, HandleObject obj, HandleValue idval,
@ -878,8 +912,11 @@ class SetElementIC : public RepatchIonCache
hasDenseStub_ = true;
}
bool attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, const Value &idval);
bool attachTypedArrayElement(JSContext *cx, IonScript *ion, TypedArrayObject *tarr);
bool attachDenseElement(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, const Value &idval);
bool attachTypedArrayElement(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleTypedArrayObject tarr);
static bool
update(JSContext *cx, size_t cacheIndex, HandleObject obj, HandleValue idval,
@ -913,8 +950,11 @@ class BindNameIC : public RepatchIonCache
return output_;
}
bool attachGlobal(JSContext *cx, IonScript *ion, JSObject *scopeChain);
bool attachNonGlobal(JSContext *cx, IonScript *ion, JSObject *scopeChain, JSObject *holder);
bool attachGlobal(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject scopeChain);
bool attachNonGlobal(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject scopeChain, HandleObject holder);
static JSObject *
update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain);
@ -959,10 +999,13 @@ class NameIC : public RepatchIonCache
return typeOf_;
}
bool attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain,
HandleObject holderBase, HandleObject holder, HandleShape shape);
bool attachCallGetter(JSContext *cx, IonScript *ion, JSObject *obj, JSObject *holder,
HandleShape shape, void *returnAddr);
bool attachReadSlot(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject scopeChain, HandleObject holderBase,
HandleObject holder, HandleShape shape);
bool attachCallGetter(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleObject holder, HandleShape shape,
void *returnAddr);
static bool
update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain, MutableHandleValue vp);
@ -1000,7 +1043,8 @@ class CallsiteCloneIC : public RepatchIonCache
return output_;
}
bool attach(JSContext *cx, IonScript *ion, HandleFunction original, HandleFunction clone);
bool attach(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleFunction original, HandleFunction clone);
static JSObject *update(JSContext *cx, size_t cacheIndex, HandleObject callee);
};
@ -1072,10 +1116,10 @@ class GetPropertyParIC : public ParallelIonCache
bool allowGetters() const { return false; }
bool allowArrayLength(Context, HandleObject) const { return true; }
bool attachReadSlot(LockedJSContext &cx, IonScript *ion, JSObject *obj, JSObject *holder,
Shape *shape);
bool attachArrayLength(LockedJSContext &cx, IonScript *ion, JSObject *obj);
bool attachTypedArrayLength(LockedJSContext &cx, IonScript *ion, JSObject *obj);
bool attachReadSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj, HandleObject holder,
HandleShape shape);
bool attachArrayLength(LockedJSContext &cx, IonScript *ion, HandleObject obj);
bool attachTypedArrayLength(LockedJSContext &cx, IonScript *ion, HandleObject obj);
static bool update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj,
MutableHandleValue vp);
@ -1132,10 +1176,11 @@ class GetElementParIC : public ParallelIonCache
bool allowGetters() const { return false; }
bool allowArrayLength(Context, HandleObject) const { return false; }
bool attachReadSlot(LockedJSContext &cx, IonScript *ion, JSObject *obj, const Value &idval,
PropertyName *name, JSObject *holder, Shape *shape);
bool attachDenseElement(LockedJSContext &cx, IonScript *ion, JSObject *obj, const Value &idval);
bool attachTypedArrayElement(LockedJSContext &cx, IonScript *ion, TypedArrayObject *tarr,
bool attachReadSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj, const Value &idval,
HandlePropertyName name, HandleObject holder, HandleShape shape);
bool attachDenseElement(LockedJSContext &cx, IonScript *ion, HandleObject obj,
const Value &idval);
bool attachTypedArrayElement(LockedJSContext &cx, IonScript *ion, HandleTypedArrayObject tarr,
const Value &idval);
static bool update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj, HandleValue idval,
@ -1187,9 +1232,9 @@ class SetPropertyParIC : public ParallelIonCache
return needsTypeBarrier_;
}
bool attachSetSlot(LockedJSContext &cx, IonScript *ion, JSObject *obj, Shape *shape,
bool attachSetSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj, HandleShape shape,
bool checkTypeset);
bool attachAddSlot(LockedJSContext &cx, IonScript *ion, JSObject *obj, Shape *oldShape,
bool attachAddSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj, HandleShape oldShape,
bool checkTypeset);
static bool update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj,
@ -1256,8 +1301,9 @@ class SetElementParIC : public ParallelIonCache
return guardHoles_;
}
bool attachDenseElement(LockedJSContext &cx, IonScript *ion, JSObject *obj, const Value &idval);
bool attachTypedArrayElement(LockedJSContext &cx, IonScript *ion, TypedArrayObject *tarr);
bool attachDenseElement(LockedJSContext &cx, IonScript *ion, HandleObject obj,
const Value &idval);
bool attachTypedArrayElement(LockedJSContext &cx, IonScript *ion, HandleTypedArrayObject tarr);
static bool update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj,
HandleValue idval, HandleValue value);

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

@ -952,6 +952,10 @@ class LRecoverInfo : public TempObject
bool operator !=(const OperandIter &where) const {
return it_ != where.it_ || op_ != where.op_;
}
#ifdef DEBUG
bool canOptimizeOutIfUnused();
#endif
};
};

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

@ -1621,7 +1621,7 @@ MAdd::fallible() const
{
// the add is fallible if range analysis does not say that it is finite, AND
// either the truncation analysis shows that there are non-truncated uses.
if (truncateKind() >= IndirectTruncate)
if (isTruncated())
return false;
if (range() && range()->hasInt32Bounds())
return false;
@ -1632,7 +1632,7 @@ bool
MSub::fallible() const
{
// see comment in MAdd::fallible()
if (truncateKind() >= IndirectTruncate)
if (isTruncated())
return false;
if (range() && range()->hasInt32Bounds())
return false;

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

@ -378,13 +378,34 @@ class MDefinition : public MNode
const BytecodeSite &trackedSite() const {
return trackedSite_;
}
jsbytecode *trackedPc() {
jsbytecode *trackedPc() const {
return trackedSite_.pc();
}
InlineScriptTree *trackedTree() {
InlineScriptTree *trackedTree() const {
return trackedSite_.tree();
}
JSScript *profilerLeaveScript() const {
return trackedTree()->outermostCaller()->script();
}
jsbytecode *profilerLeavePc() const {
// If this is in a top-level function, use the pc directly.
if (trackedTree()->isOutermostCaller())
return trackedPc();
// Walk up the InlineScriptTree chain to find the top-most callPC
InlineScriptTree *curTree = trackedTree();
InlineScriptTree *callerTree = curTree->caller();
while (!callerTree->isOutermostCaller()) {
curTree = callerTree;
callerTree = curTree->caller();
}
// Return the callPc of the topmost inlined script.
return curTree->callerPc();
}
// Return the range of this value, *before* any bailout checks. Contrast
// this with the type() method, and the Range constructor which takes an
// MDefinition*, which describe the value *after* any bailout checks.
@ -412,44 +433,8 @@ class MDefinition : public MNode
virtual void analyzeEdgeCasesForward();
virtual void analyzeEdgeCasesBackward();
// When a floating-point value is used by nodes which would prefer to
// recieve integer inputs, we may be able to help by computing our result
// into an integer directly.
//
// A value can be truncated in 4 differents ways:
// 1. Ignore Infinities (x / 0 --> 0).
// 2. Ignore overflow (INT_MIN / -1 == (INT_MAX + 1) --> INT_MIN)
// 3. Ignore negative zeros. (-0 --> 0)
// 4. Ignore remainder. (3 / 4 --> 0)
//
// Indirect truncation is used to represent that we are interested in the
// truncated result, but only if it can safely flow into operations which
// are computed modulo 2^32, such as (2) and (3). Infinities are not safe,
// as they would have absorbed other math operations. Remainders are not
// safe, as fractions can be scaled up by multiplication.
//
// Division is a particularly interesting node here because it covers all 4
// cases even when its own operands are integers.
//
// Note that these enum values are ordered from least value-modifying to
// most value-modifying, and code relies on this ordering.
enum TruncateKind {
// No correction.
NoTruncate = 0,
// An integer is desired, but we can't skip bailout checks.
TruncateAfterBailouts = 1,
// The value will be truncated after some arithmetic (see above).
IndirectTruncate = 2,
// Direct and infallible truncation to int32.
Truncate = 3
};
// Apply the given truncate to this node itself.
virtual bool truncate(TruncateKind kind);
// Determine what kind of truncate this node prefers for the operand at the
// given index.
virtual TruncateKind operandTruncateKind(size_t index) const;
virtual bool truncate();
virtual bool isOperandTruncated(size_t index) const;
// Compute an absolute or symbolic range for the value of this node.
virtual void computeRange(TempAllocator &alloc) {
@ -1013,7 +998,7 @@ class MConstant : public MNullaryInstruction
}
void computeRange(TempAllocator &alloc);
bool truncate(TruncateKind kind);
bool truncate();
bool canProduceFloat32() const;
};
@ -2411,8 +2396,8 @@ class MCompare
void trySpecializeFloat32(TempAllocator &alloc);
bool isFloat32Commutative() const { return true; }
bool truncate(TruncateKind kind);
TruncateKind operandTruncateKind(size_t index) const;
bool truncate();
bool isOperandTruncated(size_t index) const;
# ifdef DEBUG
bool isConsistentFloat32Use(MUse *use) const {
@ -2941,10 +2926,8 @@ class MToDouble
private:
ConversionKind conversion_;
TruncateKind implicitTruncate_;
MToDouble(MDefinition *def, ConversionKind conversion = NonStringPrimitives)
: MUnaryInstruction(def), conversion_(conversion), implicitTruncate_(NoTruncate)
: MUnaryInstruction(def), conversion_(conversion)
{
setResultType(MIRType_Double);
setMovable();
@ -2984,19 +2967,12 @@ class MToDouble
}
void computeRange(TempAllocator &alloc);
bool truncate(TruncateKind kind);
TruncateKind operandTruncateKind(size_t index) const;
bool truncate();
bool isOperandTruncated(size_t index) const;
#ifdef DEBUG
bool isConsistentFloat32Use(MUse *use) const { return true; }
#endif
TruncateKind truncateKind() const {
return implicitTruncate_;
}
void setTruncateKind(TruncateKind kind) {
implicitTruncate_ = Max(implicitTruncate_, kind);
}
};
// Converts a primitive (either typed or untyped) to a float32. If the input is
@ -3216,7 +3192,7 @@ class MTruncateToInt32 : public MUnaryInstruction
}
void computeRange(TempAllocator &alloc);
TruncateKind operandTruncateKind(size_t index) const;
bool isOperandTruncated(size_t index) const;
# ifdef DEBUG
bool isConsistentFloat32Use(MUse *use) const {
return true;
@ -3394,7 +3370,7 @@ class MBinaryBitwiseInstruction
return AliasSet::None();
}
TruncateKind operandTruncateKind(size_t index) const;
bool isOperandTruncated(size_t index) const;
};
class MBitAnd : public MBinaryBitwiseInstruction
@ -3569,14 +3545,14 @@ class MBinaryArithInstruction
// This optimization happens when the multiplication cannot be truncated
// even if all uses are truncating its result, such as when the range
// analysis detect a precision loss in the multiplication.
TruncateKind implicitTruncate_;
bool implicitTruncate_;
void inferFallback(BaselineInspector *inspector, jsbytecode *pc);
public:
MBinaryArithInstruction(MDefinition *left, MDefinition *right)
: MBinaryInstruction(left, right),
implicitTruncate_(NoTruncate)
implicitTruncate_(false)
{
setMovable();
}
@ -3611,13 +3587,10 @@ class MBinaryArithInstruction
}
bool isTruncated() const {
return implicitTruncate_ == Truncate;
}
TruncateKind truncateKind() const {
return implicitTruncate_;
}
void setTruncateKind(TruncateKind kind) {
implicitTruncate_ = Max(implicitTruncate_, kind);
void setTruncated(bool truncate) {
implicitTruncate_ = truncate;
}
};
@ -4065,7 +4038,7 @@ class MAdd : public MBinaryArithInstruction
add->specialization_ = type;
add->setResultType(type);
if (type == MIRType_Int32) {
add->setTruncateKind(Truncate);
add->setTruncated(true);
add->setCommutative();
}
return add;
@ -4079,8 +4052,8 @@ class MAdd : public MBinaryArithInstruction
bool fallible() const;
void computeRange(TempAllocator &alloc);
bool truncate(TruncateKind kind);
TruncateKind operandTruncateKind(size_t index) const;
bool truncate();
bool isOperandTruncated(size_t index) const;
bool writeRecoverData(CompactBufferWriter &writer) const;
bool canRecoverOnBailout() const {
@ -4108,7 +4081,7 @@ class MSub : public MBinaryArithInstruction
sub->specialization_ = type;
sub->setResultType(type);
if (type == MIRType_Int32)
sub->setTruncateKind(Truncate);
sub->setTruncated(true);
return sub;
}
@ -4120,8 +4093,8 @@ class MSub : public MBinaryArithInstruction
bool fallible() const;
void computeRange(TempAllocator &alloc);
bool truncate(TruncateKind kind);
TruncateKind operandTruncateKind(size_t index) const;
bool truncate();
bool isOperandTruncated(size_t index) const;
};
class MMul : public MBinaryArithInstruction
@ -4148,7 +4121,7 @@ class MMul : public MBinaryArithInstruction
// This implements the required behavior for Math.imul, which
// can never fail and always truncates its output to int32.
canBeNegativeZero_ = false;
setTruncateKind(Truncate);
setTruncated(true);
setCommutative();
}
JS_ASSERT_IF(mode != Integer, mode == Normal);
@ -4213,8 +4186,8 @@ class MMul : public MBinaryArithInstruction
bool isFloat32Commutative() const { return true; }
void computeRange(TempAllocator &alloc);
bool truncate(TruncateKind kind);
TruncateKind operandTruncateKind(size_t index) const;
bool truncate();
bool isOperandTruncated(size_t index) const;
Mode mode() const { return mode_; }
};
@ -4227,13 +4200,32 @@ class MDiv : public MBinaryArithInstruction
bool canBeNegativeDividend_;
bool unsigned_;
// A Division can be truncated in 4 differents ways:
// 1. Ignore Infinities (x / 0 --> 0).
// 2. Ignore overflow (INT_MIN / -1 == (INT_MAX + 1) --> INT_MIN)
// 3. Ignore negative zeros. (-0 --> 0)
// 4. Ignore remainder. (3 / 4 --> 0)
//
// isTruncatedIndirectly is used to represent that we are interested in the
// truncated result, but only if they it can safely flow in operations which
// are computed modulo 2^32, such as (2) and (3).
//
// A division can return either Infinities (1) or a remainder (4) when both
// operands are integers. Infinities are not safe, as they would have
// absorbed other math operations. Remainders are not safe, as multiple can
// add up to integers. This implies that we need to distinguish between a
// division which is truncated directly (isTruncated) or which flow into
// truncated operations (isTruncatedIndirectly).
bool isTruncatedIndirectly_;
MDiv(MDefinition *left, MDefinition *right, MIRType type)
: MBinaryArithInstruction(left, right),
canBeNegativeZero_(true),
canBeNegativeOverflow_(true),
canBeDivideByZero_(true),
canBeNegativeDividend_(true),
unsigned_(false)
unsigned_(false),
isTruncatedIndirectly_(false)
{
if (type != MIRType_Value)
specialization_ = type;
@ -4254,7 +4246,7 @@ class MDiv : public MBinaryArithInstruction
MDiv *div = new(alloc) MDiv(left, right, type);
div->unsigned_ = unsignd;
if (type == MIRType_Int32)
div->setTruncateKind(Truncate);
div->setTruncated(true);
return div;
}
@ -4290,7 +4282,10 @@ class MDiv : public MBinaryArithInstruction
}
bool isTruncatedIndirectly() const {
return truncateKind() >= IndirectTruncate;
return isTruncatedIndirectly_;
}
void setTruncatedIndirectly(bool truncate) {
isTruncatedIndirectly_ = truncate;
}
bool canTruncateInfinities() const {
@ -4310,7 +4305,7 @@ class MDiv : public MBinaryArithInstruction
void computeRange(TempAllocator &alloc);
bool fallible() const;
bool truncate(TruncateKind kind);
bool truncate();
void collectRangeInfoPreTrunc();
};
@ -4340,7 +4335,7 @@ class MMod : public MBinaryArithInstruction
MMod *mod = new(alloc) MMod(left, right, type);
mod->unsigned_ = unsignd;
if (type == MIRType_Int32)
mod->setTruncateKind(Truncate);
mod->setTruncated(true);
return mod;
}
@ -4364,7 +4359,7 @@ class MMod : public MBinaryArithInstruction
bool fallible() const;
void computeRange(TempAllocator &alloc);
bool truncate(TruncateKind kind);
bool truncate();
void collectRangeInfoPreTrunc();
};
@ -6569,7 +6564,7 @@ class MLoadTypedArrayElementStatic
}
void computeRange(TempAllocator &alloc);
bool truncate(TruncateKind kind);
bool truncate();
bool canProduceFloat32() const { return typedArray_->type() == ScalarTypeDescr::TYPE_FLOAT32; }
};
@ -6634,7 +6629,7 @@ class MStoreTypedArrayElement
void setRacy() {
racy_ = true;
}
TruncateKind operandTruncateKind(size_t index) const;
bool isOperandTruncated(size_t index) const;
bool canConsumeFloat32(MUse *use) const {
return use->index() == 2 && arrayType_ == ScalarTypeDescr::TYPE_FLOAT32;
@ -6702,7 +6697,7 @@ class MStoreTypedArrayElementHole
AliasSet getAliasSet() const {
return AliasSet::Store(AliasSet::TypedArrayElement);
}
TruncateKind operandTruncateKind(size_t index) const;
bool isOperandTruncated(size_t index) const;
bool canConsumeFloat32(MUse *use) const {
return use->index() == 3 && arrayType_ == ScalarTypeDescr::TYPE_FLOAT32;
@ -6749,7 +6744,7 @@ class MStoreTypedArrayElementStatic :
AliasSet getAliasSet() const {
return AliasSet::Store(AliasSet::TypedArrayElement);
}
TruncateKind operandTruncateKind(size_t index) const;
bool isOperandTruncated(size_t index) const;
bool canConsumeFloat32(MUse *use) const {
return use->index() == 1 && typedArray_->type() == ScalarTypeDescr::TYPE_FLOAT32;

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

@ -2136,14 +2136,14 @@ Range::wrapAroundToBoolean()
}
bool
MDefinition::truncate(TruncateKind kind)
MDefinition::truncate()
{
// No procedure defined for truncating this instruction.
return false;
}
bool
MConstant::truncate(TruncateKind kind)
MConstant::truncate()
{
if (!value_.isDouble())
return false;
@ -2158,15 +2158,15 @@ MConstant::truncate(TruncateKind kind)
}
bool
MAdd::truncate(TruncateKind kind)
MAdd::truncate()
{
// Remember analysis, needed for fallible checks.
setTruncateKind(kind);
setTruncated(true);
if (type() == MIRType_Double || type() == MIRType_Int32) {
specialization_ = MIRType_Int32;
setResultType(MIRType_Int32);
if (kind >= IndirectTruncate && range())
if (range())
range()->wrapAroundToInt32();
return true;
}
@ -2175,15 +2175,15 @@ MAdd::truncate(TruncateKind kind)
}
bool
MSub::truncate(TruncateKind kind)
MSub::truncate()
{
// Remember analysis, needed for fallible checks.
setTruncateKind(kind);
setTruncated(true);
if (type() == MIRType_Double || type() == MIRType_Int32) {
specialization_ = MIRType_Int32;
setResultType(MIRType_Int32);
if (kind >= IndirectTruncate && range())
if (range())
range()->wrapAroundToInt32();
return true;
}
@ -2192,19 +2192,17 @@ MSub::truncate(TruncateKind kind)
}
bool
MMul::truncate(TruncateKind kind)
MMul::truncate()
{
// Remember analysis, needed to remove negative zero checks.
setTruncateKind(kind);
setTruncated(true);
if (type() == MIRType_Double || type() == MIRType_Int32) {
specialization_ = MIRType_Int32;
setResultType(MIRType_Int32);
if (kind >= IndirectTruncate) {
setCanBeNegativeZero(false);
if (range())
range()->wrapAroundToInt32();
}
setCanBeNegativeZero(false);
if (range())
range()->wrapAroundToInt32();
return true;
}
@ -2212,19 +2210,36 @@ MMul::truncate(TruncateKind kind)
}
bool
MDiv::truncate(TruncateKind kind)
MDiv::truncate()
{
setTruncateKind(kind);
// Remember analysis, needed to remove negative zero checks.
setTruncatedIndirectly(true);
if (type() == MIRType_Double || type() == MIRType_Int32) {
specialization_ = MIRType_Int32;
setResultType(MIRType_Int32);
// Check if this division only flows in bitwise instructions.
if (!isTruncated()) {
bool allUsesExplictlyTruncate = true;
for (MUseDefIterator use(this); allUsesExplictlyTruncate && use; use++) {
switch (use.def()->op()) {
case MDefinition::Op_BitAnd:
case MDefinition::Op_BitOr:
case MDefinition::Op_BitXor:
case MDefinition::Op_Lsh:
case MDefinition::Op_Rsh:
case MDefinition::Op_Ursh:
break;
default:
allUsesExplictlyTruncate = false;
}
}
// Divisions where the lhs and rhs are unsigned and the result is
// truncated can be lowered more efficiently.
if (tryUseUnsignedOperands())
unsigned_ = true;
if (allUsesExplictlyTruncate)
setTruncated(true);
}
// Divisions where the lhs and rhs are unsigned and the result is
// truncated can be lowered more efficiently.
if (specialization() == MIRType_Int32 && tryUseUnsignedOperands()) {
unsigned_ = true;
return true;
}
@ -2233,19 +2248,14 @@ MDiv::truncate(TruncateKind kind)
}
bool
MMod::truncate(TruncateKind kind)
MMod::truncate()
{
// Remember analysis, needed to remove negative zero checks.
setTruncateKind(kind);
setTruncated(true);
// As for division, handle unsigned modulus with a truncated result.
if (type() == MIRType_Double || type() == MIRType_Int32) {
specialization_ = MIRType_Int32;
setResultType(MIRType_Int32);
if (tryUseUnsignedOperands())
unsigned_ = true;
if (specialization() == MIRType_Int32 && tryUseUnsignedOperands()) {
unsigned_ = true;
return true;
}
@ -2254,103 +2264,90 @@ MMod::truncate(TruncateKind kind)
}
bool
MToDouble::truncate(TruncateKind kind)
MToDouble::truncate()
{
JS_ASSERT(type() == MIRType_Double);
setTruncateKind(kind);
// We use the return type to flag that this MToDouble should be replaced by
// a MTruncateToInt32 when modifying the graph.
setResultType(MIRType_Int32);
if (kind >= IndirectTruncate) {
if (range())
range()->wrapAroundToInt32();
}
if (range())
range()->wrapAroundToInt32();
return true;
}
bool
MLoadTypedArrayElementStatic::truncate(TruncateKind kind)
MLoadTypedArrayElementStatic::truncate()
{
setInfallible();
return false;
}
MDefinition::TruncateKind
MDefinition::operandTruncateKind(size_t index) const
bool
MDefinition::isOperandTruncated(size_t index) const
{
// Generic routine: We don't know anything.
return NoTruncate;
}
MDefinition::TruncateKind
MTruncateToInt32::operandTruncateKind(size_t index) const
{
// This operator is an explicit truncate to int32.
return Truncate;
}
MDefinition::TruncateKind
MBinaryBitwiseInstruction::operandTruncateKind(size_t index) const
{
// The bitwise operators truncate to int32.
return Truncate;
}
MDefinition::TruncateKind
MAdd::operandTruncateKind(size_t index) const
{
// This operator is doing some arithmetic. If its result is truncated,
// it's an indirect truncate for its operands.
return Min(truncateKind(), IndirectTruncate);
}
MDefinition::TruncateKind
MSub::operandTruncateKind(size_t index) const
{
// See the comment in MAdd::operandTruncateKind.
return Min(truncateKind(), IndirectTruncate);
}
MDefinition::TruncateKind
MMul::operandTruncateKind(size_t index) const
{
// See the comment in MAdd::operandTruncateKind.
return Min(truncateKind(), IndirectTruncate);
}
MDefinition::TruncateKind
MToDouble::operandTruncateKind(size_t index) const
{
// MToDouble propagates its truncate kind to its operand.
return truncateKind();
}
MDefinition::TruncateKind
MStoreTypedArrayElement::operandTruncateKind(size_t index) const
{
// An integer store truncates the stored value.
return index == 2 && !isFloatArray() ? Truncate : NoTruncate;
}
MDefinition::TruncateKind
MStoreTypedArrayElementHole::operandTruncateKind(size_t index) const
{
// An integer store truncates the stored value.
return index == 3 && !isFloatArray() ? Truncate : NoTruncate;
}
MDefinition::TruncateKind
MStoreTypedArrayElementStatic::operandTruncateKind(size_t index) const
{
// An integer store truncates the stored value.
return index == 1 && !isFloatArray() ? Truncate : NoTruncate;
return false;
}
bool
MCompare::truncate(TruncateKind kind)
MTruncateToInt32::isOperandTruncated(size_t index) const
{
return true;
}
bool
MBinaryBitwiseInstruction::isOperandTruncated(size_t index) const
{
return true;
}
bool
MAdd::isOperandTruncated(size_t index) const
{
return isTruncated();
}
bool
MSub::isOperandTruncated(size_t index) const
{
return isTruncated();
}
bool
MMul::isOperandTruncated(size_t index) const
{
return isTruncated();
}
bool
MToDouble::isOperandTruncated(size_t index) const
{
// The return type is used to flag that we are replacing this Double by a
// Truncate of its operand if needed.
return type() == MIRType_Int32;
}
bool
MStoreTypedArrayElement::isOperandTruncated(size_t index) const
{
return index == 2 && !isFloatArray();
}
bool
MStoreTypedArrayElementHole::isOperandTruncated(size_t index) const
{
return index == 3 && !isFloatArray();
}
bool
MStoreTypedArrayElementStatic::isOperandTruncated(size_t index) const
{
return index == 1 && !isFloatArray();
}
bool
MCompare::truncate()
{
if (!isDoubleComparison())
return false;
@ -2362,34 +2359,32 @@ MCompare::truncate(TruncateKind kind)
compareType_ = Compare_Int32;
// Truncating the operands won't change their value because we don't force a
// truncation, but it will change their type, which we need because we
// now expect integer inputs.
// Truncating the operands won't change their value, but it will change
// their type, which we need because we now expect integer inputs.
truncateOperands_ = true;
return true;
}
MDefinition::TruncateKind
MCompare::operandTruncateKind(size_t index) const
bool
MCompare::isOperandTruncated(size_t index) const
{
// If we're doing an int32 comparison on operands which were previously
// floating-point, convert them!
JS_ASSERT_IF(truncateOperands_, isInt32Comparison());
return truncateOperands_ ? TruncateAfterBailouts : NoTruncate;
return truncateOperands_;
}
// Examine all the users of |candidate| and determine the most aggressive
// truncate kind that satisfies all of them.
static MDefinition::TruncateKind
ComputeRequestedTruncateKind(MInstruction *candidate)
// Ensure that all observables uses can work with a truncated
// version of the |candidate|'s result.
static bool
AllUsesTruncate(MInstruction *candidate)
{
// If the value naturally produces an int32 value (before bailout checks)
// that needs no conversion, we don't have to worry about resume points
// seeing truncated values.
bool needsConversion = !candidate->range() || !candidate->range()->isInt32();
MDefinition::TruncateKind kind = MDefinition::Truncate;
for (MUseIterator use(candidate->usesBegin()); use != candidate->usesEnd(); use++) {
if (!use->consumer()->isDefinition()) {
// We can only skip testing resume points, if all original uses are
@ -2398,27 +2393,24 @@ ComputeRequestedTruncateKind(MInstruction *candidate)
// value, and any bailout with a truncated value might lead an
// incorrect value.
if (candidate->isUseRemoved() && needsConversion)
kind = Min(kind, MDefinition::TruncateAfterBailouts);
return false;
continue;
}
MDefinition *consumer = use->consumer()->toDefinition();
MDefinition::TruncateKind consumerKind = consumer->operandTruncateKind(use->index());
kind = Min(kind, consumerKind);
if (kind == MDefinition::NoTruncate)
break;
if (!use->consumer()->toDefinition()->isOperandTruncated(use->index()))
return false;
}
return kind;
return true;
}
static MDefinition::TruncateKind
ComputeTruncateKind(MInstruction *candidate)
static bool
CanTruncate(MInstruction *candidate)
{
// Compare operations might coerce its inputs to int32 if the ranges are
// correct. So we do not need to check if all uses are coerced.
if (candidate->isCompare())
return MDefinition::TruncateAfterBailouts;
return true;
// Set truncated flag if range analysis ensure that it has no
// rounding errors and no fractional part. Note that we can't use
@ -2433,10 +2425,10 @@ ComputeTruncateKind(MInstruction *candidate)
canHaveRoundingErrors = false;
if (canHaveRoundingErrors)
return MDefinition::NoTruncate;
return false;
// Ensure all observable uses are truncated.
return ComputeRequestedTruncateKind(candidate);
return AllUsesTruncate(candidate);
}
static void
@ -2463,7 +2455,7 @@ AdjustTruncatedInputs(TempAllocator &alloc, MInstruction *truncated)
{
MBasicBlock *block = truncated->block();
for (size_t i = 0, e = truncated->numOperands(); i < e; i++) {
if (truncated->operandTruncateKind(i) == MDefinition::NoTruncate)
if (!truncated->isOperandTruncated(i))
continue;
MDefinition *input = truncated->getOperand(i);
@ -2523,12 +2515,11 @@ RangeAnalysis::truncate()
default:;
}
MDefinition::TruncateKind kind = ComputeTruncateKind(*iter);
if (kind == MDefinition::NoTruncate)
if (!CanTruncate(*iter))
continue;
// Truncate this instruction if possible.
if (!iter->truncate(kind))
if (!iter->truncate())
continue;
// Delay updates of inputs/outputs to avoid creating node which

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

@ -71,7 +71,7 @@ ICCompare_Double::Compiler::generateStubCode(MacroAssembler &masm)
// ICBinaryArith_Int32
extern "C" {
extern int64_t __aeabi_idivmod(int,int);
extern MOZ_EXPORT int64_t __aeabi_idivmod(int,int);
}
bool

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

@ -619,8 +619,8 @@ CodeGeneratorARM::visitDivI(LDivI *ins)
}
extern "C" {
extern int64_t __aeabi_idivmod(int,int);
extern int64_t __aeabi_uidivmod(int,int);
extern MOZ_EXPORT int64_t __aeabi_idivmod(int,int);
extern MOZ_EXPORT int64_t __aeabi_uidivmod(int,int);
}
bool

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

@ -138,7 +138,7 @@ ToStackIndex(LAllocation *a)
bool
CodeGeneratorShared::encodeAllocation(LSnapshot *snapshot, MDefinition *mir,
uint32_t *allocIndex)
uint32_t *allocIndex)
{
if (mir->isBox())
mir = mir->toBox()->getOperand(0);

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

@ -70,6 +70,25 @@ LIRGeneratorShared::getRecoverInfo(MResumePoint *rp)
return recoverInfo;
}
#ifdef DEBUG
bool
LRecoverInfo::OperandIter::canOptimizeOutIfUnused()
{
MDefinition *ins = **this;
// We check ins->type() in addition to ins->isUnused() because
// EliminateDeadResumePointOperands may replace nodes with the constant
// MagicValue(JS_OPTIMIZED_OUT).
if ((ins->isUnused() || ins->type() == MIRType_MagicOptimizedOut) &&
(*it_)->isResumePoint())
{
return (*it_)->block()->info().canOptimizeOutSlot(op_);
}
return true;
}
#endif
#ifdef JS_NUNBOX32
LSnapshot *
LIRGeneratorShared::buildSnapshot(LInstruction *ins, MResumePoint *rp, BailoutKind kind)
@ -86,7 +105,11 @@ LIRGeneratorShared::buildSnapshot(LInstruction *ins, MResumePoint *rp, BailoutKi
LRecoverInfo::OperandIter it(recoverInfo->begin());
LRecoverInfo::OperandIter end(recoverInfo->end());
for (; it != end; ++it) {
// Check that optimized out operands are in eliminable slots.
MOZ_ASSERT(it.canOptimizeOutIfUnused());
MDefinition *ins = *it;
if (ins->isRecoveredOnBailout())
continue;
@ -98,12 +121,12 @@ LIRGeneratorShared::buildSnapshot(LInstruction *ins, MResumePoint *rp, BailoutKi
ins = ins->toBox()->getOperand(0);
// Guards should never be eliminated.
JS_ASSERT_IF(ins->isUnused(), !ins->isGuard());
MOZ_ASSERT_IF(ins->isUnused(), !ins->isGuard());
// Snapshot operands other than constants should never be
// emitted-at-uses. Try-catch support depends on there being no
// code between an instruction and the LOsiPoint that follows it.
JS_ASSERT_IF(!ins->isConstant(), !ins->isEmittedAtUses());
MOZ_ASSERT_IF(!ins->isConstant(), !ins->isEmittedAtUses());
// The register allocation will fill these fields in with actual
// register/stack assignments. During code generation, we can restore
@ -142,6 +165,9 @@ LIRGeneratorShared::buildSnapshot(LInstruction *ins, MResumePoint *rp, BailoutKi
LRecoverInfo::OperandIter it(recoverInfo->begin());
LRecoverInfo::OperandIter end(recoverInfo->end());
for (; it != end; ++it) {
// Check that optimized out operands are in eliminable slots.
MOZ_ASSERT(it.canOptimizeOutIfUnused());
MDefinition *def = *it;
if (def->isRecoveredOnBailout())
@ -151,12 +177,12 @@ LIRGeneratorShared::buildSnapshot(LInstruction *ins, MResumePoint *rp, BailoutKi
def = def->toBox()->getOperand(0);
// Guards should never be eliminated.
JS_ASSERT_IF(def->isUnused(), !def->isGuard());
MOZ_ASSERT_IF(def->isUnused(), !def->isGuard());
// Snapshot operands other than constants should never be
// emitted-at-uses. Try-catch support depends on there being no
// code between an instruction and the LOsiPoint that follows it.
JS_ASSERT_IF(!def->isConstant(), !def->isEmittedAtUses());
MOZ_ASSERT_IF(!def->isConstant(), !def->isEmittedAtUses());
LAllocation *a = snapshot->getEntry(index++);

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

@ -1384,6 +1384,14 @@ JS_GetArrayPrototype(JSContext *cx, HandleObject forObj)
return GlobalObject::getOrCreateArrayPrototype(cx, global);
}
JS_PUBLIC_API(JSObject *)
JS_GetErrorPrototype(JSContext *cx)
{
CHECK_REQUEST(cx);
Rooted<GlobalObject*> global(cx, cx->global());
return GlobalObject::getOrCreateCustomErrorPrototype(cx, global, JSEXN_ERR);
}
JS_PUBLIC_API(JSObject *)
JS_GetGlobalForObject(JSContext *cx, JSObject *obj)
{

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

@ -1826,6 +1826,13 @@ JS_GetObjectPrototype(JSContext *cx, JS::HandleObject forObj);
extern JS_PUBLIC_API(JSObject *)
JS_GetArrayPrototype(JSContext *cx, JS::HandleObject forObj);
/*
* Returns the original value of |Error.prototype| from the global
* object of the current compartment of cx.
*/
extern JS_PUBLIC_API(JSObject *)
JS_GetErrorPrototype(JSContext *cx);
extern JS_PUBLIC_API(JSObject *)
JS_GetGlobalForObject(JSContext *cx, JSObject *obj);
@ -4906,8 +4913,7 @@ typedef bool
(* OpenAsmJSCacheEntryForReadOp)(HandleObject global, const jschar *begin, const jschar *limit,
size_t *size, const uint8_t **memory, intptr_t *handle);
typedef void
(* CloseAsmJSCacheEntryForReadOp)(HandleObject global, size_t size, const uint8_t *memory,
intptr_t handle);
(* CloseAsmJSCacheEntryForReadOp)(size_t size, const uint8_t *memory, intptr_t handle);
/*
* This callback represents a request by the JS engine to open for writing a
@ -4929,8 +4935,7 @@ typedef bool
const jschar *begin, const jschar *end,
size_t size, uint8_t **memory, intptr_t *handle);
typedef void
(* CloseAsmJSCacheEntryForWriteOp)(HandleObject global, size_t size, uint8_t *memory,
intptr_t handle);
(* CloseAsmJSCacheEntryForWriteOp)(size_t size, uint8_t *memory, intptr_t handle);
typedef js::Vector<char, 0, js::SystemAllocPolicy> BuildIdCharVector;

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

@ -661,6 +661,7 @@ JSCompartment::clearTables()
JS_ASSERT(!gcWeakMapList);
JS_ASSERT(enumerators->next() == enumerators);
types.clearTables();
if (baseShapes.initialized())
baseShapes.clear();
if (initialShapes.initialized())

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

@ -706,8 +706,8 @@ IsDuckTypedErrorObject(JSContext *cx, HandleObject exnObject, const char **filen
const char *filename_str = *filename_strp;
if (!JS_HasProperty(cx, exnObject, filename_str, &found) || !found) {
/* DOMException duck quacks "filename" (all lowercase) */
filename_str = "filename";
/* Now try "fileName", in case this quacks like an Error */
filename_str = js_fileName_str;
if (!JS_HasProperty(cx, exnObject, filename_str, &found) || !found)
return false;
}
@ -778,8 +778,13 @@ js_ReportUncaughtException(JSContext *cx)
// If js_ErrorFromException didn't get us a JSErrorReport, then the object
// was not an ErrorObject, security-wrapped or otherwise. However, it might
// still quack like one. Give duck-typing a chance.
const char *filename_str = js_fileName_str;
// still quack like one. Give duck-typing a chance. We start by looking for
// "filename" (all lowercase), since that's where DOMExceptions store their
// filename. Then we check "fileName", which is where Errors store it. We
// have to do it in that order, because DOMExceptions have Error.prototype
// on their proto chain, and hence also have a "fileName" property, but its
// value is "".
const char *filename_str = "filename";
JSAutoByteString filename;
if (!reportp && exnObject && IsDuckTypedErrorObject(cx, exnObject, &filename_str))
{

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

@ -1192,7 +1192,7 @@ types::FinishCompilation(JSContext *cx, HandleScript script, ExecutionMode execu
return true;
}
MOZ_NEVER_INLINE void
static void
CheckDefinitePropertiesTypeSet(JSContext *cx, TemporaryTypeSet *frozen, StackTypeSet *actual)
{
// The definite properties analysis happens on the main thread, so no new
@ -3621,7 +3621,8 @@ JSScript::makeTypes(JSContext *cx)
unsigned count = TypeScript::NumTypeSets(this);
TypeScript *typeScript = (TypeScript *) cx->calloc_(sizeof(TypeScript) + (sizeof(StackTypeSet) * count));
TypeScript *typeScript = (TypeScript *)
cx->calloc_(TypeScript::SizeIncludingTypeArray(count));
if (!typeScript)
return false;
@ -4169,6 +4170,17 @@ TypeObject::sweep(FreeOp *fop, bool *oom)
}
}
void
TypeCompartment::clearTables()
{
if (allocationSiteTable && allocationSiteTable->initialized())
allocationSiteTable->clear();
if (arrayTypeTable && arrayTypeTable->initialized())
arrayTypeTable->clear();
if (objectTypeTable && objectTypeTable->initialized())
objectTypeTable->clear();
}
void
TypeCompartment::sweep(FreeOp *fop)
{

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

@ -1267,9 +1267,24 @@ class TypeScript
{
friend class ::JSScript;
// Variable-size array
StackTypeSet typeArray_[1];
public:
/* Array of type type sets for variables and JOF_TYPESET ops. */
StackTypeSet *typeArray() const { return (StackTypeSet *) (uintptr_t(this) + sizeof(TypeScript)); }
StackTypeSet *typeArray() const {
// Ensure typeArray_ is the last data member of TypeScript.
JS_STATIC_ASSERT(sizeof(TypeScript) ==
sizeof(typeArray_) + offsetof(TypeScript, typeArray_));
return const_cast<StackTypeSet *>(typeArray_);
}
static inline size_t SizeIncludingTypeArray(size_t arraySize) {
// Ensure typeArray_ is the last data member of TypeScript.
JS_STATIC_ASSERT(sizeof(TypeScript) ==
sizeof(StackTypeSet) + offsetof(TypeScript, typeArray_));
return offsetof(TypeScript, typeArray_) + arraySize * sizeof(StackTypeSet);
}
static inline unsigned NumTypeSets(JSScript *script);
@ -1587,6 +1602,7 @@ struct TypeCompartment
/* Mark any type set containing obj as having a generic object type. */
void markSetsUnknown(JSContext *cx, TypeObject *obj);
void clearTables();
void sweep(FreeOp *fop);
void finalizeObjects();

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

@ -5514,8 +5514,7 @@ ShellOpenAsmJSCacheEntryForRead(HandleObject global, const jschar *begin, const
}
static void
ShellCloseAsmJSCacheEntryForRead(HandleObject global, size_t serializedSize, const uint8_t *memory,
intptr_t handle)
ShellCloseAsmJSCacheEntryForRead(size_t serializedSize, const uint8_t *memory, intptr_t handle)
{
// Undo the cookie adjustment done when opening the file.
memory -= sizeof(uint32_t);
@ -5603,8 +5602,7 @@ ShellOpenAsmJSCacheEntryForWrite(HandleObject global, bool installed,
}
static void
ShellCloseAsmJSCacheEntryForWrite(HandleObject global, size_t serializedSize, uint8_t *memory,
intptr_t handle)
ShellCloseAsmJSCacheEntryForWrite(size_t serializedSize, uint8_t *memory, intptr_t handle)
{
// Undo the cookie adjustment done when opening the file.
memory -= sizeof(uint32_t);

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

@ -100,7 +100,26 @@
*/ \
macro(JSOP_UNDEFINED, 1, js_undefined_str, "", 1, 0, 1, JOF_BYTE) \
macro(JSOP_UNUSED2, 2, "unused2", NULL, 1, 1, 0, JOF_BYTE) \
/*
* Pops the top of stack value, converts it to an object, and adds a
* 'DynamicWithObject' wrapping that object to the scope chain.
*
* There is a matching JSOP_LEAVEWITH instruction later. All name
* lookups between the two that may need to consult the With object
* are deoptimized.
* Category: Statements
* Type: With Statement
* Operands: uint32_t staticWithIndex
* Stack: val =>
*/ \
macro(JSOP_ENTERWITH, 3, "enterwith", NULL, 5, 1, 0, JOF_OBJECT) \
/*
* Pops the scope chain object pushed by JSOP_ENTERWITH.
* Category: Statements
* Type: With Statement
* Operands:
* Stack: =>
*/ \
macro(JSOP_LEAVEWITH, 4, "leavewith", NULL, 1, 0, 0, JOF_BYTE) \
/*
* Pops the top of stack value as 'rval', stops interpretation of current
@ -111,8 +130,35 @@
* Stack: rval =>
*/ \
macro(JSOP_RETURN, 5, "return", NULL, 1, 1, 0, JOF_BYTE) \
/*
* Jumps to a 32-bit offset from the current bytecode.
* Category: Statements
* Type: Jumps
* Operands: int32_t offset
* Stack: =>
*/ \
macro(JSOP_GOTO, 6, "goto", NULL, 5, 0, 0, JOF_JUMP) \
/*
* Pops the top of stack value, converts it into a boolean, if the result is
* 'false', jumps to a 32-bit offset from the current bytecode.
*
* The idea is that a sequence like
* JSOP_ZERO; JSOP_ZERO; JSOP_EQ; JSOP_IFEQ; JSOP_RETURN;
* reads like a nice linear sequence that will execute the return.
* Category: Statements
* Type: Jumps
* Operands: int32_t offset
* Stack: cond =>
*/ \
macro(JSOP_IFEQ, 7, "ifeq", NULL, 5, 1, 0, JOF_JUMP|JOF_DETECTING) \
/*
* Pops the top of stack value, converts it into a boolean, if the result is
* 'true', jumps to a 32-bit offset from the current bytecode.
* Category: Statements
* Type: Jumps
* Operands: int32_t offset
* Stack: cond =>
*/ \
macro(JSOP_IFNE, 8, "ifne", NULL, 5, 1, 0, JOF_JUMP) \
\
/*
@ -491,10 +537,38 @@
*/ \
macro(JSOP_FALSE, 66, js_false_str, js_false_str, 1, 0, 1, JOF_BYTE) \
macro(JSOP_TRUE, 67, js_true_str, js_true_str, 1, 0, 1, JOF_BYTE) \
/*
* Converts the top of stack value into a boolean, if the result is 'true',
* jumps to a 32-bit offset from the current bytecode.
* Category: Statements
* Type: Jumps
* Operands: int32_t offset
* Stack: cond => cond
*/ \
macro(JSOP_OR, 68, "or", NULL, 5, 1, 1, JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC) \
/*
* Converts the top of stack value into a boolean, if the result is 'false',
* jumps to a 32-bit offset from the current bytecode.
* Category: Statements
* Type: Jumps
* Operands: int32_t offset
* Stack: cond => cond
*/ \
macro(JSOP_AND, 69, "and", NULL, 5, 1, 1, JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC) \
\
/* The switch bytecodes have variable length. */ \
/*
* Pops the top of stack value as 'i', if 'low <= i <= high',
* jumps to a 32-bit offset: 'offset[i - low]' from the current bytecode,
* jumps to a 32-bit offset: 'len' from the current bytecode if not.
*
* This opcode has variable length.
* Category: Statements
* Type: Switch Statement
* Operands: int32_t len, int32_t low, int32_t high,
* int32_t offset[0], ..., int32_t offset[high-low]
* Stack: i =>
* len: len
*/ \
macro(JSOP_TABLESWITCH, 70, "tableswitch", NULL, -1, 1, 0, JOF_TABLESWITCH|JOF_DETECTING) \
\
/*
@ -531,20 +605,48 @@
macro(JSOP_SETCALL, 74, "setcall", NULL, 1, 0, 0, JOF_BYTE) \
\
/*
* JSOP_ITER sets up a for-in or for-each-in loop using the JSITER_* flag bits
* in this op's uint8_t immediate operand. It replaces the top of stack value
* with an iterator for that value.
*
* JSOP_MOREITER stores the next iterated value into cx->iterValue and pushes
* true if another value is available, and false otherwise. It is followed
* immediately by JSOP_IFNE.
*
* JSOP_ENDITER cleans up after the loop. It uses the slot above the iterator
* for temporary GC rooting.
* Sets up a for-in or for-each-in loop using the JSITER_* flag bits in
* this op's uint8_t immediate operand. It pops the top of stack value as
* 'val' and pushes 'iter' which is an iterator for 'val'.
* Category: Statements
* Type: For-In Statement
* Operands: uint8_t flags
* Stack: val => iter
*/ \
macro(JSOP_ITER, 75, "iter", NULL, 2, 1, 1, JOF_UINT8) \
/*
* Stores the next iterated value into 'cx->iterValue' and pushes 'true'
* onto the stack if another value is available, and 'false' otherwise.
* It is followed immediately by JSOP_IFNE.
*
* This opcode increments iterator cursor if current iteration has
* JSITER_FOREACH flag.
* Category: Statements
* Type: For-In Statement
* Operands:
* Stack: iter => iter, cond
*/ \
macro(JSOP_MOREITER, 76, "moreiter", NULL, 1, 1, 2, JOF_BYTE) \
/*
* Pushes the value produced by the preceding JSOP_MOREITER operation
* ('cx->iterValue') onto the stack
*
* This opcode increments iterator cursor if current iteration does not have
* JSITER_FOREACH flag.
* Category: Statements
* Type: For-In Statement
* Operands:
* Stack: iter => iter, val
*/ \
macro(JSOP_ITERNEXT, 77, "iternext", "<next>", 1, 0, 1, JOF_BYTE) \
/*
* Exits a for-in loop by popping the iterator object from the stack and
* closing it.
* Category: Statements
* Type: For-In Statement
* Operands:
* Stack: iter =>
*/ \
macro(JSOP_ENDITER, 78, "enditer", NULL, 1, 1, 0, JOF_BYTE) \
\
/*
@ -799,7 +901,16 @@
macro(JSOP_UNUSED104, 104, "unused104", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_UNUSED105, 105, "unused105", NULL, 1, 0, 0, JOF_BYTE) \
\
/* The argument is the offset to the next statement and is used by IonMonkey. */ \
/*
* This opcode precedes every labeled statement. It's a no-op.
*
* 'offset' is the offset to the next instruction after this statement,
* the one 'break LABEL;' would jump to. IonMonkey uses this.
* Category: Statements
* Type: Jumps
* Operands: int32_t offset
* Stack: =>
*/ \
macro(JSOP_LABEL, 106,"label", NULL, 5, 0, 0, JOF_JUMP) \
\
macro(JSOP_UNUSED107, 107,"unused107", NULL, 1, 0, 0, JOF_BYTE) \
@ -822,7 +933,15 @@
*/ \
macro(JSOP_FUNCALL, 108,"funcall", NULL, 3, -1, 1, JOF_UINT16|JOF_INVOKE|JOF_TYPESET) \
\
/* This opcode is the target of the backwards jump for some loop. */ \
/*
* Another no-op.
*
* This opcode is the target of the backwards jump for some loop.
* Category: Statements
* Type: Jumps
* Operands:
* Stack: =>
*/ \
macro(JSOP_LOOPHEAD, 109,"loophead", NULL, 1, 0, 0, JOF_BYTE) \
\
/* ECMA-compliant assignment ops. */ \
@ -847,6 +966,14 @@
macro(JSOP_SETNAME, 111,"setname", NULL, 5, 2, 1, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING) \
\
/* Exception handling ops. */ \
/*
* Pops the top of stack value as 'v', sets pending exception as 'v', then
* raises error.
* Category: Statements
* Type: Exception Handling
* Operands:
* Stack: v =>
*/ \
macro(JSOP_THROW, 112,js_throw_str, NULL, 1, 1, 0, JOF_BYTE) \
\
/*
@ -880,11 +1007,41 @@
*/ \
macro(JSOP_DEBUGGER, 115,"debugger", NULL, 1, 0, 0, JOF_BYTE) \
\
/* gosub/retsub for finally handling */ \
/*
* Pushes 'false' and next bytecode's PC onto the stack, and jumps to
* a 32-bit offset from the current bytecode.
*
* This opcode is used for entering 'finally' block.
* Category: Statements
* Type: Exception Handling
* Operands: int32_t offset
* Stack: => false, (next bytecode's PC)
*/ \
macro(JSOP_GOSUB, 116,"gosub", NULL, 5, 0, 0, JOF_JUMP) \
/*
* Pops the top two values on the stack as 'rval' and 'lval', converts
* 'lval' into a boolean, raises error if the result is 'true',
* jumps to a 32-bit absolute PC: 'rval' if 'false'.
*
* This opcode is used for returning from 'finally' block.
* Category: Statements
* Type: Exception Handling
* Operands:
* Stack: lval, rval =>
*/ \
macro(JSOP_RETSUB, 117,"retsub", NULL, 1, 2, 0, JOF_BYTE) \
\
/* More exception handling ops. */ \
/*
* Pushes the current pending exception onto the stack and clears the
* pending exception. This is only emitted at the beginning of code for a
* catch-block, so it is known that an exception is pending. It is used to
* implement catch-blocks and 'yield*'.
* Category: Statements
* Type: Exception Handling
* Operands:
* Stack: => exception
*/ \
macro(JSOP_EXCEPTION, 118,"exception", NULL, 1, 0, 1, JOF_BYTE) \
\
/*
@ -896,12 +1053,58 @@
macro(JSOP_LINENO, 119,"lineno", NULL, 3, 0, 0, JOF_UINT16) \
\
/*
* ECMA-compliant switch statement ops.
* CONDSWITCH is a decompilable NOP; CASE is ===, POP, jump if true, re-push
* lval if false; and DEFAULT is POP lval and GOTO.
* This no-op appears after the bytecode for EXPR in 'switch (EXPR) {...}'
* if the switch cannot be optimized using JSOP_TABLESWITCH.
* For a non-optimized switch statement like this:
*
* switch (EXPR) {
* case V0:
* C0;
* ...
* default:
* D;
* }
*
* the bytecode looks like this:
*
* (EXPR)
* condswitch
* (V0)
* case ->C0
* ...
* default ->D
* (C0)
* ...
* (D)
*
* Note that code for all case-labels is emitted first, then code for
* the body of each case clause.
* Category: Statements
* Type: Switch Statement
* Operands:
* Stack: =>
*/ \
macro(JSOP_CONDSWITCH,120,"condswitch", NULL, 1, 0, 0, JOF_BYTE) \
/*
* Pops the top two values on the stack as 'rval' and 'lval', compare them
* with '===', if the result is 'true', jumps to a 32-bit offset from the
* current bytecode, re-pushes 'lval' onto the stack if 'false'.
* Category: Statements
* Type: Switch Statement
* Operands: int32_t offset
* Stack: lval, rval => lval(if lval !== rval)
*/ \
macro(JSOP_CASE, 121,"case", NULL, 5, 2, 1, JOF_JUMP) \
/*
* This appears after all cases in a JSOP_CONDSWITCH, whether there is a
* 'default:' label in the switch statement or not. Pop the switch operand
* from the stack and jump to a 32-bit offset from the current bytecode.
* offset from the current bytecode.
* Category: Statements
* Type: Switch Statement
* Operands: int32_t offset
* Stack: lval =>
*/ \
macro(JSOP_DEFAULT, 122,"default", NULL, 5, 1, 0, JOF_JUMP) \
\
/* ECMA-compliant call to eval op. */ \
@ -1000,10 +1203,24 @@
macro(JSOP_PICK, 133, "pick", NULL, 2, 0, 0, JOF_UINT8|JOF_TMPSLOT2) \
\
/*
* Exception handling no-op, for more economical byte-coding than SRC_TRYFIN
* srcnote-annotated JSOP_NOPs and to simply stack balance handling.
* This no-op appears at the top of the bytecode for a 'TryStatement'.
*
* Location information for catch/finally blocks is stored in a
* side table, 'script->trynotes()'.
* Category: Statements
* Type: Exception Handling
* Operands:
* Stack: =>
*/ \
macro(JSOP_TRY, 134,"try", NULL, 1, 0, 0, JOF_BYTE) \
/*
* This opcode has a def count of 2, but these values are already on the
* stack (they're pushed by JSOP_GOSUB).
* Category: Statements
* Type: Exception Handling
* Operands:
* Stack: => false, (next bytecode's PC)
*/ \
macro(JSOP_FINALLY, 135,"finally", NULL, 1, 0, 2, JOF_BYTE) \
\
/*
@ -1080,11 +1297,27 @@
macro(JSOP_UNUSED147, 147,"unused147", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_UNUSED148, 148,"unused148", NULL, 1, 0, 0, JOF_BYTE) \
\
/* Placeholders for a real jump opcode set during backpatch chain fixup. */ \
/*
* Placeholder opcode used during bytecode generation. This never
* appears in a finished script. FIXME: bug 473671.
* Category: Statements
* Type: Jumps
* Operands: int32_t offset
* Stack: =>
*/ \
macro(JSOP_BACKPATCH, 149,"backpatch", NULL, 5, 0, 0, JOF_JUMP) \
macro(JSOP_UNUSED150, 150,"unused150", NULL, 1, 0, 0, JOF_BYTE) \
\
/* Set pending exception from the stack, to trigger rethrow. */ \
/*
* Pops the top of stack value as 'v', sets pending exception as 'v',
* to trigger rethrow.
*
* This opcode is used in conditional catch clauses.
* Category: Statements
* Type: Exception Handling
* Operands:
* Stack: v =>
*/ \
macro(JSOP_THROWING, 151,"throwing", NULL, 1, 1, 0, JOF_BYTE) \
\
/*
@ -1411,6 +1644,10 @@
* loops all have the same value. The upper bit is set if Ion should be
* able to OSR at this point, which is true unless there is non-loop state
* on the stack.
* Category: Statements
* Type: Jumps
* Operands: uint8_t BITFIELD
* Stack: =>
*/ \
macro(JSOP_LOOPENTRY, 227, "loopentry", NULL, 2, 0, 0, JOF_UINT8)

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

@ -274,7 +274,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
%}
[noscript, uuid(3d5a6320-8764-11e3-baa7-0800200c9a66)]
[noscript, uuid(47fbe8ff-0507-4647-9ea7-e0e1fc76c995)]
interface nsIXPConnect : nsISupports
{
%{ C++
@ -422,12 +422,6 @@ interface nsIXPConnect : nsISupports
getNativeOfWrapper(in JSContextPtr aJSContext,
in JSObjectPtr aJSObj);
/**
* The security manager to use when the current JSContext has no security
* manager.
*/
void setDefaultSecurityManager(in nsIXPCSecurityManager aManager);
nsIStackFrame
createStackFrameLocation(in uint32_t aLanguage,
in string aFilename,
@ -437,7 +431,6 @@ interface nsIXPConnect : nsISupports
[noscript,notxpcom,nostdcall] JSContextPtr getCurrentJSContext();
[noscript,notxpcom,nostdcall] JSContextPtr initSafeJSContext();
[noscript,notxpcom,nostdcall] JSContextPtr getSafeJSContext();
readonly attribute nsIStackFrame CurrentJSStack;

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

@ -121,7 +121,7 @@ interface ScheduledGCCallback : nsISupports
/**
* interface of Components.utils
*/
[scriptable, uuid(45b80e00-fb0d-439e-b7bf-54f24af0c4a6)]
[scriptable, uuid(c9b6f5a0-cfe8-11e3-9c1a-0800200c9a66)]
interface nsIXPCComponents_Utils : nsISupports
{
@ -260,6 +260,22 @@ interface nsIXPCComponents_Utils : nsISupports
*/
void forceCC();
/*
* To be called from JS only.
*
* If any incremental CC is in progress, finish it. For testing.
*/
void finishCC();
/*
* To be called from JS only.
*
* Do some cycle collector work, with the given work budget.
* The cost of calling Traverse() on a single object is set as 1.
* For testing.
*/
void ccSlice(in long long budget);
/*
* To be called from JS only.
*

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

@ -534,26 +534,7 @@ mozJSComponentLoader::FindTargetObject(JSContext* aCx,
// instance).
if (!targetObject) {
// Our targetObject is the caller's global object. Let's get it.
nsresult rv;
nsCOMPtr<nsIXPConnect> xpc =
do_GetService(kXPConnectServiceContractID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsAXPCNativeCallContext *cc = nullptr;
rv = xpc->GetCurrentNativeCallContext(&cc);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIXPConnectWrappedNative> wn;
rv = cc->GetCalleeWrapper(getter_AddRefs(wn));
NS_ENSURE_SUCCESS(rv, rv);
targetObject = wn->GetJSObject();
if (!targetObject) {
NS_ERROR("null calling object");
return NS_ERROR_FAILURE;
}
targetObject = JS_GetGlobalForObject(aCx, targetObject);
targetObject = CurrentGlobalOrNull(aCx);
}
aTargetObject.set(targetObject);

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

@ -19,7 +19,6 @@ class nsAXPCNativeCallContext
public:
NS_IMETHOD GetCallee(nsISupports **aResult) = 0;
NS_IMETHOD GetCalleeMethodIndex(uint16_t *aResult) = 0;
NS_IMETHOD GetCalleeWrapper(nsIXPConnectWrappedNative **aResult) = 0;
NS_IMETHOD GetJSContext(JSContext **aResult) = 0;
NS_IMETHOD GetArgc(uint32_t *aResult) = 0;
NS_IMETHOD GetArgvPtr(JS::Value **aResult) = 0;

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

@ -199,14 +199,6 @@ CreateXMLHttpRequest(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
if (!ssm)
return false;
nsIPrincipal *subjectPrincipal = ssm->GetCxSubjectPrincipal(cx);
if (!subjectPrincipal)
return false;
RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
MOZ_ASSERT(global);
@ -215,7 +207,8 @@ CreateXMLHttpRequest(JSContext *cx, unsigned argc, jsval *vp)
nsCOMPtr<nsIGlobalObject> iglobal = do_QueryInterface(sop);
nsCOMPtr<nsIXMLHttpRequest> xhr = new nsXMLHttpRequest();
nsresult rv = xhr->Init(subjectPrincipal, nullptr, iglobal, nullptr);
nsresult rv = xhr->Init(nsContentUtils::GetSubjectPrincipal(), nullptr,
iglobal, nullptr);
if (NS_FAILED(rv))
return false;
@ -1050,10 +1043,6 @@ xpc::CreateSandboxObject(JSContext *cx, MutableHandleValue vp, nsISupports *prin
{
// Create the sandbox global object
nsresult rv;
nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
if (NS_FAILED(rv))
return NS_ERROR_XPC_UNEXPECTED;
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(prinOrSop);
if (!principal) {
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(prinOrSop);
@ -1297,8 +1286,6 @@ GetExpandedPrincipal(JSContext *cx, HandleObject arrayObj, nsIExpandedPrincipal
nsTArray< nsCOMPtr<nsIPrincipal> > allowedDomains(length);
allowedDomains.SetLength(length);
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
NS_ENSURE_TRUE(ssm, false);
for (uint32_t i = 0; i < length; ++i) {
RootedValue allowed(cx);
@ -1329,7 +1316,7 @@ GetExpandedPrincipal(JSContext *cx, HandleObject arrayObj, nsIExpandedPrincipal
// We do not allow ExpandedPrincipals to contain any system principals.
bool isSystem;
rv = ssm->IsSystemPrincipal(principal, &isSystem);
rv = nsXPConnect::SecurityManager()->IsSystemPrincipal(principal, &isSystem);
NS_ENSURE_SUCCESS(rv, false);
if (isSystem) {
JS_ReportError(cx, "System principal is not allowed in an expanded principal");
@ -1651,7 +1638,7 @@ ContextHolder::ContextHolder(JSContext *aOuterCx,
{
if (mJSContext) {
bool isChrome;
DebugOnly<nsresult> rv = XPCWrapper::GetSecurityManager()->
DebugOnly<nsresult> rv = nsXPConnect::SecurityManager()->
IsSystemPrincipal(mPrincipal, &isChrome);
MOZ_ASSERT(NS_SUCCEEDED(rv));

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

@ -29,7 +29,6 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
mXPCContext(nullptr),
mJSContext(cx),
mCallerLanguage(callerLanguage),
mFlattenedJSObject(cx),
mWrapper(nullptr),
mTearOff(nullptr),
mName(cx)
@ -77,14 +76,10 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
}
}
if (mWrapper) {
mFlattenedJSObject = mWrapper->GetFlatJSObject();
if (mTearOff)
mScriptableInfo = nullptr;
else
mScriptableInfo = mWrapper->GetScriptableInfo();
} else {
MOZ_ASSERT(!mFlattenedJSObject, "What object do we have?");
}
if (!JSID_IS_VOID(name))
@ -258,15 +253,6 @@ XPCCallContext::GetCalleeMethodIndex(uint16_t *aCalleeMethodIndex)
return NS_OK;
}
/* readonly attribute nsIXPConnectWrappedNative CalleeWrapper; */
NS_IMETHODIMP
XPCCallContext::GetCalleeWrapper(nsIXPConnectWrappedNative * *aCalleeWrapper)
{
nsCOMPtr<nsIXPConnectWrappedNative> rval = mWrapper;
rval.forget(aCalleeWrapper);
return NS_OK;
}
/* readonly attribute XPCNativeInterface CalleeInterface; */
NS_IMETHODIMP
XPCCallContext::GetCalleeInterface(nsIInterfaceInfo * *aCalleeInterface)

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

@ -1486,8 +1486,7 @@ nsXPCComponents_ID::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
// Do the security check if necessary
nsIXPCSecurityManager* sm = nsXPConnect::XPConnect()->GetDefaultSecurityManager();
if (sm && NS_FAILED(sm->CanCreateInstance(cx, nsJSID::GetCID()))) {
if (NS_FAILED(nsXPConnect::SecurityManager()->CanCreateInstance(cx, nsJSID::GetCID()))) {
// the security manager vetoed. It should have set an exception.
*_retval = false;
return NS_OK;
@ -1850,8 +1849,7 @@ nsXPCComponents_Exception::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
// Do the security check if necessary
nsIXPCSecurityManager* sm = xpc->GetDefaultSecurityManager();
if (sm && NS_FAILED(sm->CanCreateInstance(cx, Exception::GetCID()))) {
if (NS_FAILED(nsXPConnect::SecurityManager()->CanCreateInstance(cx, Exception::GetCID()))) {
// the security manager vetoed. It should have set an exception.
*_retval = false;
return NS_OK;
@ -2359,8 +2357,7 @@ nsXPCComponents_Constructor::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
// Do the security check if necessary
nsIXPCSecurityManager* sm = xpc->GetDefaultSecurityManager();
if (sm && NS_FAILED(sm->CanCreateInstance(cx, nsXPCConstructor::GetCID()))) {
if (NS_FAILED(nsXPConnect::SecurityManager()->CanCreateInstance(cx, nsXPCConstructor::GetCID()))) {
// the security manager vetoed. It should have set an exception.
*_retval = false;
return NS_OK;
@ -2786,6 +2783,22 @@ nsXPCComponents_Utils::ForceCC()
return NS_OK;
}
/* void finishCC(); */
NS_IMETHODIMP
nsXPCComponents_Utils::FinishCC()
{
nsCycleCollector_finishAnyCurrentCollection();
return NS_OK;
}
/* void ccSlice(long long budget); */
NS_IMETHODIMP
nsXPCComponents_Utils::CcSlice(int64_t budget)
{
nsCycleCollector_collectSliceWork(budget);
return NS_OK;
}
/* void forceShrinkingGC (); */
NS_IMETHODIMP
nsXPCComponents_Utils::ForceShrinkingGC()

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

@ -81,22 +81,13 @@ XPCCallContext::GetPrevCallContext() const
return mPrevCallContext;
}
inline JSObject*
XPCCallContext::GetFlattenedJSObject() const
{
CHECK_STATE(HAVE_OBJECT);
return mFlattenedJSObject;
}
inline nsISupports*
XPCCallContext::GetIdentityObject() const
{
CHECK_STATE(HAVE_OBJECT);
if (mWrapper)
return mWrapper->GetIdentityObject();
return mFlattenedJSObject ?
static_cast<nsISupports*>(xpc_GetJSPrivate(mFlattenedJSObject)) :
nullptr;
return nullptr;
}
inline XPCWrappedNative*

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше