Merge mozilla-central to tabcandy-central.

This commit is contained in:
Edward Lee 2010-08-07 16:44:33 -07:00
Родитель 9550e5467b 192ac9af53
Коммит d35d6cdf00
3342 изменённых файлов: 9315 добавлений и 13124 удалений

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

@ -713,6 +713,7 @@ nsAttributeCharacteristics nsARIAMap::gWAIUnivAttrMap[] = {
{&nsAccessibilityAtoms::aria_grabbed, ATTR_VALTOKEN },
{&nsAccessibilityAtoms::aria_haspopup, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
{&nsAccessibilityAtoms::aria_invalid, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
{&nsAccessibilityAtoms::aria_label, ATTR_BYPASSOBJ },
{&nsAccessibilityAtoms::aria_labelledby, ATTR_BYPASSOBJ },
{&nsAccessibilityAtoms::aria_level, ATTR_BYPASSOBJ }, /* handled via groupPosition */
{&nsAccessibilityAtoms::aria_live, ATTR_VALTOKEN },

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

@ -2694,16 +2694,9 @@ nsAccessible::Shutdown()
nsresult
nsAccessible::GetARIAName(nsAString& aName)
{
// First check for label override via aria-label property
nsAutoString label;
if (mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_label,
label)) {
label.CompressWhitespace();
aName = label;
return NS_OK;
}
// Second check for label override via aria-labelledby relationship
// aria-labelledby now takes precedence over aria-label
nsresult rv = nsTextEquivUtils::
GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_labelledby, label);
if (NS_SUCCEEDED(rv)) {
@ -2711,7 +2704,14 @@ nsAccessible::GetARIAName(nsAString& aName)
aName = label;
}
return rv;
if (label.IsEmpty() &&
mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_label,
label)) {
label.CompressWhitespace();
aName = label;
}
return NS_OK;
}
nsresult

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

@ -2,6 +2,7 @@
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=475006
https://bugzilla.mozilla.org/show_bug.cgi?id=391829
https://bugzilla.mozilla.org/show_bug.cgi?id=581952
-->
<head>
<title>Group attributes tests</title>
@ -69,6 +70,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=391829
testAttrs("statusChild", {"container-live-role" : "status"}, true);
testAttrs("timerChild", {"container-live-role" : "timer"}, true);
// absent aria-label and aria-labelledby object attribute
testAbsentAttrs("label", {"label" : "foo"});
testAbsentAttrs("labelledby", {"labelledby" : "label"});
// container that has no default live attribute
testAttrs("liveGroup", {"live" : "polite"}, true);
testAttrs("liveGroupChild", {"container-live" : "polite"}, true);
@ -93,11 +98,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=391829
title="Extend nsARIAMap to capture ARIA attribute characteristics">
Mozilla Bug 475006
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=391829"
title="Add support for container-live-role to object attributes">
Mozilla Bug 391829
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=391829"
title="Add support for container-live-role to object attributes">
Mozilla Bug 391829
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=581952"
title="Make explicit that aria-label is not an object attribute">
Mozilla Bug 475006
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
@ -129,6 +139,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=391829
<div id="status" role="status">excuse <div id="statusChild">me</div></div>
<div id="timer" role="timer">excuse <div id="timerChild">me</div></div>
<!-- aria-label[ledby] should not be an object attribute -->
<div id="label" role="checkbox" aria-label="foo"></div>
<div id="labelledby" role="checkbox" aria-labelledby="label"></div>
<!-- unusual live case -->
<div id="liveGroup" role="group" aria-live="polite">
excuse <div id="liveGroupChild">me</div>

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

@ -69,8 +69,8 @@
<!-- bricks -->
<ruleset id="aria">
<rule attr="aria-label" type="string"/>
<rule attr="aria-labelledby" type="ref"/>
<rule attr="aria-label" type="string"/>
</ruleset>
<ruleset id="htmlctrl_start">

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

@ -23,8 +23,8 @@
// Simple label provided via ARIA
testName("btn_simple_aria_label", "I am a button");
// aria-label and aria-labelledby, expect aria-label
testName("btn_both_aria_labels", "I am a button, two");
// aria-label and aria-labelledby, expect aria-labelledby
testName("btn_both_aria_labels", "text I am a button, two");
//////////////////////////////////////////////////////////////////////////
// aria-labelledby
@ -207,7 +207,7 @@
<br/>
<!-- aria-label plus aria-labelledby -->
<span id="btn_both_aria_labels" role="button" aria-label="I am a button, two"
aria-labelledby="labelledby_text"/>
aria-labelledby="labelledby_text btn_both_aria_labels"/>
<br/>
<!-- aria-labelledby, single relation -->

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

@ -30,8 +30,8 @@
// Simple label provided via ARIA
testName("btn_simple_aria_label", "I am a button");
// aria-label and aria-labelledby, expect aria-label
testName("btn_both_aria_labels", "I am a button, two");
// aria-label and aria-labelledby, expect aria-labelledby
testName("btn_both_aria_labels", "text I am a button, two");
//////////////////////////////////////////////////////////////////////////
// aria-labelledby
@ -205,9 +205,10 @@
<!-- aria-label, simple label -->
<button id="btn_simple_aria_label" aria-label="I am a button"/>
<!-- aria-label plus aria-labelledby -->
<button id="btn_both_aria_labels" aria-label="I am a button, two"
aria-labelledby="labelledby_text"/>
aria-labelledby="labelledby_text btn_both_aria_labels"/>
<!-- aria-labelledby, single relation -->
<description id="labelledby_text">text</description>

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

@ -83,10 +83,9 @@
<pre id="test">
</pre>
<!-- button, aria-label, preferred to aria-labelledby -->
<!-- aria-labelledby preferred to aria-label -->
<button id="btn_aria_label"
aria-label="button label"
aria-labelledby="btn_aria_labelledby_text">1</button>
aria-label="button label">1</button>
<br/>
<!-- button, aria-labelledby, preferred to html:label -->
@ -109,10 +108,9 @@
<!-- button, no content, name from @title -->
<button id="btn_title" title="title"></button>
<!-- input, aria-label, preferred to aria-labelledby -->
<!-- input, aria-label -->
<input type="button" id="input_aria_label"
aria-label="button label"
aria-labelledby="aria_labelledby_text_for_input"
value="1"/>
<br/>

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

@ -61,10 +61,9 @@
<pre id="test">
</pre>
<!-- aria-label, preferred to aria-labelledby -->
<!-- aria-label -->
<a id="aria_label" href="mozilla.org"
aria-label="anchor label"
aria-labelledby="text">1</a>
aria-label="anchor label">1</a>
<br/>
<!-- aria-labelledby, preferred to html:label -->

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

@ -343,6 +343,7 @@ pref("browser.tabs.opentabfor.middleclick", true);
pref("browser.tabs.loadDivertedInBackground", false);
pref("browser.tabs.loadBookmarksInBackground", false);
pref("browser.tabs.tabClipWidth", 140);
pref("browser.tabs.animate", true);
// Where to show tab close buttons:
// 0 on active tab only

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

@ -29,6 +29,7 @@ tabbrowser {
max-width: 250px;
min-width: 100px;
width: 0;
-moz-transition: min-width .2s ease-out, max-width .25s ease-out;
}
.tabbrowser-tab:not([pinned]):not([fadein]) {
@ -36,19 +37,15 @@ tabbrowser {
min-width: 1px;
}
.tabbrowser-tab[fadein]:not([pinned]) {
-moz-transition: min-width .2s ease-out, max-width .25s ease-out;
}
.tabbrowser-tab:not([fadein]):not([pinned]) > .tab-text,
.tabbrowser-tab:not([fadein]):not([pinned]) > .tab-icon-image,
.tabbrowser-tab:not([fadein]):not([pinned]) > .tab-close-button {
opacity: 0 !important;
}
.tabbrowser-tab[fadein] > .tab-text,
.tabbrowser-tab[fadein] > .tab-icon-image,
.tabbrowser-tab[fadein] > .tab-close-button {
.tabbrowser-tab > .tab-text,
.tabbrowser-tab > .tab-icon-image,
.tabbrowser-tab > .tab-close-button {
-moz-transition: opacity .25s;
}

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

@ -2051,7 +2051,7 @@ function BrowserCloseTabOrWindow() {
#endif
// If the current tab is the last one, this will close the window.
gBrowser.removeCurrentTab();
gBrowser.removeCurrentTab({animate: true});
}
function BrowserTryToCloseWindow()

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

@ -457,9 +457,23 @@
label="&brandShortName;"
style="-moz-user-focus: ignore;">
<menupopup id="appmenu-popup">
<menuitem id="appmenu_newNavigator"
label="&newNavigatorCmd.label;"
command="cmd_newNavigator"/>
<hbox flex="1" class="split-menuitem">
<menuitem id="appmenu_newTab"
class="split-menuitem-item"
flex="1"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"/>
<menu class="split-menuitem-menu">
<menupopup>
<menuitem id="appmenu_newTab_sub"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"/>
<menuitem id="appmenu_newNavigator"
label="&newNavigatorCmd.label;"
command="cmd_newNavigator"/>
</menupopup>
</menu>
</hbox>
<menuseparator/>
<menuitem id="appmenu_savePage"
label="&savePageCmd.label;"

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

@ -1104,7 +1104,8 @@
// doesn't go well together with the width transition. So we skip the
// transition in that case.
if (aSkipAnimation ||
this.tabContainer.getAttribute("overflow") == "true") {
this.tabContainer.getAttribute("overflow") == "true" ||
!Services.prefs.getBoolPref("browser.tabs.animate")) {
t.setAttribute("fadein", "true");
setTimeout(function (tabContainer) {
tabContainer._handleNewTab(t);
@ -1154,12 +1155,26 @@
notificationbox.setAttribute("flex", "1");
notificationbox.appendChild(b);
b.setAttribute("flex", "1");
var position = this.tabs.length - 1;
var uniqueId = "panel" + Date.now() + position;
notificationbox.id = uniqueId;
t.linkedPanel = uniqueId;
t.linkedBrowser = b;
t._tPos = position;
if (t.previousSibling.selected)
t.setAttribute("afterselected", true);
// NB: this appendChild call causes us to run constructors for the
// browser element, which fires off a bunch of notifications. Some
// of those notifications can cause code to run that inspects our
// state, so it is important that the tab element is fully
// initialized by this point.
this.mPanelContainer.appendChild(notificationbox);
this.tabContainer.updateVisibility();
// wire up a progress listener for the new browser object.
var position = this.tabs.length - 1;
var tabListener = this.mTabProgressListener(t, b, blank);
const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
.createInstance(Components.interfaces.nsIWebProgress);
@ -1302,9 +1317,10 @@
</method>
<method name="removeCurrentTab">
<parameter name="aParams"/>
<body>
<![CDATA[
this.removeTab(this.mCurrentTab);
this.removeTab(this.mCurrentTab, aParams);
]]>
</body>
</method>
@ -1315,9 +1331,36 @@
<method name="removeTab">
<parameter name="aTab"/>
<parameter name="aParams"/>
<body>
<![CDATA[
this._endRemoveTab(this._beginRemoveTab(aTab, false, null, true));
var isLastTab = (this.tabs.length - this._removingTabs.length == 1);
if (aParams)
var animate = aParams.animate;
if (!this._beginRemoveTab(aTab, false, null, true))
return;
/* Don't animate if:
- the caller didn't opt in
- this is the last tab in the window
- this is a pinned tab
- a bunch of other tabs are already closing (arbitrary threshold)
- the fadein attribute hasn't been set yet
- browser.tabs.animate is false */
if (!animate ||
isLastTab ||
aTab.pinned ||
this._removingTabs.length > 3 ||
aTab.getAttribute("fadein") != "true" ||
!Services.prefs.getBoolPref("browser.tabs.animate")) {
this._endRemoveTab(aTab);
return;
}
this._blurTab(aTab);
aTab.removeAttribute("fadein");
]]>
</body>
</method>
@ -1328,7 +1371,6 @@
false
</field>
<!-- Returns everything that _endRemoveTab needs in an array. -->
<method name="_beginRemoveTab">
<parameter name="aTab"/>
<parameter name="aTabWillBeMoved"/>
@ -1337,14 +1379,14 @@
<body>
<![CDATA[
if (this._removingTabs.indexOf(aTab) > -1 || this._windowIsClosing)
return null;
return false;
var browser = this.getBrowserForTab(aTab);
if (!aTabWillBeMoved) {
let ds = browser.docShell;
if (ds && ds.contentViewer && !ds.contentViewer.permitUnload())
return null;
return false;
}
var closeWindow = false;
@ -1400,18 +1442,26 @@
tab.owner = null;
});
return [aTab, closeWindow, newTab];
aTab._endRemoveArgs = [closeWindow, newTab];
return true;
]]>
</body>
</method>
<method name="_endRemoveTab">
<parameter name="args"/>
<parameter name="aTab"/>
<body>
<![CDATA[
if (!args)
if (!aTab || !aTab._endRemoveArgs)
return;
var [aTab, aCloseWindow, aNewTab] = args;
var [aCloseWindow, aNewTab] = aTab._endRemoveArgs;
aTab._endRemoveArgs = null;
if (this._windowIsClosing) {
aCloseWindow = false;
aNewTab = false;
}
this._lastRelatedTab = null;
@ -1427,7 +1477,7 @@
if (aCloseWindow) {
this._windowIsClosing = true;
while (this._removingTabs.length)
this._endRemoveTab([this._removingTabs[0], false]);
this._endRemoveTab(this._removingTabs[0]);
} else if (!this._windowIsClosing) {
if (aNewTab)
focusAndSelectUrlBar();
@ -1554,13 +1604,13 @@
<body>
<![CDATA[
// That's gBrowser for the other window, not the tab's browser!
var remoteBrowser =
aOtherTab.ownerDocument.defaultView.getBrowser();
var remoteBrowser = aOtherTab.ownerDocument.defaultView.gBrowser;
// First, start teardown of the other browser. Make sure to not
// fire the beforeunload event in the process. Close the other
// window if this was its last tab.
var endRemoveArgs = remoteBrowser._beginRemoveTab(aOtherTab, true, true);
if (!remoteBrowser._beginRemoveTab(aOtherTab, true, true))
return;
// Unhook our progress listener
var ourIndex = aOurTab._tPos;
@ -1587,7 +1637,7 @@
ourBrowser.swapDocShells(aOtherTab.linkedBrowser);
// Finish tearing down the tab that's going away.
remoteBrowser._endRemoveTab(endRemoveArgs);
remoteBrowser._endRemoveTab(aOtherTab);
// Restore the progress listener
tabListener = this.mTabProgressListener(aOurTab, ourBrowser,
@ -2181,7 +2231,7 @@
if (aEvent.ctrlKey && !aEvent.shiftKey && !aEvent.metaKey &&
aEvent.keyCode == KeyEvent.DOM_VK_F4 &&
this.mTabBox.handleCtrlPageUpDown) {
this.removeCurrentTab();
this.removeCurrentTab({animate: true});
aEvent.stopPropagation();
aEvent.preventDefault();
}
@ -2383,6 +2433,10 @@
var tabs = document.getBindingParent(this);
tabs.removeAttribute("overflow");
tabs.tabbrowser._removingTabs.forEach(tabs.tabbrowser._endRemoveTab,
tabs.tabbrowser);
tabs._positionPinnedTabs();
]]></handler>
<handler event="overflow"><![CDATA[
@ -2768,8 +2822,15 @@
<handler event="TabSelect" action="this._handleTabSelect();"/>
<handler event="transitionend"><![CDATA[
if (event.propertyName == "max-width")
this._handleNewTab(event.target);
if (event.propertyName != "max-width")
return;
var tab = event.target;
if (tab.getAttribute("fadein") == "true")
this._handleNewTab(tab);
else if (this.tabbrowser._removingTabs.indexOf(tab) > -1)
this.tabbrowser._endRemoveTab(tab);
]]></handler>
<handler event="dblclick"><![CDATA[
@ -2785,7 +2846,7 @@
if (event.target.localName == "tab") {
if (this.childNodes.length > 1 || !this._closeWindowWithLastTab)
this.tabbrowser.removeTab(event.target);
this.tabbrowser.removeTab(event.target, {animate: true});
} else if (event.originalTarget.localName == "box") {
BrowserOpenTab();
} else {
@ -3102,7 +3163,7 @@
// Reset the "ignored click" flag
this._ignoredClick = false;
tabContainer.tabbrowser.removeTab(bindingParent);
tabContainer.tabbrowser.removeTab(bindingParent, {animate: true});
tabContainer._blockDblClick = true;
/* XXXmano hack (see bug 343628):

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

@ -99,6 +99,7 @@ _BROWSER_FILES = \
title_test.svg \
browser_bug329212.js \
browser_bug356571.js \
browser_bug380960.js \
browser_bug386835.js \
browser_bug405137.js \
browser_bug406216.js \

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

@ -0,0 +1,78 @@
function test() {
gBrowser.tabContainer.addEventListener("TabOpen", tabAdded, false);
var tab = gBrowser.addTab("about:blank", { skipAnimation: true });
gBrowser.removeTab(tab);
is(tab.parentNode, null, "tab removed immediately");
waitForExplicitFinish();
Services.prefs.setBoolPref("browser.tabs.animate", true);
nextAsyncText();
}
function tabAdded() {
info("tab added");
}
function cleanup() {
if (Services.prefs.prefHasUserValue("browser.tabs.animate"))
Services.prefs.clearUserPref("browser.tabs.animate");
gBrowser.tabContainer.removeEventListener("TabOpen", tabAdded, false);
finish();
}
var asyncTests = [
function (tab) {
info("closing tab with middle click");
EventUtils.synthesizeMouse(tab, 2, 2, { button: 1 });
},
function (tab) {
info("closing tab with accel+w");
gBrowser.selectedTab = tab;
content.focus();
EventUtils.synthesizeKey("w", { accelKey: true });
},
function (tab) {
info("closing tab by clicking the tab close button");
gBrowser.selectedTab = tab;
var button = document.getAnonymousElementByAttribute(tab, "anonid", "close-button");
EventUtils.synthesizeMouse(button, 2, 2, {});
}
];
function nextAsyncText() {
info("tests left: " + asyncTests.length + "; starting next");
var tab = gBrowser.addTab("about:blank", { skipAnimation: true });
var gotCloseEvent = false;
tab.addEventListener("TabClose", function () {
info("got TabClose event");
gotCloseEvent = true;
const DEFAULT_ANIMATION_LENGTH = 250;
const MAX_WAIT_TIME = DEFAULT_ANIMATION_LENGTH * 3;
const INTERVAL_LENGTH = 100;
var polls = Math.ceil(MAX_WAIT_TIME / INTERVAL_LENGTH);
var pollTabRemoved = setInterval(function () {
--polls;
if (tab.parentNode && polls > 0)
return;
clearInterval(pollTabRemoved);
is(tab.parentNode, null, "tab removed after at most " + MAX_WAIT_TIME + " ms");
if (asyncTests.length)
nextAsyncText();
else
cleanup();
}, INTERVAL_LENGTH);
}, false);
asyncTests.shift()(tab);
ok(gotCloseEvent, "got the close event syncronously");
is(tab.parentNode, gBrowser.tabContainer, "tab still exists when it's about to be removed asynchronously");
}

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

@ -1,4 +1,4 @@
var expected = ["TabOpen", "onLocationChange", "onStateChange", "onLinkIconAvailable"];
var expected = ["TabOpen", "onStateChange", "onLocationChange", "onLinkIconAvailable"];
var actual = [];
var tabIndex = -1;
__defineGetter__("tab", function () gBrowser.tabs[tabIndex]);

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

@ -45,6 +45,9 @@
#
# Define an include-at-most-once flag
#ifdef INCLUDED_CONFIG_MK
#$(error Don't include config.mk twice!)
#endif
INCLUDED_CONFIG_MK = 1
EXIT_ON_ERROR = set -e; # Shell loops continue past errors without this.
@ -182,7 +185,7 @@ else
endif
endif
MOZALLOC_LIB = -L$(DIST)/bin $(call EXPAND_MOZLIBNAME,mozalloc)
MOZALLOC_LIB = $(call EXPAND_LIBNAME_PATH,mozalloc,$(DIST)/lib)
OS_CFLAGS += $(_DEBUG_CFLAGS)
OS_CXXFLAGS += $(_DEBUG_CFLAGS)

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

@ -5696,12 +5696,6 @@ MOZ_ARG_DISABLE_BOOL(jsd,
dnl ========================================================
dnl = Disable IPC support for tabs and plugins
dnl ========================================================
case "${target}" in
*-wince*)
MOZ_IPC=
;;
esac
MOZ_ARG_DISABLE_BOOL(ipc,
[ --disable-ipc Disable IPC supports for tabs and plugins],
MOZ_IPC=,

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

@ -1014,7 +1014,7 @@ nsContentUtils::ParseIntMarginValue(const nsAString& aString, nsIntMargin& resul
PRInt32 start = 0, end = 0;
for (int count = 0; count < 4; count++) {
if (end >= marginStr.Length())
if ((PRUint32)end >= marginStr.Length())
return PR_FALSE;
// top, right, bottom, left
@ -6318,7 +6318,7 @@ nsIContentUtils::FindInternalContentViewer(const char* aType,
#ifdef MOZ_MEDIA
#ifdef MOZ_OGG
if (nsHTMLMediaElement::IsOggEnabled()) {
for (int i = 0; i < NS_ARRAY_LENGTH(nsHTMLMediaElement::gOggTypes); ++i) {
for (unsigned int i = 0; i < NS_ARRAY_LENGTH(nsHTMLMediaElement::gOggTypes); ++i) {
const char* type = nsHTMLMediaElement::gOggTypes[i];
if (!strcmp(aType, type)) {
docFactory = do_GetService("@mozilla.org/content/document-loader-factory;1");
@ -6333,7 +6333,7 @@ nsIContentUtils::FindInternalContentViewer(const char* aType,
#ifdef MOZ_WEBM
if (nsHTMLMediaElement::IsWebMEnabled()) {
for (int i = 0; i < NS_ARRAY_LENGTH(nsHTMLMediaElement::gWebMTypes); ++i) {
for (unsigned int i = 0; i < NS_ARRAY_LENGTH(nsHTMLMediaElement::gWebMTypes); ++i) {
const char* type = nsHTMLMediaElement::gWebMTypes[i];
if (!strcmp(aType, type)) {
docFactory = do_GetService("@mozilla.org/content/document-loader-factory;1");

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

@ -1719,6 +1719,13 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mPreloadingImages)
if (tmp->mBoxObjectTable) {
tmp->mBoxObjectTable->EnumerateRead(ClearAllBoxObjects, nsnull);
delete tmp->mBoxObjectTable;
tmp->mBoxObjectTable = nsnull;
}
// nsDocument has a pretty complex destructor, so we're going to
// assume that *most* cycles you actually want to break somewhere
// else, and not unlink an awful lot here.

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

@ -212,7 +212,7 @@ nsICanvasRenderingContextWebGL_BufferSubData(JSContext *cx, uintN argc, jsval *v
/*
* ReadPixels takes:
* TexImage2D(int, int, int, int, uint, uint, ArrayBufferView)
* ReadPixels(int, int, int, int, uint, uint, ArrayBufferView)
*/
static JSBool
nsICanvasRenderingContextWebGL_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
@ -230,8 +230,7 @@ nsICanvasRenderingContextWebGL_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE;
// XXX we currently allow passing only 6 args to support the API. Eventually drop that.
if (argc < 6)
if (argc < 7)
return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
jsval *argv = JS_ARGV(cx, vp);
@ -244,40 +243,8 @@ nsICanvasRenderingContextWebGL_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
GET_UINT32_ARG(argv4, 4);
GET_UINT32_ARG(argv5, 5);
if (argc == 6) {
/*** BEGIN old API deprecated code. Eventually drop that. ***/
// the code here is ugly, but temporary. It comes from the old ReadPixels implementation.
// Remove it as soon as it's OK to drop the old API.
PRInt32 byteLength;
rv = self->ReadPixels_byteLength_old_API_deprecated(argv2, argv3, argv4, argv5, &byteLength);
if (NS_FAILED(rv)) {
xpc_qsThrow(cx, NS_ERROR_FAILURE);
return JS_FALSE;
}
JSObject *abufObject = js_CreateArrayBuffer(cx, byteLength);
if (!abufObject) {
xpc_qsThrow(cx, NS_ERROR_FAILURE);
return JS_FALSE;
}
js::ArrayBuffer *abuf = js::ArrayBuffer::fromJSObject(abufObject);
rv = self->ReadPixels_buf(
argv0, argv1, argv2, argv3, argv4, argv5, abuf);
if (NS_FAILED(rv)) {
xpc_qsThrow(cx, NS_ERROR_FAILURE);
return JS_FALSE;
}
JSObject *retval = js_CreateTypedArrayWithBuffer(cx, js::TypedArray::TYPE_UINT8,
abufObject, 0, byteLength);
*vp = OBJECT_TO_JSVAL(retval);
return JS_TRUE; // return here to be unaffected by the *vp = JSVAL_VOID; below
/*** END old API deprecated code ***/
} else if (argc == 7 &&
!JSVAL_IS_PRIMITIVE(argv[6]))
if (argc == 7 &&
!JSVAL_IS_PRIMITIVE(argv[6]))
{
JSObject *argv6 = JSVAL_TO_OBJECT(argv[6]);
if (js_IsArrayBuffer(argv6)) {
@ -306,7 +273,7 @@ nsICanvasRenderingContextWebGL_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
/*
* TexImage2D takes:
* TexImage2D(uint, int, uint, int, int, int, uint, uint, ArrayBufferView)\
* TexImage2D(uint, int, uint, int, int, int, uint, uint, ArrayBufferView)
* TexImage2D(uint, int, uint, uint, uint, nsIDOMElement)
* TexImage2D(uint, int, uint, uint, uint, ImageData)
*/
@ -326,9 +293,7 @@ nsICanvasRenderingContextWebGL_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE;
// XXX we currently allow passing only 3 args to support the API. Eventually drop that.
// if (argc < 6 || argc == 7 || argc == 8)
if (argc < 3)
if (argc < 6 || argc == 7 || argc == 8)
return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
jsval *argv = JS_ARGV(cx, vp);
@ -337,22 +302,9 @@ nsICanvasRenderingContextWebGL_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
GET_UINT32_ARG(argv0, 0);
GET_INT32_ARG(argv1, 1);
if (argc > 2 && JSVAL_IS_OBJECT(argv[2])) {
// the old API. Eventually drop that.
nsIDOMElement *elt;
xpc_qsSelfRef eltRef;
rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[2], &elt, &eltRef.ptr, &argv[2]);
if (NS_FAILED(rv)) return JS_FALSE;
GET_OPTIONAL_UINT32_ARG(argv3, 3);
GET_OPTIONAL_UINT32_ARG(argv4, 4);
rv = self->TexImage2D_dom_old_API_deprecated(argv0, argv1, elt, argv3, argv4);
} else if (argc > 5 &&
!JSVAL_IS_PRIMITIVE(argv[5]))
if (argc > 5 &&
!JSVAL_IS_PRIMITIVE(argv[5]))
{
// implement the variants taking a DOMElement as argv[5]
GET_UINT32_ARG(argv2, 2);
GET_UINT32_ARG(argv3, 3);

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

@ -56,6 +56,8 @@
#include "GLContextProvider.h"
#include "prenv.h"
using namespace mozilla;
using namespace mozilla::gl;
@ -275,29 +277,77 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
format.depth = 16;
format.minDepth = 1;
gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(width, height), format);
#ifdef XP_WIN
// On Windows, we may have a choice of backends, including straight
// OpenGL, D3D through ANGLE via EGL, or straight EGL/GLES2.
// We don't differentiate the latter two yet, but we allow for
// a env var to try EGL first, instead of last.
bool preferEGL = PR_GetEnv("MOZ_WEBGL_PREFER_EGL") != nsnull;
// if we want EGL, try it first
if (!gl && preferEGL) {
gl = gl::GLContextProviderEGL::CreateOffscreen(gfxIntSize(width, height), format);
if (gl && !InitAndValidateGL()) {
gl = nsnull;
}
}
// if it failed, then try the default provider, whatever that is
if (!gl) {
gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(width, height), format);
if (gl && !InitAndValidateGL()) {
gl = nsnull;
}
}
// if that failed, and we weren't already preferring EGL, try it now.
if (!gl && !preferEGL) {
gl = gl::GLContextProviderEGL::CreateOffscreen(gfxIntSize(width, height), format);
if (gl && !InitAndValidateGL()) {
gl = nsnull;
}
}
#else
// other platforms just use whatever the default is
if (!gl) {
gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(width, height), format);
if (gl && !InitAndValidateGL()) {
gl = nsnull;
}
}
#endif
// last chance, try OSMesa
if (!gl) {
gl = gl::GLContextProviderOSMesa::CreateOffscreen(gfxIntSize(width, height), format);
if (gl) {
if (!InitAndValidateGL()) {
gl = nsnull;
} else {
// make sure we notify always in this case, because it's likely going to be
// painfully slow
LogMessage("WebGL: Using software rendering via OSMesa");
}
}
}
if (!gl) {
LogMessage("WebGL: Can't get a usable OpenGL context.");
return NS_ERROR_FAILURE;
}
printf_stderr ("--- WebGL context created: %p\n", gl.get());
#ifdef USE_GLES2
// On native GLES2, no need to validate, the compiler will do it
mShaderValidation = PR_FALSE;
#else
// Check the shader validator pref
nsCOMPtr<nsIPrefBranch> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
NS_ENSURE_TRUE(prefService != nsnull, NS_ERROR_FAILURE);
if (gl->IsGLES2()) {
// On native GLES2, no need to validate, the compiler will do it
mShaderValidation = PR_FALSE;
} else {
// Otherwise, check the shader validator pref
nsCOMPtr<nsIPrefBranch> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
NS_ENSURE_TRUE(prefService != nsnull, NS_ERROR_FAILURE);
prefService->GetBoolPref("webgl.shader_validator", &mShaderValidation);
#endif
if (!InitAndValidateGL()) {
gl = gl::GLContextProviderOSMesa::CreateOffscreen(gfxIntSize(width, height), format);
if (!InitAndValidateGL()) {
LogMessage("WebGL: Can't get a usable OpenGL context.");
return NS_ERROR_FAILURE;
}
LogMessage("WebGL: Using software rendering via OSMesa");
prefService->GetBoolPref("webgl.shader_validator", &mShaderValidation);
}
mWidth = width;

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

@ -2409,58 +2409,6 @@ WebGLContext::ReadPixels_buf(WebGLint x, WebGLint y, WebGLsizei width, WebGLsize
pixels ? pixels->byteLength : 0);
}
NS_IMETHODIMP
WebGLContext::ReadPixels_byteLength_old_API_deprecated(WebGLsizei width, WebGLsizei height,
WebGLenum format, WebGLenum type, WebGLsizei *retval)
{
*retval = 0;
if (width < 0 || height < 0)
return ErrorInvalidValue("ReadPixels: negative size passed");
PRUint32 size = 0;
switch (format) {
case LOCAL_GL_ALPHA:
size = 1;
break;
case LOCAL_GL_RGB:
size = 3;
break;
case LOCAL_GL_RGBA:
size = 4;
break;
default:
return ErrorInvalidEnumInfo("ReadPixels: format", format);
}
switch (type) {
// case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
// case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
// case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
case LOCAL_GL_UNSIGNED_BYTE:
break;
default:
return ErrorInvalidEnumInfo("ReadPixels: type", type);
}
PRUint32 packAlignment;
gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, (GLint*) &packAlignment);
CheckedUint32 checked_plainRowSize = CheckedUint32(width) * size;
// alignedRowSize = row size rounded up to next multiple of
// packAlignment which is a power of 2
CheckedUint32 checked_alignedRowSize
= ((checked_plainRowSize + packAlignment-1) / packAlignment) * packAlignment;
CheckedUint32 checked_neededByteLength = (height-1)*checked_alignedRowSize + checked_plainRowSize;
if (!checked_neededByteLength.valid())
return ErrorInvalidOperation("ReadPixels: integer overflow computing the needed buffer size");
*retval = checked_neededByteLength.value();
return NS_OK;
}
NS_IMETHODIMP
WebGLContext::RenderbufferStorage(WebGLenum target, WebGLenum internalformat, WebGLsizei width, WebGLsizei height)
{
@ -3229,27 +3177,6 @@ WebGLContext::TexImage2D_dom(WebGLenum target, WebGLint level, WebGLenum interna
isurf->Data(), byteLength);
}
NS_IMETHODIMP
WebGLContext::TexImage2D_dom_old_API_deprecated(WebGLenum target, WebGLint level, nsIDOMElement *elt,
PRBool flipY, PRBool premultiplyAlpha)
{
nsRefPtr<gfxImageSurface> isurf;
nsresult rv = DOMElementToImageSurface(elt, getter_AddRefs(isurf),
flipY, premultiplyAlpha);
if (NS_FAILED(rv))
return rv;
NS_ASSERTION(isurf->Stride() == isurf->Width() * 4, "Bad stride!");
PRUint32 byteLength = isurf->Stride() * isurf->Height();
return TexImage2D_base(target, level, LOCAL_GL_RGBA,
isurf->Width(), isurf->Height(), 0,
LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE,
isurf->Data(), byteLength);
}
NS_IMETHODIMP
WebGLContext::TexSubImage2D(PRInt32 dummy)
{

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

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<script>
function boom()
{
var input = document.getElementById("i");
input.setAttribute('type', "image");
input.removeAttribute('type');
input.placeholder = "Y";
}
</script>
</head>
<body onload="boom();"><input id="i" /></body>
</html>

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

@ -16,3 +16,4 @@ load 515829-1.html
load 515829-2.html
load 570566-1.html
load 571428-1.html
load 580507-1.xhtml

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

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
/**
* This interface is used so that the parser can notify the textarea when
* it has finished loading content.
*/
[scriptable, uuid(36878df2-1dd2-11b2-99a0-ea9fab347485)]
interface nsITextAreaElement : nsISupports
{
/**
* Called when the parser is done adding child content
* to the select during document loading.
*/
void doneAddingChildren();
};

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

@ -128,7 +128,6 @@ endif
FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
INCLUDES += \

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

@ -66,11 +66,6 @@ public:
// nsIDOMHTMLMapElement
NS_DECL_NSIDOMHTMLMAPELEMENT
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers);
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
PRBool aNullParent = PR_TRUE);
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLMapElement,
@ -110,38 +105,6 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLMapElement)
nsGenericHTMLElement)
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLMapElement)
nsresult
nsHTMLMapElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers)
{
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(aDocument);
if (htmlDoc) {
htmlDoc->AddImageMap(this);
}
return rv;
}
void
nsHTMLMapElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
{
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(GetCurrentDoc());
if (htmlDoc) {
htmlDoc->RemoveImageMap(this);
}
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
NS_IMPL_ELEMENT_CLONE(nsHTMLMapElement)

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

@ -1835,6 +1835,10 @@ nsTextEditorState::ValueWasChanged(PRBool aNotify)
void
nsTextEditorState::UpdatePlaceholderText(PRBool aNotify)
{
// If we don't have a placeholder div, there's nothing to do.
if (!mPlaceholderDiv)
return;
nsAutoString placeholderValue;
nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);

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

@ -179,8 +179,9 @@ _TEST_FILES = \
test_bug546995-5.html \
file_bug546995.html \
test_bug377624.html \
test_bug562932.html \
test_bug551846.html \
test_bug562932.html \
test_bug564001.html \
test_bug566046.html \
test_bug567938-1.html \
test_bug567938-2.html \

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

@ -80,6 +80,13 @@ var focusableElements = [
"<iframe src=\"about:blank\" tabindex=\"1\"></iframe>",
"<iframe src=\"about:blank\" contenteditable=\"true\"></iframe>",
"<iframe></iframe>",
"<iframe tabindex=\"-1\"></iframe>",
"<iframe tabindex=\"0\"></iframe>",
"<iframe tabindex=\"0\" disabled></iframe>",
"<iframe tabindex=\"1\"></iframe>",
"<iframe disabled></iframe>",
"<img tabindex=\"-1\">",
"<img tabindex=\"0\">",
"<img tabindex=\"0\" disabled>",
@ -179,13 +186,6 @@ var nonFocusableElements = [
"<div tabindex=\"0\" disabled></div>",
"<div disabled></div>",
"<iframe></iframe>",
"<iframe tabindex=\"-1\"></iframe>",
"<iframe tabindex=\"0\"></iframe>",
"<iframe tabindex=\"0\" disabled></iframe>",
"<iframe tabindex=\"1\"></iframe>",
"<iframe disabled></iframe>",
"<img>",
"<img disabled>",
"<img contenteditable=\"true\">",
@ -280,12 +280,19 @@ var focusableInContentEditable = [
"<embed contenteditable=\"true\">",
"<iframe src=\"about:blank\"></iframe>",
"<iframe></iframe>",
"<iframe src=\"about:blank\" disabled></iframe>",
"<iframe disabled></iframe>",
"<iframe src=\"about:blank\" tabindex=\"-1\"></iframe>",
"<iframe tabindex=\"-1\"></iframe>",
"<iframe src=\"about:blank\" tabindex=\"0\"></iframe>",
"<iframe tabindex=\"0\"></iframe>",
"<iframe src=\"about:blank\" tabindex=\"0\" disabled></iframe>",
"<iframe tabindex=\"0\" disabled></iframe>",
"<iframe src=\"about:blank\" tabindex=\"1\"></iframe>",
"<iframe tabindex=\"1\"></iframe>",
"<iframe src=\"about:blank\" contenteditable=\"true\"></iframe>",
"<iframe contenteditable=\"true\"></iframe>",
"<img tabindex=\"-1\">",
"<img tabindex=\"0\">",

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

@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=564001
-->
<head>
<title>Test for Bug 564001</title>
<script src="/MochiKit/packed.js"></script>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=564001">Mozilla Bug 564001</a>
<p id="display"><img usemap=#map src=image.png></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script>
/** Test for Bug 564001 **/
SimpleTest.waitForExplicitFinish();
var wrongArea = document.createElement("area");
wrongArea.shape = "default";
wrongArea.href = "#FAIL";
var wrongMap = document.createElement("map");
wrongMap.name = "map";
wrongMap.appendChild(wrongArea);
document.body.appendChild(wrongMap);
var rightArea = document.createElement("area");
rightArea.shape = "default";
rightArea.href = "#PASS";
var rightMap = document.createElement("map");
rightMap.name = "map";
rightMap.appendChild(rightArea);
document.body.insertBefore(rightMap, wrongMap);
var images = document.getElementsByTagName("img");
onhashchange = function() {
is(location.hash, "#PASS", "Should get the first map in tree order.");
SimpleTest.finish();
};
SimpleTest.waitForFocus(function() synthesizeMouse(images[0], 50, 50, {}));
</script>
</pre>
</body>
</html>

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

@ -243,7 +243,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLDocument, nsDocument)
NS_ASSERTION(!nsCCUncollectableMarker::InGeneration(cb, tmp->GetMarkedCCGeneration()),
"Shouldn't traverse nsHTMLDocument!");
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mImageMaps)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mImages)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mApplets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEmbeds)
@ -252,13 +251,14 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLDocument, nsDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mForms, nsIDOMNodeList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mFormControls,
nsIDOMNodeList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mImageMaps,
nsIDOMNodeList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mWyciwygChannel)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mMidasCommandManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFragmentParser)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLDocument, nsDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mImageMaps)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mImages)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mApplets)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mEmbeds)
@ -266,6 +266,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLDocument, nsDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAnchors)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mForms)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFormControls)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mImageMaps)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mWyciwygChannel)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mMidasCommandManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFragmentParser)
@ -330,7 +331,6 @@ nsHTMLDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
mLinks = nsnull;
mAnchors = nsnull;
mImageMaps.Clear();
mForms = nsnull;
NS_ASSERTION(!mWyciwygChannel,
@ -1157,39 +1157,20 @@ nsHTMLDocument::SetTitle(const nsAString& aTitle)
return nsDocument::SetTitle(aTitle);
}
nsresult
nsHTMLDocument::AddImageMap(nsIDOMHTMLMapElement* aMap)
{
// XXX We should order the maps based on their order in the document.
// XXX Otherwise scripts that add/remove maps with duplicate names
// XXX will cause problems
NS_PRECONDITION(nsnull != aMap, "null ptr");
if (nsnull == aMap) {
return NS_ERROR_NULL_POINTER;
}
if (mImageMaps.AppendObject(aMap)) {
return NS_OK;
}
return NS_ERROR_OUT_OF_MEMORY;
}
void
nsHTMLDocument::RemoveImageMap(nsIDOMHTMLMapElement* aMap)
{
NS_PRECONDITION(nsnull != aMap, "null ptr");
mImageMaps.RemoveObject(aMap);
}
nsIDOMHTMLMapElement *
nsHTMLDocument::GetImageMap(const nsAString& aMapName)
{
nsAutoString name;
PRUint32 i, n = mImageMaps.Count();
nsIDOMHTMLMapElement *firstMatch = nsnull;
if (!mImageMaps) {
mImageMaps = new nsContentList(this, nsGkAtoms::map, kNameSpaceID_XHTML);
}
NS_ASSERTION(mImageMaps, "Infallible malloc failed.");
nsIDOMHTMLMapElement* firstMatch = nsnull;
nsAutoString name;
PRUint32 i, n = mImageMaps->Length(PR_TRUE);
for (i = 0; i < n; ++i) {
nsIDOMHTMLMapElement *map = mImageMaps[i];
NS_ASSERTION(map, "Null map in map list!");
nsCOMPtr<nsIDOMHTMLMapElement> map(
do_QueryInterface(mImageMaps->GetNodeAt(i)));
PRBool match;
nsresult rv;

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

@ -105,10 +105,6 @@ public:
virtual void EndLoad();
virtual nsresult AddImageMap(nsIDOMHTMLMapElement* aMap);
virtual void RemoveImageMap(nsIDOMHTMLMapElement* aMap);
virtual nsIDOMHTMLMapElement *GetImageMap(const nsAString& aMapName);
virtual void SetCompatibilityMode(nsCompatibility aMode);
@ -289,8 +285,6 @@ protected:
return kNameSpaceID_XHTML;
}
nsCOMArray<nsIDOMHTMLMapElement> mImageMaps;
nsCOMPtr<nsIDOMHTMLCollection> mImages;
nsCOMPtr<nsIDOMHTMLCollection> mApplets;
nsCOMPtr<nsIDOMHTMLCollection> mEmbeds;
@ -298,6 +292,7 @@ protected:
nsCOMPtr<nsIDOMHTMLCollection> mAnchors;
nsRefPtr<nsContentList> mForms;
nsRefPtr<nsContentList> mFormControls;
nsRefPtr<nsContentList> mImageMaps;
/** # of forms in the document, synchronously set */
PRInt32 mNumForms;

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

@ -54,8 +54,8 @@ class nsIScriptElement;
class nsIEditor;
#define NS_IHTMLDOCUMENT_IID \
{ 0x1e1dc0fa, 0xf13e, 0x4abd, \
{ 0xa0, 0x95, 0x92, 0xa6, 0x7a, 0x31, 0x3c, 0x50 } }
{ 0x840cacc9, 0x1956, 0x4987, \
{ 0x80, 0x6e, 0xc6, 0xab, 0x19, 0x1b, 0x92, 0xd2 } }
/**
@ -66,12 +66,8 @@ class nsIHTMLDocument : public nsISupports
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IHTMLDOCUMENT_IID)
virtual nsresult AddImageMap(nsIDOMHTMLMapElement* aMap) = 0;
virtual nsIDOMHTMLMapElement *GetImageMap(const nsAString& aMapName) = 0;
virtual void RemoveImageMap(nsIDOMHTMLMapElement* aMap) = 0;
/**
* Set compatibility mode for this document
*/

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

@ -41,6 +41,28 @@
NS_IMPL_ADDREF(nsXMLBindingSet)
NS_IMPL_RELEASE(nsXMLBindingSet)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLBindingSet)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXMLBindingSet)
nsXMLBinding* binding = tmp->mFirst;
while (binding) {
binding->mExpr = nsnull;
binding = binding->mNext;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsXMLBindingSet)
nsXMLBinding* binding = tmp->mFirst;
while (binding) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "nsXMLBinding::mExpr");
cb.NoteXPCOMChild(binding->mExpr);
binding = binding->mNext;
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXMLBindingSet, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXMLBindingSet, Release)
nsresult
nsXMLBindingSet::AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr)
{

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

@ -39,6 +39,7 @@
#include "nsAutoPtr.h"
#include "nsIAtom.h"
#include "nsCycleCollectionParticipant.h"
class nsXULTemplateResultXML;
class nsXMLBindingValues;
@ -88,6 +89,7 @@ public:
NS_IMETHOD_(nsrefcnt) AddRef();
NS_IMETHOD_(nsrefcnt) Release();
NS_DECL_OWNINGTHREAD
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsXMLBindingSet)
/**
* Add a binding to the set

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

@ -145,7 +145,7 @@ nsXULTemplateBuilder::nsXULTemplateBuilder(void)
}
static PLDHashOperator
DestroyMatchList(nsISupports* aKey, nsTemplateMatch* aMatch, void* aContext)
DestroyMatchList(nsISupports* aKey, nsTemplateMatch*& aMatch, void* aContext)
{
nsFixedSizeAllocator* pool = static_cast<nsFixedSizeAllocator *>(aContext);
@ -156,7 +156,7 @@ DestroyMatchList(nsISupports* aKey, nsTemplateMatch* aMatch, void* aContext)
aMatch = next;
}
return PL_DHASH_NEXT;
return PL_DHASH_REMOVE;
}
nsXULTemplateBuilder::~nsXULTemplateBuilder(void)
@ -235,8 +235,7 @@ nsXULTemplateBuilder::Uninit(PRBool aIsFinal)
mQuerySets.Clear();
mMatchMap.EnumerateRead(DestroyMatchList, &mPool);
mMatchMap.Clear();
mMatchMap.Enumerate(DestroyMatchList, &mPool);
mRootResult = nsnull;
mRefVariable = nsnull;
@ -267,6 +266,13 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULTemplateBuilder)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDataSource)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDB)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCompDB)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRoot)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRootResult)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mListeners)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mQueryProcessor)
if (tmp->mMatchMap.IsInitialized()) {
tmp->mMatchMap.Enumerate(DestroyMatchList, &(tmp->mPool));
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateBuilder)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDataSource)

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

@ -109,12 +109,34 @@ nsXULTemplateResultSetXML::GetNext(nsISupports **aResult)
// nsXULTemplateQueryProcessorXML
//
static PLDHashOperator
TraverseRuleToBindingsMap(nsISupports* aKey, nsXMLBindingSet* aMatch, void* aContext)
{
nsCycleCollectionTraversalCallback *cb =
static_cast<nsCycleCollectionTraversalCallback*>(aContext);
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mRuleToBindingsMap key");
cb->NoteXPCOMChild(aKey);
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mRuleToBindingsMap value");
cb->NoteNativeChild(aMatch, &NS_CYCLE_COLLECTION_NAME(nsXMLBindingSet));
return PL_DHASH_NEXT;
}
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTemplateQueryProcessorXML)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULTemplateQueryProcessorXML)
if (tmp->mRuleToBindingsMap.IsInitialized()) {
tmp->mRuleToBindingsMap.Clear();
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRoot)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mEvaluator)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTemplateBuilder)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateQueryProcessorXML)
if (tmp->mRuleToBindingsMap.IsInitialized()) {
tmp->mRuleToBindingsMap.EnumerateRead(TraverseRuleToBindingsMap, &cb);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRoot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEvaluator)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTemplateBuilder)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END

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

@ -107,7 +107,6 @@ var oldtreefirstrow, oldtreecfirstrow;
function nextDataSource()
{
document.documentElement.getBoundingClientRect();
var tree = document.getElementById('t');
var treec = document.getElementById('tc');
tree.treeBoxObject.scrollToRow(10);

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

@ -120,6 +120,7 @@
"<body>test1</body></html>";
gExpected = [{type: "pagehide", persisted: true},
{type: "load", title: "test1"},
{type: "pageshow", title: "test1", persisted: false}];
gBrowser.loadURI(test1Doc);

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

@ -240,7 +240,7 @@ function pageEventListener(event) {
try {
dump("TEST: eventListener received a " + event.type + " event for page " +
event.originalTarget.title + ", persisted=" + event.persisted + "\n");
}catch(e) {
} catch(e) {
// Ignore any exception.
}
@ -293,8 +293,8 @@ function pageEventListener(event) {
if (typeof(expected.persisted) != "undefined") {
is(event.persisted, expected.persisted,
"The persisted property of the " + event.type + "event on page " +
event.originalTarget.title + " had an unexpected value");
"The persisted property of the " + event.type + " event on page " +
event.originalTarget.location + " had an unexpected value");
}
// If we're out of expected events, let doPageNavigation() return.

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

@ -43,11 +43,13 @@ function runNextTest() {
getInterface(Components.interfaces.nsIDOMWindowUtils);
utils.sendNativeKeyEvent(0, 13 /* w */, 0x4000 /* cmd */, "w", "w");
ok(didClose, "Cmd+W should have closed the tab");
if (!didClose) {
win.close();
}
SimpleTest.finish();
setTimeout(function () {
ok(didClose, "Cmd+W should have closed the tab");
if (!didClose) {
win.close();
}
SimpleTest.finish();
}, 1000);
}
</script>

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

