This commit is contained in:
Ms2ger 2012-04-09 09:32:28 +02:00
Родитель bb3bdcac69 1e5af79b2e
Коммит 9ae4350b73
187 изменённых файлов: 2890 добавлений и 5495 удалений

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

@ -507,7 +507,7 @@ function HistoryMenu(aPopupShowingEvent) {
"@mozilla.org/browser/sessionstore;1",
"nsISessionStore");
PlacesMenu.call(this, aPopupShowingEvent,
"place:redirectsMode=2&sort=4&maxResults=15");
"place:sort=4&maxResults=15");
}
HistoryMenu.prototype = {

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

@ -47,6 +47,8 @@
white-space: pre-wrap;
}
.expander[hidden],
.expander[hidden] + *,
.expander[collapsed] + * {
display: none;
}

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

@ -126,10 +126,8 @@
// Disallow overrides if this is a Strict-Transport-Security
// host and the cert is bad (STS Spec section 7.3) or if the
// certerror is in a frame (bug 633691).
if (getCSSClass() == "badStsCert" || window != top) {
var ec = document.getElementById('expertContent');
ec.parentNode.removeChild(ec);
}
if (getCSSClass() == "badStsCert" || window != top)
document.getElementById("expertContent").setAttribute("hidden", "true");
var tech = document.getElementById("technicalContentText");
if (tech)

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

