merge m-c to fx-team

This commit is contained in:
Rob Campbell 2011-11-03 09:29:07 -03:00
commit 182625069e
160 changed files with 4229 additions and 2785 deletions

View File

@ -369,6 +369,14 @@ body[dir=rtl] #restorePreviousSession::before {
bottom: 2%;
}
#syncLinksContainer {
padding-top: 1em;
}
.sync-link {
padding: 1em;
}
@media all and (max-height: 370px) {
#bottomSection {
visibility: hidden;

View File

@ -102,6 +102,10 @@
<div id="aboutMozilla">
<a href="http://www.mozilla.com/about/">&abouthome.aboutMozilla;</a>
</div>
<div id="syncLinksContainer">
<a href="javascript:void(0);" class="sync-link" id="setupSyncLink">&abouthome.syncSetup.label;</a>
<a href="javascript:void(0);" class="sync-link" id="pairDeviceLink">&abouthome.pairDevice.label;</a>
</div>
</div>
</body>
</html>

View File

@ -211,6 +211,24 @@ let gSyncUI = {
this.clearError(title);
},
// Set visibility of "Setup Sync" link
showSetupSyncAboutHome: function SUI_showSetupSyncAboutHome(toShow) {
let browsers = gBrowser.browsers;
for (let i = 0; i < browsers.length; i++) {
let b = browsers[i];
if ("about:home" == b.currentURI.spec) {
b.contentDocument.getElementById("setupSyncLink").hidden = !toShow;
}
}
},
onSetupComplete: function SUI_onSetupComplete() {
// Remove "setup sync" link in about:home if it is open.
this.showSetupSyncAboutHome(false);
onLoginFinish();
},
onLoginError: function SUI_onLoginError() {
// if login fails, any other notifications are essentially moot
Weave.Notifications.removeAll();
@ -255,6 +273,8 @@ let gSyncUI = {
onStartOver: function SUI_onStartOver() {
this.clearError();
// Make "setup sync" link visible in about:home if it is open.
this.showSetupSyncAboutHome(true);
},
onQuotaNotice: function onQuotaNotice(subject, data) {
@ -291,16 +311,40 @@ let gSyncUI = {
//XXXzpao should be part of syncCommon.js - which we might want to make a module...
// To be fixed in a followup (bug 583366)
openSetup: function SUI_openSetup() {
/**
* Invoke the Sync setup wizard.
*
* @param wizardType
* Indicates type of wizard to launch:
* null -- regular set up wizard
* "pair" -- pair a device first
* "reset" -- reset sync
*/
openSetup: function SUI_openSetup(wizardType) {
let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
if (win)
win.focus();
else {
window.openDialog("chrome://browser/content/syncSetup.xul",
"weaveSetup", "centerscreen,chrome,resizable=no");
"weaveSetup", "centerscreen,chrome,resizable=no",
wizardType);
}
},
openAddDevice: function () {
if (!Weave.Utils.ensureMPUnlocked())
return;
let win = Services.wm.getMostRecentWindow("Sync:AddDevice");
if (win)
win.focus();
else
window.openDialog("chrome://browser/content/syncAddDevice.xul",
"syncAddDevice", "centerscreen,chrome,resizable=no");
},
openQuotaDialog: function SUI_openQuotaDialog() {
let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
if (win)
@ -462,7 +506,7 @@ let gSyncUI = {
this.onQuotaNotice();
break;
case "weave:service:setup-complete":
this.onLoginFinish();
this.onSetupComplete();
break;
case "weave:service:login:start":
this.onActivityStart();

View File

@ -2675,6 +2675,10 @@ function BrowserOnAboutPageLoad(document) {
getService(Components.interfaces.nsISessionStore);
if (!ss.canRestoreLastSession)
document.getElementById("sessionRestoreContainer").hidden = true;
// Sync-related links
if (Services.prefs.prefHasUserValue("services.sync.username")) {
document.getElementById("setupSyncLink").hidden = true;
}
}
}
@ -2683,7 +2687,9 @@ function BrowserOnAboutPageLoad(document) {
*/
function BrowserOnClick(event) {
// Don't trust synthetic events
if (!event.isTrusted || event.target.localName != "button")
if (!event.isTrusted ||
(event.target.localName != "button" &&
event.target.className != "sync-link"))
return;
var ot = event.originalTarget;
@ -2813,6 +2819,16 @@ function BrowserOnClick(event) {
ss.restoreLastSession();
errorDoc.getElementById("sessionRestoreContainer").hidden = true;
}
else if (ot == errorDoc.getElementById("pairDeviceLink")) {
if (Services.prefs.prefHasUserValue("services.sync.username")) {
gSyncUI.openAddDevice();
} else {
gSyncUI.openSetup("pair");
}
}
else if (ot == errorDoc.getElementById("setupSyncLink")) {
gSyncUI.openSetup(null);
}
}
}

View File

@ -44,12 +44,14 @@ let gProgressBar;
let gCounter = 0;
function onLoad(event) {
Services.obs.addObserver(increaseProgressBar, "weave:engine:sync:finish", false);
Services.obs.addObserver(increaseProgressBar, "weave:engine:sync:error", false);
Services.obs.addObserver(onEngineSync, "weave:engine:sync:finish", false);
Services.obs.addObserver(onEngineSync, "weave:engine:sync:error", false);
Services.obs.addObserver(onServiceSync, "weave:service:sync:finish", false);
Services.obs.addObserver(onServiceSync, "weave:service:sync:error", false);
gProgressBar = document.getElementById('uploadProgressBar');
if (Services.prefs.getPrefType("services.sync.firstSync") != Ci.nsIPrefBranch.PREF_INVALID) {
gProgressBar.max = Weave.Engines.getEnabled().length;
gProgressBar.style.display = "inline";
}
else {
@ -58,15 +60,46 @@ function onLoad(event) {
}
function onUnload(event) {
Services.obs.removeObserver(increaseProgressBar, "weave:engine:sync:finish");
Services.obs.removeObserver(increaseProgressBar, "weave:engine:sync:error");
cleanUpObservers();
}
function increaseProgressBar(){
function cleanUpObservers() {
try {
Services.obs.removeObserver(onEngineSync, "weave:engine:sync:finish", false);
Services.obs.removeObserver(onEngineSync, "weave:engine:sync:error", false);
Services.obs.removeObserver(onServiceSync, "weave:service:sync:finish", false);
Services.obs.removeObserver(onServiceSync, "weave:service:sync:error", false);
}
catch (e) {
// may be double called by unload & exit. Ignore.
}
}
function onEngineSync(subject, topic, data) {
// The Clients engine syncs first. At this point we don't necessarily know
// yet how many engines will be enabled, so we'll ignore the Clients engine
// and evaluate how many engines are enabled when the first "real" engine
// syncs.
if (data == "clients") {
return;
}
if (!gCounter &&
Services.prefs.getPrefType("services.sync.firstSync") != Ci.nsIPrefBranch.PREF_INVALID) {
gProgressBar.max = Weave.Engines.getEnabled().length;
}
gCounter += 1;
gProgressBar.setAttribute("value", gCounter);
}
function onServiceSync(subject, topic, data) {
// To address the case where 0 engines are synced, we will fill the
// progress bar so the user knows that the sync has finished.
gProgressBar.setAttribute("value", gProgressBar.max);
cleanUpObservers();
}
function closeTab() {
window.close();
}

View File

@ -10,6 +10,9 @@ registerCleanupFunction(function() {
try {
Services.prefs.clearUserPref("network.cookie.lifetimePolicy");
} catch (ex) {}
try {
Services.prefs.clearUserPref("services.sync.username");
} catch (ex) {}
});
let gTests = [
@ -114,6 +117,116 @@ let gTests = [
}
},
{
desc: "Check sync links visibility before and after Sync setup",
setup: function ()
{
try {
Services.prefs.clearUserPref("services.sync.username");
} catch (ex) {}
Services.obs.notifyObservers(null, "weave:service:ready", null);
},
run: function ()
{
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
let pairLink = doc.getElementById("pairDeviceLink");
let setupLink = doc.getElementById("setupSyncLink");
ok(pairLink, "Found 'Pair Device' link");
ok(setupLink, "Found 'Set Up Sync' link");
ok(!pairLink.hidden, "'Pair' link is visible before setup");
ok(!setupLink.hidden, "'Set Up' link is visible before setup");
Services.obs.notifyObservers(null, "weave:service:setup-complete", null);
executeSoon(function () {
setupLink = doc.getElementById("setupSyncLink");
ok(setupLink.hidden, "'Set Up' link is hidden after setup");
ok(!pairLink.hidden, "'Pair' link is visible after setup");
executeSoon(runNextTest);
});
}
},
{
desc: "Check sync links visibility before and after Sync unlink",
setup: function ()
{
Services.prefs.setCharPref("services.sync.username", "someuser@domain.com");
Services.obs.notifyObservers(null, "weave:service:ready", null);
},
run: function ()
{
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
let pairLink = doc.getElementById("pairDeviceLink");
let setupLink = doc.getElementById("setupSyncLink");
ok(!pairLink.hidden, "'Pair' link is visible before unlink");
ok(setupLink.hidden, "'Set Up' link is hidden before unlink");
Services.obs.notifyObservers(null, "weave:service:start-over", null);
executeSoon(function () {
setupLink = doc.getElementById("setupSyncLink");
ok(!setupLink.hidden, "'Set Up' link is visible after unlink");
ok(!pairLink.hidden, "'Pair' link is visible after unlink");
executeSoon(runNextTest);
});
}
},
{
desc: "Check Pair Device link opens correct dialog with Sync account ",
setup: function ()
{
Services.prefs.setCharPref("services.sync.username", "someuser@domain.com");
Services.obs.notifyObservers(null, "weave:service:ready", null);
},
run: function ()
{
expectDialogWindow("Sync:AddDevice");
let browser = gBrowser.selectedTab.linkedBrowser;
let button = browser.contentDocument.getElementById("pairDeviceLink");
EventUtils.sendMouseEvent({type: "click"}, button, browser.contentWindow);
}
},
{
desc: "Check Pair Device link opens correct dialog without Sync account",
setup: function ()
{
try {
Services.prefs.clearUserPref("services.sync.username");
} catch (ex) {}
Services.obs.notifyObservers(null, "weave:service:ready", null);
},
run: function ()
{
expectDialogWindow("Weave:AccountSetup");
let browser = gBrowser.selectedTab.linkedBrowser;
let button = browser.contentDocument.getElementById("pairDeviceLink");
EventUtils.sendMouseEvent({type: "click"}, button, browser.contentWindow);
}
},
{
desc: "Check Sync Setup link opens correct dialog (without Sync account)",
setup: function ()
{
try {
Services.prefs.clearUserPref("services.sync.username");
} catch (ex) {}
Services.obs.notifyObservers(null, "weave:service:ready", null);
},
run: function ()
{
expectDialogWindow("Weave:AccountSetup");
let browser = gBrowser.selectedTab.linkedBrowser;
let button = browser.contentDocument.getElementById("setupSyncLink");
EventUtils.sendMouseEvent({type: "click"}, button, browser.contentWindow);
}
},
];
function test()
@ -159,6 +272,22 @@ function runNextTest()
}
}
function expectDialogWindow(expectedDialog) {
Services.ww.registerNotification(function onWindow(subject, topic) {
let win = subject.QueryInterface(Components.interfaces.nsIDOMWindow);
win.addEventListener("load", function onLoad() {
win.removeEventListener("load", onLoad, false);
let wintype = win.document.documentElement.getAttribute("windowtype");
if (topic == "domwindowopened" && wintype == expectedDialog) {
Services.ww.unregisterNotification(onWindow);
// Clean up dialog.
win.close();
executeSoon(runNextTest);
}
}, false);
});
}
function getStorage()
{
let aboutHomeURI = Services.io.newURI("moz-safe-about:home", null, null);

View File

@ -1,12 +1,16 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.reset();
/**
* TestCase for bug 564387
* <https://bugzilla.mozilla.org/show_bug.cgi?id=564387>
*/
function test() {
waitForExplicitFinish();
var fileName;
gBrowser.loadURI("http://mochi.test:8888/browser/browser/base/content/test/bug564387.html");
@ -35,17 +39,22 @@ function test() {
// Create the folder the video will be saved into.
var destDir = createTemporarySaveDirectory();
var destFile = destDir.clone();
mockFilePickerSettings.destDir = destDir;
mockFilePickerSettings.filterIndex = 1; // kSaveAsType_URL
mockFilePickerRegisterer.register();
MockFilePicker.displayDirectory = destDir;
MockFilePicker.showCallback = function(fp) {
fileName = fp.defaultString;
destFile.append (fileName);
MockFilePicker.returnFiles = [destFile];
MockFilePicker.filterIndex = 1; // kSaveAsType_URL
};
mockTransferCallback = onTransferComplete;
mockTransferRegisterer.register();
registerCleanupFunction(function () {
mockTransferRegisterer.unregister();
mockFilePickerRegisterer.unregister();
MockFilePicker.reset();
destDir.remove(true);
});
@ -59,9 +68,6 @@ function test() {
function onTransferComplete(downloadSuccess) {
ok(downloadSuccess, "Video file should have been downloaded successfully");
// Read the name of the saved file.
var fileName = mockFilePickerResults.selectedFile.leafName;
is(fileName, "Bug564387-expectedName.ogv",
"Video file name is correctly retrieved from Content-Disposition http header");
@ -74,11 +80,6 @@ Cc["@mozilla.org/moz/jssubscript-loader;1"]
.loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
this);
Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockFilePicker.js",
this);
function createTemporarySaveDirectory() {
var saveDir = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)

View File

@ -45,7 +45,9 @@ include $(DEPTH)/config/autoconf.mk
MODULE = browserdir
LIBRARY_NAME = browserdir_s
ifdef ENABLE_TESTS
DIRS = tests
endif
FORCE_STATIC_LIB = 1
FORCE_USE_PIC = 1

View File

@ -3209,6 +3209,7 @@ SessionStoreService.prototype = {
shEntry.postData = stream;
}
let childDocIdents = {};
if (aEntry.docIdentifier) {
// If we have a serialized document identifier, try to find an SHEntry
// which matches that doc identifier and adopt that SHEntry's
@ -3216,10 +3217,12 @@ SessionStoreService.prototype = {
// for the document identifier.
let matchingEntry = aDocIdentMap[aEntry.docIdentifier];
if (!matchingEntry) {
aDocIdentMap[aEntry.docIdentifier] = shEntry;
matchingEntry = {shEntry: shEntry, childDocIdents: childDocIdents};
aDocIdentMap[aEntry.docIdentifier] = matchingEntry;
}
else {
shEntry.adoptBFCacheEntry(matchingEntry);
shEntry.adoptBFCacheEntry(matchingEntry.shEntry);
childDocIdents = matchingEntry.childDocIdents;
}
}
@ -3241,8 +3244,24 @@ SessionStoreService.prototype = {
//XXXzpao Wallpaper patch for bug 514751
if (!aEntry.children[i].url)
continue;
// We're getting sessionrestore.js files with a cycle in the
// doc-identifier graph, likely due to bug 698656. (That is, we have
// an entry where doc identifier A is an ancestor of doc identifier B,
// and another entry where doc identifier B is an ancestor of A.)
//
// If we were to respect these doc identifiers, we'd create a cycle in
// the SHEntries themselves, which causes the docshell to loop forever
// when it looks for the root SHEntry.
//
// So as a hack to fix this, we restrict the scope of a doc identifier
// to be a node's siblings and cousins, and pass childDocIdents, not
// aDocIdents, to _deserializeHistoryEntry. That is, we say that two
// SHEntries with the same doc identifier have the same document iff
// they have the same parent or their parents have the same document.
shEntry.AddChild(this._deserializeHistoryEntry(aEntry.children[i], aIdMap,
aDocIdentMap), i);
childDocIdents), i);
}
}

View File

@ -155,6 +155,8 @@ _BROWSER_TEST_FILES = \
browser_662812.js \
browser_665702-state_session.js \
browser_682507.js \
browser_687710.js \
browser_687710_2.js \
browser_694378.js \
$(NULL)

View File

@ -0,0 +1,44 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that sessionrestore handles cycles in the shentry graph properly.
//
// These cycles shouldn't be there in the first place, but they cause hangs
// when they mysteriously appear (bug 687710). Docshell code assumes this
// graph is a tree and tires to walk to the root. But if there's a cycle,
// there is no root, and we loop forever.
let stateBackup = ss.getBrowserState();
let state = {windows:[{tabs:[{entries:[
{
docIdentifier: 1,
url: "http://example.com",
children: [
{
docIdentifier: 2,
url: "http://example.com"
}
]
},
{
docIdentifier: 2,
url: "http://example.com",
children: [
{
docIdentifier: 1,
url: "http://example.com"
}
]
}
]}]}]}
function test() {
registerCleanupFunction(function () {
ss.setBrowserState(stateBackup);
});
/* This test fails by hanging. */
ss.setBrowserState(JSON.stringify(state));
ok(true, "Didn't hang!");
}

View File

@ -0,0 +1,64 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that the fix for bug 687710 isn't too aggressive -- shentries which are
// cousins should be able to share bfcache entries.
let stateBackup = ss.getBrowserState();
let state = {entries:[
{
docIdentifier: 1,
url: "http://example.com?1",
children: [{ docIdentifier: 10,
url: "http://example.com?10" }]
},
{
docIdentifier: 1,
url: "http://example.com?1#a",
children: [{ docIdentifier: 10,
url: "http://example.com?10#aa" }]
}
]};
function test()
{
registerCleanupFunction(function () {
ss.setBrowserState(stateBackup);
});
let tab = gBrowser.addTab("about:blank");
ss.setTabState(tab, JSON.stringify(state));
let history = tab.linkedBrowser.webNavigation.sessionHistory;
is(history.count, 2, "history.count");
for (let i = 0; i < history.count; i++) {
for (let j = 0; j < history.count; j++) {
compareEntries(i, j, history);
}
}
}
function compareEntries(i, j, history)
{
let e1 = history.getEntryAtIndex(i, false)
.QueryInterface(Ci.nsISHEntry)
.QueryInterface(Ci.nsISHContainer);
let e2 = history.getEntryAtIndex(j, false)
.QueryInterface(Ci.nsISHEntry)
.QueryInterface(Ci.nsISHContainer);
ok(e1.sharesDocumentWith(e2),
i + ' should share doc with ' + j);
is(e1.childCount, e2.childCount,
'Child count mismatch (' + i + ', ' + j + ')');
for (let c = 0; c < e1.childCount; c++) {
let c1 = e1.GetChildAt(c);
let c2 = e2.GetChildAt(c);
ok(c1.sharesDocumentWith(c2),
'Cousins should share documents. (' + i + ', ' + j + ', ' + c + ')');
}
}

View File

@ -18,3 +18,6 @@
text in <a/> will be linked to the featured add-ons on addons.mozilla.org
-->
<!ENTITY abouthome.defaultSnippet2.v1 "It's easy to customize your Firefox exactly the way you want it. <a>Choose from thousands of add-ons</a>.">
<!ENTITY abouthome.syncSetup.label "Set Up Sync">
<!ENTITY abouthome.pairDevice.label "Pair a Device">

View File

@ -57,6 +57,8 @@
%define forwardTransitionLength 150ms
%define conditionalForwardWithUrlbar window:not([chromehidden~=toolbar]) :-moz-any(#nav-bar[currentset*="unified-back-forward-button,urlbar-container"][mode=icons], #nav-bar:not([currentset])[mode=icons]) > #unified-back-forward-button
%define conditionalForwardWithUrlbar_small window:not([chromehidden~=toolbar]) :-moz-any(#nav-bar[currentset*="unified-back-forward-button,urlbar-container"][mode=icons][iconsize=small],#nav-bar:not([currentset])[mode=icons][iconsize=small]) > #unified-back-forward-button
%define conditionalForwardWithUrlbarWidth 32
%define conditionalForwardWithUrlbarWidth_small 24
#menubar-items {
-moz-box-orient: vertical; /* for flex hack */
@ -630,18 +632,6 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
opacity: 0;
pointer-events: none;
}
@conditionalForwardWithUrlbar@ > #forward-button[disabled]:-moz-locale-dir(ltr) {
margin-left: -36px;
}
@conditionalForwardWithUrlbar@ > #forward-button[disabled]:-moz-locale-dir(rtl) {
margin-right: -36px;
}
@conditionalForwardWithUrlbar_small@ > #forward-button[disabled]:-moz-locale-dir(ltr) {
margin-left: -28px;
}
@conditionalForwardWithUrlbar_small@ > #forward-button[disabled]:-moz-locale-dir(rtl) {
margin-right: -28px;
}
#reload-button {
list-style-image: url("moz-icon://stock/gtk-refresh?size=toolbar");
@ -965,6 +955,40 @@ toolbar[iconsize="small"] #feed-button {
-moz-box-align: stretch;
}
@conditionalForwardWithUrlbar@ + #urlbar-container {
-moz-padding-start: @conditionalForwardWithUrlbarWidth@px;
-moz-margin-start: -@conditionalForwardWithUrlbarWidth@px;
position: relative;
pointer-events: none;
}
@conditionalForwardWithUrlbar_small@ + #urlbar-container {
-moz-padding-start: @conditionalForwardWithUrlbarWidth_small@px;
-moz-margin-start: -@conditionalForwardWithUrlbarWidth_small@px;
}
@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar {
pointer-events: all;
}
@conditionalForwardWithUrlbar@:not([switchingtabs]) + #urlbar-container > #urlbar {
-moz-transition: margin-left @forwardTransitionLength@ ease-out,
margin-right @forwardTransitionLength@ ease-out;
}
@conditionalForwardWithUrlbar@[forwarddisabled] + #urlbar-container > #urlbar:-moz-locale-dir(ltr) {
margin-left: -@conditionalForwardWithUrlbarWidth@px;
}
@conditionalForwardWithUrlbar@[forwarddisabled] + #urlbar-container > #urlbar:-moz-locale-dir(rtl) {
margin-right: -@conditionalForwardWithUrlbarWidth@px;
}
@conditionalForwardWithUrlbar_small@[forwarddisabled] + #urlbar-container > #urlbar:-moz-locale-dir(ltr) {
margin-left: -@conditionalForwardWithUrlbarWidth_small@px;
}
@conditionalForwardWithUrlbar_small@[forwarddisabled] + #urlbar-container > #urlbar:-moz-locale-dir(rtl) {
margin-right: -@conditionalForwardWithUrlbarWidth_small@px;
}
#urlbar-icons {
-moz-box-align: center;
}

View File

@ -743,13 +743,13 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
self.haveDumpedScreen = True;
# Need to figure out what tool and whether it write to a file or stdout
if UNIXISH:
if self.UNIXISH:
utility = [os.path.join(utilityPath, "screentopng")]
imgoutput = 'stdout'
elif IS_MAC:
elif self.IS_MAC:
utility = ['/usr/sbin/screencapture', '-C', '-x', '-t', 'png']
imgoutput = 'file'
elif IS_WIN32:
elif self.IS_WIN32:
self.log.info("If you fixed bug 589668, you'd get a screenshot here")
return

View File