@ -631,12 +631,11 @@ static nsDOMClassInfoData sClassInfoData[] = {
// to JS.
NS_DEFINE_CLASSINFO_DATA(Window, nsWindowSH,
NS_DEFINE_CLASSINFO_DATA(Window, nsOuterWindowSH,
DEFAULT_SCRIPTABLE_FLAGS |
WINDOW_SCRIPTABLE_FLAGS)
// XXX Wrong helper!
NS_DEFINE_CLASSINFO_DATA(InnerWindow, nsWindowSH,
NS_DEFINE_CLASSINFO_DATA(InnerWindow, nsInnerWindowSH,
DEFAULT_SCRIPTABLE_FLAGS |
WINDOW_SCRIPTABLE_FLAGS)
@ -927,12 +926,11 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
// DOM Chrome Window class.
NS_DEFINE_CLASSINFO_DATA(ChromeWindow, nsWindowSH,
NS_DEFINE_CLASSINFO_DATA(ChromeWindow, nsOuterWindowSH,
DEFAULT_SCRIPTABLE_FLAGS |
WINDOW_SCRIPTABLE_FLAGS)
// XXX Wrong helper!
NS_DEFINE_CLASSINFO_DATA(InnerChromeWindow, nsWindowSH,
NS_DEFINE_CLASSINFO_DATA(InnerChromeWindow, nsInnerWindowSH,
DEFAULT_SCRIPTABLE_FLAGS |
WINDOW_SCRIPTABLE_FLAGS)
@ -1315,12 +1313,11 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(FileReader, nsEventTargetSH,
EVENTTARGET_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsWindowSH,
NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsOuterWindowSH,
DEFAULT_SCRIPTABLE_FLAGS |
WINDOW_SCRIPTABLE_FLAGS)
// XXX Wrong helper!
NS_DEFINE_CLASSINFO_DATA(InnerModalContentWindow, nsWindowSH,
NS_DEFINE_CLASSINFO_DATA(InnerModalContentWindow, nsInnerWindowSH,
DEFAULT_SCRIPTABLE_FLAGS |
WINDOW_SCRIPTABLE_FLAGS)
@ -4827,8 +4824,8 @@ nsDOMClassInfo::ShutDown()
// Window helper
NS_IMETHODIMP
nsWindowSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj)
nsCommonWindowSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj)
{
// Normally ::PreCreate() is used to give XPConnect the parent
// object for the object that's being wrapped, this parent object is
@ -4847,6 +4844,10 @@ nsWindowSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
nsGlobalWindow *win = nsGlobalWindow::FromSupports(nativeObj);
if (win->IsOuterWindow()) {
win->EnsureInnerWindow();
}
if (sgo) {
*parentObj = sgo->GetGlobalJSObject();
@ -4870,18 +4871,21 @@ nsWindowSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
static JSClass sGlobalScopePolluterClass = {
"Global Scope Polluter",
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_NEW_RESOLVE,
nsWindowSH::SecurityCheckOnSetProp, nsWindowSH::SecurityCheckOnSetProp,
nsWindowSH::GlobalScopePolluterGetProperty,
nsWindowSH::SecurityCheckOnSetProp, JS_EnumerateStub,
(JSResolveOp)nsWindowSH::GlobalScopePolluterNewResolve, JS_ConvertStub,
nsCommonWindowSH::SecurityCheckOnSetProp,
nsCommonWindowSH::SecurityCheckOnSetProp,
nsCommonWindowSH::GlobalScopePolluterGetProperty,
nsCommonWindowSH::SecurityCheckOnSetProp,
JS_EnumerateStub,
(JSResolveOp)nsCommonWindowSH::GlobalScopePolluterNewResolve,
JS_ConvertStub,
nsHTMLDocumentSH::ReleaseDocument
};
// static
JSBool
nsWindowSH::GlobalScopePolluterGetProperty(JSContext *cx, JSObject *obj,
jsid id, jsval *vp)
nsCommonWindowSH::GlobalScopePolluterGetProperty(JSContext *cx, JSObject *obj,
jsid id, jsval *vp)
{
// Someone is accessing a element by referencing its name/id in the
// global scope, do a security check to make sure that's ok.
@ -4907,8 +4911,8 @@ nsWindowSH::GlobalScopePolluterGetProperty(JSContext *cx, JSObject *obj,
// static
JSBool
nsWindowSH::SecurityCheckOnSetProp(JSContext *cx, JSObject *obj, jsid id,
jsval *vp)
nsCommonWindowSH::SecurityCheckOnSetProp(JSContext *cx, JSObject *obj, jsid id,
jsval *vp)
{
// Someone is accessing a element by referencing its name/id in the
// global scope, do a security check to make sure that's ok.
@ -4932,8 +4936,8 @@ GetDocument(JSContext *cx, JSObject *obj)
// static
JSBool
nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
jsid id, uintN flags,
nsCommonWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
jsid id, uintN flags,
JSObject **objp)
{
if (flags & (JSRESOLVE_ASSIGNING | JSRESOLVE_DECLARING |
@ -5002,7 +5006,7 @@ nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
// static
void
nsWindowSH::InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj)
nsCommonWindowSH::InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj)
{
JSObject *proto;
@ -5029,8 +5033,8 @@ nsWindowSH::InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj)
// static
nsresult
nsWindowSH::InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
nsIHTMLDocument *doc)
nsCommonWindowSH::InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
nsIHTMLDocument *doc)
{
// If global scope pollution is disabled, or if our document is not
// a HTML document, do nothing
@ -5097,8 +5101,8 @@ GetChildFrame(nsGlobalWindow *win, jsid id)
}
NS_IMETHODIMP
nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, jsval *vp, PRBool *_retval)
nsCommonWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, jsval *vp, PRBool *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
@ -5171,6 +5175,9 @@ nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// check and return.
nsGlobalWindow *frameWin = (nsGlobalWindow *)frame.get();
NS_ASSERTION(frameWin->IsOuterWindow(), "GetChildFrame gave us an inner?");
frameWin->EnsureInnerWindow();
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = WrapNative(cx, frameWin->GetGlobalJSObject(), frame,
@ -5195,7 +5202,7 @@ nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
if (JSID_IS_STRING(id) && !JSVAL_IS_PRIMITIVE(*vp) &&
::JS_TypeOfValue(cx, *vp) != JSTYPE_FUNCTION) {
// A named property accessed which could have been resolved to a
// child frame in nsWindowSH::NewResolve() (*vp will tell us if
// child frame in nsCommonWindowSH::NewResolve() (*vp will tell us if
// that's the case). If *vp is a window object (i.e. a child
// frame), return without doing a security check.
//
@ -5233,8 +5240,8 @@ nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
NS_IMETHODIMP
nsWindowSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, jsval *vp, PRBool *_retval)
nsCommonWindowSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, jsval *vp, PRBool *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
@ -5310,9 +5317,9 @@ nsWindowSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
NS_IMETHODIMP
nsWindowSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, jsval *vp,
PRBool *_retval)
nsCommonWindowSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, jsval *vp,
PRBool *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
@ -5369,9 +5376,9 @@ nsWindowSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
NS_IMETHODIMP
nsWindowSH::DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, jsval *vp,
PRBool *_retval)
nsCommonWindowSH::DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, jsval *vp,
PRBool *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
@ -6213,8 +6220,8 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx,
// static
nsresult
nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
JSObject *obj, JSString *str, PRBool *did_resolve)
nsCommonWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
JSObject *obj, JSString *str, PRBool *did_resolve)
{
*did_resolve = PR_FALSE;
@ -6454,12 +6461,12 @@ ContentWindowGetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
}
PRBool
nsWindowSH::sResolving = PR_FALSE;
nsCommonWindowSH::sResolving = PR_FALSE;
NS_IMETHODIMP
nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval)
nsCommonWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
@ -7003,9 +7010,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_OK;
}
}
} else if (id == sDialogArguments_id &&
(mData == &sClassInfoData[eDOMClassInfo_InnerModalContentWindow_id] ||
mData == &sClassInfoData[eDOMClassInfo_ModalContentWindow_id])) {
} else if (id == sDialogArguments_id && win->IsModalContentWindow()) {
nsCOMPtr<nsIArray> args;
((nsGlobalModalWindow *)win)->GetDialogArguments(getter_AddRefs(args));
@ -7092,9 +7097,9 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
NS_IMETHODIMP
nsWindowSH::NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 enum_op, jsval *statep,
jsid *idp, PRBool *_retval)
nsCommonWindowSH::NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 enum_op, jsval *statep,
jsid *idp, PRBool *_retval)
{
switch ((JSIterateOp)enum_op) {
/* FIXME bug 576449: non-enumerable property support */
@ -7156,8 +7161,8 @@ nsWindowSH::NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
NS_IMETHODIMP
nsWindowSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj)
nsCommonWindowSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj)
{
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryWrappedNative(wrapper));
NS_ENSURE_TRUE(sgo, NS_ERROR_UNEXPECTED);
@ -7168,8 +7173,8 @@ nsWindowSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
NS_IMETHODIMP
nsWindowSH::Equality(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, const jsval &val, PRBool *bp)
nsCommonWindowSH::Equality(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, const jsval &val, PRBool *bp)
{
*bp = PR_FALSE;
@ -7205,8 +7210,8 @@ nsWindowSH::Equality(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
}
NS_IMETHODIMP
nsWindowSH::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval)
nsCommonWindowSH::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval)
{
nsGlobalWindow *origWin = nsGlobalWindow::FromWrapper(wrapper);
nsGlobalWindow *win = origWin->GetOuterWindowInternal();
@ -7233,8 +7238,8 @@ nsWindowSH::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
}
NS_IMETHODIMP
nsWindowSH::InnerObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval)
nsCommonWindowSH::InnerObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);

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

