This commit is contained in:
Carsten "Tomcat" Book 2014-10-17 16:41:45 +02:00
Родитель 9b4c29f73f e658a539a6
Коммит 90db5d3cce
174 изменённых файлов: 3254 добавлений и 2005 удалений

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

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1061335 - CLOBBER for Win32 compiler update.
Bug 609976 - CLOBBER

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

@ -28,7 +28,6 @@ html xul|scrollbar {
background-image: none !important;
border: 0px solid transparent !important;
pointer-events: none;
opacity: 1;
}
xul|scrollbar[orient="vertical"] {
@ -56,7 +55,6 @@ xul|scrollbar[orient="horizontal"] xul|thumb {
xul|scrollbar:not([active="true"]),
xul|scrollbar[disabled] {
opacity: 0;
transition: opacity 1s ease;
}
xul|scrollbarbutton {

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>

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

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "63436aa17e7fa3ad521fdeffdc22b81c36e5d69b",
"revision": "934b8c3014a3e20dd5d90ecf95f4b6b704dddb1e",
"repo_path": "/integration/gaia-central"
}

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

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>

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

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -74,3 +74,13 @@ tabpanels {
browser[pending] {
display: none;
}
browser[pendingpaint] {
opacity: 0;
}
tabbrowser[pendingpaint] {
background-image: url(chrome://global/skin/spinner.png);
background-repeat: no-repeat;
background-position: center center;
}

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

@ -136,6 +136,10 @@
""
</field>
<field name="_contentWaitingCount">
0
</field>
<property name="_numPinnedTabs" readonly="true">
<getter><![CDATA[
for (var i = 0; i < this.tabs.length; i++) {
@ -3228,6 +3232,31 @@
</body>
</method>
<method name="_showBusySpinnerRemoteBrowser">
<parameter name="aBrowser"/>
<body><![CDATA[
aBrowser.setAttribute("pendingpaint", "true");
if (this._contentWaitingCount <= 0) {
// We are not currently spinning
this.setAttribute("pendingpaint", "true");
this._contentWaitingCount = 1;
} else {
this._contentWaitingCount++;
}
]]></body>
</method>
<method name="_hideBusySpinnerRemoteBrowser">
<parameter name="aBrowser"/>
<body><![CDATA[
aBrowser.removeAttribute("pendingpaint");
this._contentWaitingCount--;
if (this._contentWaitingCount <= 0) {
this.removeAttribute("pendingpaint");
}
]]></body>
</method>
<method name="_prepareForTabSwitch">
<parameter name="toTab"/>
<parameter name="fromTab"/>
@ -3266,16 +3295,19 @@
let timeoutPromise = new Promise((aResolve, aReject) => {
timeoutId = setTimeout(() => {
this._showBusySpinnerRemoteBrowser(toBrowser);
attemptTabSwitch(aResolve, aReject);
}, kTabSwitchTimeout);
});
let paintPromise = new Promise((aResolve, aReject) => {
toBrowser.addEventListener("MozAfterRemotePaint", function onRemotePaint() {
let onRemotePaint = () => {
toBrowser.removeEventListener("MozAfterRemotePaint", onRemotePaint);
this._hideBusySpinnerRemoteBrowser(toBrowser);
clearTimeout(timeoutId);
attemptTabSwitch(aResolve, aReject);
});
};
toBrowser.addEventListener("MozAfterRemotePaint", onRemotePaint);
toBrowser.QueryInterface(Ci.nsIFrameLoaderOwner)
.frameLoader
.requestNotifyAfterRemotePaint();

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

@ -1376,7 +1376,7 @@ PlacesToolbar.prototype = {
elt.localName != "menupopup") {
let eltRect = elt.getBoundingClientRect();
let eltIndex = Array.indexOf(this._rootElt.childNodes, elt);
if (PlacesUIUtils.nodeIsFolder(elt._placesNode) &&
if (PlacesUtils.nodeIsFolder(elt._placesNode) &&
!PlacesUIUtils.isContentsReadOnly(elt._placesNode)) {
// This is a folder.
// If we are in the middle of it, drop inside it.

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

@ -137,6 +137,9 @@ DEFINES += -DMOZ_ICU_DBG_SUFFIX=$(MOZ_ICU_DBG_SUFFIX)
ifdef CLANG_CXX
DEFINES += -DCLANG_CXX
endif
ifdef CLANG_CL
DEFINES += -DCLANG_CL
endif
libs::
$(MAKE) -C $(DEPTH)/browser/locales langpack

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

@ -921,4 +921,7 @@ bin/libfreebl_32int64_3.so
#ifdef CLANG_CXX
@BINPATH@/llvm-symbolizer
#endif
#ifdef CLANG_CL
@BINPATH@/clang_rt.asan_dynamic-i386.dll
#endif
#endif

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

@ -94,6 +94,9 @@ PluginContent.prototype = {
return;
}
if (Services.telemetry.canSend) {
this._finishRecordingFlashPluginTelemetry();
}
this.clearPluginDataCache();
},
@ -378,6 +381,11 @@ PluginContent.prototype = {
break;
}
if (Services.telemetry.canSend && this._getPluginInfo(plugin).mimetype ===
"application/x-shockwave-flash") {
this._recordFlashPluginTelemetry(eventType, plugin);
}
// Show the in-content UI if it's not too big. The crashed plugin handler already did this.
if (eventType != "PluginCrashed") {
let overlay = this.getPluginUI(plugin, "main");
@ -407,6 +415,42 @@ PluginContent.prototype = {
}
},
_recordFlashPluginTelemetry: function (eventType, plugin) {
if (!this.flashPluginStats) {
this.flashPluginStats = {
instancesCount: 0,
plugins: new WeakSet()
};
}
if (!this.flashPluginStats.plugins.has(plugin)) {
// Reporting plugin instance and its dimensions only once.
this.flashPluginStats.plugins.add(plugin);
this.flashPluginStats.instancesCount++;
let pluginRect = plugin.getBoundingClientRect();
Services.telemetry.getHistogramById('FLASH_PLUGIN_WIDTH')
.add(pluginRect.width);
Services.telemetry.getHistogramById('FLASH_PLUGIN_HEIGHT')
.add(pluginRect.height);
Services.telemetry.getHistogramById('FLASH_PLUGIN_AREA')
.add(pluginRect.width * pluginRect.height);
let state = this._getPluginInfo(plugin).fallbackType;
Services.telemetry.getHistogramById('FLASH_PLUGIN_STATES')
.add(state);
}
},
_finishRecordingFlashPluginTelemetry: function () {
if (this.flashPluginStats) {
Services.telemetry.getHistogramById('FLASH_PLUGIN_INSTANCES_ON_PAGE')
.add(this.flashPluginStats.instancesCount);
delete this.flashPluginStats;
}
},
isKnownPlugin: function (objLoadingContent) {
return (objLoadingContent.getContentTypeForMIMEType(objLoadingContent.actualType) ==
Ci.nsIObjectLoadingContent.TYPE_PLUGIN);

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

@ -66,6 +66,13 @@ LLDBINIT_FINAL_TARGET_FILES := $(DEPTH)/.lldbinit
LLDBINIT_FINAL_TARGET_DEST = $(FINAL_TARGET)
INSTALL_TARGETS += LLDBINIT_FINAL_TARGET
ifeq (1_1,$(MOZ_ASAN)_$(CLANG_CL))
# Install the clang-cl runtime library for ASAN next to the binaries we produce.
CLANG_RT_ASAN_FILES := $(MOZ_CLANG_RT_ASAN_LIB_PATH)
CLANG_RT_ASAN_DEST = $(FINAL_TARGET)
INSTALL_TARGETS += CLANG_RT_ASAN
endif
include $(topsrcdir)/config/rules.mk
TARGET_DEPTH = ..

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

@ -506,6 +506,11 @@ case "$target" in
if test -z "$CLANG_CL"; then
AC_DEFINE(HAVE_SEH_EXCEPTIONS)
else
# Build on clang-cl with MSVC 2013 with fallback emulation.
CFLAGS="$CFLAGS -fmsc-version=1800 -fallback"
CXXFLAGS="$CXXFLAGS -fmsc-version=1800 -fallback"
# Send our CFLAGS to NSS too
MOZ_CFLAGS_NSS=1
AC_DEFINE_UNQUOTED(GTEST_HAS_SEH, 0)
fi
@ -1260,6 +1265,16 @@ MOZ_ARG_ENABLE_BOOL(address-sanitizer,
MOZ_ASAN= )
if test -n "$MOZ_ASAN"; then
MOZ_LLVM_HACKS=1
if test -n "$CLANG_CL"; then
# Look for clang_rt.asan_dynamic-i386.dll
MOZ_CLANG_RT_ASAN_LIB=clang_rt.asan_dynamic-i386.dll
# We use MOZ_PATH_PROG in order to get a Windows style path.
MOZ_PATH_PROG(MOZ_CLANG_RT_ASAN_LIB_PATH, $MOZ_CLANG_RT_ASAN_LIB)
if test -z "$MOZ_CLANG_RT_ASAN_LIB_PATH"; then
AC_MSG_ERROR([Couldn't find $MOZ_CLANG_RT_ASAN_LIB. It should be available in the same location as clang-cl.])
fi
AC_SUBST(MOZ_CLANG_RT_ASAN_LIB_PATH)
fi
AC_DEFINE(MOZ_ASAN)
MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer)
fi
@ -3796,11 +3811,6 @@ dnl system libffi Support
dnl ========================================================
MOZ_CONFIG_FFI()
# split JS out by default to avoid VS2005 PGO crash (bug 591836).
if test "$OS_ARCH" = "WINNT"; then
JS_SHARED_LIBRARY=1
fi
MOZ_ARG_ENABLE_BOOL(shared-js,
[ --enable-shared-js
Create a shared JavaScript library.],
@ -7953,8 +7963,7 @@ dnl =
dnl ========================================================
MOZ_ARG_HEADER(Static build options)
if test "$OS_ARCH" = "WINNT"; then
GKMEDIAS_SHARED_LIBRARY=1
if test -n "$GKMEDIAS_SHARED_LIBRARY"; then
AC_DEFINE(GKMEDIAS_SHARED_LIBRARY)
fi
AC_SUBST(GKMEDIAS_SHARED_LIBRARY)

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

@ -412,7 +412,7 @@ public:
/**
* Web components custom element data.
*/
nsAutoPtr<CustomElementData> mCustomElementData;
nsRefPtr<CustomElementData> mCustomElementData;
};
protected:

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

@ -238,18 +238,15 @@ DOMParser::ParseFromStream(nsIInputStream *stream,
// Create a fake channel
nsCOMPtr<nsIChannel> parserChannel;
NS_NewInputStreamChannel(getter_AddRefs(parserChannel), mDocumentURI, nullptr,
nsDependentCString(contentType), nullptr);
NS_NewInputStreamChannel(getter_AddRefs(parserChannel),
mDocumentURI,
nullptr, // aStream
mOriginalPrincipal,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER,
nsDependentCString(contentType));
NS_ENSURE_STATE(parserChannel);
// More principal-faking here
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(mOriginalPrincipal,
nullptr,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER);
parserChannel->SetLoadInfo(loadInfo);
if (charset) {
parserChannel->SetContentCharset(nsDependentCString(charset));
}

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

@ -193,6 +193,8 @@ public:
WorkerPrivate* mWorkerPrivate;
nsAutoPtr<WorkerFeature> mWorkerFeature;
nsWeakPtr mWeakLoadGroup;
private:
~WebSocketImpl()
{
@ -528,8 +530,7 @@ WebSocketImpl::DisconnectInternal()
{
AssertIsOnMainThread();
nsCOMPtr<nsILoadGroup> loadGroup;
GetLoadGroup(getter_AddRefs(loadGroup));
nsCOMPtr<nsILoadGroup> loadGroup = do_QueryReferent(mWeakLoadGroup);
if (loadGroup) {
loadGroup->RemoveRequest(this, nullptr, NS_OK);
}
@ -1390,6 +1391,8 @@ WebSocketImpl::InitializeConnection()
NS_ENSURE_SUCCESS(rv, rv);
rv = loadGroup->AddRequest(this, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
mWeakLoadGroup = do_GetWeakReference(loadGroup);
}
// manually adding loadinfo to the channel since it

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

@ -5844,12 +5844,7 @@ nsDocument::ProcessTopElementQueue(bool aIsBaseQueue)
{
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
if (sProcessingStack.isNothing()) {
// If XPCOM shutdown has reset the processing stack, don't do anything.
return;
}
nsTArray<CustomElementData*>& stack = *sProcessingStack;
nsTArray<nsRefPtr<CustomElementData>>& stack = *sProcessingStack;
uint32_t firstQueue = stack.LastIndexOf((CustomElementData*) nullptr);
if (aIsBaseQueue && firstQueue != 0) {
@ -5886,7 +5881,7 @@ nsDocument::RegisterEnabled()
}
// static
Maybe<nsTArray<mozilla::dom::CustomElementData*>>
Maybe<nsTArray<nsRefPtr<mozilla::dom::CustomElementData>>>
nsDocument::sProcessingStack;
// static

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

@ -325,6 +325,8 @@ private:
// being created flag.
struct CustomElementData
{
NS_INLINE_DECL_REFCOUNTING(CustomElementData)
explicit CustomElementData(nsIAtom* aType);
// Objects in this array are transient and empty after each microtask
// checkpoint.
@ -346,6 +348,9 @@ struct CustomElementData
// Empties the callback queue.
void RunCallbackQueue();
private:
virtual ~CustomElementData() {}
};
// The required information for a custom element as defined in:
@ -1520,7 +1525,7 @@ private:
// CustomElementData in this array, separated by nullptr that
// represent the boundaries of the items in the stack. The first
// queue in the stack is the base element queue.
static mozilla::Maybe<nsTArray<mozilla::dom::CustomElementData*>> sProcessingStack;
static mozilla::Maybe<nsTArray<nsRefPtr<mozilla::dom::CustomElementData>>> sProcessingStack;
// Flag to prevent re-entrance into base element queue as described in the
// custom elements speicification.

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

@ -519,7 +519,11 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
nsCOMPtr<nsIChannel> channel;
rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
uri,
stream);
stream,
info->mPrincipal,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER);
NS_ENSURE_SUCCESS(rv, rv);
nsString type;
@ -537,12 +541,6 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
return error.ErrorCode();
}
nsCOMPtr<nsILoadInfo> loadInfo =
new mozilla::LoadInfo(info->mPrincipal,
nullptr,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER);
channel->SetLoadInfo(loadInfo);
channel->SetOriginalURI(uri);
channel->SetContentType(NS_ConvertUTF16toUTF8(type));
channel->SetContentLength(size);

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

@ -12,6 +12,9 @@ var is_remote;
error_reporting_test();
dom_test();
xray_test();
if (typeof Symbol === "function") {
symbol_test();
}
compartment_test();
regexp_test();
sync_test();
@ -119,15 +122,13 @@ function symbol_test()
{
let iterator = Symbol.iterator;
let named = Symbol.for("cpow-test");
// let unique = Symbol();
let object = {
[iterator]: iterator,
[named]: named,
// [unique]: unique,
// "unique": unique
};
sendSyncMessage("cpows:symbol_test", {}, object);
let test = ['a'];
sendSyncMessage("cpows:symbol_test", {}, {object: object, test: test});
}
// Parent->Child references should go X->parent.privilegedJunkScope->child.privilegedJunkScope->Y

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

@ -206,10 +206,16 @@
}
function recvSymbolTest(message) {
let object = message.objects;
let object = message.objects.object;
is(object[Symbol.iterator], Symbol.iterator, "Should use Symbol.iterator");
is(Symbol.keyFor(object[Symbol.for("cpow-test")]), "cpow-test", "Symbols aren't registered correctly");
// is(object.unique, object[object.unique], "Unique symbols as ids and values don't seem to work");
let symbols = Object.getOwnPropertySymbols(object);
is(symbols.length, 2, "Object should have two symbol keys");
let test = undefined;
for (let x of message.objects.test) {
test = x;
}
is(test, "a", "for .. of iteration should work");
}
let systemGlobal = this;
@ -307,7 +313,9 @@
mm.addMessageListener("cpows:dom_test", recvDomTest);
mm.addMessageListener("cpows:dom_test_after_gc", recvDomTestAfterGC);
mm.addMessageListener("cpows:xray_test", recvXrayTest);
mm.addMessageListener("cpows:symbol_test", recvSymbolTest);
if (typeof Symbol === "function") {
mm.addMessageListener("cpows:symbol_test", recvSymbolTest);
}
mm.addMessageListener("cpows:compartment_test", recvCompartmentTest);
mm.addMessageListener("cpows:regexp_test", recvRegExpTest);
mm.addMessageListener("cpows:lifetime_test_1", recvLifetimeTest1);

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

@ -1655,12 +1655,25 @@ nsDocShell::LoadStream(nsIInputStream *aStream, nsIURI * aURI,
mLoadType = loadType;
nsCOMPtr<nsISupports> owner;
aLoadInfo->GetOwner(getter_AddRefs(owner));
nsCOMPtr<nsIPrincipal> requestingPrincipal = do_QueryInterface(owner);
if (!requestingPrincipal) {
requestingPrincipal = nsContentUtils::GetSystemPrincipal();
}
// build up a channel for this stream.
nsCOMPtr<nsIChannel> channel;
NS_ENSURE_SUCCESS(NS_NewInputStreamChannel
(getter_AddRefs(channel), uri, aStream,
aContentType, aContentCharset),
NS_ERROR_FAILURE);
nsresult rv =
NS_NewInputStreamChannel(getter_AddRefs(channel),
uri,
aStream,
requestingPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
aContentType,
aContentCharset);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
nsCOMPtr<nsIURILoader>
uriLoader(do_GetService(NS_URI_LOADER_CONTRACTID));
@ -10266,25 +10279,28 @@ nsDocShell::DoURILoad(nsIURI * aURI,
rv = vsh->NewSrcdocChannel(aURI, aSrcdoc, aBaseURI,
getter_AddRefs(channel));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(requestingPrincipal,
requestingNode,
securityFlags,
aContentPolicyType);
channel->SetLoadInfo(loadInfo);
}
else {
rv = NS_NewInputStreamChannel(getter_AddRefs(channel),aURI,
aSrcdoc,
NS_LITERAL_CSTRING("text/html"),
true);
rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel),
aURI,
aSrcdoc,
NS_LITERAL_CSTRING("text/html"),
requestingNode,
requestingPrincipal,
securityFlags,
aContentPolicyType,
true);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(channel);
MOZ_ASSERT(isc);
isc->SetBaseURI(aBaseURI);
}
// NS_NewInputStreamChannel does not yet attach the loadInfo in nsNetutil.h,
// hence we have to manually attach the loadInfo for that channel.
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(requestingPrincipal,
requestingNode,
securityFlags,
aContentPolicyType);
channel->SetLoadInfo(loadInfo);
}
nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =

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

@ -599,20 +599,7 @@ public:
return false;
}
virtual const char *className(JSContext *cx,
JS::Handle<JSObject*> wrapper) const MOZ_OVERRIDE;
virtual void finalize(JSFreeOp *fop, JSObject *proxy) const MOZ_OVERRIDE;
// Fundamental traps
virtual bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx,
JS::Handle<JSObject*> proxy) const MOZ_OVERRIDE;
virtual bool getPropertyDescriptor(JSContext* cx,
JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc)
const MOZ_OVERRIDE;
// Standard internal methods
virtual bool getOwnPropertyDescriptor(JSContext* cx,
JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
@ -631,23 +618,12 @@ public:
bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool watch(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, JS::Handle<JSObject*> callable) const MOZ_OVERRIDE;
virtual bool unwatch(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id) const MOZ_OVERRIDE;
virtual bool isCallable(JSObject *obj) const MOZ_OVERRIDE {
return false;
}
virtual bool isConstructor(JSObject *obj) const MOZ_OVERRIDE {
return false;
}
// Derived traps
virtual bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx,
JS::Handle<JSObject*> proxy) const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
virtual bool hasOwn(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id,
@ -657,11 +633,36 @@ public:
JS::Handle<jsid> id,
bool strict,
JS::MutableHandle<JS::Value> vp) const MOZ_OVERRIDE;
virtual bool keys(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
// SpiderMonkey extensions
virtual bool getPropertyDescriptor(JSContext* cx,
JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc)
const MOZ_OVERRIDE;
virtual bool hasOwn(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool iterate(JSContext *cx, JS::Handle<JSObject*> proxy,
unsigned flags,
JS::MutableHandle<JS::Value> vp) const MOZ_OVERRIDE;
virtual const char *className(JSContext *cx,
JS::Handle<JSObject*> wrapper) const MOZ_OVERRIDE;
virtual void finalize(JSFreeOp *fop, JSObject *proxy) const MOZ_OVERRIDE;
virtual bool isCallable(JSObject *obj) const MOZ_OVERRIDE {
return false;
}
virtual bool isConstructor(JSObject *obj) const MOZ_OVERRIDE {
return false;
}
virtual bool watch(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, JS::Handle<JSObject*> callable) const MOZ_OVERRIDE;
virtual bool unwatch(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id) const MOZ_OVERRIDE;
static void ObjectMoved(JSObject *obj, const JSObject *old);
@ -930,12 +931,12 @@ nsOuterWindowProxy::set(JSContext *cx, JS::Handle<JSObject*> proxy,
}
bool
nsOuterWindowProxy::keys(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const
nsOuterWindowProxy::getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const
{
// BaseProxyHandler::keys seems to do what we want here: call
// ownPropertyKeys and then filter out the non-enumerable properties.
return js::BaseProxyHandler::keys(cx, proxy, props);
return js::BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, proxy, props);
}
bool

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

@ -82,6 +82,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
[test_urlutils_stringify.html]
[test_window_constructor.html]
[test_window_cross_origin_props.html]
[test_window_define_symbol.html]
[test_window_enumeration.html]
[test_window_extensible.html]
[test_window_indexing.html]

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

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1082672
-->
<head>
<meta charset="UTF-8">
<title>Test for Bug 1082672 part 2</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.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=1082672">Mozilla Bug 1082672</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
var sym = Symbol("ponies");
Object.defineProperty(window, sym, {configurable: true, value: 3});
is(window[sym], 3);
</script>
</pre>
</body>
</html>

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

@ -1406,8 +1406,11 @@ XrayAttributeOrMethodKeys(JSContext* cx, JS::Handle<JSObject*> wrapper,
// looking at now.
size_t i = list->specs - specList;
for ( ; ids[i] != JSID_VOID; ++i) {
// Skip non-enumerable properties and symbol-keyed properties unless
// they are specially requested via flags.
if (((flags & JSITER_HIDDEN) ||
(specList[i].flags & JSPROP_ENUMERATE)) &&
((flags & JSITER_SYMBOLS) || !JSID_IS_SYMBOL(ids[i])) &&
!props.append(ids[i])) {
return false;
}

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

@ -1685,7 +1685,7 @@ InitIds(JSContext* cx, const Prefable<Spec>* prefableSpecs, jsid* ids)
// because this is only done once per application runtime.
Spec* spec = prefableSpecs->specs;
do {
if (!InternJSString(cx, *ids, spec->name)) {
if (!JS::PropertySpecNameToPermanentId(cx, spec->name, ids)) {
return false;
}
} while (++ids, (++spec)->name);

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

@ -277,7 +277,7 @@ BaseDOMProxyHandler::enumerate(JSContext* cx, JS::Handle<JSObject*> proxy,
if (!JS_GetPrototype(cx, proxy, &proto)) {
return false;
}
return keys(cx, proxy, props) &&
return getOwnEnumerablePropertyKeys(cx, proxy, props) &&
(!proto || js::GetPropertyKeys(cx, proto, 0, &props));
}
@ -299,13 +299,13 @@ BaseDOMProxyHandler::ownPropertyKeys(JSContext* cx,
JS::Handle<JSObject*> proxy,
JS::AutoIdVector& props) const
{
return ownPropNames(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN, props);
return ownPropNames(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props);
}
bool
BaseDOMProxyHandler::keys(JSContext* cx,
JS::Handle<JSObject*> proxy,
JS::AutoIdVector& props) const
BaseDOMProxyHandler::getOwnEnumerablePropertyKeys(JSContext* cx,
JS::Handle<JSObject*> proxy,
JS::AutoIdVector& props) const
{
return ownPropNames(cx, proxy, JSITER_OWNONLY, props);
}
@ -345,7 +345,8 @@ IdToInt32(JSContext* cx, JS::Handle<jsid> id)
JS::Rooted<JS::Value> idval(cx);
double array_index;
int32_t i;
if (!::JS_IdToValue(cx, id, &idval) ||
if (JSID_IS_SYMBOL(id) ||
!::JS_IdToValue(cx, id, &idval) ||
!JS::ToNumber(cx, idval, &array_index) ||
!::JS_DoubleIsInt32(array_index, &i)) {
return -1;

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

@ -50,34 +50,38 @@ public:
: js::BaseProxyHandler(aProxyFamily, aHasPrototype)
{}
// Implementations of traps that can be implemented in terms of
// fundamental traps.
bool enumerate(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector& props) const MOZ_OVERRIDE;
bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
// Implementations of methods that can be implemented in terms of
// other lower-level methods.
bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
virtual bool ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
bool enumerate(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector& props) const MOZ_OVERRIDE;
bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
// We override getOwnEnumerablePropertyKeys() and implement it directly
// instead of using the default implementation, which would call
// ownPropertyKeys and then filter out the non-enumerable ones. This avoids
// unnecessary work during enumeration.
virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
bool watch(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::Handle<JSObject*> callable) const MOZ_OVERRIDE;
bool unwatch(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id) const MOZ_OVERRIDE;
virtual bool ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
// We override keys() and implement it directly instead of using the
// default implementation, which would getOwnPropertyNames and then
// filter out the non-enumerable ones. This avoids doing
// unnecessary work during enumeration.
virtual bool keys(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
protected:
// Hook for subclasses to implement shared ownPropertyKeys()/keys()
// functionality. The "flags" argument is either JSITER_OWNONLY (for keys())
// or JSITER_OWNONLY | JSITER_HIDDEN (for ownPropertyKeys()).
// or JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS (for
// ownPropertyKeys()).
virtual bool ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy,
unsigned flags,
JS::AutoIdVector& props) const = 0;
@ -100,7 +104,6 @@ public:
: BaseDOMProxyHandler(&family)
{}
bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy) const MOZ_OVERRIDE;
bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE
{
@ -110,15 +113,16 @@ public:
virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc, bool* defined)
const;
bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool* bp) const MOZ_OVERRIDE;
bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy) const MOZ_OVERRIDE;
bool has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
bool* bp) const MOZ_OVERRIDE;
bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id, bool strict, JS::MutableHandle<JS::Value> vp)
const MOZ_OVERRIDE;
bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool* bp) const MOZ_OVERRIDE;
bool has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
bool* bp) const MOZ_OVERRIDE;
bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
/*
* If assigning to proxy[id] hits a named setter with OverrideBuiltins or

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

@ -39,4 +39,9 @@
/* CHLD values */
#define BTA_AG_CHLD_VAL "(0,1,2,3)"
/* BLE Feature */
#define BTA_GATT_INCLUDED TRUE
#define BLE_INCLUDED TRUE
#define SMP_INCLUDED TRUE
#endif /* B2G_BDROID_BUILDCFG_H */

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

@ -66,7 +66,11 @@ public:
void TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
void TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height,
GLsizei depth);
void TexImage3D(GLenum target, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
const Nullable<dom::ArrayBufferView> &pixels,
ErrorResult& rv);
void TexSubImage3D(GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,

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

@ -204,6 +204,119 @@ WebGL2Context::TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat
}
}
void
WebGL2Context::TexImage3D(GLenum target, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
const Nullable<dom::ArrayBufferView> &pixels,
ErrorResult& rv)
{
if (IsContextLost())
return;
void* data;
size_t dataLength;
js::Scalar::Type jsArrayType;
if (pixels.IsNull()) {
data = nullptr;
dataLength = 0;
jsArrayType = js::Scalar::TypeMax;
} else {
const ArrayBufferView& view = pixels.Value();
view.ComputeLengthAndData();
data = view.Data();
dataLength = view.Length();
jsArrayType = JS_GetArrayBufferViewType(view.Obj());
}
const WebGLTexImageFunc func = WebGLTexImageFunc::TexImage;
const WebGLTexDimensions dims = WebGLTexDimensions::Tex3D;
if (!ValidateTexImageTarget(target, func, dims))
return;
TexImageTarget texImageTarget = target;
if (!ValidateTexImage(texImageTarget, level, internalformat,
0, 0, 0,
width, height, depth,
border, format, type, func, dims))
{
return;
}
if (!ValidateTexInputData(type, jsArrayType, func, dims))
return;
TexInternalFormat effectiveInternalFormat =
EffectiveInternalFormatFromInternalFormatAndType(internalformat, type);
if (effectiveInternalFormat == LOCAL_GL_NONE) {
return ErrorInvalidOperation("texImage3D: bad combination of internalformat and type");
}
// we need to find the exact sized format of the source data. Slightly abusing
// EffectiveInternalFormatFromInternalFormatAndType for that purpose. Really, an unsized source format
// is the same thing as an unsized internalformat.
TexInternalFormat effectiveSourceFormat =
EffectiveInternalFormatFromInternalFormatAndType(format, type);
MOZ_ASSERT(effectiveSourceFormat != LOCAL_GL_NONE); // should have validated format/type combo earlier
const size_t srcbitsPerTexel = GetBitsPerTexel(effectiveSourceFormat);
MOZ_ASSERT((srcbitsPerTexel % 8) == 0); // should not have compressed formats here.
size_t srcTexelSize = srcbitsPerTexel / 8;
CheckedUint32 checked_neededByteLength =
GetImageSize(height, width, depth, srcTexelSize, mPixelStoreUnpackAlignment);
if (!checked_neededByteLength.isValid())
return ErrorInvalidOperation("texSubImage2D: integer overflow computing the needed buffer size");
uint32_t bytesNeeded = checked_neededByteLength.value();
if (dataLength && dataLength < bytesNeeded)
return ErrorInvalidOperation("texImage3D: not enough data for operation (need %d, have %d)",
bytesNeeded, dataLength);
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
if (!tex)
return ErrorInvalidOperation("texImage3D: no texture is bound to this target");
if (tex->IsImmutable()) {
return ErrorInvalidOperation(
"texImage3D: disallowed because the texture "
"bound to this target has already been made immutable by texStorage3D");
}
GLenum driverType = LOCAL_GL_NONE;
GLenum driverInternalFormat = LOCAL_GL_NONE;
GLenum driverFormat = LOCAL_GL_NONE;
DriverFormatsFromEffectiveInternalFormat(gl,
effectiveInternalFormat,
&driverInternalFormat,
&driverFormat,
&driverType);
MakeContextCurrent();
GetAndFlushUnderlyingGLErrors();
gl->fTexImage3D(texImageTarget.get(), level,
driverInternalFormat,
width, height, depth,
0, driverFormat, driverType,
data);
GLenum error = GetAndFlushUnderlyingGLErrors();
if (error) {
return GenerateWarning("texImage3D generated error %s", ErrorName(error));
}
tex->SetImageInfo(texImageTarget, level,
width, height, depth,
effectiveInternalFormat,
data ? WebGLImageDataStatus::InitializedImageData
: WebGLImageDataStatus::UninitializedImageData);
}
void
WebGL2Context::TexSubImage3D(GLenum rawTarget, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,

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

@ -922,7 +922,11 @@ WebGLContext::GenerateMipmap(GLenum rawTarget)
const TexImageTarget imageTarget = (target == LOCAL_GL_TEXTURE_2D)
? LOCAL_GL_TEXTURE_2D
: LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
if (!tex->HasImageInfoAt(imageTarget, tex->GetBaseMipmapLevel()))
if (!tex->IsMipmapRangeValid())
{
return ErrorInvalidOperation("generateMipmap: Texture does not have a valid mipmap range.");
}
if (!tex->HasImageInfoAt(imageTarget, tex->EffectiveBaseMipmapLevel()))
{
return ErrorInvalidOperation("generateMipmap: Level zero of texture is not defined.");
}

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

@ -867,6 +867,7 @@ InfoFrom(WebGLTexImageFunc func, WebGLTexDimensions dims)
}
case WebGLTexDimensions::Tex3D:
switch (func) {
case WebGLTexImageFunc::TexImage: return "texImage3D";
case WebGLTexImageFunc::TexSubImage: return "texSubImage3D";
case WebGLTexImageFunc::CopyTexSubImage: return "copyTexSubImage3D";
case WebGLTexImageFunc::CompTexSubImage: return "compressedTexSubImage3D";

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

@ -14,6 +14,7 @@
#include "WebGLTexelConversions.h"
#include <algorithm>
#include "mozilla/MathAlgorithms.h"
using namespace mozilla;
@ -64,36 +65,50 @@ WebGLTexture::MemoryUsage() const {
return 0;
size_t result = 0;
for(size_t face = 0; face < mFacesCount; face++) {
for(size_t level = 0; level <= mMaxLevelWithCustomImages; level++)
result += ImageInfoAtFace(face, level).MemoryUsage();
}
for(size_t level = 0; level <= mMaxLevelWithCustomImages; level++)
result += ImageInfoAtFace(face, level).MemoryUsage();
}
return result;
}
static inline size_t
MipmapLevelsForSize(const WebGLTexture::ImageInfo &info)
{
GLsizei size = std::max(std::max(info.Width(), info.Height()), info.Depth());
// Find floor(log2(size)). (ES 3.0.4, 3.8 - Mipmapping).
return mozilla::FloorLog2(size);
}
bool
WebGLTexture::DoesMipmapHaveAllLevelsConsistentlyDefined(TexImageTarget texImageTarget) const
{
// We could not have generated a mipmap if the base image wasn't defined.
if (mHaveGeneratedMipmap)
return true;
if (GetMaxMipmapLevel() < GetBaseMipmapLevel())
if (!IsMipmapRangeValid())
return false;
// We want a copy here so we can modify it temporarily.
ImageInfo expected = ImageInfoAt(texImageTarget, GetBaseMipmapLevel());
ImageInfo expected = ImageInfoAt(texImageTarget, EffectiveBaseMipmapLevel());
if (!expected.IsPositive())
return false;
// checks if custom level>0 images are all defined up to the highest level defined
// and have the expected dimensions
for (size_t level = GetBaseMipmapLevel(); level <= GetMaxMipmapLevel(); ++level) {
// If Level{max} is > mMaxLevelWithCustomImages, then check if we are
// missing any image levels.
if (mMaxMipmapLevel > mMaxLevelWithCustomImages) {
if (MipmapLevelsForSize(expected) > mMaxLevelWithCustomImages)
return false;
}
// Checks if custom images are all defined up to the highest level and
// have the expected dimensions.
for (size_t level = EffectiveBaseMipmapLevel(); level <= EffectiveMaxMipmapLevel(); ++level) {
const ImageInfo& actual = ImageInfoAt(texImageTarget, level);
if (actual != expected)
return false;
// Check the raw value here, not the clamped one, since we don't want
// to terminate early if there aren't enough levels defined.
if (level == mMaxMipmapLevel)
return true;
expected.mWidth = std::max(1, expected.mWidth / 2);
expected.mHeight = std::max(1, expected.mHeight / 2);
expected.mDepth = std::max(1, expected.mDepth / 2);
@ -108,8 +123,7 @@ WebGLTexture::DoesMipmapHaveAllLevelsConsistentlyDefined(TexImageTarget texImage
}
}
// if we're here, we've exhausted all levels without finding a 1x1 image
return false;
return true;
}
void
@ -177,25 +191,19 @@ WebGLTexture::SetGeneratedMipmap() {
void
WebGLTexture::SetCustomMipmap() {
if (mHaveGeneratedMipmap) {
// if we were in GeneratedMipmap mode and are now switching to CustomMipmap mode,
// we need to compute now all the mipmap image info.
if (!IsMipmapRangeValid())
return;
// since we were in GeneratedMipmap mode, we know that the level 0 images all have the same info,
// and are power-of-two.
ImageInfo imageInfo = ImageInfoAtFace(0, GetBaseMipmapLevel());
// If we were in GeneratedMipmap mode and are now switching to CustomMipmap mode,
// we now need to compute all the mipmap image info.
ImageInfo imageInfo = ImageInfoAtFace(0, EffectiveBaseMipmapLevel());
NS_ASSERTION(mContext->IsWebGL2() || imageInfo.IsPowerOfTwo(),
"this texture is NPOT, so how could GenerateMipmap() ever accept it?");
GLsizei size = std::max(std::max(imageInfo.mWidth, imageInfo.mHeight), imageInfo.mDepth);
size_t maxLevel = MipmapLevelsForSize(imageInfo);
EnsureMaxLevelWithCustomImagesAtLeast(EffectiveBaseMipmapLevel() + maxLevel);
// Find floor(log2(size)). (ES 3.0.4, 3.8 - Mipmapping).
size_t maxLevel = 0;
for (GLsizei n = size; n > 1; n >>= 1)
++maxLevel;
EnsureMaxLevelWithCustomImagesAtLeast(maxLevel);
for (size_t level = GetBaseMipmapLevel() + 1; level <= GetMaxMipmapLevel(); ++level) {
for (size_t level = EffectiveBaseMipmapLevel() + 1; level <= EffectiveMaxMipmapLevel(); ++level) {
imageInfo.mWidth = std::max(imageInfo.mWidth / 2, 1);
imageInfo.mHeight = std::max(imageInfo.mHeight / 2, 1);
imageInfo.mDepth = std::max(imageInfo.mDepth / 2, 1);
@ -219,11 +227,6 @@ bool
WebGLTexture::IsMipmapComplete() const {
MOZ_ASSERT(mTarget == LOCAL_GL_TEXTURE_2D ||
mTarget == LOCAL_GL_TEXTURE_3D);
if (!ImageInfoAtFace(0, GetBaseMipmapLevel()).IsPositive())
return false;
if (mHaveGeneratedMipmap)
return true;
return DoesMipmapHaveAllLevelsConsistentlyDefined(LOCAL_GL_TEXTURE_2D);
}
@ -249,6 +252,17 @@ WebGLTexture::IsMipmapCubeComplete() const {
return true;
}
bool
WebGLTexture::IsMipmapRangeValid() const
{
// In ES3, if a texture is immutable, the mipmap levels are clamped.
if (IsImmutable())
return true;
if (mBaseMipmapLevel > std::min(mMaxLevelWithCustomImages, mMaxMipmapLevel))
return false;
return true;
}
WebGLTextureFakeBlackStatus
WebGLTexture::ResolvedFakeBlackStatus() {
if (MOZ_LIKELY(mFakeBlackStatus != WebGLTextureFakeBlackStatus::Unknown)) {
@ -256,10 +270,14 @@ WebGLTexture::ResolvedFakeBlackStatus() {
}
// Determine if the texture needs to be faked as a black texture.
// See 3.8.2 Shader Execution in the OpenGL ES 2.0.24 spec.
// See 3.8.2 Shader Execution in the OpenGL ES 2.0.24 spec, and 3.8.13 in
// the OpenGL ES 3.0.4 spec.
if (!IsMipmapRangeValid()) {
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
return mFakeBlackStatus;
}
for (size_t face = 0; face < mFacesCount; ++face) {
if (ImageInfoAtFace(face, GetBaseMipmapLevel()).mImageDataStatus == WebGLImageDataStatus::NoImageData) {
if (ImageInfoAtFace(face, EffectiveBaseMipmapLevel()).mImageDataStatus == WebGLImageDataStatus::NoImageData) {
// In case of undefined texture image, we don't print any message because this is a very common
// and often legitimate case (asynchronous texture loading).
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;

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

@ -17,6 +17,7 @@
#include "mozilla/LinkedList.h"
#include "mozilla/Assertions.h"
#include <algorithm>
#include "nsAlgorithm.h"
namespace mozilla {
@ -286,16 +287,22 @@ public:
bool IsImmutable() const { return mImmutable; }
void SetImmutable() { mImmutable = true; }
void SetBaseMipmapLevel(unsigned level) { mBaseMipmapLevel = level; }
void SetMaxMipmapLevel(unsigned level) { mMaxMipmapLevel = level; }
size_t GetBaseMipmapLevel() const {
// Clamp to [0, levels - 1]
return std::min(mBaseMipmapLevel, mMaxLevelWithCustomImages);
void SetBaseMipmapLevel(size_t level) { mBaseMipmapLevel = level; }
void SetMaxMipmapLevel(size_t level) { mMaxMipmapLevel = level; }
// Clamping (from ES 3.0.4, section 3.8 - Texturing). When not immutable,
// the ranges must be guarded.
size_t EffectiveBaseMipmapLevel() const {
if (IsImmutable())
return std::min(mBaseMipmapLevel, mMaxLevelWithCustomImages);
return mBaseMipmapLevel;
}
size_t GetMaxMipmapLevel() const {
// Clamp to [base, levels - 1]
size_t EffectiveMaxMipmapLevel() const {
if (IsImmutable())
return mozilla::clamped(mMaxMipmapLevel, EffectiveBaseMipmapLevel(), mMaxLevelWithCustomImages);
return std::min(mMaxMipmapLevel, mMaxLevelWithCustomImages);
}
bool IsMipmapRangeValid() const;
size_t MaxLevelWithCustomImages() const { return mMaxLevelWithCustomImages; }

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

@ -22,6 +22,7 @@
#include "nsCRTGlue.h"
#include "nsAutoPtr.h"
#include "nsIScriptSecurityManager.h"
#include "nsNullPrincipal.h"
#include "mozilla/Maybe.h"
#include <algorithm>
@ -409,9 +410,19 @@ nsJSON::DecodeInternal(JSContext* cx,
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult rv =
NS_NewInputStreamChannel(getter_AddRefs(jsonChannel), mURI, aStream,
NS_LITERAL_CSTRING("application/json"));
nsresult rv;
nsCOMPtr<nsIPrincipal> nullPrincipal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewInputStreamChannel(getter_AddRefs(jsonChannel),
mURI,
aStream,
nullPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
NS_LITERAL_CSTRING("application/json"));
if (!jsonChannel || NS_FAILED(rv))
return NS_ERROR_FAILURE;

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

@ -36,6 +36,7 @@
#include "nsIContentViewer.h"
#include "nsIXPConnect.h"
#include "nsContentUtils.h"
#include "nsNullPrincipal.h"
#include "nsJSUtils.h"
#include "nsThreadUtils.h"
#include "nsIScriptChannel.h"
@ -427,9 +428,18 @@ nsresult nsJSChannel::Init(nsIURI *aURI)
// and the underlying Input Stream will not be created...
nsCOMPtr<nsIChannel> channel;
nsCOMPtr<nsIPrincipal> nullPrincipal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
// If the resultant script evaluation actually does return a value, we
// treat it as html.
rv = NS_NewInputStreamChannel(getter_AddRefs(channel), aURI, mIOThunk,
rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
aURI,
mIOThunk,
nullPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
NS_LITERAL_CSTRING("text/html"));
if (NS_FAILED(rv)) return rv;

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

@ -21,7 +21,6 @@ interface MediaKeySession : EventTarget {
readonly attribute unrestricted double expiration;
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
readonly attribute Promise<void> closed;
[NewObject, Throws]
@ -31,15 +30,12 @@ interface MediaKeySession : EventTarget {
Promise<boolean> load(DOMString sessionId);
// session operations
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
[NewObject, Throws]
Promise<void> update((ArrayBufferView or ArrayBuffer) response);
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
[NewObject, Throws]
Promise<void> close();
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
[NewObject, Throws]
Promise<void> remove();

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

@ -20,7 +20,6 @@ interface MediaKeys {
[NewObject, Throws]
MediaKeySession createSession(optional SessionType sessionType = "temporary");
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
[NewObject, Throws]
Promise<void> setServerCertificate((ArrayBufferView or ArrayBuffer) serverCertificate);

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

@ -342,6 +342,11 @@ interface WebGL2RenderingContext : WebGLRenderingContext
void texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
void texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height,
GLsizei depth);
[Throws]
void texImage3D(GLenum target, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format,
GLenum type, ArrayBufferView? pixels);
[Throws] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
ArrayBufferView? pixels);

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

@ -72,6 +72,11 @@ nsresult
nsHTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
{
nsHTMLEditor* htmlEditor = GetHTMLEditor();
// Contenteditable should disregard mousedowns outside it.
// IsAcceptableInputEvent() checks it for a mouse event.
if (!htmlEditor->IsAcceptableInputEvent(aMouseEvent)) {
return NS_OK;
}
// Detect only "context menu" click
// XXX This should be easier to do!
@ -93,11 +98,6 @@ nsHTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
NS_ENSURE_TRUE(target, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
// Contenteditable should disregard mousedowns outside it
if (element && !htmlEditor->IsDescendantOfEditorRoot(element)) {
return NS_OK;
}
if (isContextClick || (buttonNumber == 0 && clickCount == 2)) {
nsCOMPtr<nsISelection> selection;
mEditor->GetSelection(getter_AddRefs(selection));

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

@ -17,6 +17,7 @@
#include "nsIStandardURL.h"
#include "nsMimeTypes.h"
#include "nsNetUtil.h"
#include "nsNullPrincipal.h"
#include "mozilla/Monitor.h"
#include <gio/gio.h>
#include <algorithm>
@ -1062,11 +1063,18 @@ nsGIOProtocolHandler::NewChannel(nsIURI *aURI, nsIChannel **aResult)
}
else
{
nsCOMPtr<nsIPrincipal> nullPrincipal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
// start out assuming an unknown content-type. we'll set the content-type
// to something better once we open the URI.
rv = NS_NewInputStreamChannel(aResult,
aURI,
stream,
nullPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE));
if (NS_SUCCEEDED(rv))
stream->SetChannel(*aResult);

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

@ -548,11 +548,12 @@ Factory::SetDirect3D10Device(ID3D10Device1 *aDevice)
ID3D10Device1*
Factory::GetDirect3D10Device()
{
#ifdef DEBUG
UINT mode = mD3D10Device->GetExceptionMode();
MOZ_ASSERT(0 == mode);
if (mD3D10Device) {
UINT mode = mD3D10Device->GetExceptionMode();
MOZ_ASSERT(0 == mode);
}
#endif
return mD3D10Device;
}

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

@ -17,8 +17,3 @@ endif
include $(topsrcdir)/config/rules.mk
# We have to filter out -pedantic, because of
# comma-at-end-of-enumerator list failures. We can try to get this fixed
# upstream at some point.
CXXFLAGS := $(filter-out -pedantic,$(CXXFLAGS))
CFLAGS := $(filter-out -pedantic,$(CFLAGS))

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

@ -1253,7 +1253,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
if (IsSupported(GLFeature::texture_3D)) {
SymLoadStruct coreSymbols[] = {
// TexImage3D is not required for WebGL2 so not queried here.
{ (PRFuncPtr*) &mSymbols.fTexImage3D, { "TexImage3D", nullptr } },
{ (PRFuncPtr*) &mSymbols.fTexSubImage3D, { "TexSubImage3D", nullptr } },
END_SYMBOLS
};

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

@ -3132,6 +3132,21 @@ public:
// -----------------------------------------------------------------------------
// 3D Textures
void fTexImage3D(GLenum target, GLint level,
GLint internalFormat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
const GLvoid * data)
{
BEFORE_GL_CALL;
ASSERT_SYMBOL_PRESENT(fTexImage3D);
mSymbols.fTexImage3D(target, level, internalFormat,
width, height, depth,
border, format, type,
data);
AFTER_GL_CALL;
}
void fTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type, const GLvoid* pixels)

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

@ -642,6 +642,12 @@ struct GLContextSymbols
PFNGLGETFRAGDATALOCATIONPROC fGetFragDataLocation;
// 3D Textures
typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level,
GLenum internalFormat,
GLenum width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
const GLvoid* pixels);
PFNGLTEXIMAGE3DPROC fTexImage3D;
typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset,
GLint yoffset, GLint zoffset, GLsizei width,
GLsizei height, GLsizei depth, GLenum format,

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

@ -369,17 +369,16 @@ gfxSVGGlyphsDocument::ParseDocument(const uint8_t *aBuffer, uint32_t aBufLen)
}
nsCOMPtr<nsIChannel> channel;
rv = NS_NewInputStreamChannel(getter_AddRefs(channel), uri, nullptr /* stream */,
SVG_CONTENT_TYPE, UTF8_CHARSET);
rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
uri,
nullptr, //aStream
principal,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER,
SVG_CONTENT_TYPE,
UTF8_CHARSET);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(principal,
nullptr,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER);
channel->SetLoadInfo(loadInfo);
// Set this early because various decisions during page-load depend on it.
document->SetIsBeingUsedAsImage();
document->SetReadyStateInternal(nsIDocument::READYSTATE_UNINITIALIZED);

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

@ -413,7 +413,7 @@ gfxUserFontEntry::LoadNextSrc()
mItalic);
mFontSet->SetLocalRulesUsed();
if (fe) {
LOG(("fontset (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n",
LOG(("userfonts (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n",
mFontSet, mSrcIndex,
NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(),
NS_ConvertUTF16toUTF8(mFamilyName).get(),
@ -430,7 +430,7 @@ gfxUserFontEntry::LoadNextSrc()
SetLoadState(STATUS_LOADED);
return;
} else {
LOG(("fontset (%p) [src %d] failed local: (%s) for (%s)\n",
LOG(("userfonts (%p) [src %d] failed local: (%s) for (%s)\n",
mFontSet, mSrcIndex,
NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(),
NS_ConvertUTF16toUTF8(mFamilyName).get()));
@ -647,7 +647,7 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength)
nsAutoCString fontURI;
mSrcList[mSrcIndex].mURI->GetSpec(fontURI);
LOG(("userfonts (%p) [src %d] loaded uri: (%s) for (%s) gen: %8.8x\n",
this, mSrcIndex, fontURI.get(),
mFontSet, mSrcIndex, fontURI.get(),
NS_ConvertUTF16toUTF8(mFamilyName).get(),
uint32_t(mFontSet->mGeneration)));
}
@ -662,7 +662,7 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength)
mSrcList[mSrcIndex].mURI->GetSpec(fontURI);
LOG(("userfonts (%p) [src %d] failed uri: (%s) for (%s)"
" error making platform font\n",
this, mSrcIndex, fontURI.get(),
mFontSet, mSrcIndex, fontURI.get(),
NS_ConvertUTF16toUTF8(mFamilyName).get()));
}
#endif

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

@ -467,6 +467,10 @@ public:
mLocalRulesUsed = true;
}
#ifdef PR_LOGGING
static PRLogModuleInfo* GetUserFontsLog();
#endif
protected:
// Protected destructor, to discourage deletion outside of Release():
virtual ~gfxUserFontSet();
@ -512,8 +516,6 @@ protected:
// true when local names have been looked up, false otherwise
bool mLocalRulesUsed;
static PRLogModuleInfo* GetUserFontsLog();
};
// acts a placeholder until the real font is downloaded

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

@ -12,6 +12,7 @@
#include "nsIconChannel.h"
#include "nsIStringStream.h"
#include "nsNetUtil.h"
#include "nsNullPrincipal.h"
NS_IMPL_ISUPPORTS(nsIconChannel,
nsIRequest,
@ -102,7 +103,16 @@ moz_icon_to_channel(nsIURI *aURI, const nsACString& aFileExt, uint32_t aIconSize
rv = stream->AdoptData((char*)buf, buf_size);
NS_ENSURE_SUCCESS(rv, rv);
return NS_NewInputStreamChannel(aChannel, aURI, stream,
nsCOMPtr<nsIPrincipal> nullPrincipal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
return NS_NewInputStreamChannel(aChannel,
aURI,
stream,
nullPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
NS_LITERAL_CSTRING(IMAGE_ICON_MS));
}

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

@ -33,6 +33,7 @@ extern "C" {
#include "nsIStringBundle.h"
#include "nsNetUtil.h"
#include "nsNullPrincipal.h"
#include "nsIURL.h"
#include "prlink.h"
@ -137,9 +138,17 @@ moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI *aURI,
MOZ_ASSERT(NS_SUCCEEDED(rv));
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewInputStreamChannel(aChannel, aURI, stream,
NS_LITERAL_CSTRING(IMAGE_ICON_MS));
return rv;
nsCOMPtr<nsIPrincipal> nullPrincipal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
return NS_NewInputStreamChannel(aChannel,
aURI,
stream,
nullPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
NS_LITERAL_CSTRING(IMAGE_ICON_MS));
}
static GtkWidget *gProtoWindow = nullptr;

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

@ -16,6 +16,7 @@
#include "nsIStringBundle.h"
#include "nsNetUtil.h"
#include "nsNullPrincipal.h"
#include "nsIURL.h"
#include "nsIconChannel.h"
@ -83,7 +84,16 @@ moz_qicon_to_channel(QImage *image, nsIURI *aURI,
rv = stream->AdoptData((char*)buf, buf_size);
NS_ENSURE_SUCCESS(rv, rv);
return NS_NewInputStreamChannel(aChannel, aURI, stream,
nsCOMPtr<nsIPrincipal> nullPrincipal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
return NS_NewInputStreamChannel(aChannel,
aURI,
stream,
nullPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
NS_LITERAL_CSTRING(IMAGE_ICON_MS));
}

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

@ -125,6 +125,9 @@ MessageLoop::MessageLoop(Type type)
pump_ = new mozilla::ipc::MessagePumpForNonMainUIThreads();
return;
#endif
default:
// Create one of Chromium's standard MessageLoop types below.
break;
}
#if defined(OS_WIN)

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

@ -102,8 +102,8 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
}
bool RecvGetPropertyKeys(const uint64_t &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names) {
return Answer::RecvGetPropertyKeys(ObjectId::deserialize(objId), flags, rs, names);
ReturnStatus *rs, nsTArray<JSIDVariant> *ids) {
return Answer::RecvGetPropertyKeys(ObjectId::deserialize(objId), flags, rs, ids);
}
bool RecvInstanceOf(const uint64_t &objId, const JSIID &iid,
ReturnStatus *rs, bool *instanceof) {
@ -200,8 +200,8 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
}
bool SendGetPropertyKeys(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names) {
return Base::SendGetPropertyKeys(objId.serialize(), flags, rs, names);
ReturnStatus *rs, nsTArray<JSIDVariant> *ids) {
return Base::SendGetPropertyKeys(objId.serialize(), flags, rs, ids);
}
bool SendInstanceOf(const ObjectId &objId, const JSIID &iid,
ReturnStatus *rs, bool *instanceof) {

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

@ -440,7 +440,8 @@ JavaScriptShared::toSymbolVariant(JSContext *cx, JS::Symbol *symArg, SymbolVaria
*symVarp = RegisteredSymbol(autoStr);
return true;
}
MOZ_CRASH("unique symbols not yet implemented");
JS_ReportError(cx, "unique symbol can't be used with CPOW");
return false;
}

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

@ -42,7 +42,7 @@ both:
prio(high) sync ClassName(uint64_t objId) returns (nsString name);
prio(high) sync RegExpToShared(uint64_t objId) returns (ReturnStatus rs, nsString source, uint32_t flags);
prio(high) sync GetPropertyKeys(uint64_t objId, uint32_t flags) returns (ReturnStatus rs, nsString[] names);
prio(high) sync GetPropertyKeys(uint64_t objId, uint32_t flags) returns (ReturnStatus rs, JSIDVariant[] ids);
prio(high) sync InstanceOf(uint64_t objId, JSIID iid) returns (ReturnStatus rs, bool instanceof);
prio(high) sync DOMInstanceOf(uint64_t objId, int prototypeID, int depth) returns (ReturnStatus rs, bool instanceof);

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

@ -580,7 +580,7 @@ WrapperAnswer::RecvRegExpToShared(const ObjectId &objId, ReturnStatus *rs,
bool
WrapperAnswer::RecvGetPropertyKeys(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names)
ReturnStatus *rs, nsTArray<JSIDVariant> *ids)
{
AutoSafeJSContext cx;
JSAutoRequest request(cx);
@ -598,11 +598,11 @@ WrapperAnswer::RecvGetPropertyKeys(const ObjectId &objId, const uint32_t &flags,
return fail(cx, rs);
for (size_t i = 0; i < props.length(); i++) {
nsString name;
if (!convertIdToGeckoString(cx, props[i], &name))
JSIDVariant id;
if (!toJSIDVariant(cx, props[i], &id))
return fail(cx, rs);
names->AppendElement(name);
ids->AppendElement(id);
}
return ok(rs);

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

@ -55,7 +55,7 @@ class WrapperAnswer : public virtual JavaScriptShared
bool RecvRegExpToShared(const ObjectId &objId, ReturnStatus *rs, nsString *source, uint32_t *flags);
bool RecvGetPropertyKeys(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names);
ReturnStatus *rs, nsTArray<JSIDVariant> *ids);
bool RecvInstanceOf(const ObjectId &objId, const JSIID &iid,
ReturnStatus *rs, bool *instanceof);
bool RecvDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth,

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

@ -63,9 +63,6 @@ class CPOWProxyHandler : public BaseProxyHandler
return false;
}
virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
@ -74,18 +71,21 @@ class CPOWProxyHandler : public BaseProxyHandler
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE;
virtual bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, bool strict, JS::MutableHandleValue vp) const MOZ_OVERRIDE;
virtual bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;
virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy,
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool hasInstance(JSContext *cx, HandleObject proxy,
MutableHandleValue v, bool *bp) const MOZ_OVERRIDE;
virtual bool objectClassIs(HandleObject obj, js::ESClassValue classValue,
@ -232,7 +232,7 @@ CPOWProxyHandler::ownPropertyKeys(JSContext *cx, HandleObject proxy,
bool
WrapperOwner::ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
{
return getPropertyKeys(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN, props);
return getPropertyKeys(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props);
}
bool
@ -463,13 +463,14 @@ WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiv
}
bool
CPOWProxyHandler::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const
CPOWProxyHandler::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy,
AutoIdVector &props) const
{
FORWARD(keys, (cx, proxy, props));
FORWARD(getOwnEnumerablePropertyKeys, (cx, proxy, props));
}
bool
WrapperOwner::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
WrapperOwner::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
{
return getPropertyKeys(cx, proxy, JSITER_OWNONLY, props);
}
@ -776,8 +777,8 @@ WrapperOwner::getPropertyKeys(JSContext *cx, HandleObject proxy, uint32_t flags,
ObjectId objId = idOf(proxy);
ReturnStatus status;
InfallibleTArray<nsString> names;
if (!SendGetPropertyKeys(objId, flags, &status, &names))
InfallibleTArray<JSIDVariant> ids;
if (!SendGetPropertyKeys(objId, flags, &status, &ids))
return ipcfail(cx);
LOG_STACK();
@ -785,11 +786,11 @@ WrapperOwner::getPropertyKeys(JSContext *cx, HandleObject proxy, uint32_t flags,
if (!ok(cx, status))
return false;
for (size_t i = 0; i < names.Length(); i++) {
RootedId name(cx);
if (!convertGeckoStringToId(cx, names[i], &name))
for (size_t i = 0; i < ids.Length(); i++) {
RootedId id(cx);
if (!fromJSIDVariant(cx, ids[i], &id))
return false;
if (!props.append(name))
if (!props.append(id))
return false;
}

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

@ -31,11 +31,8 @@ class WrapperOwner : public virtual JavaScriptShared
explicit WrapperOwner(JSRuntime *rt);
bool init();
// Fundamental proxy traps. These are required.
// Standard internal methods.
// (The traps should be in the same order like js/src/jsproxy.h)
bool preventExtensions(JSContext *cx, JS::HandleObject proxy);
bool getPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
bool getOwnPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
@ -43,25 +40,27 @@ class WrapperOwner : public virtual JavaScriptShared
bool ownPropertyKeys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool enumerate(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
// Derived proxy traps. Implementing these is useful for perfomance.
bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible);
bool preventExtensions(JSContext *cx, JS::HandleObject proxy);
bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool hasOwn(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool get(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, JS::MutableHandleValue vp);
bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, bool strict, JS::MutableHandleValue vp);
bool keys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
// We use "iterate" provided by the base class here.
// SpiderMonkey Extensions.
bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible);
bool regexp_toShared(JSContext *cx, JS::HandleObject proxy, js::RegExpGuard *g);
bool callOrConstruct(JSContext *cx, JS::HandleObject proxy, const JS::CallArgs &args,
bool construct);
// SpiderMonkey extensions.
bool getPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
bool hasOwn(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::HandleObject proxy,
JS::AutoIdVector &props);
// We use "iterate" provided by the base class here.
bool hasInstance(JSContext *cx, JS::HandleObject proxy, JS::MutableHandleValue v, bool *bp);
bool objectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue);
const char* className(JSContext *cx, JS::HandleObject proxy);
bool regexp_toShared(JSContext *cx, JS::HandleObject proxy, js::RegExpGuard *g);
bool isCallable(JSObject *obj);
bool isConstructor(JSObject *obj);
@ -146,7 +145,7 @@ class WrapperOwner : public virtual JavaScriptShared
uint32_t *flags) = 0;
virtual bool SendGetPropertyKeys(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names) = 0;
ReturnStatus *rs, nsTArray<JSIDVariant> *ids) = 0;
virtual bool SendInstanceOf(const ObjectId &objId, const JSIID &iid,
ReturnStatus *rs, bool *instanceof) = 0;
virtual bool SendDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth,

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

@ -315,6 +315,7 @@ selfhosting_srcs := \
$(srcdir)/builtin/Array.js \
$(srcdir)/builtin/Date.js \
$(srcdir)/builtin/Error.js \
$(srcdir)/builtin/Generator.js \
$(srcdir)/builtin/Intl.js \
$(srcdir)/builtin/IntlData.js \
$(srcdir)/builtin/Iterator.js \

104
js/src/builtin/Generator.js Normal file
Просмотреть файл

@ -0,0 +1,104 @@
/* 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/. */
function StarGeneratorNext(val) {
if (!IsObject(this) || !IsStarGeneratorObject(this))
return callFunction(CallStarGeneratorMethodIfWrapped, this, val, "StarGeneratorNext");
if (StarGeneratorObjectIsClosed(this))
return { value: undefined, done: true };
if (GeneratorIsRunning(this))
ThrowError(JSMSG_NESTING_GENERATOR);
try {
return resumeGenerator(this, val, 'next');
} catch (e) {
if (!StarGeneratorObjectIsClosed(this))
GeneratorSetClosed(this);
throw e;
}
}
function StarGeneratorThrow(val) {
if (!IsObject(this) || !IsStarGeneratorObject(this))
return callFunction(CallStarGeneratorMethodIfWrapped, this, val, "StarGeneratorThrow");
if (StarGeneratorObjectIsClosed(this))
throw val;
if (GeneratorIsRunning(this))
ThrowError(JSMSG_NESTING_GENERATOR);
try {
return resumeGenerator(this, val, 'throw');
} catch (e) {
if (!StarGeneratorObjectIsClosed(this))
GeneratorSetClosed(this);
throw e;
}
}
function LegacyGeneratorNext(val) {
if (!IsObject(this) || !IsLegacyGeneratorObject(this))
return callFunction(CallLegacyGeneratorMethodIfWrapped, this, val, "LegacyGeneratorNext");
if (LegacyGeneratorObjectIsClosed(this))
ThrowStopIteration();
if (GeneratorIsRunning(this))
ThrowError(JSMSG_NESTING_GENERATOR);
try {
return resumeGenerator(this, val, 'next');
} catch(e) {
if (!LegacyGeneratorObjectIsClosed(this))
GeneratorSetClosed(this);
throw e;
}
}
function LegacyGeneratorThrow(val) {
if (!IsObject(this) || !IsLegacyGeneratorObject(this))
return callFunction(CallLegacyGeneratorMethodIfWrapped, this, val, "LegacyGeneratorThrow");
if (LegacyGeneratorObjectIsClosed(this))
throw val;
if (GeneratorIsRunning(this))
ThrowError(JSMSG_NESTING_GENERATOR);
try {
return resumeGenerator(this, val, 'throw');
} catch(e) {
if (!LegacyGeneratorObjectIsClosed(this))
GeneratorSetClosed(this);
throw e;
}
}
// Called by js::CloseIterator.
function LegacyGeneratorCloseInternal() {
assert(IsObject(this), "Not an object: " + ToString(this));
assert(IsLegacyGeneratorObject(this), "Not a legacy generator object: " + ToString(this));
assert(!LegacyGeneratorObjectIsClosed(this), "Already closed: " + ToString(this));
assert(!CloseNewbornLegacyGeneratorObject(this), "Newborn: " + ToString(this));
if (GeneratorIsRunning(this))
ThrowError(JSMSG_NESTING_GENERATOR);
resumeGenerator(this, undefined, 'close');
if (!LegacyGeneratorObjectIsClosed(this))
CloseClosingLegacyGeneratorObject(this);
}
function LegacyGeneratorClose() {
if (!IsObject(this) || !IsLegacyGeneratorObject(this))
return callFunction(CallLegacyGeneratorMethodIfWrapped, this, "LegacyGeneratorClose");
if (LegacyGeneratorObjectIsClosed(this) || CloseNewbornLegacyGeneratorObject(this))
return;
callFunction(LegacyGeneratorCloseInternal, this);
}

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

@ -1294,7 +1294,6 @@ if test "$GNU_CXX"; then
# -Wwrite-strings - catches non-const char* pointers to string literals
#
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wignored-qualifiers"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wsign-compare"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wtype-limits"
@ -1303,6 +1302,7 @@ if test "$GNU_CXX"; then
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=comment"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=empty-body"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=endif-labels"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=ignored-qualifiers"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=int-to-pointer-cast"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=missing-braces"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=overloaded-virtual"

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

@ -2625,8 +2625,8 @@ ImplicitConvert(JSContext* cx,
if (val.isObject() && !sourceData) {
// Enumerate the properties of the object; if they match the struct
// specification, convert the fields.
RootedObject iter(cx, JS_NewPropertyIterator(cx, valObj));
if (!iter)
AutoIdArray props(cx, JS_Enumerate(cx, valObj));
if (!props)
return false;
// Convert into an intermediate, in case of failure.
@ -2637,13 +2637,15 @@ ImplicitConvert(JSContext* cx,
return false;
}
const FieldInfoHash* fields = StructType::GetFieldInfo(targetType);
if (props.length() != fields->count()) {
JS_ReportError(cx, "missing fields");
return false;
}
RootedId id(cx);
size_t i = 0;
while (1) {
if (!JS_NextProperty(cx, iter, &id))
return false;
if (JSID_IS_VOID(id))
break;
for (size_t i = 0; i < props.length(); ++i) {
id = props[i];
if (!JSID_IS_STRING(id)) {
JS_ReportError(cx, "property name is not a string");
@ -2663,14 +2665,6 @@ ImplicitConvert(JSContext* cx,
char* fieldData = intermediate.get() + field->mOffset;
if (!ImplicitConvert(cx, prop, field->mType, fieldData, false, nullptr))
return false;
++i;
}
const FieldInfoHash* fields = StructType::GetFieldInfo(targetType);
if (i != fields->count()) {
JS_ReportError(cx, "missing fields");
return false;
}
memcpy(buffer, intermediate.get(), structSize);
@ -4705,33 +4699,23 @@ ExtractStructField(JSContext* cx, jsval val, MutableHandleObject typeObj)
return nullptr;
}
RootedObject obj(cx, val.toObjectOrNull());
RootedObject iter(cx, JS_NewPropertyIterator(cx, obj));
if (!iter)
RootedObject obj(cx, &val.toObject());
AutoIdArray props(cx, JS_Enumerate(cx, obj));
if (!props)
return nullptr;
RootedId nameid(cx);
if (!JS_NextProperty(cx, iter, &nameid))
return nullptr;
if (JSID_IS_VOID(nameid)) {
JS_ReportError(cx, "struct field descriptors require a valid name and type");
return nullptr;
}
if (!JSID_IS_STRING(nameid)) {
JS_ReportError(cx, "struct field descriptors require a valid name and type");
return nullptr;
}
// make sure we have one, and only one, property
RootedId id(cx);
if (!JS_NextProperty(cx, iter, &id))
return nullptr;
if (!JSID_IS_VOID(id)) {
if (props.length() != 1) {
JS_ReportError(cx, "struct field descriptors must contain one property");
return nullptr;
}
RootedId nameid(cx, props[0]);
if (!JSID_IS_STRING(nameid)) {
JS_ReportError(cx, "struct field descriptors require a valid name and type");
return nullptr;
}
RootedValue propVal(cx);
if (!JS_GetPropertyById(cx, obj, nameid, &propVal))
return nullptr;

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

@ -31,6 +31,7 @@
#include "frontend/Parser.h"
#include "frontend/TokenStream.h"
#include "vm/Debugger.h"
#include "vm/GeneratorObject.h"
#include "vm/Stack.h"
#include "jsatominlines.h"
@ -1989,10 +1990,10 @@ CheckSideEffects(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool
default:
/*
* All of PNK_INC, PNK_DEC, PNK_THROW, PNK_YIELD, and PNK_YIELD_STAR
* have direct effects. Of the remaining unary-arity node types, we
* can't easily prove that the operand never denotes an object with
* a toString or valueOf method.
* All of PNK_INC, PNK_DEC and PNK_THROW have direct effects. Of
* the remaining unary-arity node types, we can't easily prove that
* the operand never denotes an object with a toString or valueOf
* method.
*/
*answer = true;
return true;
@ -2973,13 +2974,6 @@ frontend::EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNo
bce->switchToMain();
}
if (funbox->isGenerator()) {
bce->switchToProlog();
if (Emit1(cx, bce, JSOP_GENERATOR) < 0)
return false;
bce->switchToMain();
}
/*
* Emit a prologue for run-once scripts which will deoptimize JIT code if
* the script ends up running multiple times via foo.caller related
@ -2996,18 +2990,27 @@ frontend::EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNo
if (!EmitTree(cx, bce, body))
return false;
// If we fall off the end of an ES6 generator, return a boxed iterator
// result object of the form { value: undefined, done: true }.
if (bce->sc->isFunctionBox() && bce->sc->asFunctionBox()->isStarGenerator()) {
if (!EmitPrepareIteratorResult(cx, bce))
// If we fall off the end of a generator, do a final yield.
if (bce->sc->isFunctionBox() && bce->sc->asFunctionBox()->isGenerator()) {
if (bce->sc->asFunctionBox()->isStarGenerator() && !EmitPrepareIteratorResult(cx, bce))
return false;
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
return false;
if (!EmitFinishIteratorResult(cx, bce, true))
if (bce->sc->asFunctionBox()->isStarGenerator() && !EmitFinishIteratorResult(cx, bce, true))
return false;
ScopeCoordinate sc;
// We know that .generator is on the top scope chain node, as we are
// at the function end.
sc.setHops(0);
MOZ_ALWAYS_TRUE(LookupAliasedNameSlot(bce, bce->script, cx->names().dotGenerator, &sc));
if (!EmitAliasedVarOp(cx, JSOP_GETALIASEDVAR, sc, DontCheckLexical, bce))
return false;
// No need to check for finally blocks, etc as in EmitReturn.
if (Emit1(cx, bce, JSOP_RETURN) < 0)
if (Emit1(cx, bce, JSOP_FINALYIELD) < 0)
return false;
}
@ -5463,15 +5466,26 @@ EmitReturn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
*/
ptrdiff_t top = bce->offset();
if (Emit1(cx, bce, JSOP_RETURN) < 0)
return false;
bool isGenerator = bce->sc->isFunctionBox() && bce->sc->asFunctionBox()->isGenerator();
if (Emit1(cx, bce, isGenerator ? JSOP_SETRVAL : JSOP_RETURN) < 0)
return false;
NonLocalExitScope nle(cx, bce);
if (!nle.prepareForNonLocalJump(nullptr))
return false;
if (top + static_cast<ptrdiff_t>(JSOP_RETURN_LENGTH) != bce->offset()) {
if (isGenerator) {
ScopeCoordinate sc;
// We know that .generator is on the top scope chain node, as we just
// exited nested scopes.
sc.setHops(0);
MOZ_ALWAYS_TRUE(LookupAliasedNameSlot(bce, bce->script, cx->names().dotGenerator, &sc));
if (!EmitAliasedVarOp(cx, JSOP_GETALIASEDVAR, sc, DontCheckLexical, bce))
return false;
if (Emit1(cx, bce, JSOP_FINALYIELDRVAL) < 0)
return false;
} else if (top + static_cast<ptrdiff_t>(JSOP_RETURN_LENGTH) != bce->offset()) {
bce->code()[top] = JSOP_SETRVAL;
if (Emit1(cx, bce, JSOP_RETRVAL) < 0)
return false;
@ -5481,7 +5495,41 @@ EmitReturn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
}
static bool
EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
EmitYield(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
MOZ_ASSERT(bce->sc->isFunctionBox());
if (pn->getOp() == JSOP_YIELD) {
if (bce->sc->asFunctionBox()->isStarGenerator()) {
if (!EmitPrepareIteratorResult(cx, bce))
return false;
}
if (pn->pn_left) {
if (!EmitTree(cx, bce, pn->pn_left))
return false;
} else {
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
return false;
}
if (bce->sc->asFunctionBox()->isStarGenerator()) {
if (!EmitFinishIteratorResult(cx, bce, false))
return false;
}
} else {
MOZ_ASSERT(pn->getOp() == JSOP_INITIALYIELD);
}
if (!EmitTree(cx, bce, pn->pn_right))
return false;
if (Emit1(cx, bce, pn->getOp()) < 0)
return false;
return true;
}
static bool
EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter, ParseNode *gen)
{
MOZ_ASSERT(bce->sc->isFunctionBox());
MOZ_ASSERT(bce->sc->asFunctionBox()->isStarGenerator());
@ -5500,12 +5548,13 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
return false;
CheckTypeSet(cx, bce, JSOP_CALL);
int depth = bce->stackDepth;
MOZ_ASSERT(depth >= 1);
// Initial send value is undefined.
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0) // ITER RECEIVED
return false;
int depth = bce->stackDepth;
MOZ_ASSERT(depth >= 2);
ptrdiff_t initialSend = -1;
if (EmitBackPatchOp(cx, bce, &initialSend) < 0) // goto initialSend
return false;
@ -5514,17 +5563,21 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
StmtInfoBCE stmtInfo(cx);
PushStatementBCE(bce, &stmtInfo, STMT_TRY, bce->offset());
ptrdiff_t noteIndex = NewSrcNote(cx, bce, SRC_TRY);
ptrdiff_t tryStart = bce->offset(); // tryStart:
if (noteIndex < 0 || Emit1(cx, bce, JSOP_TRY) < 0)
return false;
ptrdiff_t tryStart = bce->offset(); // tryStart:
MOZ_ASSERT(bce->stackDepth == depth + 1);
MOZ_ASSERT(bce->stackDepth == depth);
// Load the generator object.
if (!EmitTree(cx, bce, gen)) // ITER RESULT GENOBJ
return false;
// Yield RESULT as-is, without re-boxing.
if (Emit1(cx, bce, JSOP_YIELD) < 0) // ITER RECEIVED
return false;
// Try epilogue.
if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, bce->offset() - tryStart + JSOP_TRY_LENGTH))
if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, bce->offset() - tryStart))
return false;
ptrdiff_t subsequentSend = -1;
if (EmitBackPatchOp(cx, bce, &subsequentSend) < 0) // goto subsequentSend
@ -5532,8 +5585,10 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
ptrdiff_t tryEnd = bce->offset(); // tryEnd:
// Catch location.
// THROW? = 'throw' in ITER // ITER
bce->stackDepth = (uint32_t) depth;
bce->stackDepth = uint32_t(depth); // ITER RESULT
if (Emit1(cx, bce, JSOP_POP) < 0) // ITER
return false;
// THROW? = 'throw' in ITER
if (Emit1(cx, bce, JSOP_EXCEPTION) < 0) // ITER EXCEPTION
return false;
if (Emit1(cx, bce, JSOP_SWAP) < 0) // EXCEPTION ITER
@ -5557,7 +5612,7 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
SetJumpOffsetAt(bce, checkThrow); // delegate:
// RESULT = ITER.throw(EXCEPTION) // EXCEPTION ITER
bce->stackDepth = (uint32_t) depth + 1;
bce->stackDepth = uint32_t(depth);
if (Emit1(cx, bce, JSOP_DUP) < 0) // EXCEPTION ITER ITER
return false;
if (Emit1(cx, bce, JSOP_DUP) < 0) // EXCEPTION ITER ITER ITER
@ -5571,7 +5626,7 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
if (EmitCall(cx, bce, JSOP_CALL, 1, iter) < 0) // ITER RESULT
return false;
CheckTypeSet(cx, bce, JSOP_CALL);
MOZ_ASSERT(bce->stackDepth == depth + 1);
MOZ_ASSERT(bce->stackDepth == depth);
ptrdiff_t checkResult = -1;
if (EmitBackPatchOp(cx, bce, &checkResult) < 0) // goto checkResult
return false;
@ -5582,7 +5637,7 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
// This is a peace offering to ReconstructPCStack. See the note in EmitTry.
if (Emit1(cx, bce, JSOP_NOP) < 0)
return false;
if (!bce->tryNoteList.append(JSTRY_CATCH, depth, tryStart, tryEnd))
if (!bce->tryNoteList.append(JSTRY_CATCH, depth, tryStart + JSOP_TRY_LENGTH, tryEnd))
return false;
// After the try/catch block: send the received value to the iterator.
@ -5608,7 +5663,7 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
if (EmitCall(cx, bce, JSOP_CALL, 1, iter) < 0) // ITER RESULT
return false;
CheckTypeSet(cx, bce, JSOP_CALL);
MOZ_ASSERT(bce->stackDepth == depth + 1);
MOZ_ASSERT(bce->stackDepth == depth);
if (!BackPatch(cx, bce, checkResult, bce->code().end(), JSOP_GOTO)) // checkResult:
return false;
@ -5629,7 +5684,7 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
if (!EmitAtomOp(cx, cx->names().value, JSOP_GETPROP, bce)) // VALUE
return false;
MOZ_ASSERT(bce->stackDepth == depth);
MOZ_ASSERT(bce->stackDepth == depth - 1);
return true;
}
@ -5807,6 +5862,80 @@ EmitDelete(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
static bool
EmitArray(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, uint32_t count);
static bool
EmitSelfHostedCallFunction(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
// Special-casing of callFunction to emit bytecode that directly
// invokes the callee with the correct |this| object and arguments.
// callFunction(fun, thisArg, arg0, arg1) thus becomes:
// - emit lookup for fun
// - emit lookup for thisArg
// - emit lookups for arg0, arg1
//
// argc is set to the amount of actually emitted args and the
// emitting of args below is disabled by setting emitArgs to false.
if (pn->pn_count < 3) {
bce->reportError(pn, JSMSG_MORE_ARGS_NEEDED, "callFunction", "1", "s");
return false;
}
ParseNode *pn2 = pn->pn_head;
ParseNode *funNode = pn2->pn_next;
if (!EmitTree(cx, bce, funNode))
return false;
ParseNode *thisArg = funNode->pn_next;
if (!EmitTree(cx, bce, thisArg))
return false;
bool oldEmittingForInit = bce->emittingForInit;
bce->emittingForInit = false;
for (ParseNode *argpn = thisArg->pn_next; argpn; argpn = argpn->pn_next) {
if (!EmitTree(cx, bce, argpn))
return false;
}
bce->emittingForInit = oldEmittingForInit;
uint32_t argc = pn->pn_count - 3;
if (EmitCall(cx, bce, pn->getOp(), argc) < 0)
return false;
CheckTypeSet(cx, bce, pn->getOp());
return true;
}
static bool
EmitSelfHostedResumeGenerator(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
// Syntax: resumeGenerator(gen, value, 'next'|'throw'|'close')
if (pn->pn_count != 4) {
bce->reportError(pn, JSMSG_MORE_ARGS_NEEDED, "resumeGenerator", "1", "s");
return false;
}
ParseNode *funNode = pn->pn_head; // The resumeGenerator node.
ParseNode *genNode = funNode->pn_next;
if (!EmitTree(cx, bce, genNode))
return false;
ParseNode *valNode = genNode->pn_next;
if (!EmitTree(cx, bce, valNode))
return false;
ParseNode *kindNode = valNode->pn_next;
MOZ_ASSERT(kindNode->isKind(PNK_STRING));
uint16_t operand = GeneratorObject::getResumeKind(cx, kindNode->pn_atom);
MOZ_ASSERT(!kindNode->pn_next);
if (EmitCall(cx, bce, JSOP_RESUME, operand) < 0)
return false;
return true;
}
static bool
EmitCallOrNew(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
@ -5835,46 +5964,21 @@ EmitCallOrNew(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
return false;
}
bool emitArgs = true;
ParseNode *pn2 = pn->pn_head;
bool spread = JOF_OPTYPE(pn->getOp()) == JOF_BYTE;
switch (pn2->getKind()) {
case PNK_NAME:
if (bce->emitterMode == BytecodeEmitter::SelfHosting &&
pn2->name() == cx->names().callFunction &&
!spread)
{
/*
* Special-casing of callFunction to emit bytecode that directly
* invokes the callee with the correct |this| object and arguments.
* callFunction(fun, thisArg, arg0, arg1) thus becomes:
* - emit lookup for fun
* - emit lookup for thisArg
* - emit lookups for arg0, arg1
*
* argc is set to the amount of actually emitted args and the
* emitting of args below is disabled by setting emitArgs to false.
*/
if (pn->pn_count < 3) {
bce->reportError(pn, JSMSG_MORE_ARGS_NEEDED, "callFunction", "1", "s");
return false;
}
ParseNode *funNode = pn2->pn_next;
if (!EmitTree(cx, bce, funNode))
return false;
ParseNode *thisArg = funNode->pn_next;
if (!EmitTree(cx, bce, thisArg))
return false;
bool oldEmittingForInit = bce->emittingForInit;
bce->emittingForInit = false;
for (ParseNode *argpn = thisArg->pn_next; argpn; argpn = argpn->pn_next) {
if (!EmitTree(cx, bce, argpn))
return false;
}
bce->emittingForInit = oldEmittingForInit;
argc -= 2;
emitArgs = false;
break;
if (bce->emitterMode == BytecodeEmitter::SelfHosting && !spread) {
// We shouldn't see foo(bar) = x in self-hosted code.
MOZ_ASSERT(!(pn->pn_xflags & PNX_SETCALL));
// Calls to "callFunction" or "resumeGenerator" in self-hosted code
// generate inline bytecode.
if (pn2->name() == cx->names().callFunction)
return EmitSelfHostedCallFunction(cx, bce, pn);
if (pn2->name() == cx->names().resumeGenerator)
return EmitSelfHostedResumeGenerator(cx, bce, pn);
// Fall through.
}
if (!EmitNameOp(cx, bce, pn2, callop))
return false;
@ -5922,25 +6026,23 @@ EmitCallOrNew(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
return false;
}
if (emitArgs) {
/*
* Emit code for each argument in order, then emit the JSOP_*CALL or
* JSOP_NEW bytecode with a two-byte immediate telling how many args
* were pushed on the operand stack.
*/
bool oldEmittingForInit = bce->emittingForInit;
bce->emittingForInit = false;
if (!spread) {
for (ParseNode *pn3 = pn2->pn_next; pn3; pn3 = pn3->pn_next) {
if (!EmitTree(cx, bce, pn3))
return false;
}
} else {
if (!EmitArray(cx, bce, pn2->pn_next, argc))
/*
* Emit code for each argument in order, then emit the JSOP_*CALL or
* JSOP_NEW bytecode with a two-byte immediate telling how many args
* were pushed on the operand stack.
*/
bool oldEmittingForInit = bce->emittingForInit;
bce->emittingForInit = false;
if (!spread) {
for (ParseNode *pn3 = pn2->pn_next; pn3; pn3 = pn3->pn_next) {
if (!EmitTree(cx, bce, pn3))
return false;
}
bce->emittingForInit = oldEmittingForInit;
} else {
if (!EmitArray(cx, bce, pn2->pn_next, argc))
return false;
}
bce->emittingForInit = oldEmittingForInit;
if (!spread) {
if (EmitCall(cx, bce, pn->getOp(), argc, pn) < 0)
@ -6687,28 +6789,16 @@ frontend::EmitTree(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
break;
case PNK_YIELD_STAR:
ok = EmitYieldStar(cx, bce, pn->pn_kid);
ok = EmitYieldStar(cx, bce, pn->pn_left, pn->pn_right);
break;
case PNK_GENERATOR:
if (Emit1(cx, bce, JSOP_GENERATOR) < 0)
return false;
break;
case PNK_YIELD:
MOZ_ASSERT(bce->sc->isFunctionBox());
if (bce->sc->asFunctionBox()->isStarGenerator()) {
if (!EmitPrepareIteratorResult(cx, bce))
return false;
}
if (pn->pn_kid) {
if (!EmitTree(cx, bce, pn->pn_kid))
return false;
} else {
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
return false;
}
if (bce->sc->asFunctionBox()->isStarGenerator()) {
if (!EmitFinishIteratorResult(cx, bce, false))
return false;
}
if (Emit1(cx, bce, JSOP_YIELD) < 0)
return false;
ok = EmitYield(cx, bce, pn);
break;
case PNK_STATEMENTLIST:

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

@ -323,6 +323,17 @@ class FullParseHandler
return true;
}
ParseNode *newYieldExpression(uint32_t begin, ParseNode *value, ParseNode *gen,
JSOp op = JSOP_YIELD) {
TokenPos pos(begin, value ? value->pn_pos.end : begin + 1);
return new_<BinaryNode>(PNK_YIELD, op, pos, value, gen);
}
ParseNode *newYieldStarExpression(uint32_t begin, ParseNode *value, ParseNode *gen) {
TokenPos pos(begin, value->pn_pos.end);
return new_<BinaryNode>(PNK_YIELD_STAR, JSOP_NOP, pos, value, gen);
}
// Statements
ParseNode *newStatementList(unsigned blockid, const TokenPos &pos) {
@ -352,6 +363,31 @@ class FullParseHandler
list->append(stmt);
}
bool prependInitialYield(ParseNode *stmtList, ParseNode *genName) {
MOZ_ASSERT(stmtList->isKind(PNK_STATEMENTLIST));
TokenPos yieldPos(stmtList->pn_pos.begin, stmtList->pn_pos.begin + 1);
ParseNode *makeGen = new_<NullaryNode>(PNK_GENERATOR, yieldPos);
if (!makeGen)
return false;
MOZ_ASSERT(genName->getOp() == JSOP_NAME);
genName->setOp(JSOP_SETNAME);
genName->markAsAssigned();
ParseNode *genInit = newBinary(PNK_ASSIGN, genName, makeGen);
ParseNode *initialYield = newYieldExpression(yieldPos.begin, nullptr, genInit,
JSOP_INITIALYIELD);
if (!initialYield)
return false;
initialYield->pn_next = stmtList->pn_head;
stmtList->pn_head = initialYield;
stmtList->pn_count++;
return true;
}
ParseNode *newEmptyStatement(const TokenPos &pos) {
return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, pos, (ParseNode *) nullptr);
}

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

@ -124,6 +124,7 @@ class UpvarCookie
F(FINALLY) \
F(THROW) \
F(DEBUGGER) \
F(GENERATOR) \
F(YIELD) \
F(YIELD_STAR) \
F(GENEXP) \
@ -422,6 +423,9 @@ enum ParseNodeKind
*
* PNK_LEXICALSCOPE name pn_objbox: block object in ObjectBox holder
* pn_expr: block body
* PNK_GENERATOR nullary
* PNK_YIELD, binary pn_left: expr or null; pn_right: generator object
* PNK_YIELD_STAR
* PNK_ARRAYCOMP list pn_count: 1
* pn_head: list of 1 element, which is block
* enclosing for loop(s) and optionally
@ -773,8 +777,9 @@ class ParseNode
MOZ_ASSERT(isKind(PNK_GENEXP));
ParseNode *callee = this->pn_head;
ParseNode *body = callee->pn_body;
MOZ_ASSERT(body->isKind(PNK_LEXICALSCOPE) || body->isKind(PNK_FOR));
return body;
MOZ_ASSERT(body->isKind(PNK_STATEMENTLIST));
MOZ_ASSERT(body->last()->isKind(PNK_LEXICALSCOPE) || body->last()->isKind(PNK_FOR));
return body->last();
}
#endif

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

@ -1035,6 +1035,23 @@ Parser<ParseHandler>::functionBody(FunctionSyntaxKind kind, FunctionBodyType typ
break;
}
if (pc->isGenerator()) {
MOZ_ASSERT(type == StatementListBody);
Node generator = newName(context->names().dotGenerator);
if (!generator)
return null();
if (!pc->define(tokenStream, context->names().dotGenerator, generator, Definition::VAR))
return null();
generator = newName(context->names().dotGenerator);
if (!generator)
return null();
if (!noteNameUse(context->names().dotGenerator, generator))
return null();
if (!handler.prependInitialYield(pn, generator))
return null();
}
/* Define the 'arguments' binding if necessary. */
if (!checkFunctionArguments())
return null();
@ -5007,6 +5024,21 @@ Parser<ParseHandler>::returnStatement()
return pn;
}
template <typename ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::newYieldExpression(uint32_t begin, typename ParseHandler::Node expr,
bool isYieldStar)
{
Node generator = newName(context->names().dotGenerator);
if (!generator)
return null();
if (!noteNameUse(context->names().dotGenerator, generator))
return null();
if (isYieldStar)
return handler.newYieldStarExpression(begin, expr, generator);
return handler.newYieldExpression(begin, expr, generator);
}
template <typename ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::yieldExpression()
@ -5052,7 +5084,7 @@ Parser<ParseHandler>::yieldExpression()
if (!exprNode)
return null();
}
return handler.newUnary(kind, JSOP_NOP, begin, exprNode);
return newYieldExpression(begin, exprNode, kind == PNK_YIELD_STAR);
}
case NotGenerator:
@ -5110,7 +5142,7 @@ Parser<ParseHandler>::yieldExpression()
return null();
}
return handler.newUnary(PNK_YIELD, JSOP_NOP, begin, exprNode);
return newYieldExpression(begin, exprNode);
}
}
@ -6189,9 +6221,17 @@ LegacyCompExprTransplanter::transplant(ParseNode *pn)
MOZ_ASSERT(!stmt || stmt != pc->topStmt);
#endif
if (isGenexp && !dn->isOp(JSOP_CALLEE)) {
MOZ_ASSERT(!pc->decls().lookupFirst(atom));
MOZ_ASSERT_IF(atom != parser->context->names().dotGenerator,
!pc->decls().lookupFirst(atom));
if (dn->pn_pos < root->pn_pos) {
if (atom == parser->context->names().dotGenerator) {
if (dn->dn_uses == pn) {
if (!BumpStaticLevel(parser->tokenStream, dn, pc))
return false;
if (!AdjustBlockId(parser->tokenStream, dn, adjust, pc))
return false;
}
} else if (dn->pn_pos < root->pn_pos) {
/*
* The variable originally appeared to be a use of a
* definition or placeholder outside the generator, but now
@ -6304,7 +6344,7 @@ LegacyComprehensionHeadBlockScopeDepth(ParseContext<ParseHandler> *pc)
*/
template <>
ParseNode *
Parser<FullParseHandler>::legacyComprehensionTail(ParseNode *bodyStmt, unsigned blockid,
Parser<FullParseHandler>::legacyComprehensionTail(ParseNode *bodyExpr, unsigned blockid,
GeneratorKind comprehensionKind,
ParseContext<FullParseHandler> *outerpc,
unsigned innerBlockScopeDepth)
@ -6368,15 +6408,15 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode *bodyStmt, unsigned
adjust = blockid - adjust;
}
handler.setBeginPosition(pn, bodyStmt);
handler.setBeginPosition(pn, bodyExpr);
pnp = &pn->pn_expr;
LegacyCompExprTransplanter transplanter(bodyStmt, this, outerpc, comprehensionKind, adjust);
LegacyCompExprTransplanter transplanter(bodyExpr, this, outerpc, comprehensionKind, adjust);
if (!transplanter.init())
return null();
if (!transplanter.transplant(bodyStmt))
if (!transplanter.transplant(bodyExpr))
return null();
MOZ_ASSERT(pc->staticScope && pc->staticScope == pn->pn_objbox->object);
@ -6532,6 +6572,23 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode *bodyStmt, unsigned
pnp = &pn2->pn_kid2;
}
ParseNode *bodyStmt;
if (isGenexp) {
ParseNode *yieldExpr = newYieldExpression(bodyExpr->pn_pos.begin, bodyExpr);
if (!yieldExpr)
return null();
yieldExpr->setInParens(true);
bodyStmt = handler.newExprStatement(yieldExpr, bodyExpr->pn_pos.end);
if (!bodyStmt)
return null();
} else {
bodyStmt = handler.newUnary(PNK_ARRAYPUSH, JSOP_ARRAYPUSH,
bodyExpr->pn_pos.begin, bodyExpr);
if (!bodyStmt)
return null();
}
*pnp = bodyStmt;
pc->topStmt->innerBlockScopeDepth += innerBlockScopeDepth;
@ -6568,12 +6625,7 @@ Parser<FullParseHandler>::legacyArrayComprehension(ParseNode *array)
array->pn_tail = &array->pn_head;
*array->pn_tail = nullptr;
ParseNode *arrayPush = handler.newUnary(PNK_ARRAYPUSH, JSOP_ARRAYPUSH,
bodyExpr->pn_pos.begin, bodyExpr);
if (!arrayPush)
return null();
ParseNode *comp = legacyComprehensionTail(arrayPush, array->pn_blockid, NotGenerator,
ParseNode *comp = legacyComprehensionTail(bodyExpr, array->pn_blockid, NotGenerator,
nullptr, LegacyComprehensionHeadBlockScopeDepth(pc));
if (!comp)
return null();
@ -6596,10 +6648,10 @@ Parser<SyntaxParseHandler>::legacyArrayComprehension(Node array)
template <typename ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::generatorComprehensionLambda(GeneratorKind comprehensionKind,
unsigned begin, Node innerStmt)
unsigned begin, Node innerExpr)
{
MOZ_ASSERT(comprehensionKind == LegacyGenerator || comprehensionKind == StarGenerator);
MOZ_ASSERT(!!innerStmt == (comprehensionKind == LegacyGenerator));
MOZ_ASSERT(!!innerExpr == (comprehensionKind == LegacyGenerator));
Node genfn = handler.newFunctionDefinition();
if (!genfn)
@ -6650,29 +6702,47 @@ Parser<ParseHandler>::generatorComprehensionLambda(GeneratorKind comprehensionKi
genFunbox->inGenexpLambda = true;
handler.setBlockId(genfn, genpc.bodyid);
Node body;
Node generator = newName(context->names().dotGenerator);
if (!generator)
return null();
if (!pc->define(tokenStream, context->names().dotGenerator, generator, Definition::VAR))
return null();
Node body = handler.newStatementList(pc->blockid(), TokenPos(begin, pos().end));
if (!body)
return null();
Node comp;
if (comprehensionKind == StarGenerator) {
body = comprehension(StarGenerator);
if (!body)
comp = comprehension(StarGenerator);
if (!comp)
return null();
} else {
MOZ_ASSERT(comprehensionKind == LegacyGenerator);
body = legacyComprehensionTail(innerStmt, outerpc->blockid(), LegacyGenerator,
comp = legacyComprehensionTail(innerExpr, outerpc->blockid(), LegacyGenerator,
outerpc, LegacyComprehensionHeadBlockScopeDepth(outerpc));
if (!body)
if (!comp)
return null();
}
if (comprehensionKind == StarGenerator)
MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
handler.setBeginPosition(body, begin);
handler.setBeginPosition(comp, begin);
handler.setEndPosition(comp, pos().end);
handler.addStatementToList(body, comp, pc);
handler.setEndPosition(body, pos().end);
handler.setBeginPosition(genfn, begin);
handler.setEndPosition(genfn, pos().end);
generator = newName(context->names().dotGenerator);
if (!generator)
return null();
if (!noteNameUse(context->names().dotGenerator, generator))
return null();
if (!handler.prependInitialYield(body, generator))
return null();
// Note that if we ever start syntax-parsing generators, we will also
// need to propagate the closed-over variable set to the inner
// lazyscript, as in finishFunctionDefinition.
@ -6709,19 +6779,8 @@ Parser<FullParseHandler>::legacyGeneratorExpr(ParseNode *expr)
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FOR));
/* Create a |yield| node for |kid|. */
ParseNode *yieldExpr = handler.newUnary(PNK_YIELD, JSOP_NOP, expr->pn_pos.begin, expr);
if (!yieldExpr)
return null();
yieldExpr->setInParens(true);
// A statement to wrap the yield expression.
ParseNode *yieldStmt = handler.newExprStatement(yieldExpr, expr->pn_pos.end);
if (!yieldStmt)
return null();
/* Make a new node for the desugared generator function. */
ParseNode *genfn = generatorComprehensionLambda(LegacyGenerator, expr->pn_pos.begin, yieldStmt);
ParseNode *genfn = generatorComprehensionLambda(LegacyGenerator, expr->pn_pos.begin, expr);
if (!genfn)
return null();
@ -6871,7 +6930,7 @@ Parser<ParseHandler>::comprehensionTail(GeneratorKind comprehensionKind)
return handler.newUnary(PNK_ARRAYPUSH, JSOP_ARRAYPUSH, begin, bodyExpr);
MOZ_ASSERT(comprehensionKind == StarGenerator);
Node yieldExpr = handler.newUnary(PNK_YIELD, JSOP_NOP, begin, bodyExpr);
Node yieldExpr = newYieldExpression(begin, bodyExpr);
if (!yieldExpr)
return null();
handler.setInParens(yieldExpr);

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

@ -464,6 +464,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
bool addExprAndGetNextTemplStrToken(Node nodeList, TokenKind &tt);
inline Node newName(PropertyName *name);
inline Node newYieldExpression(uint32_t begin, Node expr, bool isYieldStar = false);
inline bool abortIfSyntaxParser();

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

@ -135,11 +135,14 @@ class SyntaxParseHandler
bool addPrototypeMutation(Node literal, uint32_t begin, Node expr) { return true; }
bool addPropertyDefinition(Node literal, Node name, Node expr, bool isShorthand = false) { return true; }
bool addMethodDefinition(Node literal, Node name, Node fn, JSOp op) { return true; }
Node newYieldExpression(uint32_t begin, Node value, Node gen) { return NodeGeneric; }
Node newYieldStarExpression(uint32_t begin, Node value, Node gen) { return NodeGeneric; }
// Statements
Node newStatementList(unsigned blockid, const TokenPos &pos) { return NodeGeneric; }
void addStatementToList(Node list, Node stmt, ParseContext<SyntaxParseHandler> *pc) {}
bool prependInitialYield(Node stmtList, Node gen) { return true; }
Node newEmptyStatement(const TokenPos &pos) { return NodeGeneric; }
Node newExprStatement(Node expr, uint32_t end) {

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

@ -25,7 +25,7 @@
* - writes to object properties
* - writes to array slots
* - writes to fields like JSObject::shape_ that we trace through
* - writes to fields in private data, like JSGenerator::obj
* - writes to fields in private data
* - writes to non-markable fields like JSObject::private that point to
* markable data
* The last category is the trickiest. Even though the private pointers does not

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

@ -1,5 +1,6 @@
// |jit-test| error: StopIteration
// Returning {throw:} from an onPop handler when yielding works and
// does not close the generator-iterator.
// does closes the generator-iterator.
load(libdir + "asserts.js");
@ -17,4 +18,4 @@ var rv = gw.evalInGlobal("it.next();");
assertEq(rv.throw, "fit");
dbg.enabled = false;
assertEq(g.it.next(), 1);
g.it.next();

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

@ -1,5 +1,5 @@
// Returning {throw:} from an onPop handler when yielding works and
// does not close the generator-iterator.
// closes the generator-iterator.
load(libdir + "iteration.js");
@ -17,4 +17,4 @@ var rv = gw.evalInGlobal("it.next();");
assertEq(rv.throw, "fit");
dbg.enabled = false;
assertIteratorNext(g.it, 1);
assertIteratorDone(g.it);

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

@ -1,3 +1,4 @@
// |jit-test| error: already executing generator
// Forced return from a generator frame.
var g = newGlobal();
@ -10,5 +11,9 @@ function gen() {
debugger; // Force return here. The value is ignored.
yield '2';
}
var x = [v for (v in gen())];
assertEq(x.join(","), "1");
var iter = gen();
assertEq(iter.next(), "1");
assertEq(iter.next(), "!");
iter.next();
assertEq(0, 1);

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

@ -1,3 +1,4 @@
// |jit-test| error: already executing generator
// Forced return from a star generator frame.
load(libdir + 'asserts.js')
@ -16,4 +17,5 @@ function* gen() {
var iter = gen();
assertIteratorNext(iter, '1');
assertEq(iter.next(), '!');
assertIteratorDone(iter);
iter.next();
assertEq(0, 1);

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

@ -0,0 +1,49 @@
// When a generator function throws, the generator is closed.
load(libdir + "asserts.js");
load(libdir + "iteration.js");
// Star generator, next() throws.
function *g() {
yield 1;
yield 2;
throw 3;
yield 4;
}
var i = g();
assertIteratorNext(i, 1);
assertIteratorNext(i, 2);
assertThrowsValue(() => i.next(), 3);
assertIteratorDone(i);
assertIteratorDone(i);
// Star generator, throw() throws.
function *h() {
yield 1;
yield 2;
}
var i = h();
assertIteratorNext(i, 1);
assertThrowsValue(() => i.throw(4), 4);
assertIteratorDone(i);
// Legacy generator, throw() throws.
function l1() {
yield 1;
yield 2;
}
var i = l1();
assertEq(i.next(), 1);
assertThrowsValue(() => i.throw(5), 5);
assertThrowsInstanceOf(() => i.next(), StopIteration);
// Legacy generator, next() throws.
function l2() {
yield 1;
throw 6;
yield 2;
}
var i = l2();
assertEq(i.next(), 1);
assertThrowsValue(() => i.next(), 6);
assertThrowsInstanceOf(() => i.next(), StopIteration);

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

@ -0,0 +1,34 @@
// Generator methods work transparently on CrossCompartmentWrappers.
load(libdir + "asserts.js");
load(libdir + "iteration.js");
function gen() { yield 1; yield 2; }
var it = gen();
var g = newGlobal();
g.eval("function gen2() { yield 3; yield 4; }; var it2 = gen2();");
// LegacyGenerator.next
assertEq(it.next.call(g.it2), 3);
// LegacyGenerator.throw
assertThrowsValue(() => it.throw.call(g.it2, 7), 7);
function *gen3() { yield 1; yield 2; }
it = gen3();
g.eval("function *gen4() { yield 5; yield 6; }; var it4 = gen4();");
// StarGenerator.next
assertIteratorResult(it.next.call(g.it4), 5, false)
// StarGenerator.throw
assertThrowsValue(() => it.throw.call(g.it4, 8), 8);
// Other objects should throw.
try {
it.next.call([]);
assertEq(0, 1);
} catch (e) {
assertEq(e.toString().contains("called on incompatible Array"), true);
}

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

@ -10,6 +10,7 @@ const { value: frame } = (function iife1() {
assertEq(frame.functionDisplayName, "iife2");
assertEq(frame.parent.functionDisplayName, "generator");
assertEq(frame.parent.parent.functionDisplayName, "iife1");
assertEq(frame.parent.parent.parent.functionDisplayName, null);
assertEq(frame.parent.parent.parent.parent, null);
assertEq(frame.parent.parent.functionDisplayName, "next");
assertEq(frame.parent.parent.parent.functionDisplayName, "iife1");
assertEq(frame.parent.parent.parent.parent.functionDisplayName, null);
assertEq(frame.parent.parent.parent.parent.parent, null);

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

@ -49,7 +49,9 @@ jit::Bailout(BailoutStack *sp, BaselineBailoutInfo **bailoutInfo)
MOZ_ASSERT(IsBaselineEnabled(cx));
*bailoutInfo = nullptr;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, false, bailoutInfo);
bool poppedLastSPSFrame = false;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, false, bailoutInfo,
/* excInfo = */ nullptr, &poppedLastSPSFrame);
MOZ_ASSERT(retval == BAILOUT_RETURN_OK ||
retval == BAILOUT_RETURN_FATAL_ERROR ||
retval == BAILOUT_RETURN_OVERRECURSED);
@ -68,7 +70,8 @@ jit::Bailout(BailoutStack *sp, BaselineBailoutInfo **bailoutInfo)
// pseudostack frame would not have been pushed in the first
// place, so don't pop anything in that case.
bool popSPSFrame = iter.ionScript()->hasSPSInstrumentation() &&
(SnapshotIterator(iter).bailoutKind() != Bailout_ArgumentCheck);
(SnapshotIterator(iter).bailoutKind() != Bailout_ArgumentCheck) &&
!poppedLastSPSFrame;
JSScript *script = iter.script();
probes::ExitScript(cx, script, script->functionNonDelazifying(), popSPSFrame);
@ -105,7 +108,9 @@ jit::InvalidationBailout(InvalidationBailoutStack *sp, size_t *frameSizeOut,
MOZ_ASSERT(IsBaselineEnabled(cx));
*bailoutInfo = nullptr;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true, bailoutInfo);
bool poppedLastSPSFrame = false;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true, bailoutInfo,
/* excInfo = */ nullptr, &poppedLastSPSFrame);
MOZ_ASSERT(retval == BAILOUT_RETURN_OK ||
retval == BAILOUT_RETURN_FATAL_ERROR ||
retval == BAILOUT_RETURN_OVERRECURSED);
@ -124,7 +129,8 @@ jit::InvalidationBailout(InvalidationBailoutStack *sp, size_t *frameSizeOut,
// pseudostack frame would not have been pushed in the first
// place, so don't pop anything in that case.
bool popSPSFrame = iter.ionScript()->hasSPSInstrumentation() &&
(SnapshotIterator(iter).bailoutKind() != Bailout_ArgumentCheck);
(SnapshotIterator(iter).bailoutKind() != Bailout_ArgumentCheck) &&
!poppedLastSPSFrame;
JSScript *script = iter.script();
probes::ExitScript(cx, script, script->functionNonDelazifying(), popSPSFrame);
@ -180,7 +186,9 @@ jit::ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame,
JitFrameIterator iter(jitActivations);
BaselineBailoutInfo *bailoutInfo = nullptr;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true, &bailoutInfo, &excInfo);
bool poppedLastSPSFrame = false;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true,
&bailoutInfo, &excInfo, &poppedLastSPSFrame);
if (retval == BAILOUT_RETURN_OK) {
MOZ_ASSERT(bailoutInfo);

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

@ -515,9 +515,12 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
HandleFunction fun, HandleScript script, IonScript *ionScript,
SnapshotIterator &iter, bool invalidate, BaselineStackBuilder &builder,
AutoValueVector &startFrameFormals, MutableHandleFunction nextCallee,
jsbytecode **callPC, const ExceptionBailoutInfo *excInfo)
jsbytecode **callPC, const ExceptionBailoutInfo *excInfo,
bool *poppedLastSPSFrameOut)
{
MOZ_ASSERT(script->hasBaselineScript());
MOZ_ASSERT(poppedLastSPSFrameOut);
MOZ_ASSERT(!*poppedLastSPSFrameOut);
// Are we catching an exception?
bool catchingException = excInfo && excInfo->catchingException();
@ -1035,6 +1038,11 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
JitSpew(JitSpew_BaselineBailouts,
" Popping SPS entry for outermost frame");
cx->runtime()->spsProfiler.exit(script, fun);
// Notify caller that the last SPS frame was popped, so not
// to do it again.
if (poppedLastSPSFrameOut)
*poppedLastSPSFrameOut = true;
}
}
} else {
@ -1291,7 +1299,7 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
uint32_t
jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIterator &iter,
bool invalidate, BaselineBailoutInfo **bailoutInfo,
const ExceptionBailoutInfo *excInfo)
const ExceptionBailoutInfo *excInfo, bool *poppedLastSPSFrameOut)
{
// The Baseline frames we will reconstruct on the heap are not rooted, so GC
// must be suppressed here.
@ -1300,6 +1308,9 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIter
MOZ_ASSERT(bailoutInfo != nullptr);
MOZ_ASSERT(*bailoutInfo == nullptr);
MOZ_ASSERT(poppedLastSPSFrameOut);
MOZ_ASSERT(!*poppedLastSPSFrameOut);
TraceLogger *logger = TraceLoggerForMainThread(cx->runtime());
TraceLogStopEvent(logger, TraceLogger::IonMonkey);
TraceLogStartEvent(logger, TraceLogger::Baseline);
@ -1429,7 +1440,8 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIter
RootedFunction nextCallee(cx, nullptr);
if (!InitFromBailout(cx, caller, callerPC, fun, scr, iter.ionScript(),
snapIter, invalidate, builder, startFrameFormals,
&nextCallee, &callPC, passExcInfo ? excInfo : nullptr))
&nextCallee, &callPC, passExcInfo ? excInfo : nullptr,
poppedLastSPSFrameOut))
{
return BAILOUT_RETURN_FATAL_ERROR;
}

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

@ -323,16 +323,13 @@ jit::CanEnterBaselineMethod(JSContext *cx, RunState &state)
if (!state.maybeCreateThisForConstructor(cx))
return Method_Skipped;
} else if (state.isExecute()) {
} else {
MOZ_ASSERT(state.isExecute());
ExecuteType type = state.asExecute()->type();
if (type == EXECUTE_DEBUG || type == EXECUTE_DEBUG_GLOBAL) {
JitSpew(JitSpew_BaselineAbort, "debugger frame");
return Method_CantCompile;
}
} else {
MOZ_ASSERT(state.isGenerator());
JitSpew(JitSpew_BaselineAbort, "generator frame");
return Method_CantCompile;
}
RootedScript script(cx, state.script());

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

@ -439,7 +439,8 @@ struct BaselineBailoutInfo
uint32_t
BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIterator &iter,
bool invalidate, BaselineBailoutInfo **bailoutInfo,
const ExceptionBailoutInfo *exceptionInfo = nullptr);
const ExceptionBailoutInfo *exceptionInfo,
bool *poppedLastSPSFrame);
// Mark baseline scripts on the stack as active, so that they are not discarded
// during GC.

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

@ -2401,10 +2401,6 @@ jit::CanEnter(JSContext *cx, RunState &state)
if (!state.maybeCreateThisForConstructor(cx))
return Method_Skipped;
} else if (state.isGenerator()) {
JitSpew(JitSpew_IonAbort, "generator frame");
ForbidCompilation(cx, script);
return Method_CantCompile;
}
// If --ion-eager is used, compile with Baseline first, so that we

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

@ -2781,7 +2781,8 @@ JS_AlreadyHasOwnUCProperty(JSContext *cx, HandleObject obj, const char16_t *name
return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
}
/* Wrapper functions to create wrappers with no corresponding JSJitInfo from API
/*
* Wrapper functions to create wrappers with no corresponding JSJitInfo from API
* function arguments.
*/
static JSPropertyOpWrapper
@ -2825,8 +2826,6 @@ DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue val
MOZ_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
JSFunction::Flags zeroFlags = JSAPIToJSFunctionFlags(0);
// We can't just use JS_NewFunctionById here because it assumes a
// string id.
RootedAtom atom(cx, JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : nullptr);
attrs &= ~JSPROP_NATIVE_ACCESSORS;
if (getter) {
@ -2863,12 +2862,12 @@ DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue val
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, id, value,
(attrs & JSPROP_GETTER)
? JS_FUNC_TO_DATA_PTR(JSObject *, getter)
: nullptr,
(attrs & JSPROP_SETTER)
? JS_FUNC_TO_DATA_PTR(JSObject *, setter)
: nullptr);
(attrs & JSPROP_GETTER)
? JS_FUNC_TO_DATA_PTR(JSObject *, getter)
: nullptr,
(attrs & JSPROP_SETTER)
? JS_FUNC_TO_DATA_PTR(JSObject *, setter)
: nullptr);
return JSObject::defineGeneric(cx, obj, id, value, getter, setter, attrs);
}
@ -3012,30 +3011,22 @@ DefineProperty(JSContext *cx, HandleObject obj, const char *name, HandleValue va
return DefinePropertyById(cx, obj, id, value, getter, setter, attrs, flags);
}
static bool
DefineSelfHostedProperty(JSContext *cx,
HandleObject obj,
const char *name,
const char *getterName,
const char *setterName,
unsigned attrs,
unsigned flags)
DefineSelfHostedProperty(JSContext *cx, HandleObject obj, HandleId id,
const char *getterName, const char *setterName,
unsigned attrs, unsigned flags)
{
RootedAtom nameAtom(cx, Atomize(cx, name, strlen(name)));
if (!nameAtom)
return false;
RootedAtom getterNameAtom(cx, Atomize(cx, getterName, strlen(getterName)));
if (!getterNameAtom)
return false;
RootedValue getterValue(cx);
if (!cx->global()->getSelfHostedFunction(cx, getterNameAtom, nameAtom,
0, &getterValue))
{
RootedAtom name(cx, IdToFunctionName(cx, id));
if (!name)
return false;
RootedValue getterValue(cx);
if (!cx->global()->getSelfHostedFunction(cx, getterNameAtom, name, 0, &getterValue))
return false;
}
MOZ_ASSERT(getterValue.isObject() && getterValue.toObject().is<JSFunction>());
RootedFunction getterFunc(cx, &getterValue.toObject().as<JSFunction>());
JSPropertyOp getterOp = JS_DATA_TO_FUNC_PTR(PropertyOp, getterFunc.get());
@ -3047,19 +3038,16 @@ DefineSelfHostedProperty(JSContext *cx,
return false;
RootedValue setterValue(cx);
if (!cx->global()->getSelfHostedFunction(cx, setterNameAtom, nameAtom,
0, &setterValue))
{
if (!cx->global()->getSelfHostedFunction(cx, setterNameAtom, name, 0, &setterValue))
return false;
}
MOZ_ASSERT(setterValue.isObject() && setterValue.toObject().is<JSFunction>());
setterFunc = &getterValue.toObject().as<JSFunction>();
}
JSStrictPropertyOp setterOp = JS_DATA_TO_FUNC_PTR(StrictPropertyOp, setterFunc.get());
return DefineProperty(cx, obj, name, JS::UndefinedHandleValue,
GetterWrapper(getterOp), SetterWrapper(setterOp),
attrs, flags);
return DefinePropertyById(cx, obj, id, JS::UndefinedHandleValue,
GetterWrapper(getterOp), SetterWrapper(setterOp),
attrs, flags);
}
JS_PUBLIC_API(bool)
@ -3256,37 +3244,81 @@ JS_DefineConstIntegers(JSContext *cx, HandleObject obj, const JSConstIntegerSpec
return DefineConstScalar(cx, obj, cis);
}
static JS::SymbolCode
PropertySpecNameToSymbolCode(const char *name)
{
MOZ_ASSERT(JS::PropertySpecNameIsSymbol(name));
uintptr_t u = reinterpret_cast<uintptr_t>(name);
return JS::SymbolCode(u - 1);
}
static bool
PropertySpecNameToId(JSContext *cx, const char *name, MutableHandleId id,
js::InternBehavior ib = js::DoNotInternAtom)
{
if (JS::PropertySpecNameIsSymbol(name)) {
JS::SymbolCode which = PropertySpecNameToSymbolCode(name);
id.set(SYMBOL_TO_JSID(cx->wellKnownSymbols().get(which)));
} else {
JSAtom *atom = Atomize(cx, name, strlen(name), ib);
if (!atom)
return false;
id.set(AtomToId(atom));
}
return true;
}
JS_PUBLIC_API(bool)
JS::PropertySpecNameToPermanentId(JSContext *cx, const char *name, jsid *idp)
{
// We are calling fromMarkedLocation(idp) even though idp points to a
// location that will never be marked. This is OK because the whole point
// of this API is to populate *idp with a jsid that does not need to be
// marked.
return PropertySpecNameToId(cx, name, MutableHandleId::fromMarkedLocation(idp),
js::InternAtom);
}
JS_PUBLIC_API(bool)
JS_DefineProperties(JSContext *cx, HandleObject obj, const JSPropertySpec *ps)
{
bool ok;
for (ok = true; ps->name; ps++) {
RootedId id(cx);
for (; ps->name; ps++) {
if (!PropertySpecNameToId(cx, ps->name, &id))
return false;
if (ps->flags & JSPROP_NATIVE_ACCESSORS) {
// If you declare native accessors, then you should have a native
// getter.
MOZ_ASSERT(ps->getter.propertyOp.op);
// If you do not have a self-hosted getter, you should not have a
// self-hosted setter. This is the closest approximation to that
// assertion we can have with our setup.
MOZ_ASSERT_IF(ps->setter.propertyOp.info, ps->setter.propertyOp.op);
ok = DefineProperty(cx, obj, ps->name, JS::UndefinedHandleValue,
ps->getter.propertyOp, ps->setter.propertyOp, ps->flags, 0);
if (!DefinePropertyById(cx, obj, id, JS::UndefinedHandleValue,
ps->getter.propertyOp, ps->setter.propertyOp, ps->flags, 0))
{
return false;
}
} else {
// If you have self-hosted getter/setter, you can't have a
// native one.
MOZ_ASSERT(!ps->getter.propertyOp.op && !ps->setter.propertyOp.op);
MOZ_ASSERT(ps->flags & JSPROP_GETTER);
ok = DefineSelfHostedProperty(cx, obj, ps->name,
if (!DefineSelfHostedProperty(cx, obj, id,
ps->getter.selfHosted.funname,
ps->setter.selfHosted.funname,
ps->flags, 0);
ps->flags, 0))
{
return false;
}
}
if (!ok)
break;
}
return ok;
return true;
}
JS_PUBLIC_API(bool)
@ -3620,137 +3652,6 @@ JS_Enumerate(JSContext *cx, HandleObject obj)
return ida;
}
/*
* XXX reverse iterator for properties, unreverse and meld with jsinterp.c's
* prop_iterator_class somehow...
* + preserve the obj->enumerate API while optimizing the native object case
* + native case here uses a JSShape *, but that iterates in reverse!
* + so we make non-native match, by reverse-iterating after JS_Enumerating
*/
static const uint32_t JSSLOT_ITER_INDEX = 0;
static void
prop_iter_finalize(FreeOp *fop, JSObject *obj)
{
void *pdata = obj->as<NativeObject>().getPrivate();
if (!pdata)
return;
if (obj->as<NativeObject>().getSlot(JSSLOT_ITER_INDEX).toInt32() >= 0) {
/* Non-native case: destroy the ida enumerated when obj was created. */
JSIdArray *ida = (JSIdArray *) pdata;
fop->free_(ida);
}
}
static void
prop_iter_trace(JSTracer *trc, JSObject *obj)
{
void *pdata = obj->as<NativeObject>().getPrivate();
if (!pdata)
return;
if (obj->as<NativeObject>().getSlot(JSSLOT_ITER_INDEX).toInt32() < 0) {
/*
* Native case: just mark the next property to visit. We don't need a
* barrier here because the pointer is updated via setPrivate, which
* always takes a barrier.
*/
Shape *tmp = static_cast<Shape *>(pdata);
MarkShapeUnbarriered(trc, &tmp, "prop iter shape");
obj->as<NativeObject>().setPrivateUnbarriered(tmp);
} else {
/* Non-native case: mark each id in the JSIdArray private. */
JSIdArray *ida = (JSIdArray *) pdata;
MarkIdRange(trc, ida->length, ida->vector, "prop iter");
}
}
static const Class prop_iter_class = {
"PropertyIterator",
JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(1),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
prop_iter_finalize,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
prop_iter_trace
};
JS_PUBLIC_API(JSObject *)
JS_NewPropertyIterator(JSContext *cx, HandleObject obj)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
RootedNativeObject iterobj(cx, NewNativeObjectWithClassProto(cx, &prop_iter_class,
nullptr, obj));
if (!iterobj)
return nullptr;
int index;
if (obj->isNative()) {
/* Native case: start with the last property in obj. */
iterobj->setPrivateGCThing(obj->lastProperty());
index = -1;
} else {
/* Non-native case: enumerate a JSIdArray and keep it via private. */
JSIdArray *ida = JS_Enumerate(cx, obj);
if (!ida)
return nullptr;
iterobj->setPrivate((void *)ida);
index = ida->length;
}
/* iterobj cannot escape to other threads here. */
iterobj->setSlot(JSSLOT_ITER_INDEX, Int32Value(index));
return iterobj;
}
JS_PUBLIC_API(bool)
JS_NextProperty(JSContext *cx, HandleObject iterobj, MutableHandleId idp)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, iterobj);
int32_t i = iterobj->as<NativeObject>().getSlot(JSSLOT_ITER_INDEX).toInt32();
if (i < 0) {
/* Native case: private data is a property tree node pointer. */
MOZ_ASSERT(iterobj->getParent()->isNative());
Shape *shape = static_cast<Shape *>(iterobj->as<NativeObject>().getPrivate());
while (shape->previous() && !shape->enumerable())
shape = shape->previous();
if (!shape->previous()) {
MOZ_ASSERT(shape->isEmptyShape());
idp.set(JSID_VOID);
} else {
iterobj->as<NativeObject>().setPrivateGCThing(const_cast<Shape *>(shape->previous().get()));
idp.set(shape->propid());
}
} else {
/* Non-native case: use the ida enumerated when iterobj was created. */
JSIdArray *ida = (JSIdArray *) iterobj->as<NativeObject>().getPrivate();
MOZ_ASSERT(i <= ida->length);
STATIC_ASSUME(i <= ida->length);
if (i == 0) {
idp.set(JSID_VOID);
} else {
idp.set(ida->vector[--i]);
iterobj->as<NativeObject>().setSlot(JSSLOT_ITER_INDEX, Int32Value(i));
}
}
return true;
}
JS_PUBLIC_API(jsval)
JS_GetReservedSlot(JSObject *obj, uint32_t index)
{
@ -3899,12 +3800,14 @@ JS_NewFunctionById(JSContext *cx, JSNative native, unsigned nargs, unsigned flag
JS_PUBLIC_API(JSFunction *)
JS::GetSelfHostedFunction(JSContext *cx, const char *selfHostedName, HandleId id, unsigned nargs)
{
MOZ_ASSERT(JSID_IS_STRING(id));
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
RootedAtom name(cx, JSID_TO_ATOM(id));
RootedAtom name(cx, IdToFunctionName(cx, id));
if (!name)
return nullptr;
RootedAtom shName(cx, Atomize(cx, selfHostedName, strlen(selfHostedName)));
if (!shName)
return nullptr;
@ -4068,21 +3971,11 @@ JS_DefineFunctions(JSContext *cx, HandleObject obj, const JSFunctionSpec *fs)
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
RootedId id(cx);
for (; fs->name; fs++) {
RootedAtom atom(cx);
// If the name starts with "@@", it must be a well-known symbol.
if (fs->name[0] != '@' || fs->name[1] != '@')
atom = Atomize(cx, fs->name, strlen(fs->name));
else if (strcmp(fs->name, "@@iterator") == 0)
// FIXME: This atom should be a symbol: bug 918828.
atom = cx->names().std_iterator;
else
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_SYMBOL, fs->name);
if (!atom)
if (!PropertySpecNameToId(cx, fs->name, &id))
return false;
Rooted<jsid> id(cx, AtomToId(atom));
/*
* Define a generic arity N+1 static method for the arity N prototype
* method if flags contains JSFUN_GENERIC_NATIVE.
@ -4124,8 +4017,11 @@ JS_DefineFunctions(JSContext *cx, HandleObject obj, const JSFunctionSpec *fs)
RootedAtom shName(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName)));
if (!shName)
return false;
RootedAtom name(cx, IdToFunctionName(cx, id));
if (!name)
return false;
RootedValue funVal(cx);
if (!cx->global()->getSelfHostedFunction(cx, shName, atom, fs->nargs, &funVal))
if (!cx->global()->getSelfHostedFunction(cx, shName, name, fs->nargs, &funVal))
return false;
if (!JSObject::defineGeneric(cx, obj, id, funVal, nullptr, nullptr, flags))
return false;
@ -5628,6 +5524,33 @@ JS::GetWellKnownSymbol(JSContext *cx, JS::SymbolCode which)
return cx->runtime()->wellKnownSymbols->get(uint32_t(which));
}
static bool
PropertySpecNameIsDigits(const char *s) {
if (JS::PropertySpecNameIsSymbol(s))
return false;
if (!*s)
return false;
for (; *s; s++) {
if (*s < '0' || *s > '9')
return false;
}
return true;
}
JS_PUBLIC_API(bool)
JS::PropertySpecNameEqualsId(const char *name, HandleId id)
{
if (JS::PropertySpecNameIsSymbol(name)) {
if (!JSID_IS_SYMBOL(id))
return false;
Symbol *sym = JSID_TO_SYMBOL(id);
return sym->isWellKnownSymbol() && sym->code() == PropertySpecNameToSymbolCode(name);
}
MOZ_ASSERT(!PropertySpecNameIsDigits(name));
return JSID_IS_ATOM(id) && JS_FlatStringEqualsAscii(JSID_TO_ATOM(id), name);
}
JS_PUBLIC_API(bool)
JS_Stringify(JSContext *cx, MutableHandleValue vp, HandleObject replacer,
HandleValue space, JSONWriteCallback callback, void *data)

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

@ -2475,15 +2475,27 @@ struct JSFunctionSpec {
* JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of
* JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function. Finally
* JS_FNSPEC has slots for all the fields.
*
* The _SYM variants allow defining a function with a symbol key rather than a
* string key. For example, use JS_SYM_FN(iterator, ...) to define an
* @@iterator method.
*/
#define JS_FS(name,call,nargs,flags) \
JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr)
#define JS_FN(name,call,nargs,flags) \
JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
#define JS_SYM_FN(name,call,nargs,flags) \
JS_SYM_FNSPEC(symbol, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
#define JS_FNINFO(name,call,info,nargs,flags) \
JS_FNSPEC(name, call, info, nargs, flags, nullptr)
#define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags) \
JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName)
#define JS_SELF_HOSTED_SYM_FN(symbol, selfHostedName, nargs, flags) \
JS_SYM_FNSPEC(symbol, nullptr, nullptr, nargs, flags, selfHostedName)
#define JS_SYM_FNSPEC(symbol, call, info, nargs, flags, selfHostedName) \
JS_FNSPEC(reinterpret_cast<const char *>( \
uint32_t(::JS::SymbolCode::symbol) + 1), \
call, info, nargs, flags, selfHostedName)
#define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName) \
{name, {call, info}, nargs, flags, selfHostedName}
@ -3305,22 +3317,6 @@ JS_ReleaseMappedArrayBufferContents(void *contents, size_t length);
extern JS_PUBLIC_API(JSIdArray *)
JS_Enumerate(JSContext *cx, JS::HandleObject obj);
/*
* Create an object to iterate over enumerable properties of obj, in arbitrary
* property definition order. NB: This differs from longstanding for..in loop
* order, which uses order of property definition in obj.
*/
extern JS_PUBLIC_API(JSObject *)
JS_NewPropertyIterator(JSContext *cx, JS::Handle<JSObject*> obj);
/*
* Return true on success with *idp containing the id of the next enumerable
* property to visit using iterobj, or JSID_IS_VOID if there is no such property
* left to visit. Return false on error.
*/
extern JS_PUBLIC_API(bool)
JS_NextProperty(JSContext *cx, JS::HandleObject iterobj, JS::MutableHandleId idp);
extern JS_PUBLIC_API(jsval)
JS_GetReservedSlot(JSObject *obj, uint32_t index);
@ -4510,6 +4506,31 @@ GetSymbolCode(Handle<Symbol*> symbol);
JS_PUBLIC_API(Symbol *)
GetWellKnownSymbol(JSContext *cx, SymbolCode which);
/*
* Return true if the given JSPropertySpec::name or JSFunctionSpec::name value
* is actually a symbol code and not a string. See JS_SYM_FN.
*/
inline bool
PropertySpecNameIsSymbol(const char *name)
{
uintptr_t u = reinterpret_cast<uintptr_t>(name);
return u != 0 && u - 1 < WellKnownSymbolLimit;
}
JS_PUBLIC_API(bool)
PropertySpecNameEqualsId(const char *name, HandleId id);
/*
* Create a jsid that does not need to be marked for GC.
*
* 'name' is a JSPropertySpec::name or JSFunctionSpec::name value. The
* resulting jsid, on success, is either an interned string or a well-known
* symbol; either way it is immune to GC so there is no need to visit *idp
* during GC marking.
*/
JS_PUBLIC_API(bool)
PropertySpecNameToPermanentId(JSContext *cx, const char *name, jsid *idp);
} /* namespace JS */
/************************************************************************/

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

@ -58,7 +58,6 @@ const char js_break_str[] = "break";
const char js_case_str[] = "case";
const char js_catch_str[] = "catch";
const char js_class_str[] = "class";
const char js_close_str[] = "close";
const char js_const_str[] = "const";
const char js_continue_str[] = "continue";
const char js_debugger_str[] = "debugger";

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

@ -1109,11 +1109,10 @@ JSContext::JSContext(JSRuntime *rt)
data(nullptr),
data2(nullptr),
outstandingRequests(0),
jitIsBroken(false),
jitIsBroken(false)
#ifdef MOZ_TRACE_JSCALLS
functionCallback(nullptr),
, functionCallback(nullptr)
#endif
innermostGenerator_(nullptr)
{
MOZ_ASSERT(static_cast<ContextFriendFields*>(this) ==
ContextFriendFields::get(this));
@ -1146,23 +1145,6 @@ JSContext::isThrowingOutOfMemory()
return throwing && unwrappedException_ == StringValue(names().outOfMemory);
}
void
JSContext::enterGenerator(JSGenerator *gen)
{
MOZ_ASSERT(!gen->prevGenerator);
gen->prevGenerator = innermostGenerator_;
innermostGenerator_ = gen;
}
void
JSContext::leaveGenerator(JSGenerator *gen)
{
MOZ_ASSERT(innermostGenerator_ == gen);
innermostGenerator_ = innermostGenerator_->prevGenerator;
gen->prevGenerator = nullptr;
}
bool
JSContext::saveFrameChain()
{

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

@ -284,6 +284,7 @@ struct ThreadSafeContext : ContextFriendFields,
JSAtomState &names() { return *runtime_->commonNames; }
StaticStrings &staticStrings() { return *runtime_->staticStrings; }
AtomSet &permanentAtoms() { return *runtime_->permanentAtoms; }
WellKnownSymbols &wellKnownSymbols() { return *runtime_->wellKnownSymbols; }
const JS::AsmJSCacheOps &asmJSCacheOps() { return runtime_->asmJSCacheOps; }
PropertyName *emptyString() { return runtime_->emptyString; }
FreeOp *defaultFreeOp() { return runtime_->defaultFreeOp(); }
@ -551,14 +552,7 @@ struct JSContext : public js::ExclusiveContext,
runtime_->gc.gcIfNeeded(this);
}
private:
/* Innermost-executing generator or null if no generator are executing. */
JSGenerator *innermostGenerator_;
public:
JSGenerator *innermostGenerator() const { return innermostGenerator_; }
void enterGenerator(JSGenerator *gen);
void leaveGenerator(JSGenerator *gen);
bool isExceptionPending() {
return throwing;
}

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

@ -971,7 +971,7 @@ CopyFlatStringChars(char16_t *dest, JSFlatString *s, size_t len)
}
JS_FRIEND_API(bool)
GetPropertyKeys(JSContext *cx, JSObject *obj, unsigned flags, JS::AutoIdVector *props);
GetPropertyKeys(JSContext *cx, JS::HandleObject obj, unsigned flags, JS::AutoIdVector *props);
JS_FRIEND_API(bool)
AppendUnique(JSContext *cx, JS::AutoIdVector &base, JS::AutoIdVector &others);

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