@ -8359,32 +8359,15 @@ nsIDocument::SizeOf() const
return size;
}
class nsDispatchFullScreenChange : public nsRunnable
static void
DispatchFullScreenChange(nsINode* aTarget)
{
public:
nsDispatchFullScreenChange(nsIDocument *aDoc, nsINode* aElement)
: mDoc(aDoc),
mTarget(aElement ? aElement : aDoc) {}
NS_IMETHOD Run()
{
nsContentUtils::DispatchTrustedEvent(mDoc,
mTarget,
NS_LITERAL_STRING("mozfullscreenchange"),
true,
false);
return NS_OK;
}
nsCOMPtr<nsIDocument> mDoc;
nsCOMPtr<nsISupports> mTarget;
};
static void DispatchFullScreenChange(nsIDocument* aDocument, Element* aElement)
{
nsCOMPtr<nsIRunnable> event(
new nsDispatchFullScreenChange(aDocument, aElement));
NS_DispatchToCurrentThread(event);
nsRefPtr<nsPLDOMEvent> e =
new nsPLDOMEvent(aTarget,
NS_LITERAL_STRING("mozfullscreenchange"),
true,
false);
e->PostDOMEvent();
}
bool
@ -8470,7 +8453,7 @@ nsDocument::CancelFullScreen()
nsCOMPtr<nsIDocument> doc(do_QueryReferent(sFullScreenDoc));
while (doc != nsnull) {
if (::SetFullScreenState(doc, nsnull, false)) {
DispatchFullScreenChange(doc, nsnull);
DispatchFullScreenChange(doc);
}
doc = doc->GetParentDocument();
}
@ -8523,6 +8506,14 @@ void
nsDocument::RequestFullScreen(Element* aElement)
{
if (!aElement || !nsContentUtils::IsFullScreenApiEnabled() || !GetWindow()) {
if (aElement) {
nsRefPtr<nsPLDOMEvent> e =
new nsPLDOMEvent(aElement,
NS_LITERAL_STRING("mozfullscreenerror"),
true,
false);
e->PostDOMEvent();
}
return;
}
@ -8538,7 +8529,7 @@ nsDocument::RequestFullScreen(Element* aElement)
nsIDocument* doc = fullScreenDoc;
while (doc != commonAncestor) {
if (::SetFullScreenState(doc, nsnull, false)) {
DispatchFullScreenChange(doc, nsnull);
DispatchFullScreenChange(doc);
}
doc = doc->GetParentDocument();
}
@ -8553,7 +8544,7 @@ nsDocument::RequestFullScreen(Element* aElement)
// element, and the full-screen-ancestor styles on ancestors of the element
// in this document.
if (SetFullScreenState(aElement, true)) {
DispatchFullScreenChange(this, aElement);
DispatchFullScreenChange(aElement);
}
// Propagate up the document hierarchy, setting the full-screen element as
@ -8566,7 +8557,7 @@ nsDocument::RequestFullScreen(Element* aElement)
while ((parent = child->GetParentDocument())) {
Element* element = parent->FindContentForSubDocument(child)->AsElement();
if (::SetFullScreenState(parent, element, true)) {
DispatchFullScreenChange(parent, element);
DispatchFullScreenChange(element);
}
child = parent;
}
@ -8616,7 +8607,8 @@ nsDocument::GetMozFullScreenEnabled(bool *aFullScreen)
*aFullScreen = false;
if (!nsContentUtils::IsFullScreenApiEnabled() ||
nsContentUtils::HasPluginWithUncontrolledEventDispatch(this)) {
nsContentUtils::HasPluginWithUncontrolledEventDispatch(this) ||
!IsVisible()) {
return NS_OK;
}

View File

@ -589,6 +589,7 @@ GK_ATOM(mouseover, "mouseover")
GK_ATOM(mousethrough, "mousethrough")
GK_ATOM(mouseup, "mouseup")
GK_ATOM(mozfullscreenchange, "mozfullscreenchange")
GK_ATOM(mozfullscreenerror, "mozfullscreenerror")
GK_ATOM(moz_opaque, "moz-opaque")
GK_ATOM(moz_action_hint, "mozactionhint")
GK_ATOM(x_moz_errormessage, "x-moz-errormessage")
@ -707,6 +708,7 @@ GK_ATOM(onmouseup, "onmouseup")
GK_ATOM(onMozAfterPaint, "onMozAfterPaint")
GK_ATOM(onMozBeforePaint, "onMozBeforePaint")
GK_ATOM(onmozfullscreenchange, "onmozfullscreenchange")
GK_ATOM(onmozfullscreenerror, "onmozfullscreenerror")
GK_ATOM(onMozMousePixelScroll, "onMozMousePixelScroll")
GK_ATOM(onMozScrolledAreaChanged, "onMozScrolledAreaChanged")
GK_ATOM(ononline, "ononline")

View File

@ -36,7 +36,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=430050
document.getElementById('b').loadURI('data:text/plain,succeeded',
null,
'UTF-8');
setTimeout(endTest, 0);
document.getElementById('b').addEventListener("load", endTest);
}
}, true);
document.documentElement.setAttribute("foo", "bar");

View File

@ -271,6 +271,10 @@ EVENT(mozfullscreenchange,
NS_FULLSCREENCHANGE,
EventNameType_HTML,
NS_EVENT_NULL)
EVENT(mozfullscreenerror,
NS_FULLSCREENERROR,
EventNameType_HTML,
NS_EVENT_NULL)
// Not supported yet; probably never because "wheel" is a better idea.
// EVENT(mousewheel)
EVENT(pause,

View File

@ -98,6 +98,7 @@ static const char* const sEventNames[] = {
"MozBeforePaint",
"MozBeforeResize",
"mozfullscreenchange",
"mozfullscreenerror",
"MozSwipeGesture",
"MozMagnifyGestureStart",
"MozMagnifyGestureUpdate",
@ -1384,6 +1385,8 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
return sEventNames[eDOMEvents_deviceorientation];
case NS_FULLSCREENCHANGE:
return sEventNames[eDOMEvents_mozfullscreenchange];
case NS_FULLSCREENERROR:
return sEventNames[eDOMEvents_mozfullscreenerror];
default:
break;
}

View File

@ -181,6 +181,7 @@ public:
eDOMEvents_beforepaint,
eDOMEvents_beforeresize,
eDOMEvents_mozfullscreenchange,
eDOMEvents_mozfullscreenerror,
eDOMEvents_MozSwipeGesture,
eDOMEvents_MozMagnifyGestureStart,
eDOMEvents_MozMagnifyGestureUpdate,

View File

@ -117,6 +117,7 @@
#include "mozilla/dom/Element.h"
#include "nsHTMLFieldSetElement.h"
#include "nsHTMLMenuElement.h"
#include "nsPLDOMEvent.h"
#include "mozilla/Preferences.h"
@ -3403,17 +3404,29 @@ nsresult nsGenericHTMLElement::MozRequestFullScreen()
// This stops the full-screen from being abused similar to the popups of old,
// and it also makes it harder for bad guys' script to go full-screen and
// spoof the browser chrome/window and phish logins etc.
nsIDocument* doc = OwnerDoc();
if (!nsContentUtils::IsRequestFullScreenAllowed() ||
!IsInDoc()) {
nsRefPtr<nsPLDOMEvent> e =
new nsPLDOMEvent(this,
NS_LITERAL_STRING("mozfullscreenerror"),
true,
false);
e->PostDOMEvent();
return NS_OK;
}
nsIDocument* doc = OwnerDoc();
nsCOMPtr<nsIDOMDocument> domDocument(do_QueryInterface(doc));
NS_ENSURE_STATE(domDocument);
bool fullScreenEnabled;
domDocument->GetMozFullScreenEnabled(&fullScreenEnabled);
if (!fullScreenEnabled) {
nsRefPtr<nsPLDOMEvent> e =
new nsPLDOMEvent(this,
NS_LITERAL_STRING("mozfullscreenerror"),
true,
false);
e->PostDOMEvent();
return NS_OK;
}

View File

@ -283,6 +283,7 @@ _TEST_FILES = \
test_fullscreen-api.html \
file_fullscreen-plugins.html \
file_fullscreen-denied.html \
file_fullscreen-hidden.html \
test_li_attributes_reflection.html \
test_ol_attributes_reflection.html \
test_bug651956.html \

View File

@ -43,8 +43,10 @@ var outOfDocElement = null;
var inDocElement = null;
var container = null;
var button = null;
var fullScreenChangeCount = 0;
var fullscreendenied = false;
document.addEventListener("mozfullscreenerror", function(){fullscreendenied=true;}, false);
function sendMouseClick(element) {
synthesizeMouseAtCenter(element, {});
@ -153,13 +155,18 @@ function fullScreenChange(event) {
case 5: {
ok(!document.mozFullScreen, "Should be back in non-full-screen mode (third time)");
setRequireTrustedContext(true);
fullscreendenied = false;
fullScreenElement().mozRequestFullScreen();
ok(!document.mozFullScreen, "Should still be in normal mode, because calling context isn't trusted.");
button = document.createElement("button");
button.onclick = function(){fullScreenElement().mozRequestFullScreen();}
fullScreenElement().appendChild(button);
sendMouseClick(button);
setTimeout(
function() {
ok(fullscreendenied, "Request for fullscreen should have been denied because calling context isn't trusted");
button = document.createElement("button");
button.onclick = function(){fullScreenElement().mozRequestFullScreen();}
fullScreenElement().appendChild(button);
sendMouseClick(button);
}, 0);
break;
}
case 6: {
@ -176,22 +183,26 @@ function fullScreenChange(event) {
SpecialPowers.setBoolPref("full-screen-api.enabled", false);
is(document.mozFullScreenEnabled, false, "document.mozFullScreenEnabled should be false if full-screen-api.enabled is false");
fullscreendenied = false;
fullScreenElement().mozRequestFullScreen();
ok(!document.mozFullScreen, "Should still be in normal mode, because pref is not enabled.");
setTimeout(
function() {
ok(!document.mozFullScreen, "Should still be in normal mode, because pref is not enabled.");
SpecialPowers.setBoolPref("full-screen-api.enabled", true);
is(document.mozFullScreenEnabled, true, "document.mozFullScreenEnabled should be true if full-screen-api.enabled is true");
SpecialPowers.setBoolPref("full-screen-api.enabled", true);
is(document.mozFullScreenEnabled, true, "document.mozFullScreenEnabled should be true if full-screen-api.enabled is true");
iframe = document.createElement("iframe");
fullScreenElement().appendChild(iframe);
iframe.src = iframeContents;
ok(!document.mozFullScreen, "Should still be in normal mode, because iframe did not have mozallowfullscreen attribute.");
fullScreenElement().removeChild(iframe);
iframe = null;
iframe = document.createElement("iframe");
fullScreenElement().appendChild(iframe);
iframe.src = iframeContents;
ok(!document.mozFullScreen, "Should still be in normal mode, because iframe did not have mozallowfullscreen attribute.");
fullScreenElement().removeChild(iframe);
iframe = null;
// Set timeout for calling finish(), so that any pending "mozfullscreenchange" events
// would have a chance to fire.
setTimeout(function(){opener.nextTest();}, 0);
// Set timeout for calling finish(), so that any pending "mozfullscreenchange" events
// would have a chance to fire.
setTimeout(function(){opener.nextTest();}, 0);
}, 0);
break;
}
default: {

View File

@ -37,6 +37,9 @@ function is(a, b, msg) {
*/
var requestFullScreenContents = "data:text/html;charset=utf-8,<html>%0D%0A <body onload%3D'document.body.mozRequestFullScreen()%3B'>%0D%0A <%2Fbody>%0D%0A<%2Fhtml>";
var fullscreendenied = false;
document.addEventListener("mozfullscreenerror", function(){fullscreendenied=true;}, false);
var gotFullScreenChange = false;
@ -52,12 +55,16 @@ function run() {
// generated event!).
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", true);
document.body.mozRequestFullScreen();
ok(!document.mozFullScreen, "Should not grant request in non-truested context");
// Test requesting full-screen mode in a long-running user-generated event handler.
// The request in the key handler should not be granted.
window.addEventListener("keypress", keyHandler, false);
synthesizeKey("VK_A", {});
fullscreendenied = false;
setTimeout(
function() {
ok(!document.mozFullScreen, "Should not grant request in non-truested context");
ok(fullscreendenied, "Request in non-trusted event handler should be denied");
// Test requesting full-screen mode in a long-running user-generated event handler.
// The request in the key handler should not be granted.
window.addEventListener("keypress", keyHandler, false);
synthesizeKey("VK_A", {});
}, 0);
}
function keyHandler(event) {
@ -69,23 +76,29 @@ function keyHandler(event) {
while ((new Date()).getTime() < end) {
; // Wait...
}
fullscreendenied = false;
document.body.mozRequestFullScreen();
ok(!document.mozFullScreen, "Should not grant request in long-running event handler.");
// Disable the requirement for trusted contexts only, so the tests are easier
// to write.
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false);
// Create an iframe without a mozallowfullscreen sttribute, whose contents requests
// full-screen. The request should be denied.
var iframe = document.createElement("iframe");
iframe.src = requestFullScreenContents;
document.body.appendChild(iframe);
setTimeout(
function() {
ok(!gotFullScreenChange, "Should not ever grant a fullscreen request in this doc.");
opener.nextTest();
ok(fullscreendenied, "Request in long running event handler should be denied");
ok(!document.mozFullScreen, "Should not grant request in long-running event handler.");
// Disable the requirement for trusted contexts only, so the tests are easier
// to write.
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false);
// Create an iframe without a mozallowfullscreen sttribute, whose contents requests
// full-screen. The request should be denied, and we should not receive a fullscreenchange
// event in this document.
var iframe = document.createElement("iframe");
iframe.src = requestFullScreenContents;
document.body.appendChild(iframe);
setTimeout(
function() {
ok(!gotFullScreenChange, "Should not ever grant a fullscreen request in this doc.");
opener.nextTest();
}, 0);
}, 0);
}

View File

@ -0,0 +1,50 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=697636
-->
<head>
<title>Test for Bug 697636</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="boom();">
<iframe id="f" src="data:text/html,<body text=green>1" mozallowfullscreen></iframe>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=697636">Mozilla Bug 697636</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 697636 **/
var frameWin;
var e1;
function boom()
{
frameWin = document.getElementById("f").contentWindow;
e1 = frameWin.document.documentElement;
frameWin.location = "data:text/html,<body text=blue onload='parent.b2()'>2";
}
function b2()
{
try { e1.mozRequestFullScreen(); } catch(e) { opener.ok(false, "Should not enter full-screen"); }
setTimeout(done, 0);
}
function done() {
opener.ok(!document.mozFullScreen, "Should not have entered full-screen mode in hidden document.");
opener.ok(!e1.ownerDocument.mozFullScreen, "Requesting owner should not have entered full-screen mode.");
opener.nextTest();
}
</script>
</pre>
</body>
</html>

View File

@ -7,7 +7,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=500885
<title>Test for Bug 500885</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/mockObjects.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
@ -18,81 +17,42 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=500885
</div>
<script type="text/javascript">
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var Cu = Components.utils;
var Ci = Components.interfaces;
var Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
function MockFilePicker() { };
MockFilePicker.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
init: function(aParent, aTitle, aMode) { },
appendFilters: function(aFilterMask) { },
appendFilter: function(aTitle, aFilter) { },
defaultString: "",
defaultExtension: "",
filterIndex: 0,
displayDirectory: null,
file: null,
get fileURL() {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
get files() {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
show: function MFP_show() {
return Ci.nsIFilePicker.returnOK;
}
};
var mockFilePickerRegisterer =
new MockObjectRegisterer("@mozilla.org/filepicker;1",MockFilePicker);
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.reset();
MockFilePicker.returnValue = MockFilePicker.returnOK;
function test() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var wu = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
// SpecialPowers.DOMWindowUtils doesn't appear to fire mouseEvents correctly
var wu = SpecialPowers.getDOMWindowUtils(window);
mockFilePickerRegisterer.register();
try {
var domActivateEvents;
var fileInput = document.getElementById("file");
var rect = fileInput.getBoundingClientRect();
fileInput.addEventListener ("DOMActivate", function (e) {
ok("detail" in e, "DOMActivate should have .detail!");
is(e.detail, 1, "detail should be 1!");
ok("detail" in e, "DOMActivate should have .detail");
is(e.detail, 1, ".detail should be 1");
domActivateEvents++;
}, false);
domActivateEvents = 0;
wu.sendMouseEvent("mousedown", rect.left + 5, rect.top + 5, 0, 1, 0);
wu.sendMouseEvent("mouseup", rect.left + 5, rect.top + 5, 0, 1, 0);
is(domActivateEvents, 1, "click on text field should only fire 1 DOMActivate event");
is(domActivateEvents, 1, "click on text field should fire 1 DOMActivate event");
domActivateEvents = 0;
wu.sendMouseEvent("mousedown", rect.right - 5, rect.top + 5, 0, 1, 0);
wu.sendMouseEvent("mouseup", rect.right - 5, rect.top + 5, 0, 1, 0);
is(domActivateEvents, 1, "click on button should only fire 1 DOMActivate event");
is(domActivateEvents, 1, "click on button should fire 1 DOMActivate event");
} finally {
SimpleTest.executeSoon(unregister);
SimpleTest.executeSoon(SimpleTest.finish);
}
}
function unregister()
{
mockFilePickerRegisterer.unregister();
SimpleTest.finish();
}
window.onload = function() {
SimpleTest.waitForExplicitFinish();
setTimeout(test, 0);
};
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(test);
</script>
</body>

View File

@ -7,7 +7,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=592802
<title>Test for Bug 592802</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/mockObjects.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
@ -26,129 +25,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=592802
SimpleTest.waitForExplicitFinish();
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var Cu = Components.utils;
var Ci = Components.interfaces;
var Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
function simpleEnumerator(items)
{
this._items = items;
this._nextIndex = 0;
}
simpleEnumerator.prototype = {
QueryInterface: function(aIID)
{
if (Ci.nsISimpleEnumerator.equals(aIID) ||
Ci.nsISupports.equals(aIID)) {
return this;
}
throw Cr.NS_ERROR_NO_INTERFACE;
},
hasMoreElements: function()
{
return this._nextIndex < this._items.length;
},
getNext: function()
{
if (!this.hasMoreElements()) {
throw Cr.NS_ERROR_FAILURE;
}
return this._items[this._nextIndex++];
}
};
function MockFilePicker()
{
}
MockFilePicker.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
// Constants
returnOK: 0, // the user hits OK (select a file)
returnCancel: 1, // the user cancel the file selection
returnReplace: 2, // the user replace the selection
// Properties
defaultExtension: "",
defaultString: "",
get displayDirectory() { return null; },
set displayDirectory(val) { },
get fileURL() { return null; },
filterIndex: 0,
get file() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var fileName = "592808_file";
var fileData = "file content";
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
testFile.append(fileName);
var outStream = Components.
classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
0666, 0);
outStream.write(fileData, fileData.length);
outStream.close();
return testFile;
},
get files() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var fileName = "592808_file";
var fileData = "file content";
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
testFile.append(fileName);
var outStream = Components.
classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
0666, 0);
outStream.write(fileData, fileData.length);
outStream.close();
return new simpleEnumerator([testFile]);
},
appendFilter: function(val) {},
appendFilters: function(val) {},
init: function() {},
show: function()
{
if (firstFilePickerShow) {
firstFilePickerShow = false;
return this.returnCancel;
} else {
return this.returnOK;
}
}
};
var mockFilePickerRegisterer =
new MockObjectRegisterer("@mozilla.org/filepicker;1",MockFilePicker);
mockFilePickerRegisterer.register();
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.reset();
var testData = [
/* visibility | display | multiple */
@ -163,26 +41,27 @@ var testData = [
var testCounter = 0;
var testNb = testData.length;
var firstFilePickerShow = true;
function finished()
{
mockFilePickerRegisterer.unregister();
SimpleTest.finish();
}
SimpleTest.waitForFocus(function() {
// mockFilePicker will simulate a cancel for the first time the file picker will be shown.
MockFilePicker.returnValue = MockFilePicker.returnCancel;
var b2 = document.getElementById('b2');
b2.focus(); // Be sure the element is visible.
document.getElementById('b2').addEventListener("change", function(aEvent) {
aEvent.target.removeEventListener("change", arguments.callee, false);
ok(false, "When cancel is received, change should not fire");
}, false);
synthesizeMouse(b2, 2, 2, {});
b2.click();
// Now, we can launch tests when file picker isn't canceled.
MockFilePicker.useAnyFile();
MockFilePicker.returnValue = MockFilePicker.returnOK;
var b = document.getElementById('b');
b.focus(); // Be sure the element is visible.
@ -203,12 +82,12 @@ SimpleTest.waitForFocus(function() {
a.multiple = data[2];
SimpleTest.executeSoon(function() {
synthesizeMouse(b, 2, 2, {});
b.click();
});
}
}, false);
synthesizeMouse(b, 2, 2, {});
b.click();
});
</script>

View File

@ -39,7 +39,8 @@ var gTestWindows = [
"file_fullscreen-denied.html",
"file_fullscreen-api.html",
"file_fullscreen-api-keys.html",
"file_fullscreen-plugins.html"
"file_fullscreen-plugins.html",
"file_fullscreen-hidden.html"
];
var testWindow = null;

View File

@ -141,6 +141,7 @@
#include "prprf.h"
#include "mozilla/dom/Element.h"
#include "mozilla/Preferences.h"
#include "nsMimeTypes.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -162,6 +163,7 @@ const PRInt32 kBackward = 1;
//#define DEBUG_charset
#define NS_USE_NEW_VIEW_SOURCE 1
#define NS_USE_NEW_PLAIN_TEXT 1
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
@ -652,17 +654,30 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
bool aReset,
nsIContentSink* aSink)
{
nsCAutoString contentType;
aChannel->GetContentType(contentType);
bool viewSource = aCommand && !nsCRT::strcmp(aCommand, "view-source") &&
NS_USE_NEW_VIEW_SOURCE;
bool loadAsHtml5 = nsHtml5Module::sEnabled || viewSource;
bool plainText = (contentType.EqualsLiteral(TEXT_PLAIN) ||
contentType.EqualsLiteral(TEXT_CSS) ||
contentType.EqualsLiteral(APPLICATION_JAVASCRIPT) ||
contentType.EqualsLiteral(APPLICATION_XJAVASCRIPT) ||
contentType.EqualsLiteral(TEXT_ECMASCRIPT) ||
contentType.EqualsLiteral(APPLICATION_ECMASCRIPT) ||
contentType.EqualsLiteral(TEXT_JAVASCRIPT));
bool loadAsHtml5 = nsHtml5Module::sEnabled || viewSource || plainText;
if (!NS_USE_NEW_PLAIN_TEXT && !viewSource) {
plainText = false;
}
NS_ASSERTION(!(plainText && aSink),
"Someone tries to load plain text into a custom sink.");
if (aSink) {
loadAsHtml5 = false;
}
nsCAutoString contentType;
aChannel->GetContentType(contentType);
if (contentType.Equals("application/xhtml+xml") && !viewSource) {
// We're parsing XHTML as XML, remember that.
@ -677,7 +692,8 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
}
#endif
if (loadAsHtml5 && !viewSource && !(contentType.EqualsLiteral("text/html") &&
if (loadAsHtml5 && !viewSource &&
(!(contentType.EqualsLiteral("text/html") || plainText) &&
aCommand && !nsCRT::strcmp(aCommand, "view"))) {
loadAsHtml5 = false;
}
@ -731,9 +747,13 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
if (needsParser) {
if (loadAsHtml5) {
mParser = nsHtml5Module::NewHtml5Parser();
mParser->MarkAsNotScriptCreated((viewSource &&
!contentType.EqualsLiteral("text/html")) ?
"view-source-xml": aCommand);
if (plainText) {
mParser->MarkAsNotScriptCreated("plain-text");
} else if (viewSource && !contentType.EqualsLiteral("text/html")) {
mParser->MarkAsNotScriptCreated("view-source-xml");
} else {
mParser->MarkAsNotScriptCreated(aCommand);
}
} else {
mParser = do_CreateInstance(kCParserCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -113,13 +113,6 @@ nsSVGClass::ToDOMAnimatedString(nsIDOMSVGAnimatedString **aResult,
return NS_OK;
}
#ifdef MOZ_SMIL
nsISMILAttr*
nsSVGClass::ToSMILAttr(nsSVGStylableElement *aSVGElement)
{
return new SMILString(this, aSVGElement);
}
NS_IMETHODIMP
nsSVGClass::DOMAnimatedString::GetAnimVal(nsAString& aResult)
{
@ -130,6 +123,13 @@ nsSVGClass::DOMAnimatedString::GetAnimVal(nsAString& aResult)
return NS_OK;
}
#ifdef MOZ_SMIL
nsISMILAttr*
nsSVGClass::ToSMILAttr(nsSVGStylableElement *aSVGElement)
{
return new SMILString(this, aSVGElement);
}
nsresult
nsSVGClass::SMILString::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* /*aSrcElement*/,

View File

@ -41,9 +41,12 @@
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsString.h"
#include "nsISMILAttr.h"
#include "nsDOMError.h"
#ifdef MOZ_SMIL
#include "nsISMILAttr.h"
#endif // MOZ_SMIL
class nsSVGStylableElement;
class nsSVGClass

View File

@ -149,6 +149,7 @@ nsSVGStylableElement::DidAnimateClass()
}
}
#ifdef MOZ_SMIL
nsISMILAttr*
nsSVGStylableElement::GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName)
{
@ -158,3 +159,4 @@ nsSVGStylableElement::GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName)
}
return nsSVGStylableElementBase::GetAnimatedAttr(aNamespaceID, aName);
}
#endif // MOZ_SMIL

View File

@ -39,7 +39,7 @@
#include "jspubtd.h"
%}
[scriptable, uuid(4e9d7d5e-72c3-4fa3-94f9-55eac5a5996b)]
[scriptable, uuid(5b3f9656-9d81-40e4-85ba-01f302177815)]
interface nsIInlineEventHandlers : nsISupports
{
[implicit_jscontext] attribute jsval onabort;
@ -81,6 +81,7 @@ interface nsIInlineEventHandlers : nsISupports
// Not supported yet
// [implicit_jscontext] attribute jsval onmousewheel;
[implicit_jscontext] attribute jsval onmozfullscreenchange;
[implicit_jscontext] attribute jsval onmozfullscreenerror;
[implicit_jscontext] attribute jsval onpause;
[implicit_jscontext] attribute jsval onplay;
[implicit_jscontext] attribute jsval onplaying;

View File

@ -60,6 +60,7 @@
#include "mozilla/ipc/XPCShellEnvironment.h"
#include "mozilla/jsipc/PContextWrapperChild.h"
#include "mozilla/net/NeckoChild.h"
#include "mozilla/Preferences.h"
#if defined(MOZ_SYDNEYAUDIO)
#include "nsAudioStream.h"
@ -68,7 +69,6 @@
#include "nsIObserverService.h"
#include "nsTObserverArray.h"
#include "nsIObserver.h"
#include "nsIPrefService.h"
#include "nsServiceManagerUtils.h"
#include "nsXULAppAPI.h"
#include "nsWeakReference.h"
@ -638,24 +638,14 @@ ContentChild::AddRemoteAlertObserver(const nsString& aData,
bool
ContentChild::RecvPreferenceUpdate(const PrefTuple& aPref)
{
nsCOMPtr<nsIPrefServiceInternal> prefs = do_GetService("@mozilla.org/preferences-service;1");
if (!prefs)
return false;
prefs->SetPreference(&aPref);
Preferences::SetPreference(&aPref);
return true;
}
bool
ContentChild::RecvClearUserPreference(const nsCString& aPrefName)
{
nsCOMPtr<nsIPrefServiceInternal> prefs = do_GetService("@mozilla.org/preferences-service;1");
if (!prefs)
return false;
prefs->ClearContentPref(aPrefName);
Preferences::ClearContentPref(aPrefName.get());
return true;
}

View File

@ -51,7 +51,6 @@
#include "nsIDOMWindow.h"
#include "nsIPrefBranch.h"
#include "nsIPrefBranch2.h"
#include "nsIPrefService.h"
#include "nsIPrefLocalizedString.h"
#include "nsIObserverService.h"
#include "nsContentUtils.h"
@ -461,7 +460,7 @@ bool
ContentParent::RecvReadPrefsArray(InfallibleTArray<PrefTuple> *prefs)
{
EnsurePrefService();
mPrefService->MirrorPreferences(prefs);
Preferences::MirrorPreferences(prefs);
return true;
}
@ -707,33 +706,9 @@ ContentParent::Observe(nsISupports* aSubject,
// We know prefs are ASCII here.
NS_LossyConvertUTF16toASCII strData(aData);
nsCOMPtr<nsIPrefServiceInternal> prefService =
do_GetService("@mozilla.org/preferences-service;1");
bool prefNeedUpdate;
prefService->PrefHasUserValue(strData, &prefNeedUpdate);
// If the pref does not have a user value, check if it exist on the
// default branch or not
if (!prefNeedUpdate) {
nsCOMPtr<nsIPrefBranch> defaultBranch;
nsCOMPtr<nsIPrefService> prefsService = do_QueryInterface(prefService);
prefsService->GetDefaultBranch(nsnull, getter_AddRefs(defaultBranch));
PRInt32 prefType = nsIPrefBranch::PREF_INVALID;
defaultBranch->GetPrefType(strData.get(), &prefType);
prefNeedUpdate = (prefType != nsIPrefBranch::PREF_INVALID);
}
PrefTuple pref;
bool prefNeedUpdate = Preferences::MirrorPreference(strData.get(), &pref);
if (prefNeedUpdate) {
// Pref was created, or previously existed and its value
// changed.
PrefTuple pref;
#ifdef DEBUG
nsresult rv =
#endif
prefService->MirrorPreference(strData, &pref);
NS_ASSERTION(NS_SUCCEEDED(rv), "Pref has value but can't mirror?");
if (!SendPreferenceUpdate(pref)) {
return NS_ERROR_NOT_AVAILABLE;
}

View File

@ -241,7 +241,7 @@ private:
nsCOMArray<nsIMemoryReporter> mMemoryReporters;
bool mIsAlive;
nsCOMPtr<nsIPrefServiceInternal> mPrefService;
nsCOMPtr<nsIPrefService> mPrefService;
bool mSendPermissionUpdates;

View File

@ -126,7 +126,7 @@ CSRCS = \
tokens.c \
$(NULL)
DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD
DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD -DCOMPILER_IMPLEMENTATION
#these defines are from ANGLE's build_angle.gyp
DEFINES += -DANGLE_DISABLE_TRACE

View File

@ -1,6 +1,6 @@
This is the ANGLE project, from http://code.google.com/p/angleproject/
Current revision: r802
Current revision: r809
== Applied local patches ==

View File

@ -1,40 +1,5 @@
# HG changeset patch
# Parent cf38970fcf3b4bee12f09b3747b7b7711bc77ad8
diff --git a/gfx/angle/angle-renaming-debug.patch b/gfx/angle/angle-renaming-debug.patch
--- a/gfx/angle/angle-renaming-debug.patch
+++ b/gfx/angle/angle-renaming-debug.patch
@@ -1,11 +1,10 @@
# HG changeset patch
-# Parent 96359f46b01fdb37e791f564495e8b2755a05233
-
+# Parent 70640278da97b0ca49e21c4bb52766b8af7db4db
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -73,17 +73,17 @@ CPPSRCS = \
parseConst.cpp \
ParseHelper.cpp \
PoolAlloc.cpp \
QualifierAlive.cpp \
@@ -129,17 +128,17 @@ diff --git a/gfx/angle/src/compiler/comp
#include <assert.h>
#ifdef _DEBUG
#define TRACE_ENABLED // define to enable debug message tracing
diff --git a/gfx/angle/src/compiler/osinclude.h b/gfx/angle/src/compiler/osinclude.h
--- a/gfx/angle/src/compiler/osinclude.h
+++ b/gfx/angle/src/compiler/osinclude.h
-@@ -32,17 +32,17 @@
+@@ -30,17 +30,17 @@
#include <windows.h>
#elif defined(ANGLE_OS_POSIX)
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
#endif // ANGLE_USE_NSPR
# Parent b5604c321da4e3b5d6b0a940d18022a827061579
diff --git a/gfx/angle/src/libGLESv2/Texture.cpp b/gfx/angle/src/libGLESv2/Texture.cpp
--- a/gfx/angle/src/libGLESv2/Texture.cpp
+++ b/gfx/angle/src/libGLESv2/Texture.cpp

View File

@ -1,15 +1,36 @@
# HG changeset patch
# Parent f9415c10c3ebd27856500cca7a0ee0f28a16f53c
diff --git a/gfx/angle/src/compiler/preprocessor/scanner.h b/gfx/angle/src/compiler/preprocessor/scanner.h
--- a/gfx/angle/src/compiler/preprocessor/scanner.h
+++ b/gfx/angle/src/compiler/preprocessor/scanner.h
@@ -44,17 +44,19 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
//
// scanner.h
//
# Parent e8b87ef36a1dae3bbd7abb13c4bb0a0bb8f5b58c
diff --git a/gfx/angle/README.mozilla b/gfx/angle/README.mozilla
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -2,16 +2,17 @@ This is the ANGLE project, from http://c
#if !defined(__SCANNER_H)
#define __SCANNER_H 1
Current revision: r802
== Applied local patches ==
In this order:
angle-renaming-debug.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
+ angle-limit-identifiers-to-250-chars.patch - see bug 675625
In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
== How to update this ANGLE copy ==
1. Unapply patches
2. Apply diff with new ANGLE version
3. Reapply patches.
diff --git a/gfx/angle/src/compiler/preprocessor/length_limits.h b/gfx/angle/src/compiler/preprocessor/length_limits.h
--- a/gfx/angle/src/compiler/preprocessor/length_limits.h
+++ b/gfx/angle/src/compiler/preprocessor/length_limits.h
@@ -10,12 +10,14 @@
#if !defined(__LENGTH_LIMITS_H)
#define __LENGTH_LIMITS_H 1
// These constants are factored out from the rest of the headers to
// make it easier to reference them from the compiler sources.
// These lengths do not include the NULL terminator.
-#define MAX_SYMBOL_NAME_LEN 256
@ -18,9 +39,4 @@ diff --git a/gfx/angle/src/compiler/preprocessor/scanner.h b/gfx/angle/src/compi
+#define MAX_SYMBOL_NAME_LEN 250
#define MAX_STRING_LEN 511
#include "compiler/preprocessor/parser.h"
// Not really atom table stuff but needed first...
typedef struct SourceLoc_Rec {
unsigned short file, line;
#endif // !(defined(__LENGTH_LIMITS_H)

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 70640278da97b0ca49e21c4bb52766b8af7db4db
# Parent 0239f15c7212413b5cffe66aee9ae5a4feb28f16
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in

View File

@ -17,6 +17,9 @@
'.',
'../include',
],
'defines': [
'COMPILER_IMPLEMENTATION',
],
'sources': [
'compiler/BaseTypes.h',
'compiler/BuiltInFunctionEmulator.cpp',
@ -60,7 +63,6 @@
'compiler/QualifierAlive.h',
'compiler/RemoveTree.cpp',
'compiler/RemoveTree.h',
'compiler/ShaderLang.cpp',
'compiler/ShHandle.h',
'compiler/SymbolTable.cpp',
'compiler/SymbolTable.h',
@ -77,6 +79,7 @@
'compiler/preprocessor/cpp.c',
'compiler/preprocessor/cpp.h',
'compiler/preprocessor/cppstruct.c',
'compiler/preprocessor/length_limits.h',
'compiler/preprocessor/memory.c',
'compiler/preprocessor/memory.h',
'compiler/preprocessor/parser.h',
@ -99,12 +102,15 @@
},
{
'target_name': 'translator_glsl',
'type': 'static_library',
'type': '<(component)',
'dependencies': ['translator_common'],
'include_dirs': [
'.',
'../include',
],
'defines': [
'COMPILER_IMPLEMENTATION',
],
'sources': [
'compiler/CodeGenGLSL.cpp',
'compiler/OutputESSL.cpp',
@ -113,6 +119,7 @@
'compiler/OutputGLSLBase.h',
'compiler/OutputGLSL.cpp',
'compiler/OutputGLSL.h',
'compiler/ShaderLang.cpp',
'compiler/TranslatorESSL.cpp',
'compiler/TranslatorESSL.h',
'compiler/TranslatorGLSL.cpp',
@ -123,13 +130,17 @@
},
{
'target_name': 'translator_hlsl',
'type': 'static_library',
'type': '<(component)',
'dependencies': ['translator_common'],
'include_dirs': [
'.',
'../include',
],
'defines': [
'COMPILER_IMPLEMENTATION',
],
'sources': [
'compiler/ShaderLang.cpp',
'compiler/CodeGenHLSL.cpp',
'compiler/OutputHLSL.cpp',
'compiler/OutputHLSL.h',

View File

@ -1,7 +1,7 @@
#define MAJOR_VERSION 0
#define MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 802
#define BUILD_REVISION 809
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -252,7 +252,7 @@ void TCompiler::mapLongVariableNames(TIntermNode* root)
int TCompiler::getMappedNameMaxLength() const
{
return MAX_IDENTIFIER_NAME_SIZE + 1;
return MAX_SHORTENED_IDENTIFIER_SIZE + 1;
}
const TExtensionBehavior& TCompiler::getExtensionBehavior() const

View File

@ -10,13 +10,13 @@ namespace {
TString mapLongName(int id, const TString& name, bool isVarying)
{
ASSERT(name.size() > MAX_IDENTIFIER_NAME_SIZE);
ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE);
TStringStream stream;
stream << "webgl_";
if (isVarying)
stream << "v";
stream << id << "_";
stream << name.substr(0, MAX_IDENTIFIER_NAME_SIZE - stream.str().size());
stream << name.substr(0, MAX_SHORTENED_IDENTIFIER_SIZE - stream.str().size());
return stream.str();
}
@ -31,7 +31,7 @@ MapLongVariableNames::MapLongVariableNames(
void MapLongVariableNames::visitSymbol(TIntermSymbol* symbol)
{
ASSERT(symbol != NULL);
if (symbol->getSymbol().size() > MAX_IDENTIFIER_NAME_SIZE) {
if (symbol->getSymbol().size() > MAX_SHORTENED_IDENTIFIER_SIZE) {
switch (symbol->getQualifier()) {
case EvqVaryingIn:
case EvqVaryingOut:

View File

@ -13,10 +13,10 @@
#include "compiler/VariableInfo.h"
// This size does not include '\0' in the end.
#define MAX_IDENTIFIER_NAME_SIZE 32
#define MAX_SHORTENED_IDENTIFIER_SIZE 32
// Traverses intermediate tree to map attributes and uniforms names that are
// longer than MAX_IDENTIFIER_NAME_SIZE to MAX_IDENTIFIER_NAME_SIZE.
// longer than MAX_SHORTENED_IDENTIFIER_SIZE to MAX_SHORTENED_IDENTIFIER_SIZE.
class MapLongVariableNames : public TIntermTraverser {
public:
MapLongVariableNames(std::map<std::string, std::string>& varyingLongNameMap);

View File

@ -1425,6 +1425,53 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n
return typedNode;
}
bool TParseContext::enterStructDeclaration(int line, const TString& identifier)
{
++structNestingLevel;
// Embedded structure definitions are not supported per GLSL ES spec.
// They aren't allowed in GLSL either, but we need to detect this here
// so we don't rely on the GLSL compiler to catch it.
if (structNestingLevel > 1) {
error(line, "", "Embedded struct definitions are not allowed", "");
return true;
}
return false;
}
void TParseContext::exitStructDeclaration()
{
--structNestingLevel;
}
namespace {
const int kWebGLMaxStructNesting = 4;
} // namespace
bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldType)
{
if (shaderSpec != SH_WEBGL_SPEC) {
return false;
}
if (fieldType.getBasicType() != EbtStruct) {
return false;
}
// We're already inside a structure definition at this point, so add
// one to the field's struct nesting.
if (1 + fieldType.getDeepestStructNesting() >= kWebGLMaxStructNesting) {
error(line, "", "", "Reference of struct type %s exceeds maximum struct nesting of %d",
fieldType.getTypeName().c_str(), kWebGLMaxStructNesting);
return true;
}
return false;
}
//
// Parse an array of strings using yyparse.
//

View File

@ -31,9 +31,25 @@ struct TPragma {
//
struct TParseContext {
TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) :
intermediate(interm), symbolTable(symt), extensionBehavior(ext), infoSink(is), shaderType(type), shaderSpec(spec), compileOptions(options), checksPrecisionErrors(checksPrecErrors), sourcePath(sourcePath), treeRoot(0),
numErrors(0), lexAfterType(false), loopNestingLevel(0),
inTypeParen(false), contextPragma(true, false), scanner(NULL) { }
intermediate(interm),
symbolTable(symt),
extensionBehavior(ext),
infoSink(is),
shaderType(type),
shaderSpec(spec),
compileOptions(options),
sourcePath(sourcePath),
treeRoot(0),
numErrors(0),
lexAfterType(false),
loopNestingLevel(0),
structNestingLevel(0),
inTypeParen(false),
currentFunctionType(NULL),
functionReturnsValue(false),
checksPrecisionErrors(checksPrecErrors),
contextPragma(true, false),
scanner(NULL) { }
TIntermediate& intermediate; // to hold and build a parse tree
TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
TExtensionBehavior& extensionBehavior; // mapping between supported extensions and current behavior.
@ -46,6 +62,7 @@ struct TParseContext {
int numErrors;
bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier
int loopNestingLevel; // 0 if outside all loops
int structNestingLevel; // incremented while parsing a struct declaration
bool inTypeParen; // true if in parentheses, looking only for an identifier
const TType* currentFunctionType; // the return type of the function that's currently being parsed
bool functionReturnsValue; // true if a non-void function has a return
@ -105,6 +122,14 @@ struct TParseContext {
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
// Performs an error check for embedded struct declarations.
// Returns true if an error was raised due to the declaration of
// this struct.
bool enterStructDeclaration(TSourceLoc line, const TString& identifier);
void exitStructDeclaration();
bool structNestingErrorCheck(TSourceLoc line, const TType& fieldType);
};
int PaParseStrings(int count, const char* const string[], const int length[],

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@ -12,6 +12,7 @@
#include "GLSLANG/ShaderLang.h"
#include "compiler/InitializeDll.h"
#include "compiler/preprocessor/length_limits.h"
#include "compiler/ShHandle.h"
//
@ -19,16 +20,21 @@
// and the shading language compiler.
//
static int getVariableMaxLength(const TVariableInfoList& varList)
static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle,
int expectedValue)
{
TString::size_type maxLen = 0;
for (TVariableInfoList::const_iterator i = varList.begin();
i != varList.end(); ++i)
{
maxLen = std::max(maxLen, i->name.size());
}
// Add 1 to include null-termination character.
return static_cast<int>(maxLen) + 1;
int activeUniformLimit = 0;
ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
int activeAttribLimit = 0;
ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit);
}
static bool checkMappedNameMaxLength(const ShHandle handle, int expectedValue)
{
int mappedNameMaxLength = 0;
ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
return (expectedValue == mappedNameMaxLength);
}
static void getVariableInfo(ShShaderInfo varType,
@ -59,9 +65,20 @@ static void getVariableInfo(ShShaderInfo varType,
if (length) *length = varInfo.name.size();
*size = varInfo.size;
*type = varInfo.type;
strcpy(name, varInfo.name.c_str());
if (mappedName)
strcpy(mappedName, varInfo.mappedName.c_str());
// This size must match that queried by
// SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH
// in ShGetInfo, below.
int activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength));
strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength);
if (mappedName) {
// This size must match that queried by
// SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
int maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
}
}
//
@ -191,16 +208,18 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
*params = compiler->getUniforms().size();
break;
case SH_ACTIVE_UNIFORM_MAX_LENGTH:
*params = getVariableMaxLength(compiler->getUniforms());
*params = 1 + MAX_SYMBOL_NAME_LEN;
break;
case SH_ACTIVE_ATTRIBUTES:
*params = compiler->getAttribs().size();
break;
case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
*params = getVariableMaxLength(compiler->getAttribs());
*params = 1 + MAX_SYMBOL_NAME_LEN;
break;
case SH_MAPPED_NAME_MAX_LENGTH:
*params = compiler->getMappedNameMaxLength();
// Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
// handle array and struct dereferences.
*params = 1 + MAX_SYMBOL_NAME_LEN;
break;
default: UNREACHABLE();
}

View File

@ -13,6 +13,8 @@
#include <stdio.h>
#include <algorithm>
//
// TType helper function needs a place to live.
//
@ -71,6 +73,20 @@ int TType::getStructSize() const
return structureSize;
}
void TType::computeDeepestStructNesting()
{
if (!getStruct()) {
return;
}
int maxNesting = 0;
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); ++tl) {
maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
}
deepestStructNesting = 1 + maxNesting;
}
//
// Dump functions.
//

View File

@ -85,21 +85,22 @@ public:
TType() {}
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), fieldName(0), mangled(0), typeName(0)
maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
{
}
explicit TType(const TPublicType &p) :
type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), fieldName(0), mangled(0), typeName(0)
maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
{
if (p.userDef) {
structure = p.userDef->getStruct();
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
computeDeepestStructNesting();
}
}
TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), fieldName(0), mangled(0)
maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0)
{
typeName = NewPoolTString(n.c_str());
}
@ -144,6 +145,7 @@ public:
structureSize = copyOf.structureSize;
maxArraySize = copyOf.maxArraySize;
deepestStructNesting = copyOf.deepestStructNesting;
assert(copyOf.arrayInformationType == 0);
arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level
}
@ -202,7 +204,7 @@ public:
bool isScalar() const { return size == 1 && !matrix && !structure; }
TTypeList* getStruct() const { return structure; }
void setStruct(TTypeList* s) { structure = s; }
void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }
const TString& getTypeName() const
{
@ -268,9 +270,24 @@ public:
const char* getQualifierString() const { return ::getQualifierString(qualifier); }
TString getCompleteString() const;
// If this type is a struct, returns the deepest struct nesting of
// any field in the struct. For example:
// struct nesting1 {
// vec4 position;
// };
// struct nesting2 {
// nesting1 field1;
// vec4 field2;
// };
// For type "nesting2", this method would return 2 -- the number
// of structures through which indirection must occur to reach the
// deepest field (nesting2.field1.position).
int getDeepestStructNesting() const { return deepestStructNesting; }
protected:
void buildMangledName(TString&);
int getStructSize() const;
void computeDeepestStructNesting();
TBasicType type : 6;
TPrecision precision;
@ -284,6 +301,7 @@ protected:
TTypeList* structure; // 0 unless this is a struct
mutable int structureSize;
int deepestStructNesting;
TString *fieldName; // for structure field names
TString *mangled;

View File

@ -1642,11 +1642,11 @@ type_specifier_nonarray
;
struct_specifier
: STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
: STRUCT IDENTIFIER LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
if (context->reservedErrorCheck($2.line, *$2.string))
context->recover();
TType* structure = new TType($4, *$2.string);
TType* structure = new TType($5, *$2.string);
TVariable* userTypeDef = new TVariable($2.string, *structure, true);
if (! context->symbolTable.insert(*userTypeDef)) {
context->error($2.line, "redefinition", $2.string->c_str(), "struct");
@ -1654,11 +1654,13 @@ struct_specifier
}
$$.setBasic(EbtStruct, EvqTemporary, $1.line);
$$.userDef = structure;
context->exitStructDeclaration();
}
| STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($3, TString(""));
| STRUCT LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($4, TString(""));
$$.setBasic(EbtStruct, EvqTemporary, $1.line);
$$.userDef = structure;
context->exitStructDeclaration();
}
;
@ -1708,6 +1710,10 @@ struct_declaration
type->setStruct($1.userDef->getStruct());
type->setTypeName($1.userDef->getTypeName());
}
if (context->structNestingErrorCheck($1.line, *type)) {
context->recover();
}
}
}
;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
//
// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
//
// length_limits.h
//
#if !defined(__LENGTH_LIMITS_H)
#define __LENGTH_LIMITS_H 1
// These constants are factored out from the rest of the headers to
// make it easier to reference them from the compiler sources.
// These lengths do not include the NULL terminator.
// see bug 675625: NVIDIA driver crash with lengths >= 253
// this is only an interim fix, the real fix is name mapping, see ANGLE bug 144 / r619
#define MAX_SYMBOL_NAME_LEN 250
#define MAX_STRING_LEN 511
#endif // !(defined(__LENGTH_LIMITS_H)