@ -478,14 +478,14 @@ public:
// Window scriptable helper
class nsWindowSH : public nsEventReceiverSH
class nsCommonWindowSH : public nsEventReceiverSH
{
protected:
nsWindowSH(nsDOMClassInfoData* aData) : nsEventReceiverSH(aData)
nsCommonWindowSH(nsDOMClassInfoData *aData) : nsEventReceiverSH(aData)
{
}
virtual ~nsWindowSH()
virtual ~nsCommonWindowSH()
{
}
@ -553,10 +553,41 @@ public:
static void InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj);
static nsresult InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
nsIHTMLDocument *doc);
};
class nsOuterWindowSH : public nsCommonWindowSH
{
protected:
nsOuterWindowSH(nsDOMClassInfoData* aData) : nsCommonWindowSH(aData)
{
}
virtual ~nsOuterWindowSH()
{
}
public:
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
{
return new nsWindowSH(aData);
return new nsOuterWindowSH(aData);
}
};
class nsInnerWindowSH : public nsCommonWindowSH
{
protected:
nsInnerWindowSH(nsDOMClassInfoData* aData) : nsCommonWindowSH(aData)
{
}
virtual ~nsInnerWindowSH()
{
}
public:
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
{
return new nsInnerWindowSH(aData);
}
};

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

@ -1304,13 +1304,6 @@ nsGlobalWindow::SetScriptContext(PRUint32 lang_id, nsIScriptContext *aScriptCont
aScriptContext->SetGCOnDestruction(PR_FALSE);
}
nsCOMPtr<nsIPrincipal> principal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
aScriptContext->CreateOuterObject(this, principal);
aScriptContext->DidInitializeContext();
mJSObject = (JSObject *)aScriptContext->GetNativeGlobal();
}
mContext = aScriptContext;
@ -1620,6 +1613,10 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
if (IsFrozen()) {
// This outer is now getting its first inner, thaw the outer now
// that it's ready and is getting an inner window.
mContext->CreateOuterObject(this, aDocument->NodePrincipal());
mContext->DidInitializeContext();
mJSObject = (JSObject *)mContext->GetNativeGlobal();
Thaw();
}
@ -1745,7 +1742,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
newInnerWindow = currentInner;
if (aDocument != oldDoc) {
nsWindowSH::InvalidateGlobalScopePolluter(cx, currentInner->mJSObject);
nsCommonWindowSH::InvalidateGlobalScopePolluter(cx, currentInner->mJSObject);
}
} else {
if (aState) {
@ -1930,8 +1927,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
if ((!reUseInnerWindow || aDocument != oldDoc) && !aState) {
nsCOMPtr<nsIHTMLDocument> html_doc(do_QueryInterface(mDocument));
nsWindowSH::InstallGlobalScopePolluter(cx, newInnerWindow->mJSObject,
html_doc);
nsCommonWindowSH::InstallGlobalScopePolluter(cx, newInnerWindow->mJSObject,
html_doc);
}
// This code should not be called during shutdown any more (now that
@ -2471,7 +2468,7 @@ nsGlobalWindow::DefineArgumentsProperty(nsIArray *aArguments)
if (mIsModalContentWindow) {
// Modal content windows don't have an "arguments" property, they
// have a "dialogArguments" property which is handled
// separately. See nsWindowSH::NewResolve().
// separately. See nsCommonWindowSH::NewResolve().
return NS_OK;
}

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

@ -3464,7 +3464,7 @@ nsJSContext::ClearScope(void *aGlobalObj, PRBool aClearFromProtoChain)
// chain when we're clearing an outer window whose current inner we
// still want.
if (aClearFromProtoChain) {
nsWindowSH::InvalidateGlobalScopePolluter(mContext, obj);
nsCommonWindowSH::InvalidateGlobalScopePolluter(mContext, obj);
// Clear up obj's prototype chain, but not Object.prototype.
for (JSObject *o = ::JS_GetPrototype(mContext, obj), *next;
@ -3980,11 +3980,13 @@ SetMemoryHighWaterMarkPrefChangedCallback(const char* aPrefName, void* aClosure)
PRInt32 highwatermark = nsContentUtils::GetIntPref(aPrefName, 32);
if (highwatermark >= 32) {
// There are two options of memory usage in tracemonkey. One is
// to use malloc() and the other is to use memory for GC. (E.g.
// js_NewGCThing()/RefillDoubleFreeList()).
// Let's limit the high water mark for the first one to 32MB,
// and second one to 0xffffffff.
/*
* There are two ways to allocate memory in SpiderMonkey. One is
* to use jsmalloc() and the other is to use GC-owned memory
* (e.g. js_NewGCThing()).
*
* In the browser, we don't cap the amount of GC-owned memory.
*/
JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_MALLOC_BYTES,
64L * 1024L * 1024L);
JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_BYTES,

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

@ -404,7 +404,7 @@ nsLocation::GetHost(nsAString& aHost)
}
}
return result;
return NS_OK;
}
NS_IMETHODIMP
@ -443,7 +443,7 @@ nsLocation::GetHostname(nsAString& aHostname)
}
}
return result;
return NS_OK;
}
NS_IMETHODIMP

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

@ -397,11 +397,6 @@ public:
virtual PRBool CanClose() = 0;
virtual nsresult ForceClose() = 0;
void SetModalContentWindow(PRBool aIsModalContentWindow)
{
mIsModalContentWindow = aIsModalContentWindow;
}
PRBool IsModalContentWindow() const
{
return mIsModalContentWindow;

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

@ -288,7 +288,7 @@ nsScriptNameSpaceManager::FillHash(nsICategoryManager *aCategoryManager,
// count), once such an interface is found the "nsIDOM" prefix is cut
// off the name and the rest of the name is added into the hash for
// global names. This makes things like 'Node.ELEMENT_NODE' work in
// JS. See nsWindowSH::GlobalResolve() for detais on how this is used.
// JS. See nsCommonWindowSH::GlobalResolve() for detais on how this is used.
nsresult
nsScriptNameSpaceManager::FillHashWithDOMInterfaces()

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

@ -128,7 +128,7 @@ interface nsIWebGLUniformLocation : nsISupports
};
[scriptable, uuid(f02c85e0-8305-11de-abe2-000c29206271)]
[scriptable, uuid(2f21ca21-9720-4eee-ad94-27eefe4f72dc)]
interface nsICanvasRenderingContextWebGL : nsISupports
{
//
@ -725,8 +725,6 @@ interface nsICanvasRenderingContextWebGL : nsISupports
in WebGLenum format, in WebGLenum type, in WebGLArrayPtr pixels);
[noscript] void readPixels_buf(in WebGLint x, in WebGLint y, in WebGLsizei width, in WebGLsizei height,
in WebGLenum format, in WebGLenum type, in WebGLArrayBufferPtr pixels);
[noscript] WebGLsizei readPixels_byteLength_old_API_deprecated(
in WebGLsizei width, in WebGLsizei height, in WebGLenum format, in WebGLenum type);
//void glReleaseShaderCompiler();
@ -754,9 +752,6 @@ interface nsICanvasRenderingContextWebGL : nsISupports
// HTMLImageElement, HTMLCanvasElement, HTMLVideoElement
[noscript] void texImage2D_dom(in WebGLenum target, in WebGLint level, in WebGLenum internalformat,
in WebGLenum format, in WebGLenum type, in nsIDOMElement element);
// XXX the old API. Eventually drop that.
[noscript] void TexImage2D_dom_old_API_deprecated(in WebGLenum target, in WebGLint level,
in nsIDOMElement element, in PRBool flipY, in PRBool premultiplyAlpha);
void texSubImage2D([optional] in long dummy);
[noscript] void texSubImage2D_buf(in WebGLenum target, in WebGLint level,

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

@ -116,6 +116,7 @@ _TEST_FILES = \
test_bug563487.html \
test_bug545314.html \
test_bug548828.html \
test_bug562433.html \
test_DOMWindowCreated_chromeonly.html \
test_bug581072.html \
test_bug583225.html \

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

@ -0,0 +1,36 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=562433
-->
<head>
<title>Test for Bug 562433</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=562433">Mozilla Bug 562433</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 562433 **/
var w = window.open("");
// The new window's location.host and location.hostname must be the empty
// string (instead of throwing an exception)
is(w.location.host, "", 'w.location.host should be ""');
is(w.location.hostname, "", 'w.location.hostname should be ""');
w.close();
</script>
</pre>
</body>
</html>

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

@ -47,6 +47,7 @@
#include "nsIClipboard.h"
#include "nsEditorCommands.h"
#include "nsIDocument.h"
#define STATE_ENABLED "state_enabled"
@ -669,7 +670,6 @@ nsSelectionMoveCommands::IsCommandEnabled(const char * aCommandName,
return NS_OK;
}
NS_IMETHODIMP
nsSelectionMoveCommands::DoCommand(const char *aCommandName,
nsISupports *aCommandRefCon)
@ -677,6 +677,15 @@ nsSelectionMoveCommands::DoCommand(const char *aCommandName,
nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
NS_ENSURE_TRUE(editor, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMDocument> domDoc;
editor->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
if (doc) {
// Most of the commands below (possibly all of them) need layout to
// be up to date.
doc->FlushPendingNotifications(Flush_Layout);
}
nsCOMPtr<nsISelectionController> selCont;
nsresult rv = editor->GetSelectionController(getter_AddRefs(selCont));
NS_ENSURE_SUCCESS(rv, rv);

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

@ -223,8 +223,6 @@ nsTransactionItem::UndoTransaction(nsTransactionManager *aTxMgr)
return result;
}
// FIXME: bug 583493
// NS_ENSURE_TRUE(mTransaction, NS_OK);
if (!mTransaction)
return NS_OK;
@ -451,7 +449,8 @@ nsTransactionItem::RecoverFromRedoError(nsTransactionManager *aTxMgr)
return result;
}
NS_ENSURE_TRUE(mTransaction, NS_OK);
if (!mTransaction)
return NS_OK;
return mTransaction->UndoTransaction();
}

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

@ -172,6 +172,13 @@ public:
*/
virtual gfxIntSize GetCurrentSize() = 0;
/**
* Set a new layer manager for this image container. It must be
* either of the same type as the container's current layer manager,
* or null. TRUE is returned on success.
*/
virtual PRBool SetLayerManager(LayerManager *aManager) = 0;
protected:
LayerManager* mManager;

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

@ -142,12 +142,21 @@ public:
LAYERS_D3D9
};
LayerManager() : mUserData(nsnull)
LayerManager() : mUserData(nsnull), mDestroyed(PR_FALSE)
{
InitLog();
}
virtual ~LayerManager() {}
/**
* Release layers and resources held by this layer manager, and mark
* it as destroyed. Should do any cleanup necessary in preparation
* for its widget going away. After this call, only user data calls
* are valid on the layer manager.
*/
virtual void Destroy() { mDestroyed = PR_TRUE; }
PRBool IsDestroyed() { return mDestroyed; }
/**
* Start a new transaction. Nested transactions are not allowed so
* there must be no transaction currently in progress.
@ -297,6 +306,7 @@ public:
protected:
nsRefPtr<Layer> mRoot;
void* mUserData;
PRPackedBool mDestroyed;
// Print interesting information about this into aTo. Internally
// used to implement Dump*() and Log*().
@ -328,7 +338,9 @@ public:
virtual ~Layer() {}
/**
* Returns the LayoutManager this Layer belongs to. Cannot be null.
* Returns the LayerManager this Layer belongs to. Note that the layer
* manager might be in a destroyed state, at which point it's only
* valid to set/get user data from it.
*/
LayerManager* Manager() { return mManager; }
@ -387,6 +399,7 @@ public:
}
Mutated();
}
/**
* CONSTRUCTION PHASE ONLY
* Set a clip rect which will be applied to this layer as it is

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -226,6 +226,7 @@ public:
virtual already_AddRefed<Image> GetCurrentImage();
virtual already_AddRefed<gfxASurface> GetCurrentAsSurface(gfxIntSize* aSize);
virtual gfxIntSize GetCurrentSize();
virtual PRBool SetLayerManager(LayerManager *aManager);
protected:
Monitor mMonitor;
@ -302,6 +303,20 @@ BasicImageContainer::GetCurrentSize()
return !mImage ? gfxIntSize(0,0) : ToImageData(mImage)->GetSize();
}
PRBool
BasicImageContainer::SetLayerManager(LayerManager *aManager)
{
if (aManager &&
aManager->GetBackendType() != LayerManager::LAYERS_BASIC)
{
return PR_FALSE;
}
// for basic layers, we can just swap; no magic needed.
mManager = aManager;
return PR_TRUE;
}
already_AddRefed<ImageContainer>
BasicLayerManager::CreateImageContainer()
{

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

@ -701,15 +701,9 @@ BasicCanvasLayer::Updated(const nsIntRect& aRect)
// For simplicity, we read the entire framebuffer for now -- in
// the future we should use mUpdatedRect, though with WebGL we don't
// have an easy way to generate one.
if (mGLContext->IsGLES2()) {
mGLContext->fReadPixels(0, 0, mBounds.width, mBounds.height,
LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE,
isurf->Data());
} else {
mGLContext->fReadPixels(0, 0, mBounds.width, mBounds.height,
LOCAL_GL_BGRA, LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV,
isurf->Data());
}
mGLContext->ReadPixelsIntoImageSurface(0, 0,
mBounds.width, mBounds.height,
isurf);
// Put back the previous framebuffer binding.
if (currentFramebuffer != mCanvasFramebuffer)

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

@ -111,9 +111,15 @@ CanvasLayerD3D9::Updated(const nsIntRect& aRect)
// For simplicity, we read the entire framebuffer for now -- in
// the future we should use aRect, though with WebGL we don't
// have an easy way to generate one.
mGLContext->fReadPixels(0, 0, mBounds.width, mBounds.height,
LOCAL_GL_BGRA, LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV,
destination);
nsRefPtr<gfxImageSurface> tmpSurface =
new gfxImageSurface(destination,
gfxIntSize(mBounds.width, mBounds.height),
mBounds.width * 4,
gfxASurface::ImageFormatARGB32);
mGLContext->ReadPixelsIntoImageSurface(0, 0,
mBounds.width, mBounds.height,
tmpSurface);
tmpSurface = nsnull;
// Put back the previous framebuffer binding.
if (currentFramebuffer != mCanvasFramebuffer)

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -130,6 +130,13 @@ ImageContainerD3D9::GetCurrentSize()
return gfxIntSize(0,0);
}
PRBool
ImageContainerD3D9::SetLayerManager(LayerManager *aManager)
{
// we can't do anything here for now
return PR_FALSE;
}
Layer*
ImageLayerD3D9::GetLayer()
{

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

@ -62,6 +62,8 @@ public:
virtual gfxIntSize GetCurrentSize();
virtual PRBool SetLayerManager(LayerManager *aManager);
private:
typedef mozilla::Mutex Mutex;

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

@ -54,12 +54,17 @@ using namespace mozilla;
using namespace mozilla::layers;
using namespace mozilla::gl;
CanvasLayerOGL::~CanvasLayerOGL()
void
CanvasLayerOGL::Destroy()
{
mOGLManager->MakeCurrent();
if (!mDestroyed) {
if (mTexture) {
GLContext *cx = mOGLManager->glForResources();
cx->MakeCurrent();
cx->fDeleteTextures(1, &mTexture);
}
if (mTexture) {
gl()->fDeleteTextures(1, &mTexture);
mDestroyed = PR_TRUE;
}
}
@ -116,6 +121,10 @@ CanvasLayerOGL::MakeTexture()
void
CanvasLayerOGL::Updated(const nsIntRect& aRect)
{
if (mDestroyed) {
return;
}
NS_ASSERTION(mUpdatedRect.IsEmpty(),
"CanvasLayer::Updated called more than once during a transaction!");
@ -123,13 +132,15 @@ CanvasLayerOGL::Updated(const nsIntRect& aRect)
mUpdatedRect.UnionRect(mUpdatedRect, aRect);
if (mCanvasGLContext) {
if (mCanvasGLContext &&
mCanvasGLContext->GetContextType() == gl()->GetContextType())
{
if (gl()->BindOffscreenNeedsTexture(mCanvasGLContext) &&
mTexture == 0)
{
MakeTexture();
}
} else if (mCanvasSurface) {
} else {
PRBool newTexture = mTexture == 0;
if (newTexture) {
MakeTexture();
@ -140,40 +151,50 @@ CanvasLayerOGL::Updated(const nsIntRect& aRect)
}
nsRefPtr<gfxImageSurface> updatedAreaImageSurface;
nsRefPtr<gfxASurface> sourceSurface = mCanvasSurface;
if (mCanvasSurface) {
nsRefPtr<gfxASurface> sourceSurface = mCanvasSurface;
#ifdef XP_WIN
if (sourceSurface->GetType() == gfxASurface::SurfaceTypeWin32) {
sourceSurface = static_cast<gfxWindowsSurface*>(sourceSurface.get())->GetImageSurface();
if (!sourceSurface)
sourceSurface = mCanvasSurface;
}
if (sourceSurface->GetType() == gfxASurface::SurfaceTypeWin32) {
sourceSurface = static_cast<gfxWindowsSurface*>(sourceSurface.get())->GetImageSurface();
if (!sourceSurface)
sourceSurface = mCanvasSurface;
}
#endif
#if 0
// XXX don't copy, blah.
// but need to deal with stride on the gl side; do this later.
if (mCanvasSurface->GetType() == gfxASurface::SurfaceTypeImage) {
gfxImageSurface *s = static_cast<gfxImageSurface*>(mCanvasSurface.get());
if (s->Format() == gfxASurface::ImageFormatARGB32 ||
s->Format() == gfxASurface::ImageFormatRGB24)
{
updatedAreaImageSurface = ...;
} else {
NS_WARNING("surface with format that we can't handle");
return;
}
} else
// XXX don't copy, blah.
// but need to deal with stride on the gl side; do this later.
if (mCanvasSurface->GetType() == gfxASurface::SurfaceTypeImage) {
gfxImageSurface *s = static_cast<gfxImageSurface*>(mCanvasSurface.get());
if (s->Format() == gfxASurface::ImageFormatARGB32 ||
s->Format() == gfxASurface::ImageFormatRGB24)
{
updatedAreaImageSurface = ...;
} else {
NS_WARNING("surface with format that we can't handle");
return;
}
} else
#endif
{
{
updatedAreaImageSurface =
new gfxImageSurface(gfxIntSize(mUpdatedRect.width, mUpdatedRect.height),
gfxASurface::ImageFormatARGB32);
nsRefPtr<gfxContext> ctx = new gfxContext(updatedAreaImageSurface);
ctx->Translate(gfxPoint(-mUpdatedRect.x, -mUpdatedRect.y));
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
ctx->SetSource(sourceSurface);
ctx->Paint();
}
} else if (mCanvasGLContext) {
updatedAreaImageSurface =
new gfxImageSurface(gfxIntSize(mUpdatedRect.width, mUpdatedRect.height),
gfxASurface::ImageFormatARGB32);
nsRefPtr<gfxContext> ctx = new gfxContext(updatedAreaImageSurface);
ctx->Translate(gfxPoint(-mUpdatedRect.x, -mUpdatedRect.y));
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
ctx->SetSource(sourceSurface);
ctx->Paint();
mCanvasGLContext->ReadPixelsIntoImageSurface(mUpdatedRect.x, mUpdatedRect.y,
mUpdatedRect.width,
mUpdatedRect.height,
updatedAreaImageSurface);
}
if (newTexture) {
@ -222,12 +243,12 @@ CanvasLayerOGL::RenderLayer(int aPreviousDestination,
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
}
if (mCanvasGLContext) {
bool useGLContext = mCanvasGLContext &&
mCanvasGLContext->GetContextType() == gl()->GetContextType();
if (useGLContext) {
gl()->BindTex2DOffscreen(mCanvasGLContext);
DEBUG_GL_ERROR_CHECK(gl());
}
if (mCanvasGLContext) {
program = mOGLManager->GetRGBALayerProgram();
} else {
program = mOGLManager->GetBGRALayerProgram();
@ -244,7 +265,7 @@ CanvasLayerOGL::RenderLayer(int aPreviousDestination,
DEBUG_GL_ERROR_CHECK(gl());
if (mCanvasGLContext) {
if (useGLContext) {
gl()->UnbindTex2DOffscreen(mCanvasGLContext);
}

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

@ -56,14 +56,14 @@ public:
{
mImplData = static_cast<LayerOGL*>(this);
}
~CanvasLayerOGL();
~CanvasLayerOGL() { Destroy(); }
// CanvasLayer implementation
virtual void Initialize(const Data& aData);
virtual void Updated(const nsIntRect& aRect);
// LayerOGL implementation
virtual void Destroy();
virtual Layer* GetLayer() { return this; }
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset);

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

@ -53,10 +53,13 @@ public:
{
mImplData = static_cast<LayerOGL*>(this);
}
~ColorLayerOGL() { Destroy(); }
// LayerOGL Implementation
virtual Layer* GetLayer();
virtual void Destroy() { mDestroyed = PR_TRUE; }
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset);
};

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

@ -49,8 +49,18 @@ ContainerLayerOGL::ContainerLayerOGL(LayerManagerOGL *aManager)
ContainerLayerOGL::~ContainerLayerOGL()
{
while (mFirstChild) {
RemoveChild(mFirstChild);
Destroy();
}
void
ContainerLayerOGL::Destroy()
{
if (!mDestroyed) {
while (mFirstChild) {
GetFirstChildOGL()->Destroy();
RemoveChild(mFirstChild);
}
mDestroyed = PR_TRUE;
}
}

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -60,6 +60,8 @@ public:
/** LayerOGL implementation */
Layer* GetLayer();
void Destroy();
LayerOGL* GetFirstChildOGL();
PRBool IsEmpty();

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