@ -1352,7 +1352,7 @@ BrowserGlue.prototype = {
// be set to the version it has been added in, we will compare its value
// to users' smartBookmarksVersion and add new smart bookmarks without
// recreating old deleted ones.
const SMART_BOOKMARKS_VERSION = 3;
const SMART_BOOKMARKS_VERSION = 4;
const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion";
@ -1380,9 +1380,7 @@ BrowserGlue.prototype = {
let smartBookmarks = {
MostVisited: {
title: bundle.GetStringFromName("mostVisitedTitle"),
uri: NetUtil.newURI("place:redirectsMode=" +
Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET +
"&sort=" +
uri: NetUtil.newURI("place:sort=" +
Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
"&maxResults=" + MAX_RESULTS),
parent: PlacesUtils.toolbarFolderId,

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

@ -733,6 +733,8 @@ PlacesViewBase.prototype = {
.direction == "rtl";
},
get ownerWindow() window,
/**
* Adds an "Open All in Tabs" menuitem to the bottom of the popup.
* @param aPopup

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

@ -336,7 +336,7 @@ var PlacesOrganizer = {
// The command execution function will take care of seeing if the
// selection is a folder or a different container type, and will
// load its contents in tabs.
PlacesUIUtils.openContainerNodeInTabs(selectedNode, aEvent);
PlacesUIUtils.openContainerNodeInTabs(selectedNode, aEvent, currentView);
}
}
},
@ -363,7 +363,7 @@ var PlacesOrganizer = {
openSelectedNode: function PO_openSelectedNode(aEvent) {
PlacesUIUtils.openNodeWithEvent(this._content.selectedNode, aEvent,
this._content.treeBoxObject.view);
this._content);
},
/**

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

@ -86,7 +86,7 @@ var SidebarUtils = {
else if (!mouseInGutter && openInTabs &&
aEvent.originalTarget.localName == "treechildren") {
tbo.view.selection.select(row.value);
PlacesUIUtils.openContainerNodeInTabs(aTree.selectedNode, aEvent, tbo.view);
PlacesUIUtils.openContainerNodeInTabs(aTree.selectedNode, aEvent, aTree);
}
else if (!mouseInGutter && !isContainer &&
aEvent.originalTarget.localName == "treechildren") {
@ -94,7 +94,7 @@ var SidebarUtils = {
// do this *before* attempting to load the link since openURL uses
// selection as an indication of which link to load.
tbo.view.selection.select(row.value);
PlacesUIUtils.openNodeWithEvent(aTree.selectedNode, aEvent, tbo.view);
PlacesUIUtils.openNodeWithEvent(aTree.selectedNode, aEvent, aTree);
}
},

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

@ -699,6 +699,10 @@
this._contextMenuShown = false;
<body/>
</method>
<property name="ownerWindow"
readonly="true"
onget="return window;"/>
</implementation>
<handlers>
<handler event="focus"><![CDATA[

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

@ -377,12 +377,6 @@ var PlacesUIUtils = {
*/
showBookmarkDialog:
function PUIU_showBookmarkDialog(aInfo, aParentWindow, aResizable) {
// This is a compatibility shim for add-ons. It will warn in the Error
// Console when used.
if (!aParentWindow) {
aParentWindow = this._getWindow(null);
}
// Preserve size attributes differently based on the fact the dialog has
// a folder picker or not. If the picker is visible, the dialog should
// be resizable since it may not show enough content for the folders
@ -621,44 +615,9 @@ var PlacesUIUtils = {
browserWindow.gBrowser.loadTabs(urls, loadInBackground, false);
},
/**
* Helper method for methods which are forced to take a view/window
* parameter as an optional parameter. It will be removed post Fx4.
*/
_getWindow: function PUIU__getWindow(aView) {
if (aView) {
// Pratically, this is the case for places trees.
if (aView instanceof Components.interfaces.nsIDOMNode)
return aView.ownerDocument.defaultView;
return Cu.getGlobalForObject(aView);
}
let caller = arguments.callee.caller;
// If a view wasn't expected, the method should have got a window.
if (aView === null) {
Components.utils.reportError("The api has changed. A window should be " +
"passed to " + caller.name + ". Not " +
"passing a window will throw in a future " +
"release.");
}
else {
Components.utils.reportError("The api has changed. A places view " +
"should be passed to " + caller.name + ". " +
"Not passing a view will throw in a future " +
"release.");
}
// This could certainly break in some edge cases (like bug 562998), but
// that's the best we should do for those extreme backwards-compatibility cases.
let topBrowserWin = this._getTopBrowserWin();
return topBrowserWin ? topBrowserWin : focusManager.focusedWindow;
},
openContainerNodeInTabs:
function PUIU_openContainerInTabs(aNode, aEvent, aView) {
let window = this._getWindow(aView);
let window = aView.ownerWindow;
let urlsToOpen = PlacesUtils.getURLsForContainerNode(aNode);
if (!this._confirmOpenInTabs(urlsToOpen.length, window))
@ -668,7 +627,7 @@ var PlacesUIUtils = {
},
openURINodesInTabs: function PUIU_openURINodesInTabs(aNodes, aEvent, aView) {
let window = this._getWindow(aView);
let window = aView.ownerWindow;
let urlsToOpen = [];
for (var i=0; i < aNodes.length; i++) {
@ -693,7 +652,7 @@ var PlacesUIUtils = {
*/
openNodeWithEvent:
function PUIU_openNodeWithEvent(aNode, aEvent, aView) {
let window = this._getWindow(aView);
let window = aView.ownerWindow;
this._openNodeIn(aNode, window.whereToOpenLink(aEvent), window);
},
@ -703,7 +662,7 @@ var PlacesUIUtils = {
* see also openUILinkIn
*/
openNodeIn: function PUIU_openNodeIn(aNode, aWhere, aView) {
let window = this._getWindow(aView);
let window = aView.ownerWindow;
this._openNodeIn(aNode, aWhere, window);
},

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

@ -102,7 +102,7 @@ let (backup_date = new Date().toLocaleFormat("%Y-%m-%d")) {
}
// Smart bookmarks constants.
const SMART_BOOKMARKS_VERSION = 3;
const SMART_BOOKMARKS_VERSION = 4;
const SMART_BOOKMARKS_ON_TOOLBAR = 1;
const SMART_BOOKMARKS_ON_MENU = 3; // Takes in count the additional separator.

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

@ -11,6 +11,11 @@ ac_add_options --enable-js-diagnostics
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# This will overwrite the default of stripping everything and keep the symbol table.
# This is useful for profiling and debugging and only increases the package size
# by 2 MBs.
STRIP_FLAGS="--strip-debug"
# PGO
mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'

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

@ -11,6 +11,11 @@ ac_add_options --enable-js-diagnostics
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# This will overwrite the default of stripping everything and keep the symbol table.
# This is useful for profiling and debugging and only increases the package size
# by 2 MBs.
STRIP_FLAGS="--strip-debug"
# PGO
mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'

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

@ -432,9 +432,6 @@ let PlacesProvider = {
// Sort by frecency, descending.
options.sortingMode = Ci.nsINavHistoryQueryOptions.SORT_BY_FRECENCY_DESCENDING
// We don't want source redirects for this query.
options.redirectsMode = Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET;
let links = [];
let callback = {

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

@ -477,8 +477,6 @@ var WinTaskbarJumpList =
var options = PlacesUtils.history.getNewQueryOptions();
options.maxResults = aLimit;
options.sortingMode = aSortingMode;
// We don't want source redirects for these queries.
options.redirectsMode = Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET;
var query = PlacesUtils.history.getNewQuery();
// Return the pending statement to the caller, to allow cancelation.

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

@ -294,13 +294,15 @@ $(CONFIGURES): %: %.in $(EXTRA_CONFIG_DEPS)
cd $(@D); $(AUTOCONF)
CONFIG_STATUS_DEPS := \
$(wildcard $(CONFIGURES)) \
$(TOPSRCDIR)/allmakefiles.sh \
$(wildcard $(TOPSRCDIR)/nsprpub/configure) \
$(wildcard $(TOPSRCDIR)/config/milestone.txt) \
$(wildcard $(TOPSRCDIR)/js/src/config/milestone.txt) \
$(wildcard $(TOPSRCDIR)/browser/config/version.txt) \
$(wildcard $(addsuffix confvars.sh,$(wildcard $(TOPSRCDIR)/*/))) \
$(wildcard \
$(CONFIGURES) \
$(TOPSRCDIR)/allmakefiles.sh \
$(TOPSRCDIR)/nsprpub/configure \
$(TOPSRCDIR)/config/milestone.txt \
$(TOPSRCDIR)/js/src/config/milestone.txt \
$(TOPSRCDIR)/browser/config/version.txt \
$(TOPSRCDIR)/*/confvars.sh \
) \
$(NULL)
CONFIGURE_ENV_ARGS += \

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

@ -231,6 +231,7 @@ LIBXUL_LIBS=@LIBXUL_LIBS@
ENABLE_STRIP = @ENABLE_STRIP@
PKG_SKIP_STRIP = @PKG_SKIP_STRIP@
STRIP_FLAGS = @STRIP_FLAGS@
MOZ_POST_DSO_LIB_COMMAND = @MOZ_POST_DSO_LIB_COMMAND@
MOZ_POST_PROGRAM_COMMAND = @MOZ_POST_PROGRAM_COMMAND@

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

@ -837,3 +837,8 @@ EXPAND_LIBNAME = $(foreach lib,$(1),$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
endif
EXPAND_LIBNAME_PATH = $(foreach lib,$(1),$(2)/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
EXPAND_MOZLIBNAME = $(foreach lib,$(1),$(DIST)/lib/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
# Include internal ply only if needed
ifndef MOZ_SYSTEM_PLY
PLY_INCLUDE = -I$(topsrcdir)/other-licenses/ply
endif

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

@ -1444,7 +1444,7 @@ xpidl-preqs = \
$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
$(REPORT_BUILD)
$(PYTHON_PATH) \
-I$(topsrcdir)/other-licenses/ply \
$(PLY_INCLUDE) \
-I$(topsrcdir)/xpcom/idl-parser \
$(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
@if test -n "$(findstring $*.h, $(EXPORTS))"; \
@ -1456,7 +1456,7 @@ ifndef NO_GEN_XPT
$(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
$(REPORT_BUILD)
$(PYTHON_PATH) \
-I$(topsrcdir)/other-licenses/ply \
$(PLY_INCLUDE) \
-I$(topsrcdir)/xpcom/idl-parser \
-I$(topsrcdir)/xpcom/typelib/xpt/tools \
$(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -8403,6 +8403,7 @@ AC_SUBST(MOZ_ANDROID_HISTORY)
AC_SUBST(MOZ_WEBSMS_BACKEND)
AC_SUBST(ENABLE_STRIP)
AC_SUBST(PKG_SKIP_STRIP)
AC_SUBST(STRIP_FLAGS)
AC_SUBST(USE_ELF_DYNSTR_GC)
AC_SUBST(USE_ELF_HACK)
AC_SUBST(INCREMENTAL_LINKER)

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

@ -135,6 +135,7 @@
#include "nsIRequest.h"
#include "nsHtml5TreeOpExecutor.h"
#include "nsHtml5Parser.h"
#include "nsIDOMJSWindow.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -1326,9 +1327,10 @@ nsHTMLDocument::Open(const nsAString& aContentTypeOrUrl,
if (!window) {
return NS_OK;
}
nsCOMPtr<nsIDOMJSWindow> win = do_QueryInterface(window);
nsCOMPtr<nsIDOMWindow> newWindow;
nsresult rv = window->Open(aContentTypeOrUrl, aReplaceOrName, aFeatures,
getter_AddRefs(newWindow));
nsresult rv = win->OpenJS(aContentTypeOrUrl, aReplaceOrName, aFeatures,
getter_AddRefs(newWindow));
*aReturn = newWindow.forget().get();
return rv;
}

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

@ -107,6 +107,7 @@ _TEST_FILES = test_bug1682.html \
test_bug677495.html \
test_bug677495-1.html \
test_bug742261.html \
test_bug741266.html \
$(NULL)
ifneq (mobile,$(MOZ_BUILD_APP))

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=741266
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 741266</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=741266">Mozilla Bug 741266</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 741266 **/
var w = window.open("", "", "width=100,height=100");
is(w.innerHeight, 100, "Popup height should be 100 when opened with window.open");
// XXXbz On at least some platforms, the innerWidth is off by the scrollbar
// width for some reason. So just make sure it's the same for both popups.
var width = w.innerWidth;
w.close();
w = document.open("", "", "width=100,height=100");
is(w.innerHeight, 100, "Popup height should be 100 when opened with document.open");
is(w.innerWidth, width, "Popup width should be the same when opened with document.open");
w.close();
</script>
</pre>
</body>
</html>

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

@ -400,7 +400,7 @@ nsXBLStreamListener::HandleEvent(nsIDOMEvent* aEvent)
if (!bindingDocument->GetRootElement()) {
// FIXME: How about an error console warning?
NS_WARNING("*** XBL doc with no root element! Something went horribly wrong! ***");
NS_WARNING("XBL doc with no root element - this usually shouldn't happen");
return NS_ERROR_FAILURE;
}

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

@ -1,6 +1,6 @@
# 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/.
# 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/.
DEPTH = ../..
topsrcdir = @top_srcdir@
@ -75,18 +75,20 @@ bindinggen_dependencies := \
$(binding_header_files): %Binding.h: $(bindinggen_dependencies) \
$(webidl_base)/%.webidl \
$(NULL)
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/other-licenses/ply -I$(srcdir)/parser \
$(srcdir)/BindingGen.py $(ACCESSOR_OPT) header $(srcdir)/Bindings.conf $*Binding \
$(webidl_base)/$*.webidl
$(PYTHON_PATH) \
$(PLY_INCLUDE) -I$(srcdir)/parser \
$(srcdir)/BindingGen.py $(ACCESSOR_OPT) header \
$(srcdir)/Bindings.conf $*Binding \
$(webidl_base)/$*.webidl
$(binding_cpp_files): %Binding.cpp: $(bindinggen_dependencies) \
$(webidl_base)/%.webidl \
$(NULL)
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/other-licenses/ply -I$(srcdir)/parser \
$(srcdir)/BindingGen.py $(ACCESSOR_OPT) cpp $(srcdir)/Bindings.conf $*Binding \
$(webidl_base)/$*.webidl
$(PYTHON_PATH) \
$(PLY_INCLUDE) -I$(srcdir)/parser \
$(srcdir)/BindingGen.py $(ACCESSOR_OPT) cpp \
$(srcdir)/Bindings.conf $*Binding \
$(webidl_base)/$*.webidl
$(globalgen_targets): ParserResults.pkl
@ -108,7 +110,7 @@ $(CACHE_DIR)/.done:
ParserResults.pkl: $(globalgen_dependencies) \
$(addprefix $(webidl_base)/, $(webidl_files))
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/other-licenses/ply -I$(srcdir)/parser \
$(PLY_INCLUDE) -I$(srcdir)/parser \
$(srcdir)/GlobalGen.py $(ACCESSOR_OPT) $(srcdir)/Bindings.conf $(webidl_base) \
--cachedir=$(CACHE_DIR) \
$(webidl_files)

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

@ -593,6 +593,24 @@ const PDU_MAX_USER_DATA_8BIT = 140;
// User Data max length in chars
const PDU_MAX_USER_DATA_UCS2 = 70;
// PID - Protocol Indicator
const PDU_PID_DEFAULT = 0x00;
const PDU_PID_TELEMATIC_INTERWORKING = 0x20;
const PDU_PID_SHORT_MESSAGE_TYPE_0 = 0x40;
const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_1 = 0x41;
const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_2 = 0x42;
const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_3 = 0x43;
const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_4 = 0x44;
const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_5 = 0x45;
const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_6 = 0x46;
const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_7 = 0x47;
const PDU_PID_ENHANDED_MESSAGE_SERVICE = 0x5E;
const PDU_PID_RETURN_CALL_MESSAGE = 0x5F
const PDU_PID_ANSI_136_R_DATA = 0x7C;
const PDU_PID_ME_DATA_DOWNLOAD = 0x7D;
const PDU_PID_ME_DEPERSONALIZATION = 0x7E;
const PDU_PID_USIM_DATA_DOWNLOAD = 0x7F;
// DCS - Data Coding Scheme
const PDU_DCS_MSG_CODING_7BITS_ALPHABET = 0x00;
const PDU_DCS_MSG_CODING_8BITS_ALPHABET = 0x04;

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

@ -1518,6 +1518,13 @@ let RIL = {
return PDU_FCS_UNSPECIFIED;
}
if (message.epid == PDU_PID_SHORT_MESSAGE_TYPE_0) {
// `A short message type 0 indicates that the ME must acknowledge receipt
// of the short message but shall discard its contents.` ~ 3GPP TS 23.040
// 9.2.3.9
return PDU_FCS_OK;
}
if (message.header && (message.header.segmentMaxSeq > 1)) {
message = this._processReceivedSmsSegment(message);
} else {
@ -2233,7 +2240,7 @@ RIL[REQUEST_DEVICE_IDENTITY] = null;
RIL[REQUEST_EXIT_EMERGENCY_CALLBACK_MODE] = null;
RIL[REQUEST_GET_SMSC_ADDRESS] = function REQUEST_GET_SMSC_ADDRESS(length, options) {
if (options.rilRequestError) {
if (options.body) {
if (options.type == "sendSMS") {
this.sendDOMMessage({
type: "sms-send-failed",
envelopeId: options.envelopeId,
@ -2928,6 +2935,32 @@ let GsmPDUHelper = {
return addr;
},
/**
* Read TP-Protocol-Indicator(TP-PID).
*
* @param msg
* message object for output.
*
* @see 3GPP TS 23.040 9.2.3.9
*/
readProtocolIndicator: function readProtocolIndicator(msg) {
// `The MS shall interpret reserved, obsolete, or unsupported values as the
// value 00000000 but shall store them exactly as received.`
msg.pid = this.readHexOctet();
msg.epid = msg.pid;
switch (msg.epid & 0xC0) {
case 0x40:
// Bit 7..0 = 01xxxxxx
switch (msg.epid) {
case PDU_PID_SHORT_MESSAGE_TYPE_0:
return;
}
break;
}
msg.epid = PDU_PID_DEFAULT;
},
/**
* Read GSM TP-Service-Centre-Time-Stamp(TP-SCTS).
*
@ -2943,14 +2976,14 @@ let GsmPDUHelper = {
let timestamp = Date.UTC(year, month, day, hour, minute, second);
// If the most significant bit of the least significant nibble is 1,
// the timezone offset is negative (fourth bit from the right => 0x08).
// the timezone offset is negative (fourth bit from the right => 0x08):
// localtime = UTC + tzOffset
// therefore
// UTC = localtime - tzOffset
let tzOctet = this.readHexOctet();
let tzOffset = this.octetToBCD(tzOctet & ~0x08) * 15 * 60 * 1000;
if (tzOctet & 0x08) {
timestamp -= tzOffset;
} else {
timestamp += tzOffset;
}
tzOffset = (tzOctet & 0x08) ? -tzOffset : tzOffset;
timestamp -= tzOffset;
return timestamp;
},
@ -3074,7 +3107,7 @@ let GsmPDUHelper = {
// TP-Protocol-Identifier
if (pi & PDU_PI_PROTOCOL_IDENTIFIER) {
msg.pid = this.readHexOctet();
this.readProtocolIndicator(msg);
}
// TP-Data-Coding-Scheme
if (pi & PDU_PI_DATA_CODING_SCHEME) {
@ -3106,6 +3139,7 @@ let GsmPDUHelper = {
sender: null, // M X X X X X
recipient: null, // X X M X M M
pid: null, // M O M O O M
epid: null, // M O M O O M
dcs: null, // M O M O O X
body: null, // M O M O O O
timestamp: null, // M X X X X X
@ -3157,7 +3191,7 @@ let GsmPDUHelper = {
let senderAddressLength = this.readHexOctet();
msg.sender = this.readAddress(senderAddressLength);
// - TP-Protocolo-Identifier -
msg.pid = this.readHexOctet();
this.readProtocolIndicator(msg);
// - TP-Data-Coding-Scheme -
msg.dcs = this.readHexOctet();
// - TP-Service-Center-Time-Stamp -

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

@ -2802,8 +2802,7 @@ WorkerPrivate::OperationCallback(JSContext* aCx)
}
// Clean up before suspending.
JS_FlushCaches(aCx);
JS_GC(aCx);
JS_GC(JS_GetRuntime(aCx));
while ((mayContinue = MayContinueRunning())) {
MutexAutoLock lock(mMutex);
@ -3891,12 +3890,13 @@ WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking,
{
AssertIsOnWorkerThread();
js::PrepareForFullGC(JS_GetRuntime(aCx));
JSRuntime *rt = JS_GetRuntime(aCx);
js::PrepareForFullGC(rt);
if (aShrinking) {
js::ShrinkingGC(aCx, js::gcreason::DOM_WORKER);
js::ShrinkingGC(rt, js::gcreason::DOM_WORKER);
}
else {
js::GCForReason(aCx, js::gcreason::DOM_WORKER);
js::GCForReason(rt, js::gcreason::DOM_WORKER);
}
if (aCollectChildren) {

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

@ -1846,7 +1846,7 @@ public class GeckoAppShell
}
// This is only used in Native Fennec.
public static void setPreventPanning(final boolean aPreventPanning) { }
public static void notifyDefaultPrevented(boolean defaultPrevented) { }
public static short getScreenOrientation() {
return GeckoScreenOrientationListener.getInstance().getScreenOrientation();

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

@ -107,6 +107,7 @@ static const char *sExtensionNames[] = {
"GL_OES_rgb8_rgba8",
"GL_ARB_robustness",
"GL_EXT_robustness",
"GL_ARB_sync",
NULL
};
@ -450,6 +451,32 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
mSymbols.fRenderbufferStorageMultisample = nsnull;
}
}
if (IsExtensionSupported(ARB_sync)) {
SymLoadStruct syncSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fFenceSync, { "FenceSync", nsnull } },
{ (PRFuncPtr*) &mSymbols.fIsSync, { "IsSync", nsnull } },
{ (PRFuncPtr*) &mSymbols.fDeleteSync, { "DeleteSync", nsnull } },
{ (PRFuncPtr*) &mSymbols.fClientWaitSync, { "ClientWaitSync", nsnull } },
{ (PRFuncPtr*) &mSymbols.fWaitSync, { "WaitSync", nsnull } },
{ (PRFuncPtr*) &mSymbols.fGetInteger64v, { "GetInteger64v", nsnull } },
{ (PRFuncPtr*) &mSymbols.fGetSynciv, { "GetSynciv", nsnull } },
{ nsnull, { nsnull } },
};
if (!LoadSymbols(&syncSymbols[0], trygl, prefix)) {
NS_ERROR("GL supports ARB_sync without supplying its functions.");
MarkExtensionUnsupported(ARB_sync);
mSymbols.fFenceSync = nsnull;
mSymbols.fIsSync = nsnull;
mSymbols.fDeleteSync = nsnull;
mSymbols.fClientWaitSync = nsnull;
mSymbols.fWaitSync = nsnull;
mSymbols.fGetInteger64v = nsnull;
mSymbols.fGetSynciv = nsnull;
}
}
// Load developer symbols, don't fail if we can't find them.
SymLoadStruct auxSymbols[] = {

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

@ -1500,6 +1500,7 @@ public:
OES_rgb8_rgba8,
ARB_robustness,
EXT_robustness,
ARB_sync,
Extensions_Max
};
@ -2898,6 +2899,51 @@ public:
return ret;
}
GLsync GLAPIENTRY fFenceSync(GLenum condition, GLbitfield flags) {
BEFORE_GL_CALL;
GLsync ret = mSymbols.fFenceSync(condition, flags);
AFTER_GL_CALL;
return ret;
}
realGLboolean GLAPIENTRY fIsSync(GLsync sync) {
BEFORE_GL_CALL;
realGLboolean ret = mSymbols.fIsSync(sync);
AFTER_GL_CALL;
return ret;
}
void GLAPIENTRY fDeleteSync(GLsync sync) {
BEFORE_GL_CALL;
mSymbols.fDeleteSync(sync);
AFTER_GL_CALL;
}
GLenum GLAPIENTRY fClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
BEFORE_GL_CALL;
GLenum ret = mSymbols.fClientWaitSync(sync, flags, timeout);
AFTER_GL_CALL;
return ret;
}
void GLAPIENTRY fWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
BEFORE_GL_CALL;
mSymbols.fWaitSync(sync, flags, timeout);
AFTER_GL_CALL;
}
void GLAPIENTRY fGetInteger64v(GLenum pname, GLint64 *params) {
BEFORE_GL_CALL;
mSymbols.fGetInteger64v(pname, params);
AFTER_GL_CALL;
}
void GLAPIENTRY fGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
BEFORE_GL_CALL;
mSymbols.fGetSynciv(sync, pname, bufSize, length, values);
AFTER_GL_CALL;
}
#ifdef DEBUG
void THEBES_API CreatedProgram(GLContext *aOrigin, GLuint aName);
void THEBES_API CreatedShader(GLContext *aOrigin, GLuint aName);

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

@ -40,6 +40,8 @@
#ifndef GLCONTEXTSYMBOLS_H_
#define GLCONTEXTSYMBOLS_H_
#include "GLDefs.h"
/*
* This file should only be included by GLContext.h, and should be
* autogenerated in the future.
@ -381,6 +383,24 @@ struct GLContextSymbols
typedef GLenum (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUS) (void);
PFNGLGETGRAPHICSRESETSTATUS fGetGraphicsResetStatus;
/*
* ARB_sync extension
*/
typedef GLsync (GLAPIENTRY * PFNGLFENCESYNC) (GLenum condition, GLbitfield flags);
PFNGLFENCESYNC fFenceSync;
typedef realGLboolean (GLAPIENTRY * PFNGLISSYNC) (GLsync sync);
PFNGLISSYNC fIsSync;
typedef void (GLAPIENTRY * PFNGLDELETESYNC) (GLsync sync);
PFNGLDELETESYNC fDeleteSync;
typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
PFNGLCLIENTWAITSYNC fClientWaitSync;
typedef void (GLAPIENTRY * PFNGLWAITSYNC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
PFNGLWAITSYNC fWaitSync;
typedef void (GLAPIENTRY * PFNGLGETINTEGER64V) (GLenum pname, GLint64 *params);
PFNGLGETINTEGER64V fGetInteger64v;
typedef void (GLAPIENTRY * PFNGLGETSYNCIV) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
PFNGLGETSYNCIV fGetSynciv;
};
}

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

@ -37,7 +37,6 @@
* ***** END LICENSE BLOCK ***** */
#if !defined(LOCALGL_H_)
#define LOCALGL_H_
#if !defined(__gltypes_h_) && !defined(__gl_h_)
@ -72,6 +71,14 @@ typedef ptrdiff_t GLintptr;
#endif /* #if !defined(__gltypes_h_) && !defined(__gl_h_) */
#include "mozilla/StandardInteger.h"
// ARB_sync
typedef struct __GLsync *GLsync;
typedef int64_t GLint64;
typedef uint64_t GLuint64;
#ifndef GLAPIENTRY
# ifdef WIN32
# define GLAPIENTRY APIENTRY
@ -3032,6 +3039,23 @@ typedef ptrdiff_t GLintptr;
#define LOCAL_GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC
#define LOCAL_GL_WIN_swap_hint 1
// ARB_sync
#define LOCAL_GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
#define LOCAL_GL_OBJECT_TYPE 0x9112
#define LOCAL_GL_SYNC_CONDITION 0x9113
#define LOCAL_GL_SYNC_STATUS 0x9114
#define LOCAL_GL_SYNC_FLAGS 0x9115
#define LOCAL_GL_SYNC_FENCE 0x9116
#define LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
#define LOCAL_GL_UNSIGNALED 0x9118
#define LOCAL_GL_SIGNALED 0x9119
#define LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
#define LOCAL_GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
#define LOCAL_GL_ALREADY_SIGNALED 0x911A
#define LOCAL_GL_TIMEOUT_EXPIRED 0x911B
#define LOCAL_GL_CONDITION_SATISFIED 0x911C
#define LOCAL_GL_WAIT_FAILED 0x911D
#define LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
#define LOCAL_GL_MAX_VARYING_VECTORS 0x8DFC
#define LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD

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

@ -375,84 +375,78 @@ gfxDWriteFontEntry::ReadCMAP()
nsresult rv;
// attempt this once, if errors occur leave a blank cmap
if (mCmapInitialized)
if (mCharacterMap) {
return NS_OK;
mCmapInitialized = true;
}
nsRefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
// if loading via GDI, just use GetFontTable
if (mFont && gfxDWriteFontList::PlatformFontList()->UseGDIFontTableAccess()) {
const PRUint32 kCmapTag = TRUETYPE_TAG('c','m','a','p');
AutoFallibleTArray<PRUint8,16384> buffer;
PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p');
nsresult rv;
if (GetFontTable(kCmapTag, buffer) != NS_OK)
return NS_ERROR_FAILURE;
PRUint8 *cmap = buffer.Elements();
AutoFallibleTArray<PRUint8,16384> cmap;
rv = GetFontTable(kCMAP, cmap);
bool unicodeFont = false, symbolFont = false;
rv = gfxFontUtils::ReadCMAP(cmap, buffer.Length(),
mCharacterMap, mUVSOffset,
unicodeFont, symbolFont);
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
NS_ConvertUTF16toUTF8(mName).get(),
mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
NS_ConvertUTF16toUTF8(mName).get());
mCharacterMap.Dump(prefix, eGfxLog_cmapdata);
bool unicodeFont = false, symbolFont = false; // currently ignored
if (NS_SUCCEEDED(rv)) {
rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
*charmap, mUVSOffset,
unicodeFont, symbolFont);
}
} else {
// loading using dwrite, don't use GetFontTable to avoid copy
nsRefPtr<IDWriteFontFace> fontFace;
rv = CreateFontFace(getter_AddRefs(fontFace));
if (NS_SUCCEEDED(rv)) {
const PRUint32 kCmapTag = DWRITE_MAKE_OPENTYPE_TAG('c', 'm', 'a', 'p');
PRUint8 *tableData;
PRUint32 len;
void *tableContext = NULL;
BOOL exists;
hr = fontFace->TryGetFontTable(kCmapTag, (const void**)&tableData,
&len, &tableContext, &exists);
if (SUCCEEDED(hr)) {
bool isSymbol = fontFace->IsSymbolFont();
bool isUnicode = true;
if (exists) {
rv = gfxFontUtils::ReadCMAP(tableData, len, *charmap,
mUVSOffset, isUnicode,
isSymbol);
}
fontFace->ReleaseFontTable(tableContext);
} else {
rv = NS_ERROR_FAILURE;
}
}
#endif
mHasCmapTable = NS_SUCCEEDED(rv);
return rv;
}
// loading using dwrite, don't use GetFontTable to avoid copy
nsRefPtr<IDWriteFontFace> fontFace;
rv = CreateFontFace(getter_AddRefs(fontFace));
if (NS_FAILED(rv)) {
return rv;
mHasCmapTable = NS_SUCCEEDED(rv);
if (mHasCmapTable) {
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
mCharacterMap = pfl->FindCharMap(charmap);
} else {
// if error occurred, initialize to null cmap
mCharacterMap = new gfxCharacterMap();
}
PRUint8 *tableData;
PRUint32 len;
void *tableContext = NULL;
BOOL exists;
hr = fontFace->TryGetFontTable(DWRITE_MAKE_OPENTYPE_TAG('c', 'm', 'a', 'p'),
(const void**)&tableData,
&len,
&tableContext,
&exists);
if (FAILED(hr)) {
return NS_ERROR_FAILURE;
}
bool isSymbol = fontFace->IsSymbolFont();
bool isUnicode = true;
if (exists) {
rv = gfxFontUtils::ReadCMAP(tableData,
len,
mCharacterMap,
mUVSOffset,
isUnicode,
isSymbol);
}
fontFace->ReleaseFontTable(tableContext);
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d hash: %8.8x%s\n",
NS_ConvertUTF16toUTF8(mName).get(),
mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
charmap->SizeOfIncludingThis(moz_malloc_size_of),
charmap->mHash, mCharacterMap == charmap ? " new" : ""));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
NS_ConvertUTF16toUTF8(mName).get());
mCharacterMap.Dump(prefix, eGfxLog_cmapdata);
charmap->Dump(prefix, eGfxLog_cmapdata);
}
#endif
mHasCmapTable = NS_SUCCEEDED(rv);
return rv;
}

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

@ -343,12 +343,11 @@ FT2FontEntry::CairoFontFace()
nsresult
FT2FontEntry::ReadCMAP()
{
if (mCmapInitialized) {
if (mCharacterMap) {
return NS_OK;
}
// attempt this once, if errors occur leave a blank cmap
mCmapInitialized = true;
nsRefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
AutoFallibleTArray<PRUint8,16384> buffer;
nsresult rv = GetFontTable(TTAG_cmap, buffer);
@ -357,11 +356,18 @@ FT2FontEntry::ReadCMAP()
bool unicodeFont;
bool symbolFont;
rv = gfxFontUtils::ReadCMAP(buffer.Elements(), buffer.Length(),
mCharacterMap, mUVSOffset,
*charmap, mUVSOffset,
unicodeFont, symbolFont);
}
mHasCmapTable = NS_SUCCEEDED(rv);
if (mHasCmapTable) {
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
mCharacterMap = pfl->FindCharMap(charmap);
} else {
// if error occurred, initialize to null cmap
mCharacterMap = new gfxCharacterMap();
}
return rv;
}

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

@ -103,6 +103,16 @@ static PRUint32 gGlyphExtentsSetupLazyTight = 0;
static PRUint32 gGlyphExtentsSetupFallBackToTight = 0;
#endif
void
gfxCharacterMap::NotifyReleased()
{
gfxPlatformFontList *fontlist = gfxPlatformFontList::PlatformFontList();
if (mShared) {
fontlist->RemoveCmap(this);
}
delete this;
}
gfxFontEntry::~gfxFontEntry()
{
delete mUserFontData;
@ -115,18 +125,20 @@ bool gfxFontEntry::IsSymbolFont()
bool gfxFontEntry::TestCharacterMap(PRUint32 aCh)
{
if (!mCmapInitialized) {
if (!mCharacterMap) {
ReadCMAP();
NS_ASSERTION(mCharacterMap, "failed to initialize character map");
}
return mCharacterMap.test(aCh);
return mCharacterMap->test(aCh);
}
nsresult gfxFontEntry::InitializeUVSMap()
{
// mUVSOffset will not be initialized
// until cmap is initialized.
if (!mCmapInitialized) {
if (!mCharacterMap) {
ReadCMAP();
NS_ASSERTION(mCharacterMap, "failed to initialize character map");
}
if (!mUVSOffset) {
@ -170,7 +182,8 @@ PRUint16 gfxFontEntry::GetUVSGlyph(PRUint32 aCh, PRUint32 aVS)
nsresult gfxFontEntry::ReadCMAP()
{
mCmapInitialized = true;
NS_ASSERTION(false, "using default no-op implementation of ReadCMAP");
mCharacterMap = new gfxCharacterMap();
return NS_OK;
}
@ -433,7 +446,12 @@ gfxFontEntry::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
aSizes->mCharMapsSize += mCharacterMap.SizeOfExcludingThis(aMallocSizeOf);
// cmaps are shared so only non-shared cmaps are included here
if (mCharacterMap && mCharacterMap->mBuildOnTheFly) {
aSizes->mCharMapsSize +=
mCharacterMap->SizeOfIncludingThis(aMallocSizeOf);
}
aSizes->mFontTableCacheSize +=
mFontTableCache.SizeOfExcludingThis(
FontTableHashEntry::SizeOfEntryExcludingThis,
@ -770,7 +788,7 @@ CalcStyleMatch(gfxFontEntry *aFontEntry, const gfxFontStyle *aStyle)
void
gfxFontFamily::FindFontForChar(GlobalFontMatch *aMatchData)
{
if (mCharacterMapInitialized && !TestCharacterMap(aMatchData->mCh)) {
if (mFamilyCharacterMapInitialized && !TestCharacterMap(aMatchData->mCh)) {
// none of the faces in the family support the required char,
// so bail out immediately
return;
@ -1028,7 +1046,8 @@ gfxFontFamily::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
{
aSizes->mFontListSize +=
mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
aSizes->mCharMapsSize += mCharacterMap.SizeOfExcludingThis(aMallocSizeOf);
aSizes->mCharMapsSize +=
mFamilyCharacterMap.SizeOfExcludingThis(aMallocSizeOf);
aSizes->mFontListSize +=
mAvailableFonts.SizeOfExcludingThis(aMallocSizeOf);
@ -3647,7 +3666,9 @@ gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
// check other faces of the family
gfxFontFamily *family = font->GetFontEntry()->Family();
if (family && family->TestCharacterMap(aCh)) {
if (family && !font->GetFontEntry()->mIsProxy &&
family->TestCharacterMap(aCh))
{
GlobalFontMatch matchData(aCh, aRunScript, &mStyle);
family->SearchAllFontsForChar(&matchData);
gfxFontEntry *fe = matchData.mBestMatch;

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

@ -198,6 +198,56 @@ struct THEBES_API gfxFontStyle {
static PRUint32 ParseFontLanguageOverride(const nsString& aLangTag);
};
class gfxCharacterMap : public gfxSparseBitSet {
public:
nsrefcnt AddRef() {
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
++mRefCnt;
NS_LOG_ADDREF(this, mRefCnt, "gfxCharacterMap", sizeof(*this));
return mRefCnt;
}
nsrefcnt Release() {
NS_PRECONDITION(0 != mRefCnt, "dup release");
--mRefCnt;
NS_LOG_RELEASE(this, mRefCnt, "gfxCharacterMap");
if (mRefCnt == 0) {
NotifyReleased();
// |this| has been deleted.
return 0;
}
return mRefCnt;
}
gfxCharacterMap() :
mHash(0), mBuildOnTheFly(false), mShared(false)
{ }
void CalcHash() { mHash = GetChecksum(); }
size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
return gfxSparseBitSet::SizeOfExcludingThis(aMallocSizeOf);
}
// hash of the cmap bitvector
PRUint32 mHash;
// if cmap is built on the fly it's never shared
bool mBuildOnTheFly;
// cmap is shared globally
bool mShared;
protected:
void NotifyReleased();
nsAutoRefCnt mRefCnt;
private:
gfxCharacterMap(const gfxCharacterMap&);
gfxCharacterMap& operator=(const gfxCharacterMap&);
};
class gfxFontEntry {
public:
NS_INLINE_DECL_REFCOUNTING(gfxFontEntry)
@ -216,7 +266,6 @@ public:
mCheckedForGraphiteTables(false),
#endif
mHasCmapTable(false),
mCmapInitialized(false),
mUVSOffset(0), mUVSData(nsnull),
mUserFontData(nsnull),
mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE),
@ -259,16 +308,17 @@ public:
#endif
inline bool HasCmapTable() {
if (!mCmapInitialized) {
if (!mCharacterMap) {
ReadCMAP();
NS_ASSERTION(mCharacterMap, "failed to initialize character map");
}
return mHasCmapTable;
}
inline bool HasCharacter(PRUint32 ch) {
if (mCharacterMap.test(ch))
if (mCharacterMap && mCharacterMap->test(ch)) {
return true;
}
return TestCharacterMap(ch);
}
@ -344,8 +394,7 @@ public:
bool mCheckedForGraphiteTables;
#endif
bool mHasCmapTable;
bool mCmapInitialized;
gfxSparseBitSet mCharacterMap;
nsRefPtr<gfxCharacterMap> mCharacterMap;
PRUint32 mUVSOffset;
nsAutoArrayPtr<PRUint8> mUVSData;
gfxUserFontData* mUserFontData;
@ -375,7 +424,6 @@ protected:
mCheckedForGraphiteTables(false),
#endif
mHasCmapTable(false),
mCmapInitialized(false),
mUVSOffset(0), mUVSData(nsnull),
mUserFontData(nsnull),
mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE),
@ -529,7 +577,7 @@ public:
mHasStyles(false),
mIsSimpleFamily(false),
mIsBadUnderlineFamily(false),
mCharacterMapInitialized(false)
mFamilyCharacterMapInitialized(false)
{ }
virtual ~gfxFontFamily() {
@ -607,26 +655,27 @@ public:
PRUint32 i, numFonts = mAvailableFonts.Length();
for (i = 0; i < numFonts; i++) {
gfxFontEntry *fe = mAvailableFonts[i];
if (!fe) {
// don't try to load cmaps for downloadable fonts not yet loaded
if (!fe || fe->mIsProxy) {
continue;
}
fe->ReadCMAP();
mCharacterMap.Union(fe->mCharacterMap);
mFamilyCharacterMap.Union(*(fe->mCharacterMap));
}
mCharacterMap.Compact();
mCharacterMapInitialized = true;
mFamilyCharacterMap.Compact();
mFamilyCharacterMapInitialized = true;
}
bool TestCharacterMap(PRUint32 aCh) {
if (!mCharacterMapInitialized) {
if (!mFamilyCharacterMapInitialized) {
ReadAllCMAPs();
}
return mCharacterMap.test(aCh);
return mFamilyCharacterMap.test(aCh);
}
void ResetCharacterMap() {
mCharacterMap.reset();
mCharacterMapInitialized = false;
mFamilyCharacterMap.reset();
mFamilyCharacterMapInitialized = false;
}
// mark this family as being in the "bad" underline offset blacklist
@ -675,14 +724,14 @@ protected:
nsString mName;
nsTArray<nsRefPtr<gfxFontEntry> > mAvailableFonts;
gfxSparseBitSet mCharacterMap;
bool mOtherFamilyNamesInitialized;
bool mHasOtherFamilyNames;
bool mFaceNamesInitialized;
bool mHasStyles;
bool mIsSimpleFamily;
bool mIsBadUnderlineFamily;
bool mCharacterMapInitialized;
gfxSparseBitSet mFamilyCharacterMap;
bool mOtherFamilyNamesInitialized : 1;
bool mHasOtherFamilyNames : 1;
bool mFaceNamesInitialized : 1;
bool mHasStyles : 1;
bool mIsSimpleFamily : 1;
bool mIsBadUnderlineFamily : 1;
bool mFamilyCharacterMapInitialized : 1;
enum {
// for "simple" families, the faces are stored in mAvailableFonts

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

@ -58,6 +58,8 @@
#include "nsAutoPtr.h"
#include "nsIStreamBufferAccess.h"
#include "zlib.h"
/* Bug 341128 - w32api defines min/max which causes problems with <bitset> */
#ifdef __MINGW32__
#undef min
@ -87,6 +89,28 @@ public:
mBlocks[i] = new Block(*block);
}
}
bool Equals(const gfxSparseBitSet *aOther) const {
if (mBlocks.Length() != aOther->mBlocks.Length()) {
return false;
}
size_t n = mBlocks.Length();
for (size_t i = 0; i < n; ++i) {
const Block *b1 = mBlocks[i];
const Block *b2 = aOther->mBlocks[i];
if (!b1 != !b2) {
return false;
}
if (!b1) {
continue;
}
if (memcmp(&b1->mBits, &b2->mBits, BLOCK_SIZE) != 0) {
return false;
}
}
return true;
}
bool test(PRUint32 aIndex) const {
NS_ASSERTION(mBlocks.DebugGetHeader(), "mHdr is null, this is bad");
PRUint32 blockIndex = aIndex/BLOCK_SIZE_BITS;
@ -321,6 +345,18 @@ public:
mBlocks.Compact();
}
PRUint32 GetChecksum() const {
PRUint32 check = adler32(0, Z_NULL, 0);
for (PRUint32 i = 0; i < mBlocks.Length(); i++) {
if (mBlocks[i]) {
const Block *block = mBlocks[i];
check = adler32(check, (PRUint8*) (&i), 4);
check = adler32(check, (PRUint8*) block, sizeof(Block));
}
}
return check;
}
private:
nsTArray< nsAutoPtr<Block> > mBlocks;
};

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

@ -201,7 +201,7 @@ GDIFontEntry::GDIFontEntry(const nsAString& aFaceName,
: gfxFontEntry(aFaceName),
mWindowsFamily(0), mWindowsPitch(0),
mFontType(aFontType),
mForceGDI(false), mUnknownCMAP(false),
mForceGDI(false),
mCharset(), mUnicodeRanges()
{
mUserFontData = aUserFontData;
@ -218,43 +218,62 @@ GDIFontEntry::GDIFontEntry(const nsAString& aFaceName,
nsresult
GDIFontEntry::ReadCMAP()
{
// attempt this once, if errors occur leave a blank cmap
if (mCharacterMap) {
return NS_OK;
}
// skip non-SFNT fonts completely
if (mFontType != GFX_FONT_TYPE_PS_OPENTYPE &&
mFontType != GFX_FONT_TYPE_TT_OPENTYPE &&
mFontType != GFX_FONT_TYPE_TRUETYPE)
{
mCharacterMap = new gfxCharacterMap();
return NS_ERROR_FAILURE;
}
// attempt this once, if errors occur leave a blank cmap
if (mCmapInitialized)
return NS_OK;
mCmapInitialized = true;
nsRefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
const PRUint32 kCmapTag = TRUETYPE_TAG('c','m','a','p');
AutoFallibleTArray<PRUint8,16384> buffer;
if (GetFontTable(kCmapTag, buffer) != NS_OK)
return NS_ERROR_FAILURE;
PRUint8 *cmap = buffer.Elements();
PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p');
nsresult rv;
bool unicodeFont = false, symbolFont = false;
nsresult rv = gfxFontUtils::ReadCMAP(cmap, buffer.Length(),
mCharacterMap, mUVSOffset,
unicodeFont, symbolFont);
AutoFallibleTArray<PRUint8,16384> cmap;
rv = GetFontTable(kCMAP, cmap);
bool unicodeFont = false, symbolFont = false; // currently ignored
if (NS_SUCCEEDED(rv)) {
rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
*charmap, mUVSOffset,
unicodeFont, symbolFont);
}
mSymbolFont = symbolFont;
mHasCmapTable = NS_SUCCEEDED(rv);
if (mHasCmapTable) {
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
mCharacterMap = pfl->FindCharMap(charmap);
} else {
// if error occurred, initialize to null cmap
mCharacterMap = new gfxCharacterMap();
// For fonts where we failed to read the character map,
// we can take a slow path to look up glyphs character by character
mCharacterMap->mBuildOnTheFly = true;
}
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d hash: %8.8x%s\n",
NS_ConvertUTF16toUTF8(mName).get(),
mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
charmap->SizeOfIncludingThis(moz_malloc_size_of),
charmap->mHash, mCharacterMap == charmap ? " new" : ""));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
NS_ConvertUTF16toUTF8(mName).get());
mCharacterMap.Dump(prefix, eGfxLog_cmapdata);
charmap->Dump(prefix, eGfxLog_cmapdata);
}
#endif
return rv;
}
@ -346,13 +365,12 @@ GDIFontEntry::FillLogFont(LOGFONTW *aLogFont,
bool
GDIFontEntry::TestCharacterMap(PRUint32 aCh)
{
if (ReadCMAP() != NS_OK) {
// For fonts where we failed to read the character map,
// we can take a slow path to look up glyphs character by character
mUnknownCMAP = true;
if (!mCharacterMap) {
nsresult rv = ReadCMAP();
NS_ASSERTION(mCharacterMap, "failed to initialize a character map");
}
if (mUnknownCMAP) {
if (mCharacterMap->mBuildOnTheFly) {
if (aCh > 0xFFFF)
return false;
@ -404,12 +422,12 @@ GDIFontEntry::TestCharacterMap(PRUint32 aCh)
ReleaseDC(NULL, dc);
if (hasGlyph) {
mCharacterMap.set(aCh);
mCharacterMap->set(aCh);
return true;
}
} else {
// font had a cmap so simply check that
return mCharacterMap.test(aCh);
return mCharacterMap->test(aCh);
}
return false;

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

@ -293,7 +293,6 @@ public:
gfxWindowsFontType mFontType;
bool mForceGDI : 1;
bool mUnknownCMAP : 1;
gfxSparseBitSet mCharset;
gfxSparseBitSet mUnicodeRanges;

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

@ -189,93 +189,98 @@ nsresult
MacOSFontEntry::ReadCMAP()
{
// attempt this once, if errors occur leave a blank cmap
if (mCmapInitialized) {
if (mCharacterMap) {
return NS_OK;
}
mCmapInitialized = true;
nsRefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p');
nsresult rv;
AutoFallibleTArray<PRUint8,16384> cmap;
if (GetFontTable(kCMAP, cmap) != NS_OK) {
return NS_ERROR_FAILURE;
rv = GetFontTable(kCMAP, cmap);
bool unicodeFont = false, symbolFont = false; // currently ignored
if (NS_SUCCEEDED(rv)) {
rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
*charmap, mUVSOffset,
unicodeFont, symbolFont);
}
bool unicodeFont, symbolFont; // currently ignored
nsresult rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
mCharacterMap, mUVSOffset,
unicodeFont, symbolFont);
if (NS_FAILED(rv)) {
mCharacterMap.reset();
return rv;
}
mHasCmapTable = true;
if (NS_SUCCEEDED(rv)) {
// for layout support, check for the presence of mort/morx and/or
// opentype layout tables
bool hasAATLayout = HasFontTable(TRUETYPE_TAG('m','o','r','x')) ||
HasFontTable(TRUETYPE_TAG('m','o','r','t'));
bool hasGSUB = HasFontTable(TRUETYPE_TAG('G','S','U','B'));
bool hasGPOS = HasFontTable(TRUETYPE_TAG('G','P','O','S'));
CGFontRef fontRef = GetFontRef();
if (!fontRef) {
return NS_ERROR_FAILURE;
}
if (hasAATLayout && !(hasGSUB || hasGPOS)) {
mRequiresAAT = true; // prefer CoreText if font has no OTL tables
}
// for layout support, check for the presence of mort/morx and/or
// opentype layout tables
bool hasAATLayout = HasFontTable(TRUETYPE_TAG('m','o','r','x')) ||
HasFontTable(TRUETYPE_TAG('m','o','r','t'));
bool hasGSUB = HasFontTable(TRUETYPE_TAG('G','S','U','B'));
bool hasGPOS = HasFontTable(TRUETYPE_TAG('G','P','O','S'));
PRUint32 numScripts =
sizeof(gScriptsThatRequireShaping) / sizeof(ScriptRange);
if (hasAATLayout && !(hasGSUB || hasGPOS)) {
mRequiresAAT = true; // prefer CoreText if font has no OTL tables
}
for (PRUint32 s = 0; s < numScripts; s++) {
eComplexScript whichScript = gScriptsThatRequireShaping[s].script;
PRUint32 numScripts =
sizeof(gScriptsThatRequireShaping) / sizeof(ScriptRange);
// check to see if the cmap includes complex script codepoints
if (charmap->TestRange(gScriptsThatRequireShaping[s].rangeStart,
gScriptsThatRequireShaping[s].rangeEnd)) {
bool omitRange = true;
for (PRUint32 s = 0; s < numScripts; s++) {
eComplexScript whichScript = gScriptsThatRequireShaping[s].script;
// check to see if the cmap includes complex script codepoints
if (mCharacterMap.TestRange(gScriptsThatRequireShaping[s].rangeStart,
gScriptsThatRequireShaping[s].rangeEnd)) {
bool omitRange = true;
if (hasAATLayout) {
omitRange = false;
// prefer CoreText for Apple's complex-script fonts,
// even if they also have some OpenType tables
// (e.g. Geeza Pro Bold on 10.6; see bug 614903)
mRequiresAAT = true;
} else if (whichScript == eComplexScriptArabic) {
// special-case for Arabic:
// even if there's no morph table, CoreText can shape Arabic
// using OpenType layout; or if it's a downloaded font,
// assume the site knows what it's doing (as harfbuzz will
// be able to shape even though the font itself lacks tables
// stripped during sanitization).
// We check for GSUB here, as GPOS alone would not be ok
// for Arabic shaping.
if (hasGSUB || (mIsUserFont && !mIsLocalUserFont)) {
// TODO: to be really thorough, we could check that the
// GSUB table actually supports the 'arab' script tag.
if (hasAATLayout) {
omitRange = false;
// prefer CoreText for Apple's complex-script fonts,
// even if they also have some OpenType tables
// (e.g. Geeza Pro Bold on 10.6; see bug 614903)
mRequiresAAT = true;
} else if (whichScript == eComplexScriptArabic) {
// special-case for Arabic:
// even if there's no morph table, CoreText can shape Arabic
// using OpenType layout; or if it's a downloaded font,
// assume the site knows what it's doing (as harfbuzz will
// be able to shape even though the font itself lacks tables
// stripped during sanitization).
// We check for GSUB here, as GPOS alone would not be ok
// for Arabic shaping.
if (hasGSUB || (mIsUserFont && !mIsLocalUserFont)) {
// TODO: to be really thorough, we could check that the
// GSUB table actually supports the 'arab' script tag.
omitRange = false;
}
}
}
if (omitRange) {
mCharacterMap.ClearRange(gScriptsThatRequireShaping[s].rangeStart,
gScriptsThatRequireShaping[s].rangeEnd);
if (omitRange) {
charmap->ClearRange(gScriptsThatRequireShaping[s].rangeStart,
gScriptsThatRequireShaping[s].rangeEnd);
}
}
}
}
mHasCmapTable = NS_SUCCEEDED(rv);
if (mHasCmapTable) {
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
mCharacterMap = pfl->FindCharMap(charmap);
} else {
// if error occurred, initialize to null cmap
mCharacterMap = new gfxCharacterMap();
}
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d hash: %8.8x%s\n",
NS_ConvertUTF16toUTF8(mName).get(),
mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
charmap->SizeOfIncludingThis(moz_malloc_size_of),
charmap->mHash, mCharacterMap == charmap ? " new" : ""));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
NS_ConvertUTF16toUTF8(mName).get());
mCharacterMap.Dump(prefix, eGfxLog_cmapdata);
charmap->Dump(prefix, eGfxLog_cmapdata);
}
#endif

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

@ -213,10 +213,13 @@ gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
gFontListPrefObserver = new gfxFontListPrefObserver();
NS_ADDREF(gFontListPrefObserver);
Preferences::AddStrongObservers(gFontListPrefObserver, kObservedPrefs);
mSharedCmaps.Init(16);
}
gfxPlatformFontList::~gfxPlatformFontList()
{
mSharedCmaps.Clear();
NS_ASSERTION(gFontListPrefObserver, "There is no font list pref observer");
Preferences::RemoveObservers(gFontListPrefObserver, kObservedPrefs);
NS_RELEASE(gFontListPrefObserver);
@ -714,6 +717,41 @@ gfxPlatformFontList::GetStandardFamilyName(const nsAString& aFontName, nsAString
return !aFamilyName.IsEmpty();
}
gfxCharacterMap*
gfxPlatformFontList::FindCharMap(gfxCharacterMap *aCmap)
{
aCmap->CalcHash();
gfxCharacterMap *cmap = AddCmap(aCmap);
cmap->mShared = true;
return cmap;
}
// add a cmap to the shared cmap set
gfxCharacterMap*
gfxPlatformFontList::AddCmap(const gfxCharacterMap* aCharMap)
{
CharMapHashKey *found =
mSharedCmaps.PutEntry(const_cast<gfxCharacterMap*>(aCharMap));
return found->GetKey();
}
// remove the cmap from the shared cmap set
void
gfxPlatformFontList::RemoveCmap(const gfxCharacterMap* aCharMap)
{
// skip lookups during teardown
if (mSharedCmaps.Count() == 0) {
return;
}
// cmap needs to match the entry *and* be the same ptr before removing
CharMapHashKey *found =
mSharedCmaps.GetEntry(const_cast<gfxCharacterMap*>(aCharMap));
if (found && found->GetKey() == aCharMap) {
mSharedCmaps.RemoveEntry(const_cast<gfxCharacterMap*>(aCharMap));
}
}
void
gfxPlatformFontList::InitLoader()
{
@ -830,6 +868,21 @@ SizeOfStringEntryExcludingThis(nsStringHashKey* aHashEntry,
return aHashEntry->GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
static size_t
SizeOfSharedCmapExcludingThis(CharMapHashKey* aHashEntry,
nsMallocSizeOfFun aMallocSizeOf,
void* aUserArg)
{
FontListSizes *sizes = static_cast<FontListSizes*>(aUserArg);
PRUint32 size = aHashEntry->GetKey()->SizeOfIncludingThis(aMallocSizeOf);
sizes->mCharMapsSize += size;
// we return zero here because the measurements have been added directly
// to the relevant fields of the FontListSizes record
return 0;
}
void
gfxPlatformFontList::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
@ -865,6 +918,10 @@ gfxPlatformFontList::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
aSizes->mFontListSize +=
mBadUnderlineFamilyNames.SizeOfExcludingThis(SizeOfStringEntryExcludingThis,
aMallocSizeOf);
aSizes->mFontListSize +=
mSharedCmaps.SizeOfExcludingThis(SizeOfSharedCmapExcludingThis,
aMallocSizeOf, aSizes);
}
void

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

@ -50,6 +50,53 @@
#include "nsIMemoryReporter.h"
#include "mozilla/FunctionTimer.h"
class CharMapHashKey : public PLDHashEntryHdr
{
public:
typedef gfxCharacterMap* KeyType;
typedef const gfxCharacterMap* KeyTypePointer;
CharMapHashKey(const gfxCharacterMap *aCharMap) :
mCharMap(const_cast<gfxCharacterMap*>(aCharMap))
{
MOZ_COUNT_CTOR(CharMapHashKey);
}
CharMapHashKey(const CharMapHashKey& toCopy) :
mCharMap(toCopy.mCharMap)
{
MOZ_COUNT_CTOR(CharMapHashKey);
}
~CharMapHashKey()
{
MOZ_COUNT_DTOR(CharMapHashKey);
}
gfxCharacterMap* GetKey() const { return mCharMap; }
bool KeyEquals(const gfxCharacterMap *aCharMap) const {
NS_ASSERTION(!aCharMap->mBuildOnTheFly && !mCharMap->mBuildOnTheFly,
"custom cmap used in shared cmap hashtable");
// cmaps built on the fly never match
if (aCharMap->mHash != mCharMap->mHash)
{
return false;
}
return mCharMap->Equals(aCharMap);
}
static const gfxCharacterMap* KeyToPointer(gfxCharacterMap *aCharMap) {
return aCharMap;
}
static PLDHashNumber HashKey(const gfxCharacterMap *aCharMap) {
return aCharMap->mHash;
}
enum { ALLOW_MEMMOVE = true };
protected:
gfxCharacterMap *mCharMap;
};
// gfxPlatformFontList is an abstract class for the global font list on the system;
// concrete subclasses for each platform implement the actual interface to the system fonts.
// This class exists because we cannot rely on the platform font-finding APIs to behave
@ -155,6 +202,16 @@ public:
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
// search for existing cmap that matches the input
// return the input if no match is found
gfxCharacterMap* FindCharMap(gfxCharacterMap *aCmap);
// add a cmap to the shared cmap set
gfxCharacterMap* AddCmap(const gfxCharacterMap *aCharMap);
// remove the cmap from the shared cmap set
void RemoveCmap(const gfxCharacterMap *aCharMap);
protected:
class MemoryReporter
: public nsIMemoryMultiReporter
@ -264,6 +321,10 @@ protected:
nsTHashtable<nsStringHashKey> mBadUnderlineFamilyNames;
// character map data shared across families
// contains weak ptrs to cmaps shared by font entry objects
nsTHashtable<CharMapHashKey> mSharedCmaps;
// data used as part of the font cmap loading process
nsTArray<nsRefPtr<gfxFontFamily> > mFontFamiliesToLoad;
PRUint32 mStartIndex;

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

@ -115,12 +115,12 @@ include $(topsrcdir)/config/rules.mk
# NB: the IPDL compiler manages .ipdl-->.h/.cpp dependencies itself,
# which is why we don't have explicit .h/.cpp targets here
export:: $(ALL_IPDLSRCS)
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/other-licenses/ply \
$(srcdir)/ipdl.py \
--outheaders-dir=_ipdlheaders \
--outcpp-dir=. \
$(IPDLDIRS:%=-I$(topsrcdir)/%) \
$(PYTHON_PATH) \
$(PLY_INCLUDE) \
$(srcdir)/ipdl.py \
--outheaders-dir=_ipdlheaders \
--outcpp-dir=. \
$(IPDLDIRS:%=-I$(topsrcdir)/%) \
$^
# We #include some things in the dom/plugins/ directory that rely on

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

@ -49,7 +49,7 @@ check::
@$(PYTHON) $(srcdir)/runtests.py \
$(srcdir)/ok $(srcdir)/error \
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/other-licenses/ply \
$(PLY_INCLUDE) \
$(topsrcdir)/ipc/ipdl/ipdl.py \
OKTESTS $(OKTESTS) \
ERRORTESTS $(ERRORTESTS)

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

@ -278,6 +278,15 @@ RilClient::OnFileCanReadWithoutBlocking(int fd)
mIncoming = new RilRawData();
ssize_t ret = read(fd, mIncoming->mData, RilRawData::MAX_DATA_SIZE);
if (ret <= 0) {
if (ret == -1) {
if (errno == EINTR) {
continue; // retry system call when interrupted
}
else if (errno == EAGAIN || errno == EWOULDBLOCK) {
return; // no data available: return and re-poll
}
// else fall through to error handling on other errno's
}
LOG("Cannot read from network, error %d\n", ret);
// At this point, assume that we can't actually access
// the socket anymore, and start a reconnect loop.

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

@ -409,9 +409,9 @@ GC(JSContext *cx,
unsigned argc,
jsval *vp)
{
JS_GC(cx);
#ifdef JS_GCMETER
JSRuntime *rt = JS_GetRuntime(cx);
JS_GC(rt);
#ifdef JS_GCMETER
js_DumpGCStats(rt, stdout);
#endif
JS_SET_RVAL(cx, vp, JSVAL_VOID);
@ -1054,16 +1054,15 @@ XPCShellEnvironment::~XPCShellEnvironment()
}
mGlobalHolder.Release();
JS_GC(mCx);
JSRuntime *rt = JS_GetRuntime(mCx);
JS_GC(rt);
mCxStack = nsnull;
if (mJSPrincipals) {
JS_DropPrincipals(JS_GetRuntime(mCx), mJSPrincipals);
JS_DropPrincipals(rt, mJSPrincipals);
}
JSRuntime* rt = gOldContextCallback ? JS_GetRuntime(mCx) : NULL;
JS_EndRequest(mCx);
JS_DestroyContext(mCx);

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

@ -2817,8 +2817,8 @@ NS_IMETHODIMP
jsdService::GC (void)
{
ASSERT_VALID_CONTEXT;
JSContext *cx = JSD_GetDefaultJSContext (mCx);
JS_GC(cx);
JSRuntime *rt = JSD_GetJSRuntime (mCx);
JS_GC(rt);
return NS_OK;
}

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

@ -98,6 +98,13 @@ JSD_GetDefaultJSContext(JSDContext* jsdc)
return jsdc->dumbContext;
}
JSD_PUBLIC_API(JSRuntime*)
JSD_GetJSRuntime(JSDContext* jsdc)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsdc->jsrt;
}
JSD_PUBLIC_API(void)
JSD_SetUserCallbacks(JSRuntime* jsrt, JSD_UserCallbacks* callbacks, void* user)
{

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

@ -188,6 +188,12 @@ JSD_GetMinorVersion(void);
extern JSD_PUBLIC_API(JSContext*)
JSD_GetDefaultJSContext(JSDContext* jsdc);
/*
* Returns a JSRuntime this context is associated with
*/
extern JSD_PUBLIC_API(JSRuntime*)
JSD_GetJSRuntime(JSDContext* jsdc);
/*
* Set the private data for this context, returns previous value
*/

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

@ -286,7 +286,7 @@ MapObject::construct(JSContext *cx, unsigned argc, Value *vp)
JSBool
MapObject::size(JSContext *cx, unsigned argc, Value *vp)
{
THIS_MAP(get, cx, argc, vp, args, map);
THIS_MAP(size, cx, argc, vp, args, map);
JS_STATIC_ASSERT(sizeof map.count() <= sizeof(uint32_t));
args.rval().setNumber(map.count());
return true;
@ -455,7 +455,7 @@ SetObject::construct(JSContext *cx, unsigned argc, Value *vp)
JSBool
SetObject::size(JSContext *cx, unsigned argc, Value *vp)
{
THIS_SET(has, cx, argc, vp, args, set);
THIS_SET(size, cx, argc, vp, args, set);
JS_STATIC_ASSERT(sizeof set.count() <= sizeof(uint32_t));
args.rval().setNumber(set.count());
return true;

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

@ -47,7 +47,7 @@ GC(JSContext *cx, unsigned argc, jsval *vp)
PrepareForDebugGC(cx->runtime);
else
PrepareForFullGC(cx->runtime);
GCForReason(cx, gcreason::API);
GCForReason(cx->runtime, gcreason::API);
char buf[256] = { '\0' };
#ifndef JS_MORE_DETERMINISTIC
@ -234,7 +234,7 @@ VerifyBarriers(JSContext *cx, unsigned argc, jsval *vp)
ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Too many arguments");
return JS_FALSE;
}
gc::VerifyBarriers(cx);
gc::VerifyBarriers(cx->runtime);
*vp = JSVAL_VOID;
return JS_TRUE;
}
@ -257,7 +257,7 @@ GCSlice(JSContext *cx, unsigned argc, jsval *vp)
limit = false;
}
GCDebugSlice(cx, limit, budget);
GCDebugSlice(cx->runtime, limit, budget);
*vp = JSVAL_VOID;
return JS_TRUE;
}
@ -469,7 +469,6 @@ 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();
@ -499,7 +498,7 @@ MJitChunkLimit(JSContext *cx, unsigned argc, jsval *vp)
// Clear out analysis information which might refer to code compiled with
// the previous chunk limit.
JS_GC(cx);
JS_GC(cx->runtime);
vp->setUndefined();
return true;

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

@ -837,3 +837,8 @@ EXPAND_LIBNAME = $(foreach lib,$(1),$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
endif
EXPAND_LIBNAME_PATH = $(foreach lib,$(1),$(2)/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
EXPAND_MOZLIBNAME = $(foreach lib,$(1),$(DIST)/lib/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
# Include internal ply only if needed
ifndef MOZ_SYSTEM_PLY
PLY_INCLUDE = -I$(topsrcdir)/other-licenses/ply
endif

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

@ -1444,7 +1444,7 @@ xpidl-preqs = \
$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
$(REPORT_BUILD)
$(PYTHON_PATH) \
-I$(topsrcdir)/other-licenses/ply \
$(PLY_INCLUDE) \
-I$(topsrcdir)/xpcom/idl-parser \
$(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
@if test -n "$(findstring $*.h, $(EXPORTS))"; \
@ -1456,7 +1456,7 @@ ifndef NO_GEN_XPT
$(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
$(REPORT_BUILD)
$(PYTHON_PATH) \
-I$(topsrcdir)/other-licenses/ply \
$(PLY_INCLUDE) \
-I$(topsrcdir)/xpcom/idl-parser \
-I$(topsrcdir)/xpcom/typelib/xpt/tools \
$(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -0,0 +1,5 @@
load(libdir + "asserts.js");
var g = newGlobal('new-compartment');
assertThrowsInstanceOf(function () { Map.prototype.size.apply(g, []); }, g.TypeError);
assertThrowsInstanceOf(function () { Set.prototype.size.apply(g, []); }, g.TypeError);

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

@ -0,0 +1,14 @@
// Environment.prototype.getVariable does not see variables bound in enclosing scopes.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
var hits = 0;
dbg.onDebuggerStatement = function (frame) {
assertEq(frame.environment.getVariable("x"), 13);
assertEq(frame.environment.getVariable("k"), undefined);
assertEq(frame.environment.find("k").getVariable("k"), 3);
hits++;
};
g.eval("var k = 3; function f(x) { debugger; }");
g.f(13);
assertEq(hits, 1);

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

@ -0,0 +1,16 @@
// getVariable works in function scopes.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
var hits = 0;
dbg.onDebuggerStatement = function (frame) {
assertEq(frame.environment.getVariable("a"), 1);
assertEq(frame.environment.getVariable("b"), 2);
assertEq(frame.environment.getVariable("c"), 3);
assertEq(frame.environment.getVariable("d"), 4);
assertEq(frame.environment.getVariable("e"), 5);
hits++;
};
g.eval("function f(a, [b, c]) { var d = c + 1; let e = d + 1; debugger; }");
g.f(1, [2, 3]);
assertEq(hits, 1);

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

@ -0,0 +1,22 @@
// getVariable sees bindings in let-block scopes.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
var log = '';
dbg.onDebuggerStatement = function (frame) {
log += frame.environment.getVariable("x");
};
g.eval("function f() {\n" +
" let x = 'a';\n" +
" debugger;\n" +
" for (let x = 0; x < 2; x++)\n" +
" if (x === 0)\n" +
" debugger;\n" +
" else {\n" +
" let x = 'b'; debugger;\n" +
" }\n" +
"}\n");
g.f();
g.eval("let (x = 'c') { debugger; }");
g.eval("{ let x = 'd'; debugger; }");
assertEq(log, 'a0bcd');

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

@ -0,0 +1,12 @@
// getVariable sees variables in function scopes added by non-strict direct eval.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
var v;
dbg.onDebuggerStatement = function (frame) {
v = frame.environment.getVariable("x");
};
g.eval("function f(s) { eval(s); debugger; }");
g.f("var x = 'Q';");
assertEq(v, 'Q');

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

@ -0,0 +1,10 @@
// getVariable sees global variables.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
var log = '';
dbg.onDebuggerStatement = function (frame) {
log += frame.environment.getVariable("x") + frame.environment.getVariable("y");
};
g.eval("var x = 'a'; this.y = 'b'; debugger;");
assertEq(log, 'ab');

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

@ -0,0 +1,12 @@
// getVariable sees properties inherited from the global object's prototype chain.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
var log = '';
dbg.onDebuggerStatement = function (frame) {
log += frame.environment.getVariable("x") + frame.environment.getVariable("y");
};
g.eval("Object.getPrototypeOf(this).x = 'a';\n" +
"Object.prototype.y = 'b';\n" +
"debugger;\n");
assertEq(log, 'ab');

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

@ -0,0 +1,10 @@
// getVariable can get properties from with-block scopes.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
var v;
dbg.onDebuggerStatement = function (frame) {
v = frame.environment.getVariable("x");
};
g.eval("var x = 1; { let x = 2; with ({x: 3}) { debugger; } }");
assertEq(v, 3);

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

@ -0,0 +1,10 @@
// getVariable sees properties inherited from a with-object's prototype chain.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
var v;
dbg.onDebuggerStatement = function (frame) {
v = frame.environment.getVariable("x");
};
g.eval("var x = 1; { let x = 2; with (Object.create({x: 3})) { debugger; } }");
assertEq(v, 3);

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

@ -0,0 +1,13 @@
// getVariable works on ancestors of frame.environment.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
var log = '';
dbg.onDebuggerStatement = function (frame) {
for (var env = frame.environment; env; env = env.parent) {
if (env.find("x") === env)
log += env.getVariable("x");
}
};
g.eval("var x = 1; { let x = 2; with (Object.create({x: 3})) { debugger; } }");
assertEq(log, "321");

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

@ -0,0 +1,27 @@
// getVariable works on a heavyweight environment after control leaves its scope.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
var envs = [];
dbg.onDebuggerStatement = function (frame) {
envs.push(frame.environment);
};
g.eval("var f;\n" +
"for (var x = 0; x < 3; x++) {\n" +
" (function (x) {\n" +
" for (var y = 0; y < 3; y++) {\n" +
" (function (z) {\n" +
" eval(z); // force heavyweight\n" +
" debugger;\n" +
" })(x + y);\n" +
" }\n" +
" })(x);\n" +
"}");
var i = 0;
for (var x = 0; x < 3; x++) {
for (var y = 0; y < 3; y++) {
var e = envs[i++];
assertEq(e.getVariable("z"), x + y);
}
}

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

@ -0,0 +1,15 @@
// The value returned by getVariable can be a Debugger.Object.
var g = newGlobal('new-compartment');
var dbg = new Debugger;
var gw = dbg.addDebuggee(g);
var hits = 0;
dbg.onDebuggerStatement = function (frame) {
var a = frame.environment.getVariable('Math');
assertEq(a instanceof Debugger.Object, true);
var b = gw.getOwnPropertyDescriptor('Math').value;
assertEq(a, b);
hits++;
};
g.eval("debugger;");
assertEq(hits, 1);

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

@ -0,0 +1,17 @@
// getVariable that would trigger a getter does not crash or explode.
// It should throw WouldRunDebuggee, but that isn't implemented yet.
load(libdir + "asserts.js");
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
var hits = 0;
dbg.onDebuggerStatement = function (frame) {
assertThrowsInstanceOf(function () {
frame.environment.getVariable("x");
}, Error);
hits++;
};
g.eval("Object.defineProperty(this, 'x', {get: function () { throw new Error('fail'); }});\n" +
"debugger;");
assertEq(hits, 1);

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

@ -0,0 +1,9 @@
// Environment.prototype.setVariable can set global variables.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
dbg.onDebuggerStatement = function (frame) {
frame.environment.setVariable("x", 2);
};
g.eval("var x = 1; debugger;");
assertEq(g.x, 2);

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

@ -0,0 +1,10 @@
// The argument to setVariable can be a Debugger.Object.
var g = newGlobal('new-compartment');
var dbg = new Debugger;
var gw = dbg.addDebuggee(g);
dbg.onDebuggerStatement = function (frame) {
frame.environment.setVariable("x", gw);
};
g.eval("var x = 1; debugger;");
assertEq(g.x, g);

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

@ -0,0 +1,16 @@
// setVariable cannot create new global variables.
// (Other kinds of environment are tested in Environment-variables.js.)
load(libdir + "asserts.js");
var g = newGlobal('new-compartment');
var dbg = new Debugger(g);
var hits = 0;
dbg.onDebuggerStatement = function (frame) {
assertThrowsInstanceOf(function () { frame.environment.setVariable("x", 7); }, TypeError);
hits++;
};
g.eval("debugger");
assertEq("x" in g, false);
assertEq(hits, 1);

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

@ -0,0 +1,10 @@
// setVariable can set variables and arguments in functions.
var g = newGlobal('new-compartment');
var dbg = new Debugger(g);
dbg.onDebuggerStatement = function (frame) {
frame.environment.setVariable("a", 100);
frame.environment.setVariable("b", 200);
};
g.eval("function f(a) { var b = a + 1; debugger; return a + b; }");
assertEq(g.f(1), 300);

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

@ -0,0 +1,14 @@
// setVariable can change the types of variables and arguments in functions.
var g = newGlobal('new-compartment');
g.eval("function f(a) { var b = a + 1; debugger; return a + b; }");
for (var i = 0; i < 20; i++)
assertEq(g.f(i), 2 * i + 1);
var dbg = new Debugger(g);
dbg.onDebuggerStatement = function (frame) {
frame.environment.setVariable("a", "xyz");
frame.environment.setVariable("b", "zy");
};
for (var i = 0; i < 10; i++)
assertEq(g.f(i), "xyzzy");

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

@ -0,0 +1,9 @@
// setVariable on an argument works as expected with non-strict 'arguments'.
var g = newGlobal('new-compartment');
g.eval("function f(a) { debugger; return arguments[0]; }");
var dbg = new Debugger(g);
dbg.onDebuggerStatement = function (frame) {
frame.environment.setVariable("a", 2);
};
assertEq(g.f(1), 2);

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

@ -0,0 +1,15 @@
// setVariable works on let-bindings.
var g = newGlobal('new-compartment');
function test(code, val) {
g.eval("function f() { " + code + " }");
var dbg = new Debugger(g);
dbg.onDebuggerStatement = function (frame) {
frame.environment.setVariable("a", val);
};
assertEq(g.f(), val);
}
test("let a = 1; debugger; return a;", "xyzzy");
test("{ let a = 1; debugger; return a; }", "plugh");
test("let (a = 1) { debugger; return a; }", "wcgr");

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

@ -0,0 +1,29 @@
// setVariable throws if no binding exists.
load(libdir + "asserts.js");
function test(code) {
var g = newGlobal('new-compartment');
var dbg = new Debugger(g);
var hits = 0;
dbg.onDebuggerStatement = function (frame) {
var env = frame.older.environment;
assertThrowsInstanceOf(function () { env.setVariable("y", 2); }, Error);
hits++;
};
g.eval("var y = 0; function d() { debugger; }");
assertEq(g.eval(code), 0);
assertEq(g.y, 0);
assertEq(hits, 1);
}
// local scope of non-heavyweight function
test("function f() { var x = 1; d(); return y; } f();");
// block scope
test("function h(x) { if (x) { let x = 1; d(); return y; } } h(3);");
// strict eval scope
test("'use strict'; eval('d(); y;');");

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

@ -0,0 +1,32 @@
// setVariable works on non-innermost environments.
// (The debuggee code here is a bit convoluted to defeat optimizations that
// could make obj.b a null closure or obj.i a flat closure--that is, a function
// that gets a frozen copy of i instead of a reference to the runtime
// environment that contains it. setVariable does not currently detect this
// flat closure case.)
var g = newGlobal('new-compartment');
g.eval("function d() { debugger; }\n" +
"var i = 'FAIL';\n" +
"function a() {\n" +
" var obj = {b: function (i) { d(obj); return i; },\n" +
" i: function () { return i; }};\n" +
" var i = 'FAIL2';\n" +
" return obj;\n" +
"}\n");
var dbg = Debugger(g);
dbg.onDebuggerStatement = function (frame) {
var x = 0;
for (var env = frame.older.environment; env; env = env.parent) {
if (env.getVariable("i") !== undefined)
env.setVariable("i", x++);
}
};
var obj = g.a();
var r = obj.b('FAIL3');
assertEq(r, 0);
assertEq(obj.i(), 1);
assertEq(g.i, 2);

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

@ -0,0 +1,16 @@
// setVariable cannot modify the binding for a FunctionExpression's name.
load(libdir + "asserts.js");
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
var hits = 0;
dbg.onDebuggerStatement = function (frame) {
var env = frame.environment.find("f");
assertEq(env.getVariable("f"), frame.callee);
assertThrowsInstanceOf(function () { env.setVariable("f", 0) }, TypeError);
assertThrowsInstanceOf(function () { env.setVariable("f", frame.callee) }, TypeError);
hits++;
};
g.eval("(function f() { debugger; })();");
assertEq(hits, 1);

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

@ -0,0 +1,21 @@
// setVariable can create a new property on a with block's bindings object, if
// it is shadowing an existing property on the prototype chain.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
dbg.onDebuggerStatement = function (frame) {
var env = frame.environment.find("x");
env.setVariable("x", 2);
};
g.eval("var obj1 = {x: 1}, obj2 = Object.create(obj1), z; with (obj2) { debugger; z = x; }");
assertEq(g.obj1.x, 1);
assertEq(g.obj2.x, 2);
assertEq(g.z, 2);
// The property created by setVariable is like the one created by ordinary
// assignment in a with-block.
var desc = Object.getOwnPropertyDescriptor(g.obj2, "x");
assertEq(desc.configurable, true);
assertEq(desc.enumerable, true);
assertEq(desc.writable, true);
assertEq(desc.value, 2);

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

@ -0,0 +1,22 @@
// setVariable triggering a setter doesn't crash or explode.
// It should throw WouldRunDebuggee, but that isn't implemented yet.
function test(code) {
var g = newGlobal('new-compartment');
g.eval("function d() { debugger; }");
var dbg = Debugger(g);
var hits = 0;
dbg.onDebuggerStatement = function (frame) {
var env = frame.environment.find("x");
try {
env.setVariable("x", 0);
} catch (exc) {
}
hits++;
};
g.eval(code);
}
test("Object.defineProperty(this, 'x', {set: function (v) {}}); d();");
test("Object.defineProperty(Object.prototype, 'x', {set: function (v) {}}); d();");
test("with ({set x(v) {}}) eval(d());");

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

@ -0,0 +1,92 @@
// Comprehensive test of get/setVariable on many kinds of environments and
// bindings.
load(libdir + "asserts.js");
var cases = [
// global bindings and bindings on the global prototype chain
"x = VAL; @@",
"var x = VAL; @@",
"Object.prototype.x = VAL; @@",
// let, catch, and comprehension bindings
"let x = VAL; @@",
"{ let x = VAL; @@ }",
"let (x = VAL) { @@ }",
"try { throw VAL; } catch (x) { @@ }",
"try { throw VAL; } catch (x) { @@ }",
"for (let x of [VAL]) { @@ }",
"for each (let x in [VAL]) { @@ }",
"switch (0) { default: let x = VAL; @@ }",
"[function () { @@ }() for (x of [VAL])];",
// "((function () { @@ })() for (x of [VAL])).next();", // bug 709367
// arguments
"function f(x) { @@ } f(VAL);",
"function f([w, x]) { @@ } f([0, VAL]);",
"function f({v: x}) { @@ } f({v: VAL});",
"function f([w, {v: x}]) { @@ } f([0, {v: VAL}]);",
// bindings in functions
"function f() { var x = VAL; @@ } f();",
"function f() { let x = VAL; @@ } f();",
"function f([x]) { let x = VAL; @@ } f(['fail']);",
"function f(x) { { let x = VAL; @@ } } f('fail');",
"function f() { function x() {} x = VAL; @@ } f();",
// dynamic bindings
"function f(s) { eval(s); @@ } f('var x = VAL');",
"function f(s) { let (x = 'fail') { eval(s); } x = VAL; @@ } f('var x;');",
"var x = VAL; function f(s) { eval('var x = 0;'); eval(s); @@ } f('delete x;');",
"function f(obj) { with (obj) { @@ } } f({x: VAL});",
"function f(obj) { with (obj) { @@ } } f(Object.create({x: VAL}));",
"function f(b) { if (b) { function x(){} } x = VAL; @@ } f(1);",
];
var nextval = 1000;
function test(code, debugStmts, followupStmts) {
var val = nextval++;
var hits = 0;
var g = newGlobal('new-compartment');
g.eval("function debugMe() { var x = 'wrong-x'; debugger; }");
g.capture = null;
var dbg = Debugger(g);
dbg.onDebuggerStatement = function (frame) {
if (frame.callee !== null && frame.callee.name == 'debugMe')
frame = frame.older;
var env = frame.environment.find("x");
assertEq(env.getVariable("x"), val)
assertEq(env.setVariable("x", 'ok'), undefined);
assertEq(env.getVariable("x"), 'ok');
// setVariable cannot create new variables.
assertThrowsInstanceOf(function () { env.setVariable("newVar", 0); }, TypeError);
hits++;
};
code = code.replace("@@", debugStmts);
if (followupStmts !== undefined)
code += " " + followupStmts;
code = code.replace(/VAL/g, uneval(val));
g.eval(code);
assertEq(hits, 1);
}
for (var s of cases) {
// Test triggering the debugger right in the scope in which x is bound.
test(s, "debugger; assertEq(x, 'ok');");
// Test calling a function that triggers the debugger.
test(s, "debugMe(); assertEq(x, 'ok');");
// Test triggering the debugger from a scope nested in x's scope.
test(s, "let (y = 'irrelevant') { (function (z) { let (zz = y) { debugger; }})(); } assertEq(x, 'ok');"),
// Test closing over the variable and triggering the debugger later, after
// leaving the variable's scope.
test(s, "capture = {dbg: function () { debugger; }, get x() { return x; }};",
"assertEq(capture.x, VAL); capture.dbg(); assertEq(capture.x, 'ok');");
}

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

@ -377,3 +377,5 @@ MSG_DEF(JSMSG_EMPTY_CONSEQUENT, 290, 0, JSEXN_SYNTAXERR, "mistyped ; after
MSG_DEF(JSMSG_NOT_ITERABLE, 291, 1, JSEXN_TYPEERR, "{0} is not iterable")
MSG_DEF(JSMSG_QUERY_LINE_WITHOUT_URL, 292, 0, JSEXN_TYPEERR, "findScripts query object has 'line' property, but no 'url' property")
MSG_DEF(JSMSG_QUERY_INNERMOST_WITHOUT_LINE_URL, 293, 0, JSEXN_TYPEERR, "findScripts query object has 'innermost' property without both 'url' and 'line' properties")
MSG_DEF(JSMSG_DEBUG_VARIABLE_NOT_FOUND, 294, 0, JSEXN_TYPEERR, "variable not found in environment")

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

@ -38,7 +38,7 @@ wrap(JSContext *cx, JSObject *toWrap, JSObject *target)
static JSObject *
PreWrap(JSContext *cx, JSObject *scope, JSObject *obj, unsigned flags)
{
JS_GC(cx);
JS_GC(JS_GetRuntime(cx));
return obj;
}

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

@ -29,14 +29,14 @@ BEGIN_TEST(testConservativeGC)
tmp = JSVAL_NULL;
JS_GC(cx);
JS_GC(rt);
EVAL("var a = [];\n"
"for (var i = 0; i != 10000; ++i) {\n"
"a.push(i + 0.1, [1, 2], String(Math.sqrt(i)), {a: i});\n"
"}", &tmp);
JS_GC(cx);
JS_GC(rt);
checkObjectFields((JSObject *)objCopy, JSVAL_TO_OBJECT(v2));
CHECK(!memcmp(&strCopy, JSVAL_TO_STRING(v3), sizeof(strCopy)));
@ -69,7 +69,7 @@ BEGIN_TEST(testDerivedValues)
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 1000; j++)
JS_NewStringCopyZ(cx, "as I pondered weak and weary");
JS_GC(cx);
JS_GC(rt);
}
CHECK(!memcmp(ch, expected, sizeof(expected)));

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

@ -39,7 +39,7 @@ BEGIN_TEST(testExternalStrings)
// clear that newborn root
JS_NewUCStringCopyN(cx, arr, arrlen);
JS_GC(cx);
JS_GC(rt);
// a generous fudge factor to account for strings rooted by conservative gc
const unsigned epsilon = 10;

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

@ -37,7 +37,7 @@ BEGIN_TEST(testGCOutOfMemory)
CHECK(!ok);
CHECK(!JS_IsExceptionPending(cx));
CHECK_EQUAL(errorCount, 1);
JS_GC(cx);
JS_GC(rt);
EVAL("(function() {"
" var array = [];"
" for (var i = max >> 2; i != 0;) {"

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

@ -36,7 +36,7 @@ BEGIN_TEST(testInternAcrossGC)
sw.strOk = false;
CHECK(sw.str);
JS_SetFinalizeCallback(rt, FinalizeCallback);
JS_GC(cx);
JS_GC(rt);
CHECK(sw.strOk);
return true;
}

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

@ -19,7 +19,7 @@ struct ScriptObjectFixture : public JSAPITest {
{
CHECK(script);
JS_GC(cx);
JS_GC(rt);
/* After a garbage collection, the script should still work. */
jsval result;

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

@ -11,7 +11,7 @@ static JSTrapStatus
EmptyTrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
jsval closure)
{
JS_GC(cx);
JS_GC(JS_GetRuntime(cx));
if (JSVAL_IS_STRING(closure))
++emptyTrapCallCount;
return JSTRAP_CONTINUE;
@ -59,7 +59,7 @@ BEGIN_TEST(testTrap_gc)
JS_SetTrap(cx, script, line2, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
JS_SetTrap(cx, script, line6, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
JS_GC(cx);
JS_GC(rt);
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
}
@ -68,7 +68,7 @@ BEGIN_TEST(testTrap_gc)
CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
CHECK_EQUAL(emptyTrapCallCount, 11);
JS_GC(cx);
JS_GC(rt);
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));

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

@ -202,7 +202,7 @@ BEGIN_TEST(testXDR_bug506491)
CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
// try to break the Block object that is the parent of f
JS_GC(cx);
JS_GC(rt);
// confirm
EVAL("f() === 'ok';\n", v2.addr());

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

@ -1137,25 +1137,19 @@ JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback)
JS_PUBLIC_API(JSContext *)
JS_NewContext(JSRuntime *rt, size_t stackChunkSize)
{
return js_NewContext(rt, stackChunkSize);
return NewContext(rt, stackChunkSize);
}
JS_PUBLIC_API(void)
JS_DestroyContext(JSContext *cx)
{
js_DestroyContext(cx, JSDCM_FORCE_GC);
DestroyContext(cx, DCM_FORCE_GC);
}
JS_PUBLIC_API(void)
JS_DestroyContextNoGC(JSContext *cx)
{
js_DestroyContext(cx, JSDCM_NO_GC);
}
JS_PUBLIC_API(void)
JS_DestroyContextMaybeGC(JSContext *cx)
{
js_DestroyContext(cx, JSDCM_MAYBE_GC);
DestroyContext(cx, DCM_NO_GC);
}
JS_PUBLIC_API(void *)
@ -2860,11 +2854,11 @@ JS_IsGCMarkingTracer(JSTracer *trc)
}
JS_PUBLIC_API(void)
JS_GC(JSContext *cx)
JS_GC(JSRuntime *rt)
{
AssertNoGC(cx);
PrepareForFullGC(cx->runtime);
GC(cx, GC_NORMAL, gcreason::API);
AssertNoGC(rt);
PrepareForFullGC(rt);
GC(rt, GC_NORMAL, gcreason::API);
}
JS_PUBLIC_API(void)
@ -2961,11 +2955,6 @@ JS_GetGCParameterForThread(JSContext *cx, JSGCParamKey key)
return 0;
}
JS_PUBLIC_API(void)
JS_FlushCaches(JSContext *cx)
{
}
JS_PUBLIC_API(JSString *)
JS_NewExternalString(JSContext *cx, const jschar *chars, size_t length,
const JSStringFinalizer *fin)

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

@ -2568,9 +2568,6 @@ JS_DestroyContext(JSContext *cx);
extern JS_PUBLIC_API(void)
JS_DestroyContextNoGC(JSContext *cx);
extern JS_PUBLIC_API(void)
JS_DestroyContextMaybeGC(JSContext *cx);
extern JS_PUBLIC_API(void *)
JS_GetContextPrivate(JSContext *cx);
@ -3158,12 +3155,6 @@ JS_DumpNamedRoots(JSRuntime *rt,
* in the return value. To keep on mapping, return JS_MAP_GCROOT_NEXT. These
* constants are flags; you can OR them together.
*
* This function acquires and releases rt's GC lock around the mapping of the
* roots table, so the map function should run to completion in as few cycles
* as possible. Of course, map cannot call JS_GC, JS_MaybeGC, JS_BeginRequest,
* or any JS API entry point that acquires locks, without double-tripping or
* deadlocking on the GC lock.
*
* The JSGCRootType parameter indicates whether rp is a pointer to a Value
* (which is obtained by '(Value *)rp') or a pointer to a GC-thing pointer
* (which is obtained by '(void **)rp').
@ -3260,6 +3251,9 @@ struct JSTracer {
const void *debugPrintArg;
size_t debugPrintIndex;
JSBool eagerlyTraceWeakMaps;
#ifdef DEBUG
void *realLocation;
#endif
};
/*
@ -3300,6 +3294,22 @@ JS_CallTracer(JSTracer *trc, void *thing, JSGCTraceKind kind);
JS_END_MACRO
#endif
/*
* Sets the real location for a marked reference, when passing the address
* directly is not feasable.
*/
#ifdef DEBUG
# define JS_SET_TRACING_LOCATION(trc, location) \
JS_BEGIN_MACRO \
(trc)->realLocation = (location); \
JS_END_MACRO
#else
# define JS_SET_TRACING_LOCATION(trc, location) \
JS_BEGIN_MACRO \
JS_END_MACRO
#endif
/*
* Convenience macro to describe the argument of JS_CallTracer using C string
* and index.
@ -3395,10 +3405,10 @@ JS_DumpHeap(JSRuntime *rt, FILE *fp, void* startThing, JSGCTraceKind kind,
* Garbage collector API.
*/
extern JS_PUBLIC_API(void)
JS_GC(JSContext *cx);
JS_GC(JSRuntime *rt);
extern JS_PUBLIC_API(void)
JS_CompartmentGC(JSContext *cx, JSCompartment *comp);
JS_CompartmentGC(JSRuntime *rt, JSCompartment *comp);
extern JS_PUBLIC_API(void)
JS_MaybeGC(JSContext *cx);
@ -3473,15 +3483,6 @@ JS_SetGCParameterForThread(JSContext *cx, JSGCParamKey key, uint32_t value);
extern JS_PUBLIC_API(uint32_t)
JS_GetGCParameterForThread(JSContext *cx, JSGCParamKey key);
/*
* Flush the code cache for the current thread. The operation might be
* delayed if the cache cannot be flushed currently because native
* code is currently executing.
*/
extern JS_PUBLIC_API(void)
JS_FlushCaches(JSContext *cx);
/*
* Create a new JSString whose chars member refers to external memory, i.e.,
* memory requiring application-specific finalization.

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

@ -502,8 +502,10 @@ js_DumpAtoms(JSContext *cx, FILE *fp)
JS_STATIC_ASSERT(TEMP_SIZE_START >= sizeof(JSHashTable));
namespace js {
void
js_InitAtomMap(JSContext *cx, AtomIndexMap *indices, JSAtom **atoms)
InitAtomMap(JSContext *cx, AtomIndexMap *indices, HeapPtrAtom *atoms)
{
if (indices->isMap()) {
typedef AtomIndexMap::WordMap WordMap;
@ -512,7 +514,7 @@ js_InitAtomMap(JSContext *cx, AtomIndexMap *indices, JSAtom **atoms)
JSAtom *atom = r.front().key;
jsatomid index = r.front().value;
JS_ASSERT(index < indices->count());
atoms[index] = atom;
atoms[index].init(atom);
}
} else {
for (const AtomIndexMap::InlineElem *it = indices->asInline(), *end = indices->inlineEnd();
@ -521,13 +523,11 @@ js_InitAtomMap(JSContext *cx, AtomIndexMap *indices, JSAtom **atoms)
if (!atom)
continue;
JS_ASSERT(it->value < indices->count());
atoms[it->value] = atom;
atoms[it->value].init(atom);
}
}
}
namespace js {
bool
IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp)
{

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

@ -470,15 +470,15 @@ inline bool
js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
jsid *idp, js::Value *vp);
namespace js {
/*
* For all unmapped atoms recorded in al, add a mapping from the atom's index
* to its address. map->length must already be set to the number of atoms in
* the list and map->vector must point to pre-allocated memory.
*/
extern void
js_InitAtomMap(JSContext *cx, js::AtomIndexMap *indices, JSAtom **atoms);
namespace js {
InitAtomMap(JSContext *cx, AtomIndexMap *indices, HeapPtrAtom *atoms);
template<XDRMode mode>
bool

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

@ -169,7 +169,7 @@ js_GetCurrentScript(JSContext *cx)
}
JSContext *
js_NewContext(JSRuntime *rt, size_t stackChunkSize)
js::NewContext(JSRuntime *rt, size_t stackChunkSize)
{
JS_AbortIfWrongThread(rt);
@ -198,7 +198,7 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
* keywords, numbers, and strings. If one of these steps should fail, the
* runtime will be left in a partially initialized state, with zeroes and
* nulls stored in the default-initialized remainder of the struct. We'll
* clean the runtime up under js_DestroyContext, because cx will be "last"
* clean the runtime up under DestroyContext, because cx will be "last"
* as well as "first".
*/
if (first) {
@ -213,14 +213,14 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
JS_EndRequest(cx);
#endif
if (!ok) {
js_DestroyContext(cx, JSDCM_NEW_FAILED);
DestroyContext(cx, DCM_NEW_FAILED);
return NULL;
}
}
JSContextCallback cxCallback = rt->cxCallback;
if (cxCallback && !cxCallback(cx, JSCONTEXT_NEW)) {
js_DestroyContext(cx, JSDCM_NEW_FAILED);
DestroyContext(cx, DCM_NEW_FAILED);
return NULL;
}
@ -228,7 +228,7 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
}
void
js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
js::DestroyContext(JSContext *cx, DestroyContextMode mode)
{
JSRuntime *rt = cx->runtime;
JS_AbortIfWrongThread(rt);
@ -239,14 +239,13 @@ js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
JS_ASSERT(cx->outstandingRequests == 0);
#endif
if (mode != JSDCM_NEW_FAILED) {
if (mode != DCM_NEW_FAILED) {
if (JSContextCallback cxCallback = rt->cxCallback) {
/*
* JSCONTEXT_DESTROY callback is not allowed to fail and must
* return true.
*/
DebugOnly<JSBool> callbackStatus = cxCallback(cx, JSCONTEXT_DESTROY);
JS_ASSERT(callbackStatus);
JS_ALWAYS_TRUE(cxCallback(cx, JSCONTEXT_DESTROY));
}
}
@ -255,13 +254,6 @@ js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
if (last) {
JS_ASSERT(!rt->gcRunning);
#ifdef JS_THREADSAFE
{
AutoLockGC lock(rt);
rt->gcHelperThread.waitBackgroundSweepEnd();
}
#endif
/*
* Dump remaining type inference results first. This printing
* depends on atoms still existing.
@ -270,30 +262,20 @@ js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
c->types.print(cx, false);
/* Unpin all common atoms before final GC. */
FinishCommonAtoms(cx->runtime);
FinishCommonAtoms(rt);
/* Clear debugging state to remove GC roots. */
for (CompartmentsIter c(rt); !c.done(); c.next())
c->clearTraps(cx);
c->clearTraps(rt->defaultFreeOp());
JS_ClearAllWatchPoints(cx);
PrepareForFullGC(rt);
GC(cx, GC_NORMAL, gcreason::LAST_CONTEXT);
} else if (mode == JSDCM_FORCE_GC) {
GC(rt, GC_NORMAL, gcreason::LAST_CONTEXT);
} else if (mode == DCM_FORCE_GC) {
JS_ASSERT(!rt->gcRunning);
PrepareForFullGC(rt);
GC(cx, GC_NORMAL, gcreason::DESTROY_CONTEXT);
} else if (mode == JSDCM_MAYBE_GC) {
JS_ASSERT(!rt->gcRunning);
JS_MaybeGC(cx);
GC(rt, GC_NORMAL, gcreason::DESTROY_CONTEXT);
}
#ifdef JS_THREADSAFE
{
AutoLockGC lock(rt);
rt->gcHelperThread.waitBackgroundSweepEnd();
}
#endif
Foreground::delete_(cx);
}
@ -885,30 +867,14 @@ js_InvokeOperationCallback(JSContext *cx)
JS_ATOMIC_SET(&rt->interrupt, 0);
if (rt->gcIsNeeded)
GCSlice(cx, GC_NORMAL, rt->gcTriggerReason);
#ifdef JS_THREADSAFE
/*
* We automatically yield the current context every time the operation
* callback is hit since we might be called as a result of an impending
* GC on another thread, which would deadlock if we do not yield.
* Operation callbacks are supposed to happen rarely (seconds, not
* milliseconds) so it is acceptable to yield at every callback.
*
* As the GC can be canceled before it does any request checks we yield
* even if rt->gcIsNeeded was true above. See bug 590533.
*/
JS_YieldRequest(cx);
#endif
JSOperationCallback cb = cx->operationCallback;
GCSlice(rt, GC_NORMAL, rt->gcTriggerReason);
/*
* Important: Additional callbacks can occur inside the callback handler
* if it re-enters the JS engine. The embedding must ensure that the
* callback is disconnected before attempting such re-entry.
*/
JSOperationCallback cb = cx->operationCallback;
return !cb || cb(cx);
}
@ -990,9 +956,6 @@ JSContext::JSContext(JSRuntime *rt)
functionCallback(NULL),
#endif
enumerators(NULL),
#ifdef JS_THREADSAFE
gcBackgroundFree(NULL),
#endif
activeCompilations(0)
#ifdef DEBUG
, stackIterAssertionEnabled(true)

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

@ -146,15 +146,8 @@ struct ConservativeGCData
uintptr_t words[JS_HOWMANY(sizeof(jmp_buf), sizeof(uintptr_t))];
} registerSnapshot;
/*
* Cycle collector uses this to communicate that the native stack of the
* GC thread should be scanned only if the thread have more than the given
* threshold of requests.
*/
unsigned requestThreshold;
ConservativeGCData()
: nativeStackTop(NULL), requestThreshold(0)
: nativeStackTop(NULL)
{}
~ConservativeGCData() {
@ -183,6 +176,13 @@ struct ConservativeGCData
}
};
/*
* A FreeOp can do one thing: free memory. For convenience, it has delete_
* convenience methods that also call destructors.
*
* FreeOp is passed to finalizers and other sweep-phase hooks so that we do not
* need to pass a JSContext to those hooks.
*/
class FreeOp : public JSFreeOp {
bool shouldFreeLater_;
bool onBackgroundThread_;
@ -215,7 +215,7 @@ class FreeOp : public JSFreeOp {
/*
* Check that JSFreeOp is the first base class for FreeOp and we can
* reinterpret a pointer to JSFreeOp as a pointer to FreeOp without
* any offset adjustments. JSClass::freeOp <-> Class::freeOp depends
* any offset adjustments. JSClass::finalize <-> Class::finalize depends
* on this.
*/
JS_STATIC_ASSERT(offsetof(FreeOp, shouldFreeLater_) == sizeof(JSFreeOp));
@ -1119,14 +1119,6 @@ struct JSContext : js::ContextFriendFields
genStack.popBack();
}
#ifdef JS_THREADSAFE
/*
* When non-null JSContext::free_ delegates the job to the background
* thread.
*/
js::GCHelperThread *gcBackgroundFree;
#endif
inline void* malloc_(size_t bytes) {
return runtime->malloc_(bytes, this);
}
@ -1150,12 +1142,6 @@ struct JSContext : js::ContextFriendFields
}
inline void free_(void* p) {
#ifdef JS_THREADSAFE
if (gcBackgroundFree) {
gcBackgroundFree->freeLater(p);
return;
}
#endif
runtime->free_(p);
}
@ -1461,24 +1447,23 @@ public:
}
};
} /* namespace js */
/*
* Create and destroy functions for JSContext, which is manually allocated
* and exclusively owned.
*/
extern JSContext *
js_NewContext(JSRuntime *rt, size_t stackChunkSize);
NewContext(JSRuntime *rt, size_t stackChunkSize);
typedef enum JSDestroyContextMode {
JSDCM_NO_GC,
JSDCM_MAYBE_GC,
JSDCM_FORCE_GC,
JSDCM_NEW_FAILED
} JSDestroyContextMode;
enum DestroyContextMode {
DCM_NO_GC,
DCM_FORCE_GC,
DCM_NEW_FAILED
};
extern void
js_DestroyContext(JSContext *cx, JSDestroyContextMode mode);
DestroyContext(JSContext *cx, DestroyContextMode mode);
} /* namespace js */
#ifdef va_start
extern JSBool

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

@ -390,7 +390,7 @@ CallSetter(JSContext *cx, JSObject *obj, jsid id, StrictPropertyOp op, unsigned
return CallJSPropertyOpSetter(cx, op, obj, id, strict, vp);
}
static inline JSAtom **
static inline HeapPtrAtom *
FrameAtomBase(JSContext *cx, js::StackFrame *fp)
{
return fp->script()->atoms;

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

@ -746,22 +746,22 @@ JSCompartment::removeDebuggee(FreeOp *fop,
}
void
JSCompartment::clearBreakpointsIn(JSContext *cx, js::Debugger *dbg, JSObject *handler)
JSCompartment::clearBreakpointsIn(FreeOp *fop, js::Debugger *dbg, JSObject *handler)
{
for (gc::CellIter i(this, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
if (script->hasAnyBreakpointsOrStepMode())
script->clearBreakpointsIn(cx, dbg, handler);
script->clearBreakpointsIn(fop, dbg, handler);
}
}
void
JSCompartment::clearTraps(JSContext *cx)
JSCompartment::clearTraps(FreeOp *fop)
{
for (gc::CellIter i(this, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
if (script->hasAnyBreakpointsOrStepMode())
script->clearTraps(cx->runtime->defaultFreeOp());
script->clearTraps(fop);
}
}

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

@ -455,8 +455,8 @@ struct JSCompartment
js::GlobalObjectSet::Enum *debuggeesEnum = NULL);
bool setDebugModeFromC(JSContext *cx, bool b);
void clearBreakpointsIn(JSContext *cx, js::Debugger *dbg, JSObject *handler);
void clearTraps(JSContext *cx);
void clearBreakpointsIn(js::FreeOp *fop, js::Debugger *dbg, JSObject *handler);
void clearTraps(js::FreeOp *fop);
private:
void sweepBreakpoints(js::FreeOp *fop);

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

@ -231,7 +231,7 @@ JS_ClearScriptTraps(JSContext *cx, JSScript *script)
JS_PUBLIC_API(void)
JS_ClearAllTrapsForCompartment(JSContext *cx)
{
cx->compartment->clearTraps(cx);
cx->compartment->clearTraps(cx->runtime->defaultFreeOp());
}
JS_PUBLIC_API(JSBool)

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