View File

@ -48,12 +48,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(__SCANNER_H)
#define __SCANNER_H 1
// These lengths do not include the NULL terminator.
// see bug 675625: NVIDIA driver crash with lengths >= 253
// this is only an interim fix, the real fix is name mapping, see ANGLE bug 144 / r619
#define MAX_SYMBOL_NAME_LEN 250
#define MAX_STRING_LEN 511
#include "compiler/preprocessor/length_limits.h"
#include "compiler/preprocessor/parser.h"
// Not really atom table stuff but needed first...

View File

@ -40,6 +40,9 @@ namespace gl
{
Context::Context(const egl::Config *config, const gl::Context *shareContext) : mConfig(config)
{
mDisplay = NULL;
mDevice = NULL;
mFenceHandleAllocator.setBaseHandle(0);
setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@ -234,19 +237,20 @@ Context::~Context()
void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
{
IDirect3DDevice9 *device = display->getDevice();
mDisplay = display;
mDevice = mDisplay->getDevice();
if (!mHasBeenCurrent)
{
mDeviceCaps = display->getDeviceCaps();
mDeviceCaps = mDisplay->getDeviceCaps();
mVertexDataManager = new VertexDataManager(this, device);
mIndexDataManager = new IndexDataManager(this, device);
mVertexDataManager = new VertexDataManager(this, mDevice);
mIndexDataManager = new IndexDataManager(this, mDevice);
mBlit = new Blit(this);
mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
mSupportsVertexTexture = display->getVertexTextureSupport();
mSupportsNonPower2Texture = display->getNonPower2TextureSupport();
mSupportsVertexTexture = mDisplay->getVertexTextureSupport();
mSupportsNonPower2Texture = mDisplay->getNonPower2TextureSupport();
mMaxTextureDimension = std::min(std::min((int)mDeviceCaps.MaxTextureWidth, (int)mDeviceCaps.MaxTextureHeight),
(int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
@ -268,7 +272,7 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
for (int i = 0; i < sizeof(renderBufferFormats) / sizeof(D3DFORMAT); ++i)
{
bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
display->getMultiSampleSupport(renderBufferFormats[i], multisampleArray);
mDisplay->getMultiSampleSupport(renderBufferFormats[i], multisampleArray);
mMultiSampleSupport[renderBufferFormats[i]] = multisampleArray;
for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j)
@ -282,14 +286,14 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
mMaxSupportedSamples = max;
mSupportsEventQueries = display->getEventQuerySupport();
mSupportsDXT1Textures = display->getDXT1TextureSupport();
mSupportsDXT3Textures = display->getDXT3TextureSupport();
mSupportsDXT5Textures = display->getDXT5TextureSupport();
mSupportsFloatTextures = display->getFloatTextureSupport(&mSupportsFloatLinearFilter, &mSupportsFloatRenderableTextures);
mSupportsHalfFloatTextures = display->getHalfFloatTextureSupport(&mSupportsHalfFloatLinearFilter, &mSupportsHalfFloatRenderableTextures);
mSupportsLuminanceTextures = display->getLuminanceTextureSupport();
mSupportsLuminanceAlphaTextures = display->getLuminanceAlphaTextureSupport();
mSupportsEventQueries = mDisplay->getEventQuerySupport();
mSupportsDXT1Textures = mDisplay->getDXT1TextureSupport();
mSupportsDXT3Textures = mDisplay->getDXT3TextureSupport();
mSupportsDXT5Textures = mDisplay->getDXT5TextureSupport();
mSupportsFloatTextures = mDisplay->getFloatTextureSupport(&mSupportsFloatLinearFilter, &mSupportsFloatRenderableTextures);
mSupportsHalfFloatTextures = mDisplay->getHalfFloatTextureSupport(&mSupportsHalfFloatLinearFilter, &mSupportsHalfFloatRenderableTextures);
mSupportsLuminanceTextures = mDisplay->getLuminanceTextureSupport();
mSupportsLuminanceAlphaTextures = mDisplay->getLuminanceAlphaTextureSupport();
mSupports32bitIndices = mDeviceCaps.MaxVertexIndex >= (1 << 16);
@ -1620,8 +1624,6 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
// scissor rectangle to the Direct3D 9 device
bool Context::applyRenderTarget(bool ignoreViewport)
{
IDirect3DDevice9 *device = getDevice();
Framebuffer *framebufferObject = getDrawFramebuffer();
if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
@ -1642,7 +1644,7 @@ bool Context::applyRenderTarget(bool ignoreViewport)
{
return false; // Context must be lost
}
device->SetRenderTarget(0, renderTarget);
mDevice->SetRenderTarget(0, renderTarget);
mAppliedRenderTargetSerial = renderTargetSerial;
mScissorStateDirty = true; // Scissor area must be clamped to render target's size-- this is different for different render targets.
renderTargetChanged = true;
@ -1677,7 +1679,7 @@ bool Context::applyRenderTarget(bool ignoreViewport)
stencilbufferSerial != mAppliedStencilbufferSerial ||
!mDepthStencilInitialized)
{
device->SetDepthStencilSurface(depthStencil);
mDevice->SetDepthStencilSurface(depthStencil);
mAppliedDepthbufferSerial = depthbufferSerial;
mAppliedStencilbufferSerial = stencilbufferSerial;
mDepthStencilInitialized = true;
@ -1730,7 +1732,7 @@ bool Context::applyRenderTarget(bool ignoreViewport)
if (!mViewportInitialized || memcmp(&viewport, &mSetViewport, sizeof mSetViewport) != 0)
{
device->SetViewport(&viewport);
mDevice->SetViewport(&viewport);
mSetViewport = viewport;
mViewportInitialized = true;
mDxUniformsDirty = true;
@ -1745,12 +1747,12 @@ bool Context::applyRenderTarget(bool ignoreViewport)
rect.top = clamp(rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
rect.right = clamp(rect.right, 0L, static_cast<LONG>(mRenderTargetDesc.Width));
rect.bottom = clamp(rect.bottom, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
device->SetScissorRect(&rect);
device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
mDevice->SetScissorRect(&rect);
mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
}
else
{
device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
}
mScissorStateDirty = false;
@ -1786,7 +1788,6 @@ bool Context::applyRenderTarget(bool ignoreViewport)
// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
void Context::applyState(GLenum drawMode)
{
IDirect3DDevice9 *device = getDevice();
Program *programObject = getCurrentProgram();
Framebuffer *framebufferObject = getDrawFramebuffer();
@ -1801,8 +1802,7 @@ void Context::applyState(GLenum drawMode)
GLint alwaysFront = !isTriangleMode(drawMode);
programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront);
egl::Display *display = getDisplay();
D3DADAPTER_IDENTIFIER9 *identifier = display->getAdapterIdentifier();
D3DADAPTER_IDENTIFIER9 *identifier = mDisplay->getAdapterIdentifier();
bool zeroColorMaskAllowed = identifier->VendorId != 0x1002;
// Apparently some ATI cards have a bug where a draw with a zero color
// write mask can cause later draws to have incorrect results. Instead,
@ -1814,11 +1814,11 @@ void Context::applyState(GLenum drawMode)
{
if (mState.cullFace)
{
device->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, adjustedFrontFace));
mDevice->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, adjustedFrontFace));
}
else
{
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
}
mCullStateDirty = false;
@ -1828,12 +1828,12 @@ void Context::applyState(GLenum drawMode)
{
if (mState.depthTest)
{
device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
device->SetRenderState(D3DRS_ZFUNC, es2dx::ConvertComparison(mState.depthFunc));
mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
mDevice->SetRenderState(D3DRS_ZFUNC, es2dx::ConvertComparison(mState.depthFunc));
}
else
{
device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
}
mDepthStateDirty = false;
@ -1849,43 +1849,43 @@ void Context::applyState(GLenum drawMode)
{
if (mState.blend)
{
device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
if (mState.sourceBlendRGB != GL_CONSTANT_ALPHA && mState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
mState.destBlendRGB != GL_CONSTANT_ALPHA && mState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
{
device->SetRenderState(D3DRS_BLENDFACTOR, es2dx::ConvertColor(mState.blendColor));
mDevice->SetRenderState(D3DRS_BLENDFACTOR, es2dx::ConvertColor(mState.blendColor));
}
else
{
device->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(unorm<8>(mState.blendColor.alpha),
mDevice->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(unorm<8>(mState.blendColor.alpha),
unorm<8>(mState.blendColor.alpha),
unorm<8>(mState.blendColor.alpha),
unorm<8>(mState.blendColor.alpha)));
}
device->SetRenderState(D3DRS_SRCBLEND, es2dx::ConvertBlendFunc(mState.sourceBlendRGB));
device->SetRenderState(D3DRS_DESTBLEND, es2dx::ConvertBlendFunc(mState.destBlendRGB));
device->SetRenderState(D3DRS_BLENDOP, es2dx::ConvertBlendOp(mState.blendEquationRGB));
mDevice->SetRenderState(D3DRS_SRCBLEND, es2dx::ConvertBlendFunc(mState.sourceBlendRGB));
mDevice->SetRenderState(D3DRS_DESTBLEND, es2dx::ConvertBlendFunc(mState.destBlendRGB));
mDevice->SetRenderState(D3DRS_BLENDOP, es2dx::ConvertBlendOp(mState.blendEquationRGB));
if (mState.sourceBlendRGB != mState.sourceBlendAlpha ||
mState.destBlendRGB != mState.destBlendAlpha ||
mState.blendEquationRGB != mState.blendEquationAlpha)
{
device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
device->SetRenderState(D3DRS_SRCBLENDALPHA, es2dx::ConvertBlendFunc(mState.sourceBlendAlpha));
device->SetRenderState(D3DRS_DESTBLENDALPHA, es2dx::ConvertBlendFunc(mState.destBlendAlpha));
device->SetRenderState(D3DRS_BLENDOPALPHA, es2dx::ConvertBlendOp(mState.blendEquationAlpha));
mDevice->SetRenderState(D3DRS_SRCBLENDALPHA, es2dx::ConvertBlendFunc(mState.sourceBlendAlpha));
mDevice->SetRenderState(D3DRS_DESTBLENDALPHA, es2dx::ConvertBlendFunc(mState.destBlendAlpha));
mDevice->SetRenderState(D3DRS_BLENDOPALPHA, es2dx::ConvertBlendOp(mState.blendEquationAlpha));
}
else
{
device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
}
}
else
{
device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
mBlendStateDirty = false;
@ -1895,8 +1895,8 @@ void Context::applyState(GLenum drawMode)
{
if (mState.stencilTest && framebufferObject->hasStencil())
{
device->SetRenderState(D3DRS_STENCILENABLE, TRUE);
device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
// FIXME: Unsupported by D3D9
const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF;
@ -1914,37 +1914,37 @@ void Context::applyState(GLenum drawMode)
gl::DepthStencilbuffer *stencilbuffer = framebufferObject->getStencilbuffer();
GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask);
device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask);
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
es2dx::ConvertComparison(mState.stencilFunc));
device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask);
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask);
device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
es2dx::ConvertStencilOp(mState.stencilFail));
device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
es2dx::ConvertStencilOp(mState.stencilPassDepthFail));
device->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
es2dx::ConvertStencilOp(mState.stencilPassDepthPass));
device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask);
device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask);
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
es2dx::ConvertComparison(mState.stencilBackFunc));
device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask);
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask);
device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
es2dx::ConvertStencilOp(mState.stencilBackFail));
device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
es2dx::ConvertStencilOp(mState.stencilBackPassDepthFail));
device->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
es2dx::ConvertStencilOp(mState.stencilBackPassDepthPass));
}
else
{
device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
}
mStencilStateDirty = false;
@ -1958,18 +1958,18 @@ void Context::applyState(GLenum drawMode)
if (colorMask == 0 && !zeroColorMaskAllowed)
{
// Enable green channel, but set blending so nothing will be drawn.
device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN);
device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN);
mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
}
else
{
device->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask);
mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask);
}
device->SetRenderState(D3DRS_ZWRITEENABLE, mState.depthMask ? TRUE : FALSE);
mDevice->SetRenderState(D3DRS_ZWRITEENABLE, mState.depthMask ? TRUE : FALSE);
mMaskStateDirty = false;
}
@ -1981,15 +1981,15 @@ void Context::applyState(GLenum drawMode)
gl::DepthStencilbuffer *depthbuffer = framebufferObject->getDepthbuffer();
if (depthbuffer)
{
device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *((DWORD*)&mState.polygonOffsetFactor));
mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *((DWORD*)&mState.polygonOffsetFactor));
float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
device->SetRenderState(D3DRS_DEPTHBIAS, *((DWORD*)&depthBias));
mDevice->SetRenderState(D3DRS_DEPTHBIAS, *((DWORD*)&depthBias));
}
}
else
{
device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
device->SetRenderState(D3DRS_DEPTHBIAS, 0);
mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
mDevice->SetRenderState(D3DRS_DEPTHBIAS, 0);
}
mPolygonOffsetStateDirty = false;
@ -2002,7 +2002,7 @@ void Context::applyState(GLenum drawMode)
FIXME("Sample alpha to coverage is unimplemented.");
}
device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
mDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
if (mState.sampleCoverage)
{
unsigned int mask = 0;
@ -2027,11 +2027,11 @@ void Context::applyState(GLenum drawMode)
mask = ~mask;
}
device->SetRenderState(D3DRS_MULTISAMPLEMASK, mask);
mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, mask);
}
else
{
device->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
}
mSampleStateDirty = false;
@ -2039,7 +2039,7 @@ void Context::applyState(GLenum drawMode)
if (mDitherStateDirty)
{
device->SetRenderState(D3DRS_DITHERENABLE, mState.dither ? TRUE : FALSE);
mDevice->SetRenderState(D3DRS_DITHERENABLE, mState.dither ? TRUE : FALSE);
mDitherStateDirty = false;
}
@ -2055,20 +2055,19 @@ GLenum Context::applyVertexBuffer(GLint first, GLsizei count)
return err;
}
return mVertexDeclarationCache.applyDeclaration(attributes, getCurrentProgram());
return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, getCurrentProgram());
}
// Applies the indices and element array bindings to the Direct3D 9 device
GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
{
IDirect3DDevice9 *device = getDevice();
GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
if (err == GL_NO_ERROR)
{
if (indexInfo->serial != mAppliedIBSerial)
{
device->SetIndices(indexInfo->indexBuffer);
mDevice->SetIndices(indexInfo->indexBuffer);
mAppliedIBSerial = indexInfo->serial;
}
}
@ -2079,15 +2078,14 @@ GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode
// Applies the shaders and shader constants to the Direct3D 9 device
void Context::applyShaders()
{
IDirect3DDevice9 *device = getDevice();
Program *programObject = getCurrentProgram();
if (programObject->getSerial() != mAppliedProgramSerial)
{
IDirect3DVertexShader9 *vertexShader = programObject->getVertexShader();
IDirect3DPixelShader9 *pixelShader = programObject->getPixelShader();
device->SetPixelShader(pixelShader);
device->SetVertexShader(vertexShader);
mDevice->SetPixelShader(pixelShader);
mDevice->SetVertexShader(vertexShader);
programObject->dirtyAllUniforms();
mAppliedProgramSerial = programObject->getSerial();
}
@ -2111,7 +2109,6 @@ void Context::applyTextures()
// and sets the texture and its addressing/filtering state (or NULL when inactive).
void Context::applyTextures(SamplerType type)
{
IDirect3DDevice9 *device = getDevice();
Program *programObject = getCurrentProgram();
int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; // Range of Direct3D 9 samplers of given sampler type
@ -2143,24 +2140,24 @@ void Context::applyTextures(SamplerType type)
GLenum minFilter = texture->getMinFilter();
GLenum magFilter = texture->getMagFilter();
device->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS));
device->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT));
mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS));
mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT));
device->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter));
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter));
D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter);
device->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
device->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
}
if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyImage())
{
device->SetTexture(d3dSampler, d3dTexture);
mDevice->SetTexture(d3dSampler, d3dTexture);
}
}
else
{
device->SetTexture(d3dSampler, getIncompleteTexture(textureType)->getTexture());
mDevice->SetTexture(d3dSampler, getIncompleteTexture(textureType)->getTexture());
}
appliedTextureSerial[samplerIndex] = texture->getSerial();
@ -2171,7 +2168,7 @@ void Context::applyTextures(SamplerType type)
{
if (appliedTextureSerial[samplerIndex] != 0)
{
device->SetTexture(d3dSampler, NULL);
mDevice->SetTexture(d3dSampler, NULL);
appliedTextureSerial[samplerIndex] = 0;
}
}
@ -2181,7 +2178,7 @@ void Context::applyTextures(SamplerType type)
{
if (appliedTextureSerial[samplerIndex] != 0)
{
device->SetTexture(samplerIndex + d3dSamplerOffset, NULL);
mDevice->SetTexture(samplerIndex + d3dSamplerOffset, NULL);
appliedTextureSerial[samplerIndex] = 0;
}
}
@ -2208,13 +2205,11 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
return; // Context must be lost, return silently
}
IDirect3DDevice9 *device = getDevice();
D3DSURFACE_DESC desc;
renderTarget->GetDesc(&desc);
IDirect3DSurface9 *systemSurface;
HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &systemSurface, NULL);
HRESULT result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &systemSurface, NULL);
if (FAILED(result))
{
@ -2228,7 +2223,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
return error(GL_OUT_OF_MEMORY);
}
result = device->GetRenderTargetData(renderTarget, systemSurface);
result = mDevice->GetRenderTargetData(renderTarget, systemSurface);
if (FAILED(result))
{
@ -2457,8 +2452,6 @@ void Context::clear(GLbitfield mask)
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = getDevice();
DWORD flags = 0;
if (mask & GL_COLOR_BUFFER_BIT)
@ -2550,32 +2543,32 @@ void Context::clear(GLbitfield mask)
HRESULT hr;
if (mMaskedClearSavedState == NULL)
{
hr = device->BeginStateBlock();
hr = mDevice->BeginStateBlock();
ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
device->SetRenderState(D3DRS_ZENABLE, FALSE);
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
device->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
device->SetStreamSource(0, NULL, 0, 0);
device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
device->SetRenderState(D3DRS_TEXTUREFACTOR, color);
device->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
mDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
mDevice->SetPixelShader(NULL);
mDevice->SetVertexShader(NULL);
mDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
mDevice->SetStreamSource(0, NULL, 0, 0);
mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color);
mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
hr = device->EndStateBlock(&mMaskedClearSavedState);
hr = mDevice->EndStateBlock(&mMaskedClearSavedState);
ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
}
@ -2587,51 +2580,51 @@ void Context::clear(GLbitfield mask)
ASSERT(SUCCEEDED(hr));
}
device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
device->SetRenderState(D3DRS_ZENABLE, FALSE);
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
mDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
if (flags & D3DCLEAR_TARGET)
{
device->SetRenderState(D3DRS_COLORWRITEENABLE, es2dx::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, es2dx::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
}
else
{
device->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
}
if (stencilUnmasked != 0x0 && (flags & D3DCLEAR_STENCIL))
{
device->SetRenderState(D3DRS_STENCILENABLE, TRUE);
device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
device->SetRenderState(D3DRS_STENCILREF, stencil);
device->SetRenderState(D3DRS_STENCILWRITEMASK, mState.stencilWritemask);
device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE);
device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE);
device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
mDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
mDevice->SetRenderState(D3DRS_STENCILREF, stencil);
mDevice->SetRenderState(D3DRS_STENCILWRITEMASK, mState.stencilWritemask);
mDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE);
mDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE);
mDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
mStencilStateDirty = true;
}
else
{
device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
}
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW);
device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
device->SetRenderState(D3DRS_TEXTUREFACTOR, color);
device->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
mDevice->SetPixelShader(NULL);
mDevice->SetVertexShader(NULL);
mDevice->SetFVF(D3DFVF_XYZRHW);
mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color);
mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges
quad[0][0] = -0.5f;
@ -2654,14 +2647,14 @@ void Context::clear(GLbitfield mask)
quad[3][2] = 0.0f;
quad[3][3] = 1.0f;
display->startScene();
device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4]));
mDisplay->startScene();
mDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4]));
if (flags & D3DCLEAR_ZBUFFER)
{
device->SetRenderState(D3DRS_ZENABLE, TRUE);
device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
device->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil);
mDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
mDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
mDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil);
}
if (mMaskedClearSavedState != NULL)
@ -2671,7 +2664,7 @@ void Context::clear(GLbitfield mask)
}
else if (flags)
{
device->Clear(0, NULL, flags, color, depth, stencil);
mDevice->Clear(0, NULL, flags, color, depth, stencil);
}
}
@ -2682,8 +2675,6 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
return error(GL_INVALID_OPERATION);
}
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = getDevice();
D3DPRIMITIVETYPE primitiveType;
int primitiveCount;
@ -2718,9 +2709,9 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
if (!cullSkipsDraw(mode))
{
display->startScene();
mDisplay->startScene();
device->DrawPrimitive(primitiveType, 0, primitiveCount);
mDevice->DrawPrimitive(primitiveType, 0, primitiveCount);
if (mode == GL_LINE_LOOP) // Draw the last segment separately
{
@ -2741,8 +2732,6 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *
return error(GL_INVALID_OPERATION);
}
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = getDevice();
D3DPRIMITIVETYPE primitiveType;
int primitiveCount;
@ -2785,9 +2774,9 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *
if (!cullSkipsDraw(mode))
{
display->startScene();
mDisplay->startScene();
device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount);
mDevice->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount);
if (mode == GL_LINE_LOOP) // Draw the last segment separately
{
@ -2796,92 +2785,13 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *
}
}
void Context::finish()
// Implements glFlush when block is false, glFinish when block is true
void Context::sync(bool block)
{
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = getDevice();
IDirect3DQuery9 *occlusionQuery = NULL;
HRESULT result;
result = device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery);
if (FAILED(result))
{
ERR("CreateQuery failed hr=%x\n", result);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return error(GL_OUT_OF_MEMORY);
}
ASSERT(false);
return;
}
IDirect3DStateBlock9 *savedState = NULL;
result = device->CreateStateBlock(D3DSBT_ALL, &savedState);
if (FAILED(result))
{
ERR("CreateStateBlock failed hr=%x\n", result);
occlusionQuery->Release();
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return error(GL_OUT_OF_MEMORY);
}
ASSERT(false);
return;
}
result = occlusionQuery->Issue(D3DISSUE_BEGIN);
if (FAILED(result))
{
ERR("occlusionQuery->Issue(BEGIN) failed hr=%x\n", result);
occlusionQuery->Release();
savedState->Release();
ASSERT(false);
return;
}
// Render something outside the render target
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW);
float data[4] = {-1.0f, -1.0f, -1.0f, 1.0f};
display->startScene();
device->DrawPrimitiveUP(D3DPT_POINTLIST, 1, data, sizeof(data));
result = occlusionQuery->Issue(D3DISSUE_END);
if (FAILED(result))
{
ERR("occlusionQuery->Issue(END) failed hr=%x\n", result);
occlusionQuery->Release();
savedState->Apply();
savedState->Release();
ASSERT(false);
return;
}
while ((result = occlusionQuery->GetData(NULL, 0, D3DGETDATA_FLUSH)) == S_FALSE)
{
// Keep polling, but allow other threads to do something useful first
Sleep(0);
}
occlusionQuery->Release();
savedState->Apply();
savedState->Release();
if (result == D3DERR_DEVICELOST)
{
error(GL_OUT_OF_MEMORY);
}
}
void Context::flush()
{
IDirect3DDevice9 *device = getDevice();
IDirect3DQuery9 *eventQuery = NULL;
HRESULT result;
result = device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery);
result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery);
if (FAILED(result))
{
ERR("CreateQuery failed hr=%x\n", result);
@ -2902,7 +2812,18 @@ void Context::flush()
return;
}
result = eventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
do
{
result = eventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
if(block && result == S_FALSE)
{
// Keep polling, but allow other threads to do something useful first
Sleep(0);
}
}
while(block && result == S_FALSE);
eventQuery->Release();
if (result == D3DERR_DEVICELOST)
@ -2913,7 +2834,6 @@ void Context::flush()
void Context::drawClosingLine(unsigned int first, unsigned int last)
{
IDirect3DDevice9 *device = getDevice();
IDirect3DIndexBuffer9 *indexBuffer = NULL;
bool succeeded = false;
UINT offset;
@ -2924,7 +2844,7 @@ void Context::drawClosingLine(unsigned int first, unsigned int last)
if (!mClosingIB)
{
mClosingIB = new StreamingIndexBuffer(device, CLOSING_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
mClosingIB = new StreamingIndexBuffer(mDevice, CLOSING_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
}
mClosingIB->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
@ -2945,7 +2865,7 @@ void Context::drawClosingLine(unsigned int first, unsigned int last)
if (!mClosingIB)
{
mClosingIB = new StreamingIndexBuffer(device, CLOSING_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
mClosingIB = new StreamingIndexBuffer(mDevice, CLOSING_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
}
mClosingIB->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
@ -2963,10 +2883,10 @@ void Context::drawClosingLine(unsigned int first, unsigned int last)
if (succeeded)
{
device->SetIndices(mClosingIB->getBuffer());
mDevice->SetIndices(mClosingIB->getBuffer());
mAppliedIBSerial = mClosingIB->getSerial();
device->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, last, offset, 1);
mDevice->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, last, offset, 1);
}
else
{
@ -3493,8 +3413,7 @@ const char *Context::getExtensionString() const
void Context::initRendererString()
{
egl::Display *display = getDisplay();
D3DADAPTER_IDENTIFIER9 *identifier = display->getAdapterIdentifier();
D3DADAPTER_IDENTIFIER9 *identifier = mDisplay->getAdapterIdentifier();
mRendererString = "ANGLE (";
mRendererString += identifier->Description;
@ -3510,8 +3429,6 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask)
{
IDirect3DDevice9 *device = getDevice();
Framebuffer *readFramebuffer = getReadFramebuffer();
Framebuffer *drawFramebuffer = getDrawFramebuffer();
@ -3752,12 +3669,11 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if (blitRenderTarget || blitDepthStencil)
{
egl::Display *display = getDisplay();
display->endScene();
mDisplay->endScene();
if (blitRenderTarget)
{
HRESULT result = device->StretchRect(readFramebuffer->getRenderTarget(), &sourceTrimmedRect,
HRESULT result = mDevice->StretchRect(readFramebuffer->getRenderTarget(), &sourceTrimmedRect,
drawFramebuffer->getRenderTarget(), &destTrimmedRect, D3DTEXF_NONE);
if (FAILED(result))
@ -3769,7 +3685,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if (blitDepthStencil)
{
HRESULT result = device->StretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, D3DTEXF_NONE);
HRESULT result = mDevice->StretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, D3DTEXF_NONE);
if (FAILED(result))
{
@ -3800,10 +3716,8 @@ VertexDeclarationCache::~VertexDeclarationCache()
}
}
GLenum VertexDeclarationCache::applyDeclaration(TranslatedAttribute attributes[], Program *program)
GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], Program *program)
{
IDirect3DDevice9 *device = getDevice();
D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS + 1];
D3DVERTEXELEMENT9 *element = &elements[0];

View File

@ -228,7 +228,7 @@ class VertexDeclarationCache
VertexDeclarationCache();
~VertexDeclarationCache();
GLenum applyDeclaration(TranslatedAttribute attributes[], Program *program);
GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], Program *program);
void markStateDirty();
@ -421,8 +421,7 @@ class Context
void clear(GLbitfield mask);
void drawArrays(GLenum mode, GLint first, GLsizei count);
void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
void finish();
void flush();
void sync(bool block); // flush/finish
// Draw the last segment of a line loop
void drawClosingLine(unsigned int first, unsigned int last);
@ -497,6 +496,8 @@ class Context
void initRendererString();
const egl::Config *const mConfig;
egl::Display *mDisplay;
IDirect3DDevice9 *mDevice;
State mState;

View File

@ -59,6 +59,7 @@ UniformLocation::UniformLocation(const std::string &_name, unsigned int element,
Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle), mSerial(issueSerial())
{
mDevice = getDevice();
mFragmentShader = NULL;
mVertexShader = NULL;
@ -1675,9 +1676,8 @@ void Program::link()
if (vertexBinary && pixelBinary)
{
IDirect3DDevice9 *device = getDevice();
HRESULT vertexResult = device->CreateVertexShader((DWORD*)vertexBinary->GetBufferPointer(), &mVertexExecutable);
HRESULT pixelResult = device->CreatePixelShader((DWORD*)pixelBinary->GetBufferPointer(), &mPixelExecutable);
HRESULT vertexResult = mDevice->CreateVertexShader((DWORD*)vertexBinary->GetBufferPointer(), &mVertexExecutable);
HRESULT pixelResult = mDevice->CreatePixelShader((DWORD*)pixelBinary->GetBufferPointer(), &mPixelExecutable);
if (vertexResult == D3DERR_OUTOFVIDEOMEMORY || vertexResult == E_OUTOFMEMORY || pixelResult == D3DERR_OUTOFVIDEOMEMORY || pixelResult == E_OUTOFMEMORY)
{
@ -2051,8 +2051,6 @@ std::string Program::undecorateUniform(const std::string &_name)
void Program::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v)
{
IDirect3DDevice9 *device = getDevice();
float *vector = NULL;
BOOL *boolVector = NULL;
@ -2091,11 +2089,11 @@ void Program::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width,
{
if (targetUniform->ps.registerSet == D3DXRS_FLOAT4)
{
device->SetPixelShaderConstantF(targetUniform->ps.registerIndex, vector, targetUniform->ps.registerCount);
mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, vector, targetUniform->ps.registerCount);
}
else if (targetUniform->ps.registerSet == D3DXRS_BOOL)
{
device->SetPixelShaderConstantB(targetUniform->ps.registerIndex, boolVector, targetUniform->ps.registerCount);
mDevice->SetPixelShaderConstantB(targetUniform->ps.registerIndex, boolVector, targetUniform->ps.registerCount);
}
else UNREACHABLE();
}
@ -2104,11 +2102,11 @@ void Program::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width,
{
if (targetUniform->vs.registerSet == D3DXRS_FLOAT4)
{
device->SetVertexShaderConstantF(targetUniform->vs.registerIndex, vector, targetUniform->vs.registerCount);
mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, vector, targetUniform->vs.registerCount);
}
else if (targetUniform->vs.registerSet == D3DXRS_BOOL)
{
device->SetVertexShaderConstantB(targetUniform->vs.registerIndex, boolVector, targetUniform->vs.registerCount);
mDevice->SetVertexShaderConstantB(targetUniform->vs.registerIndex, boolVector, targetUniform->vs.registerCount);
}
else UNREACHABLE();
}
@ -2119,16 +2117,14 @@ void Program::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width,
bool Program::applyUniformnfv(Uniform *targetUniform, const GLfloat *v)
{
IDirect3DDevice9 *device = getDevice();
if (targetUniform->ps.registerCount)
{
device->SetPixelShaderConstantF(targetUniform->ps.registerIndex, v, targetUniform->ps.registerCount);
mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, v, targetUniform->ps.registerCount);
}
if (targetUniform->vs.registerCount)
{
device->SetVertexShaderConstantF(targetUniform->vs.registerIndex, v, targetUniform->vs.registerCount);
mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, v, targetUniform->vs.registerCount);
}
return true;
@ -2143,8 +2139,6 @@ bool Program::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint
vector[i] = D3DXVECTOR4((float)v[i], 0, 0, 0);
}
IDirect3DDevice9 *device = getDevice();
if (targetUniform->ps.registerCount)
{
if (targetUniform->ps.registerSet == D3DXRS_SAMPLER)
@ -2165,7 +2159,7 @@ bool Program::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint
else
{
ASSERT(targetUniform->ps.registerSet == D3DXRS_FLOAT4);
device->SetPixelShaderConstantF(targetUniform->ps.registerIndex, (const float*)vector, targetUniform->ps.registerCount);
mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, (const float*)vector, targetUniform->ps.registerCount);
}
}
@ -2189,7 +2183,7 @@ bool Program::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint
else
{
ASSERT(targetUniform->vs.registerSet == D3DXRS_FLOAT4);
device->SetVertexShaderConstantF(targetUniform->vs.registerIndex, (const float *)vector, targetUniform->vs.registerCount);
mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, (const float *)vector, targetUniform->vs.registerCount);
}
}
@ -2254,18 +2248,16 @@ bool Program::applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint
void Program::applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector)
{
IDirect3DDevice9 *device = getDevice();
if (targetUniform->ps.registerCount)
{
ASSERT(targetUniform->ps.registerSet == D3DXRS_FLOAT4);
device->SetPixelShaderConstantF(targetUniform->ps.registerIndex, (const float *)vector, targetUniform->ps.registerCount);
mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, (const float *)vector, targetUniform->ps.registerCount);
}
if (targetUniform->vs.registerCount)
{
ASSERT(targetUniform->vs.registerSet == D3DXRS_FLOAT4);
device->SetVertexShaderConstantF(targetUniform->vs.registerIndex, (const float *)vector, targetUniform->vs.registerCount);
mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, (const float *)vector, targetUniform->vs.registerCount);
}
}