@ -57,11 +57,13 @@ public:
GLuint aTexture)
: mContext(aContext), mTexture(aTexture)
{
NS_ASSERTION(aTexture, "TextureDeleter instantiated with nothing to do");
}
NS_IMETHOD Run() {
if (mTexture) {
mContext->DestroyTexture(mTexture);
}
mContext->MakeCurrent();
mContext->fDeleteTextures(1, &mTexture);
// Ensure context is released on the main thread
mContext = nsnull;
return NS_OK;
@ -74,12 +76,15 @@ public:
void
GLTexture::Allocate(GLContext *aContext)
{
NS_ASSERTION(NS_IsMainThread(), "Can only allocate texture on main thread");
NS_ASSERTION(aContext->IsGlobalSharedContext() ||
NS_IsMainThread(), "Can only allocate texture on main thread or with cx sharing");
Release();
mContext = aContext;
mTexture = mContext->CreateTexture();
mContext->MakeCurrent();
mContext->fGenTextures(1, &mTexture);
}
void
@ -100,19 +105,20 @@ GLTexture::Release()
return;
}
if (NS_IsMainThread()) {
if (mTexture) {
mContext->DestroyTexture(mTexture);
mTexture = 0;
if (mTexture) {
if (NS_IsMainThread() || mContext->IsGlobalSharedContext()) {
mContext->MakeCurrent();
mContext->fDeleteTextures(1, &mTexture);
} else {
nsCOMPtr<nsIRunnable> runnable =
new TextureDeleter(mContext.forget(), mTexture);
NS_DispatchToMainThread(runnable);
}
mContext = nsnull;
return;
mTexture = 0;
}
nsCOMPtr<nsIRunnable> runnable =
new TextureDeleter(mContext.forget(), mTexture);
NS_DispatchToMainThread(runnable);
mTexture = 0;
mContext = nsnull;
}
RecycleBin::RecycleBin()
@ -133,7 +139,7 @@ RecycleBin::RecycleBuffer(PRUint8* aBuffer, PRUint32 aSize)
}
PRUint8*
RecycleBin::TakeBuffer(PRUint32 aSize)
RecycleBin::GetBuffer(PRUint32 aSize)
{
MutexAutoLock lock(mLock);
@ -163,8 +169,8 @@ RecycleBin::RecycleTexture(GLTexture *aTexture, TextureType aType,
}
void
RecycleBin::TakeTexture(TextureType aType, const gfxIntSize& aSize,
GLContext *aContext, GLTexture *aOutTexture)
RecycleBin::GetTexture(TextureType aType, const gfxIntSize& aSize,
GLContext *aContext, GLTexture *aOutTexture)
{
MutexAutoLock lock(mLock);
@ -184,6 +190,15 @@ ImageContainerOGL::ImageContainerOGL(LayerManagerOGL *aManager)
{
}
ImageContainerOGL::~ImageContainerOGL()
{
if (mManager) {
NS_ASSERTION(mManager->GetBackendType() == LayerManager::LAYERS_OPENGL, "Wrong layer manager got assigned to ImageContainerOGL!");
static_cast<LayerManagerOGL*>(mManager)->ForgetImageContainer(this);
}
}
already_AddRefed<Image>
ImageContainerOGL::CreateImage(const Image::Format *aFormats,
PRUint32 aNumFormats)
@ -193,7 +208,8 @@ ImageContainerOGL::CreateImage(const Image::Format *aFormats,
}
nsRefPtr<Image> img;
if (aFormats[0] == Image::PLANAR_YCBCR) {
img = new PlanarYCbCrImageOGL(mRecycleBin);
img = new PlanarYCbCrImageOGL(static_cast<LayerManagerOGL*>(mManager),
mRecycleBin);
} else if (aFormats[0] == Image::CAIRO_SURFACE) {
img = new CairoImageOGL(static_cast<LayerManagerOGL*>(mManager));
}
@ -228,7 +244,47 @@ ImageContainerOGL::GetCurrentImage()
already_AddRefed<gfxASurface>
ImageContainerOGL::GetCurrentAsSurface(gfxIntSize *aSize)
{
return nsnull;
MutexAutoLock lock(mActiveImageLock);
if (!mActiveImage) {
*aSize = gfxIntSize(0,0);
return nsnull;
}
GLContext *gl = nsnull;
// tex1 will be RGBA or Y, tex2 will Cb, tex3 will be Cr
GLuint tex1 = 0, tex2 = 0, tex3 = 0;
gfxIntSize size;
if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
PlanarYCbCrImageOGL *yuvImage =
static_cast<PlanarYCbCrImageOGL*>(mActiveImage.get());
if (!yuvImage->HasData() || !yuvImage->HasTextures()) {
*aSize = gfxIntSize(0, 0);
return nsnull;
}
size = yuvImage->mSize;
gl = yuvImage->mTextures[0].GetGLContext();
tex1 = yuvImage->mTextures[0].GetTextureID();
tex2 = yuvImage->mTextures[1].GetTextureID();
tex3 = yuvImage->mTextures[2].GetTextureID();
}
if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) {
CairoImageOGL *cairoImage =
static_cast<CairoImageOGL*>(mActiveImage.get());
size = cairoImage->mSize;
gl = cairoImage->mTexture.GetGLContext();
tex1 = cairoImage->mTexture.GetTextureID();
}
// XXX TODO: read all textures in YCbCr case and convert to RGB
// XXX Or maybe add a ReadYCbCrTextureImage that will take 3 textures
// and return RGB, since we can render YCbCr to the temporary framebuffer.
nsRefPtr<gfxImageSurface> s = gl->ReadTextureImage(tex1, size, LOCAL_GL_RGBA);
*aSize = size;
return s.forget();
}
gfxIntSize
@ -238,6 +294,7 @@ ImageContainerOGL::GetCurrentSize()
if (!mActiveImage) {
return gfxIntSize(0,0);
}
if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
PlanarYCbCrImageOGL *yuvImage =
static_cast<PlanarYCbCrImageOGL*>(mActiveImage.get());
@ -246,7 +303,9 @@ ImageContainerOGL::GetCurrentSize()
}
return yuvImage->mSize;
} else if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) {
}
if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) {
CairoImageOGL *cairoImage =
static_cast<CairoImageOGL*>(mActiveImage.get());
return cairoImage->mSize;
@ -255,6 +314,38 @@ ImageContainerOGL::GetCurrentSize()
return gfxIntSize(0,0);
}
PRBool
ImageContainerOGL::SetLayerManager(LayerManager *aManager)
{
if (!aManager) {
// the layer manager just entirely went away
// XXX if we don't have context sharing, we should tell our images
// that their textures are no longer valid.
mManager = nsnull;
return PR_TRUE;
}
if (aManager->GetBackendType() != LayerManager::LAYERS_OPENGL) {
return PR_FALSE;
}
LayerManagerOGL* lmOld = static_cast<LayerManagerOGL*>(mManager);
LayerManagerOGL* lmNew = static_cast<LayerManagerOGL*>(aManager);
if (lmOld) {
NS_ASSERTION(lmNew->glForResources() == lmOld->glForResources(),
"We require GL context sharing here!");
lmOld->ForgetImageContainer(this);
}
mManager = aManager;
lmNew->RememberImageContainer(this);
return PR_TRUE;
}
Layer*
ImageLayerOGL::GetLayer()
{
@ -276,11 +367,15 @@ ImageLayerOGL::RenderLayer(int,
PlanarYCbCrImageOGL *yuvImage =
static_cast<PlanarYCbCrImageOGL*>(image.get());
if (!yuvImage->HasData())
if (!yuvImage->HasData()) {
return;
}
if (!yuvImage->HasTextures()) {
yuvImage->AllocateTextures(gl());
}
if (!yuvImage->HasTextures())
yuvImage->AllocateTextures(mOGLManager);
yuvImage->UpdateTextures(gl());
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, yuvImage->mTextures[0].GetTextureID());
@ -335,9 +430,39 @@ ImageLayerOGL::RenderLayer(int,
DEBUG_GL_ERROR_CHECK(gl());
}
PlanarYCbCrImageOGL::PlanarYCbCrImageOGL(RecycleBin *aRecycleBin)
static void
InitTexture(GLContext* aGL, GLuint aTexture, GLenum aFormat, const gfxIntSize& aSize)
{
aGL->fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
aGL->fTexImage2D(LOCAL_GL_TEXTURE_2D,
0,
aFormat,
aSize.width,
aSize.height,
0,
aFormat,
LOCAL_GL_UNSIGNED_BYTE,
NULL);
}
PlanarYCbCrImageOGL::PlanarYCbCrImageOGL(LayerManagerOGL *aManager,
RecycleBin *aRecycleBin)
: PlanarYCbCrImage(nsnull), mRecycleBin(aRecycleBin), mHasData(PR_FALSE)
{
#if 0
// We really want to allocate this on the decode thread -- but to do that,
// we need to create a per-thread shared GL context, and it will only work
// if we have context sharing. For now, create the textures on the main
// thread the first time we render.
if (aManager) {
AllocateTextures(aManager->glForResources());
}
#endif
}
PlanarYCbCrImageOGL::~PlanarYCbCrImageOGL()
@ -346,9 +471,11 @@ PlanarYCbCrImageOGL::~PlanarYCbCrImageOGL()
mRecycleBin->RecycleBuffer(mBuffer.forget(), mBufferSize);
}
mRecycleBin->RecycleTexture(&mTextures[0], RecycleBin::TEXTURE_Y, mData.mYSize);
mRecycleBin->RecycleTexture(&mTextures[1], RecycleBin::TEXTURE_C, mData.mCbCrSize);
mRecycleBin->RecycleTexture(&mTextures[2], RecycleBin::TEXTURE_C, mData.mCbCrSize);
if (HasTextures()) {
mRecycleBin->RecycleTexture(&mTextures[0], RecycleBin::TEXTURE_Y, mData.mYSize);
mRecycleBin->RecycleTexture(&mTextures[1], RecycleBin::TEXTURE_C, mData.mCbCrSize);
mRecycleBin->RecycleTexture(&mTextures[2], RecycleBin::TEXTURE_C, mData.mCbCrSize);
}
}
void
@ -384,7 +511,7 @@ PlanarYCbCrImageOGL::SetData(const PlanarYCbCrImage::Data &aData)
mBufferSize = mData.mCbCrStride * mData.mCbCrSize.height * 2 +
mData.mYStride * mData.mYSize.height;
mBuffer = mRecycleBin->TakeBuffer(mBufferSize);
mBuffer = mRecycleBin->GetBuffer(mBufferSize);
if (!mBuffer)
return;
@ -417,54 +544,24 @@ PlanarYCbCrImageOGL::SetData(const PlanarYCbCrImage::Data &aData)
mHasData = PR_TRUE;
}
static void
SetupPlaneTexture(GLContext* aGL, const gfxIntSize& aSize, PRUint8* aData, PRBool aIsNew)
void
PlanarYCbCrImageOGL::AllocateTextures(mozilla::gl::GLContext *gl)
{
aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
gl->MakeCurrent();
if (aIsNew) {
aGL->fTexImage2D(LOCAL_GL_TEXTURE_2D,
0,
LOCAL_GL_LUMINANCE,
aSize.width,
aSize.height,
0,
LOCAL_GL_LUMINANCE,
LOCAL_GL_UNSIGNED_BYTE,
aData);
} else {
aGL->fTexSubImage2D(LOCAL_GL_TEXTURE_2D,
0,
0, 0,
aSize.width,
aSize.height,
LOCAL_GL_LUMINANCE,
LOCAL_GL_UNSIGNED_BYTE,
aData);
}
mRecycleBin->GetTexture(RecycleBin::TEXTURE_Y, mData.mYSize, gl, &mTextures[0]);
InitTexture(gl, mTextures[0].GetTextureID(), LOCAL_GL_LUMINANCE, mData.mYSize);
mRecycleBin->GetTexture(RecycleBin::TEXTURE_C, mData.mCbCrSize, gl, &mTextures[1]);
InitTexture(gl, mTextures[1].GetTextureID(), LOCAL_GL_LUMINANCE, mData.mCbCrSize);
mRecycleBin->GetTexture(RecycleBin::TEXTURE_C, mData.mCbCrSize, gl, &mTextures[2]);
InitTexture(gl, mTextures[2].GetTextureID(), LOCAL_GL_LUMINANCE, mData.mCbCrSize);
}
void
PlanarYCbCrImageOGL::AllocateTextures(LayerManagerOGL *aManager)
PlanarYCbCrImageOGL::UpdateTextures(GLContext *gl)
{
aManager->MakeCurrent();
mozilla::gl::GLContext *gl = aManager->gl();
PRPackedBool isNewTexture[3];
for (PRUint32 i = 0; i < 3; ++i) {
isNewTexture[i] = !mTextures[i].IsAllocated();
}
mRecycleBin->TakeTexture(RecycleBin::TEXTURE_Y, mData.mYSize, gl, &mTextures[0]);
mRecycleBin->TakeTexture(RecycleBin::TEXTURE_C, mData.mCbCrSize, gl, &mTextures[1]);
mRecycleBin->TakeTexture(RecycleBin::TEXTURE_C, mData.mCbCrSize, gl, &mTextures[2]);
if (!HasTextures())
return;
GLint alignment;
if (!((ptrdiff_t)mData.mYStride & 0x7) && !((ptrdiff_t)mData.mYChannel & 0x7)) {
@ -481,12 +578,16 @@ PlanarYCbCrImageOGL::AllocateTextures(LayerManagerOGL *aManager)
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, alignment);
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mTextures[0].GetTextureID());
SetupPlaneTexture(gl, mData.mYSize, mData.mYChannel, isNewTexture[0]);
gl->fTexSubImage2D(LOCAL_GL_TEXTURE_2D, 0,
0, 0, mData.mYSize.width, mData.mYSize.height,
LOCAL_GL_LUMINANCE,
LOCAL_GL_UNSIGNED_BYTE,
mData.mYChannel);
if (!((ptrdiff_t)mData.mCbCrStride & 0x7) &&
!((ptrdiff_t)mData.mCbChannel & 0x7) &&
!((ptrdiff_t)mData.mCrChannel & 0x7)) {
!((ptrdiff_t)mData.mCrChannel & 0x7))
{
alignment = 8;
} else if (!((ptrdiff_t)mData.mCbCrStride & 0x3)) {
alignment = 4;
@ -500,12 +601,18 @@ PlanarYCbCrImageOGL::AllocateTextures(LayerManagerOGL *aManager)
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, alignment);
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mTextures[1].GetTextureID());
SetupPlaneTexture(gl, mData.mCbCrSize, mData.mCbChannel, isNewTexture[1]);
gl->fTexSubImage2D(LOCAL_GL_TEXTURE_2D, 0,
0, 0, mData.mCbCrSize.width, mData.mCbCrSize.height,
LOCAL_GL_LUMINANCE,
LOCAL_GL_UNSIGNED_BYTE,
mData.mCbChannel);
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mTextures[2].GetTextureID());
SetupPlaneTexture(gl, mData.mCbCrSize, mData.mCrChannel, isNewTexture[2]);
gl->fTexSubImage2D(LOCAL_GL_TEXTURE_2D, 0,
0, 0, mData.mCbCrSize.width, mData.mCbCrSize.height,
LOCAL_GL_LUMINANCE,
LOCAL_GL_UNSIGNED_BYTE,
mData.mCrChannel);
// Reset alignment to default
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
@ -516,12 +623,15 @@ PlanarYCbCrImageOGL::AllocateTextures(LayerManagerOGL *aManager)
}
}
CairoImageOGL::CairoImageOGL(LayerManagerOGL *aManager) : CairoImage(nsnull)
CairoImageOGL::CairoImageOGL(LayerManagerOGL *aManager)
: CairoImage(nsnull)
{
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread to create a cairo image");
// Allocate texture now to grab a reference to the GLContext
mTexture.Allocate(aManager->gl());
if (aManager) {
// Allocate texture now to grab a reference to the GLContext
mTexture.Allocate(aManager->glForResources());
}
}
void
@ -533,20 +643,20 @@ CairoImageOGL::SetData(const CairoImage::Data &aData)
mozilla::gl::GLContext *gl = mTexture.GetGLContext();
gl->MakeCurrent();
mSize = aData.mSize;
gl->fActiveTexture(LOCAL_GL_TEXTURE0);
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture.GetTextureID());
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
if (mSize != aData.mSize) {
gl->fActiveTexture(LOCAL_GL_TEXTURE0);
InitTexture(gl, mTexture.GetTextureID(), LOCAL_GL_RGBA, aData.mSize);
mSize = aData.mSize;
} else {
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture.GetTextureID());
}
if (!mASurfaceAsGLContext) {
mASurfaceAsGLContext = GLContextProvider::CreateForNativePixmapSurface(aData.mSurface);
if (mASurfaceAsGLContext)
mASurfaceAsGLContext->BindTexImage();
}
if (mASurfaceAsGLContext)
return;
@ -561,15 +671,11 @@ CairoImageOGL::SetData(const CairoImage::Data &aData)
context->SetSource(aData.mSurface);
context->Paint();
gl->fTexImage2D(LOCAL_GL_TEXTURE_2D,
0,
LOCAL_GL_RGBA,
mSize.width,
mSize.height,
0,
LOCAL_GL_RGBA,
LOCAL_GL_UNSIGNED_BYTE,
imageSurface->Data());
gl->fTexSubImage2D(LOCAL_GL_TEXTURE_2D, 0,
0, 0, mSize.width, mSize.height,
LOCAL_GL_RGBA,
LOCAL_GL_UNSIGNED_BYTE,
imageSurface->Data());
}
} /* layers */

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -102,7 +102,7 @@ public:
void RecycleBuffer(PRUint8* aBuffer, PRUint32 aSize);
// Returns a recycled buffer of the right size, or allocates a new buffer.
PRUint8* TakeBuffer(PRUint32 aSize);
PRUint8* GetBuffer(PRUint32 aSize);
enum TextureType {
TEXTURE_Y,
@ -111,8 +111,8 @@ public:
void RecycleTexture(GLTexture *aTexture, TextureType aType,
const gfxIntSize& aSize);
void TakeTexture(TextureType aType, const gfxIntSize& aSize,
GLContext *aContext, GLTexture *aOutTexture);
void GetTexture(TextureType aType, const gfxIntSize& aSize,
GLContext *aContext, GLTexture *aOutTexture);
private:
typedef mozilla::Mutex Mutex;
@ -135,7 +135,7 @@ class THEBES_API ImageContainerOGL : public ImageContainer
{
public:
ImageContainerOGL(LayerManagerOGL *aManager);
virtual ~ImageContainerOGL() {}
virtual ~ImageContainerOGL();
virtual already_AddRefed<Image> CreateImage(const Image::Format* aFormats,
PRUint32 aNumFormats);
@ -148,6 +148,8 @@ public:
virtual gfxIntSize GetCurrentSize();
virtual PRBool SetLayerManager(LayerManager *aManager);
private:
typedef mozilla::Mutex Mutex;
@ -169,8 +171,10 @@ public:
{
mImplData = static_cast<LayerOGL*>(this);
}
~ImageLayerOGL() { Destroy(); }
// LayerOGL Implementation
virtual void Destroy() { mDestroyed = PR_TRUE; }
virtual Layer* GetLayer();
virtual void RenderLayer(int aPreviousFrameBuffer,
@ -182,7 +186,8 @@ class THEBES_API PlanarYCbCrImageOGL : public PlanarYCbCrImage
typedef mozilla::gl::GLContext GLContext;
public:
PlanarYCbCrImageOGL(RecycleBin *aRecycleBin);
PlanarYCbCrImageOGL(LayerManagerOGL *aManager,
RecycleBin *aRecycleBin);
~PlanarYCbCrImageOGL();
virtual void SetData(const Data &aData);
@ -191,7 +196,9 @@ public:
* Upload the data from out mData into our textures. For now we use this to
* make sure the textures are created and filled on the main thread.
*/
void AllocateTextures(LayerManagerOGL *aManager);
void AllocateTextures(GLContext *gl);
void UpdateTextures(GLContext *gl);
PRBool HasData() { return mHasData; }
PRBool HasTextures()
{

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

@ -76,8 +76,30 @@ LayerManagerOGL::LayerManagerOGL(nsIWidget *aWidget)
LayerManagerOGL::~LayerManagerOGL()
{
mRoot = nsnull;
CleanupResources();
Destroy();
}
void
LayerManagerOGL::Destroy()
{
if (!mDestroyed) {
if (mRoot) {
RootLayer()->Destroy();
}
mRoot = nsnull;
// Make a copy, since SetLayerManager will cause mImageContainers
// to get mutated.
nsTArray<ImageContainer*> imageContainers(mImageContainers);
for (PRUint32 i = 0; i < imageContainers.Length(); ++i) {
ImageContainer *c = imageContainers[i];
c->SetLayerManager(nsnull);
}
CleanupResources();
mDestroyed = PR_TRUE;
}
}
void
@ -90,7 +112,7 @@ LayerManagerOGL::CleanupResources()
if (!ctx) {
ctx = mGLContext;
}
ctx->MakeCurrent();
for (unsigned int i = 0; i < mPrograms.Length(); ++i)
@ -125,6 +147,7 @@ LayerManagerOGL::Initialize(GLContext *aExistingContext)
} else {
if (mGLContext)
CleanupResources();
mGLContext = gl::GLContextProvider::CreateForWindow(mWidget);
if (!mGLContext) {
@ -137,10 +160,9 @@ LayerManagerOGL::Initialize(GLContext *aExistingContext)
DEBUG_GL_ERROR_CHECK(mGLContext);
const char *extensionStr =
(const char*) mGLContext->fGetString(LOCAL_GL_EXTENSIONS);
mHasBGRA = (strstr(extensionStr, "EXT_bgra") != nsnull);
mHasBGRA =
mGLContext->IsExtensionSupported(gl::GLContext::EXT_texture_format_BGRA8888) ||
mGLContext->IsExtensionSupported(gl::GLContext::EXT_bgra);
mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
LOCAL_GL_ONE, LOCAL_GL_ONE);
@ -259,7 +281,7 @@ LayerManagerOGL::Initialize(GLContext *aExistingContext)
* texture rectangle access inside GLSL (sampler2DRect,
* texture2DRect).
*/
if (strstr(extensionStr, "ARB_texture_rectangle") == NULL)
if (!mGLContext->IsExtensionSupported(gl::GLContext::ARB_texture_rectangle))
return false;
}
@ -327,6 +349,11 @@ LayerManagerOGL::BeginTransaction()
void
LayerManagerOGL::BeginTransactionWithTarget(gfxContext *aTarget)
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return;
}
mTarget = aTarget;
}
@ -334,6 +361,11 @@ void
LayerManagerOGL::EndTransaction(DrawThebesLayerCallback aCallback,
void* aCallbackData)
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return;
}
mThebesLayerCallback = aCallback;
mThebesLayerCallbackData = aCallbackData;
@ -348,6 +380,11 @@ LayerManagerOGL::EndTransaction(DrawThebesLayerCallback aCallback,
already_AddRefed<ThebesLayer>
LayerManagerOGL::CreateThebesLayer()
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nsnull;
}
nsRefPtr<ThebesLayer> layer = new ThebesLayerOGL(this);
return layer.forget();
}
@ -355,6 +392,11 @@ LayerManagerOGL::CreateThebesLayer()
already_AddRefed<ContainerLayer>
LayerManagerOGL::CreateContainerLayer()
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nsnull;
}
nsRefPtr<ContainerLayer> layer = new ContainerLayerOGL(this);
return layer.forget();
}
@ -362,13 +404,24 @@ LayerManagerOGL::CreateContainerLayer()
already_AddRefed<ImageContainer>
LayerManagerOGL::CreateImageContainer()
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nsnull;
}
nsRefPtr<ImageContainer> container = new ImageContainerOGL(this);
RememberImageContainer(container);
return container.forget();
}
already_AddRefed<ImageLayer>
LayerManagerOGL::CreateImageLayer()
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nsnull;
}
nsRefPtr<ImageLayer> layer = new ImageLayerOGL(this);
return layer.forget();
}
@ -376,6 +429,11 @@ LayerManagerOGL::CreateImageLayer()
already_AddRefed<ColorLayer>
LayerManagerOGL::CreateColorLayer()
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nsnull;
}
nsRefPtr<ColorLayer> layer = new ColorLayerOGL(this);
return layer.forget();
}
@ -383,25 +441,65 @@ LayerManagerOGL::CreateColorLayer()
already_AddRefed<CanvasLayer>
LayerManagerOGL::CreateCanvasLayer()
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nsnull;
}
nsRefPtr<CanvasLayer> layer = new CanvasLayerOGL(this);
return layer.forget();
}
void
LayerManagerOGL::ForgetImageContainer(ImageContainer *aContainer)
{
NS_ASSERTION(aContainer->Manager() == this,
"ForgetImageContainer called on non-owned container!");
if (!mImageContainers.RemoveElement(aContainer)) {
NS_WARNING("ForgetImageContainer couldn't find container it was supposed to forget!");
return;
}
}
void
LayerManagerOGL::RememberImageContainer(ImageContainer *aContainer)
{
NS_ASSERTION(aContainer->Manager() == this,
"RememberImageContainer called on non-owned container!");
mImageContainers.AppendElement(aContainer);
}
void
LayerManagerOGL::MakeCurrent()
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return;
}
mGLContext->MakeCurrent();
}
LayerOGL*
LayerManagerOGL::RootLayer() const
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return nsnull;
}
return static_cast<LayerOGL*>(mRoot->ImplData());
}
void
LayerManagerOGL::Render()
{
if (mDestroyed) {
NS_WARNING("Call on destroyed layer manager");
return;
}
nsIntRect rect;
mWidget->GetBounds(rect);
GLint width = rect.width;
@ -645,12 +743,22 @@ LayerManagerOGL::CopyToTarget()
NS_ASSERTION(imageSurface->Stride() == width * 4,
"Image Surfaces being created with weird stride!");
PRUint32 currentPackAlignment = 0;
mGLContext->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, (GLint*)&currentPackAlignment);
if (currentPackAlignment != 4) {
mGLContext->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4);
}
mGLContext->fReadPixels(0, 0,
width, height,
format,
LOCAL_GL_UNSIGNED_BYTE,
imageSurface->Data());
if (currentPackAlignment != 4) {
mGLContext->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment);
}
if (!mHasBGRA) {
// need to swap B and R bytes
for (int j = 0; j < height; ++j) {
@ -739,6 +847,5 @@ LayerManagerOGL::CreateFBOWithTexture(int aWidth, int aHeight,
DEBUG_GL_ERROR_CHECK(gl());
}
} /* layers */
} /* mozilla */

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

@ -83,6 +83,8 @@ public:
void CleanupResources();
void Destroy();
/**
* Initializes the layer manager, this is when the layer manager will
* actually access the device and attempt to create the swap chain used
@ -135,6 +137,16 @@ public:
virtual LayersBackend GetBackendType() { return LAYERS_OPENGL; }
/**
* Image Container management.
*/
/* Forget this image container. Should be called by ImageContainerOGL
* on its current layer manager before switching to a new one.
*/
void ForgetImageContainer(ImageContainer* aContainer);
void RememberImageContainer(ImageContainer* aContainer);
/**
* Helper methods.
*/
@ -182,6 +194,16 @@ public:
void* GetThebesLayerCallbackData() const
{ return mThebesLayerCallbackData; }
// This is a GLContext that can be used for resource
// management (creation, destruction). It is guaranteed
// to be either the same as the gl() context, or a context
// that is in the same share pool.
GLContext *glForResources() const {
if (mGLContext->GetSharedContext())
return mGLContext->GetSharedContext();
return mGLContext;
}
/*
* Helper functions for our layers
*/
@ -281,6 +303,11 @@ private:
nsRefPtr<GLContext> mGLContext;
// The image containers that this layer manager has created.
// The destructor will tell the layer manager to remove
// it from the list.
nsTArray<ImageContainer*> mImageContainers;
enum ProgramType {
RGBALayerProgramType,
BGRALayerProgramType,
@ -364,13 +391,20 @@ class LayerOGL
{
public:
LayerOGL(LayerManagerOGL *aManager)
: mOGLManager(aManager)
: mOGLManager(aManager), mDestroyed(PR_FALSE)
{ }
virtual ~LayerOGL() { }
virtual LayerOGL *GetFirstChildOGL() {
return nsnull;
}
/* Do NOT call this from the generic LayerOGL destructor. Only from the
* concrete class destructor
*/
virtual void Destroy() = 0;
virtual Layer* GetLayer() = 0;
virtual void RenderLayer(int aPreviousFrameBuffer,
@ -381,6 +415,7 @@ public:
GLContext *gl() const { return mOGLManager->gl(); }
protected:
LayerManagerOGL *mOGLManager;
PRPackedBool mDestroyed;
};
} /* layers */

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

@ -300,19 +300,17 @@ protected:
}
fprintf (stderr, "=== Log:\n%s\n", nsPromiseFlatCString(log).get());
fprintf (stderr, "============\n");
}
// We can mark the shaders for deletion; they're attached to the program
// and will remain attached.
mGL->fDeleteShader(vertexShader);
mGL->fDeleteShader(fragmentShader);
// We can mark the shaders for deletion; they're attached to the program
// and will remain attached.
mGL->fDeleteShader(vertexShader);
mGL->fDeleteShader(fragmentShader);
if (!success) {
mGL->fDeleteProgram(mProgram);
mProgram = 0;
return false;
}
if (!success) {
mGL->fDeleteProgram(mProgram);
mProgram = 0;
return false;
}
// Now query uniforms, so that we can initialize mUniformValues

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

@ -331,8 +331,18 @@ ThebesLayerOGL::ThebesLayerOGL(LayerManagerOGL *aManager)
ThebesLayerOGL::~ThebesLayerOGL()
{
mBuffer = nsnull;
DEBUG_GL_ERROR_CHECK(gl());
Destroy();
}
void
ThebesLayerOGL::Destroy()
{
if (!mDestroyed) {
mBuffer = nsnull;
DEBUG_GL_ERROR_CHECK(gl());
mDestroyed = PR_TRUE;
}
}
PRBool

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

