Merge inbound and central

This commit is contained in:
Marco Bonardo 2012-03-07 10:33:11 +01:00
commit 7a53ebb551
203 changed files with 7043 additions and 3880 deletions

View File

@ -696,6 +696,16 @@ nsApplicationAccessibleWrap::Unload()
// }
}
NS_IMETHODIMP
nsApplicationAccessibleWrap::GetName(nsAString& aName)
{
// ATK doesn't provide a way to obtain an application name (for example,
// Firefox or Thunderbird) like IA2 does. Thus let's return an application
// name as accessible name that was used to get a branding name (for example,
// Minefield aka nightly Firefox or Daily aka nightly Thunderbird).
return GetAppName(aName);
}
NS_IMETHODIMP
nsApplicationAccessibleWrap::GetNativeInterface(void **aOutAccessible)
{

View File

@ -57,6 +57,8 @@ public:
virtual bool Init();
// nsAccessible
NS_IMETHOD GetName(nsAString &aName);
virtual bool AppendChild(nsAccessible* aChild);
virtual bool RemoveChild(nsAccessible* aChild);

View File

@ -47,6 +47,7 @@
#include "States.h"
#include "nsIClipboard.h"
#include "nsContentUtils.h"
#include "nsFocusManager.h"
#include "nsIDOMCharacterData.h"
#include "nsIDOMDocument.h"
@ -1153,15 +1154,14 @@ nsHyperTextAccessible::GetTextAttributes(bool aIncludeDefAttrs,
// Compute spelling attributes on text accessible only.
nsIFrame *offsetFrame = accAtOffset->GetFrame();
if (offsetFrame && offsetFrame->GetType() == nsGkAtoms::textFrame) {
nsCOMPtr<nsIDOMNode> node = accAtOffset->DOMNode();
PRInt32 nodeOffset = 0;
nsresult rv = RenderedToContentOffset(offsetFrame, offsetInAcc,
&nodeOffset);
NS_ENSURE_SUCCESS(rv, rv);
// Set 'misspelled' text attribute.
rv = GetSpellTextAttribute(node, nodeOffset, &startOffset, &endOffset,
rv = GetSpellTextAttribute(accAtOffset->GetNode(), nodeOffset,
&startOffset, &endOffset,
aAttributes ? *aAttributes : nsnull);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -1789,13 +1789,11 @@ nsHyperTextAccessible::GetSelectionDOMRanges(PRInt16 aType,
// Remove collapsed ranges
PRUint32 numRanges = aRanges->Length();
for (PRUint32 count = 0; count < numRanges; count ++) {
bool isCollapsed = false;
(*aRanges)[count]->GetCollapsed(&isCollapsed);
if (isCollapsed) {
aRanges->RemoveElementAt(count);
for (PRUint32 idx = 0; idx < numRanges; idx ++) {
if ((*aRanges)[idx]->Collapsed()) {
aRanges->RemoveElementAt(idx);
--numRanges;
--count;
--idx;
}
}
}
@ -1837,29 +1835,19 @@ nsHyperTextAccessible::GetSelectionBounds(PRInt32 aSelectionNum,
nsRange* range = ranges[aSelectionNum];
// Get start point
nsCOMPtr<nsIDOMNode> startDOMNode;
range->GetStartContainer(getter_AddRefs(startDOMNode));
nsCOMPtr<nsINode> startNode(do_QueryInterface(startDOMNode));
PRInt32 startOffset = 0;
range->GetStartOffset(&startOffset);
// Get start and end points.
nsINode* startNode = range->GetStartParent();
nsINode* endNode = range->GetEndParent();
PRInt32 startOffset = range->StartOffset(), endOffset = range->EndOffset();
// Get end point
nsCOMPtr<nsIDOMNode> endDOMNode;
range->GetEndContainer(getter_AddRefs(endDOMNode));
nsCOMPtr<nsINode> endNode(do_QueryInterface(endDOMNode));
PRInt32 endOffset = 0;
range->GetEndOffset(&endOffset);
PRInt16 rangeCompareResult = 0;
nsresult rv = range->CompareBoundaryPoints(nsIDOMRange::START_TO_END, range,
&rangeCompareResult);
NS_ENSURE_SUCCESS(rv, rv);
if (rangeCompareResult < 0) {
// Make sure start is before end, by swapping offsets
// This occurs when the user selects backwards in the text
startNode.swap(endNode);
// Make sure start is before end, by swapping DOM points. This occurs when
// the user selects backwards in the text.
PRInt32 rangeCompare = nsContentUtils::ComparePoints(endNode, endOffset,
startNode, startOffset);
if (rangeCompare < 0) {
nsINode* tempNode = startNode;
startNode = endNode;
endNode = tempNode;
PRInt32 tempOffset = startOffset;
startOffset = endOffset;
endOffset = tempOffset;
@ -2324,25 +2312,17 @@ nsHyperTextAccessible::RangeBoundToHypertextOffset(nsRange *aRange,
bool aIsStartHTOffset,
PRInt32 *aHTOffset)
{
nsCOMPtr<nsIDOMNode> DOMNode;
nsINode* node = nsnull;
PRInt32 nodeOffset = 0;
nsresult rv;
if (aIsStartBound) {
rv = aRange->GetStartContainer(getter_AddRefs(DOMNode));
NS_ENSURE_SUCCESS(rv, rv);
rv = aRange->GetStartOffset(&nodeOffset);
NS_ENSURE_SUCCESS(rv, rv);
node = aRange->GetStartParent();
nodeOffset = aRange->StartOffset();
} else {
rv = aRange->GetEndContainer(getter_AddRefs(DOMNode));
NS_ENSURE_SUCCESS(rv, rv);
rv = aRange->GetEndOffset(&nodeOffset);
NS_ENSURE_SUCCESS(rv, rv);
node = aRange->GetEndParent();
nodeOffset = aRange->EndOffset();
}
nsCOMPtr<nsINode> node(do_QueryInterface(DOMNode));
nsAccessible *startAcc =
DOMPointToHypertextOffset(node, nodeOffset, aHTOffset);
@ -2354,7 +2334,7 @@ nsHyperTextAccessible::RangeBoundToHypertextOffset(nsRange *aRange,
// nsHyperTextAccessible
nsresult
nsHyperTextAccessible::GetSpellTextAttribute(nsIDOMNode *aNode,
nsHyperTextAccessible::GetSpellTextAttribute(nsINode* aNode,
PRInt32 aNodeOffset,
PRInt32 *aHTStartOffset,
PRInt32 *aHTEndOffset,
@ -2367,25 +2347,19 @@ nsHyperTextAccessible::GetSpellTextAttribute(nsIDOMNode *aNode,
if (!rangeCount)
return NS_OK;
nsCOMPtr<nsIDOMNode> DOMNode = do_QueryInterface(aNode);
for (PRUint32 index = 0; index < rangeCount; index++) {
nsRange* range = ranges[index];
PRInt16 result;
nsresult rv = range->ComparePoint(aNode, aNodeOffset, &result);
nsresult rv = range->ComparePoint(DOMNode, aNodeOffset, &result);
NS_ENSURE_SUCCESS(rv, rv);
// ComparePoint checks boundary points, but we need to check that
// text at aNodeOffset is inside the range.
// See also bug 460690.
if (result == 0) {
nsCOMPtr<nsIDOMNode> end;
rv = range->GetEndContainer(getter_AddRefs(end));
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 endOffset;
rv = range->GetEndOffset(&endOffset);
NS_ENSURE_SUCCESS(rv, rv);
if (aNode == end && aNodeOffset == endOffset) {
if (aNode == range->GetEndParent() && aNodeOffset == range->EndOffset())
result = 1;
}
}
if (result == 1) { // range is before point

View File

@ -409,7 +409,7 @@ protected:
* @param aEndOffset [in, out] the end offset
* @param aAttributes [out, optional] result attributes
*/
nsresult GetSpellTextAttribute(nsIDOMNode *aNode, PRInt32 aNodeOffset,
nsresult GetSpellTextAttribute(nsINode* aNode, PRInt32 aNodeOffset,
PRInt32 *aStartOffset,
PRInt32 *aEndOffset,
nsIPersistentProperties *aAttributes);

View File

@ -15,41 +15,46 @@
<script type="application/javascript">
function doTest()
{
var accessible = getApplicationAccessible();
if (!accessible) {
SimpleTest.finish();
return;
}
var accessible = getApplicationAccessible();
if (!accessible) {
SimpleTest.finish();
return;
}
// nsIAccessible::name
var bundleServ = Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService);
var bundle = bundleServ.createBundle("chrome://branding/locale/brand.properties");
var bundleServ =
Components.classes["@mozilla.org/intl/stringbundle;1"].
getService(Components.interfaces.nsIStringBundleService);
var brandBundle =
bundleServ.createBundle("chrome://branding/locale/brand.properties");
var applicationName = "";
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].
getService(Components.interfaces.nsIXULAppInfo);
// nsIAccessible::name
var applicationName = "";
if (LINUX || SOLARIS) {
applicationName = appInfo.name;
} else {
try {
applicationName = bundle.GetStringFromName("brandShortName");
} catch(e) {
applicationName = brandBundle.GetStringFromName("brandShortName");
} catch(e) {
}
if (applicationName == "")
applicationName = "Gecko based application";
applicationName = "Gecko based application";
}
is (accessible.name, applicationName, "wrong application accessible name");
is (accessible.name, applicationName, "wrong application accessible name");
// nsIAccessibleApplication
is(accessible.appName, appInfo.name, "Wrong application name");
is(accessible.appVersion, appInfo.version, "Wrong application version");
is(accessible.platformName, "Gecko", "Wrong platform name");
is(accessible.platformVersion, appInfo.platformVersion,
"Wrong platform version");
// nsIAccessibleApplication
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].
getService(Components.interfaces.nsIXULAppInfo);
is(accessible.appName, appInfo.name, "Wrong application name");
is(accessible.appVersion, appInfo.version, "Wrong application version");
is(accessible.platformName, "Gecko", "Wrong platform name");
is(accessible.platformVersion, appInfo.platformVersion,
"Wrong platform version");
SimpleTest.finish();
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>

View File

@ -1563,49 +1563,6 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
gHomeButton.updateTooltip(homeButton);
gHomeButton.updatePersonalToolbarStyle(homeButton);
#ifdef HAVE_SHELL_SERVICE
// Perform default browser checking (after window opens).
var shell = getShellService();
if (shell) {
#ifdef DEBUG
var shouldCheck = false;
#else
var shouldCheck = shell.shouldCheckDefaultBrowser;
#endif
var willRecoverSession = false;
try {
var ss = Cc["@mozilla.org/browser/sessionstartup;1"].
getService(Ci.nsISessionStartup);
willRecoverSession =
(ss.sessionType == Ci.nsISessionStartup.RECOVER_SESSION);
}
catch (ex) { /* never mind; suppose SessionStore is broken */ }
if (shouldCheck && !shell.isDefaultBrowser(true) && !willRecoverSession) {
// Delay the set-default-browser prompt so it doesn't block
// initialisation of the session store service.
setTimeout(function () {
var brandBundle = document.getElementById("bundle_brand");
var shellBundle = document.getElementById("bundle_shell");
var brandShortName = brandBundle.getString("brandShortName");
var promptTitle = shellBundle.getString("setDefaultBrowserTitle");
var promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage",
[brandShortName]);
var checkboxLabel = shellBundle.getFormattedString("setDefaultBrowserDontAsk",
[brandShortName]);
var checkEveryTime = { value: shouldCheck };
var ps = Services.prompt;
var rv = ps.confirmEx(window, promptTitle, promptMessage,
ps.STD_YES_NO_BUTTONS,
null, null, null, checkboxLabel, checkEveryTime);
if (rv == 0)
shell.setDefaultBrowser(true, false);
shell.shouldCheckDefaultBrowser = checkEveryTime.value;
}, 0);
}
}
#endif
// BiDi UI
gBidiUI = isBidiEnabled();
if (gBidiUI) {
@ -5374,6 +5331,7 @@ function setToolbarVisibility(toolbar, isVisible) {
var TabsOnTop = {
init: function TabsOnTop_init() {
this._initialized = true;
this.syncUI();
Services.prefs.addObserver(this._prefName, this, false);
},
@ -5387,6 +5345,9 @@ var TabsOnTop = {
},
syncUI: function () {
if (!this._initialized)
return;
let userEnabled = Services.prefs.getBoolPref(this._prefName);
let enabled = userEnabled && gBrowser.tabContainer.visible;

View File

@ -426,6 +426,49 @@ BrowserGlue.prototype = {
let keywordURLUserSet = Services.prefs.prefHasUserValue("keyword.URL");
Services.telemetry.getHistogramById("FX_KEYWORD_URL_USERSET").add(keywordURLUserSet);
// Perform default browser checking.
var shell;
try {
shell = Components.classes["@mozilla.org/browser/shell-service;1"]
.getService(Components.interfaces.nsIShellService);
} catch (e) { }
if (shell) {
#ifdef DEBUG
var shouldCheck = false;
#else
var shouldCheck = shell.shouldCheckDefaultBrowser;
#endif
var willRecoverSession = false;
try {
var ss = Cc["@mozilla.org/browser/sessionstartup;1"].
getService(Ci.nsISessionStartup);
willRecoverSession =
(ss.sessionType == Ci.nsISessionStartup.RECOVER_SESSION);
}
catch (ex) { /* never mind; suppose SessionStore is broken */ }
if (shouldCheck && !shell.isDefaultBrowser(true) && !willRecoverSession) {
Services.tm.mainThread.dispatch(function() {
var brandBundle = win.document.getElementById("bundle_brand");
var shellBundle = win.document.getElementById("bundle_shell");
var brandShortName = brandBundle.getString("brandShortName");
var promptTitle = shellBundle.getString("setDefaultBrowserTitle");
var promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage",
[brandShortName]);
var checkboxLabel = shellBundle.getFormattedString("setDefaultBrowserDontAsk",
[brandShortName]);
var checkEveryTime = { value: shouldCheck };
var ps = Services.prompt;
var rv = ps.confirmEx(win, promptTitle, promptMessage,
ps.STD_YES_NO_BUTTONS,
null, null, null, checkboxLabel, checkEveryTime);
if (rv == 0)
shell.setDefaultBrowser(true, false);
shell.shouldCheckDefaultBrowser = checkEveryTime.value;
}, Ci.nsIThread.DISPATCH_NORMAL);
}
}
},
_onQuitRequest: function BG__onQuitRequest(aCancelQuit, aQuitType) {

View File

@ -167,73 +167,33 @@ PlacesViewBase.prototype = {
},
_cleanPopup: function PVB_cleanPopup(aPopup) {
// Remove places popup children and update markers to keep track of
// their indices.
let start = aPopup._startMarker != -1 ? aPopup._startMarker + 1 : 0;
let end = aPopup._endMarker != -1 ? aPopup._endMarker :
aPopup.childNodes.length;
let items = [];
// Automatically adjust the start and the end markers.
let firstNonStaticNodeFound = false;
for (let i = start; i < end; ++i) {
let item = aPopup.childNodes[i];
if (item.getAttribute("builder") == "end") {
// we need to do this for menus that have static content at the end but
// are initially empty, eg. the history menu, we need to know where to
// start inserting new items.
aPopup._endMarker = i;
break;
}
if (item._placesNode) {
items.push(item);
firstNonStaticNodeFound = true;
}
else {
// This is static content.
if (!firstNonStaticNodeFound) {
// We are at the beginning of the popup, in static content.
// The markers are initialized in menu.xml, in the base binding.
aPopup._startMarker++;
}
else {
// We are at the end of the popup, after places nodes
aPopup._endMarker = i;
break;
}
}
}
for (let i = 0; i < items.length; ++i) {
aPopup.removeChild(items[i]);
if (aPopup._endMarker != -1)
aPopup._endMarker--;
// Remove Places nodes from the popup.
let child = aPopup._startMarker;
while (child.nextSibling != aPopup._endMarker) {
if (child.nextSibling._placesNode)
aPopup.removeChild(child.nextSibling);
else
child = child.nextSibling;
}
},
_rebuildPopup: function PVB__rebuildPopup(aPopup) {
this._cleanPopup(aPopup);
let resultNode = aPopup._placesNode;
if (!resultNode.containerOpen)
return;
if (resultNode._feedURI) {
aPopup.removeAttribute("emptyplacesresult");
if (aPopup._emptyMenuItem) {
aPopup._emptyMenuItem.hidden = true;
}
this._setEmptyPopupStatus(aPopup, false);
aPopup._built = true;
this._populateLivemarkPopup(aPopup);
return;
}
this._cleanPopup(aPopup);
let cc = resultNode.childCount;
if (cc > 0) {
aPopup.removeAttribute("emptyplacesresult");
if (aPopup._emptyMenuItem)
aPopup._emptyMenuItem.hidden = true;
this._setEmptyPopupStatus(aPopup, false);
for (let i = 0; i < cc; ++i) {
let child = resultNode.getChild(i);
@ -241,11 +201,7 @@ PlacesViewBase.prototype = {
}
}
else {
aPopup.setAttribute("emptyplacesresult", "true");
// This menu is empty. If there is no static content, add
// an element to show it is empty.
if (aPopup._startMarker == -1 && aPopup._endMarker == -1)
this._showEmptyMenuItem(aPopup);
this._setEmptyPopupStatus(aPopup, true);
}
aPopup._built = true;
},
@ -260,17 +216,28 @@ PlacesViewBase.prototype = {
aChild.parentNode.removeChild(aChild);
},
_showEmptyMenuItem: function PVB__showEmptyMenuItem(aPopup) {
if (aPopup._emptyMenuItem) {
aPopup._emptyMenuItem.hidden = false;
return;
_setEmptyPopupStatus:
function PVB__setEmptyPopupStatus(aPopup, aEmpty) {
if (!aPopup._emptyMenuitem) {
let label = PlacesUIUtils.getString("bookmarksMenuEmptyFolder");
aPopup._emptyMenuitem = document.createElement("menuitem");
aPopup._emptyMenuitem.setAttribute("label", label);
aPopup._emptyMenuitem.setAttribute("disabled", true);
}
let label = PlacesUIUtils.getString("bookmarksMenuEmptyFolder");
aPopup._emptyMenuItem = document.createElement("menuitem");
aPopup._emptyMenuItem.setAttribute("label", label);
aPopup._emptyMenuItem.setAttribute("disabled", true);
aPopup.appendChild(aPopup._emptyMenuItem);
if (aEmpty) {
aPopup.setAttribute("emptyplacesresult", "true");
// Don't add the menuitem if there is static content.
if (!aPopup._startMarker.previousSibling &&
!aPopup._endMarker.nextSibling)
aPopup.insertBefore(aPopup._emptyMenuitem, aPopup._endMarker);
}
else {
aPopup.removeAttribute("emptyplacesresult");
try {
aPopup.removeChild(aPopup._emptyMenuitem);
} catch (ex) {}
}
},
_createMenuItemForPlacesNode:
@ -308,6 +275,12 @@ PlacesViewBase.prototype = {
function (aStatus, aLivemark) {
if (Components.isSuccessCode(aStatus)) {
element.setAttribute("livemark", "true");
#ifdef XP_MACOSX
// OS X native menubar doesn't track list-style-images since
// it doesn't have a frame (bug 733415). Thus enforce updating.
element.setAttribute("image", "");
element.removeAttribute("image");
#endif
// Set an expando on the node, controller will use it to build
// its metadata.
aPlacesNode._feedURI = aLivemark.feedURI;
@ -319,12 +292,11 @@ PlacesViewBase.prototype = {
let popup = document.createElement("menupopup");
popup._placesNode = PlacesUtils.asContainer(aPlacesNode);
if (this._nativeView) {
popup._startMarker = -1;
popup._endMarker = -1;
}
else
if (!this._nativeView) {
popup.setAttribute("placespopup", "true");
}
#ifdef XP_MACOSX
// No context menu on mac.
popup.setAttribute("context", "placesContext");
@ -354,26 +326,8 @@ PlacesViewBase.prototype = {
_insertNewItemToPopup:
function PVB__insertNewItemToPopup(aNewChild, aPopup, aBefore) {
let element = this._createMenuItemForPlacesNode(aNewChild);
if (aBefore) {
aPopup.insertBefore(element, aBefore);
}
else {
// Add the new element to the menu. If there is static content at
// the end of the menu, add the element before that. Otherwise,
// just add to the end.
if (aPopup._endMarker != -1) {
let lastElt = aPopup.childNodes[aPopup._endMarker];
aPopup.insertBefore(element, lastElt);
}
else {
aPopup.appendChild(element);
}
}
if (aPopup._endMarker != -1)
aPopup._endMarker++;
let before = aBefore || aPopup._endMarker;
aPopup.insertBefore(element, before);
return element;
},
@ -384,10 +338,8 @@ PlacesViewBase.prototype = {
if (!siteUrl && aPopup._siteURIMenuitem) {
aPopup.removeChild(aPopup._siteURIMenuitem);
aPopup._siteURIMenuitem = null;
aPopup._startMarker--;
aPopup.removeChild(aPopup._siteURIMenuseparator);
aPopup._siteURIMenuseparator = null;
aPopup._startMarker--;
}
else if (siteUrl && !aPopup._siteURIMenuitem) {
// Add "Open (Feed Name)" menuitem.
@ -407,14 +359,10 @@ PlacesViewBase.prototype = {
PlacesUIUtils.getFormattedString("menuOpenLivemarkOrigin.label",
[aPopup.parentNode.getAttribute("label")])
aPopup._siteURIMenuitem.setAttribute("label", label);
aPopup.insertBefore(aPopup._siteURIMenuitem,
aPopup.childNodes.item(aPopup._startMarker + 1));
aPopup._startMarker++;
aPopup.insertBefore(aPopup._siteURIMenuitem, aPopup._startMarker);
aPopup._siteURIMenuseparator = document.createElement("menuseparator");
aPopup.insertBefore(aPopup._siteURIMenuseparator,
aPopup.childNodes.item(aPopup._startMarker + 1));
aPopup._startMarker++;
aPopup.insertBefore(aPopup._siteURIMenuseparator, aPopup._startMarker);
}
},
@ -427,7 +375,6 @@ PlacesViewBase.prototype = {
*/
_setLivemarkStatusMenuItem:
function PVB_setLivemarkStatusMenuItem(aPopup, aStatus) {
let itemId = aPopup._placesNode.itemId;
let statusMenuitem = aPopup._statusMenuitem;
let stringId = "";
if (aStatus == Ci.mozILivemark.STATUS_LOADING)
@ -439,12 +386,11 @@ PlacesViewBase.prototype = {
// Create the status menuitem and cache it in the popup object.
statusMenuitem = document.createElement("menuitem");
statusMenuitem.setAttribute("livemarkStatus", stringId);
statusMenuitem.className = "livemarkstatus-menuitem";
statusMenuitem.setAttribute("label", PlacesUIUtils.getString(stringId));
statusMenuitem.setAttribute("disabled", true);
aPopup.insertBefore(statusMenuitem,
aPopup.childNodes.item(aPopup._startMarker + 1));
aPopup.insertBefore(statusMenuitem, aPopup._startMarker.nextSibling);
aPopup._statusMenuitem = statusMenuitem;
aPopup._startMarker++;
}
else if (stringId &&
statusMenuitem.getAttribute("livemarkStatus") != stringId) {
@ -455,7 +401,6 @@ PlacesViewBase.prototype = {
// The livemark has finished loading.
aPopup.removeChild(aPopup._statusMenuitem);
aPopup._statusMenuitem = null;
aPopup._startMarker--;
}
},
@ -517,6 +462,12 @@ PlacesViewBase.prototype = {
let menu = elt.parentNode;
if (!menu.hasAttribute("livemark")) {
menu.setAttribute("livemark", "true");
#ifdef XP_MACOSX
// OS X native menubar doesn't track list-style-images since
// it doesn't have a frame (bug 733415). Thus enforce updating.
menu.setAttribute("image", "");
menu.removeAttribute("image");
#endif
}
PlacesUtils.livemarks.getLivemark(
@ -580,13 +531,8 @@ PlacesViewBase.prototype = {
// Figure out if we need to show the "<Empty>" menu-item.
// TODO Bug 517701: This doesn't seem to handle the case of an empty
// root.
if (!parentElt.hasChildNodes() ||
(parentElt.childNodes.length == 1 &&
parentElt.firstChild == parentElt._emptyMenuItem))
this._showEmptyMenuItem(parentElt);
if (parentElt._endMarker != -1)
parentElt._endMarker--;
if (parentElt._startMarker.nextSibling == parentElt._endMarker)
this._setEmptyPopupStatus(parentElt, true);
}
},
@ -620,8 +566,9 @@ PlacesViewBase.prototype = {
if (aPlacesNode.parent && aPlacesNode.parent._feedURI) {
// Find the node in the parent.
let popup = aPlacesNode.parent._DOMElement;
for (let i = popup._startMarker; i < popup.childNodes.length; i++) {
let child = popup.childNodes[i];
for (let child = popup._startMarker.nextSibling;
child != popup._endMarker;
child = child.nextSibling) {
if (child._placesNode && child._placesNode.uri == aPlacesNode.uri) {
if (aCount)
child.setAttribute("visited", "true");
@ -649,11 +596,11 @@ PlacesViewBase.prototype = {
if (!parentElt._built)
return;
let index = parentElt._startMarker + 1 + aIndex;
let index = Array.indexOf(parentElt.childNodes, parentElt._startMarker) +
aIndex + 1;
this._insertNewItemToPopup(aPlacesNode, parentElt,
parentElt.childNodes[index]);
if (parentElt._emptyMenuItem)
parentElt._emptyMenuItem.hidden = true;
this._setEmptyPopupStatus(parentElt, false);
},
nodeMoved:
@ -684,7 +631,8 @@ PlacesViewBase.prototype = {
if (parentElt._built) {
// Move the node.
parentElt.removeChild(elt);
let index = parentElt._startMarker + 1 + aNewIndex;
let index = Array.indexOf(parentElt.childNodes, parentElt._startMarker) +
aNewIndex + 1;
parentElt.insertBefore(elt, parentElt.childNodes[index]);
}
},
@ -821,11 +769,9 @@ PlacesViewBase.prototype = {
if (aPopup._endOptOpenAllInTabs) {
aPopup.removeChild(aPopup._endOptOpenAllInTabs);
aPopup._endOptOpenAllInTabs = null;
aPopup._endMarker--;
aPopup.removeChild(aPopup._endOptSeparator);
aPopup._endOptSeparator = null;
aPopup._endMarker--;
}
}
else if (!aPopup._endOptOpenAllInTabs) {
@ -833,7 +779,6 @@ PlacesViewBase.prototype = {
aPopup._endOptSeparator = document.createElement("menuseparator");
aPopup._endOptSeparator.className = "bookmarks-actions-menuseparator";
aPopup.appendChild(aPopup._endOptSeparator);
aPopup._endMarker++;
// Add the "Open All in Tabs" menuitem.
aPopup._endOptOpenAllInTabs = document.createElement("menuitem");
@ -846,13 +791,51 @@ PlacesViewBase.prototype = {
aPopup._endOptOpenAllInTabs.setAttribute("label",
gNavigatorBundle.getString("menuOpenAllInTabs.label"));
aPopup.appendChild(aPopup._endOptOpenAllInTabs);
aPopup._endMarker++;
}
},
_ensureMarkers: function PVB__ensureMarkers(aPopup) {
if (aPopup._startMarker)
return;
// _startMarker is an hidden menuseparator that lives before places nodes.
aPopup._startMarker = document.createElement("menuseparator");
aPopup._startMarker.hidden = true;
aPopup.insertBefore(aPopup._startMarker, aPopup.firstChild);
// _endMarker is an hidden menuseparator that lives after places nodes.
aPopup._endMarker = document.createElement("menuseparator");
aPopup._endMarker.hidden = true;
aPopup.appendChild(aPopup._endMarker);
// Move the markers to the right position.
let firstNonStaticNodeFound = false;
for (let i = 0; i < aPopup.childNodes.length; i++) {
let child = aPopup.childNodes[i];
// Menus that have static content at the end, but are initially empty,
// use a special "builder" attribute to figure out where to start
// inserting places nodes.
if (child.getAttribute("builder") == "end") {
aPopup.insertBefore(aPopup._endMarker, child);
break;
}
if (child._placesNode && !firstNonStaticNodeFound) {
firstNonStaticNodeFound = true;
aPopup.insertBefore(aPopup._startMarker, child);
}
}
if (!firstNonStaticNodeFound) {
aPopup.insertBefore(aPopup._startMarker, aPopup._endMarker);
}
},
_onPopupShowing: function PVB__onPopupShowing(aEvent) {
// Avoid handling popupshowing of inner views.
let popup = aEvent.originalTarget;
this._ensureMarkers(popup);
if (popup._placesNode && PlacesUIUtils.getViewForNode(popup) == this) {
if (!popup._placesNode.containerOpen)
popup._placesNode.containerOpen = true;
@ -1808,8 +1791,6 @@ function PlacesMenu(aPopupShowingEvent, aPlace) {
#ifdef XP_MACOSX
if (this._viewElt.parentNode.localName == "menubar") {
this._nativeView = true;
this._rootElt._startMarker = -1;
this._rootElt._endMarker = -1;
}
#endif
@ -1829,8 +1810,6 @@ PlacesMenu.prototype = {
_removeChild: function PM_removeChild(aChild) {
PlacesViewBase.prototype._removeChild.apply(this, arguments);
if (this._endMarker != -1)
this._endMarker--;
},
uninit: function PM_uninit() {

View File

@ -72,10 +72,6 @@
"popup-internal-box");
</field>
<!-- markers for start and end of valid places items -->
<field name="_startMarker">-1</field>
<field name="_endMarker">-1</field>
<!-- This is the view that manage the popup -->
<field name="_rootView">PlacesUIUtils.getViewForNode(this);</field>
@ -83,17 +79,16 @@
<method name="_hideDropIndicator">
<parameter name="aEvent"/>
<body><![CDATA[
var target = aEvent.target;
let target = aEvent.target;
// in some view we have _startMarker and _endMarker, we should not
// draw the drop indicator outside of them
var betweenMarkers = true;
if (this._startMarker != -1 &&
target.boxObject.y <= this.childNodes[this._startMarker].boxObject.y)
betweenMarkers = false;
if (this._endMarker != -1 &&
target.boxObject.y >= this.childNodes[this._endMarker].boxObject.y)
betweenMarkers = false;
// Don't draw the drop indicator outside of markers.
// The markers are hidden, since otherwise sometimes popups acquire
// scrollboxes on OS X, so we can't use them directly.
let firstChildTop = this._startMarker.nextSibling.boxObject.y;
let lastChildBottom = this._endMarker.previousSibling.boxObject.y +
this._endMarker.previousSibling.boxObject.height;
let betweenMarkers = target.boxObject.y >= firstChildTop ||
target.boxObject.y <= lastChildBottom;
// Hide the dropmarker if current node is not a Places node.
return !(target && target._placesNode && betweenMarkers);

View File

@ -199,7 +199,7 @@ menuitem.bookmark-item {
}
/* Bookmark items */
.bookmark-item:not([container]) {
.bookmark-item {
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
}

View File

@ -229,15 +229,20 @@ toolbarbutton.bookmark-item > menupopup {
list-style-image: url("chrome://global/skin/tree/folder.png");
}
.query-item[container] {
list-style-image: url("chrome://browser/skin/places/history.png");
}
.bookmark-item[livemark] {
.bookmark-item[container][livemark] {
list-style-image: url("chrome://browser/skin/page-livemarks.png");
}
.bookmark-item[query] {
.bookmark-item[container][livemark] .bookmark-item {
list-style-image: url("chrome://browser/skin/places/livemark-item.png");
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
.bookmark-item[container][livemark] .bookmark-item[visited] {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
.bookmark-item[container][query] {
list-style-image: url("chrome://browser/skin/places/query.png");
}
@ -257,20 +262,23 @@ toolbarbutton.bookmark-item > menupopup {
list-style-image: url("chrome://global/skin/tree/folder.png");
}
.bookmark-item[livemark] .menuitem-iconic {
list-style-image: url("chrome://browser/skin/places/livemark-item.png");
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
.bookmark-item[livemark] .menuitem-iconic[visited] {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
.bookmark-item menuitem[openInTabs],
.bookmark-item menuitem[siteURI] {
/* Workaround for native menubar inheritance */
.openintabs-menuitem,
.openlivemarksite-menuitem,
.livemarkstatus-menuitem {
list-style-image: none;
}
.bookmark-item[cutting] > .toolbarbutton-icon,
.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-icon {
opacity: 0.5;
}
.bookmark-item[cutting] > .toolbarbutton-text,
.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-text {
opacity: 0.7;
}
#wrapper-personal-bookmarks[place="palette"] > .toolbarpaletteitem-box {
background: url("chrome://browser/skin/places/bookmarksToolbar.png") no-repeat center;
}
@ -287,16 +295,6 @@ toolbarbutton.bookmark-item > menupopup {
height: 16px;
}
.bookmark-item[cutting] > .toolbarbutton-icon,
.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-icon {
opacity: 0.5;
}
.bookmark-item[cutting] > .toolbarbutton-text,
.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-text {
opacity: 0.7;
}
#bookmarksToolbarFolderMenu,
#BMB_bookmarksToolbar {
list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");

View File

@ -77,5 +77,5 @@ public interface Driver {
* @return A 2-D array of pixels (indexed by y, then x). The pixels
* are in ARGB-8888 format.
*/
int[][] getPaintedSurface();
PaintedSurface getPaintedSurface();
}

View File

@ -48,6 +48,8 @@ import java.io.IOException;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.List;
import java.io.FileOutputStream;
import java.io.DataOutputStream;
import java.lang.Class;
import java.lang.reflect.InvocationTargetException;
@ -291,7 +293,7 @@ public class FennecNativeDriver implements Driver {
return null;
}
public int[][] getPaintedSurface() {
public PaintedSurface getPaintedSurface() {
GLSurfaceView view = getSurfaceView();
if (view == null) {
return null;
@ -309,14 +311,34 @@ public class FennecNativeDriver implements Driver {
int w = view.getWidth();
int h = view.getHeight();
pixelBuffer.position(0);
int[][] pixels = new int[h][w];
for (int y = h - 1; y >= 0; y--) {
for (int x = 0; x < w; x++) {
int agbr = pixelBuffer.get();
pixels[y][x] = (agbr & 0xFF00FF00) | ((agbr >> 16) & 0x000000FF) | ((agbr << 16) & 0x00FF0000);
String mapFile = "/mnt/sdcard/pixels.map";
FileOutputStream fos = null;
DataOutputStream dos = null;
try {
fos = new FileOutputStream(mapFile);
dos = new DataOutputStream(fos);
for (int y = h - 1; y >= 0; y--) {
for (int x = 0; x < w; x++) {
int agbr = pixelBuffer.get();
dos.writeInt((agbr & 0xFF00FF00) | ((agbr >> 16) & 0x000000FF) | ((agbr << 16) & 0x00FF0000));
}
}
return new PaintedSurface(mapFile, w, h);
} catch (IOException e) {
throw new RoboCopException("exception with pixel writer on file: " + mapFile);
} finally {
try {
if (dos != null && fos != null) {
dos.flush();
dos.close();
fos.close();
}
} catch (IOException e) {
throw new RoboCopException("exception closing pixel writer on file: " + mapFile);
}
}
return pixels;
}
public int mHeight=0;

View File

@ -61,6 +61,7 @@ _JAVA_HARNESS = \
FennecNativeDriver.java \
FennecNativeElement.java \
RoboCopException.java \
PaintedSurface.java \
$(NULL)
_JAVA_TESTS = $(patsubst $(TESTPATH)/%.in,%,$(wildcard $(TESTPATH)/*.java.in))

View File

@ -0,0 +1,62 @@
#filter substitution
/* 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/. */
package @ANDROID_PACKAGE_NAME@;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class PaintedSurface {
private String mFileName = null;
private int mWidth = -1;
private int mHeight = -1;
private MappedByteBuffer mPixelBuffer = null;
public PaintedSurface(String filename, int width, int height) {
mFileName = filename;
mWidth = width;
mHeight = height;
try {
File f = new File(filename);
int pixelSize = (int)f.length();
FileInputStream pixelFile = new FileInputStream(filename);
mPixelBuffer = pixelFile.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, pixelSize);
} catch (java.io.FileNotFoundException e) {
e.printStackTrace();
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
public final int getPixelAt(int x, int y) {
if (mPixelBuffer == null) {
throw new RoboCopException("Trying to access PaintedSurface with no active PixelBuffer");
}
if (x >= mWidth || x < 0) {
throw new RoboCopException("Trying to access PaintedSurface with invalid x value");
}
if (y >= mHeight || y < 0) {
throw new RoboCopException("Trying to access PaintedSurface with invalid y value");
}
// The rows are reversed so row 0 is at the end and we start with the last row.
// This is why we do mHeight-y;
int index = (x + ((mHeight - y - 1) * mWidth)) * 4;
int b1 = mPixelBuffer.get(index) & 0xFF;
int b2 = mPixelBuffer.get(index + 1) & 0xFF;
int b3 = mPixelBuffer.get(index + 2) & 0xFF;
int b4 = mPixelBuffer.get(index + 3) & 0xFF;
int value = (b1 << 24) + (b2 << 16) + (b3 << 8) + (b4 << 0);
return value;
}
}

View File

@ -148,6 +148,9 @@ xpcshell-tests:
$(testxpcsrcdir)/runxpcshelltests.py \
--symbols-path=$(DIST)/crashreporter-symbols \
--build-info-json=$(DEPTH)/mozinfo.json \
--tests-root-dir=$(testxpcobjdir) \
--xunit-file=$(testxpcobjdir)/$(relativesrcdir)/results.xml \
--xunit-suite-name=xpcshell \
$(EXTRA_TEST_ARGS) \
$(LIBXUL_DIST)/bin/xpcshell \
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))

View File

@ -628,9 +628,10 @@ if test "$GXX" = "yes"; then
GNU_CXX=1
CXX_VERSION=`$CXX -v 2>&1 | grep 'gcc version'`
fi
if test "`echo | $AS -v 2>&1 | grep -c GNU`" != "0"; then
if test "`echo | $AS -o conftest.out -v 2>&1 | grep -c GNU`" != "0"; then
GNU_AS=1
fi
rm -f conftest.out
if test "`echo | $LD -v 2>&1 | grep -c GNU`" != "0"; then
GNU_LD=1
fi

View File

@ -597,29 +597,10 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
if (aCx && wrapper) {
nsIXPConnect *xpc = nsContentUtils::XPConnect();
if (xpc) {
JSObject *preservedWrapper = nsnull;
// If reparenting moves us to a new compartment, preserving causes
// problems. In that case, we release ourselves and re-preserve after
// reparenting so we're sure to have the right JS object preserved.
// We use a JSObject stack copy of the wrapper to protect it from GC
// under ReparentWrappedNativeIfFound.
if (aNode->PreservingWrapper()) {
preservedWrapper = wrapper;
nsContentUtils::ReleaseWrapper(aNode, aNode);
NS_ASSERTION(aNode->GetWrapper(),
"ReleaseWrapper cleared our wrapper, this code needs to "
"be changed to deal with that!");
}
nsCOMPtr<nsIXPConnectJSObjectHolder> oldWrapper;
rv = xpc->ReparentWrappedNativeIfFound(aCx, wrapper, aNewScope, aNode,
getter_AddRefs(oldWrapper));
if (preservedWrapper) {
nsContentUtils::PreserveWrapper(aNode, aNode);
}
if (NS_FAILED(rv)) {
aNode->mNodeInfo.swap(nodeInfo);

View File

@ -602,7 +602,7 @@ nsWebSocket::Initialize(nsISupports* aOwner,
if (JSVAL_IS_OBJECT(aArgv[1]) &&
(jsobj = JSVAL_TO_OBJECT(aArgv[1])) &&
JS_IsArrayObject(aContext, jsobj)) {
jsuint len;
uint32_t len;
JS_GetArrayLength(aContext, jsobj, &len);
for (PRUint32 index = 0; index < len; ++index) {

View File

@ -122,7 +122,7 @@ JSValToMatrixElts(JSContext* cx, const jsval& val,
double* (&elts)[N], nsresult* rv)
{
JSObject* obj;
jsuint length;
uint32_t length;
if (JSVAL_IS_PRIMITIVE(val) ||
!(obj = JSVAL_TO_OBJECT(val)) ||

View File

@ -146,11 +146,11 @@ JSValToDashArray(JSContext* cx, const jsval& patternArray,
{
// The cap is pretty arbitrary. 16k should be enough for
// anybody...
static const jsuint MAX_NUM_DASHES = 1 << 14;
static const uint32_t MAX_NUM_DASHES = 1 << 14;
if (!JSVAL_IS_PRIMITIVE(patternArray)) {
JSObject* obj = JSVAL_TO_OBJECT(patternArray);
jsuint length;
uint32_t length;
if (!JS_GetArrayLength(cx, obj, &length)) {
// Not an array-like thing
return NS_ERROR_INVALID_ARG;

View File

@ -42,6 +42,7 @@
#include "nsMediaCache.h"
#include "nsDirectoryServiceUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsXULAppAPI.h"
#include "nsNetUtil.h"
#include "prio.h"
#include "nsThreadUtils.h"
@ -545,8 +546,15 @@ nsMediaCache::Init()
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
NS_ASSERTION(!mFD, "Cache file already open?");
// In single process Gecko, store the media cache in the profile directory
// so that multiple users can use separate media caches concurrently.
// In multi-process Gecko, there is no profile dir, so just store it in the
// system temp directory instead.
nsresult rv;
nsCOMPtr<nsIFile> tmp;
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmp));
const char* dir = (XRE_GetProcessType() == GeckoProcessType_Content) ?
NS_OS_TEMP_DIR : NS_APP_USER_PROFILE_LOCAL_50_DIR;
rv = NS_GetSpecialDirectory(dir, getter_AddRefs(tmp));
NS_ENSURE_SUCCESS(rv,rv);
nsCOMPtr<nsILocalFile> tmpFile = do_QueryInterface(tmp);

View File

@ -0,0 +1,80 @@
/* 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/. */
/**
* helper object for APIs that deal with DOMRequest and need to release them properly
* when the window goes out of scope
*/
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
let EXPORTED_SYMBOLS = ["DOMRequestIpcHelper"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyGetter(Services, "rs", function() {
return Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci.nsIDOMRequestService);
});
XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
return Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
});
function DOMRequestIpcHelper() {
}
DOMRequestIpcHelper.prototype = {
getRequestId: function(aRequest) {
let id = "id" + this._getRandomId();
this._requests[id] = aRequest;
return id;
},
getRequest: function(aId) {
if (this._requests[aId])
return this._requests[aId];
},
removeRequest: function(aId) {
if (this._requests[aId])
delete this._requests[aId];
},
_getRandomId: function() {
return Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
},
observe: function(aSubject, aTopic, aData) {
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (wId == this.innerWindowID) {
Services.obs.removeObserver(this, "inner-window-destroyed");
this._requests = [];
this._window = null;
this._messages.forEach((function(msgName) {
cpmm.removeMessageListener(msgName, this);
}).bind(this));
if(this.uninit)
this.uninit();
}
},
initHelper: function(aWindow, aMessages) {
this._messages = aMessages;
this._requests = [];
this._window = aWindow;
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
this.innerWindowID = util.currentInnerWindowID;
this._id = this._getRandomId();
Services.obs.addObserver(this, "inner-window-destroyed", false);
this._messages.forEach((function(msgName) {
cpmm.addMessageListener(msgName, this);
}).bind(this));
},
createRequest: function() {
return Services.rs.createRequest(this._window);
}
}

View File

@ -66,6 +66,7 @@ EXTRA_COMPONENTS = \
$(NULL)
EXTRA_JS_MODULES += Webapps.jsm \
DOMRequestHelper.jsm \
$(NULL)
endif

View File

@ -1,38 +1,6 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Open Web Apps.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Fabrice Desré <fabrice@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* 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/. */
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -41,27 +9,31 @@ const Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
XPCOMUtils.defineLazyGetter(Services, "rs", function() {
return Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci.nsIDOMRequestService);
});
XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
return Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
});
function convertAppsArray(aApps, aWindow) {
let apps = new Array();
for (let i = 0; i < aApps.length; i++) {
let app = aApps[i];
apps.push(new WebappsApplication(aWindow, app.origin, app.manifest, app.manifestURL,
app.receipts, app.installOrigin, app.installTime));
}
return apps;
}
function WebappsRegistry() {
this.messages = ["Webapps:Install:Return:OK", "Webapps:Install:Return:KO",
"Webapps:Uninstall:Return:OK", "Webapps:Uninstall:Return:KO",
"Webapps:Enumerate:Return:OK", "Webapps:Enumerate:Return:KO"];
this.mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
this.messages.forEach((function(msgName) {
this.mm.addMessageListener(msgName, this);
}).bind(this));
this._window = null;
this._id = this._getRandomId();
this._callbacks = [];
}
WebappsRegistry.prototype = {
_onerror: null,
_oninstall: null,
_onuninstall: null,
__proto__: DOMRequestIpcHelper.prototype,
/** from https://developer.mozilla.org/en/OpenWebApps/The_Manifest
* only the name property is mandatory
@ -70,7 +42,7 @@ WebappsRegistry.prototype = {
// TODO : check for install_allowed_from
if (aManifest.name == undefined)
return false;
if (aManifest.installs_allowed_from) {
ok = false;
aManifest.installs_allowed_from.forEach(function(aOrigin) {
@ -81,97 +53,41 @@ WebappsRegistry.prototype = {
}
return true;
},
getCallbackId: function(aCallback) {
let id = "id" + this._getRandomId();
this._callbacks[id] = aCallback;
return id;
},
getCallback: function(aId) {
return this._callbacks[aId];
},
removeCallback: function(aId) {
if (this._callbacks[aId])
delete this._callbacks[aId];
},
_getRandomId: function() {
return Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
},
_convertAppsArray: function(aApps) {
let apps = new Array();
for (let i = 0; i < aApps.length; i++) {
let app = aApps[i];
apps.push(new WebappsApplication(app.origin, app.manifest, app.receipt, app.installOrigin, app.installTime));
}
return apps;
},
set oninstall(aCallback) {
if (this.hasPrivileges)
this._oninstall = aCallback;
else
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
set onuninstall(aCallback) {
if (this.hasPrivileges)
this._onuninstall = aCallback;
else
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
set onerror(aCallback) {
this._onerror = aCallback;
},
receiveMessage: function(aMessage) {
let msg = aMessage.json;
if (!(msg.oid == this._id || aMessage.name == "Webapps:Install:Return:OK" || aMessage.name == "Webapps:Uninstall:Return:OK"))
if (msg.oid != this._id)
return
let req = this.getRequest(msg.requestID);
if (!req)
return;
let app = msg.app;
let cb;
switch (aMessage.name) {
case "Webapps:Install:Return:OK":
if (this._oninstall)
this._oninstall.handleEvent(new WebappsApplication(app.origin, app.manifest, app.receipt,
Services.rs.fireSuccess(req, new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
app.installOrigin, app.installTime));
break;
case "Webapps:Install:Return:KO":
if (this._onerror)
this._onerror.handleEvent(new RegistryError(Ci.mozIDOMApplicationRegistryError.DENIED));
Services.rs.fireError(req, "DENIED");
break;
case "Webapps:Uninstall:Return:OK":
if (this._onuninstall)
this._onuninstall.handleEvent(new WebappsApplication(msg.origin, null, null, null, 0));
break;
case "Webapps:Uninstall:Return:KO":
if (this._onerror)
this._onerror.handleEvent(new RegistryError(Ci.mozIDOMApplicationRegistryError.PERMISSION_DENIED));
break;
case "Webapps:Enumerate:Return:OK":
cb = this.getCallback(msg.callbackID);
if (cb.success) {
let apps = this._convertAppsArray(msg.apps);
cb.success.handleEvent(apps, apps.length);
case "Webapps:GetSelf:Return:OK":
if (msg.apps.length) {
app = msg.apps[0];
Services.rs.fireSuccess(req, new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
app.installOrigin, app.installTime));
} else {
Services.rs.fireSuccess(req, null);
}
break;
case "Webapps:Enumerate:Return:KO":
cb = this.getCallback(msg.callbackID);
if (cb.error)
cb.error.handleEvent(new RegistryError(Ci.mozIDOMApplicationRegistryError.PERMISSION_DENIED));
case "Webapps:GetInstalled:Return:OK":
Services.rs.fireSuccess(req, convertAppsArray(msg.apps, this._window));
break;
case "Webapps:GetSelf:Return:KO":
case "Webapps:GetInstalled:Return:KO":
Services.rs.fireError(req, "ERROR");
break;
}
this.removeCallback(msg.callbackID);
},
_fireError: function(aCode) {
if (!this._onerror)
return;
this._onerror.handleEvent(new RegistryError(aCode));
this.removeRequest(msg.requestID);
},
_getOrigin: function(aURL) {
@ -181,7 +97,9 @@ WebappsRegistry.prototype = {
// mozIDOMApplicationRegistry implementation
install: function(aURL, aReceipt) {
install: function(aURL, aParams) {
let request = this.createRequest();
let requestID = this.getRequestId(request);
let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
xhr.open("GET", aURL, true);
@ -191,90 +109,70 @@ WebappsRegistry.prototype = {
let installOrigin = this._getOrigin(this._window.location.href);
let manifest = JSON.parse(xhr.responseText, installOrigin);
if (!this.checkManifest(manifest, installOrigin)) {
this._fireError(Ci.mozIDOMApplicationRegistryError.INVALID_MANIFEST);
Services.rs.fireError(request, "INVALID_MANIFEST");
} else {
this.mm.sendAsyncMessage("Webapps:Install", { app: { installOrigin: installOrigin,
origin: this._getOrigin(aURL),
manifest: manifest,
receipt: aReceipt },
from: this._window.location.href,
oid: this._id });
let receipts = (aParams && aParams.receipts && Array.isArray(aParams.receipts)) ? aParams.receipts : [];
cpmm.sendAsyncMessage("Webapps:Install", { app: { installOrigin: installOrigin,
origin: this._getOrigin(aURL),
manifestURL: aURL,
manifest: manifest,
receipts: receipts },
from: this._window.location.href,
oid: this._id,
requestID: requestID });
}
} catch(e) {
this._fireError(Ci.mozIDOMApplicationRegistryError.MANIFEST_PARSE_ERROR);
Services.rs.fireError(request, "MANIFEST_PARSE_ERROR");
}
}
else {
this._fireError(Ci.mozIDOMApplicationRegistryError.MANIFEST_URL_ERROR);
Services.rs.fireError(request, "MANIFEST_URL_ERROR");
}
}).bind(this), false);
xhr.addEventListener("error", (function() {
this._fireError(Ci.mozIDOMApplicationRegistryError.NETWORK_ERROR);
Services.rs.fireError(request, "NETWORK_ERROR");
}).bind(this), false);
xhr.send(null);
return request;
},
uninstall: function(aOrigin) {
if (this.hasPrivileges)
this.mm.sendAsyncMessage("Webapps:Uninstall", { from: this._window.location.href,
origin: aOrigin,
oid: this._id });
else
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
getSelf: function() {
let request = this.createRequest();
cpmm.sendAsyncMessage("Webapps:GetSelf", { origin: this._getOrigin(this._window.location.href),
oid: this._id,
requestID: this.getRequestId(request) });
return request;
},
launch: function(aOrigin) {
this.mm.sendAsyncMessage("Webapps:Launch", { origin: aOrigin,
from: this._window.location.href});
},
enumerate: function(aSuccess, aError) {
this.mm.sendAsyncMessage("Webapps:Enumerate", { from: this._window.location.href,
origin: this._getOrigin(this._window.location.href),
getInstalled: function() {
let request = this.createRequest();
cpmm.sendAsyncMessage("Webapps:GetInstalled", { origin: this._getOrigin(this._window.location.href),
oid: this._id,
callbackID: this.getCallbackId({ success: aSuccess, error: aError }) });
requestID: this.getRequestId(request) });
return request;
},
enumerateAll: function(aSuccess, aError) {
if (this.hasPrivileges) {
this.mm.sendAsyncMessage("Webapps:EnumerateAll", { from: this._window.location.href,
origin: this._getOrigin(this._window.location.href),
oid: this._id,
callbackID: this.getCallbackId({ success: aSuccess, error: aError }) });
} else {
if (aError)
aError.handleEvent(new RegistryError(Ci.mozIDOMApplicationRegistryError.PERMISSION_DENIED));
}
get mgmt() {
if (!this._mgmt)
this._mgmt = new WebappsApplicationMgmt(this._window);
return this._mgmt;
},
observe: function(aSubject, aTopic, aData) {
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (wId == this.innerWindowID) {
Services.obs.removeObserver(this, "inner-window-destroyed");
this._oninstall = null;
this._onuninstall = null;
this._onerror = null;
this._callbacks = [];
this._window = null;
}
uninit: function() {
this._mgmt = null;
},
// nsIDOMGlobalPropertyInitializer implementation
init: function(aWindow) {
dump("DOMApplicationRegistry::init() " + aWindow + "\n");
this._window = aWindow;
this._window.appId = this._id;
let from = Services.io.newURI(this._window.location.href, null, null);
let perm = Services.perms.testExactPermission(from, "webapps-manage");
//only pages with perm set and chrome or about pages can uninstall, enumerate all set oninstall an onuninstall
this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION || from.schemeIs("chrome") || from.schemeIs("about");
this.initHelper(aWindow, ["Webapps:Install:Return:OK", "Webapps:Install:Return:KO",
"Webapps:GetInstalled:Return:OK", "Webapps:GetInstalled:Return:KO",
"Webapps:GetSelf:Return:OK", "Webapps:GetSelf:Return:KO"]);
Services.obs.addObserver(this, "inner-window-destroyed", false);
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
this.innerWindowID = util.currentInnerWindowID;
this._id = util.outerWindowID;
},
classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
@ -288,18 +186,26 @@ WebappsRegistry.prototype = {
classDescription: "Webapps Registry"})
}
function WebappsApplication(aOrigin, aManifest, aReceipt, aInstallOrigin, aInstallTime) {
/**
* mozIDOMApplication object
*/
function WebappsApplication(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime) {
this._origin = aOrigin;
this._manifest = aManifest;
this._receipt = aReceipt;
this._manifestURL = aManifestURL;
this._receipts = aReceipts;
this._installOrigin = aInstallOrigin;
this._installTime = aInstallTime;
this.initHelper(aWindow, ["Webapps:Uninstall:Return:OK", "Webapps:Uninstall:Return:KO"]);
}
WebappsApplication.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
_origin: null,
_manifest: null,
_receipt: null,
_manifestURL: null,
_receipts: [],
_installOrigin: null,
_installTime: 0,
@ -311,8 +217,12 @@ WebappsApplication.prototype = {
return this._manifest;
},
get receipt() {
return this._receipt;
get manifestURL() {
return this._manifestURL;
},
get receipts() {
return this._receipts;
},
get installOrigin() {
@ -323,6 +233,39 @@ WebappsApplication.prototype = {
return this._installTime;
},
launch: function(aStartPoint) {
let request = this.createRequest();
cpmm.sendAsyncMessage("Webapps:Launch", { origin: this._origin,
startPoint: aStartPoint,
oid: this._id,
requestID: this.getRequestId(request) });
return request;
},
uninstall: function() {
let request = this.createRequest();
cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: this._origin,
oid: this._id,
requestID: this.getRequestId(request) });
return request;
},
receiveMessage: function(aMessage) {
var msg = aMessage.json;
let req = this.getRequest(msg.requestID);
if (msg.oid != this._id || !req)
return;
switch (aMessage.name) {
case "Webapps:Uninstall:Return:OK":
Services.rs.fireSuccess(req, msg.origin);
break;
case "Webapps:Uninstall:Return:KO":
Services.rs.fireError(req, msg.origin);
break;
}
this.removeRequest(msg.requestID);
},
classID: Components.ID("{723ed303-7757-4fb0-b261-4f78b1f6bd22}"),
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplication]),
@ -334,26 +277,131 @@ WebappsApplication.prototype = {
classDescription: "Webapps Application"})
}
function RegistryError(aCode) {
this._code = aCode;
/**
* mozIDOMApplicationMgmt object
*/
function WebappsApplicationMgmt(aWindow) {
let principal = aWindow.document.nodePrincipal;
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
let perm = principal == secMan.getSystemPrincipal() ?
Ci.nsIPermissionManager.ALLOW_ACTION :
Services.perms.testExactPermission(principal.URI, "webapps-manage");
//only pages with perm set can use some functions
this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION;
this.initHelper(aWindow, ["Webapps:GetAll:Return:OK", "Webapps:GetAll:Return:KO",
"Webapps:Install:Return:OK", "Webapps:Uninstall:Return:OK"]);
this._oninstall = null;
this._onuninstall = null;
}
RegistryError.prototype = {
_code: null,
get code() {
return this._code;
WebappsApplicationMgmt.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
uninit: function() {
this._oninstall = null;
this._onuninstall = null;
},
classID: Components.ID("{b4937718-11a3-400b-a69f-ab442a418569}"),
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationRegistryError]),
getAll: function() {
let request = this.createRequest();
cpmm.sendAsyncMessage("Webapps:GetAll", { oid: this._id,
requestID: this.getRequestId(request),
hasPrivileges: this.hasPrivileges });
return request;
},
classInfo: XPCOMUtils.generateCI({classID: Components.ID("{b4937718-11a3-400b-a69f-ab442a418569}"),
contractID: "@mozilla.org/webapps/error;1",
interfaces: [Ci.mozIDOMApplicationRegistryError],
get oninstall() {
return this._oninstall;
},
get onuninstall() {
this._onuninstall;
},
set oninstall(aCallback) {
if (this.hasPrivileges)
this._oninstall = aCallback;
else
throw new Components.exception("Denied", Cr.NS_ERROR_FAILURE);
},
set onuninstall(aCallback) {
if (this.hasPrivileges)
this._onuninstall = aCallback;
else
throw new Components.exception("Denied", Cr.NS_ERROR_FAILURE);
},
receiveMessage: function(aMessage) {
var msg = aMessage.json;
let req = this.getRequest(msg.requestID);
// We want Webapps:Install:Return:OK and Webapps:Uninstall:Return:OK to be boradcasted
// to all instances of mozApps.mgmt
if (!((msg.oid == this._id && req)
|| aMessage.name == "Webapps:Install:Return:OK" || aMessage.name == "Webapps:Uninstall:Return:OK"))
return;
switch (aMessage.name) {
case "Webapps:GetAll:Return:OK":
Services.rs.fireSuccess(req, convertAppsArray(msg.apps, this._window));
break;
case "Webapps:GetAll:Return:KO":
Services.rs.fireError(req, "DENIED");
break;
case "Webapps:Install:Return:OK":
if (this._oninstall) {
let app = msg.app;
let event = new WebappsApplicationEvent(new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
app.installOrigin, app.installTime));
this._oninstall.handleEvent(event);
}
break;
case "Webapps:Uninstall:Return:OK":
if (this._onuninstall) {
let event = new WebappsApplicationEvent(new WebappsApplication(this._window, msg.origin, null, null, null, null, 0));
this._onuninstall.handleEvent(event);
}
break;
}
this.removeRequest(msg.requestID);
},
classID: Components.ID("{8c1bca96-266f-493a-8d57-ec7a95098c15}"),
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationMgmt]),
classInfo: XPCOMUtils.generateCI({classID: Components.ID("{8c1bca96-266f-493a-8d57-ec7a95098c15}"),
contractID: "@mozilla.org/webapps/application-mgmt;1",
interfaces: [Ci.mozIDOMApplicationMgmt],
flags: Ci.nsIClassInfo.DOM_OBJECT,
classDescription: "Webapps Registry Error"})
classDescription: "Webapps Application Mgmt"})
}
const NSGetFactory = XPCOMUtils.generateNSGetFactory([WebappsRegistry, WebappsApplication, RegistryError]);
/**
* mozIDOMApplicationEvent object
*/
function WebappsApplicationEvent(aApp) {
this._app = aApp;
}
WebappsApplicationEvent.prototype = {
get application() {
return this._app;
},
classID: Components.ID("{5bc42b2a-9acc-49d5-a336-c353c8125e48}"),
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationEvent]),
classInfo: XPCOMUtils.generateCI({classID: Components.ID("{8c1bca96-266f-493a-8d57-ec7a95098c15}"),
contractID: "@mozilla.org/webapps/application-event;1",
interfaces: [Ci.mozIDOMApplicationEvent],
flags: Ci.nsIClassInfo.DOM_OBJECT,
classDescription: "Webapps Application Event"})
}
const NSGetFactory = XPCOMUtils.generateNSGetFactory([WebappsRegistry, WebappsApplication]);

View File

@ -1,39 +1,6 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Mobile Browser.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Fabrice Desré <fabrice@mozilla.com>
* Mark Finkle <mfinkle@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* 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/. */
const Cu = Components.utils;
const Cc = Components.classes;
@ -50,17 +17,21 @@ XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
return NetUtil;
});
XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
return Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
});
let DOMApplicationRegistry = {
appsFile: null,
webapps: { },
init: function() {
this.mm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
let messages = ["Webapps:Install", "Webapps:Uninstall",
"Webapps:Enumerate", "Webapps:EnumerateAll", "Webapps:Launch"];
"Webapps:GetSelf", "Webapps:GetInstalled",
"Webapps:Launch", "Webapps:GetAll"];
messages.forEach((function(msgName) {
this.mm.addMessageListener(msgName, this);
ppmm.addMessageListener(msgName, this);
}).bind(this));
let appsDir = FileUtils.getDir("ProfD", ["webapps"], true, true);
@ -114,29 +85,29 @@ let DOMApplicationRegistry = {
receiveMessage: function(aMessage) {
let msg = aMessage.json;
let from = Services.io.newURI(msg.from, null, null);
let perm = Services.perms.testExactPermission(from, "webapps-manage");
//only pages with perm set and chrome or about pages can uninstall, enumerate all set oninstall an onuninstall
let hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION || from.schemeIs("chrome") || from.schemeIs("about");
switch (aMessage.name) {
case "Webapps:Install":
// always ask for UI to install
Services.obs.notifyObservers(this, "webapps-ask-install", JSON.stringify(msg));
break;
case "Webapps:GetSelf":
this.getSelf(msg);
break;
case "Webapps:Uninstall":
if (hasPrivileges)
this.uninstall(msg);
this.uninstall(msg);
break;
case "Webapps:Launch":
Services.obs.notifyObservers(this, "webapps-launch", JSON.stringify(msg));
break;
case "Webapps:Enumerate":
this.enumerate(msg);
case "Webapps:GetInstalled":
this.getInstalled(msg);
break;
case "Webapps:EnumerateAll":
this.enumerateAll(msg);
case "Webapps:GetAll":
if (msg.hasPrivileges)
this.getAll(msg);
else
ppmm.sendAsyncMessage("Webapps:GetAll:Return:KO", msg);
break;
}
},
@ -162,14 +133,15 @@ let DOMApplicationRegistry = {
let clone = {
installOrigin: aApp.installOrigin,
origin: aApp.origin,
receipt: aApp.receipt,
installTime: aApp.installTime
receipts: aApp.receipts,
installTime: aApp.installTime,
manifestURL: aApp.manifestURL
};
return clone;
},
denyInstall: function(aData) {
this.mm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
ppmm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
},
confirmInstall: function(aData, aFromSync) {
@ -202,7 +174,7 @@ let DOMApplicationRegistry = {
if (!aFromSync)
this._saveApps((function() {
this.mm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
ppmm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
Services.obs.notifyObservers(this, "webapps-sync-install", id);
}).bind(this));
},
@ -244,9 +216,11 @@ let DOMApplicationRegistry = {
},
uninstall: function(aData) {
let found = false;
for (let id in this.webapps) {
let app = this.webapps[id];
if (app.origin == aData.origin) {
found = true;
delete this.webapps[id];
let dir = FileUtils.getDir("ProfD", ["webapps", id], true, true);
try {
@ -254,62 +228,53 @@ let DOMApplicationRegistry = {
} catch (e) {
}
this._saveApps((function() {
this.mm.sendAsyncMessage("Webapps:Uninstall:Return:OK", aData);
ppmm.sendAsyncMessage("Webapps:Uninstall:Return:OK", aData);
Services.obs.notifyObservers(this, "webapps-sync-uninstall", id);
}).bind(this));
}
}
if (!found)
ppmm.sendAsyncMessage("Webapps:Uninstall:Return:KO", aData);
},
enumerate: function(aData) {
getSelf: function(aData) {
aData.apps = [];
let tmp = [];
let selfId;
let id = this._appId(aData.origin);
// if it's an app, add itself to the result
if (id) {
let app = this._cloneAppObject(this.webapps[id]);
aData.apps.push(app);
tmp.push({ id: id });
selfId = id;
}
// check if it's a store.
let isStore = false;
this._readManifests(tmp, (function(aResult) {
for (let i = 0; i < aResult.length; i++)
aData.apps[i].manifest = aResult[i].manifest;
ppmm.sendAsyncMessage("Webapps:GetSelf:Return:OK", aData);
}).bind(this));
},
getInstalled: function(aData) {
aData.apps = [];
let tmp = [];
let id = this._appId(aData.origin);
for (id in this.webapps) {
let app = this.webapps[id];
if (app.installOrigin == aData.origin) {
isStore = true;
break;
}
}
// add all the apps from this store
if (isStore) {
for (id in this.webapps) {
if (id == selfId)
continue;
let app = this._cloneAppObject(this.webapps[id]);
if (app.installOrigin == aData.origin) {
aData.apps.push(app);
tmp.push({ id: id });
}
if (this.webapps[id].installOrigin == aData.origin) {
aData.apps.push(this._cloneAppObject(this.webapps[id]));
tmp.push({ id: id });
}
}
this._readManifests(tmp, (function(aResult) {
for (let i = 0; i < aResult.length; i++)
aData.apps[i].manifest = aResult[i].manifest;
this.mm.sendAsyncMessage("Webapps:Enumerate:Return:OK", aData);
ppmm.sendAsyncMessage("Webapps:GetInstalled:Return:OK", aData);
}).bind(this));
},
denyEnumerate: function(aData) {
this.mm.sendAsyncMessage("Webapps:Enumerate:Return:KO", aData);
},
enumerateAll: function(aData) {
getAll: function(aData) {
aData.apps = [];
let tmp = [];
@ -322,7 +287,7 @@ let DOMApplicationRegistry = {
this._readManifests(tmp, (function(aResult) {
for (let i = 0; i < aResult.length; i++)
aData.apps[i].manifest = aResult[i].manifest;
this.mm.sendAsyncMessage("Webapps:Enumerate:Return:OK", aData);
ppmm.sendAsyncMessage("Webapps:GetAll:Return:OK", aData);
}).bind(this));
},
@ -368,7 +333,7 @@ let DOMApplicationRegistry = {
dir.remove(true);
} catch (e) {
}
this.mm.sendAsyncMessage("Webapps:Uninstall:Return:OK", { origin: origin });
ppmm.sendAsyncMessage("Webapps:Uninstall:Return:OK", { origin: origin });
} else {
if (!!this.webapps[record.id]) {
this.webapps[record.id] = record.value;
@ -377,7 +342,7 @@ let DOMApplicationRegistry = {
else {
let data = { app: record.value };
this.confirmInstall(data, true);
this.mm.sendAsyncMessage("Webapps:Install:Return:OK", data);
ppmm.sendAsyncMessage("Webapps:Install:Return:OK", data);
}
}
}

View File

@ -2,9 +2,3 @@
component {fff440b3-fae2-45c1-bf03-3b5a2e432270} Webapps.js
contract @mozilla.org/webapps;1 {fff440b3-fae2-45c1-bf03-3b5a2e432270}
category JavaScript-navigator-property mozApps @mozilla.org/webapps;1
component {723ed303-7757-4fb0-b261-4f78b1f6bd22} Webapps.js
contract @mozilla.org/webapps/application;1 {723ed303-7757-4fb0-b261-4f78b1f6bd22}
component {b4937718-11a3-400b-a69f-ab442a418569} Webapps.js
contract @mozilla.org/webapps/error;1 {b4937718-11a3-400b-a69f-ab442a418569}

View File

@ -90,7 +90,7 @@ ConvertCloneReadInfosToArrayInternal(
}
if (!aReadInfos.IsEmpty()) {
if (!JS_SetArrayLength(aCx, array, jsuint(aReadInfos.Length()))) {
if (!JS_SetArrayLength(aCx, array, uint32_t(aReadInfos.Length()))) {
NS_WARNING("Failed to set array length!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}

View File

@ -410,7 +410,7 @@ IDBDatabase::CreateObjectStore(const nsAString& aName,
JSObject* obj = JSVAL_TO_OBJECT(val);
jsuint length;
uint32_t length;
if (!JS_GetArrayLength(aCx, obj, &length)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
@ -421,7 +421,7 @@ IDBDatabase::CreateObjectStore(const nsAString& aName,
keyPathArray.SetCapacity(length);
for (jsuint index = 0; index < length; index++) {
for (uint32_t index = 0; index < length; index++) {
jsval val;
JSString* jsstr;
nsDependentJSString str;
@ -566,7 +566,7 @@ IDBDatabase::Transaction(const jsval& aStoreNames,
// See if this is a JS array.
if (JS_IsArrayObject(aCx, obj)) {
jsuint length;
uint32_t length;
if (!JS_GetArrayLength(aCx, obj, &length)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
@ -577,7 +577,7 @@ IDBDatabase::Transaction(const jsval& aStoreNames,
storesToOpen.SetCapacity(length);
for (jsuint index = 0; index < length; index++) {
for (uint32_t index = 0; index < length; index++) {
jsval val;
JSString* jsstr;
nsDependentJSString str;

View File

@ -904,7 +904,7 @@ GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
}
if (!keys.IsEmpty()) {
if (!JS_SetArrayLength(aCx, array, jsuint(keys.Length()))) {
if (!JS_SetArrayLength(aCx, array, uint32_t(keys.Length()))) {
NS_WARNING("Failed to set array length!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}

View File

@ -618,12 +618,12 @@ IDBObjectStore::AppendIndexUpdateInfo(PRInt64 aIndexID,
if (aMultiEntry && !JSVAL_IS_PRIMITIVE(key) &&
JS_IsArrayObject(aCx, JSVAL_TO_OBJECT(key))) {
JSObject* array = JSVAL_TO_OBJECT(key);
jsuint arrayLength;
uint32_t arrayLength;
if (!JS_GetArrayLength(aCx, array, &arrayLength)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
for (jsuint arrayIndex = 0; arrayIndex < arrayLength; arrayIndex++) {
for (uint32_t arrayIndex = 0; arrayIndex < arrayLength; arrayIndex++) {
jsval arrayItem;
if (!JS_GetElement(aCx, array, arrayIndex, &arrayItem)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
@ -1700,7 +1700,7 @@ IDBObjectStore::CreateIndex(const nsAString& aName,
JSObject* obj = JSVAL_TO_OBJECT(aKeyPath);
jsuint length;
uint32_t length;
if (!JS_GetArrayLength(aCx, obj, &length)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
@ -1711,7 +1711,7 @@ IDBObjectStore::CreateIndex(const nsAString& aName,
keyPathArray.SetCapacity(length);
for (jsuint index = 0; index < length; index++) {
for (uint32_t index = 0; index < length; index++) {
jsval val;
JSString* jsstr;
nsDependentJSString str;

View File

@ -170,12 +170,12 @@ Key::EncodeJSVal(JSContext* aCx, const jsval aVal, PRUint8 aTypeOffset)
aTypeOffset < (eMaxType * MaxArrayCollapse),
"Wrong typeoffset");
jsuint length;
uint32_t length;
if (!JS_GetArrayLength(aCx, obj, &length)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
for (jsuint index = 0; index < length; index++) {
for (uint32_t index = 0; index < length; index++) {
jsval val;
if (!JS_GetElement(aCx, obj, index, &val)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
@ -220,7 +220,7 @@ Key::DecodeJSVal(const unsigned char*& aPos, const unsigned char* aEnd,
aTypeOffset = 0;
}
jsuint index = 0;
uint32_t index = 0;
while (aPos < aEnd && *aPos - aTypeOffset != eTerminator) {
jsval val;
nsresult rv = DecodeJSVal(aPos, aEnd, aCx, aTypeOffset, &val);

View File

@ -36,104 +36,79 @@
* ***** END LICENSE BLOCK ***** */
#include "domstubs.idl"
#include "nsIArray.idl"
#include "nsIDOMEvent.idl"
#include "nsIDOMEventTarget.idl"
[scriptable, uuid(e0c271cb-266b-48c9-a7e4-96590b445c26)]
interface mozIDOMApplicationRegistryError : nsISupports
{
const unsigned short DENIED = 1;
const unsigned short PERMISSION_DENIED = 2;
const unsigned short MANIFEST_URL_ERROR = 3;
const unsigned short NETWORK_ERROR = 4;
const unsigned short MANIFEST_PARSE_ERROR = 5;
const unsigned short INVALID_MANIFEST = 6;
interface nsIDOMDOMRequest;
readonly attribute short code;
};
[scriptable, uuid(a6856a3d-dece-43ce-89b9-72dba07f4246)]
interface mozIDOMApplication : nsISupports
[scriptable, uuid(b70b84f1-7ac9-4a92-bc32-8b6a7eb7879e)]
interface mozIDOMApplication : nsISupports
{
readonly attribute jsval manifest;
readonly attribute DOMString receipt;
readonly attribute DOMString manifestURL;
readonly attribute nsIArray receipts; /* an array of strings */
readonly attribute DOMString origin;
readonly attribute DOMString installOrigin;
readonly attribute unsigned long installTime;
/* startPoint will be used when several launch_path exists for an app */
nsIDOMDOMRequest launch([optional] in DOMString startPoint);
nsIDOMDOMRequest uninstall();
};
[scriptable, function, uuid(be170df5-9154-463b-9197-10a6195eba52)]
interface mozIDOMApplicationRegistryEnumerateCallback : nsISupports
[scriptable, uuid(870bfbdc-3e13-4042-99dd-18e25720782d)]
interface mozIDOMApplicationEvent : nsIDOMEvent
{
void handleEvent([array, size_is(count)] in mozIDOMApplication apps,
in unsigned long count);
readonly attribute mozIDOMApplication application;
};
[scriptable, function, uuid(ae0ed33d-35cf-443a-837b-a6cebf16bd49)]
interface mozIDOMApplicationRegistryErrorCallback : nsISupports
[scriptable, uuid(a82771f6-ba46-4073-9e6e-f1ad3f42b1f6)]
interface mozIDOMApplicationMgmt : nsIDOMEventTarget
{
void handleEvent(in mozIDOMApplicationRegistryError error);
/**
* the request will return the all the applications installed. Only accessible
* to privileged callers.
*/
nsIDOMDOMRequest getAll();
/**
* event listener to get notified of application installs. Only settable by
* privileged callers.
* the event will be a mozIDOMApplicationEvent
*/
attribute nsIDOMEventListener oninstall;
/**
* event listener to get notified of application uninstalls. Only settable by
* privileged callers.
* the event will be a mozIDOMApplicationEvent
*/
attribute nsIDOMEventListener onuninstall;
};
[scriptable, uuid(ac63c0ba-1f33-4e3e-b9aa-6a3243a9adba)]
[scriptable, uuid(f6929871-288b-4613-9a37-9a150760ac50)]
interface mozIDOMApplicationRegistry : nsISupports
{
/**
* Install a web app. onerror can be used to report errors,
* and oninstall if the caller is privileged.
*
* @param manifestUrl : the URL of the webapps manifest
* @param receipt : An opaque string used to track payment status
* @param manifestUrl : the URL of the webapps manifest.
* @param parameters : A structure with optional information.
* { receipts: ... } will be used to specify the payment receipts for this installation.
*/
void install(in DOMString manifestUrl,
[optional] in DOMString receipt);
nsIDOMDOMRequest install(in DOMString manifestUrl, [optional] in jsval parameters);
/**
* This call is only accessible to privileged callers.
*
* @param origin : the origin of the application to uninstall.
* the request will return the application currently installed, or null.
*/
void uninstall(in DOMString origin);
nsIDOMDOMRequest getSelf();
/**
* Enumerate apps : either return itself if caller is an app, or
* apps installed from a store if caller is a store
*
* @param success: the callback that will get the array of applications
* @param error: optional error callback
* the request will return the applications installed from this origin, or null.
*/
void enumerate(in mozIDOMApplicationRegistryEnumerateCallback success,
[optional] in mozIDOMApplicationRegistryErrorCallback error);
nsIDOMDOMRequest getInstalled();
/**
* Enumerate all apps installed from all stores.
* Only usable by privileged callers.
*
* @param success: the callback that will get the array of applications
* @param error: optional error callback
*/
void enumerateAll(in mozIDOMApplicationRegistryEnumerateCallback success,
[optional] in mozIDOMApplicationRegistryErrorCallback error);
/**
* launch a webapp. Behavior is application dependant.
*
* @param origin : the origin of the application to launch
*/
void launch(in DOMString origin);
/**
* event listener to get notified of application installs. Only settable by
* privileged callers
*/
attribute nsIDOMEventListener oninstall;
/**
* event listener to get notified of application uninstalls. Only settable by
* privileged callers
*/
attribute nsIDOMEventListener onuninstall;
/**
* event listener to get notified of errors.
*/
attribute nsIDOMEventListener onerror;
readonly attribute mozIDOMApplicationMgmt mgmt;
};

View File

@ -190,12 +190,12 @@ SmsFilter::SetNumbers(JSContext* aCx, const jsval& aNumbers)
return NS_ERROR_INVALID_ARG;
}
jsuint size;
uint32_t size;
JS_ALWAYS_TRUE(JS_GetArrayLength(aCx, &obj, &size));
nsTArray<nsString> numbers;
for (jsuint i=0; i<size; ++i) {
for (uint32_t i=0; i<size; ++i) {
jsval jsNumber;
if (!JS_GetElement(aCx, &obj, i, &jsNumber)) {
return NS_ERROR_INVALID_ARG;

View File

@ -199,12 +199,12 @@ SmsManager::Send(const jsval& aNumber, const nsAString& aMessage, jsval* aReturn
// Must be an array then.
JSObject& numbers = aNumber.toObject();
jsuint size;
uint32_t size;
JS_ALWAYS_TRUE(JS_GetArrayLength(cx, &numbers, &size));
jsval* requests = new jsval[size];
for (jsuint i=0; i<size; ++i) {
for (uint32_t i=0; i<size; ++i) {
jsval number;
if (!JS_GetElement(cx, &numbers, i, &number)) {
return NS_ERROR_INVALID_ARG;

View File

@ -528,8 +528,8 @@ private:
#ifdef ANDROID
__android_log_print(ANDROID_LOG_INFO, "Gecko", buffer.ptr());
#endif
fputs(buffer.ptr(), stderr);
fflush(stderr);
fputs(buffer.ptr(), stdout);
fflush(stdout);
}
return true;

View File

@ -1157,7 +1157,17 @@ _dwrite_draw_glyphs_to_gdi_surface_gdi(cairo_win32_surface_t *surface,
surface->dc,
area.left, area.top,
SRCCOPY | NOMIRRORBITMAP);
HRESULT hr = rt->DrawGlyphRun(0, 0, DWRITE_MEASURING_MODE_NATURAL, run, params, color);
DWRITE_MEASURING_MODE measureMode;
switch (scaled_font->rendering_mode) {
case cairo_d2d_surface_t::TEXT_RENDERING_GDI_CLASSIC:
case cairo_d2d_surface_t::TEXT_RENDERING_NO_CLEARTYPE:
measureMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
break;
default:
measureMode = DWRITE_MEASURING_MODE_NATURAL;
break;
}
HRESULT hr = rt->DrawGlyphRun(0, 0, measureMode, run, params, color);
BitBlt(surface->dc,
area.left, area.top,
area.right - area.left, area.bottom - area.top,

View File

@ -1209,6 +1209,8 @@ GLContext::ResizeOffscreenFBO(const gfxIntSize& aSize, const bool aUseReadFBO, c
fBindTexture(LOCAL_GL_TEXTURE_2D, newOffscreenTexture);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
if (alpha) {
fTexImage2D(LOCAL_GL_TEXTURE_2D,

View File

@ -232,25 +232,25 @@ _resume:
#line 62 "hb-ot-shape-complex-indic-machine.rl"
{ found_consonant_syllable (map, buffer, mask_array, last, p); }
#line 67 "hb-ot-shape-complex-indic-machine.rl"
{ set_cluster (buffer, p, last); last = p; }
{ set_cluster (buffer, last, p); last = p; }
break;
case 3:
#line 63 "hb-ot-shape-complex-indic-machine.rl"
{ found_vowel_syllable (map, buffer, mask_array, last, p); }
#line 67 "hb-ot-shape-complex-indic-machine.rl"
{ set_cluster (buffer, p, last); last = p; }
{ set_cluster (buffer, last, p); last = p; }
break;
case 4:
#line 64 "hb-ot-shape-complex-indic-machine.rl"
{ found_standalone_cluster (map, buffer, mask_array, last, p); }
#line 67 "hb-ot-shape-complex-indic-machine.rl"
{ set_cluster (buffer, p, last); last = p; }
{ set_cluster (buffer, last, p); last = p; }
break;
case 1:
#line 65 "hb-ot-shape-complex-indic-machine.rl"
{ found_non_indic (map, buffer, mask_array, last, p); }
#line 67 "hb-ot-shape-complex-indic-machine.rl"
{ set_cluster (buffer, p, last); last = p; }
{ set_cluster (buffer, last, p); last = p; }
break;
#line 256 "hb-ot-shape-complex-indic-machine.hh"
}
@ -268,25 +268,25 @@ _again:
#line 62 "hb-ot-shape-complex-indic-machine.rl"
{ found_consonant_syllable (map, buffer, mask_array, last, p); }
#line 67 "hb-ot-shape-complex-indic-machine.rl"
{ set_cluster (buffer, p, last); last = p; }
{ set_cluster (buffer, last, p); last = p; }
break;
case 3:
#line 63 "hb-ot-shape-complex-indic-machine.rl"
{ found_vowel_syllable (map, buffer, mask_array, last, p); }
#line 67 "hb-ot-shape-complex-indic-machine.rl"
{ set_cluster (buffer, p, last); last = p; }
{ set_cluster (buffer, last, p); last = p; }
break;
case 4:
#line 64 "hb-ot-shape-complex-indic-machine.rl"
{ found_standalone_cluster (map, buffer, mask_array, last, p); }
#line 67 "hb-ot-shape-complex-indic-machine.rl"
{ set_cluster (buffer, p, last); last = p; }
{ set_cluster (buffer, last, p); last = p; }
break;
case 1:
#line 65 "hb-ot-shape-complex-indic-machine.rl"
{ found_non_indic (map, buffer, mask_array, last, p); }
#line 67 "hb-ot-shape-complex-indic-machine.rl"
{ set_cluster (buffer, p, last); last = p; }
{ set_cluster (buffer, last, p); last = p; }
break;
#line 292 "hb-ot-shape-complex-indic-machine.hh"
}

View File

@ -64,7 +64,7 @@ action found_vowel_syllable { found_vowel_syllable (map, buffer, mask_array, las
action found_standalone_cluster { found_standalone_cluster (map, buffer, mask_array, last, p); }
action found_non_indic { found_non_indic (map, buffer, mask_array, last, p); }
action next_syllable { set_cluster (buffer, p, last); last = p; }
action next_syllable { set_cluster (buffer, last, p); last = p; }
consonant_syllable = (c.N? (z.H|H.z?))* c.N? A? (H.z? | matra_group*)? syllable_tail %(found_consonant_syllable);
vowel_syllable = (Ra H)? V N? (z.H.c | ZWJ.c)? matra_group* syllable_tail %(found_vowel_syllable);

View File

@ -96,8 +96,8 @@ private:
};
gfxContext::gfxContext(gfxASurface *surface)
: mSurface(surface)
, mRefCairo(NULL)
: mRefCairo(NULL)
, mSurface(surface)
{
MOZ_COUNT_CTOR(gfxContext);
@ -1266,8 +1266,6 @@ gfxContext::ClipContainsRect(const gfxRect& aRect)
}
}
bool result = true;
// Since we always return false when the clip list contains a
// non-rectangular clip or a non-rectilinear transform, our 'total' clip
// is always a rectangle if we hit the end of this function.

View File

@ -402,9 +402,11 @@ StoreUserFontData(gfxFontEntry* aFontEntry, gfxProxyFontEntry* aProxy,
}
}
static void
CopyWOFFMetadata(const PRUint8* aFontData, PRUint32 aLength,
nsTArray<PRUint8>* aMetadata, PRUint32* aMetaOrigLen)
void
gfxUserFontSet::CopyWOFFMetadata(const PRUint8* aFontData,
PRUint32 aLength,
nsTArray<PRUint8>* aMetadata,
PRUint32* aMetaOrigLen)
{
// This function may be called with arbitrary, unvalidated "font" data
// from @font-face, so it needs to be careful to bounds-check, etc.,

View File

@ -281,6 +281,12 @@ protected:
PRUint64 mGeneration;
static PRLogModuleInfo *sUserFontsLog;
private:
static void CopyWOFFMetadata(const PRUint8* aFontData,
PRUint32 aLength,
nsTArray<PRUint8>* aMetadata,
PRUint32* aMetaOrigLen);
};
// acts a placeholder until the real font is downloaded

View File

@ -506,11 +506,11 @@ ObjectWrapperChild::AnswerNewEnumerateNext(const JSVariant& in_state,
jsval v = JS_GetReservedSlot(state, sNextIdIndexSlot);
jsuint i = JSVAL_TO_INT(v);
int32_t i = JSVAL_TO_INT(v);
NS_ASSERTION(i >= 0, "Index of next jsid negative?");
NS_ASSERTION(i <= strIds->Length(), "Index of next jsid too large?");
if (jsuint(i) == strIds->Length()) {
if (size_t(i) == strIds->Length()) {
*status = JS_TRUE;
return JSObject_to_JSVariant(cx, NULL, statep);
}

View File

@ -165,6 +165,7 @@ CPPSRCS = \
Parser.cpp \
SemanticAnalysis.cpp \
TokenStream.cpp \
TestingFunctions.cpp \
LifoAlloc.cpp \
MapObject.cpp \
MemoryMetrics.cpp \

View File

@ -0,0 +1,570 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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/. */
#include "jsapi.h"
#include "jsbool.h"
#include "jscntxt.h"
#include "jscompartment.h"
#include "jsfriendapi.h"
#include "jsgc.h"
#include "jsobj.h"
#include "jsprf.h"
#include "jswrapper.h"
#include "methodjit/MethodJIT.h"
using namespace js;
using namespace JS;
static JSBool
GC(JSContext *cx, unsigned argc, jsval *vp)
{
JSCompartment *comp = NULL;
if (argc == 1) {
Value arg = vp[2];
if (arg.isObject())
comp = UnwrapObject(&arg.toObject())->compartment();
}
#ifndef JS_MORE_DETERMINISTIC
size_t preBytes = cx->runtime->gcBytes;
#endif
JS_CompartmentGC(cx, comp);
char buf[256] = { '\0' };
#ifndef JS_MORE_DETERMINISTIC
JS_snprintf(buf, sizeof(buf), "before %lu, after %lu\n",
(unsigned long)preBytes, (unsigned long)cx->runtime->gcBytes);
#endif
JSString *str = JS_NewStringCopyZ(cx, buf);
if (!str)
return false;
*vp = STRING_TO_JSVAL(str);
return true;
}
static const struct ParamPair {
const char *name;
JSGCParamKey param;
} paramMap[] = {
{"maxBytes", JSGC_MAX_BYTES },
{"maxMallocBytes", JSGC_MAX_MALLOC_BYTES},
{"gcBytes", JSGC_BYTES},
{"gcNumber", JSGC_NUMBER},
{"sliceTimeBudget", JSGC_SLICE_TIME_BUDGET}
};
static JSBool
GCParameter(JSContext *cx, unsigned argc, jsval *vp)
{
JSString *str;
if (argc == 0) {
str = JS_ValueToString(cx, JSVAL_VOID);
JS_ASSERT(str);
} else {
str = JS_ValueToString(cx, vp[2]);
if (!str)
return JS_FALSE;
vp[2] = STRING_TO_JSVAL(str);
}
JSFlatString *flatStr = JS_FlattenString(cx, str);
if (!flatStr)
return false;
size_t paramIndex = 0;
for (;; paramIndex++) {
if (paramIndex == ArrayLength(paramMap)) {
JS_ReportError(cx,
"the first argument argument must be maxBytes, "
"maxMallocBytes, gcStackpoolLifespan, gcBytes or "
"gcNumber");
return false;
}
if (JS_FlatStringEqualsAscii(flatStr, paramMap[paramIndex].name))
break;
}
JSGCParamKey param = paramMap[paramIndex].param;
if (argc == 1) {
uint32_t value = JS_GetGCParameter(cx->runtime, param);
return JS_NewNumberValue(cx, value, &vp[0]);
}
if (param == JSGC_NUMBER ||
param == JSGC_BYTES) {
JS_ReportError(cx, "Attempt to change read-only parameter %s",
paramMap[paramIndex].name);
return false;
}
uint32_t value;
if (!JS_ValueToECMAUint32(cx, vp[3], &value)) {
JS_ReportError(cx,
"the second argument must be convertable to uint32_t "
"with non-zero value");
return false;
}
if (param == JSGC_MAX_BYTES) {
uint32_t gcBytes = JS_GetGCParameter(cx->runtime, JSGC_BYTES);
if (value < gcBytes) {
JS_ReportError(cx,
"attempt to set maxBytes to the value less than the current "
"gcBytes (%u)",
gcBytes);
return false;
}
}
JS_SetGCParameter(cx->runtime, param, value);
*vp = JSVAL_VOID;
return true;
}
static JSBool
InternalConst(JSContext *cx, unsigned argc, jsval *vp)
{
if (argc != 1) {
JS_ReportError(cx, "the function takes exactly one argument");
return false;
}
JSString *str = JS_ValueToString(cx, vp[2]);
if (!str)
return false;
JSFlatString *flat = JS_FlattenString(cx, str);
if (!flat)
return false;
if (JS_FlatStringEqualsAscii(flat, "MARK_STACK_LENGTH")) {
vp[0] = UINT_TO_JSVAL(js::MARK_STACK_LENGTH);
} else {
JS_ReportError(cx, "unknown const name");
return false;
}
return true;
}
#ifdef JS_GC_ZEAL
static JSBool
GCZeal(JSContext *cx, unsigned argc, jsval *vp)
{
uint32_t zeal, frequency = JS_DEFAULT_ZEAL_FREQ;
JSBool compartment = JS_FALSE;
if (argc > 3) {
ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Too many arguments");
return JS_FALSE;
}
if (!JS_ValueToECMAUint32(cx, argc < 1 ? JSVAL_VOID : vp[2], &zeal))
return JS_FALSE;
if (argc >= 2)
if (!JS_ValueToECMAUint32(cx, vp[3], &frequency))
return JS_FALSE;
if (argc >= 3)
compartment = js_ValueToBoolean(vp[3]);
JS_SetGCZeal(cx, (uint8_t)zeal, frequency, compartment);
*vp = JSVAL_VOID;
return JS_TRUE;
}
static JSBool
ScheduleGC(JSContext *cx, unsigned argc, jsval *vp)
{
uint32_t count;
bool compartment = false;
if (argc != 1 && argc != 2) {
ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Wrong number of arguments");
return JS_FALSE;
}
if (!JS_ValueToECMAUint32(cx, vp[2], &count))
return JS_FALSE;
if (argc == 2)
compartment = js_ValueToBoolean(vp[3]);
JS_ScheduleGC(cx, count, compartment);
*vp = JSVAL_VOID;
return JS_TRUE;
}
static JSBool
VerifyBarriers(JSContext *cx, unsigned argc, jsval *vp)
{
if (argc) {
ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Too many arguments");
return JS_FALSE;
}
gc::VerifyBarriers(cx);
*vp = JSVAL_VOID;
return JS_TRUE;
}
static JSBool
GCSlice(JSContext *cx, unsigned argc, jsval *vp)
{
uint32_t budget;
if (argc != 1) {
ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Wrong number of arguments");
return JS_FALSE;
}
if (!JS_ValueToECMAUint32(cx, vp[2], &budget))
return JS_FALSE;
GCDebugSlice(cx, budget);
*vp = JSVAL_VOID;
return JS_TRUE;
}
static JSBool
DeterministicGC(JSContext *cx, unsigned argc, jsval *vp)
{
if (argc != 1) {
ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Wrong number of arguments");
return JS_FALSE;
}
gc::SetDeterministicGC(cx, js_ValueToBoolean(vp[2]));
*vp = JSVAL_VOID;
return JS_TRUE;
}
#endif /* JS_GC_ZEAL */
typedef struct JSCountHeapNode JSCountHeapNode;
struct JSCountHeapNode {
void *thing;
JSGCTraceKind kind;
JSCountHeapNode *next;
};
typedef struct JSCountHeapTracer {
JSTracer base;
JSDHashTable visited;
bool ok;
JSCountHeapNode *traceList;
JSCountHeapNode *recycleList;
} JSCountHeapTracer;
static void
CountHeapNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
JSCountHeapTracer *countTracer;
JSDHashEntryStub *entry;
JSCountHeapNode *node;
void *thing = *thingp;
JS_ASSERT(trc->callback == CountHeapNotify);
countTracer = (JSCountHeapTracer *)trc;
if (!countTracer->ok)
return;
entry = (JSDHashEntryStub *)
JS_DHashTableOperate(&countTracer->visited, thing, JS_DHASH_ADD);
if (!entry) {
countTracer->ok = false;
return;
}
if (entry->key)
return;
entry->key = thing;
node = countTracer->recycleList;
if (node) {
countTracer->recycleList = node->next;
} else {
node = (JSCountHeapNode *) js_malloc(sizeof *node);
if (!node) {
countTracer->ok = false;
return;
}
}
node->thing = thing;
node->kind = kind;
node->next = countTracer->traceList;
countTracer->traceList = node;
}
static const struct TraceKindPair {
const char *name;
int32_t kind;
} traceKindNames[] = {
{ "all", -1 },
{ "object", JSTRACE_OBJECT },
{ "string", JSTRACE_STRING },
#if JS_HAS_XML_SUPPORT
{ "xml", JSTRACE_XML },
#endif
};
static JSBool
CountHeap(JSContext *cx, unsigned argc, jsval *vp)
{
void* startThing;
JSGCTraceKind startTraceKind;
jsval v;
int32_t traceKind;
JSString *str;
JSCountHeapTracer countTracer;
JSCountHeapNode *node;
size_t counter;
startThing = NULL;
startTraceKind = JSTRACE_OBJECT;
if (argc > 0) {
v = JS_ARGV(cx, vp)[0];
if (JSVAL_IS_TRACEABLE(v)) {
startThing = JSVAL_TO_TRACEABLE(v);
startTraceKind = JSVAL_TRACE_KIND(v);
} else if (!JSVAL_IS_NULL(v)) {
JS_ReportError(cx,
"the first argument is not null or a heap-allocated "
"thing");
return JS_FALSE;
}
}
traceKind = -1;
if (argc > 1) {
str = JS_ValueToString(cx, JS_ARGV(cx, vp)[1]);
if (!str)
return JS_FALSE;
JSFlatString *flatStr = JS_FlattenString(cx, str);
if (!flatStr)
return JS_FALSE;
for (size_t i = 0; ;) {
if (JS_FlatStringEqualsAscii(flatStr, traceKindNames[i].name)) {
traceKind = traceKindNames[i].kind;
break;
}
if (++i == ArrayLength(traceKindNames)) {
JSAutoByteString bytes(cx, str);
if (!!bytes)
JS_ReportError(cx, "trace kind name '%s' is unknown", bytes.ptr());
return JS_FALSE;
}
}
}
JS_TracerInit(&countTracer.base, JS_GetRuntime(cx), CountHeapNotify);
if (!JS_DHashTableInit(&countTracer.visited, JS_DHashGetStubOps(),
NULL, sizeof(JSDHashEntryStub),
JS_DHASH_DEFAULT_CAPACITY(100))) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
countTracer.ok = true;
countTracer.traceList = NULL;
countTracer.recycleList = NULL;
if (!startThing) {
JS_TraceRuntime(&countTracer.base);
} else {
JS_SET_TRACING_NAME(&countTracer.base, "root");
JS_CallTracer(&countTracer.base, startThing, startTraceKind);
}
counter = 0;
while ((node = countTracer.traceList) != NULL) {
if (traceKind == -1 || node->kind == traceKind)
counter++;
countTracer.traceList = node->next;
node->next = countTracer.recycleList;
countTracer.recycleList = node;
JS_TraceChildren(&countTracer.base, node->thing, node->kind);
}
while ((node = countTracer.recycleList) != NULL) {
countTracer.recycleList = node->next;
js_free(node);
}
JS_DHashTableFinish(&countTracer.visited);
if (!countTracer.ok) {
JS_ReportOutOfMemory(cx);
return false;
}
return JS_NewNumberValue(cx, (double) counter, vp);
}
static unsigned finalizeCount = 0;
static void
finalize_counter_finalize(JSContext *cx, JSObject *obj)
{
JS_ATOMIC_INCREMENT(&finalizeCount);
}
static JSClass FinalizeCounterClass = {
"FinalizeCounter", JSCLASS_IS_ANONYMOUS,
JS_PropertyStub, /* addProperty */
JS_PropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
finalize_counter_finalize
};
static JSBool
MakeFinalizeObserver(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = JS_NewObjectWithGivenProto(cx, &FinalizeCounterClass, NULL,
JS_GetGlobalObject(cx));
if (!obj)
return false;
*vp = OBJECT_TO_JSVAL(obj);
return true;
}
static JSBool
FinalizeCount(JSContext *cx, unsigned argc, jsval *vp)
{
*vp = INT_TO_JSVAL(finalizeCount);
return true;
}
JSBool
MJitCodeStats(JSContext *cx, unsigned argc, jsval *vp)
{
#ifdef JS_METHODJIT
JSRuntime *rt = cx->runtime;
AutoLockGC lock(rt);
size_t n = 0;
for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c) {
n += (*c)->sizeOfMjitCode();
}
JS_SET_RVAL(cx, vp, INT_TO_JSVAL(n));
#else
JS_SET_RVAL(cx, vp, JSVAL_VOID);
#endif
return true;
}
JSBool
MJitChunkLimit(JSContext *cx, unsigned argc, jsval *vp)
{
if (argc != 1) {
ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Wrong number of arguments");
return JS_FALSE;
}
double t;
if (!JS_ValueToNumber(cx, JS_ARGV(cx, vp)[0], &t))
return JS_FALSE;
#ifdef JS_METHODJIT
mjit::SetChunkLimit((uint32_t) t);
#endif
// Clear out analysis information which might refer to code compiled with
// the previous chunk limit.
JS_GC(cx);
vp->setUndefined();
return true;
}
static JSBool
Terminate(JSContext *cx, unsigned arg, jsval *vp)
{
JS_ClearPendingException(cx);
return JS_FALSE;
}
static JSFunctionSpecWithHelp TestingFunctions[] = {
JS_FN_HELP("gc", ::GC, 0, 0,
"gc([obj])",
" Run the garbage collector. When obj is given, GC only its compartment."),
JS_FN_HELP("gcparam", GCParameter, 2, 0,
"gcparam(name [, value])",
" Wrapper for JS_[GS]etGCParameter. The name is either maxBytes,\n"
" maxMallocBytes, gcBytes, gcNumber, or sliceTimeBudget."),
JS_FN_HELP("countHeap", CountHeap, 0, 0,
"countHeap([start[, kind]])",
" Count the number of live GC things in the heap or things reachable from\n"
" start when it is given and is not null. kind is either 'all' (default) to\n"
" count all things or one of 'object', 'double', 'string', 'function',\n"
" 'qname', 'namespace', 'xml' to count only things of that kind."),
JS_FN_HELP("makeFinalizeObserver", MakeFinalizeObserver, 0, 0,
"makeFinalizeObserver()",
" Get a special object whose finalization increases the counter returned\n"
" by the finalizeCount function."),
JS_FN_HELP("finalizeCount", FinalizeCount, 0, 0,
"finalizeCount()",
" Return the current value of the finalization counter that is incremented\n"
" each time an object returned by the makeFinalizeObserver is finalized."),
#ifdef JS_GC_ZEAL
JS_FN_HELP("gczeal", GCZeal, 2, 0,
"gczeal(level, [period], [compartmentGC?])",
" Specifies how zealous the garbage collector should be. Values for level:\n"
" 0: Normal amount of collection\n"
" 1: Collect when roots are added or removed\n"
" 2: Collect when memory is allocated\n"
" 3: Collect when the window paints (browser only)\n"
" 4: Verify write barriers between instructions\n"
" 5: Verify write barriers between paints\n"
" Period specifies that collection happens every n allocations.\n"
" If compartmentGC is true, the collections will be compartmental."),
JS_FN_HELP("schedulegc", ScheduleGC, 1, 0,
"schedulegc(num, [compartmentGC?])",
" Schedule a GC to happen after num allocations."),
JS_FN_HELP("verifybarriers", VerifyBarriers, 0, 0,
"verifybarriers()",
" Start or end a run of the write barrier verifier."),
JS_FN_HELP("gcslice", GCSlice, 1, 0,
"gcslice(n)",
" Run an incremental GC slice that marks about n objects."),
JS_FN_HELP("deterministicgc", DeterministicGC, 1, 0,
"deterministicgc(true|false)",
" If true, only allow determinstic GCs to run."),
#endif
JS_FN_HELP("internalConst", InternalConst, 1, 0,
"internalConst(name)",
" Query an internal constant for the engine. See InternalConst source for\n"
" the list of constant names."),
#ifdef JS_METHODJIT
JS_FN_HELP("mjitcodestats", MJitCodeStats, 0, 0,
"mjitcodestats()",
"Return stats on mjit code memory usage."),
#endif
JS_FN_HELP("mjitChunkLimit", MJitChunkLimit, 1, 0,
"mjitChunkLimit(N)",
" Specify limit on compiled chunk size during mjit compilation."),
JS_FN_HELP("terminate", Terminate, 0, 0,
"terminate()",
" Terminate JavaScript execution, as if we had run out of\n"
" memory or been terminated by the slow script dialog."),
JS_FS_END
};
namespace js {
bool
DefineTestingFunctions(JSContext *cx, JSObject *obj)
{
return JS_DefineFunctionsWithHelp(cx, obj, TestingFunctions);
}
} /* namespace js */

View File

@ -0,0 +1,16 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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/. */
#ifndef TestingFunctions_h__
#define TestingFunctions_h__
namespace js {
bool
DefineTestingFunctions(JSContext *cx, JSObject *obj);
} /* namespace js */
#endif /* TestingFunctions_h__ */

View File

@ -148,6 +148,9 @@ xpcshell-tests:
$(testxpcsrcdir)/runxpcshelltests.py \
--symbols-path=$(DIST)/crashreporter-symbols \
--build-info-json=$(DEPTH)/mozinfo.json \
--tests-root-dir=$(testxpcobjdir) \
--xunit-file=$(testxpcobjdir)/$(relativesrcdir)/results.xml \
--xunit-suite-name=xpcshell \
$(EXTRA_TEST_ARGS) \
$(LIBXUL_DIST)/bin/xpcshell \
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))

View File

@ -616,9 +616,10 @@ if test "$GXX" = "yes"; then
GNU_CXX=1
CXX_VERSION=`$CXX -v 2>&1 | grep 'gcc version'`
fi
if test "`echo | $AS -v 2>&1 | grep -c GNU`" != "0"; then
if test "`echo | $AS -o conftest.out -v 2>&1 | grep -c GNU`" != "0"; then
GNU_AS=1
fi
rm -f conftest.out
if test "`echo | $LD -v 2>&1 | grep -c GNU`" != "0"; then
GNU_LD=1
fi

View File

@ -1574,7 +1574,7 @@ jsvalToPtrExplicit(JSContext* cx, jsval val, uintptr_t* result)
template<class IntegerType, class CharType, size_t N, class AP>
void
IntegerToString(IntegerType i, jsuint radix, Vector<CharType, N, AP>& result)
IntegerToString(IntegerType i, int radix, Vector<CharType, N, AP>& result)
{
JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
@ -1955,7 +1955,7 @@ ImplicitConvert(JSContext* cx,
JS_IsArrayObject(cx, JSVAL_TO_OBJECT(val))) {
// Convert each element of the array by calling ImplicitConvert.
JSObject* sourceArray = JSVAL_TO_OBJECT(val);
jsuint sourceLength;
uint32_t sourceLength;
if (!JS_GetArrayLength(cx, sourceArray, &sourceLength) ||
targetLength != size_t(sourceLength)) {
JS_ReportError(cx, "ArrayType length does not match source array length");
@ -1971,7 +1971,7 @@ ImplicitConvert(JSContext* cx,
return false;
}
for (jsuint i = 0; i < sourceLength; ++i) {
for (uint32_t i = 0; i < sourceLength; ++i) {
js::AutoValueRooter item(cx);
if (!JS_GetElement(cx, sourceArray, i, item.jsval_addr()))
return false;
@ -4112,7 +4112,7 @@ StructType::Create(JSContext* cx, unsigned argc, jsval* vp)
JSBool
StructType::DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj)
{
jsuint len;
uint32_t len;
ASSERT_OK(JS_GetArrayLength(cx, fieldsObj, &len));
// Get the common prototype for CData objects of this type from
@ -4150,7 +4150,7 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj
structSize = 0;
structAlign = 0;
for (jsuint i = 0; i < len; ++i) {
for (uint32_t i = 0; i < len; ++i) {
js::AutoValueRooter item(cx);
if (!JS_GetElement(cx, fieldsObj, i, item.jsval_addr()))
return JS_FALSE;
@ -4925,7 +4925,7 @@ FunctionType::Create(JSContext* cx, unsigned argc, jsval* vp)
}
arrayObj = JSVAL_TO_OBJECT(argv[2]);
jsuint len;
uint32_t len;
ASSERT_OK(JS_GetArrayLength(cx, arrayObj, &len));
if (!argTypes.appendN(JSVAL_VOID, len)) {
@ -4937,7 +4937,7 @@ FunctionType::Create(JSContext* cx, unsigned argc, jsval* vp)
// Pull out the argument types from the array, if any.
JS_ASSERT(!argTypes.length() || arrayObj);
js::AutoArrayRooter items(cx, argTypes.length(), argTypes.begin());
for (jsuint i = 0; i < argTypes.length(); ++i) {
for (uint32_t i = 0; i < argTypes.length(); ++i) {
if (!JS_GetElement(cx, arrayObj, i, &argTypes[i]))
return JS_FALSE;
}
@ -4956,7 +4956,7 @@ FunctionType::CreateInternal(JSContext* cx,
jsval abi,
jsval rtype,
jsval* argtypes,
jsuint arglen)
unsigned arglen)
{
// Determine and check the types, and prepare the function CIF.
AutoPtr<FunctionInfo> fninfo(NewFunctionInfo(cx, abi, rtype, argtypes, arglen));
@ -5109,7 +5109,7 @@ FunctionType::Call(JSContext* cx,
}
jsval* argv = JS_ARGV(cx, vp);
for (jsuint i = 0; i < argcFixed; ++i)
for (unsigned i = 0; i < argcFixed; ++i)
if (!ConvertArgument(cx, argv[i], fninfo->mArgTypes[i], &values[i], &strings))
return false;
@ -6044,7 +6044,7 @@ Int64Base::ToString(JSContext* cx,
return JS_FALSE;
}
jsuint radix = 10;
int radix = 10;
if (argc == 1) {
jsval arg = JS_ARGV(cx, vp)[0];
if (JSVAL_IS_INT(arg))

View File

@ -496,7 +496,7 @@ namespace StructType {
namespace FunctionType {
JSObject* CreateInternal(JSContext* cx, jsval abi, jsval rtype,
jsval* argtypes, jsuint arglen);
jsval* argtypes, unsigned arglen);
JSObject* ConstructWithObject(JSContext* cx, JSObject* typeObj,
JSObject* refObj, PRFuncPtr fnptr, JSObject* result);

View File

@ -1010,7 +1010,7 @@ BytecodeEmitter::shouldNoteClosedName(ParseNode *pn)
static int
AdjustBlockSlot(JSContext *cx, BytecodeEmitter *bce, int slot)
{
JS_ASSERT((jsuint) slot < bce->maxStackDepth);
JS_ASSERT((unsigned) slot < bce->maxStackDepth);
if (bce->inFunction()) {
slot += bce->bindings.countVars();
if ((unsigned) slot >= SLOTNO_LIMIT) {
@ -2468,7 +2468,7 @@ EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
continue;
}
i = pn3->pn_pval->toInt32();
if ((jsuint)(i + (int)JS_BIT(15)) >= (jsuint)JS_BIT(16)) {
if ((unsigned)(i + (int)JS_BIT(15)) >= (unsigned)JS_BIT(16)) {
switchOp = JSOP_LOOKUPSWITCH;
continue;
}
@ -3068,7 +3068,7 @@ EmitDestructuringOpsHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn,
{
JS_ASSERT(emitOption != DefineVars);
jsuint index;
unsigned index;
ParseNode *pn2, *pn3;
JSBool doElemOp;
@ -3303,7 +3303,7 @@ static JSBool
EmitGroupAssignment(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp,
ParseNode *lhs, ParseNode *rhs)
{
jsuint depth, limit, i, nslots;
unsigned depth, limit, i, nslots;
ParseNode *pn;
depth = limit = (unsigned) bce->stackDepth;

View File

@ -6810,7 +6810,7 @@ Parser::primaryExpr(TokenKind tt, bool afterDoubleDot)
case TOK_LB:
{
JSBool matched;
jsuint index;
unsigned index;
pn = ListNode::create(PNK_RB, tc);
if (!pn)

View File

@ -8,14 +8,14 @@
static JSGCCallback oldGCCallback;
static void **checkPointers;
static jsuint checkPointersLength;
static unsigned checkPointersLength;
static size_t checkPointersStaticStrings;
static JSBool
TestAboutToBeFinalizedCallback(JSContext *cx, JSGCStatus status)
{
if (status == JSGC_MARK_END && checkPointers) {
for (jsuint i = 0; i != checkPointersLength; ++i) {
for (unsigned i = 0; i != checkPointersLength; ++i) {
void *p = checkPointers[i];
JS_ASSERT(p);
if (JS_IsAboutToBeFinalized(p))
@ -52,7 +52,7 @@ BEGIN_TEST(testIsAboutToBeFinalized_bug528645)
JS_GC(cx);
/* Everything is unrooted except unit strings. */
for (jsuint i = 0; i != checkPointersLength; ++i) {
for (unsigned i = 0; i != checkPointersLength; ++i) {
void *p = checkPointers[i];
if (p) {
CHECK(JSString::isStatic(p));
@ -97,7 +97,7 @@ cls_testIsAboutToBeFinalized_bug528645::createAndTestRooted()
CHECK(checkPointers);
checkPointersStaticStrings = 0;
for (jsuint i = 0; i != checkPointersLength; ++i) {
for (unsigned i = 0; i != checkPointersLength; ++i) {
jsval v;
ok = JS_GetElement(cx, array, i, &v);
CHECK(ok);
@ -115,7 +115,7 @@ cls_testIsAboutToBeFinalized_bug528645::createAndTestRooted()
* All GC things are rooted via the root holding the array containing them
* and TestAboutToBeFinalizedCallback must keep them as is.
*/
for (jsuint i = 0; i != checkPointersLength; ++i)
for (unsigned i = 0; i != checkPointersLength; ++i)
CHECK(checkPointers[i]);
/*
@ -127,7 +127,7 @@ cls_testIsAboutToBeFinalized_bug528645::createAndTestRooted()
array = JSVAL_TO_OBJECT(root.value());
JS_ASSERT(JS_IsArrayObject(cx, array));
jsuint tmp;
uint32_t tmp;
CHECK(JS_GetArrayLength(cx, array, &tmp));
CHECK(ok);

View File

@ -55,7 +55,7 @@ BEGIN_TEST(testNewObject_1)
CHECK(obj);
jsvalRoot rt(cx, OBJECT_TO_JSVAL(obj));
CHECK(JS_IsArrayObject(cx, obj));
jsuint len;
uint32_t len;
CHECK(JS_GetArrayLength(cx, obj, &len));
CHECK_EQUAL(len, 0);

View File

@ -753,6 +753,7 @@ JSRuntime::JSRuntime()
gcZealFrequency(0),
gcNextScheduled(0),
gcDebugCompartmentGC(false),
gcDeterministicOnly(false),
#endif
gcCallback(NULL),
gcSliceCallback(NULL),
@ -4407,9 +4408,9 @@ JS_NewArrayObject(JSContext *cx, int length, jsval *vector)
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
AssertNoGC(cx);
CHECK_REQUEST(cx);
/* NB: jsuint cast does ToUint32. */
assertSameCompartment(cx, JSValueArray(vector, vector ? (jsuint)length : 0));
return NewDenseCopiedArray(cx, (jsuint)length, vector);
assertSameCompartment(cx, JSValueArray(vector, vector ? (uint32_t)length : 0));
return NewDenseCopiedArray(cx, (uint32_t)length, vector);
}
JS_PUBLIC_API(JSBool)
@ -4420,7 +4421,7 @@ JS_IsArrayObject(JSContext *cx, JSObject *obj)
}
JS_PUBLIC_API(JSBool)
JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp)
JS_GetArrayLength(JSContext *cx, JSObject *obj, uint32_t *lengthp)
{
AssertNoGC(cx);
CHECK_REQUEST(cx);
@ -4429,7 +4430,7 @@ JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp)
}
JS_PUBLIC_API(JSBool)
JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length)
JS_SetArrayLength(JSContext *cx, JSObject *obj, uint32_t length)
{
AssertNoGC(cx);
CHECK_REQUEST(cx);
@ -6466,23 +6467,10 @@ JS_ClearPendingException(JSContext *cx)
JS_PUBLIC_API(JSBool)
JS_ReportPendingException(JSContext *cx)
{
JSBool ok;
bool save;
AssertNoGC(cx);
CHECK_REQUEST(cx);
/*
* Set cx->generatingError to suppress the standard error-to-exception
* conversion done by all {js,JS}_Report* functions except for OOM. The
* cx->generatingError flag was added to suppress recursive divergence
* under js_ErrorToException, but it serves for our purposes here too.
*/
save = cx->generatingError;
cx->generatingError = JS_TRUE;
ok = js_ReportUncaughtException(cx);
cx->generatingError = save;
return ok;
return js_ReportUncaughtException(cx);
}
struct JSExceptionState {

View File

@ -1896,8 +1896,8 @@ JSID_TO_INT(jsid id)
static JS_ALWAYS_INLINE JSBool
INT_FITS_IN_JSID(int32_t i)
{
return ((jsuint)(i) - (jsuint)JSID_INT_MIN <=
(jsuint)(JSID_INT_MAX - JSID_INT_MIN));
return ((uint32_t)(i) - (uint32_t)JSID_INT_MIN <=
(uint32_t)(JSID_INT_MAX - JSID_INT_MIN));
}
static JS_ALWAYS_INLINE jsid
@ -3986,10 +3986,10 @@ extern JS_PUBLIC_API(JSBool)
JS_IsArrayObject(JSContext *cx, JSObject *obj);
extern JS_PUBLIC_API(JSBool)
JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp);
JS_GetArrayLength(JSContext *cx, JSObject *obj, uint32_t *lengthp);
extern JS_PUBLIC_API(JSBool)
JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length);
JS_SetArrayLength(JSContext *cx, JSObject *obj, uint32_t length);
extern JS_PUBLIC_API(JSBool)
JS_DefineElement(JSContext *cx, JSObject *obj, uint32_t index, jsval value,

View File

@ -148,7 +148,7 @@ using namespace js::gc;
using namespace js::types;
JSBool
js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
js_GetLengthProperty(JSContext *cx, JSObject *obj, uint32_t *lengthp)
{
if (obj->isArray()) {
*lengthp = obj->getArrayLength();
@ -168,11 +168,11 @@ js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
return false;
if (tvr.value().isInt32()) {
*lengthp = jsuint(tvr.value().toInt32()); /* jsuint cast does ToUint32_t */
*lengthp = uint32_t(tvr.value().toInt32()); /* uint32_t cast does ToUint32_t */
return true;
}
JS_STATIC_ASSERT(sizeof(jsuint) == sizeof(uint32_t));
return ToUint32(cx, tvr.value(), (uint32_t *)lengthp);
}
@ -198,7 +198,7 @@ namespace js {
*
*/
JS_FRIEND_API(bool)
StringIsArrayIndex(JSLinearString *str, jsuint *indexp)
StringIsArrayIndex(JSLinearString *str, uint32_t *indexp)
{
const jschar *s = str->chars();
uint32_t length = str->length();
@ -237,10 +237,10 @@ StringIsArrayIndex(JSLinearString *str, jsuint *indexp)
}
static JSBool
BigIndexToId(JSContext *cx, JSObject *obj, jsuint index, JSBool createAtom,
BigIndexToId(JSContext *cx, JSObject *obj, uint32_t index, JSBool createAtom,
jsid *idp)
{
JS_STATIC_ASSERT((jsuint)-1 == 4294967295U);
JS_ASSERT(index > JSID_INT_MAX);
jschar buf[10];
@ -319,8 +319,8 @@ IndexToId(JSContext* cx, JSObject* obj, double index, JSBool* hole, jsid* idp,
return JS_TRUE;
}
if (index <= jsuint(-1)) {
if (!BigIndexToId(cx, obj, jsuint(index), createAtom, idp))
if (index <= uint32_t(-1)) {
if (!BigIndexToId(cx, obj, uint32_t(index), createAtom, idp))
return JS_FALSE;
if (hole && JSID_IS_VOID(*idp))
*hole = JS_TRUE;
@ -438,7 +438,7 @@ GetElementsSlow(JSContext *cx, JSObject *aobj, uint32_t length, Value *vp)
}
bool
GetElements(JSContext *cx, JSObject *aobj, jsuint length, Value *vp)
GetElements(JSContext *cx, JSObject *aobj, uint32_t length, Value *vp)
{
if (aobj->isDenseArray() && length <= aobj->getDenseArrayInitializedLength() &&
!js_PrototypeHasIndexedProperties(cx, aobj)) {
@ -476,9 +476,9 @@ SetArrayElement(JSContext *cx, JSObject *obj, double index, const Value &v)
/* Predicted/prefetched code should favor the remains-dense case. */
JSObject::EnsureDenseResult result = JSObject::ED_SPARSE;
do {
if (index > jsuint(-1))
if (index > uint32_t(-1))
break;
jsuint idx = jsuint(index);
uint32_t idx = uint32_t(index);
result = obj->ensureDenseArrayElements(cx, idx, 1);
if (result != JSObject::ED_OK)
break;
@ -630,8 +630,8 @@ array_length_setter(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value
* us to disregard length when reading from arrays as long we are within
* the initialized capacity.
*/
jsuint oldcap = obj->getDenseArrayCapacity();
jsuint oldinit = obj->getDenseArrayInitializedLength();
uint32_t oldcap = obj->getDenseArrayCapacity();
uint32_t oldinit = obj->getDenseArrayInitializedLength();
if (oldinit > newlen)
obj->setDenseArrayInitializedLength(newlen);
if (oldcap > newlen)
@ -661,13 +661,13 @@ array_length_setter(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value
if (!iter)
return false;
jsuint gap = oldlen - newlen;
uint32_t gap = oldlen - newlen;
for (;;) {
if (!JS_CHECK_OPERATION_LIMIT(cx) || !JS_NextProperty(cx, iter, &id))
return false;
if (JSID_IS_VOID(id))
break;
jsuint index;
uint32_t index;
Value junk;
if (js_IdIsIndex(id, &index) && index - newlen < gap &&
!obj->deleteElement(cx, index, &junk, false)) {
@ -864,7 +864,7 @@ array_getGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Valu
static JSBool
slowarray_addProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
{
jsuint index, length;
uint32_t index, length;
if (!js_IdIsIndex(id, &index))
return JS_TRUE;
@ -1489,11 +1489,11 @@ array_toSource(JSContext *cx, unsigned argc, Value *vp)
if (!sb.append('['))
return false;
jsuint length;
uint32_t length;
if (!js_GetLengthProperty(cx, obj, &length))
return false;
for (jsuint index = 0; index < length; index++) {
for (uint32_t index = 0; index < length; index++) {
JSBool hole;
Value elt;
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
@ -1609,7 +1609,7 @@ array_toString_sub(JSContext *cx, JSObject *obj, JSBool locale,
return true;
}
jsuint length;
uint32_t length;
if (!js_GetLengthProperty(cx, obj, &length))
return false;
@ -1650,7 +1650,7 @@ array_toString_sub(JSContext *cx, JSObject *obj, JSBool locale,
}
}
} else {
for (jsuint index = 0; index < length; index++) {
for (uint32_t index = 0; index < length; index++) {
if (!JS_CHECK_OPERATION_LIMIT(cx))
return false;
@ -1794,7 +1794,7 @@ InitArrayElements(JSContext *cx, JSObject *obj, uint32_t start, uint32_t count,
JS_ASSERT(result == JSObject::ED_SPARSE);
break;
}
jsuint newlen = start + count;
uint32_t newlen = start + count;
if (newlen > obj->getArrayLength())
obj->setDenseArrayLength(newlen);
@ -1837,7 +1837,7 @@ InitArrayElements(JSContext *cx, JSObject *obj, uint32_t start, uint32_t count,
#if 0
static JSBool
InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, const Value *vector)
InitArrayObject(JSContext *cx, JSObject *obj, uint32_t length, const Value *vector)
{
JS_ASSERT(obj->isArray());
@ -1856,7 +1856,7 @@ InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, const Value *vector
obj->setDenseArrayInitializedLength(length);
bool hole = false;
for (jsuint i = 0; i < length; i++) {
for (uint32_t i = 0; i < length; i++) {
obj->setDenseArrayElement(i, vector[i]);
hole |= vector[i].isMagic(JS_ARRAY_HOLE);
}
@ -1899,7 +1899,7 @@ array_reverse(JSContext *cx, unsigned argc, Value *vp)
if (!obj)
return false;
jsuint len;
uint32_t len;
if (!js_GetLengthProperty(cx, obj, &len))
return false;
@ -1961,7 +1961,7 @@ array_reverse(JSContext *cx, unsigned argc, Value *vp)
} while (false);
Value lowval, hival;
for (jsuint i = 0, half = len / 2; i < half; i++) {
for (uint32_t i = 0, half = len / 2; i < half; i++) {
JSBool hole, hole2;
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
!GetElement(cx, obj, i, &hole, &lowval) ||
@ -2203,7 +2203,7 @@ js::array_sort(JSContext *cx, unsigned argc, Value *vp)
if (!obj)
return false;
jsuint len;
uint32_t len;
if (!js_GetLengthProperty(cx, obj, &len))
return false;
if (len == 0) {
@ -2250,7 +2250,7 @@ js::array_sort(JSContext *cx, unsigned argc, Value *vp)
undefs = 0;
bool allStrings = true;
bool allInts = true;
for (jsuint i = 0; i < len; i++) {
for (uint32_t i = 0; i < len; i++) {
if (!JS_CHECK_OPERATION_LIMIT(cx))
return false;
@ -2341,7 +2341,7 @@ js::array_sort(JSContext *cx, unsigned argc, Value *vp)
}
}
if (!InitArrayElements(cx, obj, 0, jsuint(n), result, DontUpdateTypes))
if (!InitArrayElements(cx, obj, 0, uint32_t(n), result, DontUpdateTypes))
return false;
}
@ -2367,7 +2367,7 @@ js::array_sort(JSContext *cx, unsigned argc, Value *vp)
static bool
array_push_slowly(JSContext *cx, JSObject *obj, CallArgs &args)
{
jsuint length;
uint32_t length;
if (!js_GetLengthProperty(cx, obj, &length))
return false;
@ -2451,7 +2451,7 @@ js::array_push(JSContext *cx, unsigned argc, Value *vp)
static JSBool
array_pop_slowly(JSContext *cx, JSObject* obj, CallArgs &args)
{
jsuint index;
uint32_t index;
if (!js_GetLengthProperty(cx, obj, &index))
return false;
@ -2477,7 +2477,7 @@ array_pop_slowly(JSContext *cx, JSObject* obj, CallArgs &args)
static JSBool
array_pop_dense(JSContext *cx, JSObject* obj, CallArgs &args)
{
jsuint index = obj->getArrayLength();
uint32_t index = obj->getArrayLength();
if (index == 0) {
args.rval().setUndefined();
return JS_TRUE;
@ -2538,7 +2538,7 @@ js::array_shift(JSContext *cx, unsigned argc, Value *vp)
if (!obj)
return JS_FALSE;
jsuint length;
uint32_t length;
if (!js_GetLengthProperty(cx, obj, &length))
return JS_FALSE;
@ -2567,7 +2567,7 @@ js::array_shift(JSContext *cx, unsigned argc, Value *vp)
/* Slide down the array above the first element. */
AutoValueRooter tvr(cx);
for (jsuint i = 0; i < length; i++) {
for (uint32_t i = 0; i < length; i++) {
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
!GetElement(cx, obj, i + 1, &hole, tvr.addr()) ||
!SetOrDeleteArrayElement(cx, obj, i, hole, tvr.value())) {
@ -2590,7 +2590,7 @@ array_unshift(JSContext *cx, unsigned argc, Value *vp)
if (!obj)
return false;
jsuint length;
uint32_t length;
if (!js_GetLengthProperty(cx, obj, &length))
return JS_FALSE;
@ -2936,11 +2936,11 @@ js::array_concat(JSContext *cx, unsigned argc, Value *vp)
return false;
JSObject *nobj;
jsuint length;
uint32_t length;
if (aobj->isDenseArray()) {
length = aobj->getArrayLength();
const Value *vector = aobj->getDenseArrayElements();
jsuint initlen = aobj->getDenseArrayInitializedLength();
uint32_t initlen = aobj->getDenseArrayInitializedLength();
nobj = NewDenseCopiedArray(cx, initlen, vector);
if (!nobj)
return JS_FALSE;
@ -2967,7 +2967,7 @@ js::array_concat(JSContext *cx, unsigned argc, Value *vp)
if (v.isObject()) {
JSObject &obj = v.toObject();
if (ObjectClassIs(obj, ESClass_Array, cx)) {
jsuint alength;
uint32_t alength;
if (!js_GetLengthProperty(cx, &obj, &alength))
return false;
for (uint32_t slot = 0; slot < alength; slot++) {
@ -3000,7 +3000,7 @@ static JSBool
array_slice(JSContext *cx, unsigned argc, Value *vp)
{
JSObject *nobj;
jsuint length, begin, end, slot;
uint32_t length, begin, end, slot;
JSBool hole;
CallArgs args = CallArgsFromVp(argc, vp);
@ -3025,7 +3025,7 @@ array_slice(JSContext *cx, unsigned argc, Value *vp)
} else if (d > length) {
d = length;
}
begin = (jsuint)d;
begin = (uint32_t)d;
if (args.hasDefined(1)) {
if (!ToInteger(cx, args[1], &d))
@ -3037,7 +3037,7 @@ array_slice(JSContext *cx, unsigned argc, Value *vp)
} else if (d > length) {
d = length;
}
end = (jsuint)d;
end = (uint32_t)d;
}
}
@ -3081,7 +3081,7 @@ enum IndexOfKind {
static JSBool
array_indexOfHelper(JSContext *cx, IndexOfKind mode, CallArgs &args)
{
jsuint length, i, stop;
uint32_t length, i, stop;
Value tosearch;
int direction;
JSBool hole;
@ -3110,14 +3110,14 @@ array_indexOfHelper(JSContext *cx, IndexOfKind mode, CallArgs &args)
goto not_found;
i = 0;
} else {
i = (jsuint)start;
i = (uint32_t)start;
}
} else if (start >= length) {
if (mode == IndexOf)
goto not_found;
i = length - 1;
} else {
i = (jsuint)start;
i = (uint32_t)start;
}
}
@ -3132,7 +3132,7 @@ array_indexOfHelper(JSContext *cx, IndexOfKind mode, CallArgs &args)
for (;;) {
Value elt;
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
!GetElement(cx, obj, (jsuint)i, &hole, &elt)) {
!GetElement(cx, obj, (uint32_t)i, &hole, &elt)) {
return JS_FALSE;
}
if (!hole) {
@ -3736,7 +3736,7 @@ js_InitArrayClass(JSContext *cx, JSObject *obj)
namespace js {
static inline bool
EnsureNewArrayElements(JSContext *cx, JSObject *obj, jsuint length)
EnsureNewArrayElements(JSContext *cx, JSObject *obj, uint32_t length)
{
/*
* If ensureElements creates dynamically allocated slots, then having

View File

@ -57,13 +57,13 @@ const uint32_t MAX_ARRAY_INDEX = 4294967294u;
}
inline JSBool
js_IdIsIndex(jsid id, jsuint *indexp)
js_IdIsIndex(jsid id, uint32_t *indexp)
{
if (JSID_IS_INT(id)) {
int32_t i = JSID_TO_INT(id);
if (i < 0)
return JS_FALSE;
*indexp = (jsuint)i;
*indexp = (uint32_t)i;
return JS_TRUE;
}
@ -137,7 +137,7 @@ NewSlowEmptyArray(JSContext *cx);
} /* namespace js */
extern JSBool
js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp);
js_GetLengthProperty(JSContext *cx, JSObject *obj, uint32_t *lengthp);
extern JSBool
js_SetLengthProperty(JSContext *cx, JSObject *obj, double length);
@ -158,7 +158,7 @@ array_deleteElement(JSContext *cx, JSObject *obj, uint32_t index, Value *rval, J
* js_GetLengthProperty on aobj.
*/
extern bool
GetElements(JSContext *cx, JSObject *aobj, jsuint length, js::Value *vp);
GetElements(JSContext *cx, JSObject *aobj, uint32_t length, js::Value *vp);
/* Natives exposed for optimization by the interpreter and JITs. */

View File

@ -712,9 +712,9 @@ js_CheckForStringIndex(jsid id)
const jschar *cp = s;
const jschar *end = s + n;
jsuint index = JS7_UNDEC(*cp++);
jsuint oldIndex = 0;
jsuint c = 0;
uint32_t index = JS7_UNDEC(*cp++);
uint32_t oldIndex = 0;
uint32_t c = 0;
if (index != 0) {
while (JS7_ISDEC(*cp)) {

View File

@ -504,6 +504,37 @@ js_ReportErrorVA(JSContext *cx, unsigned flags, const char *format, va_list ap)
return warning;
}
namespace js {
/* |callee| requires a usage string provided by JS_DefineFunctionsWithHelp. */
void
ReportUsageError(JSContext *cx, JSObject *callee, const char *msg)
{
const char *usageStr = "usage";
JSAtom *usageAtom = js_Atomize(cx, usageStr, strlen(usageStr));
DebugOnly<const Shape *> shape = callee->nativeLookup(cx, ATOM_TO_JSID(usageAtom));
JS_ASSERT(!shape->configurable());
JS_ASSERT(!shape->writable());
JS_ASSERT(shape->hasDefaultGetter());
jsval usage;
if (!JS_LookupProperty(cx, callee, "usage", &usage))
return;
if (JSVAL_IS_VOID(usage)) {
JS_ReportError(cx, "%s", msg);
} else {
JSString *str = JSVAL_TO_STRING(usage);
JS::Anchor<JSString *> a_str(str);
const jschar *chars = JS_GetStringCharsZ(cx, str);
if (!chars)
return;
JS_ReportError(cx, "%s. Usage: %hs", msg, chars);
}
}
} /* namespace js */
/*
* The arguments from ap need to be packaged up into an array and stored
* into the report struct.

View File

@ -419,6 +419,7 @@ struct JSRuntime : js::RuntimeFriendFields
int gcZealFrequency;
int gcNextScheduled;
bool gcDebugCompartmentGC;
bool gcDeterministicOnly;
int gcZeal() { return gcZeal_; }
@ -829,11 +830,11 @@ struct JSContext : js::ContextFriendFields
bool hasVersionOverride;
/* Exception state -- the exception member is a GC root by definition. */
JSBool throwing; /* is there a pending exception? */
js::Value exception; /* most-recently-thrown exception */
JSBool throwing; /* is there a pending exception? */
js::Value exception; /* most-recently-thrown exception */
/* Per-context run options. */
unsigned runOptions; /* see jsapi.h for JSOPTION_* */
unsigned runOptions; /* see jsapi.h for JSOPTION_* */
public:
int32_t reportGranularity; /* see jsprobes.h */
@ -843,11 +844,8 @@ struct JSContext : js::ContextFriendFields
js::AutoResolving *resolvingList;
/*
* True if generating an error, to prevent runaway recursion.
* NB: generatingError packs with throwing below.
*/
bool generatingError;
/* True if generating an error, to prevent runaway recursion. */
bool generatingError;
/* GC heap compartment. */
JSCompartment *compartment;
@ -1418,6 +1416,14 @@ js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
bool charArgs, va_list ap);
#endif
namespace js {
/* |callee| requires a usage string provided by JS_DefineFunctionsWithHelp. */
extern void
ReportUsageError(JSContext *cx, JSObject *callee, const char *msg);
} /* namespace js */
extern void
js_ReportOutOfMemory(JSContext *cx);

View File

@ -1084,7 +1084,7 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
*/
JS_ASSERT(reportp);
if (JSREPORT_IS_WARNING(reportp->flags))
return JS_FALSE;
return false;
/* Find the exception index associated with this error. */
errorNumber = (JSErrNum) reportp->errorNumber;
@ -1107,19 +1107,12 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
* with the given error number.
*/
if (exn == JSEXN_NONE)
return JS_FALSE;
return false;
/*
* Prevent runaway recursion, via cx->generatingError. If an out-of-memory
* error occurs, no exception object will be created, but we don't assume
* that OOM is the only kind of error that subroutines of this function
* called below might raise.
*/
/* Prevent infinite recursion. */
if (cx->generatingError)
return JS_FALSE;
MUST_FLOW_THROUGH("out");
cx->generatingError = JS_TRUE;
return false;
AutoScopedAssign<bool> asa(&cx->generatingError, false);
/* Protect the newly-created strings below from nesting GCs. */
PodArrayZero(tv);
@ -1132,43 +1125,34 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
*/
ok = js_GetClassPrototype(cx, NULL, GetExceptionProtoKey(exn), &errProto);
if (!ok)
goto out;
return false;
tv[0] = OBJECT_TO_JSVAL(errProto);
errObject = NewObjectWithGivenProto(cx, &ErrorClass, errProto, NULL);
if (!errObject) {
ok = JS_FALSE;
goto out;
}
if (!errObject)
return false;
tv[1] = OBJECT_TO_JSVAL(errObject);
messageStr = JS_NewStringCopyZ(cx, message);
if (!messageStr) {
ok = JS_FALSE;
goto out;
}
if (!messageStr)
return false;
tv[2] = STRING_TO_JSVAL(messageStr);
filenameStr = JS_NewStringCopyZ(cx, reportp->filename);
if (!filenameStr) {
ok = JS_FALSE;
goto out;
}
if (!filenameStr)
return false;
tv[3] = STRING_TO_JSVAL(filenameStr);
ok = InitExnPrivate(cx, errObject, messageStr, filenameStr,
reportp->lineno, reportp, exn);
if (!ok)
goto out;
return false;
JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject));
/* Flag the error report passed in to indicate an exception was raised. */
reportp->flags |= JSREPORT_EXCEPTION;
out:
cx->generatingError = JS_FALSE;
return ok;
return true;
}
JSBool

View File

@ -47,6 +47,8 @@
#include "jsweakmap.h"
#include "jswatchpoint.h"
#include "builtin/TestingFunctions.h"
#include "jsobjinlines.h"
using namespace js;
@ -180,6 +182,51 @@ JS_TraceShapeCycleCollectorChildren(JSTracer *trc, void *shape)
MarkCycleCollectorChildren(trc, (Shape *)shape);
}
static bool
DefineHelpProperty(JSContext *cx, JSObject *obj, const char *prop, const char *value)
{
JSAtom *atom = js_Atomize(cx, value, strlen(value));
if (!atom)
return false;
jsval v = STRING_TO_JSVAL(atom);
return JS_DefineProperty(cx, obj, prop, v,
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_READONLY | JSPROP_PERMANENT);
}
JS_FRIEND_API(bool)
JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *obj, const JSFunctionSpecWithHelp *fs)
{
RootObject objRoot(cx, &obj);
JS_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
for (; fs->name; fs++) {
JSAtom *atom = js_Atomize(cx, fs->name, strlen(fs->name));
if (!atom)
return false;
JSFunction *fun = js_DefineFunction(cx, objRoot,
ATOM_TO_JSID(atom), fs->call, fs->nargs, fs->flags);
if (!fun)
return false;
if (fs->usage) {
if (!DefineHelpProperty(cx, fun, "usage", fs->usage))
return false;
}
if (fs->help) {
if (!DefineHelpProperty(cx, fun, "help", fs->help))
return false;
}
}
return true;
}
AutoPreserveCompartment::AutoPreserveCompartment(JSContext *cx
JS_GUARD_OBJECT_NOTIFIER_PARAM_NO_INIT)
: cx(cx), oldCompartment(cx->compartment)
@ -789,4 +836,17 @@ IncrementalValueBarrier(const Value &v)
HeapValue::writeBarrierPre(v);
}
JS_FRIEND_API(JSObject *)
GetTestingFunctions(JSContext *cx)
{
JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL);
if (!obj)
return NULL;
if (!DefineTestingFunctions(cx, obj))
return NULL;
return obj;
}
} // namespace js

View File

@ -166,6 +166,21 @@ JS_WrapPropertyDescriptor(JSContext *cx, js::PropertyDescriptor *desc);
extern JS_FRIEND_API(JSBool)
JS_EnumerateState(JSContext *cx, JSObject *obj, JSIterateOp enum_op, js::Value *statep, jsid *idp);
struct JSFunctionSpecWithHelp {
const char *name;
JSNative call;
uint16_t nargs;
uint16_t flags;
const char *usage;
const char *help;
};
#define JS_FN_HELP(name,call,nargs,flags,usage,help) \
{name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, usage, help}
extern JS_FRIEND_API(bool)
JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *obj, const JSFunctionSpecWithHelp *fs);
#endif
JS_END_EXTERN_C
@ -498,7 +513,7 @@ JS_FRIEND_API(bool)
GetPropertyNames(JSContext *cx, JSObject *obj, unsigned flags, js::AutoIdVector *props);
JS_FRIEND_API(bool)
StringIsArrayIndex(JSLinearString *str, jsuint *indexp);
StringIsArrayIndex(JSLinearString *str, uint32_t *indexp);
JS_FRIEND_API(void)
SetPreserveWrapperCallback(JSRuntime *rt, PreserveWrapperCallback callback);
@ -658,7 +673,7 @@ SizeOfJSContext();
D(LAST_DITCH) \
D(TOO_MUCH_MALLOC) \
D(ALLOC_TRIGGER) \
D(UNUSED1) /* was CHUNK */ \
D(DEBUG_GC) \
D(UNUSED2) /* was SHAPE */ \
D(UNUSED3) /* was REFILL */ \
\
@ -808,6 +823,9 @@ class ObjectPtr
operator JSObject *() const { return value; }
};
extern JS_FRIEND_API(JSObject *)
GetTestingFunctions(JSContext *cx);
} /* namespace js */
#endif

View File

@ -1296,7 +1296,7 @@ js_fun_apply(JSContext *cx, unsigned argc, Value *vp)
* original version of ES5).
*/
JSObject *aobj = &vp[3].toObject();
jsuint length;
uint32_t length;
if (!js_GetLengthProperty(cx, aobj, &length))
return false;

View File

@ -664,7 +664,7 @@ Chunk::init()
info.age = 0;
/* Initialize the arena header state. */
for (jsuint i = 0; i < ArenasPerChunk; i++) {
for (unsigned i = 0; i < ArenasPerChunk; i++) {
arenas[i].aheader.setAsNotAllocated();
arenas[i].aheader.next = (i + 1 < ArenasPerChunk)
? &arenas[i + 1].aheader
@ -724,14 +724,14 @@ Chunk::removeFromAvailableList()
* it to the most recently freed arena when we free, and forcing it to
* the last alloc + 1 when we allocate.
*/
jsuint
uint32_t
Chunk::findDecommittedArenaOffset()
{
/* Note: lastFreeArenaOffset can be past the end of the list. */
for (jsuint i = info.lastDecommittedArenaOffset; i < ArenasPerChunk; i++)
for (unsigned i = info.lastDecommittedArenaOffset; i < ArenasPerChunk; i++)
if (decommittedArenas.get(i))
return i;
for (jsuint i = 0; i < info.lastDecommittedArenaOffset; i++)
for (unsigned i = 0; i < info.lastDecommittedArenaOffset; i++)
if (decommittedArenas.get(i))
return i;
JS_NOT_REACHED("No decommitted arenas found.");
@ -744,7 +744,7 @@ Chunk::fetchNextDecommittedArena()
JS_ASSERT(info.numArenasFreeCommitted == 0);
JS_ASSERT(info.numArenasFree > 0);
jsuint offset = findDecommittedArenaOffset();
unsigned offset = findDecommittedArenaOffset();
info.lastDecommittedArenaOffset = offset + 1;
--info.numArenasFree;
decommittedArenas.unset(offset);
@ -1708,13 +1708,13 @@ ArenaLists::finalizeScripts(JSContext *cx)
}
static void
RunLastDitchGC(JSContext *cx)
RunLastDitchGC(JSContext *cx, gcreason::Reason reason)
{
JSRuntime *rt = cx->runtime;
/* The last ditch GC preserves all atoms. */
AutoKeepAtoms keep(rt);
GC(cx, rt->gcTriggerCompartment, GC_NORMAL, gcreason::LAST_DITCH);
GC(cx, rt->gcTriggerCompartment, GC_NORMAL, reason);
}
/* static */ void *
@ -1729,7 +1729,7 @@ ArenaLists::refillFreeList(JSContext *cx, AllocKind thingKind)
bool runGC = rt->gcIncrementalState != NO_INCREMENTAL && comp->gcBytes > comp->gcTriggerBytes;
for (;;) {
if (JS_UNLIKELY(runGC)) {
RunLastDitchGC(cx);
RunLastDitchGC(cx, gcreason::LAST_DITCH);
/*
* The JSGC_END callback can legitimately allocate new GC
@ -3662,6 +3662,20 @@ GCCycle(JSContext *cx, JSCompartment *comp, int64_t budget, JSGCInvocationKind g
#endif
}
#ifdef JS_GC_ZEAL
static bool
IsDeterministicGCReason(gcreason::Reason reason)
{
if (reason > gcreason::DEBUG_GC && reason != gcreason::CC_FORCED)
return false;
if (reason == gcreason::MAYBEGC)
return false;
return true;
}
#endif
static void
Collect(JSContext *cx, JSCompartment *comp, int64_t budget,
JSGCInvocationKind gckind, gcreason::Reason reason)
@ -3669,6 +3683,11 @@ Collect(JSContext *cx, JSCompartment *comp, int64_t budget,
JSRuntime *rt = cx->runtime;
JS_AbortIfWrongThread(rt);
#ifdef JS_GC_ZEAL
if (rt->gcDeterministicOnly && !IsDeterministicGCReason(reason))
return;
#endif
JS_ASSERT_IF(budget != SliceBudget::Unlimited, JSGC_INCREMENTAL);
#ifdef JS_GC_ZEAL
@ -3947,7 +3966,16 @@ RunDebugGC(JSContext *cx)
if (rt->gcTriggerCompartment == rt->atomsCompartment)
rt->gcTriggerCompartment = NULL;
RunLastDitchGC(cx);
RunLastDitchGC(cx, gcreason::DEBUG_GC);
#endif
}
void
SetDeterministicGC(JSContext *cx, bool enabled)
{
#ifdef JS_GC_ZEAL
JSRuntime *rt = cx->runtime;
rt->gcDeterministicOnly = enabled;
#endif
}

View File

@ -808,7 +808,7 @@ struct Chunk {
inline void init();
/* Search for a decommitted arena to allocate. */
jsuint findDecommittedArenaOffset();
unsigned findDecommittedArenaOffset();
ArenaHeader* fetchNextDecommittedArena();
public:
@ -1968,6 +1968,9 @@ NewCompartment(JSContext *cx, JSPrincipals *principals);
void
RunDebugGC(JSContext *cx);
void
SetDeterministicGC(JSContext *cx, bool enabled);
#if defined(JSGC_ROOT_ANALYSIS) && defined(DEBUG) && !defined(JS_THREADSAFE)
/* Overwrites stack references to GC things which have not been rooted. */
void CheckStackRoots(JSContext *cx);

View File

@ -440,6 +440,21 @@ js::RunScript(JSContext *cx, JSScript *script, StackFrame *fp)
}
}
#ifdef DEBUG
struct CheckStackBalance {
JSContext *cx;
StackFrame *fp;
JSObject *enumerators;
CheckStackBalance(JSContext *cx)
: cx(cx), fp(cx->fp()), enumerators(cx->enumerators)
{}
~CheckStackBalance() {
JS_ASSERT(fp == cx->fp());
JS_ASSERT_IF(!fp->isGeneratorFrame(), enumerators == cx->enumerators);
}
} check(cx);
#endif
#ifdef JS_METHODJIT
mjit::CompileStatus status;
status = mjit::CanMethodJIT(cx, script, script->code, fp->isConstructing(),
@ -511,12 +526,9 @@ js::InvokeKernel(JSContext *cx, CallArgs args, MaybeConstruct construct)
return false;
/* Run function until JSOP_STOP, JSOP_RETURN or error. */
JSBool ok;
{
AutoPreserveEnumerators preserve(cx);
ok = RunScript(cx, fun->script(), fp);
}
JSBool ok = RunScript(cx, fun->script(), fp);
/* Propagate the return value out. */
args.rval() = fp->returnValue();
JS_ASSERT_IF(ok && construct, !args.rval().isPrimitive());
return ok;
@ -653,17 +665,17 @@ js::ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const V
TypeScript::SetThis(cx, script, fp->thisValue());
AutoPreserveEnumerators preserve(cx);
JSBool ok = RunScript(cx, script, fp);
if (result && ok)
*result = fp->returnValue();
bool ok = RunScript(cx, script, fp);
if (fp->isStrictEvalFrame())
js_PutCallObject(fp);
Probes::stopExecution(cx, script);
return !!ok;
/* Propgate the return value out. */
if (result)
*result = fp->returnValue();
return ok;
}
bool
@ -977,31 +989,35 @@ js::UnwindScope(JSContext *cx, uint32_t stackDepth)
}
/*
* Find the results of incrementing or decrementing *vp. For pre-increments,
* both *vp and *vp2 will contain the result on return. For post-increments,
* vp will contain the original value converted to a number and vp2 will get
* the result. Both vp and vp2 must be roots.
* Increment/decrement the value 'v'. The resulting value is stored in *slot.
* The result of the expression (taking into account prefix/postfix) is stored
* in *expr.
*/
static bool
DoIncDec(JSContext *cx, const JSCodeSpec *cs, Value *vp, Value *vp2)
DoIncDec(JSContext *cx, JSScript *script, jsbytecode *pc, const Value &v, Value *slot, Value *expr)
{
if (cs->format & JOF_POST) {
double d;
if (!ToNumber(cx, *vp, &d))
return JS_FALSE;
vp->setNumber(d);
(cs->format & JOF_INC) ? ++d : --d;
vp2->setNumber(d);
return JS_TRUE;
const JSCodeSpec &cs = js_CodeSpec[*pc];
if (v.isInt32()) {
int32_t i = v.toInt32();
if (i > JSVAL_INT_MIN && i < JSVAL_INT_MAX) {
int32_t sum = i + (cs.format & JOF_INC ? 1 : -1);
*slot = Int32Value(sum);
*expr = (cs.format & JOF_POST) ? Int32Value(i) : *slot;
return true;
}
}
double d;
if (!ToNumber(cx, *vp, &d))
return JS_FALSE;
(cs->format & JOF_INC) ? ++d : --d;
vp->setNumber(d);
*vp2 = *vp;
return JS_TRUE;
if (!ToNumber(cx, *slot, &d))
return false;
double sum = d + (cs.format & JOF_INC ? 1 : -1);
*slot = NumberValue(sum);
*expr = (cs.format & JOF_POST) ? NumberValue(d) : *slot;
TypeScript::MonitorOverflow(cx, script, pc);
return true;
}
const Value &
@ -1079,13 +1095,6 @@ js::FindUpvarFrame(JSContext *cx, unsigned targetLevel)
goto error; \
JS_END_MACRO
/* Test whether v is an int in the range [-2^31 + 1, 2^31 - 2] */
static JS_ALWAYS_INLINE bool
CanIncDecWithoutOverflow(int32_t i)
{
return (i > JSVAL_INT_MIN) && (i < JSVAL_INT_MAX);
}
/*
* Threaded interpretation via computed goto appears to be well-supported by
* GCC 3 and higher. IBM's C compiler when run with the right options (e.g.,
@ -2489,62 +2498,29 @@ BEGIN_CASE(JSOP_GNAMEDEC)
/* No-op */
END_CASE(JSOP_INCPROP)
{
int incr, incr2;
uint32_t slot;
Value *vp;
/* Position cases so the most frequent i++ does not need a jump. */
BEGIN_CASE(JSOP_DECARG)
incr = -1; incr2 = -1; goto do_arg_incop;
BEGIN_CASE(JSOP_ARGDEC)
incr = -1; incr2 = 0; goto do_arg_incop;
BEGIN_CASE(JSOP_INCARG)
incr = 1; incr2 = 1; goto do_arg_incop;
BEGIN_CASE(JSOP_ARGINC)
incr = 1; incr2 = 0;
do_arg_incop:
slot = GET_ARGNO(regs.pc);
JS_ASSERT(slot < regs.fp()->numFormalArgs());
vp = argv + slot;
goto do_int_fast_incop;
{
Value &arg = regs.fp()->formalArg(GET_ARGNO(regs.pc));
if (!DoIncDec(cx, script, regs.pc, arg, &arg, &regs.sp[0]))
goto error;
regs.sp++;
}
END_CASE(JSOP_ARGINC);
BEGIN_CASE(JSOP_DECLOCAL)
incr = -1; incr2 = -1; goto do_local_incop;
BEGIN_CASE(JSOP_LOCALDEC)
incr = -1; incr2 = 0; goto do_local_incop;
BEGIN_CASE(JSOP_INCLOCAL)
incr = 1; incr2 = 1; goto do_local_incop;
BEGIN_CASE(JSOP_LOCALINC)
incr = 1; incr2 = 0;
/*
* do_local_incop comes right before do_int_fast_incop as we want to
* avoid an extra jump for variable cases as local++ is more frequent
* than arg++.
*/
do_local_incop:
slot = GET_SLOTNO(regs.pc);
JS_ASSERT(slot < regs.fp()->numSlots());
vp = regs.fp()->slots() + slot;
do_int_fast_incop:
int32_t tmp;
if (JS_LIKELY(vp->isInt32() && CanIncDecWithoutOverflow(tmp = vp->toInt32()))) {
vp->getInt32Ref() = tmp + incr;
JS_ASSERT(JSOP_INCARG_LENGTH == js_CodeSpec[op].length);
PUSH_INT32(tmp + incr2);
} else {
PUSH_COPY(*vp);
if (!DoIncDec(cx, &js_CodeSpec[op], &regs.sp[-1], vp))
goto error;
TypeScript::MonitorOverflow(cx, script, regs.pc);
}
len = JSOP_INCARG_LENGTH;
JS_ASSERT(len == js_CodeSpec[op].length);
DO_NEXT_OP(len);
{
Value &local = regs.fp()->localSlot(GET_SLOTNO(regs.pc));
if (!DoIncDec(cx, script, regs.pc, local, &local, &regs.sp[0]))
goto error;
regs.sp++;
}
END_CASE(JSOP_LOCALINC)
BEGIN_CASE(JSOP_THIS)
if (!ComputeThis(cx, regs.fp()))
@ -2905,7 +2881,7 @@ BEGIN_CASE(JSOP_TABLESWITCH)
int32_t high = GET_JUMP_OFFSET(pc2);
i -= low;
if ((jsuint)i < (jsuint)(high - low + 1)) {
if ((uint32_t)i < (uint32_t)(high - low + 1)) {
pc2 += JUMP_OFFSET_LEN + JUMP_OFFSET_LEN * i;
int32_t off = (int32_t) GET_JUMP_OFFSET(pc2);
if (off)
@ -3557,9 +3533,9 @@ BEGIN_CASE(JSOP_INITELEM)
if (rref.isMagic(JS_ARRAY_HOLE)) {
JS_ASSERT(obj->isArray());
JS_ASSERT(JSID_IS_INT(id));
JS_ASSERT(jsuint(JSID_TO_INT(id)) < StackSpace::ARGS_LENGTH_MAX);
JS_ASSERT(uint32_t(JSID_TO_INT(id)) < StackSpace::ARGS_LENGTH_MAX);
if (JSOp(regs.pc[JSOP_INITELEM_LENGTH]) == JSOP_ENDINIT &&
!js_SetLengthProperty(cx, obj, (jsuint) (JSID_TO_INT(id) + 1))) {
!js_SetLengthProperty(cx, obj, (uint32_t) (JSID_TO_INT(id) + 1))) {
goto error;
}
} else {

View File

@ -61,21 +61,6 @@
namespace js {
class AutoPreserveEnumerators {
JSContext *cx;
JSObject *enumerators;
public:
AutoPreserveEnumerators(JSContext *cx) : cx(cx), enumerators(cx->enumerators)
{
}
~AutoPreserveEnumerators()
{
cx->enumerators = enumerators;
}
};
/*
* Compute the implicit |this| parameter for a call expression where the callee
* funval was resolved from an unqualified name reference to a property on obj
@ -232,7 +217,7 @@ GetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, Value *vp
if (lval.isObject()) {
JSObject *obj = &lval.toObject();
if (obj->isArray()) {
jsuint length = obj->getArrayLength();
uint32_t length = obj->getArrayLength();
*vp = NumberValue(length);
return true;
}
@ -804,13 +789,13 @@ SetObjectElementOperation(JSContext *cx, JSObject *obj, jsid id, const Value &va
do {
if (obj->isDenseArray() && JSID_IS_INT(id)) {
jsuint length = obj->getDenseArrayInitializedLength();
uint32_t length = obj->getDenseArrayInitializedLength();
int32_t i = JSID_TO_INT(id);
if ((jsuint)i < length) {
if ((uint32_t)i < length) {
if (obj->getDenseArrayElement(i).isMagic(JS_ARRAY_HOLE)) {
if (js_PrototypeHasIndexedProperties(cx, obj))
break;
if ((jsuint)i >= obj->getArrayLength())
if ((uint32_t)i >= obj->getArrayLength())
obj->setArrayLength(cx, i + 1);
}
obj->setDenseArrayElementWithType(cx, i, value);

View File

@ -435,7 +435,7 @@ js_math_min(JSContext *cx, unsigned argc, Value *vp)
static double
powi(double x, int y)
{
jsuint n = (y < 0) ? -y : y;
unsigned n = (y < 0) ? -y : y;
double m = x;
double p = 1;
while (true) {

View File

@ -577,7 +577,7 @@ js_IntToString(JSContext *cx, int32_t si)
static char *
IntToCString(ToCStringBuf *cbuf, int i, int base = 10)
{
jsuint u = (i < 0) ? -i : i;
unsigned u = (i < 0) ? -i : i;
RangedPtr<char> cp(cbuf->sbuf + cbuf->sbufSize - 1, cbuf->sbuf, cbuf->sbufSize);
*cp = '\0';
@ -589,7 +589,7 @@ IntToCString(ToCStringBuf *cbuf, int i, int base = 10)
break;
case 16:
do {
jsuint newu = u / 16;
unsigned newu = u / 16;
*--cp = "0123456789abcdef"[u - newu * 16];
u = newu;
} while (u != 0);
@ -597,7 +597,7 @@ IntToCString(ToCStringBuf *cbuf, int i, int base = 10)
default:
JS_ASSERT(base >= 2 && base <= 36);
do {
jsuint newu = u / base;
unsigned newu = u / base;
*--cp = "0123456789abcdefghijklmnopqrstuvwxyz"[u - newu * base];
u = newu;
} while (u != 0);
@ -1127,7 +1127,7 @@ js_NumberToStringWithBase(JSContext *cx, double d, int base)
if (JSDOUBLE_IS_INT32(d, &i)) {
if (base == 10 && StaticStrings::hasInt(i))
return cx->runtime->staticStrings.getInt(i);
if (jsuint(i) < jsuint(base)) {
if (unsigned(i) < unsigned(base)) {
if (i < 10)
return cx->runtime->staticStrings.getInt(i);
jschar c = 'a' + i - 10;
@ -1346,7 +1346,7 @@ ValueToUint16Slow(JSContext *cx, const Value &v, uint16_t *out)
bool neg = (d < 0);
d = floor(neg ? -d : d);
d = neg ? -d : d;
jsuint m = JS_BIT(16);
unsigned m = JS_BIT(16);
d = fmod(d, (double) m);
if (d < 0)
d += m;

View File

@ -2194,7 +2194,7 @@ DefinePropertyOnArray(JSContext *cx, JSObject *obj, const jsid &id, const PropDe
if (obj->isDenseArray() && !obj->makeDenseArraySlow(cx))
return JS_FALSE;
jsuint oldLen = obj->getArrayLength();
uint32_t oldLen = obj->getArrayLength();
if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
/*

View File

@ -500,7 +500,7 @@ JA(JSContext *cx, JSObject *obj, StringifyContext *scx)
return JS_FALSE;
/* Step 6. */
jsuint length;
uint32_t length;
if (!js_GetLengthProperty(cx, obj, &length))
return JS_FALSE;
@ -649,7 +649,7 @@ js_Stringify(JSContext *cx, Value *vp, JSObject *replacer, Value space, StringBu
*/
/* Step 4b(ii). */
jsuint len;
uint32_t len;
JS_ALWAYS_TRUE(js_GetLengthProperty(cx, replacer, &len));
if (replacer->isDenseArray())
len = JS_MIN(len, replacer->getDenseArrayCapacity());
@ -659,7 +659,7 @@ js_Stringify(JSContext *cx, Value *vp, JSObject *replacer, Value space, StringBu
return false;
/* Step 4b(iii). */
jsuint i = 0;
uint32_t i = 0;
/* Step 4b(iv). */
for (; i < len; i++) {

View File

@ -1825,7 +1825,7 @@ GetLocal(SprintStack *ss, int i)
if (obj->isBlock()) {
uint32_t depth = obj->asBlock().stackDepth();
uint32_t count = obj->asBlock().slotCount();
if (jsuint(i - depth) < jsuint(count))
if (uint32_t(i - depth) < uint32_t(count))
return GetLocalInSlot(ss, i, int(i - depth), obj);
}
}
@ -1838,7 +1838,7 @@ GetLocal(SprintStack *ss, int i)
if (obj->isBlock()) {
uint32_t depth = obj->asBlock().stackDepth();
uint32_t count = obj->asBlock().slotCount();
if (jsuint(i - depth) < jsuint(count))
if (uint32_t(i - depth) < uint32_t(count))
return GetLocalInSlot(ss, i, int(i - depth), obj);
}
}

View File

@ -494,11 +494,11 @@ ArrayToIdVector(JSContext *cx, const Value &array, AutoIdVector &props)
return true;
JSObject *obj = &array.toObject();
jsuint length;
uint32_t length;
if (!js_GetLengthProperty(cx, obj, &length))
return false;
for (jsuint n = 0; n < length; ++n) {
for (uint32_t n = 0; n < length; ++n) {
if (!JS_CHECK_OPERATION_LIMIT(cx))
return false;
Value v;

View File

@ -93,9 +93,6 @@ typedef ptrdiff_t jsid;
JS_BEGIN_EXTERN_C
/* Scalar typedefs. */
typedef uint32_t jsuint;
#ifdef WIN32
typedef wchar_t jschar;
#else

View File

@ -644,7 +644,7 @@ JSObject::addPropertyInternal(JSContext *cx, jsid id,
{
shape = self->lastProperty();
jsuint index;
uint32_t index;
bool indexed = js_IdIsIndex(id, &index);
UnownedBaseShape *nbase;
if (shape->base()->matchesGetterSetter(getter, setter) && !indexed) {
@ -758,7 +758,7 @@ JSObject::putProperty(JSContext *cx, jsid id,
RootedVar<UnownedBaseShape*> nbase(cx);
{
jsuint index;
uint32_t index;
bool indexed = js_IdIsIndex(id, &index);
StackBaseShape base(self->lastProperty()->base());
base.updateGetterSetter(attrs, getter, setter);

View File

@ -877,31 +877,31 @@ out_of_range:
*
* Return the index of pat in text, or -1 if not found.
*/
static const jsuint sBMHCharSetSize = 256; /* ISO-Latin-1 */
static const jsuint sBMHPatLenMax = 255; /* skip table element is uint8_t */
static const int sBMHBadPattern = -2; /* return value if pat is not ISO-Latin-1 */
static const uint32_t sBMHCharSetSize = 256; /* ISO-Latin-1 */
static const uint32_t sBMHPatLenMax = 255; /* skip table element is uint8_t */
static const int sBMHBadPattern = -2; /* return value if pat is not ISO-Latin-1 */
int
js_BoyerMooreHorspool(const jschar *text, jsuint textlen,
const jschar *pat, jsuint patlen)
js_BoyerMooreHorspool(const jschar *text, uint32_t textlen,
const jschar *pat, uint32_t patlen)
{
uint8_t skip[sBMHCharSetSize];
JS_ASSERT(0 < patlen && patlen <= sBMHPatLenMax);
for (jsuint i = 0; i < sBMHCharSetSize; i++)
for (uint32_t i = 0; i < sBMHCharSetSize; i++)
skip[i] = (uint8_t)patlen;
jsuint m = patlen - 1;
for (jsuint i = 0; i < m; i++) {
uint32_t m = patlen - 1;
for (uint32_t i = 0; i < m; i++) {
jschar c = pat[i];
if (c >= sBMHCharSetSize)
return sBMHBadPattern;
skip[c] = (uint8_t)(m - i);
}
jschar c;
for (jsuint k = m;
for (uint32_t k = m;
k < textlen;
k += ((c = text[k]) >= sBMHCharSetSize) ? patlen : skip[c]) {
for (jsuint i = k, j = m; ; i--, j--) {
for (uint32_t i = k, j = m; ; i--, j--) {
if (text[i] != pat[j])
break;
if (j == 0)
@ -912,8 +912,8 @@ js_BoyerMooreHorspool(const jschar *text, jsuint textlen,
}
struct MemCmp {
typedef jsuint Extent;
static JS_ALWAYS_INLINE Extent computeExtent(const jschar *, jsuint patlen) {
typedef uint32_t Extent;
static JS_ALWAYS_INLINE Extent computeExtent(const jschar *, uint32_t patlen) {
return (patlen - 1) * sizeof(jschar);
}
static JS_ALWAYS_INLINE bool match(const jschar *p, const jschar *t, Extent extent) {
@ -923,7 +923,7 @@ struct MemCmp {
struct ManualCmp {
typedef const jschar *Extent;
static JS_ALWAYS_INLINE Extent computeExtent(const jschar *pat, jsuint patlen) {
static JS_ALWAYS_INLINE Extent computeExtent(const jschar *pat, uint32_t patlen) {
return pat + patlen;
}
static JS_ALWAYS_INLINE bool match(const jschar *p, const jschar *t, Extent extent) {
@ -937,7 +937,7 @@ struct ManualCmp {
template <class InnerMatch>
static int
UnrolledMatch(const jschar *text, jsuint textlen, const jschar *pat, jsuint patlen)
UnrolledMatch(const jschar *text, uint32_t textlen, const jschar *pat, uint32_t patlen)
{
JS_ASSERT(patlen > 0 && textlen > 0);
const jschar *textend = text + textlen - (patlen - 1);
@ -982,8 +982,8 @@ UnrolledMatch(const jschar *text, jsuint textlen, const jschar *pat, jsuint patl
}
static JS_ALWAYS_INLINE int
StringMatch(const jschar *text, jsuint textlen,
const jschar *pat, jsuint patlen)
StringMatch(const jschar *text, uint32_t textlen,
const jschar *pat, uint32_t patlen)
{
if (patlen == 0)
return 0;
@ -1046,7 +1046,7 @@ static const size_t sRopeMatchThresholdRatioLog2 = 5;
* the 'match' outparam (-1 for not found).
*/
static bool
RopeMatch(JSContext *cx, JSString *textstr, const jschar *pat, jsuint patlen, int *match)
RopeMatch(JSContext *cx, JSString *textstr, const jschar *pat, uint32_t patlen, int *match)
{
JS_ASSERT(textstr->isRope());
@ -1157,21 +1157,21 @@ str_indexOf(JSContext *cx, unsigned argc, Value *vp)
if (!patstr)
return false;
jsuint textlen = str->length();
uint32_t textlen = str->length();
const jschar *text = str->getChars(cx);
if (!text)
return false;
jsuint patlen = patstr->length();
uint32_t patlen = patstr->length();
const jschar *pat = patstr->chars();
jsuint start;
uint32_t start;
if (args.length() > 1) {
if (args[1].isInt32()) {
int i = args[1].toInt32();
if (i <= 0) {
start = 0;
} else if (jsuint(i) > textlen) {
} else if (uint32_t(i) > textlen) {
start = textlen;
textlen = 0;
} else {
@ -3957,7 +3957,7 @@ Decode(JSContext *cx, JSString *str, const jschar *reservedSet, Value *rval)
goto report_bad_uri;
if (!JS7_ISHEX(chars[k+1]) || !JS7_ISHEX(chars[k+2]))
goto report_bad_uri;
jsuint B = JS7_UNHEX(chars[k+1]) * 16 + JS7_UNHEX(chars[k+2]);
uint32_t B = JS7_UNHEX(chars[k+1]) * 16 + JS7_UNHEX(chars[k+2]);
k += 2;
if (!(B & 0x80)) {
c = (jschar)B;

View File

@ -81,7 +81,7 @@ using namespace js::types;
static const uint8_t ARRAYBUFFER_RESERVED_SLOTS = JSObject::MAX_FIXED_SLOTS - 1;
static bool
ValueIsLength(JSContext *cx, const Value &v, jsuint *len)
ValueIsLength(JSContext *cx, const Value &v, uint32_t *len)
{
if (v.isInt32()) {
int32_t i = v.toInt32();
@ -96,7 +96,7 @@ ValueIsLength(JSContext *cx, const Value &v, jsuint *len)
if (JSDOUBLE_IS_NaN(d))
return false;
jsuint length = jsuint(d);
uint32_t length = uint32_t(d);
if (d != double(length))
return false;
@ -730,9 +730,9 @@ TypedArray::getTypedArray(JSObject *obj)
}
inline bool
TypedArray::isArrayIndex(JSContext *cx, JSObject *obj, jsid id, jsuint *ip)
TypedArray::isArrayIndex(JSContext *cx, JSObject *obj, jsid id, uint32_t *ip)
{
jsuint index;
uint32_t index;
if (js_IdIsIndex(id, &index) && index < getLength(obj)) {
if (ip)
*ip = index;
@ -1264,7 +1264,7 @@ class TypedArrayTemplate
return true;
}
jsuint index;
uint32_t index;
// We can't just chain to js_SetPropertyHelper, because we're not a normal object.
if (!isArrayIndex(cx, tarray, id, &index)) {
// Silent ignore is better than an exception here, because
@ -1509,7 +1509,7 @@ class TypedArrayTemplate
/* N.B. there may not be an argv[-2]/argv[-1]. */
/* () or (number) */
jsuint len = 0;
uint32_t len = 0;
if (argc == 0 || ValueIsLength(cx, argv[0], &len)) {
JSObject *bufobj = createBufferWithSizeAndCount(cx, len);
if (!bufobj)
@ -1663,7 +1663,7 @@ class TypedArrayTemplate
if (!copyFromTypedArray(cx, obj, src, offset))
return false;
} else {
jsuint len;
uint32_t len;
if (!js_GetLengthProperty(cx, arg0, &len))
return false;
@ -1734,7 +1734,7 @@ class TypedArrayTemplate
* Otherwise create a new typed array and copy len properties from the
* object.
*/
jsuint len;
uint32_t len;
if (!js_GetLengthProperty(cx, other, &len))
return NULL;
@ -1824,7 +1824,7 @@ class TypedArrayTemplate
static bool
copyFromArray(JSContext *cx, JSObject *thisTypedArrayObj,
JSObject *ar, jsuint len, jsuint offset = 0)
JSObject *ar, uint32_t len, uint32_t offset = 0)
{
thisTypedArrayObj = getTypedArray(thisTypedArrayObj);
JS_ASSERT(thisTypedArrayObj);
@ -1858,7 +1858,7 @@ class TypedArrayTemplate
}
static bool
copyFromTypedArray(JSContext *cx, JSObject *thisTypedArrayObj, JSObject *tarray, jsuint offset)
copyFromTypedArray(JSContext *cx, JSObject *thisTypedArrayObj, JSObject *tarray, uint32_t offset)
{
thisTypedArrayObj = getTypedArray(thisTypedArrayObj);
JS_ASSERT(thisTypedArrayObj);
@ -1935,7 +1935,7 @@ class TypedArrayTemplate
}
static bool
copyFromWithOverlap(JSContext *cx, JSObject *self, JSObject *tarray, jsuint offset)
copyFromWithOverlap(JSContext *cx, JSObject *self, JSObject *tarray, uint32_t offset)
{
JS_ASSERT(offset <= getLength(self));
@ -2532,13 +2532,13 @@ js_IsTypedArray(JSObject *obj)
}
JS_FRIEND_API(JSObject *)
js_CreateArrayBuffer(JSContext *cx, jsuint nbytes)
js_CreateArrayBuffer(JSContext *cx, uint32_t nbytes)
{
return ArrayBuffer::create(cx, nbytes);
}
JS_FRIEND_API(JSObject *)
JS_NewArrayBuffer(JSContext *cx, jsuint nbytes)
JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes)
{
return js_CreateArrayBuffer(cx, nbytes);
}
@ -2581,7 +2581,7 @@ TypedArrayConstruct(JSContext *cx, int atype, unsigned argc, Value *argv)
}
JS_FRIEND_API(JSObject *)
js_CreateTypedArray(JSContext *cx, int atype, jsuint nelements)
js_CreateTypedArray(JSContext *cx, int atype, uint32_t nelements)
{
JS_ASSERT(atype >= 0 && atype < TypedArray::TYPE_MAX);

View File

@ -252,7 +252,7 @@ struct JS_FRIEND_API(TypedArray) {
public:
static bool
isArrayIndex(JSContext *cx, JSObject *obj, jsid id, jsuint *ip = NULL);
isArrayIndex(JSContext *cx, JSObject *obj, jsid id, uint32_t *ip = NULL);
static inline uint32_t slotWidth(int atype) {
switch (atype) {
@ -335,7 +335,7 @@ JS_FRIEND_API(JSBool)
JS_IsArrayBufferObject(JSObject *obj);
JS_FRIEND_API(JSObject *)
JS_NewArrayBuffer(JSContext *cx, jsuint nbytes);
JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes);
JS_FRIEND_API(uint32_t)
JS_GetArrayBufferByteLength(JSObject *obj);

View File

@ -4665,7 +4665,7 @@ HasFunctionProperty(JSContext *cx, JSObject *obj, jsid funid, JSBool *found)
}
static bool
IdValIsIndex(JSContext *cx, jsval id, jsuint *indexp, bool *isIndex)
IdValIsIndex(JSContext *cx, jsval id, uint32_t *indexp, bool *isIndex)
{
if (JSVAL_IS_INT(id)) {
int32_t i = JSVAL_TO_INT(id);
@ -4673,7 +4673,7 @@ IdValIsIndex(JSContext *cx, jsval id, jsuint *indexp, bool *isIndex)
*isIndex = false;
return true;
}
*indexp = (jsuint)i;
*indexp = (uint32_t)i;
*isIndex = true;
return true;
}
@ -6198,7 +6198,7 @@ static JSBool
xml_namespace(JSContext *cx, unsigned argc, jsval *vp)
{
JSLinearString *prefix, *nsprefix;
jsuint i, length;
uint32_t i, length;
JSObject *ns;
NON_LIST_XML_METHOD_PROLOG;

View File

@ -1143,7 +1143,7 @@ ic::SplatApplyArgs(VMFrame &f)
/* Steps 4-5. */
JSObject *aobj = &vp[3].toObject();
jsuint length;
uint32_t length;
if (!js_GetLengthProperty(cx, aobj, &length))
THROWV(false);

View File

@ -234,13 +234,13 @@ stubs::SetElem(VMFrame &f)
do {
if (obj->isDenseArray() && JSID_IS_INT(id)) {
jsuint length = obj->getDenseArrayInitializedLength();
uint32_t length = obj->getDenseArrayInitializedLength();
int32_t i = JSID_TO_INT(id);
if ((jsuint)i < length) {
if ((uint32_t)i < length) {
if (obj->getDenseArrayElement(i).isMagic(JS_ARRAY_HOLE)) {
if (js_PrototypeHasIndexedProperties(cx, obj))
break;
if ((jsuint)i >= obj->getArrayLength())
if ((uint32_t)i >= obj->getArrayLength())
obj->setArrayLength(cx, i + 1);
}
obj->setDenseArrayElementWithType(cx, i, rval);
@ -1034,8 +1034,8 @@ stubs::InitElem(VMFrame &f, uint32_t last)
if (rref.isMagic(JS_ARRAY_HOLE)) {
JS_ASSERT(obj->isArray());
JS_ASSERT(JSID_IS_INT(id));
JS_ASSERT(jsuint(JSID_TO_INT(id)) < StackSpace::ARGS_LENGTH_MAX);
if (last && !js_SetLengthProperty(cx, obj, (jsuint) (JSID_TO_INT(id) + 1)))
JS_ASSERT(uint32_t(JSID_TO_INT(id)) < StackSpace::ARGS_LENGTH_MAX);
if (last && !js_SetLengthProperty(cx, obj, (uint32_t) (JSID_TO_INT(id) + 1)))
THROW();
} else {
if (!obj->defineGeneric(cx, id, rref, NULL, NULL, JSPROP_ENUMERATE))
@ -1584,7 +1584,7 @@ stubs::TableSwitch(VMFrame &f, jsbytecode *origPc)
pc += JUMP_OFFSET_LEN;
tableIdx -= low;
if ((jsuint) tableIdx < (jsuint)(high - low + 1)) {
if ((uint32_t) tableIdx < (uint32_t)(high - low + 1)) {
pc += JUMP_OFFSET_LEN * tableIdx;
if (uint32_t candidateOffset = GET_JUMP_OFFSET(pc))
jumpOffset = candidateOffset;

File diff suppressed because it is too large Load Diff

View File

@ -532,7 +532,7 @@ ReferenceFinder::addReferrer(jsval referrer, Path *path)
JS_ASSERT(JS_IsArrayObject(context, array));
/* Append our referrer to this array. */
jsuint length;
uint32_t length;
return JS_GetArrayLength(context, array, &length) &&
JS_SetElement(context, array, length, &referrer);
}

View File

@ -1,4 +1,5 @@
import re
from subprocess import list2cmdline
class TestOutput:
"""Output from a test run."""

View File

@ -376,7 +376,7 @@ js::StaticStrings::lookup(const jschar *chars, size_t length)
(chars[1] - '0') * 10 +
(chars[2] - '0');
if (jsuint(i) < INT_STATIC_LIMIT)
if (unsigned(i) < INT_STATIC_LIMIT)
return getInt(i);
}
return NULL;

View File

@ -533,7 +533,7 @@ StaticStrings::isStatic(JSAtom *atom)
(chars[1] - '0') * 10 +
(chars[2] - '0');
return (jsuint(i) < INT_STATIC_LIMIT);
return (unsigned(i) < INT_STATIC_LIMIT);
}
return false;
default:

View File

@ -152,7 +152,7 @@ interface ScheduledGCCallback : nsISupports
/**
* interface of Components.utils
*/
[scriptable, uuid(9e9ba9d6-a0fa-4767-9f49-9b74bb2368cd)]
[scriptable, uuid(9e43a260-5db2-11e1-b86c-0800200c9a66)]
interface nsIXPCComponents_Utils : nsISupports
{
@ -301,6 +301,9 @@ interface nsIXPCComponents_Utils : nsISupports
[implicit_jscontext]
jsval nondeterministicGetWeakMapKeys(in jsval aMap);
[implicit_jscontext]
jsval getJSTestingFunctions();
/*
* To be called from JS only.
*

View File

@ -1214,7 +1214,7 @@ mozJSComponentLoader::ImportInto(const nsACString & aLocation,
// Iterate over symbols array, installing symbols on targetObj:
jsuint symbolCount = 0;
uint32_t symbolCount = 0;
if (!JS_GetArrayLength(mContext, symbolsObj, &symbolCount)) {
return ReportOnCaller(cxhelper, ERROR_GETTING_ARRAY_LENGTH,
PromiseFlatCString(aLocation).get());
@ -1224,7 +1224,7 @@ mozJSComponentLoader::ImportInto(const nsACString & aLocation,
nsCAutoString logBuffer;
#endif
for (jsuint i = 0; i < symbolCount; ++i) {
for (uint32_t i = 0; i < symbolCount; ++i) {
jsval val;
jsid symbolId;

View File

@ -2799,8 +2799,8 @@ SandboxDump(JSContext *cx, unsigned argc, jsval *vp)
}
#endif
fputs(cstr, stderr);
fflush(stderr);
fputs(cstr, stdout);
fflush(stdout);
NS_Free(cstr);
JS_SET_RVAL(cx, vp, JSVAL_TRUE);
return true;
@ -3704,6 +3704,18 @@ nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(const jsval &aMap,
return NS_OK;
}
/* void getDebugObject(); */
NS_IMETHODIMP
nsXPCComponents_Utils::GetJSTestingFunctions(JSContext *cx,
JS::Value *retval)
{
JSObject *obj = js::GetTestingFunctions(cx);
if (!obj)
return NS_ERROR_XPC_JAVASCRIPT_ERROR;
*retval = OBJECT_TO_JSVAL(obj);
return NS_OK;
}
/* void getGlobalForObject(); */
NS_IMETHODIMP
nsXPCComponents_Utils::GetGlobalForObject(const JS::Value& object,

View File

@ -1684,7 +1684,7 @@ ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats, const nsACStri
callback, closure);
ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("runtime/gc-marker"),
nsIMemoryReporter::KIND_NONHEAP, rtStats.runtimeGCMarker,
nsIMemoryReporter::KIND_HEAP, rtStats.runtimeGCMarker,
"Memory used for the GC mark stack and gray roots.",
callback, closure);

View File

@ -190,7 +190,7 @@ private:
public:
static JSBool GetTypeForArray(XPCCallContext& ccx, JSObject* array,
jsuint length,
uint32_t length,
nsXPTType* resultType, nsID* resultID);
};
@ -215,7 +215,7 @@ XPCArrayHomogenizer::StateTable[tTypeCount][tTypeCount-1] = {
// static
JSBool
XPCArrayHomogenizer::GetTypeForArray(XPCCallContext& ccx, JSObject* array,
jsuint length,
uint32_t length,
nsXPTType* resultType, nsID* resultID)
{
Type state = tUnk;

View File

@ -53,6 +53,8 @@
#include "WrapperFactory.h"
#include "dombindings.h"
#include "nsContentUtils.h"
#include "mozilla/Util.h"
bool
@ -1479,6 +1481,43 @@ XPCWrappedNative::SystemIsBeingShutDown()
/***************************************************************************/
// If we have to transplant an object across compartments, we need to be
// careful if the underlying object implements nsWrapperCache and is preserving
// the wrapper.
//
// The class brackets a pair of Unpreserve/Preserve calls in the given scope.
//
// This class _must_ live on the stack, in part so that mPreservedWrapper is
// visible to the stack scanner. The caller wants the wrapper to be preserved,
// so we don't want it to get accidentally GCed.
class AutoWrapperChanger NS_STACK_CLASS {
public:
AutoWrapperChanger() : mCache(nsnull)
, mCOMObj(nsnull)
, mPreservedWrapper(nsnull)
{}
void init(nsISupports* aCOMObj, nsWrapperCache* aWrapperCache) {
mCOMObj = aCOMObj;
mCache = aWrapperCache;
if (mCache->PreservingWrapper()) {
mPreservedWrapper = mCache->GetWrapper();
MOZ_ASSERT(mPreservedWrapper);
nsContentUtils::ReleaseWrapper(mCOMObj, mCache);
}
}
~AutoWrapperChanger() {
if (mPreservedWrapper)
nsContentUtils::PreserveWrapper(mCOMObj, mCache);
}
private:
nsWrapperCache* mCache;
nsISupports* mCOMObj;
JSObject* mPreservedWrapper;
};
// static
nsresult
XPCWrappedNative::ReparentWrapperIfFound(XPCCallContext& ccx,
@ -1497,10 +1536,16 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCCallContext& ccx,
nsresult rv;
nsRefPtr<XPCWrappedNative> wrapper;
AutoWrapperChanger wrapperChanger;
JSObject *flat;
nsWrapperCache* cache = nsnull;
CallQueryInterface(aCOMObj, &cache);
if (cache) {
// There's a wrapper cache. Make sure we keep it sane no matter what
// happens.
wrapperChanger.init(aCOMObj, cache);
flat = cache->GetWrapper();
if (flat && !IS_SLIM_WRAPPER_OBJECT(flat)) {
wrapper = static_cast<XPCWrappedNative*>(xpc_GetJSPrivate(flat));

View File

@ -607,7 +607,7 @@ GetArrayIndexFromId(JSContext *cx, jsid id)
if (NS_LIKELY((unsigned)s >= 'a' && (unsigned)s <= 'z'))
return -1;
jsuint i;
uint32_t i;
JSLinearString *str = js::AtomToLinearString(JSID_TO_ATOM(id));
return js::StringIsArrayIndex(str, &i) ? i : -1;
}

View File

@ -699,6 +699,18 @@ xpc_GCThingIsGrayCCThing(void *thing)
xpc_IsGrayGCThing(thing);
}
struct UnmarkGrayTracer : public JSTracer
{
UnmarkGrayTracer() : mTracingShape(false), mPreviousShape(nsnull) {}
UnmarkGrayTracer(JSTracer *trc, bool aTracingShape)
: mTracingShape(aTracingShape), mPreviousShape(nsnull)
{
JS_TracerInit(this, trc->runtime, trc->callback);
}
bool mTracingShape; // true iff we are tracing the immediate children of a shape
void *mPreviousShape; // If mTracingShape, shape child or NULL. Otherwise, NULL.
};
/*
* The GC and CC are run independently. Consequently, the following sequence of
* events can occur:
@ -729,15 +741,38 @@ UnmarkGrayChildren(JSTracer *trc, void **thingp, JSGCTraceKind kind)
return;
}
// If this thing is not a CC-kind or already non-gray then we're done.
if (!AddToCCKind(kind) || !xpc_IsGrayGCThing(thing))
if (!xpc_IsGrayGCThing(thing))
return;
// Unmark.
static_cast<js::gc::Cell *>(thing)->unmark(js::gc::GRAY);
// Trace children.
JS_TraceChildren(trc, thing, kind);
/*
* Trace children of |thing|. If |thing| and its parent are both shapes, |thing| will
* get saved to mPreviousShape without being traced. The parent will later
* trace |thing|. This is done to avoid increasing the stack depth during shape
* tracing. It is safe to do because a shape can only have one child that is a shape.
*/
UnmarkGrayTracer *tracer = static_cast<UnmarkGrayTracer*>(trc);
UnmarkGrayTracer childTracer(tracer, kind == JSTRACE_SHAPE);
if (kind != JSTRACE_SHAPE) {
JS_TraceChildren(&childTracer, thing, kind);
MOZ_ASSERT(!childTracer.mPreviousShape);
return;
}
if (tracer->mTracingShape) {
MOZ_ASSERT(!tracer->mPreviousShape);
tracer->mPreviousShape = thing;
return;
}
do {
MOZ_ASSERT(!xpc_IsGrayGCThing(thing));
JS_TraceChildren(&childTracer, thing, JSTRACE_SHAPE);
thing = childTracer.mPreviousShape;
childTracer.mPreviousShape = nsnull;
} while (thing);
}
void
@ -749,7 +784,7 @@ xpc_UnmarkGrayObjectRecursive(JSObject *obj)
js::gc::AsCell(obj)->unmark(js::gc::GRAY);
// Trace children.
JSTracer trc;
UnmarkGrayTracer trc;
JS_TracerInit(&trc, JS_GetObjectRuntime(obj), UnmarkGrayChildren);
JS_TraceChildren(&trc, obj, JSTRACE_OBJECT);
}

View File

@ -258,4 +258,18 @@ FramePropertyTable::DeleteAll()
mEntries.EnumerateEntries(DeleteEnumerator, nsnull);
}
size_t
FramePropertyTable::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
{
return mEntries.SizeOfExcludingThis(SizeOfPropertyTableEntryExcludingThis,
aMallocSizeOf);
}
/* static */ size_t
FramePropertyTable::SizeOfPropertyTableEntryExcludingThis(Entry* aEntry,
nsMallocSizeOfFun aMallocSizeOf, void *)
{
return aEntry->mProp.SizeOfExcludingThis(aMallocSizeOf);
}
}

View File

@ -154,6 +154,8 @@ public:
*/
void DeleteAll();
size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
protected:
/**
* Stores a property descriptor/value pair. It can also be used to
@ -179,6 +181,20 @@ protected:
}
}
size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) {
size_t n = 0;
// We don't need to measure mProperty because it always points to static
// memory. As for mValue: if it's a single value we can't measure it,
// because the type is opaque; if it's an array, we measure the array
// storage, but we can't measure the individual values, again because
// their types are opaque.
if (IsArray()) {
nsTArray<PropertyValue>* array = ToArray();
n += array->SizeOfExcludingThis(aMallocSizeOf);
}
return n;
}
const FramePropertyDescriptor* mProperty;
void* mValue;
};
@ -217,6 +233,9 @@ protected:
static void DeleteAllForEntry(Entry* aEntry);
static PLDHashOperator DeleteEnumerator(Entry* aEntry, void* aArg);
static size_t SizeOfPropertyTableEntryExcludingThis(Entry* aEntry,
nsMallocSizeOfFun aMallocSizeOf, void *);
nsTHashtable<Entry> mEntries;
nsIFrame* mLastFrame;
Entry* mLastEntry;

View File

@ -1048,14 +1048,14 @@ nsLayoutUtils::GetEventCoordinatesRelativeTo(const nsEvent* aEvent,
nsIView* view = aFrame->GetView();
if (view) {
nsIWidget* fwidget = view->GetWidget();
if (fwidget && fwidget == GUIEvent->widget) {
nsIWidget* frameWidget = view->GetWidget();
if (frameWidget && frameWidget == GUIEvent->widget) {
// Special case this cause it happens a lot.
// This also fixes bug 664707, events in the extra-special case of select
// dropdown popups that are transformed.
nsPresContext* presContext = aFrame->PresContext();
nsPoint pt(presContext->DevPixelsToAppUnits(GUIEvent->refPoint.x),
presContext->DevPixelsToAppUnits(GUIEvent->refPoint.y));
nsPoint pt(presContext->DevPixelsToAppUnits(aPoint.x),
presContext->DevPixelsToAppUnits(aPoint.y));
return pt - view->ViewToWidgetOffset();
}
}

Some files were not shown because too many files have changed in this diff Show More