View File

@ -172,6 +172,7 @@ class Program
static unsigned int issueSerial();
IDirect3DDevice9 *mDevice;
FragmentShader *mFragmentShader;
VertexShader *mVertexShader;

View File

@ -1951,7 +1951,7 @@ void __stdcall glFinish(void)
if (context)
{
context->finish();
context->sync(true);
}
}
catch(std::bad_alloc&)
@ -1970,7 +1970,7 @@ void __stdcall glFlush(void)
if (context)
{
context->flush();
context->sync(false);
}
}
catch(std::bad_alloc&)

View File

@ -794,12 +794,10 @@ CairoImageOGL::SetData(const CairoImage::Data &aData)
}
#endif
InitTexture(gl, tex, LOCAL_GL_RGBA, mSize);
mLayerProgram =
gl->UploadSurfaceToTexture(aData.mSurface,
nsIntRect(0,0, mSize.width, mSize.height),
tex);
tex, true);
}
void CairoImageOGL::SetTiling(bool aTiling)

View File

@ -417,11 +417,6 @@ class HashTable : private AllocPolicy
destroyTable(*this, table, tableCapacity);
}
size_t allocatedSize() const
{
return sizeof(Entry) * tableCapacity;
}
private:
static HashNumber hash1(HashNumber hash0, uint32 shift) {
return hash0 >> shift;
@ -1135,9 +1130,6 @@ class HashMap
*/
unsigned generation() const { return impl.generation(); }
/* Number of bytes of heap data allocated by this table. */
size_t allocatedSize() const { return impl.allocatedSize(); }
/* Shorthand operations: */
bool has(const Lookup &l) const {
@ -1338,9 +1330,6 @@ class HashSet
*/
unsigned generation() const { return impl.generation(); }
/* Number of bytes of heap data allocated by this table. */
size_t allocatedSize() const { return impl.allocatedSize(); }
/* Shorthand operations: */
bool has(const Lookup &l) const {

View File

@ -74,10 +74,10 @@ AlignPtr(void *orig)
/* Header for a chunk of memory wrangled by the LifoAlloc. */
class BumpChunk
{
char *bump;
char *limit;
BumpChunk *next_;
size_t bumpSpaceSize;
char *bump; /* start of the available data */
char *limit; /* end of the data */
BumpChunk *next_; /* the next BumpChunk */
size_t bumpSpaceSize; /* size of the data area */
char *headerBase() { return reinterpret_cast<char *>(this); }
char *bumpBase() const { return limit - bumpSpaceSize; }
@ -111,6 +111,10 @@ class BumpChunk
void setNext(BumpChunk *succ) { next_ = succ; }
size_t used() const { return bump - bumpBase(); }
size_t sizeOf(JSUsableSizeFun usf) {
size_t usable = usf((void*)this);
return usable ? usable : limit - headerBase();
}
void resetBump() {
setBump(headerBase() + sizeof(BumpChunk));
@ -290,6 +294,22 @@ class LifoAlloc
return accum;
}
/* Get the total size of the arena chunks (including unused space), plus,
* if |countMe| is true, the size of the LifoAlloc itself. */
size_t sizeOf(JSUsableSizeFun usf, bool countMe) const {
size_t accum = 0;
if (countMe) {
size_t usable = usf((void*)this);
accum += usable ? usable : sizeof(LifoAlloc);
}
BumpChunk *it = first;
while (it) {
accum += it->sizeOf(usf);
it = it->next();
}
return accum;
}
/* Doesn't perform construction; useful for lazily-initialized POD types. */
template <typename T>
JS_ALWAYS_INLINE

View File

@ -2878,17 +2878,8 @@ EmitPropOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce,
op = JSOP_CALLPROP;
} else if (op == JSOP_GETPROP && pn->isKind(TOK_DOT)) {
if (pn2->isKind(TOK_NAME)) {
/*
* Try to optimize arguments.length into JSOP_ARGCNT. If type
* inference is enabled this is optimized separately.
*/
if (!BindNameToSlot(cx, bce, pn2))
return false;
if (!cx->typeInferenceEnabled() &&
pn->pn_atom == cx->runtime->atomState.lengthAtom) {
if (pn2->isOp(JSOP_ARGUMENTS))
return Emit1(cx, bce, JSOP_ARGCNT) >= 0;
}
}
}
@ -3066,124 +3057,51 @@ EmitNameIncDec(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
static JSBool
EmitElemOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
{
ptrdiff_t top;
ParseNode *left, *right, *next;
int32_t slot;
ParseNode *left, *right;
top = bce->offset();
if (pn->isArity(PN_LIST)) {
/* Left-associative operator chain to avoid too much recursion. */
JS_ASSERT(pn->isOp(JSOP_GETELEM));
JS_ASSERT(pn->pn_count >= 3);
left = pn->pn_head;
right = pn->last();
next = left->pn_next;
JS_ASSERT(next != right);
ptrdiff_t top = bce->offset();
if (pn->isArity(PN_NAME)) {
/*
* Try to optimize arguments[0][j]... into JSOP_ARGSUB<0> followed by
* one or more index expression and JSOP_GETELEM op pairs. If type
* inference is enabled this is optimized separately.
* Set left and right so pn appears to be a TOK_LB node, instead
* of a TOK_DOT node. See the TOK_FOR/IN case in EmitTree, and
* EmitDestructuringOps nearer below. In the destructuring case,
* the base expression (pn_expr) of the name may be null, which
* means we have to emit a JSOP_BINDNAME.
*/
if (left->isKind(TOK_NAME) && next->isKind(TOK_NUMBER)) {
if (!BindNameToSlot(cx, bce, left))
left = pn->maybeExpr();
if (!left) {
left = NullaryNode::create(bce);
if (!left)
return false;
if (left->isOp(JSOP_ARGUMENTS) &&
JSDOUBLE_IS_INT32(next->pn_dval, &slot) &&
jsuint(slot) < JS_BIT(16) &&
!cx->typeInferenceEnabled() &&
(!bce->inStrictMode() ||
(!bce->mutatesParameter() && !bce->callsEval()))) {
/*
* arguments[i]() requires arguments object as "this".
* Check that we never generates list for that usage.
*/
JS_ASSERT(op != JSOP_CALLELEM || next->pn_next);
left->pn_offset = next->pn_offset = top;
EMIT_UINT16_IMM_OP(JSOP_ARGSUB, (jsatomid)slot);
left = next;
next = left->pn_next;
}
}
/*
* Check whether we generated JSOP_ARGSUB, just above, and have only
* one more index expression to emit. Given arguments[0][j], we must
* skip the while loop altogether, falling through to emit code for j
* (in the subtree referenced by right), followed by the annotated op,
* at the bottom of this function.
*/
JS_ASSERT(next != right || pn->pn_count == 3);
if (left == pn->pn_head) {
if (!EmitTree(cx, bce, left))
return false;
}
while (next != right) {
if (!EmitTree(cx, bce, next))
return false;
if (NewSrcNote2(cx, bce, SRC_PCBASE, bce->offset() - top) < 0)
return false;
if (!EmitElemOpBase(cx, bce, JSOP_GETELEM))
return false;
next = next->pn_next;
left->setKind(TOK_STRING);
left->setOp(JSOP_BINDNAME);
left->pn_pos = pn->pn_pos;
left->pn_atom = pn->pn_atom;
}
right = NullaryNode::create(bce);
if (!right)
return false;
right->setKind(TOK_STRING);
right->setOp(IsIdentifier(pn->pn_atom) ? JSOP_QNAMEPART : JSOP_STRING);
right->pn_pos = pn->pn_pos;
right->pn_atom = pn->pn_atom;
} else {
if (pn->isArity(PN_NAME)) {
/*
* Set left and right so pn appears to be a TOK_LB node, instead
* of a TOK_DOT node. See the TOK_FOR/IN case in EmitTree, and
* EmitDestructuringOps nearer below. In the destructuring case,
* the base expression (pn_expr) of the name may be null, which
* means we have to emit a JSOP_BINDNAME.
*/
left = pn->maybeExpr();
if (!left) {
left = NullaryNode::create(bce);
if (!left)
return false;
left->setKind(TOK_STRING);
left->setOp(JSOP_BINDNAME);
left->pn_pos = pn->pn_pos;
left->pn_atom = pn->pn_atom;
}
right = NullaryNode::create(bce);
if (!right)
return false;
right->setKind(TOK_STRING);
right->setOp(IsIdentifier(pn->pn_atom) ? JSOP_QNAMEPART : JSOP_STRING);
right->pn_pos = pn->pn_pos;
right->pn_atom = pn->pn_atom;
} else {
JS_ASSERT(pn->isArity(PN_BINARY));
left = pn->pn_left;
right = pn->pn_right;
}
JS_ASSERT(pn->isArity(PN_BINARY));
left = pn->pn_left;
right = pn->pn_right;
}
/*
* Try to optimize arguments[0] (e.g.) into JSOP_ARGSUB<0>. If type
* inference is enabled this is optimized separately.
*/
if (op == JSOP_GETELEM &&
left->isKind(TOK_NAME) &&
right->isKind(TOK_NUMBER)) {
if (!BindNameToSlot(cx, bce, left))
return false;
if (left->isOp(JSOP_ARGUMENTS) &&
JSDOUBLE_IS_INT32(right->pn_dval, &slot) &&
jsuint(slot) < JS_BIT(16) &&
!cx->typeInferenceEnabled() &&
(!bce->inStrictMode() ||
(!bce->mutatesParameter() && !bce->callsEval()))) {
left->pn_offset = right->pn_offset = top;
EMIT_UINT16_IMM_OP(JSOP_ARGSUB, (jsatomid)slot);
return true;
}
}
if (!EmitTree(cx, bce, left))
if (op == JSOP_GETELEM &&
left->isKind(TOK_NAME) &&
right->isKind(TOK_NUMBER)) {
if (!BindNameToSlot(cx, bce, left))
return false;
}
if (!EmitTree(cx, bce, left))
return false;
/* The right side of the descendant operator is implicitly quoted. */
JS_ASSERT(op != JSOP_DESCENDANTS || !right->isKind(TOK_STRING) ||
right->isOp(JSOP_QNAMEPART));

View File

@ -550,8 +550,6 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
case JSOP_LAMBDA_FC:
case JSOP_GETFCSLOT:
case JSOP_CALLFCSLOT:
case JSOP_ARGSUB:
case JSOP_ARGCNT:
case JSOP_DEBUGGER:
case JSOP_FUNCALL:
case JSOP_FUNAPPLY:

View File

@ -616,14 +616,13 @@ class Chars {
JSContext *cx;
jschar *p;
public:
Chars() : p(NULL) {}
Chars(JSContext *cx) : cx(cx), p(NULL) {}
~Chars() { if (p) cx->free_(p); }
bool allocate(JSContext *cx, size_t len) {
bool allocate(size_t len) {
JS_ASSERT(!p);
// We're going to null-terminate!
p = (jschar *) cx->malloc_((len + 1) * sizeof(jschar));
this->cx = cx;
if (p) {
p[len] = jschar(0);
return true;
@ -642,8 +641,8 @@ JSStructuredCloneReader::readString(uint32_t nchars)
"string length");
return NULL;
}
Chars chars;
if (!chars.allocate(context(), nchars) || !in.readChars(chars.get(), nchars))
Chars chars(context());
if (!chars.allocate(nchars) || !in.readChars(chars.get(), nchars))
return NULL;
JSString *str = js_NewString(context(), chars.get(), nchars);
if (str)

View File

@ -109,11 +109,13 @@ typedef struct TypeInferenceMemoryStats
extern JS_FRIEND_API(void)
JS_GetTypeInferenceMemoryStats(JSContext *cx, JSCompartment *compartment,
TypeInferenceMemoryStats *stats);
TypeInferenceMemoryStats *stats,
JSUsableSizeFun usf);
extern JS_FRIEND_API(void)
JS_GetTypeInferenceObjectStats(/*TypeObject*/ void *object,
TypeInferenceMemoryStats *stats);
TypeInferenceMemoryStats *stats,
JSUsableSizeFun usf);
extern JS_FRIEND_API(JSPrincipals *)
JS_GetCompartmentPrincipals(JSCompartment *compartment);

View File

@ -124,69 +124,6 @@ js_GetArgsValue(JSContext *cx, StackFrame *fp, Value *vp)
return JS_TRUE;
}
JSBool
js_GetArgsProperty(JSContext *cx, StackFrame *fp, jsid id, Value *vp)
{
JS_ASSERT(fp->isFunctionFrame());
if (fp->hasOverriddenArgs()) {
JS_ASSERT(fp->hasCallObj());
Value v;
if (!fp->callObj().getProperty(cx, cx->runtime->atomState.argumentsAtom, &v))
return false;
JSObject *obj;
if (v.isPrimitive()) {
obj = js_ValueToNonNullObject(cx, v);
if (!obj)
return false;
} else {
obj = &v.toObject();
}
return obj->getGeneric(cx, id, vp);
}
vp->setUndefined();
if (JSID_IS_INT(id)) {
uint32 arg = uint32(JSID_TO_INT(id));
ArgumentsObject *argsobj = fp->maybeArgsObj();
if (arg < fp->numActualArgs()) {
if (argsobj) {
const Value &v = argsobj->element(arg);
if (v.isMagic(JS_ARGS_HOLE))
return argsobj->getGeneric(cx, id, vp);
if (fp->functionScript()->strictModeCode) {
*vp = v;
return true;
}
}
*vp = fp->canonicalActualArg(arg);
} else {
/*
* Per ECMA-262 Ed. 3, 10.1.8, last bulleted item, do not share
* storage between the formal parameter and arguments[k] for all
* fp->argc <= k && k < fp->fun->nargs. For example, in
*
* function f(x) { x = 42; return arguments[0]; }
* f();
*
* the call to f should return undefined, not 42. If fp->argsobj
* is null at this point, as it would be in the example, return
* undefined in *vp.
*/
if (argsobj)
return argsobj->getGeneric(cx, id, vp);
}
} else if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
ArgumentsObject *argsobj = fp->maybeArgsObj();
if (argsobj && argsobj->hasOverriddenLength())
return argsobj->getGeneric(cx, id, vp);
vp->setInt32(fp->numActualArgs());
}
return true;
}
js::ArgumentsObject *
ArgumentsObject::create(JSContext *cx, uint32 argc, JSObject &callee)
{

View File

@ -536,9 +536,6 @@ SetCallUpvar(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp
extern JSBool
js_GetArgsValue(JSContext *cx, js::StackFrame *fp, js::Value *vp);
extern JSBool
js_GetArgsProperty(JSContext *cx, js::StackFrame *fp, jsid id, js::Value *vp);
/*
* Get the arguments object for the given frame. If the frame is strict mode
* code, its current arguments will be copied into the arguments object.

View File

@ -6106,7 +6106,11 @@ TypeScript::destroy()
inline size_t
TypeSet::dynamicSize()
{
/* Get the amount of memory allocated from the analysis pool for this set. */
/*
* This memory is allocated within the temp pool (but accounted for
* elsewhere) so we can't use a JSUsableSizeFun to measure it. We must do
* it analytically.
*/
uint32 count = baseObjectCount();
if (count >= 2)
return HashSetCapacity(count) * sizeof(TypeObject *);
@ -6116,6 +6120,11 @@ TypeSet::dynamicSize()
inline size_t
TypeObject::dynamicSize()
{
/*
* This memory is allocated within the temp pool (but accounted for
* elsewhere) so we can't use a JSUsableSizeFun to measure it. We must do
* it analytically.
*/
size_t bytes = 0;
uint32 count = basePropertyCount();
@ -6133,26 +6142,40 @@ TypeObject::dynamicSize()
}
static void
GetScriptMemoryStats(JSScript *script, TypeInferenceMemoryStats *stats)
GetScriptMemoryStats(JSScript *script, TypeInferenceMemoryStats *stats, JSUsableSizeFun usf)
{
if (!script->types)
TypeScript *typeScript = script->types;
if (!typeScript)
return;
size_t usable;
/* If TI is disabled, a single TypeScript is still present. */
if (!script->compartment()->types.inferenceEnabled) {
stats->scripts += sizeof(TypeScript);
usable = usf(typeScript);
stats->scripts += usable ? usable : sizeof(TypeScript);
return;
}
unsigned count = TypeScript::NumTypeSets(script);
stats->scripts += sizeof(TypeScript) + count * sizeof(TypeSet);
usable = usf(typeScript->nesting);
stats->scripts += usable ? usable : sizeof(TypeScriptNesting);
TypeResult *result = script->types->dynamicList;
unsigned count = TypeScript::NumTypeSets(script);
usable = usf(typeScript);
stats->scripts += usable ? usable : sizeof(TypeScript) + count * sizeof(TypeSet);
TypeResult *result = typeScript->dynamicList;
while (result) {
stats->scripts += sizeof(TypeResult);
usable = usf(result);
stats->scripts += usable ? usable : sizeof(TypeResult);
result = result->next;
}
TypeSet *typeArray = script->types->typeArray();
/*
* This counts memory that is in the temp pool but gets attributed
* elsewhere. See JS_GetTypeInferenceMemoryStats for more details.
*/
TypeSet *typeArray = typeScript->typeArray();
for (unsigned i = 0; i < count; i++) {
size_t bytes = typeArray[i].dynamicSize();
stats->scripts += bytes;
@ -6162,44 +6185,54 @@ GetScriptMemoryStats(JSScript *script, TypeInferenceMemoryStats *stats)
JS_FRIEND_API(void)
JS_GetTypeInferenceMemoryStats(JSContext *cx, JSCompartment *compartment,
TypeInferenceMemoryStats *stats)
TypeInferenceMemoryStats *stats, JSUsableSizeFun usf)
{
/*
* Note: not all data in the pool is temporary, and some will survive GCs
* by being copied to the replacement pool. This memory will be counted too
* and deducted from the amount of temporary data.
* by being copied to the replacement pool. This memory will be counted
* elsewhere and deducted from the amount of temporary data.
*/
stats->temporary += compartment->typeLifoAlloc.used();
stats->temporary += compartment->typeLifoAlloc.sizeOf(usf, /* countMe = */false);
/* Pending arrays are cleared on GC along with the analysis pool. */
stats->temporary += sizeof(TypeCompartment::PendingWork) * compartment->types.pendingCapacity;
size_t usable = usf(compartment->types.pendingArray);
stats->temporary +=
usable ? usable
: sizeof(TypeCompartment::PendingWork) * compartment->types.pendingCapacity;
/* TypeCompartment::pendingRecompiles is non-NULL only while inference code is running. */
JS_ASSERT(!compartment->types.pendingRecompiles);
for (gc::CellIter i(cx, compartment, gc::FINALIZE_SCRIPT); !i.done(); i.next())
GetScriptMemoryStats(i.get<JSScript>(), stats);
GetScriptMemoryStats(i.get<JSScript>(), stats, usf);
if (compartment->types.allocationSiteTable)
stats->tables += compartment->types.allocationSiteTable->allocatedSize();
stats->tables += compartment->types.allocationSiteTable->sizeOf(usf, /* countMe = */true);
if (compartment->types.arrayTypeTable)
stats->tables += compartment->types.arrayTypeTable->allocatedSize();
stats->tables += compartment->types.arrayTypeTable->sizeOf(usf, /* countMe = */true);
if (compartment->types.objectTypeTable) {
stats->tables += compartment->types.objectTypeTable->allocatedSize();
stats->tables += compartment->types.objectTypeTable->sizeOf(usf, /* countMe = */true);
for (ObjectTypeTable::Enum e(*compartment->types.objectTypeTable);
!e.empty();
e.popFront()) {
e.popFront())
{
const ObjectTableKey &key = e.front().key;
stats->tables += key.nslots * (sizeof(jsid) + sizeof(Type));
const ObjectTableEntry &value = e.front().value;
/* key.ids and values.types have the same length. */
usable = usf(key.ids) + usf(value.types);
stats->tables += usable ? usable : key.nslots * (sizeof(jsid) + sizeof(Type));
}
}
}
JS_FRIEND_API(void)
JS_GetTypeInferenceObjectStats(void *object_, TypeInferenceMemoryStats *stats)
JS_GetTypeInferenceObjectStats(void *object_, TypeInferenceMemoryStats *stats, JSUsableSizeFun usf)
{
TypeObject *object = (TypeObject *) object_;
stats->objects += sizeof(TypeObject);
if (object->singleton) {
/*
@ -6212,18 +6245,30 @@ JS_GetTypeInferenceObjectStats(void *object_, TypeInferenceMemoryStats *stats)
}
if (object->newScript) {
size_t length = 0;
for (TypeNewScript::Initializer *init = object->newScript->initializerList;; init++) {
length++;
if (init->kind == TypeNewScript::Initializer::DONE)
break;
/* The initializerList is tacked onto the end of the TypeNewScript. */
size_t usable = usf(object->newScript);
if (usable) {
stats->objects += usable;
} else {
stats->objects += sizeof(TypeNewScript);
for (TypeNewScript::Initializer *init = object->newScript->initializerList; ; init++) {
stats->objects += sizeof(TypeNewScript::Initializer);
if (init->kind == TypeNewScript::Initializer::DONE)
break;
}
}
stats->objects += sizeof(TypeNewScript) + (length * sizeof(TypeNewScript::Initializer));
}
if (object->emptyShapes)
stats->emptyShapes += sizeof(EmptyShape*) * gc::FINALIZE_FUNCTION_AND_OBJECT_LAST;
if (object->emptyShapes) {
size_t usable = usf(object->emptyShapes);
stats->emptyShapes +=
usable ? usable : sizeof(EmptyShape*) * gc::FINALIZE_FUNCTION_AND_OBJECT_LAST;
}
/*
* This counts memory that is in the temp pool but gets attributed
* elsewhere. See JS_GetTypeInferenceMemoryStats for more details.
*/
size_t bytes = object->dynamicSize();
stats->objects += bytes;
stats->temporary -= bytes;

View File

@ -1022,11 +1022,11 @@ class TypeScript
/* Global object for the script, if compileAndGo. */
js::GlobalObject *global;
public:
/* Nesting state for outer or inner function scripts. */
TypeScriptNesting *nesting;
public:
/* Dynamic types generated at points within this script. */
TypeResult *dynamicList;

View File

@ -4397,26 +4397,6 @@ BEGIN_CASE(JSOP_ARGUMENTS)
}
END_CASE(JSOP_ARGUMENTS)
BEGIN_CASE(JSOP_ARGSUB)
{
jsid id = INT_TO_JSID(GET_ARGNO(regs.pc));
Value rval;
if (!js_GetArgsProperty(cx, regs.fp(), id, &rval))
goto error;
PUSH_COPY(rval);
}
END_CASE(JSOP_ARGSUB)
BEGIN_CASE(JSOP_ARGCNT)
{
jsid id = ATOM_TO_JSID(rt->atomState.lengthAtom);
Value rval;
if (!js_GetArgsProperty(cx, regs.fp(), id, &rval))
goto error;
PUSH_COPY(rval);
}
END_CASE(JSOP_ARGCNT)
BEGIN_CASE(JSOP_GETARG)
BEGIN_CASE(JSOP_CALLARG)
{

View File

@ -3974,17 +3974,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
rval);
break;
case JSOP_ARGSUB:
i = (jsint) GET_ARGNO(pc);
todo = Sprint(&ss->sprinter, "%s[%d]",
js_arguments_str, (int) i);
break;
case JSOP_ARGCNT:
todo = Sprint(&ss->sprinter, dot_format,
js_arguments_str, js_length_str);
break;
case JSOP_CALLARG:
case JSOP_GETARG:
i = GET_ARGNO(pc);

View File

@ -373,82 +373,74 @@ OPDEF(JSOP_FINALLY, 135,"finally", NULL, 1, 0, 2, 0, JOF_BYTE)
OPDEF(JSOP_GETFCSLOT, 136,"getfcslot", NULL, 3, 0, 1, 19, JOF_UINT16|JOF_NAME|JOF_TYPESET)
OPDEF(JSOP_CALLFCSLOT, 137,"callfcslot", NULL, 3, 0, 2, 19, JOF_UINT16|JOF_NAME|JOF_TYPESET|JOF_CALLOP)
/*
* Bytecodes that avoid making an arguments object in most cases:
* JSOP_ARGSUB gets arguments[i] from fp->argv, iff i is in [0, fp->argc-1].
* JSOP_ARGCNT returns fp->argc.
*/
OPDEF(JSOP_ARGSUB, 138,"argsub", NULL, 3, 0, 1, 18, JOF_QARG |JOF_NAME)
OPDEF(JSOP_ARGCNT, 139,"argcnt", NULL, 1, 0, 1, 18, JOF_BYTE)
/*
* Define a local function object as a local variable.
* The local variable's slot number is the first immediate two-byte operand.
* The function object's atom index is the second immediate operand.
*/
OPDEF(JSOP_DEFLOCALFUN, 140,"deflocalfun",NULL, 5, 0, 0, 0, JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT)
OPDEF(JSOP_DEFLOCALFUN, 138,"deflocalfun",NULL, 5, 0, 0, 0, JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT)
/* Extended jumps. */
OPDEF(JSOP_GOTOX, 141,"gotox", NULL, 5, 0, 0, 0, JOF_JUMPX)
OPDEF(JSOP_IFEQX, 142,"ifeqx", NULL, 5, 1, 0, 4, JOF_JUMPX|JOF_DETECTING)
OPDEF(JSOP_IFNEX, 143,"ifnex", NULL, 5, 1, 0, 0, JOF_JUMPX|JOF_PARENHEAD)
OPDEF(JSOP_ORX, 144,"orx", NULL, 5, 1, 0, 5, JOF_JUMPX|JOF_DETECTING)
OPDEF(JSOP_ANDX, 145,"andx", NULL, 5, 1, 0, 6, JOF_JUMPX|JOF_DETECTING)
OPDEF(JSOP_GOSUBX, 146,"gosubx", NULL, 5, 0, 0, 0, JOF_JUMPX)
OPDEF(JSOP_CASEX, 147,"casex", NULL, 5, 2, 1, 0, JOF_JUMPX)
OPDEF(JSOP_DEFAULTX, 148,"defaultx", NULL, 5, 1, 0, 0, JOF_JUMPX)
OPDEF(JSOP_TABLESWITCHX, 149,"tableswitchx",NULL, -1, 1, 0, 0, JOF_TABLESWITCHX|JOF_DETECTING|JOF_PARENHEAD)
OPDEF(JSOP_LOOKUPSWITCHX, 150,"lookupswitchx",NULL, -1, 1, 0, 0, JOF_LOOKUPSWITCHX|JOF_DETECTING|JOF_PARENHEAD)
OPDEF(JSOP_GOTOX, 139,"gotox", NULL, 5, 0, 0, 0, JOF_JUMPX)
OPDEF(JSOP_IFEQX, 140,"ifeqx", NULL, 5, 1, 0, 4, JOF_JUMPX|JOF_DETECTING)
OPDEF(JSOP_IFNEX, 141,"ifnex", NULL, 5, 1, 0, 0, JOF_JUMPX|JOF_PARENHEAD)
OPDEF(JSOP_ORX, 142,"orx", NULL, 5, 1, 0, 5, JOF_JUMPX|JOF_DETECTING)
OPDEF(JSOP_ANDX, 143,"andx", NULL, 5, 1, 0, 6, JOF_JUMPX|JOF_DETECTING)
OPDEF(JSOP_GOSUBX, 144,"gosubx", NULL, 5, 0, 0, 0, JOF_JUMPX)
OPDEF(JSOP_CASEX, 145,"casex", NULL, 5, 2, 1, 0, JOF_JUMPX)
OPDEF(JSOP_DEFAULTX, 146,"defaultx", NULL, 5, 1, 0, 0, JOF_JUMPX)
OPDEF(JSOP_TABLESWITCHX, 147,"tableswitchx",NULL, -1, 1, 0, 0, JOF_TABLESWITCHX|JOF_DETECTING|JOF_PARENHEAD)
OPDEF(JSOP_LOOKUPSWITCHX, 148,"lookupswitchx",NULL, -1, 1, 0, 0, JOF_LOOKUPSWITCHX|JOF_DETECTING|JOF_PARENHEAD)
/* Placeholders for a real jump opcode set during backpatch chain fixup. */
OPDEF(JSOP_BACKPATCH, 151,"backpatch",NULL, 3, 0, 0, 0, JOF_JUMP|JOF_BACKPATCH)
OPDEF(JSOP_BACKPATCH_POP, 152,"backpatch_pop",NULL, 3, 1, 0, 0, JOF_JUMP|JOF_BACKPATCH)
OPDEF(JSOP_BACKPATCH, 149,"backpatch",NULL, 3, 0, 0, 0, JOF_JUMP|JOF_BACKPATCH)
OPDEF(JSOP_BACKPATCH_POP, 150,"backpatch_pop",NULL, 3, 1, 0, 0, JOF_JUMP|JOF_BACKPATCH)
/* Set pending exception from the stack, to trigger rethrow. */
OPDEF(JSOP_THROWING, 153,"throwing", NULL, 1, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_THROWING, 151,"throwing", NULL, 1, 1, 0, 0, JOF_BYTE)
/* Set and get return value pseudo-register in stack frame. */
OPDEF(JSOP_SETRVAL, 154,"setrval", NULL, 1, 1, 0, 2, JOF_BYTE)
OPDEF(JSOP_RETRVAL, 155,"retrval", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_SETRVAL, 152,"setrval", NULL, 1, 1, 0, 2, JOF_BYTE)
OPDEF(JSOP_RETRVAL, 153,"retrval", NULL, 1, 0, 0, 0, JOF_BYTE)
/* Free variable references that must either be found on the global or a ReferenceError */
OPDEF(JSOP_GETGNAME, 156,"getgname", NULL, 3, 0, 1, 19, JOF_ATOM|JOF_NAME|JOF_TYPESET|JOF_GNAME)
OPDEF(JSOP_SETGNAME, 157,"setgname", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME)
OPDEF(JSOP_INCGNAME, 158,"incgname", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_DECGNAME, 159,"decgname", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_GNAMEINC, 160,"gnameinc", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_GNAMEDEC, 161,"gnamedec", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_GETGNAME, 154,"getgname", NULL, 3, 0, 1, 19, JOF_ATOM|JOF_NAME|JOF_TYPESET|JOF_GNAME)
OPDEF(JSOP_SETGNAME, 155,"setgname", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME)
OPDEF(JSOP_INCGNAME, 156,"incgname", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_DECGNAME, 157,"decgname", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_GNAMEINC, 158,"gnameinc", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_GNAMEDEC, 159,"gnamedec", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
/* Regular expression literal requiring special "fork on exec" handling. */
OPDEF(JSOP_REGEXP, 162,"regexp", NULL, 3, 0, 1, 19, JOF_REGEXP)
OPDEF(JSOP_REGEXP, 160,"regexp", NULL, 3, 0, 1, 19, JOF_REGEXP)
/* XML (ECMA-357, a.k.a. "E4X") support. */
OPDEF(JSOP_DEFXMLNS, 163,"defxmlns", NULL, 1, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_ANYNAME, 164,"anyname", NULL, 1, 0, 1, 19, JOF_BYTE|JOF_XMLNAME)
OPDEF(JSOP_QNAMEPART, 165,"qnamepart", NULL, 3, 0, 1, 19, JOF_ATOM|JOF_XMLNAME)
OPDEF(JSOP_QNAMECONST, 166,"qnameconst", NULL, 3, 1, 1, 19, JOF_ATOM|JOF_XMLNAME)
OPDEF(JSOP_QNAME, 167,"qname", NULL, 1, 2, 1, 0, JOF_BYTE|JOF_XMLNAME)
OPDEF(JSOP_TOATTRNAME, 168,"toattrname", NULL, 1, 1, 1, 19, JOF_BYTE|JOF_XMLNAME)
OPDEF(JSOP_TOATTRVAL, 169,"toattrval", NULL, 1, 1, 1, 19, JOF_BYTE)
OPDEF(JSOP_ADDATTRNAME, 170,"addattrname",NULL, 1, 2, 1, 13, JOF_BYTE)
OPDEF(JSOP_ADDATTRVAL, 171,"addattrval", NULL, 1, 2, 1, 13, JOF_BYTE)
OPDEF(JSOP_BINDXMLNAME, 172,"bindxmlname",NULL, 1, 1, 2, 3, JOF_BYTE|JOF_SET)
OPDEF(JSOP_SETXMLNAME, 173,"setxmlname", NULL, 1, 3, 1, 3, JOF_BYTE|JOF_SET|JOF_DETECTING)
OPDEF(JSOP_XMLNAME, 174,"xmlname", NULL, 1, 1, 1, 19, JOF_BYTE)
OPDEF(JSOP_DESCENDANTS, 175,"descendants",NULL, 1, 2, 1, 18, JOF_BYTE)
OPDEF(JSOP_FILTER, 176,"filter", NULL, 3, 1, 1, 0, JOF_JUMP)
OPDEF(JSOP_ENDFILTER, 177,"endfilter", NULL, 3, 2, 1, 18, JOF_JUMP)
OPDEF(JSOP_TOXML, 178,"toxml", NULL, 1, 1, 1, 19, JOF_BYTE)
OPDEF(JSOP_TOXMLLIST, 179,"toxmllist", NULL, 1, 1, 1, 19, JOF_BYTE)
OPDEF(JSOP_XMLTAGEXPR, 180,"xmltagexpr", NULL, 1, 1, 1, 0, JOF_BYTE)
OPDEF(JSOP_XMLELTEXPR, 181,"xmleltexpr", NULL, 1, 1, 1, 0, JOF_BYTE)
OPDEF(JSOP_NOTRACE, 182,"notrace", NULL, 3, 0, 0, 0, JOF_UINT16)
OPDEF(JSOP_XMLCDATA, 183,"xmlcdata", NULL, 3, 0, 1, 19, JOF_ATOM)
OPDEF(JSOP_XMLCOMMENT, 184,"xmlcomment", NULL, 3, 0, 1, 19, JOF_ATOM)
OPDEF(JSOP_XMLPI, 185,"xmlpi", NULL, 3, 1, 1, 19, JOF_ATOM)
OPDEF(JSOP_DELDESC, 186,"deldesc", NULL, 1, 2, 1, 15, JOF_BYTE|JOF_ELEM|JOF_DEL)
OPDEF(JSOP_DEFXMLNS, 161,"defxmlns", NULL, 1, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_ANYNAME, 162,"anyname", NULL, 1, 0, 1, 19, JOF_BYTE|JOF_XMLNAME)
OPDEF(JSOP_QNAMEPART, 163,"qnamepart", NULL, 3, 0, 1, 19, JOF_ATOM|JOF_XMLNAME)
OPDEF(JSOP_QNAMECONST, 164,"qnameconst", NULL, 3, 1, 1, 19, JOF_ATOM|JOF_XMLNAME)
OPDEF(JSOP_QNAME, 165,"qname", NULL, 1, 2, 1, 0, JOF_BYTE|JOF_XMLNAME)
OPDEF(JSOP_TOATTRNAME, 166,"toattrname", NULL, 1, 1, 1, 19, JOF_BYTE|JOF_XMLNAME)
OPDEF(JSOP_TOATTRVAL, 167,"toattrval", NULL, 1, 1, 1, 19, JOF_BYTE)
OPDEF(JSOP_ADDATTRNAME, 168,"addattrname",NULL, 1, 2, 1, 13, JOF_BYTE)
OPDEF(JSOP_ADDATTRVAL, 169,"addattrval", NULL, 1, 2, 1, 13, JOF_BYTE)
OPDEF(JSOP_BINDXMLNAME, 170,"bindxmlname",NULL, 1, 1, 2, 3, JOF_BYTE|JOF_SET)
OPDEF(JSOP_SETXMLNAME, 171,"setxmlname", NULL, 1, 3, 1, 3, JOF_BYTE|JOF_SET|JOF_DETECTING)
OPDEF(JSOP_XMLNAME, 172,"xmlname", NULL, 1, 1, 1, 19, JOF_BYTE)
OPDEF(JSOP_DESCENDANTS, 173,"descendants",NULL, 1, 2, 1, 18, JOF_BYTE)
OPDEF(JSOP_FILTER, 174,"filter", NULL, 3, 1, 1, 0, JOF_JUMP)
OPDEF(JSOP_ENDFILTER, 175,"endfilter", NULL, 3, 2, 1, 18, JOF_JUMP)
OPDEF(JSOP_TOXML, 176,"toxml", NULL, 1, 1, 1, 19, JOF_BYTE)
OPDEF(JSOP_TOXMLLIST, 177,"toxmllist", NULL, 1, 1, 1, 19, JOF_BYTE)
OPDEF(JSOP_XMLTAGEXPR, 178,"xmltagexpr", NULL, 1, 1, 1, 0, JOF_BYTE)
OPDEF(JSOP_XMLELTEXPR, 179,"xmleltexpr", NULL, 1, 1, 1, 0, JOF_BYTE)
OPDEF(JSOP_NOTRACE, 180,"notrace", NULL, 3, 0, 0, 0, JOF_UINT16)
OPDEF(JSOP_XMLCDATA, 181,"xmlcdata", NULL, 3, 0, 1, 19, JOF_ATOM)
OPDEF(JSOP_XMLCOMMENT, 182,"xmlcomment", NULL, 3, 0, 1, 19, JOF_ATOM)
OPDEF(JSOP_XMLPI, 183,"xmlpi", NULL, 3, 1, 1, 19, JOF_ATOM)
OPDEF(JSOP_DELDESC, 184,"deldesc", NULL, 1, 2, 1, 15, JOF_BYTE|JOF_ELEM|JOF_DEL)
OPDEF(JSOP_CALLPROP, 187,"callprop", NULL, 3, 1, 2, 18, JOF_ATOM|JOF_PROP|JOF_TYPESET|JOF_CALLOP|JOF_TMPSLOT3)
OPDEF(JSOP_CALLPROP, 185,"callprop", NULL, 3, 1, 2, 18, JOF_ATOM|JOF_PROP|JOF_TYPESET|JOF_CALLOP|JOF_TMPSLOT3)
/*
* These opcodes contain a reference to the current blockChain object.
@ -457,13 +449,13 @@ OPDEF(JSOP_CALLPROP, 187,"callprop", NULL, 3, 1, 2, 18, JOF_ATOM|J
* does not permit NULL object references, since it stores an index into a table of
* objects.
*/
OPDEF(JSOP_BLOCKCHAIN, 188,"blockchain", NULL, 3, 0, 0, 0, JOF_OBJECT)
OPDEF(JSOP_NULLBLOCKCHAIN,189,"nullblockchain",NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_BLOCKCHAIN, 186,"blockchain", NULL, 3, 0, 0, 0, JOF_OBJECT)
OPDEF(JSOP_NULLBLOCKCHAIN,187,"nullblockchain",NULL, 1, 0, 0, 0, JOF_BYTE)
/*
* Opcode to hold 24-bit immediate integer operands.
*/
OPDEF(JSOP_UINT24, 190,"uint24", NULL, 4, 0, 1, 16, JOF_UINT24)
OPDEF(JSOP_UINT24, 188,"uint24", NULL, 4, 0, 1, 16, JOF_UINT24)
/*
* Opcodes to allow 24-bit atom or object indexes. Whenever an index exceeds
@ -471,126 +463,126 @@ OPDEF(JSOP_UINT24, 190,"uint24", NULL, 4, 0, 1, 16, JOF_UINT24
* JSOP_INDEXBASE and JSOP_RESETBASE to provide the upper bits of the index.
* See jsemit.c, EmitIndexOp.
*/
OPDEF(JSOP_INDEXBASE, 191,"indexbase", NULL, 2, 0, 0, 0, JOF_UINT8|JOF_INDEXBASE)
OPDEF(JSOP_RESETBASE, 192,"resetbase", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_RESETBASE0, 193,"resetbase0", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_INDEXBASE, 189,"indexbase", NULL, 2, 0, 0, 0, JOF_UINT8|JOF_INDEXBASE)
OPDEF(JSOP_RESETBASE, 190,"resetbase", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_RESETBASE0, 191,"resetbase0", NULL, 1, 0, 0, 0, JOF_BYTE)
/*
* Opcodes to help the decompiler deal with XML.
*/
OPDEF(JSOP_STARTXML, 194,"startxml", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_STARTXMLEXPR, 195,"startxmlexpr",NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_STARTXML, 192,"startxml", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_STARTXMLEXPR, 193,"startxmlexpr",NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_CALLELEM, 196, "callelem", NULL, 1, 2, 2, 18, JOF_BYTE |JOF_ELEM|JOF_TYPESET|JOF_LEFTASSOC|JOF_CALLOP)
OPDEF(JSOP_CALLELEM, 194, "callelem", NULL, 1, 2, 2, 18, JOF_BYTE |JOF_ELEM|JOF_TYPESET|JOF_LEFTASSOC|JOF_CALLOP)
/*
* Stop interpretation, emitted at end of script to save the threaded bytecode
* interpreter an extra branch test on every DO_NEXT_OP (see jsinterp.c).
*/
OPDEF(JSOP_STOP, 197,"stop", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_STOP, 195,"stop", NULL, 1, 0, 0, 0, JOF_BYTE)
/*
* Get an extant property value, throwing ReferenceError if the identified
* property does not exist.
*/
OPDEF(JSOP_GETXPROP, 198,"getxprop", NULL, 3, 1, 1, 18, JOF_ATOM|JOF_PROP|JOF_TYPESET)
OPDEF(JSOP_GETXPROP, 196,"getxprop", NULL, 3, 1, 1, 18, JOF_ATOM|JOF_PROP|JOF_TYPESET)
OPDEF(JSOP_CALLXMLNAME, 199, "callxmlname", NULL, 1, 1, 2, 19, JOF_BYTE|JOF_CALLOP)
OPDEF(JSOP_CALLXMLNAME, 197, "callxmlname", NULL, 1, 1, 2, 19, JOF_BYTE|JOF_CALLOP)
/*
* Specialized JSOP_TYPEOF to avoid reporting undefined for typeof(0, undef).
*/
OPDEF(JSOP_TYPEOFEXPR, 200,"typeofexpr", NULL, 1, 1, 1, 15, JOF_BYTE|JOF_DETECTING)
OPDEF(JSOP_TYPEOFEXPR, 198,"typeofexpr", NULL, 1, 1, 1, 15, JOF_BYTE|JOF_DETECTING)
/*
* Block-local scope support.
*/
OPDEF(JSOP_ENTERBLOCK, 201,"enterblock", NULL, 3, 0, -1, 0, JOF_OBJECT)
OPDEF(JSOP_LEAVEBLOCK, 202,"leaveblock", NULL, 5, -1, 0, 0, JOF_UINT16)
OPDEF(JSOP_ENTERBLOCK, 199,"enterblock", NULL, 3, 0, -1, 0, JOF_OBJECT)
OPDEF(JSOP_LEAVEBLOCK, 200,"leaveblock", NULL, 5, -1, 0, 0, JOF_UINT16)
/* Jump to target if top of stack value isn't callable. */
OPDEF(JSOP_IFCANTCALLTOP, 203,"ifcantcalltop",NULL, 3, 1, 1, 0, JOF_JUMP|JOF_DETECTING)
OPDEF(JSOP_IFCANTCALLTOP, 201,"ifcantcalltop",NULL, 3, 1, 1, 0, JOF_JUMP|JOF_DETECTING)
/* Throws a TypeError if the value at the top of the stack is not primitive. */
OPDEF(JSOP_PRIMTOP, 204,"primtop", NULL, 2, 1, 1, 0, JOF_INT8)
OPDEF(JSOP_PRIMTOP, 202,"primtop", NULL, 2, 1, 1, 0, JOF_INT8)
/*
* Generator and array comprehension support.
*/
OPDEF(JSOP_GENERATOR, 205,"generator", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_YIELD, 206,"yield", NULL, 1, 1, 1, 1, JOF_BYTE)
OPDEF(JSOP_ARRAYPUSH, 207,"arraypush", NULL, 3, 1, 0, 3, JOF_LOCAL)
OPDEF(JSOP_GENERATOR, 203,"generator", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_YIELD, 204,"yield", NULL, 1, 1, 1, 1, JOF_BYTE)
OPDEF(JSOP_ARRAYPUSH, 205,"arraypush", NULL, 3, 1, 0, 3, JOF_LOCAL)
/*
* Get the built-in function::foo namespace and push it.
*/
OPDEF(JSOP_GETFUNNS, 208,"getfunns", NULL, 1, 0, 1, 19, JOF_BYTE)
OPDEF(JSOP_GETFUNNS, 206,"getfunns", NULL, 1, 0, 1, 19, JOF_BYTE)
/*
* Variant of JSOP_ENUMELEM for destructuring const (const [a, b] = ...).
*/
OPDEF(JSOP_ENUMCONSTELEM, 209,"enumconstelem",NULL, 1, 3, 0, 3, JOF_BYTE|JOF_SET)
OPDEF(JSOP_ENUMCONSTELEM, 207,"enumconstelem",NULL, 1, 3, 0, 3, JOF_BYTE|JOF_SET)
/*
* Variant of JSOP_LEAVEBLOCK has a result on the stack above the locals,
* which must be moved down when the block pops.
*/
OPDEF(JSOP_LEAVEBLOCKEXPR,210,"leaveblockexpr",NULL, 5, -1, 1, 3, JOF_UINT16)
OPDEF(JSOP_LEAVEBLOCKEXPR,208,"leaveblockexpr",NULL, 5, -1, 1, 3, JOF_UINT16)
\
/*
* Optimize atom segments 1-3. These must be followed by JSOP_RESETBASE0 after
* the opcode that they prefix.
*/
OPDEF(JSOP_INDEXBASE1, 211,"indexbase1", NULL, 1, 0, 0, 0, JOF_BYTE |JOF_INDEXBASE)
OPDEF(JSOP_INDEXBASE2, 212,"indexbase2", NULL, 1, 0, 0, 0, JOF_BYTE |JOF_INDEXBASE)
OPDEF(JSOP_INDEXBASE3, 213,"indexbase3", NULL, 1, 0, 0, 0, JOF_BYTE |JOF_INDEXBASE)
OPDEF(JSOP_INDEXBASE1, 209,"indexbase1", NULL, 1, 0, 0, 0, JOF_BYTE |JOF_INDEXBASE)
OPDEF(JSOP_INDEXBASE2, 210,"indexbase2", NULL, 1, 0, 0, 0, JOF_BYTE |JOF_INDEXBASE)
OPDEF(JSOP_INDEXBASE3, 211,"indexbase3", NULL, 1, 0, 0, 0, JOF_BYTE |JOF_INDEXBASE)
OPDEF(JSOP_CALLGNAME, 214, "callgname", NULL, 3, 0, 2, 19, JOF_ATOM|JOF_NAME|JOF_TYPESET|JOF_CALLOP|JOF_GNAME)
OPDEF(JSOP_CALLLOCAL, 215, "calllocal", NULL, 3, 0, 2, 19, JOF_LOCAL|JOF_NAME|JOF_CALLOP)
OPDEF(JSOP_CALLARG, 216, "callarg", NULL, 3, 0, 2, 19, JOF_QARG |JOF_NAME|JOF_CALLOP)
OPDEF(JSOP_BINDGNAME, 217, "bindgname", NULL, 3, 0, 1, 0, JOF_ATOM|JOF_NAME|JOF_SET|JOF_GNAME)
OPDEF(JSOP_CALLGNAME, 212, "callgname", NULL, 3, 0, 2, 19, JOF_ATOM|JOF_NAME|JOF_TYPESET|JOF_CALLOP|JOF_GNAME)
OPDEF(JSOP_CALLLOCAL, 213, "calllocal", NULL, 3, 0, 2, 19, JOF_LOCAL|JOF_NAME|JOF_CALLOP)
OPDEF(JSOP_CALLARG, 214, "callarg", NULL, 3, 0, 2, 19, JOF_QARG |JOF_NAME|JOF_CALLOP)
OPDEF(JSOP_BINDGNAME, 215, "bindgname", NULL, 3, 0, 1, 0, JOF_ATOM|JOF_NAME|JOF_SET|JOF_GNAME)
/*
* Opcodes to hold 8-bit and 32-bit immediate integer operands.
*/
OPDEF(JSOP_INT8, 218, "int8", NULL, 2, 0, 1, 16, JOF_INT8)
OPDEF(JSOP_INT32, 219, "int32", NULL, 5, 0, 1, 16, JOF_INT32)
OPDEF(JSOP_INT8, 216, "int8", NULL, 2, 0, 1, 16, JOF_INT8)
OPDEF(JSOP_INT32, 217, "int32", NULL, 5, 0, 1, 16, JOF_INT32)
/*
* Get the value of the 'length' property from a stacked object.
*/
OPDEF(JSOP_LENGTH, 220, "length", NULL, 3, 1, 1, 18, JOF_ATOM|JOF_PROP|JOF_TYPESET)
OPDEF(JSOP_LENGTH, 218, "length", NULL, 3, 1, 1, 18, JOF_ATOM|JOF_PROP|JOF_TYPESET)
/*
* Push a JSVAL_HOLE value onto the stack, representing an omitted property in
* an array literal (e.g. property 0 in the array [, 1]). This opcode is used
* with the JSOP_NEWARRAY opcode.
*/
OPDEF(JSOP_HOLE, 221, "hole", NULL, 1, 0, 1, 0, JOF_BYTE)
OPDEF(JSOP_HOLE, 219, "hole", NULL, 1, 0, 1, 0, JOF_BYTE)
/*
* Variants of JSOP_{DEF{,LOCAL}FUN,LAMBDA} optimized for the flat closure case.
*/
OPDEF(JSOP_DEFFUN_FC, 222,"deffun_fc", NULL, 3, 0, 0, 0, JOF_OBJECT|JOF_DECLARING)
OPDEF(JSOP_DEFLOCALFUN_FC,223,"deflocalfun_fc",NULL, 5, 0, 0, 0, JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT)
OPDEF(JSOP_LAMBDA_FC, 224,"lambda_fc", NULL, 3, 0, 1, 19, JOF_OBJECT)
OPDEF(JSOP_DEFFUN_FC, 220,"deffun_fc", NULL, 3, 0, 0, 0, JOF_OBJECT|JOF_DECLARING)
OPDEF(JSOP_DEFLOCALFUN_FC,221,"deflocalfun_fc",NULL, 5, 0, 0, 0, JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT)
OPDEF(JSOP_LAMBDA_FC, 222,"lambda_fc", NULL, 3, 0, 1, 19, JOF_OBJECT)
/*
* Ensure that the value on the top of the stack is an object. The one
* argument is an error message, defined in js.msg, that takes one parameter
* (the decompilation of the primitive value).
*/
OPDEF(JSOP_OBJTOP, 225,"objtop", NULL, 3, 0, 0, 0, JOF_UINT16)
OPDEF(JSOP_OBJTOP, 223,"objtop", NULL, 3, 0, 0, 0, JOF_UINT16)
/*
* Joined function object as method optimization support.
*/
OPDEF(JSOP_SETMETHOD, 226,"setmethod", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
OPDEF(JSOP_INITMETHOD, 227,"initmethod", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
OPDEF(JSOP_UNBRAND, 228,"unbrand", NULL, 1, 1, 1, 0, JOF_BYTE)
OPDEF(JSOP_UNBRANDTHIS, 229,"unbrandthis", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_SETMETHOD, 224,"setmethod", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
OPDEF(JSOP_INITMETHOD, 225,"initmethod", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
OPDEF(JSOP_UNBRAND, 226,"unbrand", NULL, 1, 1, 1, 0, JOF_BYTE)
OPDEF(JSOP_UNBRANDTHIS, 227,"unbrandthis", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_SHARPINIT, 230,"sharpinit", NULL, 3, 0, 0, 0, JOF_UINT16|JOF_SHARPSLOT)
OPDEF(JSOP_SHARPINIT, 228,"sharpinit", NULL, 3, 0, 0, 0, JOF_UINT16|JOF_SHARPSLOT)
/* Pop the stack, convert to a jsid (int or string), and push back. */
OPDEF(JSOP_TOID, 231, "toid", NULL, 1, 1, 1, 0, JOF_BYTE)
OPDEF(JSOP_TOID, 229, "toid", NULL, 1, 1, 1, 0, JOF_BYTE)

View File

@ -15427,28 +15427,6 @@ TraceRecorder::record_JSOP_NOP()
return ARECORD_CONTINUE;
}
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_JSOP_ARGSUB()
{
StackFrame* const fp = cx->fp();
/*
* The arguments object or its absence in the frame is part of the typemap,
* so a record-time check suffices here. We don't bother tracing ARGSUB in
* the case of an arguments object exising, because ARGSUB and to a lesser
* extent ARGCNT are emitted to avoid arguments object creation.
*/
if (!fp->hasArgsObj() && !fp->fun()->isHeavyweight()) {
uintN slot = GET_ARGNO(cx->regs().pc);
if (slot >= fp->numActualArgs())
RETURN_STOP_A("can't trace out-of-range arguments");
stack(0, get(&cx->fp()->canonicalActualArg(slot)));
return ARECORD_CONTINUE;
}
RETURN_STOP_A("can't trace JSOP_ARGSUB hard case");
}
JS_REQUIRES_STACK LIns*
TraceRecorder::guardArgsLengthNotAssigned(LIns* argsobj_ins)
{
@ -15460,33 +15438,6 @@ TraceRecorder::guardArgsLengthNotAssigned(LIns* argsobj_ins)
return len_ins;
}
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_JSOP_ARGCNT()
{
StackFrame * const fp = cx->fp();
if (fp->fun()->flags & JSFUN_HEAVYWEIGHT)
RETURN_STOP_A("can't trace heavyweight JSOP_ARGCNT");
// argc is fixed on trace, so ideally we would simply generate LIR for
// constant argc. But the user can mutate arguments.length in the
// interpreter, so we have to check for that in the trace entry frame.
// We also have to check that arguments.length has not been mutated
// at record time, because if so we will generate incorrect constant
// LIR, which will assert in tryToDemote().
if (fp->hasArgsObj() && fp->argsObj().hasOverriddenLength())
RETURN_STOP_A("can't trace JSOP_ARGCNT if arguments.length has been modified");
LIns *a_ins = getFrameObjPtr(fp->addressOfArgs());
if (callDepth == 0) {
if (MaybeBranch mbr = w.jt(w.eqp0(a_ins))) {
guardArgsLengthNotAssigned(a_ins);
w.label(mbr);
}
}
stack(0, w.immd(fp->numActualArgs()));
return ARECORD_CONTINUE;
}
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_DefLocalFunSetSlot(uint32 slot, JSObject* obj)
{
@ -16107,7 +16058,7 @@ TraceRecorder::record_JSOP_LENGTH()
// We must both check at record time and guard at run time that
// arguments.length has not been reassigned, redefined or deleted.
if (obj->asArguments()->hasOverriddenLength())
RETURN_STOP_A("can't trace JSOP_ARGCNT if arguments.length has been modified");
RETURN_STOP_A("can't trace arguments.length if it has been modified");
LIns* slot_ins = guardArgsLengthNotAssigned(obj_ins);
// slot_ins is the value from the slot; right-shift to get the length;

View File

@ -222,7 +222,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
* before deserialization of bytecode. If the saved version does not match
* the current version, abort deserialization and invalidate the file.
*/
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 95)
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 96)
/*
* Library-private functions.

View File

@ -2624,23 +2624,6 @@ mjit::Compiler::generateMethod()
}
END_CASE(JSOP_CALLFCSLOT)
BEGIN_CASE(JSOP_ARGSUB)
{
prepareStubCall(Uses(0));
masm.move(Imm32(GET_ARGNO(PC)), Registers::ArgReg1);
INLINE_STUBCALL(stubs::ArgSub, REJOIN_FALLTHROUGH);
pushSyncedEntry(0);
}
END_CASE(JSOP_ARGSUB)
BEGIN_CASE(JSOP_ARGCNT)
{
prepareStubCall(Uses(0));
INLINE_STUBCALL(stubs::ArgCnt, REJOIN_FALLTHROUGH);
pushSyncedEntry(0);
}
END_CASE(JSOP_ARGCNT)
BEGIN_CASE(JSOP_DEFLOCALFUN)
{
uint32 slot = GET_SLOTNO(PC);

View File

@ -1942,19 +1942,6 @@ stubs::FastInstanceOf(VMFrame &f)
f.regs.sp[-3].setBoolean(js_IsDelegate(f.cx, &lref.toObject(), f.regs.sp[-3]));
}
void JS_FASTCALL
stubs::ArgCnt(VMFrame &f)
{
JSContext *cx = f.cx;
JSRuntime *rt = cx->runtime;
StackFrame *fp = f.fp();
jsid id = ATOM_TO_JSID(rt->atomState.lengthAtom);
f.regs.sp++;
if (!js_GetArgsProperty(cx, fp, id, &f.regs.sp[-1]))
THROW();
}
void JS_FASTCALL
stubs::EnterBlock(VMFrame &f, JSObject *obj)
{
@ -2183,16 +2170,6 @@ stubs::Pos(VMFrame &f)
TypeScript::MonitorOverflow(f.cx, f.script(), f.pc());
}
void JS_FASTCALL
stubs::ArgSub(VMFrame &f, uint32 n)
{
jsid id = INT_TO_JSID(n);
Value rval;
if (!js_GetArgsProperty(f.cx, f.fp(), id, &rval))
THROW();
f.regs.sp[0] = rval;
}
void JS_FASTCALL
stubs::DelName(VMFrame &f, JSAtom *atom)
{

View File

@ -155,7 +155,6 @@ JSObject * JS_FASTCALL LambdaJoinableForCall(VMFrame &f, JSFunction *fun);
JSObject * JS_FASTCALL LambdaJoinableForNull(VMFrame &f, JSFunction *fun);
JSObject * JS_FASTCALL FlatLambda(VMFrame &f, JSFunction *fun);
void JS_FASTCALL Arguments(VMFrame &f);
void JS_FASTCALL ArgSub(VMFrame &f, uint32 n);
void JS_FASTCALL EnterBlock(VMFrame &f, JSObject *obj);
void JS_FASTCALL LeaveBlock(VMFrame &f, JSObject *blockChain);
@ -193,7 +192,6 @@ JSBool JS_FASTCALL ValueToBoolean(VMFrame &f);
JSString * JS_FASTCALL TypeOf(VMFrame &f);
JSBool JS_FASTCALL InstanceOf(VMFrame &f);
void JS_FASTCALL FastInstanceOf(VMFrame &f);
void JS_FASTCALL ArgCnt(VMFrame &f);
void JS_FASTCALL Unbrand(VMFrame &f);
void JS_FASTCALL UnbrandThis(VMFrame &f);

View File

@ -1280,7 +1280,8 @@ CompartmentCallback(JSContext *cx, void *vdata, JSCompartment *compartment)
curr->tjitDataAllocatorsReserve = GetCompartmentTjitDataAllocatorsReserveSize(compartment);
curr->tjitDataNonAllocators = GetCompartmentTjitDataTraceMonitorSize(compartment);
#endif
JS_GetTypeInferenceMemoryStats(cx, compartment, &curr->typeInferenceMemory);
JS_GetTypeInferenceMemoryStats(cx, compartment, &curr->typeInferenceMemory,
moz_malloc_usable_size);
}
void
@ -1352,7 +1353,7 @@ CellCallback(JSContext *cx, void *vdata, void *thing, JSGCTraceKind traceKind,
{
js::types::TypeObject *obj = static_cast<js::types::TypeObject *>(thing);
curr->gcHeapTypeObjects += thingSize;
JS_GetTypeInferenceObjectStats(obj, &curr->typeInferenceMemory);
JS_GetTypeInferenceObjectStats(obj, &curr->typeInferenceMemory, moz_malloc_usable_size);
break;
}
case JSTRACE_XML:

View File

@ -87,7 +87,8 @@ nsresult
NS_NewContentViewer(nsIContentViewer** aResult);
// XXXbz if you change the MIME types here, be sure to update
// nsIParser.h and DetermineParseMode in nsParser.cpp accordingly.
// nsIParser.h and DetermineParseMode in nsParser.cpp and
// nsHTMLDocument::StartDocumentLoad accordingly.
static const char* const gHTMLTypes[] = {
TEXT_HTML,
TEXT_PLAIN,

View File

@ -1,75 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/mockObjects.js"></script>
</head>
<body>
<input id="target" type="file" />
<script type="text/javascript">
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var Cu = Components.utils;
var Ci = Components.interfaces;
var Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
function MockFilePicker() { };
MockFilePicker.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
init: function(aParent, aTitle, aMode) { },
appendFilters: function(aFilterMask) { },
appendFilter: function(aTitle, aFilter) { },
defaultString: "",
defaultExtension: "",
filterIndex: 0,
displayDirectory: null,
get file() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var f = window.parent.dirs[window.parent.index].clone();
f.append("aFile.txt");
return f;
},
get fileURL() {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
get files() {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
show: function MFP_show() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
if (this.displayDirectory)
window.parent.postMessage(this.displayDirectory.path, "*");
else
window.parent.postMessage("", "*");
mockFilePickerRegisterer.unregister();
return Ci.nsIFilePicker.returnOK;
}
};
var mockFilePickerRegisterer =
new MockObjectRegisterer("@mozilla.org/filepicker;1",MockFilePicker);
function test() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var wu = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
var fileInput = document.getElementById("target");
var rect = fileInput.getBoundingClientRect();
mockFilePickerRegisterer.register();
try {
wu.sendMouseEvent("mousedown", rect.left + 5, rect.top + 5, 0, 1, 0);
wu.sendMouseEvent("mouseup", rect.left + 5, rect.top + 5, 0, 1, 0);
} catch (e) {
Cu.reportError(e);
} finally {
}
}
window.onload = function() {
setTimeout(test, 0);
var fileInput = document.getElementById("target");
fileInput.click();
};
</script>

View File

@ -7,7 +7,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=36619
<title>Test for Bug 36619</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/mockObjects.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
@ -24,87 +23,34 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=36619
SimpleTest.waitForExplicitFinish();
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var Cu = Components.utils;
var Ci = Components.interfaces;
var Cc = Components.classes;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
function MockFilePicker()
{
}
MockFilePicker.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
// properties
defaultExtension: "",
defaultString: "",
get displayDirectory() { return null; },
set displayDirectory(val) { },
file: null,
get files() { return null; },
get fileURL() { return null; },
filterIndex: 0,
// methods
appendFilter: function(val)
{
},
appendFilters: function(val)
{
},
init: function() {
},
show: function()
{
shown = true;
}
};
var mockFilePickerRegisterer =
new MockObjectRegisterer("@mozilla.org/filepicker;1",MockFilePicker);
mockFilePickerRegisterer.register();
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.reset();
// enable popups the first time
var pbi = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
var oldAllow = pbi.getBoolPref("dom.disable_open_during_load");
var oldShowBar = pbi.getBoolPref("privacy.popups.showBrowserMessage");
pbi.setBoolPref("dom.disable_open_during_load", true);
pbi.setBoolPref("privacy.popups.showBrowserMessage", false);
SpecialPowers.pushPrefEnv({'set': [
["dom.disable_open_during_load", true],
["privacy.popups.showBrowserMessage", false]
]}, function() {
SimpleTest.waitForFocus(function() {
var shown = false;
// Tests that a click on 'b' calls the show method.
var b = document.getElementById('b');
b.focus(); // Be sure the element is visible.
synthesizeMouse(b, 2, 2, {});
SimpleTest.executeSoon(function() {
ok(MockFilePicker.shown, "File picker show method should have been called");
MockFilePicker.reset();
function checkFirst()
{
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
ok(shown, "File picker show method should have been called");
shown = false;
document.getElementById("a").click();
setTimeout(finishTest, 1000);
}
// Tests that a click on 'a' doesn't call the show method, because it is hidden.
document.getElementById("a").click();
SimpleTest.executeSoon(function() {
ok(!MockFilePicker.shown, "File picker show method should not have been called");
MockFilePicker.reset();
function finishTest()
{
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
ok(!shown, "File picker show method should not have been called");
mockFilePickerRegisterer.unregister();
pbi.setBoolPref("dom.disable_open_during_load", oldAllow);
pbi.setBoolPref("privacy.popups.showBrowserMessage", oldShowBar);
SimpleTest.finish();
}
SimpleTest.waitForFocus(function() {
var b = document.getElementById('b');
b.focus(); // Be sure the element is visible.
synthesizeMouse(b, 2, 2, {});
SimpleTest.executeSoon(checkFirst);
SimpleTest.finish();
});
});
});
});
</script>

View File

@ -9,7 +9,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=377624
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="runTests();">
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=377624">Mozilla Bug 377624</a>
<p id="display"></p>
<div id="content">
@ -32,198 +32,71 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=377624
SimpleTest.waitForExplicitFinish();
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.reset();
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cm = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
const Cu = Components.utils;
const FILE_PICKER_CID = "@mozilla.org/filepicker;1";
const FILE_PICKER_ID = Components.ID(Cc[FILE_PICKER_CID].number);
const CUSTOM_FILE_PICKER_ID = Components.ID("d63dee33-fb6d-4547-a8d1-c12197655cce");
const FILE_PICKER_DESCRIPTION = "File Picker Test Service";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
// disable popups to make sure that the popup blocker does not interfere
// with manually opened file pickers.
var pbi = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
var oldAllow = pbi.getBoolPref("dom.disable_open_during_load");
pbi.setBoolPref("dom.disable_open_during_load", true);
function FilePickerService()
{
}
FilePickerService.prototype = {
_obs: Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
// constants
modeOpen: 0,
modeSave: 1,
modeGetFolder: 2,
modeOpenMultiple: 3,
returnOK: 0,
returnCancel: 1,
returnReplace: 2,
filterAll: 1,
filterHTML: 2,
filterText: 4,
filterImages: 8,
filterXML: 16,
filterXUL: 32,
filterApps: 64,
filterAllowURLs: 128,
filterAudio: 256,
filterVideo: 512,
// properties
defaultExtension: "",
defaultString: "",
get displayDirectory() { return null; },
set displayDirectory(val) { },
file: null,
get files() { return null; },
get fileURL() { return null; },
filterIndex: 0,
// methods
appendFilter: function(val)
{
this._obs.notifyObservers(null, "TEST_FILEPICKER_APPENDFILTER", val);
},
appendFilters: function(val)
{
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
this._obs.notifyObservers(null, "TEST_FILEPICKER_APPENDFILTERS", val);
},
init: function() {},
show: function()
{
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
this._obs.notifyObservers(null, "TEST_FILEPICKER_SHOW", this.filterIndex);
return this.returnOK;
}
};
factory = {
createInstance: function(aOuter, aIid) {
if (aOuter != null)
throw Cr.NS_ERROR_NO_AGGREGATION;
return new FilePickerService().QueryInterface(aIid);
}
};
var testData = [["a", FilePickerService.prototype.filterImages, 1],
["b", FilePickerService.prototype.filterAudio, 1],
["c", FilePickerService.prototype.filterVideo, 1],
var testData = [["a", MockFilePicker.filterImages, 1],
["b", MockFilePicker.filterAudio, 1],
["c", MockFilePicker.filterVideo, 1],
["d", 0, 0],
["e", 0, 0],
["f", 0, 0],
["g", 0, 0],
["h", FilePickerService.prototype.filterImages, 1],
["i", FilePickerService.prototype.filterVideo, 1],
["j", FilePickerService.prototype.filterAudio, 1],
["h", MockFilePicker.filterImages, 1],
["i", MockFilePicker.filterVideo, 1],
["j", MockFilePicker.filterAudio, 1],
["z", 0, 0]];
testData.forEach(function (datum) {
document.getElementById(datum[0]).addEventListener("focus", function (aEvent) {
aEvent.target.removeEventListener("focus", arguments.callee, false);
synthesizeKey('VK_SPACE', {});
}, false);
});
var currentTest = 0;
var appendFilterCalled;
var filters;
var filterIndex;
function launchNextTest(aObserver)
{
aObserver.shown = false;
aObserver.appendFilterCalled = false;
aObserver.filters = [];
aObserver.filterIndex = 0;
// disable popups to make sure that the popup blocker does not interfere
// with manually opened file pickers.
SpecialPowers.pushPrefEnv({'set': [["dom.disable_open_during_load", false]]}, runTests);
document.getElementById(testData[currentTest][0]).focus();
function launchNextTest() {
MockFilePicker.shown = false;
appendFilterCalled = false;
filters = [];
filterIndex = 0;
document.getElementById(testData[currentTest][0]).click();
}
function runTests()
{
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
function runTests() {
MockFilePicker.appendFilterCallback = function(filepicker, title, val) {
this.appendFilterCalled = true;
};
MockFilePicker.appendFiltersCallback = function(filepicker, val) {
filters.push(val);
};
MockFilePicker.showCallback = function(filepicker) {
filterIndex = filepicker.filterIndex;
SimpleTest.executeSoon(function () {
ok(MockFilePicker.shown,
"File picker show method should have been called");
ok(!appendFilterCalled,
"appendFilter should not have been called");
is(filters.length, 1,
"appendFilters should have been called once");
is(filters[0], MockFilePicker.filterAll +
testData[currentTest][1],
"Correct filters should have been added");
is(filterIndex, testData[currentTest][2],
"File picker should show the correct filter index");
Cm.registerFactory(CUSTOM_FILE_PICKER_ID,
FILE_PICKER_DESCRIPTION,
FILE_PICKER_CID,
factory);
var obs = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
var observer = {
observe: function(aSubject, aTopic, aData) {
switch (aTopic) {
case "TEST_FILEPICKER_APPENDFILTER":
this.appendFilterCalled = true;
break;
case "TEST_FILEPICKER_APPENDFILTERS":
this.filters.push(aData);
break;
case "TEST_FILEPICKER_SHOW":
this.shown = true;
this.filterIndex = aData;
SimpleTest.executeSoon(function () {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
ok(observer.shown,
"File picker show method should have been called");
ok(!observer.appendFilterCalled,
"appendFilter should not have been called");
is(observer.filters.length, 1,
"appendFilters should have been called once");
is(observer.filters[0], FilePickerService.prototype.filterAll +
testData[currentTest][1],
"Correct filters should have been added");
is(observer.filterIndex, testData[currentTest][2],
"File picker should show the correct filter index");
if (++currentTest == testData.length) {
obs.removeObserver(observer, "TEST_FILEPICKER_APPENDFILTER", false);
obs.removeObserver(observer, "TEST_FILEPICKER_APPENDFILTERS", false);
obs.removeObserver(observer, "TEST_FILEPICKER_SHOW", false);
Cm.unregisterFactory(CUSTOM_FILE_PICKER_ID, factory);
Cm.registerFactory(FILE_PICKER_ID,
"File Picker Service",
FILE_PICKER_CID,
null);
pbi.setBoolPref("dom.disable_open_during_load", oldAllow);
SimpleTest.finish();
} else {
launchNextTest(observer);
}
} );
break;
if (++currentTest == testData.length) {
MockFilePicker.reset();
SimpleTest.finish();
} else {
launchNextTest();
}
},
shown: false,
appendFilterCalled: false,
filters: [],
filterIndex: 0
});
};
obs.addObserver(observer, "TEST_FILEPICKER_APPENDFILTER", false);
obs.addObserver(observer, "TEST_FILEPICKER_APPENDFILTERS", false);
obs.addObserver(observer, "TEST_FILEPICKER_SHOW", false);
// We are simulating a focus then a SPACE key press to open the file picker.
// We were not able to do this with |synthesizeMouse|.
launchNextTest(observer);
launchNextTest();
}
</script>

View File

@ -7,6 +7,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=536567
<title>Test for Bug 536567</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=536567">Mozilla Bug 536567</a>
@ -22,6 +23,9 @@ const Ci = Components.interfaces;
const Cu = Components.utils;
const Cm = Components.manager;
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.reset();
var ioSvc = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
var prefSvc = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
@ -92,7 +96,6 @@ var tests = [
"pb off"
];
var index;
var testIndex = 0;
var content = document.getElementById('content');
@ -118,7 +121,9 @@ function runTest() {
testIndex++;
runTest();
} else {
index = test[2];
var file = dirs[test[2]].clone();
file.append("file.file");
MockFilePicker.returnFiles = [file];
content.setAttribute ('src', domains[test[0]] + '/chrome/layout/forms/test/bug536567_subframe.html');
}
}
@ -129,14 +134,15 @@ function endTest() {
dirs[i].remove(true);
}
MockFilePicker.reset();
SimpleTest.finish();
}
window.addEventListener("message", function(event) {
MockFilePicker.showCallback = function(filepicker) {
var test = tests[testIndex];
var returned = -1;
for (var i = 0; i < dirs.length; i++) {
if (dirs[i].path == event.data) {
if (dirs[i].path == MockFilePicker.displayDirectory.path) {
returned = i;
break;
}
@ -146,10 +152,12 @@ window.addEventListener("message", function(event) {
} else {
is(returned, test[1], 'test ' + testIndex);
}
testIndex++;
runTest();
}, false);
SimpleTest.executeSoon(function() {
testIndex++;
runTest();
});
};
window.onload = function() {
SimpleTest.waitForExplicitFinish();

View File

@ -264,7 +264,7 @@ nsImageBoxFrame::UpdateImage()
// Only get the list-style-image if we aren't being drawn
// by a native theme.
PRUint8 appearance = GetStyleDisplay()->mAppearance;
if (!(appearance && nsBox::gTheme &&
if (!(appearance && nsBox::gTheme &&
nsBox::gTheme->ThemeSupportsWidget(nsnull, this, appearance))) {
// get the list-style-image
imgIRequest *styleRequest = GetStyleList()->GetListStyleImage();
@ -337,7 +337,7 @@ NS_IMETHODIMP
nsImageBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists)
{
{
nsresult rv = nsLeafBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
NS_ENSURE_SUCCESS(rv, rv);
@ -404,7 +404,7 @@ nsImageBoxFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
// If we're using a native theme implementation, we shouldn't draw anything.
const nsStyleDisplay* disp = GetStyleDisplay();
if (disp->mAppearance && nsBox::gTheme &&
if (disp->mAppearance && nsBox::gTheme &&
nsBox::gTheme->ThemeSupportsWidget(nsnull, this, disp->mAppearance))
return;
@ -461,7 +461,7 @@ nsImageBoxFrame::GetPrefSize(nsBoxLayoutState& aState)
bool widthSet, heightSet;
nsIBox::AddCSSPrefSize(this, size, widthSet, heightSet);
NS_ASSERTION(size.width != NS_INTRINSICSIZE && size.height != NS_INTRINSICSIZE,
"non-nintrinsic size expected");
"non-intrinsic size expected");
nsSize minSize = GetMinSize(aState);
nsSize maxSize = GetMaxSize(aState);
@ -480,7 +480,7 @@ nsImageBoxFrame::GetPrefSize(nsBoxLayoutState& aState)
maxSize.width, maxSize.height,
intrinsicSize.width, intrinsicSize.height);
NS_ASSERTION(size.width != NS_INTRINSICSIZE && size.height != NS_INTRINSICSIZE,
"non-nintrinsic size expected");
"non-intrinsic size expected");
size.width += borderPadding.LeftRight();
size.height += borderPadding.TopBottom();
return size;

View File

@ -96,6 +96,7 @@
</div>
<div id="sync-setup">
<a id="syncSetupSync" href="#" onclick="openSetupSyncWizard();">&aboutHome.setupSync;</a>
<a id="syncPairDevice" href="#" onclick="openPairDeviceWizard();">&aboutHome.syncPairDevice;</a>
</div>
</div>
</div>
@ -433,8 +434,10 @@
function initSetupSync() {
let services = getChromeWin().Services;
if (services.prefs.prefHasUserValue("services.sync.username")) {
document.getElementById("syncSetupSync").style.display = "none";
}
syncConnected();
} else {
syncDisconnected();
}
services.obs.addObserver(syncConnected, "weave:service:setup-complete", false);
services.obs.addObserver(syncDisconnected, "weave:service:start-over", false);
}
@ -447,10 +450,12 @@
function syncConnected() {
document.getElementById("syncSetupSync").style.display = "none";
document.getElementById("syncPairDevice").style.display = "inline";
}
function syncDisconnected() {
document.getElementById("syncSetupSync").style.display = "inline";
document.getElementById("syncPairDevice").style.display = "none";
}
function openSetupSyncWizard() {
@ -458,6 +463,11 @@
chromeWin.WeaveGlue.open();
}
function openPairDeviceWizard() {
let chromeWin = getChromeWin();
chromeWin.SyncPairDevice.open();
}
function initLightbox() {
let prefs = getChromeWin().Services.prefs;
let channel = prefs.getCharPref("app.update.channel");

View File

@ -282,6 +282,7 @@ let WebNavigation = {
shEntry.setScrollPosition(scrollPos[0], scrollPos[1]);
}
let childDocIdents = {};
if (aEntry.docIdentifier) {
// If we have a serialized document identifier, try to find an SHEntry
// which matches that doc identifier and adopt that SHEntry's
@ -289,9 +290,11 @@ let WebNavigation = {
// for the document identifier.
let matchingEntry = aDocIdentMap[aEntry.docIdentifier];
if (!matchingEntry) {
aDocIdentMap[aEntry.docIdentifier] = shEntry;
matchingEntry = {shEntry: shEntry, childDocIdents: childDocIdents};
aDocIdentMap[aEntry.docIdentifier] = matchingEntry;
} else {
shEntry.adoptBFCacheEntry(matchingEntry);
childDocIdents = matchingEntry.childDocIdents;
}
}
@ -310,7 +313,23 @@ let WebNavigation = {
for (let i = 0; i < aEntry.children.length; i++) {
if (!aEntry.children[i].url)
continue;
shEntry.AddChild(this._deserializeHistoryEntry(aEntry.children[i], aIdMap, aDocIdentMap), i);
// We're getting sessionrestore.js files with a cycle in the
// doc-identifier graph, likely due to bug 698656. (That is, we have
// an entry where doc identifier A is an ancestor of doc identifier B,
// and another entry where doc identifier B is an ancestor of A.)
//
// If we were to respect these doc identifiers, we'd create a cycle in
// the SHEntries themselves, which causes the docshell to loop forever
// when it looks for the root SHEntry.
//
// So as a hack to fix this, we restrict the scope of a doc identifier
// to be a node's siblings and cousins, and pass childDocIdents, not
// aDocIdents, to _deserializeHistoryEntry. That is, we say that two
// SHEntries with the same doc identifier have the same document iff
// they have the same parent or their parents have the same document.
shEntry.AddChild(this._deserializeHistoryEntry(aEntry.children[i], aIdMap, childDocIdents), i);
}
}

View File

@ -113,6 +113,7 @@ XPCOMUtils.defineLazyGetter(this, "CommonUI", function() {
["MasterPasswordUI", "chrome://browser/content/MasterPasswordUI.js"],
#ifdef MOZ_SERVICES_SYNC
["WeaveGlue", "chrome://browser/content/sync.js"],
["SyncPairDevice", "chrome://browser/content/sync.js"],
#endif
["WebappsUI", "chrome://browser/content/WebappsUI.js"],
["SSLExceptions", "chrome://browser/content/exceptions.js"],

View File

@ -24,6 +24,7 @@
- Brad Lassey <blassey@mozilla.com>
- Mark Finkle <mfinkle@mozila.com>
- Matt Brubeck <mbrubeck@mozila.com>
- Allison Naaktgeboren <ally@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
@ -487,6 +488,7 @@
<button label="&sync.connect;" oncommand="WeaveGlue.tryConnect();" />
</setting>
<setting id="sync-connected" class="setting-group" title="&sync.connected;" type="control" collapsed="true">
<button id="sync-pairdevice" label="&sync.pair.title;" oncommand="SyncPairDevice.open();" />
<button id="sync-details" label="&sync.details;" type="checkbox" autocheck="false" checked="false" oncommand="WeaveGlue.showDetails();" />
</setting>
<setting id="sync-sync" class="setting-subgroup" type="control" collapsed="true">
@ -593,7 +595,15 @@
</hbox>
</vbox>
<vbox id="syncsetup-waiting" class="syncsetup-page" flex="1" hidden="true">
<description class="syncsetup-desc syncsetup-center" flex="1">&sync.setup.waiting;</description>
<progressmeter id="syncsetup-progressbar" mode="undetermined"/>
<vbox id="syncsetup-waiting-top" align="center" flex="1">
<description id="syncsetup-waiting-desc" class="syncsetup-desc syncsetup-center" flex="1">&sync.setup.waiting2;</description>
<description id="syncsetup-waitingdownload-desc" class="syncsetup-desc syncsetup-center" hidden="true" flex="1">&sync.setup.waitingdownload;</description>
</vbox>
<hbox class="prompt-buttons" pack="center" align="end">
<button id="syncsetup-waiting-cancel" class="prompt-button" oncommand="WeaveGlue.close();">&sync.setup.cancel;</button>
<button id="syncsetup-waiting-close" class="prompt-button" hidden="true" oncommand="WeaveGlue.close();">&sync.setup.close;</button>
</hbox>
</vbox>
<vbox id="syncsetup-fallback" class="syncsetup-page" flex="1" hidden="true">
<scrollbox class="prompt-message" orient="vertical" flex="1">
@ -618,6 +628,32 @@
</vbox>
</dialog>
</box>
<box id="syncpair-container" class="perm-modal-block" hidden="true">
<dialog id="syncpair-dialog" class="content-dialog" flex="1">
<hbox class="prompt-title">
<description>&sync.pair.title;</description>
</hbox>
<separator class="prompt-line"/>
<vbox id="syncpair-simple" class="syncsetup-page" flex="1">
<scrollbox id="sync-message" class="prompt-message" orient="vertical" flex="1">
<description class="syncsetup-desc syncsetup-center" flex="1">&sync.pair.description;</description>
<description class="syncsetup-center link" flex="1" onclick="SyncPairDevice.close(); WeaveGlue.openTutorial();">&sync.setup.tutorial;</description>
<separator/>
<vbox align="center" flex="1">
<textbox id="syncpair-code1" class="syncsetup-code" oninput="SyncPairDevice.onTextBoxInput(this);"/>
<textbox id="syncpair-code2" class="syncsetup-code" oninput="SyncPairDevice.onTextBoxInput(this);"/>
<textbox id="syncpair-code3" class="syncsetup-code" oninput="SyncPairDevice.onTextBoxInput(this);"/>
</vbox>
<separator flex="1"/>
</scrollbox>
<hbox class="prompt-buttons" pack="center">
<button class="prompt-button" oncommand="SyncPairDevice.close();">&sync.setup.cancel;</button>
<button id="syncpair-connectbutton" class="prompt-button" disabled="true" oncommand="SyncPairDevice.connect();">&sync.setup.connect;</button>
</hbox>
</vbox>
</dialog>
</box>
#endif
<arrowbox id="search-engines-popup" hidden="true" offset="18" flex="1" type="dialog">

View File

@ -21,6 +21,7 @@
* Mark Finkle <mfinkle@mozila.com>
* Matt Brubeck <mbrubeck@mozila.com>
* Jono DiCarlo <jdicarlo@mozilla.com>
* Allison Naaktgeboren <ally@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
@ -38,9 +39,14 @@
let WeaveGlue = {
setupData: null,
_boundOnEngineSync: null, // Needed to unhook the observers in close().
_boundOnServiceSync: null,
jpake: null,
_bundle: null,
_loginError: false,
_progressBar: null,
_progressValue: 0,
_progressMax: null,
init: function init() {
if (this._bundle)
@ -64,6 +70,9 @@ let WeaveGlue = {
} else if (Weave.Status.login != Weave.LOGIN_FAILED_NO_USERNAME) {
this.loadSetupData();
}
this._boundOnEngineSync = this.onEngineSync.bind(this);
this._boundOnServiceSync = this.onServiceSync.bind(this);
this._progressBar = document.getElementById("syncsetup-progressbar");
},
abortEasySetup: function abortEasySetup() {
@ -128,7 +137,16 @@ let WeaveGlue = {
onComplete: function onComplete(aCredentials) {
self.jpake = null;
self.close();
self._progressBar.mode = "determined";
document.getElementById("syncsetup-waiting-desc").hidden = true;
document.getElementById("syncsetup-waiting-cancel").hidden = true;
document.getElementById("syncsetup-waitingdownload-desc").hidden = false;
document.getElementById("syncsetup-waiting-close").hidden = false;
Services.obs.addObserver(self._boundOnEngineSync, "weave:engine:sync:finish", false);
Services.obs.addObserver(self._boundOnEngineSync, "weave:engine:sync:error", false);
Services.obs.addObserver(self._boundOnServiceSync, "weave:service:sync:finish", false);
Services.obs.addObserver(self._boundOnServiceSync, "weave:service:sync:error", false);
self.setupData = aCredentials;
self.connect();
},
@ -180,6 +198,7 @@ let WeaveGlue = {
this._resetScrollPosition();
document.getElementById("syncsetup-simple").hidden = true;
document.getElementById("syncsetup-waiting").hidden = true;
document.getElementById("syncsetup-fallback").hidden = false;
// Push the current setup data into the UI
@ -204,7 +223,37 @@ let WeaveGlue = {
this.canConnect();
},
onEngineSync: function onEngineSync(subject, topic, data) {
// The Clients engine syncs first. At this point we don't necessarily know
// yet how many engines will be enabled, so we'll ignore the Clients engine
// and evaluate how many engines are enabled when the first "real" engine
// syncs.
if (data == 'clients') {
return;
}
if (this._progressMax == null) {
this._progressMax = Weave.Engines.getEnabled().length;
this._progressBar.max = this._progressMax;
}
this._progressValue += 1;
this._progressBar.setAttribute("value", this._progressValue);
},
onServiceSync: function onServiceSync() {
this.close();
},
close: function close() {
try {
Services.obs.removeObserver(this._boundOnEngineSync, "weave:engine:sync:finish");
Services.obs.removeObserver(this._boundOnEngineSync, "weave:engine:sync:error");
Services.obs.removeObserver(this._boundOnServiceSync, "weave:service:sync:finish");
Services.obs.removeObserver(this._boundOnServiceSync, "weave:service:sync:error");
}
catch(e) {
// Observers weren't registered because we never got as far as onComplete.
}
if (this.jpake)
this.abortEasySetup();
@ -226,6 +275,15 @@ let WeaveGlue = {
this._elements.usecustomserver.checked = false;
this._elements.customserver.disabled = true;
this._elements.customserver.value = "";
document.getElementById("syncsetup-waiting-desc").hidden = false;
document.getElementById("syncsetup-waiting-cancel").hidden = false;
document.getElementById("syncsetup-waitingdownload-desc").hidden = true;
document.getElementById("syncsetup-waiting-close").hidden = true;
this._progressMax = null;
this._progressValue = 0;
this._progressBar.max = 0;
this._progressBar.value = 0;
this._progressBar.mode = "undetermined";
// Close the connect UI
document.getElementById("syncsetup-container").hidden = true;
@ -372,7 +430,7 @@ let WeaveGlue = {
elements[id] = document.getElementById("syncsetup-" + id);
});
let settingids = ["device", "connect", "connected", "disconnect", "sync", "details"];
let settingids = ["device", "connect", "connected", "disconnect", "sync", "details", "pairdevice"];
settingids.forEach(function(id) {
elements[id] = document.getElementById("sync-" + id);
});
@ -397,6 +455,7 @@ let WeaveGlue = {
let device = this._elements.device;
let disconnect = this._elements.disconnect;
let sync = this._elements.sync;
let pairdevice = this._elements.pairdevice;
// Show what went wrong with login if necessary
if (aTopic == "weave:ui:login:error") {
@ -541,3 +600,95 @@ let WeaveGlue = {
this.setupData.serverURL = serverURL;
}
};
const PIN_PART_LENGTH = 4;
let SyncPairDevice = {
jpake: null,
open: function open() {
this.code1.setAttribute("maxlength", PIN_PART_LENGTH);
this.code2.setAttribute("maxlength", PIN_PART_LENGTH);
this.code3.setAttribute("maxlength", PIN_PART_LENGTH);
this.nextFocusEl = {code1: this.code2,
code2: this.code3,
code3: this.connectbutton};
document.getElementById("syncpair-container").hidden = false;
BrowserUI.pushDialog(this);
this.code1.focus();
// Kick off a sync. That way the server will have the most recent data from
// this computer and it will show up immediately on the new device.
Weave.SyncScheduler.scheduleNextSync(0);
},
close: function close() {
this.code1.value = this.code2.value = this.code3.value = "";
this.code1.disabled = this.code2.disabled = this.code3.disabled = false;
this.connectbutton.disabled = true;
if (this.jpake) {
this.jpake.abort();
this.jpake = null;
}
document.getElementById("syncpair-container").hidden = true;
BrowserUI.popDialog();
},
onTextBoxInput: function onTextBoxInput(textbox) {
if (textbox && textbox.value.length == PIN_PART_LENGTH) {
let name = textbox.id.split("-")[1];
this.nextFocusEl[name].focus();
}
this.connectbutton.disabled =
!(this.code1.value.length == PIN_PART_LENGTH &&
this.code2.value.length == PIN_PART_LENGTH &&
this.code3.value.length == PIN_PART_LENGTH);
},
connect: function connect() {
let self = this;
let jpake = this.jpake = new Weave.JPAKEClient({
onPaired: function onPaired() {
let credentials = {account: Weave.Service.account,
password: Weave.Service.password,
synckey: Weave.Service.passphrase,
serverURL: Weave.Service.serverURL};
jpake.sendAndComplete(credentials);
},
onComplete: function onComplete() {
self.jpake = null;
self.close();
// Schedule a Sync for soonish to fetch the data uploaded by the
// device with which we just paired.
Weave.SyncScheduler.scheduleNextSync(Weave.SyncScheduler.activeInterval);
},
onAbort: function onAbort(error) {
self.jpake = null;
// Aborted by user, ignore.
if (error == Weave.JPAKE_ERROR_USERABORT) {
return;
}
self.code1.value = self.code2.value = self.code3.value = "";
self.code1.disabled = self.code2.disabled = self.code3.disabled = false;
self.code1.focus();
}
});
this.code1.disabled = this.code2.disabled = this.code3.disabled = true;
this.connectbutton.disabled = true;
let pin = this.code1.value + this.code2.value + this.code3.value;
let expectDelay = false;
jpake.pairWithPIN(pin, expectDelay);
}
};
["code1", "code2", "code3", "connectbutton"].forEach(function (id) {
XPCOMUtils.defineLazyGetter(SyncPairDevice, id, function() {
return document.getElementById("syncpair-" + id);
});
});

View File

@ -19,4 +19,13 @@
(aboutHome.forAndroid): Second line of a multi-line button. Treat as a subtitle.
-->
<!ENTITY aboutHome.forAndroid "for Android">
<!ENTITY aboutHome.setupSync "Set Up Sync">
<!-- LOCALIZATION NOTE:
(aboutHome.setupSync): This string should match the desktop
equivalent, in particular concerning syncBrand.fullName.label.
-->
<!ENTITY aboutHome.setupSync "Set Up Sync">
<!-- LOCALIZATION NOTE:
(aboutHome.syncPairDevice): This string should match the desktop
equivalent, in particular concerning syncBrand.fullName.label.
-->
<!ENTITY aboutHome.syncPairDevice "Pair a Device">

View File

@ -19,4 +19,9 @@
<!ENTITY sync.setup.connect "Connect">
<!ENTITY sync.setup.cancel "Cancel">
<!ENTITY sync.setup.tutorial "Show me how">
<!ENTITY sync.setup.waiting "Pairing in progress…">
<!ENTITY sync.setup.waiting2 "Waiting for other device…">
<!ENTITY sync.pair.title "Pair a Device">
<!ENTITY sync.pair.description "To activate your new device, select &#x0022;Set Up Sync&#x0022; on the device.">
<!ENTITY sync.setup.close "Close">
<!ENTITY sync.setup.waitingdownload "Your data is now being downloaded in the background. You can close this window at any time.">

View File

@ -267,7 +267,8 @@ body[dir="rtl"] {
text-align: center;
}
#syncSetupSync {
#syncSetupSync,
#syncPairDevice {
text-decoration: underline;
color: blue;
}

View File

@ -1534,7 +1534,11 @@ setting {
}
#syncsetup-waiting {
padding: 10em 0;
padding: 2em 0 0 0;
}
#syncsetup-waiting-top {
padding: 1em;
}
/* content scrollbars */

View File

@ -65,7 +65,6 @@ typedef int (*PR_CALLBACK PrefChangedFunc)(const char *, void *);
namespace mozilla {
class Preferences : public nsIPrefService,
public nsIPrefServiceInternal,
public nsIObserver,
public nsIPrefBranchInternal,
public nsSupportsWeakReference
@ -73,7 +72,6 @@ class Preferences : public nsIPrefService,
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPREFSERVICE
NS_DECL_NSIPREFSERVICEINTERNAL
NS_FORWARD_NSIPREFBRANCH(sRootBranch->)
NS_FORWARD_NSIPREFBRANCH2(sRootBranch->)
NS_DECL_NSIOBSERVER
@ -341,6 +339,14 @@ public:
static nsresult GetDefaultComplex(const char* aPref, const nsIID &aType,
void** aResult);
// Used to synchronise preferences between chrome and content processes.
static nsresult ReadExtensionPrefs(nsIFile *aFile);
static void MirrorPreferences(nsTArray<PrefTuple,
nsTArrayInfallibleAllocator> *aArray);
static bool MirrorPreference(const char *aPref, PrefTuple *aTuple);
static void ClearContentPref(const char *aPref);
static void SetPreference(const PrefTuple *aTuple);
protected:
nsresult NotifyServiceObservers(const char *aSubject);
nsresult UseDefaultPrefFile();

View File

@ -163,29 +163,6 @@ interface nsIPrefService : nsISupports
};
[scriptable, uuid(08c8cd2f-8345-45ee-938d-37ee6d3661b2)]
interface nsIPrefServiceInternal : nsISupports
{
/**
* Called to read the preferences in the defaults/preferences/
* directory of a zip file
*
* @param aFile The zip file to be read.
*
* @return NS_OK The file was read and processed.
* @return Other The file failed to read or contained invalid data.
*
* @see readUserPrefs
*/
void readExtensionPrefs(in nsILocalFile aFile);
[noscript] void mirrorPreferences(in nsPreferencesArrayPtr aArray);
[noscript] void mirrorPreference(in ACString aPrefName, in nsPreferencePtr aPref);
[noscript] boolean prefHasUserValue(in ACString aPrefName);
[noscript] void setPreference(in nsPreferencePtrConst aPref);
[noscript] void clearContentPref(in ACString aPrefName);
};
%{C++
#define NS_PREFSERVICE_CID \

View File

@ -303,7 +303,6 @@ NS_IMPL_THREADSAFE_RELEASE(Preferences)
NS_INTERFACE_MAP_BEGIN(Preferences)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrefService)
NS_INTERFACE_MAP_ENTRY(nsIPrefService)
NS_INTERFACE_MAP_ENTRY(nsIPrefServiceInternal)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsIPrefBranch)
NS_INTERFACE_MAP_ENTRY(nsIPrefBranch2)
@ -463,9 +462,8 @@ Preferences::SavePrefFile(nsIFile *aFile)
return SavePrefFileInternal(aFile);
}
/* part of nsIPrefServiceInternal */
NS_IMETHODIMP
Preferences::ReadExtensionPrefs(nsILocalFile *aFile)
nsresult
Preferences::ReadExtensionPrefs(nsIFile *aFile)
{
nsresult rv;
nsCOMPtr<nsIZipReader> reader = do_CreateInstance(kZipReaderCID, &rv);
@ -513,47 +511,35 @@ Preferences::ReadExtensionPrefs(nsILocalFile *aFile)
return rv;
}
NS_IMETHODIMP
Preferences::PrefHasUserValue(const nsACString& aPrefName, bool* aHasValue)
{
*aHasValue = PREF_HasUserPref(aPrefName.BeginReading());
return NS_OK;
}
NS_IMETHODIMP
void
Preferences::SetPreference(const PrefTuple *aPref)
{
return pref_SetPrefTuple(*aPref, true);
pref_SetPrefTuple(*aPref, true);
}
NS_IMETHODIMP
Preferences::ClearContentPref(const nsACString& aPrefName)
void
Preferences::ClearContentPref(const char *aPref)
{
return PREF_ClearUserPref(aPrefName.BeginReading());
PREF_ClearUserPref(aPref);
}
NS_IMETHODIMP
Preferences::MirrorPreference(const nsACString& aPrefName, PrefTuple *aPref)
bool
Preferences::MirrorPreference(const char *aPref, PrefTuple *aTuple)
{
PrefHashEntry *pref = pref_HashTableLookup(PromiseFlatCString(aPrefName).get());
PrefHashEntry *entry = pref_HashTableLookup(aPref);
if (!entry)
return false;
if (!pref)
return NS_ERROR_NOT_AVAILABLE;
pref_GetTupleFromEntry(pref, aPref);
return NS_OK;
pref_GetTupleFromEntry(entry, aTuple);
return true;
}
NS_IMETHODIMP
void
Preferences::MirrorPreferences(nsTArray<PrefTuple,
nsTArrayInfallibleAllocator> *aArray)
{
aArray->SetCapacity(PL_DHASH_TABLE_SIZE(&gHashTable));
PL_DHashTableEnumerate(&gHashTable, pref_MirrorPrefs, aArray);
return NS_OK;
}
NS_IMETHODIMP

View File

@ -239,7 +239,7 @@ nsHtml5Parser::Parse(nsIURI* aURL, // legacy parameter; ignored
NS_IMETHODIMP
nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
void* aKey,
const nsACString& aContentType, // ignored
const nsACString& aContentType,
bool aLastCall,
nsDTDMode aMode) // ignored
{
@ -270,6 +270,10 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
mTreeBuilder->setScriptingEnabled(mExecutor->IsScriptEnabled());
mTokenizer->start();
mExecutor->Start();
if (!aContentType.EqualsLiteral("text/html")) {
mTreeBuilder->StartPlainText();
mTokenizer->StartPlainText();
}
/*
* If you move the following line, be very careful not to cause
* WillBuildModel to be called before the document has had its
@ -707,6 +711,8 @@ nsHtml5Parser::MarkAsNotScriptCreated(const char* aCommand)
mode = VIEW_SOURCE_HTML;
} else if (!nsCRT::strcmp(aCommand, "view-source-xml")) {
mode = VIEW_SOURCE_XML;
} else if (!nsCRT::strcmp(aCommand, "plain-text")) {
mode = PLAIN_TEXT;
}
#ifdef DEBUG
else {

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