@ -50,7 +50,7 @@ namespace layers {
class ThebesLayerBufferOGL;
class ThebesLayerOGL : public ThebesLayer,
public LayerOGL
public LayerOGL
{
typedef ThebesLayerBufferOGL Buffer;
@ -65,6 +65,7 @@ public:
void InvalidateRegion(const nsIntRegion& aRegion);
/** LayerOGL implementation */
void Destroy();
Layer* GetLayer();
virtual PRBool IsEmpty();
virtual void RenderLayer(int aPreviousFrameBuffer,

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

@ -309,9 +309,64 @@ GLContext::InitWithPrefix(const char *prefix, PRBool trygl)
};
mInitialized = LoadSymbols(&symbols[0], trygl, prefix);
if (mInitialized) {
InitExtensions();
}
return mInitialized;
}
// should match the order of GLExtensions
static const char *sExtensionNames[] = {
"GL_EXT_framebuffer_object",
"GL_ARB_framebuffer_object",
"GL_ARB_texture_rectangle",
"GL_EXT_bgra",
"GL_EXT_texture_format_BGRA8888",
"GL_OES_depth24",
"GL_OES_depth32",
"GL_OES_stencil8",
"GL_OES_texture_npot",
"GL_OES_depth_texture",
"GL_OES_packed_depth_stencil",
"GL_IMG_read_format",
"GL_EXT_read_format_bgra",
NULL
};
void
GLContext::InitExtensions()
{
MakeCurrent();
const GLubyte *extensions = fGetString(LOCAL_GL_EXTENSIONS);
char *exts = strdup((char *)extensions);
printf_stderr("GL extensions: %s\n", exts);
char *s = exts;
bool done = false;
while (!done) {
char *space = strchr(s, ' ');
if (space) {
*space = '\0';
} else {
done = true;
}
for (int i = 0; sExtensionNames[i]; ++i) {
if (strcmp(s, sExtensionNames[i]) == 0) {
printf_stderr("Found extension %s\n", s);
mAvailableExtensions[i] = 1;
}
}
s = space+1;
}
free(exts);
}
PRBool
GLContext::IsExtensionSupported(const char *extension)
{
@ -479,6 +534,9 @@ GLContext::ResizeOffscreenFBO(const gfxIntSize& aSize)
GLint viewport[4];
bool useDepthStencil =
!mIsGLES2 || IsExtensionSupported(OES_packed_depth_stencil);
// save a few things for later restoring
fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, (GLint*) &curBoundTexture);
fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, (GLint*) &curBoundFramebuffer);
@ -496,7 +554,7 @@ GLContext::ResizeOffscreenFBO(const gfxIntSize& aSize)
fGenFramebuffers(1, &mOffscreenFBO);
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mOffscreenFBO);
if (depth && stencil && !mIsGLES2) {
if (depth && stencil && useDepthStencil) {
fGenRenderbuffers(1, &mOffscreenDepthRB);
} else {
if (depth) {
@ -529,18 +587,35 @@ GLContext::ResizeOffscreenFBO(const gfxIntSize& aSize)
aSize.width, aSize.height,
0,
LOCAL_GL_RGB,
#ifdef XP_WIN
LOCAL_GL_UNSIGNED_BYTE,
#else
mIsGLES2 ? LOCAL_GL_UNSIGNED_SHORT_5_6_5
: LOCAL_GL_UNSIGNED_BYTE,
#endif
NULL);
}
if (depth && stencil && !mIsGLES2) {
if (depth && stencil && useDepthStencil) {
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mOffscreenDepthRB);
fRenderbufferStorage(LOCAL_GL_RENDERBUFFER,
LOCAL_GL_DEPTH24_STENCIL8,
aSize.width, aSize.height);
} else {
if (depth) {
GLenum depthType;
if (mIsGLES2) {
if (IsExtensionSupported(OES_depth32)) {
depthType = LOCAL_GL_DEPTH_COMPONENT32;
} else if (IsExtensionSupported(OES_depth24)) {
depthType = LOCAL_GL_DEPTH_COMPONENT24;
} else {
depthType = LOCAL_GL_DEPTH_COMPONENT16;
}
} else {
depthType = LOCAL_GL_DEPTH_COMPONENT24;
}
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mOffscreenDepthRB);
fRenderbufferStorage(LOCAL_GL_RENDERBUFFER,
mIsGLES2 ? LOCAL_GL_DEPTH_COMPONENT16
@ -565,7 +640,7 @@ GLContext::ResizeOffscreenFBO(const gfxIntSize& aSize)
mOffscreenTexture,
0);
if (depth && stencil && !mIsGLES2) {
if (depth && stencil && useDepthStencil) {
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_DEPTH_ATTACHMENT,
LOCAL_GL_RENDERBUFFER,
@ -603,6 +678,10 @@ GLContext::ResizeOffscreenFBO(const gfxIntSize& aSize)
if (firstTime) {
UpdateActualFormat();
printf_stderr("Created offscreen FBO: r: %d g: %d b: %d a: %d depth: %d stencil: %d\n",
mActualFormat.red, mActualFormat.green, mActualFormat.blue, mActualFormat.alpha,
mActualFormat.depth, mActualFormat.stencil);
}
// We're good, and the framebuffer is already attached, so let's
@ -665,7 +744,216 @@ GLContext::ClearSafely()
void
GLContext::UpdateActualFormat()
{
// TODO
ContextFormat nf;
fGetIntegerv(LOCAL_GL_RED_BITS, (GLint*) &nf.alpha);
fGetIntegerv(LOCAL_GL_GREEN_BITS, (GLint*) &nf.alpha);
fGetIntegerv(LOCAL_GL_BLUE_BITS, (GLint*) &nf.alpha);
fGetIntegerv(LOCAL_GL_ALPHA_BITS, (GLint*) &nf.alpha);
fGetIntegerv(LOCAL_GL_DEPTH_BITS, (GLint*) &nf.depth);
fGetIntegerv(LOCAL_GL_STENCIL_BITS, (GLint*) &nf.depth);
mActualFormat = nf;
}
void
GLContext::MarkDestroyed()
{
MakeCurrent();
DeleteOffscreenFBO();
memset(&mFunctionListStartSentinel, 0, &mFunctionListEndSentinel - &mFunctionListStartSentinel);
}
already_AddRefed<gfxImageSurface>
GLContext::ReadTextureImage(GLuint aTexture,
const gfxIntSize& aSize,
GLenum aTextureFormat)
{
MakeCurrent();
nsRefPtr<gfxImageSurface> isurf;
GLint oldrb, oldfb, oldprog, oldvp[4], oldPackAlignment;
GLint success;
GLuint rb = 0, fb = 0;
GLuint vs = 0, fs = 0, prog = 0;
const char *vShader =
"attribute vec4 aVertex;\n"
"attribute vec2 aTexCoord;\n"
"varying vec2 vTexCoord;\n"
"void main() { gl_Position = aVertex; vTexCoord = aTexCoord; }";
const char *fShader =
"#ifdef GL_ES\n"
"precision mediump float;\n"
"#endif\n"
"varying vec2 vTexCoord;\n"
"uniform sampler2D uTexture;\n"
"void main() { gl_FragColor = texture2D(uTexture, vTexCoord); }";
float verts[4*4] = {
-1.0f, -1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f
};
float texcoords[2*4] = {
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f
};
fGetIntegerv(LOCAL_GL_RENDERBUFFER_BINDING, &oldrb);
fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &oldfb);
fGetIntegerv(LOCAL_GL_CURRENT_PROGRAM, &oldprog);
fGetIntegerv(LOCAL_GL_VIEWPORT, oldvp);
fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, &oldPackAlignment);
fGenRenderbuffers(1, &rb);
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, rb);
fRenderbufferStorage(LOCAL_GL_RENDERBUFFER, LOCAL_GL_RGBA,
aSize.width, aSize.height);
fGenFramebuffers(1, &fb);
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
LOCAL_GL_RENDERBUFFER, rb);
if (fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER) !=
LOCAL_GL_FRAMEBUFFER_COMPLETE)
{
goto cleanup;
}
vs = fCreateShader(LOCAL_GL_VERTEX_SHADER);
fs = fCreateShader(LOCAL_GL_FRAGMENT_SHADER);
fShaderSource(vs, 1, (const GLchar**) &vShader, NULL);
fShaderSource(fs, 1, (const GLchar**) &fShader, NULL);
prog = fCreateProgram();
fAttachShader(prog, vs);
fAttachShader(prog, fs);
fBindAttribLocation(prog, 0, "aVertex");
fBindAttribLocation(prog, 1, "aTexCoord");
fLinkProgram(prog);
fGetProgramiv(prog, LOCAL_GL_LINK_STATUS, &success);
if (!success) {
goto cleanup;
}
fUseProgram(prog);
fEnableVertexAttribArray(0);
fEnableVertexAttribArray(1);
fVertexAttribPointer(0, 4, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, verts);
fVertexAttribPointer(1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, texcoords);
fActiveTexture(LOCAL_GL_TEXTURE0);
fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
fUniform1i(fGetUniformLocation(prog, "uTexture"), 0);
fViewport(0, 0, aSize.width, aSize.height);
fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
fDisableVertexAttribArray(1);
fDisableVertexAttribArray(0);
isurf = new gfxImageSurface(aSize, gfxASurface::ImageFormatARGB32);
if (!isurf || isurf->CairoStatus()) {
isurf = nsnull;
goto cleanup;
}
if (oldPackAlignment != 4)
fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4);
fReadPixels(0, 0, aSize.width, aSize.height,
LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE,
isurf->Data());
if (oldPackAlignment != 4)
fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, oldPackAlignment);
cleanup:
// note that deleting 0 has no effect in any of these calls
fDeleteRenderbuffers(1, &rb);
fDeleteFramebuffers(1, &fb);
fDeleteShader(vs);
fDeleteShader(fs);
fDeleteProgram(prog);
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, oldrb);
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, oldfb);
fUseProgram(oldprog);
fViewport(oldvp[0], oldvp[1], oldvp[2], oldvp[3]);
return isurf.forget();
}
void
GLContext::ReadPixelsIntoImageSurface(GLint aX, GLint aY,
GLsizei aWidth, GLsizei aHeight,
gfxImageSurface *aDest)
{
MakeCurrent();
if (aDest->Format() != gfxASurface::ImageFormatARGB32 &&
aDest->Format() != gfxASurface::ImageFormatRGB24)
{
NS_WARNING("ReadPixelsIntoImageSurface called with invalid image format");
return;
}
if (aDest->Width() != aWidth ||
aDest->Height() != aHeight ||
aDest->Stride() != aWidth * 4)
{
NS_WARNING("ReadPixelsIntoImageSurface called with wrong size or stride surface");
return;
}
GLint currentPackAlignment = 0;
fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, &currentPackAlignment);
fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4);
// defaults for desktop
GLenum format = LOCAL_GL_BGRA;
GLenum datatype = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
bool swap = false;
if (IsGLES2()) {
datatype = LOCAL_GL_UNSIGNED_BYTE;
if (IsExtensionSupported(gl::GLContext::EXT_read_format_bgra) ||
IsExtensionSupported(gl::GLContext::IMG_read_format) ||
IsExtensionSupported(gl::GLContext::EXT_bgra))
{
format = LOCAL_GL_BGRA;
} else {
format = LOCAL_GL_RGBA;
swap = true;
}
}
fReadPixels(0, 0, aWidth, aHeight,
format, datatype,
aDest->Data());
if (swap) {
// swap B and R bytes
for (int j = 0; j < aHeight; ++j) {
PRUint32 *row = (PRUint32*) (aDest->Data() + aDest->Stride() * j);
for (int i = 0; i < aWidth; ++i) {
*row = (*row & 0xff00ff00) | ((*row & 0xff) << 16) | ((*row & 0xff0000) >> 16);
row++;
}
}
}
fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment);
}
#ifdef DEBUG

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

@ -385,6 +385,10 @@ public:
mUserData.Put(aKey, aValue);
}
// Mark this context as destroyed. This will NULL out all
// the GL function pointers!
void THEBES_API MarkDestroyed();
enum NativeDataType {
NativeGLContext,
NativeImageSurface,
@ -395,6 +399,9 @@ public:
virtual void *GetNativeData(NativeDataType aType) { return NULL; }
GLContext *GetSharedContext() { return mSharedContext; }
PRBool IsGlobalSharedContext() { return mIsGlobalSharedContext; }
void SetIsGlobalSharedContext(PRBool aIsOne) { mIsGlobalSharedContext = aIsOne; }
const ContextFormat& CreationFormat() { return mCreationFormat; }
const ContextFormat& ActualFormat() { return mActualFormat; }
@ -428,20 +435,6 @@ public:
*/
virtual PRBool ReleaseTexImage() { return PR_FALSE; }
virtual GLuint CreateTexture()
{
GLuint tex;
MakeCurrent();
fGenTextures(1, &tex);
return tex;
}
virtual void DestroyTexture(GLuint tex)
{
MakeCurrent();
fDeleteTextures(1, &tex);
}
/*
* Offscreen support API
*/
@ -554,10 +547,61 @@ public:
GLint aWrapMode,
PRBool aUseNearestFilter=PR_FALSE);
/**
* Read the image data contained in aTexture, and return it as an ImageSurface.
* If GL_RGBA is given as the format, a ImageFormatARGB32 surface is returned.
* Not implemented yet:
* If GL_RGB is given as the format, a ImageFormatRGB24 surface is returned.
* If GL_LUMINANCE is given as the format, a ImageFormatA8 surface is returned.
*
* THIS IS EXPENSIVE. It is ridiculously expensive. Only do this
* if you absolutely positively must, and never in any performance
* critical path.
*/
already_AddRefed<gfxImageSurface> ReadTextureImage(GLuint aTexture,
const gfxIntSize& aSize,
GLenum aTextureFormat);
/**
* Call ReadPixels into an existing gfxImageSurface for the given bounds.
* The image surface must be using image format RGBA32 or RGB24.
*/
void ReadPixelsIntoImageSurface(GLint aX, GLint aY, GLsizei aWidth, GLsizei aHeight,
gfxImageSurface *aDest);
/**
* Known GL extensions that can be queried by
* IsExtensionSupported. The results of this are cached, and as
* such it's safe to use this even in performance critical code.
* If you add to this array, remember to add to the string names
* in GLContext.cpp.
*/
enum GLExtensions {
EXT_framebuffer_object,
ARB_framebuffer_object,
ARB_texture_rectangle,
EXT_bgra,
EXT_texture_format_BGRA8888,
OES_depth24,
OES_depth32,
OES_stencil8,
OES_texture_npot,
OES_depth_texture,
OES_packed_depth_stencil,
IMG_read_format,
EXT_read_format_bgra,
Extensions_Max
};
PRBool IsExtensionSupported(GLExtensions aKnownExtension) {
return mAvailableExtensions[aKnownExtension];
}
protected:
PRPackedBool mInitialized;
PRPackedBool mIsOffscreen;
PRPackedBool mIsGLES2;
PRPackedBool mIsGlobalSharedContext;
ContextFormat mCreationFormat;
nsRefPtr<GLContext> mSharedContext;
@ -576,6 +620,25 @@ protected:
GLuint mOffscreenDepthRB;
GLuint mOffscreenStencilRB;
// this should just be a std::bitset, but that ended up breaking
// MacOS X builds; see bug 584919. We can replace this with one
// later on.
template<size_t setlen>
struct ExtensionBitset {
ExtensionBitset() {
for (int i = 0; i < setlen; ++i)
values[i] = false;
}
bool& operator[](const int index) {
NS_ASSERTION(index >= 0 && index < setlen, "out of range");
return values[index];
}
bool values[setlen];
};
ExtensionBitset<Extensions_Max> mAvailableExtensions;
// Clear to transparent black, with 0 depth and stencil,
// while preserving current ClearColor etc. values.
// Useful for resizing offscreen buffers.
@ -590,6 +653,7 @@ protected:
PRBool InitWithPrefix(const char *prefix, PRBool trygl);
void InitExtensions();
PRBool IsExtensionSupported(const char *extension);
virtual already_AddRefed<TextureImage>
@ -607,6 +671,9 @@ public:
* perl-or-python-or-js script somewhere and would be
* autogenerated; one would be wrong.
*/
// Keep this at the start of the function pointers
void *mFunctionListStartSentinel;
typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture);
PFNGLACTIVETEXTUREPROC fActiveTexture;
typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
@ -851,6 +918,9 @@ public:
typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGE) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
PFNGLRENDERBUFFERSTORAGE fRenderbufferStorage;
// keep this at the end of the function pointers
void *mFunctionListEndSentinel;
void fDepthRange(GLclampf a, GLclampf b) {
if (mIsGLES2) {
priv_fDepthRangef(a, b);
@ -963,127 +1033,73 @@ public:
priv_fDeleteRenderbuffers(n, names);
}
#else
GLContext *TrackingContext() {
GLContext *tip = this;
while (tip->mSharedContext)
tip = tip->mSharedContext;
return tip;
}
GLuint GLAPIENTRY fCreateProgram() {
GLuint ret = priv_fCreateProgram();
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->CreatedProgram(this, ret);
}
TrackingContext()->CreatedProgram(this, ret);
return ret;
}
GLuint GLAPIENTRY fCreateShader(GLenum t) {
GLuint ret = priv_fCreateShader(t);
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->CreatedShader(this, ret);
}
TrackingContext()->CreatedShader(this, ret);
return ret;
}
void GLAPIENTRY fGenBuffers(GLsizei n, GLuint* names) {
priv_fGenBuffers(n, names);
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->CreatedBuffers(this, n, names);
}
TrackingContext()->CreatedBuffers(this, n, names);
}
void GLAPIENTRY fGenTextures(GLsizei n, GLuint* names) {
priv_fGenTextures(n, names);
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->CreatedTextures(this, n, names);
}
TrackingContext()->CreatedTextures(this, n, names);
}
void GLAPIENTRY fGenFramebuffers(GLsizei n, GLuint* names) {
priv_fGenFramebuffers(n, names);
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->CreatedFramebuffers(this, n, names);
}
TrackingContext()->CreatedFramebuffers(this, n, names);
}
void GLAPIENTRY fGenRenderbuffers(GLsizei n, GLuint* names) {
priv_fGenRenderbuffers(n, names);
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->CreatedRenderbuffers(this, n, names);
}
TrackingContext()->CreatedRenderbuffers(this, n, names);
}
void GLAPIENTRY fDeleteProgram(GLuint program) {
priv_fDeleteProgram(program);
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->DeletedProgram(this, program);
}
TrackingContext()->DeletedProgram(this, program);
}
void GLAPIENTRY fDeleteShader(GLuint shader) {
priv_fDeleteShader(shader);
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->DeletedShader(this, shader);
}
TrackingContext()->DeletedShader(this, shader);
}
void GLAPIENTRY fDeleteBuffers(GLsizei n, GLuint *names) {
priv_fDeleteBuffers(n, names);
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->DeletedBuffers(this, n, names);
}
TrackingContext()->DeletedBuffers(this, n, names);
}
void GLAPIENTRY fDeleteTextures(GLsizei n, GLuint *names) {
priv_fDeleteTextures(n, names);
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->DeletedTextures(this, n, names);
}
TrackingContext()->DeletedTextures(this, n, names);
}
void GLAPIENTRY fDeleteFramebuffers(GLsizei n, GLuint *names) {
priv_fDeleteFramebuffers(n, names);
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->DeletedFramebuffers(this, n, names);
}
TrackingContext()->DeletedFramebuffers(this, n, names);
}
void GLAPIENTRY fDeleteRenderbuffers(GLsizei n, GLuint *names) {
priv_fDeleteRenderbuffers(n, names);
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->DeletedRenderbuffers(this, n, names);
}
TrackingContext()->DeletedRenderbuffers(this, n, names);
}
void THEBES_API CreatedProgram(GLContext *aOrigin, GLuint aName);

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

@ -74,12 +74,15 @@ namespace gl {
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderCGL
#endif
#if defined(ANDROID) || defined(MOZ_PLATFORM_MAEMO)
#if defined(ANDROID) || defined(MOZ_PLATFORM_MAEMO) || defined(XP_WIN)
#define GL_CONTEXT_PROVIDER_NAME GLContextProviderEGL
#include "GLContextProviderImpl.h"
#undef GL_CONTEXT_PROVIDER_NAME
#ifndef GL_CONTEXT_PROVIDER_DEFAULT
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderEGL
#endif
#endif
// X11, but only if we didn't use EGL above
#if defined(MOZ_X11) && !defined(GL_CONTEXT_PROVIDER_DEFAULT)

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

@ -520,6 +520,8 @@ GLContextProviderCGL::GetGlobalContext()
gGlobalContext = nsnull;
return nsnull;
}
gGlobalContext->SetIsGlobalSharedContext(PR_TRUE);
}
return gGlobalContext;

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

@ -76,6 +76,62 @@ typedef void *EGLNativeWindowType;
#define EGL_LIB "/system/lib/libEGL.so"
#define GLES2_LIB "/system/lib/libGLESv2.so"
#elif defined(XP_WIN)
#include <nsServiceManagerUtils.h>
#include <nsIPrefBranch.h>
#include <nsILocalFile.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
typedef HDC EGLNativeDisplayType;
typedef HBITMAP EGLNativePixmapType;
typedef HWND EGLNativeWindowType;
#define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
#define EGL_LIB "libEGL.dll"
#define GLES2_LIB "libGLESv2.dll"
// a little helper
class AutoDestroyHWND {
public:
AutoDestroyHWND(HWND aWnd = NULL)
: mWnd(aWnd)
{
}
~AutoDestroyHWND() {
if (mWnd) {
::DestroyWindow(mWnd);
}
}
operator HWND() {
return mWnd;
}
HWND forget() {
HWND w = mWnd;
mWnd = NULL;
return w;
}
HWND operator=(HWND aWnd) {
if (mWnd && mWnd != aWnd) {
::DestroyWindow(mWnd);
}
mWnd = aWnd;
return mWnd;
}
HWND mWnd;
};
#else
#error "Platform not recognized"
@ -147,58 +203,58 @@ public:
mHave_EGL_KHR_gl_texture_2D_image = PR_FALSE;
}
typedef EGLDisplay (*pfnGetDisplay)(void *display_id);
typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void *display_id);
pfnGetDisplay fGetDisplay;
typedef EGLContext (*pfnGetCurrentContext)(void);
typedef EGLContext (GLAPIENTRY * pfnGetCurrentContext)(void);
pfnGetCurrentContext fGetCurrentContext;
typedef EGLBoolean (*pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
typedef EGLBoolean (GLAPIENTRY * pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
pfnMakeCurrent fMakeCurrent;
typedef EGLBoolean (*pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx);
typedef EGLBoolean (GLAPIENTRY * pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx);
pfnDestroyContext fDestroyContext;
typedef EGLContext (*pfnCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
typedef EGLContext (GLAPIENTRY * pfnCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
pfnCreateContext fCreateContext;
typedef EGLBoolean (*pfnDestroySurface)(EGLDisplay dpy, EGLSurface surface);
typedef EGLBoolean (GLAPIENTRY * pfnDestroySurface)(EGLDisplay dpy, EGLSurface surface);
pfnDestroySurface fDestroySurface;
typedef EGLSurface (*pfnCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
typedef EGLSurface (GLAPIENTRY * pfnCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
pfnCreateWindowSurface fCreateWindowSurface;
typedef EGLSurface (*pfnCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
typedef EGLSurface (GLAPIENTRY * pfnCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
pfnCreatePbufferSurface fCreatePbufferSurface;
typedef EGLSurface (*pfnCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
typedef EGLSurface (GLAPIENTRY * pfnCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
pfnCreatePixmapSurface fCreatePixmapSurface;
typedef EGLBoolean (*pfnBindAPI)(EGLenum api);
typedef EGLBoolean (GLAPIENTRY * pfnBindAPI)(EGLenum api);
pfnBindAPI fBindAPI;
typedef EGLBoolean (*pfnInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
typedef EGLBoolean (GLAPIENTRY * pfnInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
pfnInitialize fInitialize;
typedef EGLBoolean (*pfnChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
typedef EGLBoolean (GLAPIENTRY * pfnChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
pfnChooseConfig fChooseConfig;
typedef EGLint (*pfnGetError)(void);
typedef EGLint (GLAPIENTRY * pfnGetError)(void);
pfnGetError fGetError;
typedef EGLBoolean (*pfnGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
typedef EGLBoolean (GLAPIENTRY * pfnGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
pfnGetConfigAttrib fGetConfigAttrib;
typedef EGLBoolean (*pfnGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
typedef EGLBoolean (GLAPIENTRY * pfnGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
pfnGetConfigs fGetConfigs;
typedef EGLBoolean (*pfnWaitNative)(EGLint engine);
typedef EGLBoolean (GLAPIENTRY * pfnWaitNative)(EGLint engine);
pfnWaitNative fWaitNative;
typedef EGLCastToRelevantPtr (*pfnGetProcAddress)(const char *procname);
typedef EGLCastToRelevantPtr (GLAPIENTRY * pfnGetProcAddress)(const char *procname);
pfnGetProcAddress fGetProcAddress;
typedef EGLBoolean (*pfnSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
typedef EGLBoolean (GLAPIENTRY * pfnSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
pfnSwapBuffers fSwapBuffers;
typedef EGLBoolean (*pfnCopyBuffers)(EGLDisplay dpy, EGLSurface surface,
EGLNativePixmapType target);
typedef EGLBoolean (GLAPIENTRY * pfnCopyBuffers)(EGLDisplay dpy, EGLSurface surface,
EGLNativePixmapType target);
pfnCopyBuffers fCopyBuffers;
typedef const GLubyte* (*pfnQueryString)(EGLDisplay, EGLint name);
typedef const GLubyte* (GLAPIENTRY * pfnQueryString)(EGLDisplay, EGLint name);
pfnQueryString fQueryString;
typedef EGLBoolean (*pfnBindTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
typedef EGLBoolean (GLAPIENTRY * pfnBindTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
pfnBindTexImage fBindTexImage;
typedef EGLBoolean (*pfnReleaseTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
typedef EGLBoolean (GLAPIENTRY * pfnReleaseTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
pfnReleaseTexImage fReleaseTexImage;
typedef EGLImageKHR (*pfnCreateImageKHR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
typedef EGLImageKHR (GLAPIENTRY * pfnCreateImageKHR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
pfnCreateImageKHR fCreateImageKHR;
typedef EGLBoolean (*pfnDestroyImageKHR)(EGLDisplay dpy, EGLImageKHR image);
typedef EGLBoolean (GLAPIENTRY * pfnDestroyImageKHR)(EGLDisplay dpy, EGLImageKHR image);
pfnDestroyImageKHR fDestroyImageKHR;
// This is EGL specific GL ext symbol "glEGLImageTargetTexture2DOES"
// Lets keep it here for now.
typedef void (*pfnImageTargetTexture2DOES)(GLenum target, GLeglImageOES image);
typedef void (GLAPIENTRY * pfnImageTargetTexture2DOES)(GLenum target, GLeglImageOES image);
pfnImageTargetTexture2DOES fImageTargetTexture2DOES;
PRBool EnsureInitialized()
@ -207,6 +263,43 @@ public:
return PR_TRUE;
}
#ifdef XP_WIN
// ANGLE is an addon currently, so we have to do a bit of work
// to find the directory; the addon sets this on startup/shutdown.
do {
nsCOMPtr<nsIPrefBranch> prefs = do_GetService("@mozilla.org/preferences-service;1");
nsCOMPtr<nsILocalFile> angleFile, glesv2File;
if (!prefs)
break;
nsresult rv = prefs->GetComplexValue("gfx.angle.egl.path",
NS_GET_IID(nsILocalFile),
getter_AddRefs(angleFile));
if (NS_FAILED(rv) || !angleFile)
break;
nsCAutoString s;
// note that we have to load the libs in this order, because libEGL.dll
// depends on libGLESv2.dll, but is not in our search path.
nsCOMPtr<nsIFile> f;
angleFile->Clone(getter_AddRefs(f));
glesv2File = do_QueryInterface(f);
if (!glesv2File)
break;
glesv2File->Append(NS_LITERAL_STRING("libGLESv2.dll"));
PRLibrary *glesv2lib = nsnull; // this will be leaked on purpose
glesv2File->Load(&glesv2lib);
if (!glesv2lib)
break;
angleFile->Append(NS_LITERAL_STRING("libEGL.dll"));
angleFile->Load(&mEGLLibrary);
} while (false);
#endif
if (!mEGLLibrary) {
mEGLLibrary = PR_LoadLibrary(EGL_LIB);
if (!mEGLLibrary) {
@ -253,6 +346,11 @@ public:
return PR_FALSE;
const char *extensions = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS);
if (!extensions)
extensions = "";
printf_stderr("Extensions: %s 0x%02x\n", extensions, extensions[0]);
printf_stderr("Extensions length: %d\n", strlen(extensions));
// note the extra space -- this ugliness tries to match
// EGL_KHR_image in the middle of the string, or right at the
@ -406,10 +504,21 @@ public:
, mThebesSurface(nsnull)
, mBound(PR_FALSE)
, mIsPBuffer(PR_FALSE)
{}
#ifdef XP_WIN
, mWnd(0)
#endif
{
// any EGL contexts will always be GLESv2
SetIsGLES2(PR_TRUE);
}
~GLContextEGL()
{
if (mOffscreenFBO) {
MakeCurrent();
DeleteOffscreenFBO();
}
// If mGLWidget is non-null, then we've been given it by the GL context provider,
// and it's managed by the widget implementation. In this case, We can't destroy
// our contexts.
@ -559,6 +668,15 @@ public:
CreateEGLPBufferOffscreenContext(const gfxIntSize& aSize,
const ContextFormat& aFormat);
#ifdef XP_WIN
static already_AddRefed<GLContextEGL>
CreateEGLWin32OffscreenContext(const gfxIntSize& aSize,
const ContextFormat& aFormat);
void HoldWin32Window(HWND aWnd) { mWnd = aWnd; }
HWND GetWin32Window() { return mWnd; }
#endif
void SetOffscreenSize(const gfxIntSize &aRequestedSize,
const gfxIntSize &aActualSize)
{
@ -577,6 +695,10 @@ protected:
PRBool mBound;
PRPackedBool mIsPBuffer;
#ifdef XP_WIN
AutoDestroyHWND mWnd;
#endif
};
PRBool
@ -1167,6 +1289,95 @@ GLContextEGL::CreateEGLPixmapOffscreenContext(const gfxIntSize& aSize,
return glContext.forget();
}
#ifdef XP_WIN
already_AddRefed<GLContextEGL>
GLContextEGL::CreateEGLWin32OffscreenContext(const gfxIntSize& aSize,
const ContextFormat& aFormat)
{
if (!sEGLLibrary.EnsureInitialized()) {
return nsnull;
}
WNDCLASSW wc;
if (!GetClassInfoW(GetModuleHandle(NULL), L"ANGLEContextClass", &wc)) {
ZeroMemory(&wc, sizeof(WNDCLASSW));
wc.style = CS_OWNDC;
wc.hInstance = GetModuleHandle(NULL);
wc.lpfnWndProc = DefWindowProc;
wc.lpszClassName = L"ANGLEContextClass";
if (!RegisterClassW(&wc)) {
NS_WARNING("Failed to register ANGLEContextClass?!");
return NULL;
}
}
AutoDestroyHWND wnd = CreateWindowW(L"ANGLEContextClass", L"ANGLEContext", 0,
0, 0, 16, 16,
NULL, NULL, GetModuleHandle(NULL), NULL);
NS_ENSURE_TRUE(HWND(wnd), NULL);
EGLConfig config;
EGLSurface surface;
EGLContext context;
// We don't really care, we're going to use a FBO anyway
EGLint attribs[] = {
LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_WINDOW_BIT,
LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
LOCAL_EGL_NONE
};
EGLint ncfg = 1;
if (!sEGLLibrary.fChooseConfig(sEGLLibrary.Display(), attribs, &config, ncfg, &ncfg) ||
ncfg < 1)
{
return nsnull;
}
surface = sEGLLibrary.fCreateWindowSurface(sEGLLibrary.Display(),
config,
HWND(wnd),
0);
if (!surface) {
return nsnull;
}
if (!sEGLLibrary.fBindAPI(LOCAL_EGL_OPENGL_ES_API)) {
sEGLLibrary.fDestroySurface(sEGLLibrary.Display(), surface);
return nsnull;
}
EGLint cxattribs[] = {
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
LOCAL_EGL_NONE
};
context = sEGLLibrary.fCreateContext(sEGLLibrary.Display(),
config,
EGL_NO_CONTEXT,
cxattribs);
if (!context) {
sEGLLibrary.fDestroySurface(sEGLLibrary.Display(), surface);
return nsnull;
}
nsRefPtr<GLContextEGL> glContext = new GLContextEGL(aFormat, nsnull,
config, surface, context,
PR_TRUE);
// hold this even before we initialize, because we need to make
// sure it gets destroyed after the surface etc. in case of error.
glContext->HoldWin32Window(wnd.forget());
if (!glContext->Init() ||
!glContext->ResizeOffscreenFBO(aSize))
{
return nsnull;
}
return glContext.forget();
}
#endif
// Under EGL, if we're under X11, then we have to create a Pixmap
// because Maemo's EGL implementation doesn't support pbuffers at all
// for some reason. On Android, pbuffers are supported fine, though
@ -1183,6 +1394,8 @@ GLContextProviderEGL::CreateOffscreen(const gfxIntSize& aSize,
return GLContextEGL::CreateEGLPBufferOffscreenContext(aSize, aFormat);
#elif defined(MOZ_X11)
return GLContextEGL::CreateEGLPixmapOffscreenContext(aSize, aFormat);
#elif defined(XP_WIN)
return GLContextEGL::CreateEGLWin32OffscreenContext(aSize, aFormat);
#else
return nsnull;
#endif
@ -1291,6 +1504,8 @@ GLContextProviderEGL::GetGlobalContext()
if (!triedToCreateContext && !gGlobalContext) {
triedToCreateContext = true;
gGlobalContext = CreateOffscreen(gfxIntSize(16, 16));
if (gGlobalContext)
gGlobalContext->SetIsGlobalSharedContext(PR_TRUE);
}
return gGlobalContext;

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

@ -225,6 +225,11 @@ TRY_AGAIN_NO_SHARING:
~GLContextGLX()
{
if (mOffscreenFBO) {
MakeCurrent();
DeleteOffscreenFBO();
}
sGLXLibrary.xDeleteContext(mDisplay, mContext);
if (mDeleteDrawable) {
@ -287,34 +292,6 @@ TRY_AGAIN_NO_SHARING:
return PR_TRUE;
}
void WindowDestroyed()
{
for (unsigned int i=0; i<textures.Length(); i++) {
GLContext::DestroyTexture(textures.ElementAt(i));
}
textures.Clear();
}
// NB: we could set a flag upon WindowDestroyed() to dictate an
// early-return from CreateTexture(), but then we would need the
// same check before all GL calls, and that heads down a rabbit
// hole.
virtual GLuint CreateTexture()
{
GLuint tex = GLContext::CreateTexture();
NS_ASSERTION(!textures.Contains(tex), "");
textures.AppendElement(tex);
return tex;
}
virtual void DestroyTexture(GLuint texture)
{
if (textures.Contains(texture)) {
textures.RemoveElement(texture);
GLContext::DestroyTexture(texture);
}
}
virtual already_AddRefed<TextureImage>
CreateBasicTextureImage(GLuint aTexture,
const nsIntSize& aSize,
@ -347,7 +324,6 @@ private:
PRPackedBool mDeleteDrawable;
PRPackedBool mDoubleBuffered;
nsTArray<GLuint> textures;
nsRefPtr<gfxXlibSurface> mPixmap;
};
@ -740,6 +716,8 @@ GLContextProviderGLX::GetGlobalContext()
gGlobalContext = CreateOffscreenPixmapContext(gfxIntSize(1, 1),
ContextFormat(ContextFormat::BasicRGB24),
PR_FALSE);
if (gGlobalContext)
gGlobalContext->SetIsGlobalSharedContext(PR_TRUE);
}
return gGlobalContext;

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

@ -87,6 +87,10 @@ CreateDummyWindow(HDC *aWindowDC = nsnull)
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cRedBits = 8;
pfd.cGreenBits = 8;
pfd.cBlueBits = 8;
pfd.cAlphaBits = 8;
pfd.cDepthBits = 0;
pfd.iLayerType = PFD_MAIN_PLANE;
@ -688,6 +692,8 @@ GLContextProviderWGL::GetGlobalContext()
gGlobalContext = nsnull;
return PR_FALSE;
}
gGlobalContext->SetIsGlobalSharedContext(PR_TRUE);
}
return static_cast<GLContext*>(gGlobalContext);

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

@ -116,6 +116,15 @@ public:
GLXContext,
Bool);
PFNGLXCREATECONTEXT xCreateContext;
typedef int (GLAPIENTRY * PFNGLXGETCONFIG) (Display *,
XVisualInfo *,
int,
int *);
PFNGLXGETCONFIG xGetConfig;
typedef GLXPixmap (GLAPIENTRY * PFNGLXCREATEGLXPIXMAP) (Display *,
XVisualInfo *,
Pixmap);
PFNGLXCREATEGLXPIXMAP xCreateGLXPixmap;
PRBool EnsureInitialized();

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

@ -414,6 +414,11 @@ else
CPPSRCS += GLContextProvider$(GL_PROVIDER).cpp
endif
# Win32 is a special snowflake, for ANGLE
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
CPPSRCS += GLContextProviderEGL.cpp
endif
DEFINES += -DIMPL_THEBES -DWOFF_MOZILLA_CLIENT
include $(topsrcdir)/config/rules.mk

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

@ -500,9 +500,10 @@ PRBool gfxOS2Font::SetupCairoFont(gfxContext *aContext)
already_AddRefed<gfxOS2Font> gfxOS2Font::GetOrMakeFont(const nsAString& aName,
const gfxFontStyle *aStyle)
{
nsRefPtr<gfxFont> font = gfxFontCache::GetCache()->Lookup(aName, aStyle);
nsRefPtr<gfxOS2FontEntry> fe = new gfxOS2FontEntry(aName);
nsRefPtr<gfxFont> font =
gfxFontCache::GetCache()->Lookup(static_cast<gfxFontEntry *>(fe), aStyle);
if (!font) {
nsRefPtr<gfxOS2FontEntry> fe = new gfxOS2FontEntry(aName);
font = new gfxOS2Font(fe, aStyle);
if (!font)
return nsnull;

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

@ -43,13 +43,17 @@
* separately to take advantage of the simple switch-case constant propagation
* done by SpiderMonkey.
*/
Narcissus = {};
Narcissus = {
options: { version: 185 }
};
Narcissus.jsdefs = (function() {
var tokens = [
// End of source.
"END",
// Operators and punctuators. Some pair-wise order matters, e.g. (+, -)
// and (UNARY_PLUS, UNARY_MINUS).
"\n", ";",
@ -72,15 +76,15 @@ Narcissus.jsdefs = (function() {
"[", "]",
"{", "}",
"(", ")",
// Nonterminal tree node type codes.
"SCRIPT", "BLOCK", "LABEL", "FOR_IN", "CALL", "NEW_WITH_ARGS", "INDEX",
"ARRAY_INIT", "OBJECT_INIT", "PROPERTY_INIT", "GETTER", "SETTER",
"GROUP", "LIST", "LET_BLOCK", "ARRAY_COMP", "GENERATOR", "COMP_TAIL",
// Terminals.
"IDENTIFIER", "NUMBER", "STRING", "REGEXP",
// Keywords.
"break",
"case", "catch", "const", "continue",
@ -97,7 +101,7 @@ Narcissus.jsdefs = (function() {
"yield",
"while", "with",
];
// Operator and punctuator mapping from token to tree node type name.
// NB: because the lexer doesn't backtrack, all token prefixes must themselves
// be valid tokens (e.g. !== is acceptable because its prefixes are the valid
@ -142,14 +146,14 @@ Narcissus.jsdefs = (function() {
'(': "LEFT_PAREN",
')': "RIGHT_PAREN"
};
// Hash of keyword identifier to tokens index. NB: we must null __proto__ to
// avoid toString, etc. namespace pollution.
var keywords = {__proto__: null};
// Define const END, etc., based on the token names. Also map name to index.
var tokenIds = {};
// Building up a string to be eval'd in different contexts.
var consts = "const ";
for (var i = 0, j = tokens.length; i < j; i++) {
@ -168,23 +172,23 @@ Narcissus.jsdefs = (function() {
tokens[t] = i;
}
consts += ";";
// Map assignment operators to their indexes in the tokens array.
var assignOps = ['|', '^', '&', '<<', '>>', '>>>', '+', '-', '*', '/', '%'];
for (i = 0, j = assignOps.length; i < j; i++) {
t = assignOps[i];
assignOps[t] = tokens[t];
}
function defineGetter(obj, prop, fn, dontDelete, dontEnum) {
Object.defineProperty(obj, prop, { get: fn, configurable: !dontDelete, enumerable: !dontEnum });
}
function defineProperty(obj, prop, val, dontDelete, readOnly, dontEnum) {
Object.defineProperty(obj, prop, { value: val, writable: !readOnly, configurable: !dontDelete, enumerable: !dontEnum });
}
return {
"tokens": tokens,
"opTypeNames": opTypeNames,

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

@ -52,25 +52,25 @@ Narcissus.jsexec = (function() {
var jsparse = Narcissus.jsparse;
var jsdefs = Narcissus.jsdefs;
// Set constants in the local scope.
eval(jsdefs.consts);
const GLOBAL_CODE = 0, EVAL_CODE = 1, FUNCTION_CODE = 2;
function ExecutionContext(type) {
this.type = type;
}
var global = {
// Value properties.
NaN: NaN, Infinity: Infinity, undefined: undefined,
// Function properties.
eval: function eval(s) {
if (typeof s != "string")
return s;
var x = ExecutionContext.current;
var x2 = new ExecutionContext(EVAL_CODE);
x2.thisObject = x.thisObject;
@ -110,7 +110,7 @@ Narcissus.jsexec = (function() {
decodeURI: decodeURI, encodeURI: encodeURI,
decodeURIComponent: decodeURIComponent,
encodeURIComponent: encodeURIComponent,
// Class constructors. Where ECMA-262 requires C.length == 1, we declare
// a dummy formal parameter.
Object: Object,
@ -125,11 +125,11 @@ Narcissus.jsexec = (function() {
}
b += arguments[m];
}
// XXX We want to pass a good file and line to the tokenizer.
// Note the anonymous name to maintain parity with Spidermonkey.
var t = new jsparse.Tokenizer("anonymous(" + p + ") {" + b + "}");
// NB: Use the STATEMENT_FORM constant since we don't want to push this
// function onto the fake compilation context.
var x = { builder: new jsparse.VanillaBuilder };
@ -156,27 +156,28 @@ Narcissus.jsexec = (function() {
Error: Error, EvalError: EvalError, RangeError: RangeError,
ReferenceError: ReferenceError, SyntaxError: SyntaxError,
TypeError: TypeError, URIError: URIError,
// Other properties.
Math: Math,
// Extensions to ECMA.
snarf: snarf, evaluate: evaluate,
load: function load(s) {
if (typeof s != "string")
return s;
evaluate(snarf(s), s, 1)
},
print: print,
version: function() { return 185; }
version: function() { return Narcissus.options.version; },
quit: function() { throw END; }
};
// Helper to avoid Object.prototype.hasOwnProperty polluting scope objects.
function hasDirectProperty(o, p) {
return Object.prototype.hasOwnProperty.call(o, p);
}
// Reflect a host class into the target global environment by delegation.
function reflectClass(name, proto) {
var gctor = global[name];
@ -184,19 +185,19 @@ Narcissus.jsexec = (function() {
jsdefs.defineProperty(proto, "constructor", gctor, false, false, true);
return proto;
}
// Reflect Array -- note that all Array methods are generic.
reflectClass('Array', new Array);
// Reflect String, overriding non-generic methods.
var gSp = reflectClass('String', new String);
gSp.toSource = function () { return this.value.toSource(); };
gSp.toString = function () { return this.value; };
gSp.valueOf = function () { return this.value; };
global.String.fromCharCode = String.fromCharCode;
ExecutionContext.current = null;
ExecutionContext.prototype = {
caller: null,
callee: null,
@ -204,17 +205,34 @@ Narcissus.jsexec = (function() {
thisObject: global,
result: undefined,
target: null,
ecma3OnlyMode: false
ecma3OnlyMode: false,
// Run a thunk in this execution context and return its result.
run: function(thunk) {
var prev = ExecutionContext.current;
ExecutionContext.current = this;
try {
thunk();
return this.result;
} catch (e if e == THROW) {
if (prev) {
prev.result = this.result;
throw THROW;
}
throw this.result;
} finally {
ExecutionContext.current = prev;
}
}
};
function Reference(base, propertyName, node) {
this.base = base;
this.propertyName = propertyName;
this.node = node;
}
Reference.prototype.toString = function () { return this.node.getSource(); }
function getValue(v) {
if (v instanceof Reference) {
if (!v.base) {
@ -225,24 +243,24 @@ Narcissus.jsexec = (function() {
}
return v;
}
function putValue(v, w, vn) {
if (v instanceof Reference)
return (v.base || global)[v.propertyName] = w;
throw new ReferenceError("Invalid assignment left-hand side",
vn.filename, vn.lineno);
}
function isPrimitive(v) {
var t = typeof v;
return (t == "object") ? v === null : t != "function";
}
function isObject(v) {
var t = typeof v;
return (t == "object") ? v !== null : t == "function";
}
// If r instanceof Reference, v == getValue(r); else v === r. If passed, rn
// is the node whose execute result was r.
function toObject(v, r, rn) {
@ -263,10 +281,10 @@ Narcissus.jsexec = (function() {
throw rn ? new TypeError(message, rn.filename, rn.lineno)
: new TypeError(message);
}
function execute(n, x) {
var a, f, i, j, r, s, t, u, v;
switch (n.type) {
case FUNCTION:
if (n.functionForm != jsparse.DECLARED_FORM) {
@ -286,7 +304,7 @@ Narcissus.jsexec = (function() {
}
}
break;
case SCRIPT:
t = x.scope.object;
a = n.funDecls;
@ -308,19 +326,19 @@ Narcissus.jsexec = (function() {
}
}
// FALL THROUGH
case BLOCK:
for (i = 0, j = n.length; i < j; i++)
execute(n[i], x);
break;
case IF:
if (getValue(execute(n.condition, x)))
execute(n.thenPart, x);
else if (n.elsePart)
execute(n.elsePart, x);
break;
case SWITCH:
s = getValue(execute(n.discriminant, x));
a = n.cases;
@ -360,7 +378,7 @@ Narcissus.jsexec = (function() {
}
}
break;
case FOR:
n.setup && getValue(execute(n.setup, x));
// FALL THROUGH
@ -376,7 +394,7 @@ Narcissus.jsexec = (function() {
n.update && getValue(execute(n.update, x));
}
break;
case FOR_IN:
u = n.varDecl;
if (u)
@ -384,7 +402,7 @@ Narcissus.jsexec = (function() {
r = n.iterator;
s = execute(n.object, x);
v = getValue(s);
// ECMA deviation to track extant browser JS implementation behavior.
t = (v == null && !x.ecma3OnlyMode) ? v : toObject(v, s, n.object);
a = [];
@ -401,7 +419,7 @@ Narcissus.jsexec = (function() {
}
}
break;
case DO:
do {
try {
@ -413,12 +431,12 @@ Narcissus.jsexec = (function() {
}
} while (getValue(execute(n.condition, x)));
break;
case BREAK:
case CONTINUE:
x.target = n.target;
throw n.type;
case TRY:
try {
execute(n.tryBlock, x);
@ -447,15 +465,15 @@ Narcissus.jsexec = (function() {
execute(n.finallyBlock, x);
}
break;
case THROW:
x.result = getValue(execute(n.exception, x));
throw THROW;
case RETURN:
x.result = getValue(execute(n.value, x));
throw RETURN;
case WITH:
r = execute(n.object, x);
t = toObject(getValue(r), r, n.object);
@ -466,7 +484,7 @@ Narcissus.jsexec = (function() {
x.scope = x.scope.parent;
}
break;
case VAR:
case CONST:
for (i = 0, j = n.length; i < j; i++) {
@ -485,27 +503,27 @@ Narcissus.jsexec = (function() {
s.object[t] = u;
}
break;
case DEBUGGER:
throw "NYI: " + jsdefs.tokens[n.type];
case SEMICOLON:
if (n.expression)
x.result = getValue(execute(n.expression, x));
break;
case LABEL:
try {
execute(n.statement, x);
} catch (e if e == BREAK && x.target == n) {
}
break;
case COMMA:
for (i = 0, j = n.length; i < j; i++)
v = getValue(execute(n[i], x));
break;
case ASSIGN:
r = execute(n[0], x);
t = n.assignOp;
@ -529,68 +547,68 @@ Narcissus.jsexec = (function() {
}
putValue(r, v, n[0]);
break;
case HOOK:
v = getValue(execute(n[0], x)) ? getValue(execute(n[1], x))
: getValue(execute(n[2], x));
break;
case OR:
v = getValue(execute(n[0], x)) || getValue(execute(n[1], x));
break;
case AND:
v = getValue(execute(n[0], x)) && getValue(execute(n[1], x));
break;
case BITWISE_OR:
v = getValue(execute(n[0], x)) | getValue(execute(n[1], x));
break;
case BITWISE_XOR:
v = getValue(execute(n[0], x)) ^ getValue(execute(n[1], x));
break;
case BITWISE_AND:
v = getValue(execute(n[0], x)) & getValue(execute(n[1], x));
break;
case EQ:
v = getValue(execute(n[0], x)) == getValue(execute(n[1], x));
break;
case NE:
v = getValue(execute(n[0], x)) != getValue(execute(n[1], x));
break;
case STRICT_EQ:
v = getValue(execute(n[0], x)) === getValue(execute(n[1], x));
break;
case STRICT_NE:
v = getValue(execute(n[0], x)) !== getValue(execute(n[1], x));
break;
case LT:
v = getValue(execute(n[0], x)) < getValue(execute(n[1], x));
break;
case LE:
v = getValue(execute(n[0], x)) <= getValue(execute(n[1], x));
break;
case GE:
v = getValue(execute(n[0], x)) >= getValue(execute(n[1], x));
break;
case GT:
v = getValue(execute(n[0], x)) > getValue(execute(n[1], x));
break;
case IN:
v = getValue(execute(n[0], x)) in getValue(execute(n[1], x));
break;
case INSTANCEOF:
t = getValue(execute(n[0], x));
u = getValue(execute(n[1], x));
@ -599,71 +617,71 @@ Narcissus.jsexec = (function() {
else
v = t instanceof u;
break;
case LSH:
v = getValue(execute(n[0], x)) << getValue(execute(n[1], x));
break;
case RSH:
v = getValue(execute(n[0], x)) >> getValue(execute(n[1], x));
break;
case URSH:
v = getValue(execute(n[0], x)) >>> getValue(execute(n[1], x));
break;
case PLUS:
v = getValue(execute(n[0], x)) + getValue(execute(n[1], x));
break;
case MINUS:
v = getValue(execute(n[0], x)) - getValue(execute(n[1], x));
break;
case MUL:
v = getValue(execute(n[0], x)) * getValue(execute(n[1], x));
break;
case DIV:
v = getValue(execute(n[0], x)) / getValue(execute(n[1], x));
break;
case MOD:
v = getValue(execute(n[0], x)) % getValue(execute(n[1], x));
break;
case DELETE:
t = execute(n[0], x);
v = !(t instanceof Reference) || delete t.base[t.propertyName];
break;
case VOID:
getValue(execute(n[0], x));
break;
case TYPEOF:
t = execute(n[0], x);
if (t instanceof Reference)
t = t.base ? t.base[t.propertyName] : undefined;
v = typeof t;
break;
case NOT:
v = !getValue(execute(n[0], x));
break;
case BITWISE_NOT:
v = ~getValue(execute(n[0], x));
break;
case UNARY_PLUS:
v = +getValue(execute(n[0], x));
break;
case UNARY_MINUS:
v = -getValue(execute(n[0], x));
break;
case INCREMENT:
case DECREMENT:
t = execute(n[0], x);
@ -674,21 +692,21 @@ Narcissus.jsexec = (function() {
if (!n.postfix)
v = u;
break;
case DOT:
r = execute(n[0], x);
t = getValue(r);
u = n[1].value;
v = new Reference(toObject(t, r, n[0]), u, n);
break;
case INDEX:
r = execute(n[0], x);
t = getValue(r);
u = getValue(execute(n[1], x));
v = new Reference(toObject(t, r, n[0]), String(u), n);
break;
case LIST:
// Curse ECMA for specifying that arguments is not an Array object!
v = {};
@ -698,7 +716,7 @@ Narcissus.jsexec = (function() {
}
jsdefs.defineProperty(v, "length", i, false, false, true);
break;
case CALL:
r = execute(n[0], x);
a = execute(n[1], x);
@ -712,7 +730,7 @@ Narcissus.jsexec = (function() {
t = null;
v = f.__call__(t, a, x);
break;
case NEW:
case NEW_WITH_ARGS:
r = execute(n[0], x);
@ -729,7 +747,7 @@ Narcissus.jsexec = (function() {
}
v = f.__construct__(a, x);
break;
case ARRAY_INIT:
v = [];
for (i = 0, j = n.length; i < j; i++) {
@ -738,7 +756,7 @@ Narcissus.jsexec = (function() {
}
v.length = j;
break;
case OBJECT_INIT:
v = {};
for (i = 0, j = n.length; i < j; i++) {
@ -753,23 +771,23 @@ Narcissus.jsexec = (function() {
}
}
break;
case NULL:
v = null;
break;
case THIS:
v = x.thisObject;
break;
case TRUE:
v = true;
break;
case FALSE:
v = false;
break;
case IDENTIFIER:
for (s = x.scope; s; s = s.parent) {
if (n.value in s.object)
@ -777,37 +795,37 @@ Narcissus.jsexec = (function() {
}
v = new Reference(s && s.object, n.value, n);
break;
case NUMBER:
case STRING:
case REGEXP:
v = n.value;
break;
case GROUP:
v = execute(n[0], x);
break;
default:
throw "PANIC: unknown operation " + n.type + ": " + uneval(n);
}
return v;
}
function Activation(f, a) {
for (var i = 0, j = f.params.length; i < j; i++)
jsdefs.defineProperty(this, f.params[i], a[i], true);
jsdefs.defineProperty(this, "arguments", a, true);
}
// Null Activation.prototype's proto slot so that Object.prototype.* does not
// pollute the scope of heavyweight functions. Also delete its 'constructor'
// property so that it doesn't pollute function scopes.
Activation.prototype.__proto__ = null;
delete Activation.prototype.constructor;
function FunctionObject(node, scope) {
this.node = node;
this.scope = scope;
@ -816,65 +834,80 @@ Narcissus.jsexec = (function() {
jsdefs.defineProperty(this, "prototype", proto, true);
jsdefs.defineProperty(proto, "constructor", this, false, false, true);
}
function getPropertyDescriptor(obj, name) {
while (obj) {
if (({}).hasOwnProperty.call(obj, name))
return Object.getOwnPropertyDescriptor(obj, name);
obj = Object.getPrototypeOf(obj);
}
}
function getOwnProperties(obj) {
var map = {};
for (var name in Object.getOwnPropertyNames(obj))
map[name] = Object.getOwnPropertyDescriptor(obj, name);
return map;
}
// Returns a new function wrapped with a Proxy.
function newFunction(n,x) {
var f = new FunctionObject(n, x.scope);
var p = Proxy.createFunction(
// Handler function copied from
// http://wiki.ecmascript.org/doku.php?id=harmony:proxies&s=proxy%20object#examplea_no-op_forwarding_proxy
function(obj) { return {
getOwnPropertyDescriptor: function(name) {
var desc = Object.getOwnPropertyDescriptor(obj);
// a trapping proxy's properties must always be configurable
desc.configurable = true;
return desc;
},
getPropertyDescriptor: function(name) {
var desc = Object.getPropertyDescriptor(obj); //assumed
// a trapping proxy's properties must always be configurable
desc.configurable = true;
return desc;
},
getOwnPropertyNames: function() {
return Object.getOwnPropertyNames(obj);
},
defineProperty: function(name, desc) {
Object.defineProperty(obj, name, desc);
},
delete: function(name) { return delete obj[name]; },
fix: function() {
if (Object.isFrozen(obj)) {
return Object.getOwnProperties(obj); // assumed
}
// As long as obj is not frozen, the proxy won't allow itself to be fixed.
return undefined; // will cause a TypeError to be thrown
},
has: function(name) { return name in obj; },
hasOwn: function(name) { return ({}).hasOwnProperty.call(obj, name); },
get: function(receiver, name) { return obj[name]; },
// bad behavior when set fails in non-strict mode
set: function(receiver, name, val) { obj[name] = val; return true; },
enumerate: function() {
var result = [];
for (name in obj) { result.push(name); };
return result;
},
enumerateOwn: function() { return Object.keys(obj); } };
}(f),
function() { return f.__call__(this, arguments, x); },
function() { return f.__construct__(arguments, x); });
function newFunction(n, x) {
var fobj = new FunctionObject(n, x.scope);
// Handler copied from
// http://wiki.ecmascript.org/doku.php?id=harmony:proxies&s=proxy%20object#examplea_no-op_forwarding_proxy
var handler = {
getOwnPropertyDescriptor: function(name) {
var desc = Object.getOwnPropertyDescriptor(fobj, name);
// a trapping proxy's properties must always be configurable
desc.configurable = true;
return desc;
},
getPropertyDescriptor: function(name) {
var desc = getPropertyDescriptor(fobj, name);
// a trapping proxy's properties must always be configurable
desc.configurable = true;
return desc;
},
getOwnPropertyNames: function() {
return Object.getOwnPropertyNames(fobj);
},
defineProperty: function(name, desc) {
Object.defineProperty(fobj, name, desc);
},
delete: function(name) { return delete fobj[name]; },
fix: function() {
if (Object.isFrozen(fobj)) {
return getOwnProperties(fobj);
}
// As long as fobj is not frozen, the proxy won't allow itself to be fixed.
return undefined; // will cause a TypeError to be thrown
},
has: function(name) { return name in fobj; },
hasOwn: function(name) { return ({}).hasOwnProperty.call(fobj, name); },
get: function(receiver, name) { return fobj[name]; },
// bad behavior when set fails in non-strict mode
set: function(receiver, name, val) { fobj[name] = val; return true; },
enumerate: function() {
var result = [];
for (name in fobj) { result.push(name); };
return result;
},
keys: function() { return Object.keys(fobj); }
};
var p = Proxy.createFunction(handler,
function() { return fobj.__call__(this, arguments, x); },
function() { return fobj.__construct__(arguments, x); });
return p;
}
var FOp = FunctionObject.prototype = {
// Internal methods.
__call__: function (t, a, x) {
var x2 = new ExecutionContext(FUNCTION_CODE);
@ -884,7 +917,7 @@ Narcissus.jsexec = (function() {
jsdefs.defineProperty(a, "callee", this, false, false, true);
var f = this.node;
x2.scope = {object: new Activation(f, a), parent: this.scope};
ExecutionContext.current = x2;
try {
execute(f.body, x2);
@ -898,20 +931,20 @@ Narcissus.jsexec = (function() {
}
return undefined;
},
__construct__: function (a, x) {
var o = new Object;
var p = this.prototype;
if (isObject(p))
o.__proto__ = p;
// else o.__proto__ defaulted to Object.prototype
var v = this.__call__(o, a, x);
if (isObject(v))
return v;
return o;
},
__hasInstance__: function (v) {
if (isPrimitive(v))
return false;
@ -928,24 +961,24 @@ Narcissus.jsexec = (function() {
}
return false;
},
// Standard methods.
toString: function () {
return this.node.getSource();
},
apply: function (t, a) {
// Curse ECMA again!
if (typeof this.__call__ != "function") {
throw new TypeError("Function.prototype.apply called on" +
" uncallable object");
}
if (t === undefined || t === null)
t = global;
else if (typeof t != "object")
t = toObject(t, t);
if (a === undefined || a === null) {
a = {};
jsdefs.defineProperty(a, "length", 0, false, false, true);
@ -961,24 +994,24 @@ Narcissus.jsexec = (function() {
" must be an array or arguments object",
this.node.filename, this.node.lineno);
}
return this.__call__(t, a, ExecutionContext.current);
},
call: function (t) {
// Curse ECMA a third time!
var a = Array.prototype.splice.call(arguments, 1);
return this.apply(t, a);
}
};
// Connect Function.prototype and Function.prototype.constructor in global.
reflectClass('Function', FOp);
// Help native and host-scripted functions be like FunctionObjects.
var Fp = Function.prototype;
var REp = RegExp.prototype;
if (!('__call__' in Fp)) {
jsdefs.defineProperty(Fp, "__call__",
function (t, a, x) {
@ -1011,7 +1044,7 @@ Narcissus.jsexec = (function() {
return eval('new this(' + argStr.slice(0,-1) + ');');
}
}, true, true, true);
// Since we use native functions such as Date along with host ones such
// as global.eval, we want both to be considered instances of the native
// Function constructor.
@ -1020,15 +1053,15 @@ Narcissus.jsexec = (function() {
return v instanceof Function || v instanceof global.Function;
}, true, true, true);
}
function thunk(f, x) {
return function () { return f.__call__(this, arguments, x); };
}
function evaluate(s, f, l) {
if (typeof s != "string")
return s;
var x = ExecutionContext.current;
var x2 = new ExecutionContext(GLOBAL_CODE);
ExecutionContext.current = x2;
@ -1045,9 +1078,67 @@ Narcissus.jsexec = (function() {
}
return x2.result;
}
// A read-eval-print-loop that roughly tracks the behavior of the js shell.
function repl() {
// Display a value similarly to the js shell.
function display(x) {
if (typeof x == "object") {
// At the js shell, objects with no |toSource| don't print.
if (x != null && "toSource" in x) {
try {
print(x.toSource());
} catch (e) {
}
} else {
print("null");
}
} else if (typeof x == "string") {
print(uneval(x));
} else if (typeof x != "undefined") {
// Since x must be primitive, String can't throw.
print(String(x));
}
}
// String conversion that never throws.
function string(x) {
try {
return String(x);
} catch (e) {
return "unknown (can't convert to string)";
}
}
var b = new jsparse.VanillaBuilder;
var x = new ExecutionContext(GLOBAL_CODE);
x.run(function() {
for (;;) {
putstr("njs> ");
var line = readline();
x.result = undefined;
try {
execute(jsparse.parse(b, line, "stdin", 1), x);
display(x.result);
} catch (e if e == THROW) {
print("uncaught exception: " + string(x.result));
} catch (e if e == END) {
break;
} catch (e if e instanceof SyntaxError) {
print(e.toString());
} catch (e) {
print("internal Narcissus error");
throw e;
}
}
});
}
return {
"evaluate": evaluate
"evaluate": evaluate,
"repl": repl
};
}());

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

@ -44,16 +44,16 @@
Narcissus.jslex = (function() {
var jsdefs = Narcissus.jsdefs;
// Set constants in the local scope.
eval(jsdefs.consts);
// Build up a trie of operator tokens.
var opTokens = {};
for (var op in jsdefs.opTypeNames) {
if (op === '\n' || op === '.')
continue;
var node = opTokens;
for (var i = 0; i < op.length; i++) {
var ch = op[i];
@ -63,7 +63,7 @@ Narcissus.jslex = (function() {
node.op = op;
}
}
/*
* Tokenizer :: (file ptr, path, line number) -> Tokenizer
*/
@ -77,28 +77,28 @@ Narcissus.jslex = (function() {
this.filename = f || "";
this.lineno = l || 1;
}
Tokenizer.prototype = {
get done() {
// We need to set scanOperand to true here because the first thing
// might be a regexp.
return this.peek(true) == END;
},
get token() {
return this.tokens[this.tokenIndex];
},
match: function (tt, scanOperand) {
return this.get(scanOperand) == tt || this.unget();
},
mustMatch: function (tt) {
if (!this.match(tt))
throw this.newSyntaxError("Missing " + tokens[tt].toLowerCase());
return this.token;
},
peek: function (scanOperand) {
var tt, next;
if (this.lookahead) {
@ -112,14 +112,14 @@ Narcissus.jslex = (function() {
}
return tt;
},
peekOnSameLine: function (scanOperand) {
this.scanNewlines = true;
var tt = this.peek(scanOperand);
this.scanNewlines = false;
return tt;
},
// Eats comments and whitespace.
skip: function () {
var input = this.source;
@ -134,7 +134,7 @@ Narcissus.jslex = (function() {
ch = input[this.cursor++];
if (ch === undefined)
throw this.newSyntaxError("Unterminated comment");
if (ch === '*') {
next = input[this.cursor];
if (next === '/') {
@ -151,7 +151,7 @@ Narcissus.jslex = (function() {
ch = input[this.cursor++];
if (ch === undefined)
return;
if (ch === '\n') {
this.lineno++;
break;
@ -163,7 +163,7 @@ Narcissus.jslex = (function() {
}
}
},
// Lexes the exponential part of a number, if present. Returns true iff an
// exponential part was found.
lexExponent: function() {
@ -174,32 +174,32 @@ Narcissus.jslex = (function() {
ch = input[this.cursor++];
if (ch === '+' || ch === '-')
ch = input[this.cursor++];
if (ch < '0' || ch > '9')
throw this.newSyntaxError("Missing exponent");
do {
ch = input[this.cursor++];
} while (ch >= '0' && ch <= '9');
this.cursor--;
return true;
}
return false;
},
lexZeroNumber: function (ch) {
var token = this.token, input = this.source;
token.type = NUMBER;
ch = input[this.cursor++];
if (ch === '.') {
do {
ch = input[this.cursor++];
} while (ch >= '0' && ch <= '9');
this.cursor--;
this.lexExponent();
token.value = parseFloat(token.start, this.cursor);
} else if (ch === 'x' || ch === 'X') {
@ -208,14 +208,14 @@ Narcissus.jslex = (function() {
} while ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') ||
(ch >= 'A' && ch <= 'F'));
this.cursor--;
token.value = parseInt(input.substring(token.start, this.cursor));
} else if (ch >= '0' && ch <= '7') {
do {
ch = input[this.cursor++];
} while (ch >= '0' && ch <= '7');
this.cursor--;
token.value = parseInt(input.substring(token.start, this.cursor));
} else {
this.cursor--;
@ -223,11 +223,11 @@ Narcissus.jslex = (function() {
token.value = 0;
}
},
lexNumber: function (ch) {
var token = this.token, input = this.source;
token.type = NUMBER;
var floating = false;
do {
ch = input[this.cursor++];
@ -236,16 +236,16 @@ Narcissus.jslex = (function() {
ch = input[this.cursor++];
}
} while (ch >= '0' && ch <= '9');
this.cursor--;
var exponent = this.lexExponent();
floating = floating || exponent;
var str = input.substring(token.start, this.cursor);
token.value = floating ? parseFloat(str) : parseInt(str);
},
lexDot: function (ch) {
var token = this.token, input = this.source;
var next = input[this.cursor];
@ -254,9 +254,9 @@ Narcissus.jslex = (function() {
ch = input[this.cursor++];
} while (ch >= '0' && ch <= '9');
this.cursor--;
this.lexExponent();
token.type = NUMBER;
token.value = parseFloat(token.start, this.cursor);
} else {
@ -265,11 +265,11 @@ Narcissus.jslex = (function() {
token.value = '.';
}
},
lexString: function (ch) {
var token = this.token, input = this.source;
token.type = STRING;
var hasEscapes = false;
var delim = ch;
ch = input[this.cursor++];
@ -280,16 +280,16 @@ Narcissus.jslex = (function() {
}
ch = input[this.cursor++];
}
token.value = (hasEscapes)
? eval(input.substring(token.start, this.cursor))
: input.substring(token.start + 1, this.cursor - 1);
},
lexRegExp: function (ch) {
var token = this.token, input = this.source;
token.type = REGEXP;
do {
ch = input[this.cursor++];
if (ch === '\\') {
@ -298,29 +298,29 @@ Narcissus.jslex = (function() {
do {
if (ch === undefined)
throw this.newSyntaxError("Unterminated character class");
if (ch === '\\')
this.cursor++;
ch = input[this.cursor++];
} while (ch !== ']');
} else if (ch === undefined) {
throw this.newSyntaxError("Unterminated regex");
}
} while (ch !== '/');
do {
ch = input[this.cursor++];
} while (ch >= 'a' && ch <= 'z');
this.cursor--;
token.value = eval(input.substring(token.start, this.cursor));
},
lexOp: function (ch) {
var token = this.token, input = this.source;
// A bit ugly, but it seems wasteful to write a trie lookup routine for
// only 3 characters...
var node = opTokens[ch];
@ -335,7 +335,7 @@ Narcissus.jslex = (function() {
next = input[this.cursor];
}
}
var op = node.op;
if (jsdefs.assignOps[op] && input[this.cursor] === '=') {
this.cursor++;
@ -346,27 +346,27 @@ Narcissus.jslex = (function() {
token.type = jsdefs.tokenIds[jsdefs.opTypeNames[op]];
token.assignOp = null;
}
token.value = op;
},
// FIXME: Unicode escape sequences
// FIXME: Unicode identifiers
lexIdent: function (ch) {
var token = this.token, input = this.source;
do {
ch = input[this.cursor++];
} while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
(ch >= '0' && ch <= '9') || ch === '$' || ch === '_');
this.cursor--; // Put the non-word character back.
var id = input.substring(token.start, this.cursor);
token.type = jsdefs.keywords[id] || IDENTIFIER;
token.value = id;
},
/*
* Tokenizer.get :: void -> token type
*
@ -382,21 +382,21 @@ Narcissus.jslex = (function() {
if (token.type != NEWLINE || this.scanNewlines)
return token.type;
}
this.skip();
this.tokenIndex = (this.tokenIndex + 1) & 3;
token = this.tokens[this.tokenIndex];
if (!token)
this.tokens[this.tokenIndex] = token = {};
var input = this.source;
if (this.cursor === input.length)
return token.type = END;
token.start = this.cursor;
token.lineno = this.lineno;
var ch = input[this.cursor++];
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
ch === '$' || ch === '_') {
@ -420,11 +420,11 @@ Narcissus.jslex = (function() {
} else {
throw this.newSyntaxError("Illegal token");
}
token.end = this.cursor;
return token.type;
},
/*
* Tokenizer.unget :: void -> undefined
*
@ -434,14 +434,14 @@ Narcissus.jslex = (function() {
if (++this.lookahead == 4) throw "PANIC: too much lookahead!";
this.tokenIndex = (this.tokenIndex - 1) & 3;
},
newSyntaxError: function (m) {
var e = new SyntaxError(m, this.filename, this.lineno);
e.source = this.source;
e.cursor = this.cursor;
return e;
},
save: function () {
return {
cursor: this.cursor,
@ -452,7 +452,7 @@ Narcissus.jslex = (function() {
lineno: this.lineno
};
},
rewind: function(point) {
this.cursor = point.cursor;
this.tokenIndex = point.tokenIndex;
@ -462,7 +462,7 @@ Narcissus.jslex = (function() {
this.lineno = point.lineno;
}
};
return { "Tokenizer": Tokenizer };
}());

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

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

@ -45,6 +45,9 @@
#
# Define an include-at-most-once flag
#ifdef INCLUDED_CONFIG_MK
#$(error Don't include config.mk twice!)
#endif
INCLUDED_CONFIG_MK = 1
EXIT_ON_ERROR = set -e; # Shell loops continue past errors without this.
@ -182,7 +185,7 @@ else
endif
endif
MOZALLOC_LIB = -L$(DIST)/bin $(call EXPAND_MOZLIBNAME,mozalloc)
MOZALLOC_LIB = $(call EXPAND_LIBNAME_PATH,mozalloc,$(DIST)/lib)
OS_CFLAGS += $(_DEBUG_CFLAGS)
OS_CXXFLAGS += $(_DEBUG_CFLAGS)

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

@ -1520,17 +1520,17 @@ jsvalToPtrExplicit(JSContext* cx, jsval val, uintptr_t* result)
return false;
}
template<class IntegerType>
template<class IntegerType, class CharType, size_t N, class AP>
void
IntegerToString(IntegerType i, jsuint radix, AutoString& result)
IntegerToString(IntegerType i, jsuint radix, Vector<CharType, N, AP>& result)
{
JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
// The buffer must be big enough for all the bits of IntegerType to fit,
// in base-2, including '-'.
jschar buffer[sizeof(IntegerType) * 8 + 1];
jschar* end = buffer + sizeof(buffer) / sizeof(jschar);
jschar* cp = end;
CharType buffer[sizeof(IntegerType) * 8 + 1];
CharType* end = buffer + sizeof(buffer) / sizeof(CharType);
CharType* cp = end;
// Build the string in reverse. We use multiplication and subtraction
// instead of modulus because that's much faster.
@ -4636,6 +4636,46 @@ PrepareCIF(JSContext* cx,
}
}
void
FunctionType::BuildSymbolName(JSContext* cx,
JSString* name,
JSObject* typeObj,
AutoCString& result)
{
FunctionInfo* fninfo = GetFunctionInfo(cx, typeObj);
switch (GetABICode(cx, fninfo->mABI)) {
case ABI_DEFAULT:
// For cdecl functions, no mangling is necessary.
AppendString(result, name);
break;
case ABI_STDCALL: {
// On WIN32, stdcall functions look like:
// _foo@40
// where 'foo' is the function name, and '40' is the aligned size of the
// arguments.
AppendString(result, "_");
AppendString(result, name);
AppendString(result, "@");
// Compute the suffix by aligning each argument to sizeof(ffi_arg).
size_t size = 0;
for (size_t i = 0; i < fninfo->mArgTypes.length(); ++i) {
JSObject* argType = fninfo->mArgTypes[i];
size += Align(CType::GetSize(cx, argType), sizeof(ffi_arg));
}
IntegerToString(size, 10, result);
break;
}
case INVALID_ABI:
JS_NOT_REACHED("invalid abi");
break;
}
}
static FunctionInfo*
NewFunctionInfo(JSContext* cx,
jsval abiType,

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

@ -111,6 +111,8 @@ class Array : public Vector<T, N, SystemAllocPolicy>
// String and AutoString classes, based on Vector.
typedef Vector<jschar, 0, SystemAllocPolicy> String;
typedef Vector<jschar, 64, SystemAllocPolicy> AutoString;
typedef Vector<char, 0, SystemAllocPolicy> CString;
typedef Vector<char, 64, SystemAllocPolicy> AutoCString;
// Convenience functions to append, insert, and compare Strings.
template <class T, size_t N, class AP, size_t ArrayLength>
@ -142,6 +144,20 @@ AppendString(Vector<jschar, N, AP> &v, JSString* str)
v.append(str->chars(), str->length());
}
template <size_t N, class AP>
void
AppendString(Vector<char, N, AP> &v, JSString* str)
{
JS_ASSERT(str);
size_t vlen = v.length();
size_t alen = str->length();
if (!v.resize(vlen + alen))
return;
for (size_t i = 0; i < alen; ++i)
v[i + vlen] = char(str->chars()[i]);
}
template <class T, size_t N, class AP, size_t ArrayLength>
void
PrependString(Vector<T, N, AP> &v, const char (&array)[ArrayLength])
@ -462,6 +478,8 @@ namespace FunctionType {
FunctionInfo* GetFunctionInfo(JSContext* cx, JSObject* obj);
JSObject* GetLibrary(JSContext* cx, JSObject* obj);
void BuildSymbolName(JSContext* cx, JSString* name, JSObject* typeObj,
AutoCString& result);
}
namespace CClosure {

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

@ -268,24 +268,21 @@ Library::Declare(JSContext* cx, uintN argc, jsval* vp)
return JS_FALSE;
}
const char* name = JS_GetStringBytesZ(cx, JSVAL_TO_STRING(argv[0]));
if (!name)
return JS_FALSE;
JSObject* fnObj = NULL;
JSObject* typeObj;
js::AutoObjectRooter root(cx);
bool isFunction = argc > 2;
if (isFunction) {
// Case 1).
// Create a FunctionType representing the function.
typeObj = FunctionType::CreateInternal(cx,
argv[1], argv[2], &argv[3], argc - 3);
if (!typeObj)
fnObj = FunctionType::CreateInternal(cx,
argv[1], argv[2], &argv[3], argc - 3);
if (!fnObj)
return JS_FALSE;
root.setObject(typeObj);
root.setObject(fnObj);
// Make a function pointer type.
typeObj = PointerType::CreateInternal(cx, typeObj);
typeObj = PointerType::CreateInternal(cx, fnObj);
if (!typeObj)
return JS_FALSE;
root.setObject(typeObj);
@ -301,16 +298,22 @@ Library::Declare(JSContext* cx, uintN argc, jsval* vp)
typeObj = JSVAL_TO_OBJECT(argv[1]);
if (CType::GetTypeCode(cx, typeObj) == TYPE_pointer) {
JSObject* baseType = PointerType::GetBaseType(cx, typeObj);
isFunction = baseType && CType::GetTypeCode(cx, baseType) == TYPE_function;
fnObj = PointerType::GetBaseType(cx, typeObj);
isFunction = fnObj && CType::GetTypeCode(cx, fnObj) == TYPE_function;
}
}
void* data;
PRFuncPtr fnptr;
JSString* nameStr = JSVAL_TO_STRING(argv[0]);
AutoCString symbol;
if (isFunction) {
// Build the symbol, with mangling if necessary.
FunctionType::BuildSymbolName(cx, nameStr, fnObj, symbol);
AppendString(symbol, "\0");
// Look up the function symbol.
fnptr = PR_FindFunctionSymbol(library, name);
fnptr = PR_FindFunctionSymbol(library, symbol.begin());
if (!fnptr) {
JS_ReportError(cx, "couldn't find function symbol in library");
return JS_FALSE;
@ -319,7 +322,10 @@ Library::Declare(JSContext* cx, uintN argc, jsval* vp)
} else {
// 'typeObj' is another data type. Look up the data symbol.
data = PR_FindSymbol(library, name);
AppendString(symbol, nameStr);
AppendString(symbol, "\0");
data = PR_FindSymbol(library, symbol.begin());
if (!data) {
JS_ReportError(cx, "couldn't find symbol in library");
return JS_FALSE;

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

@ -1,4 +1,4 @@
Patch libffi to fix bug 550602, bug 528129, bug 538216, bug 556902, bug 538002, and bug 581909.
Patch libffi to fix bug 550602 and bug 538216.
diff --git a/js/src/ctypes/libffi/Makefile.in b/js/src/ctypes/libffi/Makefile.in
--- a/js/src/ctypes/libffi/Makefile.in
@ -107,645 +107,4 @@ diff --git a/js/src/ctypes/libffi/configure b/js/src/ctypes/libffi/configure
archive_cmds_need_lc=no
hardcode_direct=no
@@ -12179,17 +12179,17 @@ case "$host" in
;;
hppa*-*-hpux*)
TARGET=PA_HPUX; TARGETDIR=pa
;;
i?86-*-freebsd* | i?86-*-openbsd*)
TARGET=X86_FREEBSD; TARGETDIR=x86
;;
- i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*)
+ i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2*)
TARGET=X86_WIN32; TARGETDIR=x86
# All mingw/cygwin/win32 builds require this for sharedlib
AM_LTLDFLAGS="-no-undefined"
;;
i?86-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
i?86-*-solaris2.1[0-9]*)
diff --git a/js/src/ctypes/libffi/msvcc.sh b/js/src/ctypes/libffi/msvcc.sh
--- a/js/src/ctypes/libffi/msvcc.sh
+++ b/js/src/ctypes/libffi/msvcc.sh
@@ -37,20 +37,21 @@
#
# ***** END LICENSE BLOCK *****
#
# GCC-compatible wrapper for cl.exe and ml.exe. Arguments are given in GCC
# format and translated into something sensible for cl or ml.
#
-args="-nologo -W3"
+args="-nologo"
md=-MD
cl="cl"
ml="ml"
+safeseh="-safeseh"
output=
while [ $# -gt 0 ]
do
case $1
in
-fexceptions)
# Don't enable exceptions for now.
@@ -58,16 +59,17 @@ do
shift 1
;;
-m32)
shift 1
;;
-m64)
cl="cl" # "$MSVC/x86_amd64/cl"
ml="ml64" # "$MSVC/x86_amd64/ml64"
+ safeseh=
shift 1
;;
-O*)
args="$args $1"
shift 1
;;
-g)
# Can't specify -RTC1 or -Zi in opt. -Gy is ok. Use -OPT:REF?
@@ -103,17 +105,18 @@ do
includes="$includes $1"
shift 1
;;
-W|-Wextra)
# TODO map extra warnings
shift 1
;;
-Wall)
- args="$args -Wall"
+ # -Wall on MSVC is overzealous. Use -W3 instead.
+ args="$args -W3"
shift 1
;;
-Werror)
args="$args -WX"
shift 1
;;
-W*)
# TODO map specific warnings
@@ -158,17 +161,17 @@ done
if [ -n "$assembly" ]; then
if [ -z "$outdir" ]; then
outdir="."
fi
ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')"
echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
"$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $?
output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
- args="-nologo -safeseh $single $output $ppsrc"
+ args="-nologo $safeseh $single $output $ppsrc"
echo "$ml $args"
eval "\"$ml\" $args"
result=$?
# required to fix ml64 broken output?
#mv *.obj $outdir
else
diff --git a/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c b/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c
--- a/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c
+++ b/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c
@@ -339,17 +339,17 @@ aix_adjust_aggregate_sizes (ffi_type *s)
/* Do not add additional tail padding. */
}
/* Perform machine dependent cif processing. */
ffi_status
ffi_prep_cif_machdep (ffi_cif *cif)
{
/* All this is for the DARWIN ABI. */
- int i;
+ unsigned i;
ffi_type **ptr;
unsigned bytes;
int fparg_count = 0, intarg_count = 0;
unsigned flags = 0;
unsigned size_al = 0;
/* All the machine-independent calculation of cif->bytes will be wrong.
All the calculation of structure sizes will also be wrong.
@@ -537,21 +537,21 @@ ffi_call (ffi_cif *cif, void (*fn)(void)
}
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
case FFI_AIX:
ffi_call_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
- ffi_prep_args);
+ FFI_FN(ffi_prep_args));
break;
case FFI_DARWIN:
ffi_call_DARWIN(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
- ffi_prep_args);
+ FFI_FN(ffi_prep_args));
break;
default:
FFI_ASSERT(0);
break;
}
}
static void flush_icache(char *);
@@ -794,32 +794,32 @@ ffi_closure_helper_DARWIN (ffi_closure *
break;
case FFI_TYPE_STRUCT:
#ifdef POWERPC64
size_al = arg_types[i]->size;
if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
size_al = ALIGN (arg_types[i]->size, 8);
if (size_al < 3 && cif->abi == FFI_DARWIN)
- avalue[i] = (void *) pgr + 8 - size_al;
+ avalue[i] = (char *) pgr + 8 - size_al;
else
- avalue[i] = (void *) pgr;
+ avalue[i] = pgr;
pgr += (size_al + 7) / 8;
#else
/* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
SI 4 bytes) are aligned as if they were those modes. */
size_al = arg_types[i]->size;
/* If the first member of the struct is a double, then align
the struct to double-word. */
if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
size_al = ALIGN(arg_types[i]->size, 8);
if (size_al < 3 && cif->abi == FFI_DARWIN)
- avalue[i] = (void*) pgr + 4 - size_al;
+ avalue[i] = (char*) pgr + 4 - size_al;
else
- avalue[i] = (void*) pgr;
+ avalue[i] = pgr;
pgr += (size_al + 3) / 4;
#endif
break;
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
#ifdef POWERPC64
case FFI_TYPE_POINTER:
diff --git a/js/src/ctypes/libffi/src/x86/ffi.c b/js/src/ctypes/libffi/src/x86/ffi.c
--- a/js/src/ctypes/libffi/src/x86/ffi.c
+++ b/js/src/ctypes/libffi/src/x86/ffi.c
@@ -204,17 +204,17 @@ ffi_status ffi_prep_cif_machdep(ffi_cif
else if (cif->rtype->size == 8)
{
cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
}
else
#endif
{
cif->flags = FFI_TYPE_STRUCT;
- // allocate space for return value pointer
+ /* allocate space for return value pointer */
cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
}
break;
default:
#ifdef X86_WIN64
cif->flags = FFI_TYPE_SINT64;
break;
@@ -229,17 +229,17 @@ ffi_status ffi_prep_cif_machdep(ffi_cif
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
{
if (((*ptr)->alignment - 1) & cif->bytes)
cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
}
#ifdef X86_WIN64
- // ensure space for storing four registers
+ /* ensure space for storing four registers */
cif->bytes += 4 * sizeof(ffi_arg);
#endif
#ifdef X86_DARWIN
cif->bytes = (cif->bytes + 15) & ~0xF;
#endif
return FFI_OK;
@@ -287,18 +287,18 @@ void ffi_call(ffi_cif *cif, void (*fn)(v
ecif.rvalue = rvalue;
switch (cif->abi)
{
#ifdef X86_WIN64
case FFI_WIN64:
{
- // Make copies of all struct arguments
- // NOTE: not sure if responsibility should be here or in caller
+ /* Make copies of all struct arguments
+ NOTE: not sure if responsibility should be here or in caller */
unsigned int i;
for (i=0; i < cif->nargs;i++) {
size_t size = cif->arg_types[i]->size;
if ((cif->arg_types[i]->type == FFI_TYPE_STRUCT
&& (size != 1 && size != 2 && size != 4 && size != 8))
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|| cif->arg_types[i]->type == FFI_TYPE_LONGDOUBLE
#endif
@@ -580,20 +580,20 @@ ffi_prep_raw_closure_loc (ffi_raw_closur
void *codeloc)
{
int i;
if (cif->abi != FFI_SYSV) {
return FFI_BAD_ABI;
}
- // we currently don't support certain kinds of arguments for raw
- // closures. This should be implemented by a separate assembly language
- // routine, since it would require argument processing, something we
- // don't do now for performance.
+ /* we currently don't support certain kinds of arguments for raw
+ closures. This should be implemented by a separate assembly language
+ routine, since it would require argument processing, something we
+ don't do now for performance. */
for (i = cif->nargs-1; i >= 0; i--)
{
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
}
diff --git a/js/src/ctypes/libffi/src/x86/ffitarget.h b/js/src/ctypes/libffi/src/x86/ffitarget.h
--- a/js/src/ctypes/libffi/src/x86/ffitarget.h
+++ b/js/src/ctypes/libffi/src/x86/ffitarget.h
@@ -33,17 +33,17 @@
#if defined (X86_64) && defined (__i386__)
#undef X86_64
#define X86
#endif
#ifdef X86_WIN64
#define FFI_SIZEOF_ARG 8
-#define USE_BUILTIN_FFS 0 // not yet implemented in mingw-64
+#define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
#endif
/* ---- Generic type definitions ----------------------------------------- */
#ifndef LIBFFI_ASM
#ifdef X86_WIN64
#ifdef _MSC_VER
typedef unsigned __int64 ffi_arg;
diff --git a/js/src/ctypes/libffi/src/closures.c b/js/src/ctypes/libffi/src/closures.c
--- a/js/src/ctypes/libffi/src/closures.c
+++ b/js/src/ctypes/libffi/src/closures.c
@@ -39,17 +39,17 @@
option is defined will attempt to map such pages once, but if it
fails, it falls back to creating a temporary file in a writable and
executable filesystem and mapping pages from it into separate
locations in the virtual memory space, one location writable and
another executable. */
# define FFI_MMAP_EXEC_WRIT 1
# define HAVE_MNTENT 1
# endif
-# if defined(X86_WIN32) || defined(X86_WIN64)
+# if defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)
/* Windows systems may have Data Execution Protection (DEP) enabled,
which requires the use of VirtualMalloc/VirtualFree to alloc/free
executable memory. */
# define FFI_MMAP_EXEC_WRIT 1
# endif
#endif
#if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
@@ -188,31 +188,31 @@ static size_t dlmalloc_footprint(void) M
static size_t dlmalloc_max_footprint(void) MAYBE_UNUSED;
static void** dlindependent_calloc(size_t, size_t, void**) MAYBE_UNUSED;
static void** dlindependent_comalloc(size_t, size_t*, void**) MAYBE_UNUSED;
static void *dlpvalloc(size_t) MAYBE_UNUSED;
static int dlmalloc_trim(size_t) MAYBE_UNUSED;
static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
static void dlmalloc_stats(void) MAYBE_UNUSED;
-#if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
+#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__)
/* Use these for mmap and munmap within dlmalloc.c. */
static void *dlmmap(void *, size_t, int, int, int, off_t);
static int dlmunmap(void *, size_t);
-#endif /* !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) */
+#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) */
#define mmap dlmmap
#define munmap dlmunmap
#include "dlmalloc.c"
#undef mmap
#undef munmap
-#if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
+#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__)
/* A mutex used to synchronize access to *exec* variables in this file. */
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
/* A file descriptor of a temporary file from which we'll map
executable pages. */
static int execfd = -1;
@@ -517,17 +517,17 @@ segment_holding_code (mstate m, char* ad
&& addr < add_segment_exec_offset (sp->base, sp) + sp->size)
return sp;
if ((sp = sp->next) == 0)
return 0;
}
}
#endif
-#endif /* !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) */
+#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) */
/* Allocate a chunk of memory with the given size. Returns a pointer
to the writable address, and sets *CODE to the executable
corresponding virtual address. */
void *
ffi_closure_alloc (size_t size, void **code)
{
void *ptr;
diff --git a/js/src/ctypes/libffi/src/dlmalloc.c b/js/src/ctypes/libffi/src/dlmalloc.c
--- a/js/src/ctypes/libffi/src/dlmalloc.c
+++ b/js/src/ctypes/libffi/src/dlmalloc.c
@@ -454,16 +454,24 @@ DEFAULT_MMAP_THRESHOLD default: 25
#define LACKS_STRING_H
#define LACKS_STRINGS_H
#define LACKS_SYS_TYPES_H
#define LACKS_ERRNO_H
#define MALLOC_FAILURE_ACTION
#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */
#endif /* WIN32 */
+#ifdef __OS2__
+#define INCL_DOS
+#include <os2.h>
+#define HAVE_MMAP 1
+#define HAVE_MORECORE 0
+#define LACKS_SYS_MMAN_H
+#endif /* __OS2__ */
+
#if defined(DARWIN) || defined(_DARWIN)
/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */
#ifndef HAVE_MORECORE
#define HAVE_MORECORE 0
#define HAVE_MMAP 1
#endif /* HAVE_MORECORE */
#endif /* DARWIN */
@@ -1283,17 +1291,17 @@ extern void* sbrk(ptrdiff_t);
#define CALL_MMAP(s) MFAIL
#define CALL_MUNMAP(a, s) (-1)
#define DIRECT_MMAP(s) MFAIL
#else /* HAVE_MMAP */
#define IS_MMAPPED_BIT (SIZE_T_ONE)
#define USE_MMAP_BIT (SIZE_T_ONE)
-#ifndef WIN32
+#if !defined(WIN32) && !defined (__OS2__)
#define CALL_MUNMAP(a, s) munmap((a), (s))
#define MMAP_PROT (PROT_READ|PROT_WRITE)
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
#define MAP_ANONYMOUS MAP_ANON
#endif /* MAP_ANON */
#ifdef MAP_ANONYMOUS
#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS)
#define CALL_MMAP(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0)
@@ -1306,16 +1314,52 @@ extern void* sbrk(ptrdiff_t);
static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */
#define CALL_MMAP(s) ((dev_zero_fd < 0) ? \
(dev_zero_fd = open("/dev/zero", O_RDWR), \
mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \
mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0))
#endif /* MAP_ANONYMOUS */
#define DIRECT_MMAP(s) CALL_MMAP(s)
+
+#elif defined(__OS2__)
+
+/* OS/2 MMAP via DosAllocMem */
+static void* os2mmap(size_t size) {
+ void* ptr;
+ if (DosAllocMem(&ptr, size, OBJ_ANY|PAG_COMMIT|PAG_READ|PAG_WRITE) &&
+ DosAllocMem(&ptr, size, PAG_COMMIT|PAG_READ|PAG_WRITE))
+ return MFAIL;
+ return ptr;
+}
+
+#define os2direct_mmap(n) os2mmap(n)
+
+/* This function supports releasing coalesed segments */
+static int os2munmap(void* ptr, size_t size) {
+ while (size) {
+ ULONG ulSize = size;
+ ULONG ulFlags = 0;
+ if (DosQueryMem(ptr, &ulSize, &ulFlags) != 0)
+ return -1;
+ if ((ulFlags & PAG_BASE) == 0 ||(ulFlags & PAG_COMMIT) == 0 ||
+ ulSize > size)
+ return -1;
+ if (DosFreeMem(ptr) != 0)
+ return -1;
+ ptr = ( void * ) ( ( char * ) ptr + ulSize );
+ size -= ulSize;
+ }
+ return 0;
+}
+
+#define CALL_MMAP(s) os2mmap(s)
+#define CALL_MUNMAP(a, s) os2munmap((a), (s))
+#define DIRECT_MMAP(s) os2direct_mmap(s)
+
#else /* WIN32 */
/* Win32 MMAP via VirtualAlloc */
static void* win32mmap(size_t size) {
void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
return (ptr != 0)? ptr: MFAIL;
}
@@ -1382,30 +1426,40 @@ static int win32munmap(void* ptr, size_t
protect against direct calls to MORECORE by other threads not
using this lock, so there is still code to cope the best we can on
interference.
* magic_init_mutex ensures that mparams.magic and other
unique mparams values are initialized only once.
*/
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__OS2__)
/* By default use posix locks */
#include <pthread.h>
#define MLOCK_T pthread_mutex_t
#define INITIAL_LOCK(l) pthread_mutex_init(l, NULL)
#define ACQUIRE_LOCK(l) pthread_mutex_lock(l)
#define RELEASE_LOCK(l) pthread_mutex_unlock(l)
#if HAVE_MORECORE
static MLOCK_T morecore_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif /* HAVE_MORECORE */
static MLOCK_T magic_init_mutex = PTHREAD_MUTEX_INITIALIZER;
+#elif defined(__OS2__)
+#define MLOCK_T HMTX
+#define INITIAL_LOCK(l) DosCreateMutexSem(0, l, 0, FALSE)
+#define ACQUIRE_LOCK(l) DosRequestMutexSem(*l, SEM_INDEFINITE_WAIT)
+#define RELEASE_LOCK(l) DosReleaseMutexSem(*l)
+#if HAVE_MORECORE
+static MLOCK_T morecore_mutex;
+#endif /* HAVE_MORECORE */
+static MLOCK_T magic_init_mutex;
+
#else /* WIN32 */
/*
Because lock-protected regions have bounded times, and there
are no recursive lock calls, we can use simple spinlocks.
*/
#define MLOCK_T long
static int win32_acquire_lock (MLOCK_T *sl) {
@@ -2487,20 +2541,25 @@ static int init_mparams(void) {
if (mparams.magic == 0) {
mparams.magic = s;
/* Set up lock for main malloc area */
INITIAL_LOCK(&gm->mutex);
gm->mflags = mparams.default_mflags;
}
RELEASE_MAGIC_INIT_LOCK();
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__OS2__)
mparams.page_size = malloc_getpagesize;
mparams.granularity = ((DEFAULT_GRANULARITY != 0)?
DEFAULT_GRANULARITY : mparams.page_size);
+#elif defined (__OS2__)
+ /* if low-memory is used, os2munmap() would break
+ if it were anything other than 64k */
+ mparams.page_size = 4096u;
+ mparams.granularity = 65536u;
#else /* WIN32 */
{
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
mparams.page_size = system_info.dwPageSize;
mparams.granularity = system_info.dwAllocationGranularity;
}
#endif /* WIN32 */
diff --git a/js/src/ctypes/libffi/src/x86/win32.S b/js/src/ctypes/libffi/src/x86/win32.S
--- a/js/src/ctypes/libffi/src/x86/win32.S
+++ b/js/src/ctypes/libffi/src/x86/win32.S
@@ -390,17 +390,19 @@ END
#else
.text
# This assumes we are using gas.
.balign 16
.globl _ffi_call_win32
+#ifndef __OS2__
.def _ffi_call_win32; .scl 2; .type 32; .endef
+#endif
_ffi_call_win32:
.LFB1:
pushl %ebp
.LCFI0:
movl %esp,%ebp
.LCFI1:
# Make room for all of the new args.
movl 16(%ebp),%ecx
@@ -542,17 +544,19 @@ 1:
popl %ebp
ret
.ffi_call_win32_end:
.LFE1:
# This assumes we are using gas.
.balign 16
.globl _ffi_closure_SYSV
+#ifndef __OS2__
.def _ffi_closure_SYSV; .scl 2; .type 32; .endef
+#endif
_ffi_closure_SYSV:
.LFB3:
pushl %ebp
.LCFI4:
movl %esp, %ebp
.LCFI5:
subl $40, %esp
leal -24(%ebp), %edx
@@ -663,17 +667,19 @@ 1:
#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
#define CIF_FLAGS_OFFSET 20
# This assumes we are using gas.
.balign 16
.globl _ffi_closure_raw_SYSV
+#ifndef __OS2__
.def _ffi_closure_raw_SYSV; .scl 2; .type 32; .endef
+#endif
_ffi_closure_raw_SYSV:
.LFB4:
pushl %ebp
.LCFI6:
movl %esp, %ebp
.LCFI7:
pushl %esi
.LCFI8:
@@ -779,17 +785,19 @@ 1:
.ffi_closure_raw_SYSV_end:
.LFE4:
#endif /* !FFI_NO_RAW_API */
# This assumes we are using gas.
.balign 16
.globl _ffi_closure_STDCALL
+#ifndef __OS2__
.def _ffi_closure_STDCALL; .scl 2; .type 32; .endef
+#endif
_ffi_closure_STDCALL:
.LFB5:
pushl %ebp
.LCFI9:
movl %esp, %ebp
.LCFI10:
subl $40, %esp
leal -24(%ebp), %edx
@@ -885,17 +893,19 @@ 1:
.Lscls_noretval:
.Lscls_epilogue:
movl %ebp, %esp
popl %ebp
ret
.ffi_closure_STDCALL_end:
.LFE5:
+#ifndef __OS2__
.section .eh_frame,"w"
+#endif
.Lframe1:
.LSCIE1:
.long .LECIE1-.LASCIE1 /* Length of Common Information Entry */
.LASCIE1:
.long 0x0 /* CIE Identifier Tag */
.byte 0x1 /* CIE Version */
#ifdef __PIC__
.ascii "zR\0" /* CIE Augmentation */

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

@ -1,3 +1,122 @@
2010-08-05 Dan Witte <dwitte@mozilla.com>
* Makefile.am: Pass FFI_DEBUG define to msvcc.sh for linking to the
debug CRT when --enable-debug is given.
* configure.ac: Define it.
* msvcc.sh: Translate -g and -DFFI_DEBUG appropriately.
2010-08-04 Dan Witte <dwitte@mozilla.com>
* src/x86/ffitarget.h: Add X86_ANY define for all x86/x86_64
platforms.
* src/x86/ffi.c: Remove redundant ifdef checks.
* src/prep_cif.c: Push stack space computation into src/x86/ffi.c
for X86_ANY so return value space doesn't get added twice.
2010-08-03 Neil Rashbrooke <neil@parkwaycc.co.uk>
* msvcc.sh: Don't pass -safeseh to ml64 because behavior is buggy.
2010-07-22 Dan Witte <dwitte@mozilla.com>
* src/*/ffitarget.h: Make FFI_LAST_ABI one past the last valid ABI.
* src/prep_cif.c: Fix ABI assertion.
* src/cris/ffi.c: Ditto.
2010-07-10 Evan Phoenix <evan@fallingsnow.net>
* src/closures.c (selinux_enabled_check): Fix strncmp usage bug.
2010-07-07 Dan Horák <dan@danny.cz>
* include/ffi.h.in: Protect #define with #ifndef.
* src/powerpc/ffitarget.h: Ditto.
* src/s390/ffitarget.h: Ditto.
* src/sparc/ffitarget.h: Ditto.
2010-05-11 Dan Witte <dwitte@mozilla.com>
* doc/libffi.tex: Document previous change.
2010-05-11 Makoto Kato <m_kato@ga2.so-net.ne.jp>
* src/x86/ffi.c (ffi_call): Don't copy structs passed by value.
2010-05-05 Michael Kohler <michaelkohler@live.com>
* src/dlmalloc.c (dlfree): Fix spelling.
* src/ia64/ffi.c (ffi_prep_cif_machdep): Ditto.
* configure.ac: Ditto.
* configure: Rebuilt.
2010-04-13 Dan Witte <dwitte@mozilla.com>
* msvcc.sh: Build with -W3 instead of -Wall.
* src/powerpc/ffi_darwin.c: Remove build warnings.
* src/x86/ffi.c: Ditto.
* src/x86/ffitarget.h: Ditto.
2010-03-30 Dan Witte <dwitte@mozilla.com>
* msvcc.sh: Disable build warnings.
* README (tested): Clarify windows build procedure.
2010-03-14 Matthias Klose <doko@ubuntu.com>
* src/x86/ffi64.c: Fix typo in comment.
* src/x86/ffi.c: Use /* ... */ comment style.
2010-07-07 Neil Roberts <neil@linux.intel.com>
* src/x86/sysv.S (ffi_call_SYSV): Align the stack pointer to
16-bytes.
2010-07-02 Jakub Jelinek <jakub@redhat.com>
* Makefile.am (AM_MAKEFLAGS): Pass also mandir to submakes.
* Makefile.in: Regenerated.
2010-05-19 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* configure.ac (libffi_cv_as_x86_pcrel): Check for illegal in as
output, too.
(libffi_cv_as_ascii_pseudo_op): Check for .ascii.
(libffi_cv_as_string_pseudo_op): Check for .string.
* configure: Regenerate.
* fficonfig.h.in: Regenerate.
* src/x86/sysv.S (.eh_frame): Use .ascii, .string or error.
2010-04-07 Jakub Jelinek <jakub@redhat.com>
* regex.c (byte_re_match_2_internal): Avoid set but not used
warning.
2010-04-02 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* Makefile.in: Regenerate.
* aclocal.m4: Regenerate.
* include/Makefile.in: Regenerate.
* man/Makefile.in: Regenerate.
* testsuite/Makefile.in: Regenerate.
2010-03-15 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* configure.ac (libffi_cv_as_x86_64_unwind_section_type): New test.
* configure: Regenerate.
* fficonfig.h.in: Regenerate.
* libffi/src/x86/unix64.S (.eh_frame)
[HAVE_AS_X86_64_UNWIND_SECTION_TYPE]: Use @unwind section type.
2010-02-24 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* doc/libffi.texi (The Closure API): Fix typo.
* doc/libffi.info: Remove.
2010-02-15 Matthias Klose <doko@ubuntu.com>
* src/arm/sysv.S (__ARM_ARCH__): Define for processor
__ARM_ARCH_7EM__.
2010-01-07 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR libffi/40701

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

@ -69,6 +69,7 @@ AM_MAKEFLAGS = \
"exec_prefix=$(exec_prefix)" \
"infodir=$(infodir)" \
"libdir=$(libdir)" \
"mandir=$(mandir)" \
"prefix=$(prefix)" \
"AR=$(AR)" \
"AS=$(AS)" \
@ -151,6 +152,9 @@ endif
if FRV
nodist_libffi_la_SOURCES += src/frv/eabi.S src/frv/ffi.c
endif
if MOXIE
nodist_libffi_la_SOURCES += src/moxie/eabi.S src/moxie/ffi.c
endif
if S390
nodist_libffi_la_SOURCES += src/s390/sysv.S src/s390/ffi.c
endif
@ -174,6 +178,14 @@ libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
AM_CFLAGS = -Wall -g -fexceptions
if FFI_DEBUG
# Build debug. Define FFI_DEBUG on the commandline so that, when building with
# MSVC, it can link against the debug CRT.
AM_CFLAGS += -DFFI_DEBUG
else
# Build opt.
AM_CFLAGS += -O2
endif
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)

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

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.11 from Makefile.am.
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@ -55,12 +55,18 @@ target_triplet = @target@
@AVR32_TRUE@am__append_17 = src/avr32/sysv.S src/avr32/ffi.c
@LIBFFI_CRIS_TRUE@am__append_18 = src/cris/sysv.S src/cris/ffi.c
@FRV_TRUE@am__append_19 = src/frv/eabi.S src/frv/ffi.c
@S390_TRUE@am__append_20 = src/s390/sysv.S src/s390/ffi.c
@X86_64_TRUE@am__append_21 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
@SH_TRUE@am__append_22 = src/sh/sysv.S src/sh/ffi.c
@SH64_TRUE@am__append_23 = src/sh64/sysv.S src/sh64/ffi.c
@PA_LINUX_TRUE@am__append_24 = src/pa/linux.S src/pa/ffi.c
@PA_HPUX_TRUE@am__append_25 = src/pa/hpux32.S src/pa/ffi.c
@MOXIE_TRUE@am__append_20 = src/moxie/eabi.S src/moxie/ffi.c
@S390_TRUE@am__append_21 = src/s390/sysv.S src/s390/ffi.c
@X86_64_TRUE@am__append_22 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
@SH_TRUE@am__append_23 = src/sh/sysv.S src/sh/ffi.c
@SH64_TRUE@am__append_24 = src/sh64/sysv.S src/sh64/ffi.c
@PA_LINUX_TRUE@am__append_25 = src/pa/linux.S src/pa/ffi.c
@PA_HPUX_TRUE@am__append_26 = src/pa/hpux32.S src/pa/ffi.c
# Build debug. Define FFI_DEBUG on the commandline so that, when building with
# MSVC, it can link against the debug CRT.
@FFI_DEBUG_TRUE@am__append_27 = -DFFI_DEBUG
# Build opt.
@FFI_DEBUG_FALSE@am__append_28 = -O2
subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/doc/stamp-vti \
@ -138,13 +144,14 @@ am_libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \
@AVR32_TRUE@am__objects_17 = src/avr32/sysv.lo src/avr32/ffi.lo
@LIBFFI_CRIS_TRUE@am__objects_18 = src/cris/sysv.lo src/cris/ffi.lo
@FRV_TRUE@am__objects_19 = src/frv/eabi.lo src/frv/ffi.lo
@S390_TRUE@am__objects_20 = src/s390/sysv.lo src/s390/ffi.lo
@X86_64_TRUE@am__objects_21 = src/x86/ffi64.lo src/x86/unix64.lo \
@MOXIE_TRUE@am__objects_20 = src/moxie/eabi.lo src/moxie/ffi.lo
@S390_TRUE@am__objects_21 = src/s390/sysv.lo src/s390/ffi.lo
@X86_64_TRUE@am__objects_22 = src/x86/ffi64.lo src/x86/unix64.lo \
@X86_64_TRUE@ src/x86/ffi.lo src/x86/sysv.lo
@SH_TRUE@am__objects_22 = src/sh/sysv.lo src/sh/ffi.lo
@SH64_TRUE@am__objects_23 = src/sh64/sysv.lo src/sh64/ffi.lo
@PA_LINUX_TRUE@am__objects_24 = src/pa/linux.lo src/pa/ffi.lo
@PA_HPUX_TRUE@am__objects_25 = src/pa/hpux32.lo src/pa/ffi.lo
@SH_TRUE@am__objects_23 = src/sh/sysv.lo src/sh/ffi.lo
@SH64_TRUE@am__objects_24 = src/sh64/sysv.lo src/sh64/ffi.lo
@PA_LINUX_TRUE@am__objects_25 = src/pa/linux.lo src/pa/ffi.lo
@PA_HPUX_TRUE@am__objects_26 = src/pa/hpux32.lo src/pa/ffi.lo
nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
$(am__objects_6) $(am__objects_7) $(am__objects_8) \
@ -153,17 +160,17 @@ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_15) $(am__objects_16) $(am__objects_17) \
$(am__objects_18) $(am__objects_19) $(am__objects_20) \
$(am__objects_21) $(am__objects_22) $(am__objects_23) \
$(am__objects_24) $(am__objects_25)
$(am__objects_24) $(am__objects_25) $(am__objects_26)
libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \
$(nodist_libffi_la_OBJECTS)
libffi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libffi_la_LDFLAGS) $(LDFLAGS) -o $@
libffi_convenience_la_LIBADD =
am__objects_26 = src/debug.lo src/prep_cif.lo src/types.lo \
am__objects_27 = src/debug.lo src/prep_cif.lo src/types.lo \
src/raw_api.lo src/java_raw_api.lo src/closures.lo
am_libffi_convenience_la_OBJECTS = $(am__objects_26)
am__objects_27 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
am_libffi_convenience_la_OBJECTS = $(am__objects_27)
am__objects_28 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
$(am__objects_7) $(am__objects_8) $(am__objects_9) \
$(am__objects_10) $(am__objects_11) $(am__objects_12) \
@ -171,8 +178,8 @@ am__objects_27 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_16) $(am__objects_17) $(am__objects_18) \
$(am__objects_19) $(am__objects_20) $(am__objects_21) \
$(am__objects_22) $(am__objects_23) $(am__objects_24) \
$(am__objects_25)
nodist_libffi_convenience_la_OBJECTS = $(am__objects_27)
$(am__objects_25) $(am__objects_26)
nodist_libffi_convenience_la_OBJECTS = $(am__objects_28)
libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \
$(nodist_libffi_convenience_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
@ -319,6 +326,7 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
@ -448,6 +456,7 @@ AM_MAKEFLAGS = \
"exec_prefix=$(exec_prefix)" \
"infodir=$(infodir)" \
"libdir=$(libdir)" \
"mandir=$(mandir)" \
"prefix=$(prefix)" \
"AR=$(AR)" \
"AS=$(AS)" \
@ -475,10 +484,10 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \
$(am__append_15) $(am__append_16) $(am__append_17) \
$(am__append_18) $(am__append_19) $(am__append_20) \
$(am__append_21) $(am__append_22) $(am__append_23) \
$(am__append_24) $(am__append_25)
$(am__append_24) $(am__append_25) $(am__append_26)
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
AM_CFLAGS = -Wall -g -fexceptions
AM_CFLAGS = -Wall -g -fexceptions $(am__append_27) $(am__append_28)
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
AM_CCASFLAGS = $(AM_CPPFLAGS)
@ -744,6 +753,16 @@ src/frv/eabi.lo: src/frv/$(am__dirstamp) \
src/frv/$(DEPDIR)/$(am__dirstamp)
src/frv/ffi.lo: src/frv/$(am__dirstamp) \
src/frv/$(DEPDIR)/$(am__dirstamp)
src/moxie/$(am__dirstamp):
@$(MKDIR_P) src/moxie
@: > src/moxie/$(am__dirstamp)
src/moxie/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) src/moxie/$(DEPDIR)
@: > src/moxie/$(DEPDIR)/$(am__dirstamp)
src/moxie/eabi.lo: src/moxie/$(am__dirstamp) \
src/moxie/$(DEPDIR)/$(am__dirstamp)
src/moxie/ffi.lo: src/moxie/$(am__dirstamp) \
src/moxie/$(DEPDIR)/$(am__dirstamp)
src/s390/$(am__dirstamp):
@$(MKDIR_P) src/s390
@: > src/s390/$(am__dirstamp)
@ -837,6 +856,10 @@ mostlyclean-compile:
-rm -f src/mips/n32.lo
-rm -f src/mips/o32.$(OBJEXT)
-rm -f src/mips/o32.lo
-rm -f src/moxie/eabi.$(OBJEXT)
-rm -f src/moxie/eabi.lo
-rm -f src/moxie/ffi.$(OBJEXT)
-rm -f src/moxie/ffi.lo
-rm -f src/pa/ffi.$(OBJEXT)
-rm -f src/pa/ffi.lo
-rm -f src/pa/hpux32.$(OBJEXT)
@ -934,6 +957,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/ffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/n32.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/o32.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/moxie/$(DEPDIR)/eabi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/moxie/$(DEPDIR)/ffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/ffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/hpux32.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/linux.Plo@am__quote@
@ -1029,6 +1054,7 @@ clean-libtool:
-rm -rf src/m32r/.libs src/m32r/_libs
-rm -rf src/m68k/.libs src/m68k/_libs
-rm -rf src/mips/.libs src/mips/_libs
-rm -rf src/moxie/.libs src/moxie/_libs
-rm -rf src/pa/.libs src/pa/_libs
-rm -rf src/powerpc/.libs src/powerpc/_libs
-rm -rf src/s390/.libs src/s390/_libs
@ -1232,7 +1258,7 @@ uninstall-pkgconfigDATA:
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@failcom='exit 1'; \
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@ -1257,7 +1283,7 @@ $(RECURSIVE_TARGETS):
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
@failcom='exit 1'; \
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@ -1424,7 +1450,8 @@ distdir: $(DISTFILES)
top_distdir="$(top_distdir)" distdir="$(distdir)" \
dist-info
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
@ -1468,17 +1495,17 @@ dist dist-all: distdir
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lzma*) \
unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
@ -1587,6 +1614,8 @@ distclean-generic:
-rm -f src/m68k/$(am__dirstamp)
-rm -f src/mips/$(DEPDIR)/$(am__dirstamp)
-rm -f src/mips/$(am__dirstamp)
-rm -f src/moxie/$(DEPDIR)/$(am__dirstamp)
-rm -f src/moxie/$(am__dirstamp)
-rm -f src/pa/$(DEPDIR)/$(am__dirstamp)
-rm -f src/pa/$(am__dirstamp)
-rm -f src/powerpc/$(DEPDIR)/$(am__dirstamp)
@ -1612,7 +1641,7 @@ clean-am: clean-aminfo clean-generic clean-libLTLIBRARIES \
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf src/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
-rm -rf src/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-libtool distclean-tags
@ -1732,7 +1761,7 @@ installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -rf src/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
-rm -rf src/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-aminfo \
maintainer-clean-generic maintainer-clean-vti

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

@ -75,6 +75,7 @@ tested:
| X86 | Linux |
| X86 | Mac OSX |
| X86 | OpenBSD |
| X86 | OS/2 |
| X86 | Solaris |
| X86 | Windows/Cygwin |
| X86 | Windows/MingW |
@ -113,9 +114,13 @@ It's also possible to build libffi on Windows platforms with
Microsoft's Visual C++ compiler. In this case, use the msvcc.sh
wrapper script during configuration like so:
path/to/configure --enable-shared --enable-static \
CC=path/to/msvcc.sh LD=link \
CPP=\"cl -nologo -EP\"
path/to/configure CC=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\"
For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64".
You may also need to specify --build appropriately. When building with MSVC
under a MingW environment, you may need to remove the line in configure
that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not
present in MingW, and is not required when using MingW-style paths.)
Configure has many other options. Use "configure --help" to see them all.

20
js/src/ctypes/libffi/aclocal.m4 поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
# generated automatically by aclocal 1.11 -*- Autoconf -*-
# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
@ -13,8 +13,8 @@
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.63],,
[m4_warning([this file was generated for autoconf 2.63.
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],,
[m4_warning([this file was generated for autoconf 2.65.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically `autoreconf'.])])
@ -7862,15 +7862,15 @@ m4_define([lt_dict_filter],
# Generated from ltversion.in.
# serial 3012 ltversion.m4
# serial 3017 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.2.6])
m4_define([LT_PACKAGE_REVISION], [1.3012])
m4_define([LT_PACKAGE_VERSION], [2.2.6b])
m4_define([LT_PACKAGE_REVISION], [1.3017])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.2.6'
macro_revision='1.3012'
[macro_version='2.2.6b'
macro_revision='1.3017'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])
@ -7983,7 +7983,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.11'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.11], [],
m4_if([$1], [1.11.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@ -7999,7 +7999,7 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.11])dnl
[AM_AUTOMAKE_VERSION([1.11.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])

6932
js/src/ctypes/libffi/configure поставляемый

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

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

@ -16,10 +16,14 @@ AM_INIT_AUTOMAKE
# We must force CC to /not/ be precious variables; otherwise
# the wrong, non-multilib-adjusted value will be used in multilibs.
# As a side effect, we have to subst CFLAGS ourselves.
# Also save and restore CFLAGS, since AC_PROG_CC will come up with
# defaults of its own if none are provided.
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
m4_define([_AC_ARG_VAR_PRECIOUS],[])
save_CFLAGS=$CFLAGS
AC_PROG_CC
CFLAGS=$save_CFLAGS
m4_undefine([_AC_ARG_VAR_PRECIOUS])
m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
@ -43,7 +47,7 @@ TARGETDIR="unknown"
case "$host" in
alpha*-*-*)
TARGET=ALPHA; TARGETDIR=alpha;
# Support 128-bit long double, changable via command-line switch.
# Support 128-bit long double, changeable via command-line switch.
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
;;
@ -120,6 +124,10 @@ case "$host" in
TARGET=MIPS; TARGETDIR=mips
;;
moxie-*-*)
TARGET=MOXIE; TARGETDIR=moxie
;;
powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
@ -185,6 +193,7 @@ AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
AM_CONDITIONAL(MOXIE, test x$TARGET = xMOXIE)
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
@ -270,7 +279,7 @@ if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64
libffi_cv_as_x86_pcrel, [
libffi_cv_as_x86_pcrel=yes
echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
if $CC $CFLAGS -c conftest.s 2>&1 | $EGREP -i 'illegal|warning' > /dev/null; then
libffi_cv_as_x86_pcrel=no
fi
])
@ -278,6 +287,32 @@ if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64
AC_DEFINE(HAVE_AS_X86_PCREL, 1,
[Define if your assembler supports PC relative relocs.])
fi
AC_CACHE_CHECK([assembler .ascii pseudo-op support],
libffi_cv_as_ascii_pseudo_op, [
libffi_cv_as_ascii_pseudo_op=unknown
# Check if we have .ascii
AC_TRY_COMPILE([asm (".ascii \"string\"");],,
[libffi_cv_as_ascii_pseudo_op=yes],
[libffi_cv_as_ascii_pseudo_op=no])
])
if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_ASCII_PSEUDO_OP, 1,
[Define if your assembler supports .ascii.])
fi
AC_CACHE_CHECK([assembler .string pseudo-op support],
libffi_cv_as_string_pseudo_op, [
libffi_cv_as_string_pseudo_op=unknown
# Check if we have .string
AC_TRY_COMPILE([asm (".string \"string\"");],,
[libffi_cv_as_string_pseudo_op=yes],
[libffi_cv_as_string_pseudo_op=no])
])
if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_STRING_PSEUDO_OP, 1,
[Define if your assembler supports .string.])
fi
fi
case "$target" in
@ -288,6 +323,21 @@ case "$target" in
;;
esac
if test x$TARGET = xX86_64; then
AC_CACHE_CHECK([assembler supports unwind section type],
libffi_cv_as_x86_64_unwind_section_type, [
libffi_cv_as_x86_64_unwind_section_type=yes
echo '.section .eh_frame,"a",@unwind' > conftest.s
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
libffi_cv_as_x86_64_unwind_section_type=no
fi
])
if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
[Define if your assembler supports unwind section type.])
fi
fi
AC_CACHE_CHECK([whether .eh_frame section should be read-only],
libffi_cv_ro_eh_frame, [
libffi_cv_ro_eh_frame=no
@ -354,6 +404,7 @@ AC_ARG_ENABLE(debug,
if test "$enable_debug" = "yes"; then
AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
fi)
AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
AC_ARG_ENABLE(structs,
[ --disable-structs omit code for struct support],

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