Merge commit for bug 439340

This commit is contained in:
Peter Weilbacher 2008-07-02 18:47:20 +02:00
commit 6115e668e7
357 changed files with 15350 additions and 7083 deletions

View File

@ -1,3 +1,4 @@
df7a3c8ffeeaba229067efee5a20e21dae0dd877 MOZILLA_1_9_a4_BASE df7a3c8ffeeaba229067efee5a20e21dae0dd877 MOZILLA_1_9_a4_BASE
4209e16b58411750ac73f761023e46b76b793e2c MOZILLA_1_9_a6_BASE 4209e16b58411750ac73f761023e46b76b793e2c MOZILLA_1_9_a6_BASE
66a5c7bce7ee86a820d3c0d54fa07cb719be751c MOZILLA_1_9_a7_BASE 66a5c7bce7ee86a820d3c0d54fa07cb719be751c MOZILLA_1_9_a7_BASE
caeba7562e495a9f604984df0b48b6f99bec3e2e FENNEC_M4

View File

@ -2117,13 +2117,21 @@ nsAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
// If accessible is invisible we don't want to calculate group ARIA // If accessible is invisible we don't want to calculate group ARIA
// attributes for it. // attributes for it.
if ((role == nsIAccessibleRole::ROLE_LISTITEM || if ((role == nsIAccessibleRole::ROLE_LISTITEM ||
role == nsIAccessibleRole::ROLE_MENUITEM || role == nsIAccessibleRole::ROLE_MENUITEM ||
role == nsIAccessibleRole::ROLE_RADIOBUTTON || role == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
role == nsIAccessibleRole::ROLE_PAGETAB || role == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM ||
role == nsIAccessibleRole::ROLE_OPTION || role == nsIAccessibleRole::ROLE_RADIOBUTTON ||
role == nsIAccessibleRole::ROLE_RADIOBUTTON || role == nsIAccessibleRole::ROLE_PAGETAB ||
role == nsIAccessibleRole::ROLE_OUTLINEITEM) && role == nsIAccessibleRole::ROLE_OPTION ||
role == nsIAccessibleRole::ROLE_RADIOBUTTON ||
role == nsIAccessibleRole::ROLE_OUTLINEITEM) &&
0 == (State(this) & nsIAccessibleStates::STATE_INVISIBLE)) { 0 == (State(this) & nsIAccessibleStates::STATE_INVISIBLE)) {
PRUint32 baseRole = role;
if (role == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
role == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
baseRole = nsIAccessibleRole::ROLE_MENUITEM;
nsCOMPtr<nsIAccessible> parent = GetParent(); nsCOMPtr<nsIAccessible> parent = GetParent();
NS_ENSURE_TRUE(parent, NS_ERROR_FAILURE); NS_ENSURE_TRUE(parent, NS_ERROR_FAILURE);
@ -2135,10 +2143,17 @@ nsAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
NS_ENSURE_TRUE(sibling, NS_ERROR_FAILURE); NS_ENSURE_TRUE(sibling, NS_ERROR_FAILURE);
PRBool foundCurrent = PR_FALSE; PRBool foundCurrent = PR_FALSE;
PRUint32 siblingRole; PRUint32 siblingRole, siblingBaseRole;
while (sibling) { while (sibling) {
sibling->GetFinalRole(&siblingRole); sibling->GetFinalRole(&siblingRole);
if (siblingRole == role &&
siblingBaseRole = siblingRole;
if (siblingRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
siblingRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
siblingBaseRole = nsIAccessibleRole::ROLE_MENUITEM;
// If sibling is visible and has the same base role.
if (siblingBaseRole == baseRole &&
!(State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)) { !(State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)) {
++ setSize; ++ setSize;
if (!foundCurrent) { if (!foundCurrent) {
@ -2147,6 +2162,17 @@ nsAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
foundCurrent = PR_TRUE; foundCurrent = PR_TRUE;
} }
} }
// If the sibling is separator
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR) {
if (foundCurrent) // the our group is ended
break;
// not our group, continue the searching
positionInGroup = 0;
setSize = 0;
}
sibling->GetNextSibling(getter_AddRefs(nextSibling)); sibling->GetNextSibling(getter_AddRefs(nextSibling));
sibling = nextSibling; sibling = nextSibling;
} }

View File

@ -51,6 +51,11 @@ class nsAccessibleWrap : public nsAccessible
public: // construction, destruction public: // construction, destruction
nsAccessibleWrap(nsIDOMNode*, nsIWeakReference *aShell); nsAccessibleWrap(nsIDOMNode*, nsIWeakReference *aShell);
virtual ~nsAccessibleWrap(); virtual ~nsAccessibleWrap();
protected:
virtual nsresult FirePlatformEvent(nsIAccessibleEvent *aEvent) {
return NS_OK;
}
}; };
#endif #endif

View File

@ -58,6 +58,7 @@ _TEST_FILES =\
test_nsIAccessibleTable_3.html \ test_nsIAccessibleTable_3.html \
test_nsIAccessibleTable_4.html \ test_nsIAccessibleTable_4.html \
test_nsIAccessibleTable_listboxes.xul \ test_nsIAccessibleTable_listboxes.xul \
test_nsIAccessibleDocument.html \
test_nsIAccessibleHyperLink.html \ test_nsIAccessibleHyperLink.html \
test_nsIAccessibleHyperLink.xul \ test_nsIAccessibleHyperLink.xul \
test_nsIAccessibleHyperText.html \ test_nsIAccessibleHyperText.html \

View File

@ -30,19 +30,30 @@
this.mAttrs = this.mAcc.attributes; this.mAttrs = this.mAcc.attributes;
} }
function testGroupAtts(aID, aPosInSet, aSetSize)
{
var attrs = new accAttributes(aID);
is(attrs.getAttribute("posinset"), aPosInSet, "Wrong posinset on " + aID);
is(attrs.getAttribute("setsize"), aSetSize, "Wrong setsize on " + aID);
}
function doTest() function doTest()
{ {
// Activate accessibility, otherwise events aren't fired. // Activate accessibility, otherwise events aren't fired.
gAccService = Components.classes["@mozilla.org/accessibleRetrieval;1"]. gAccService = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(Components.interfaces.nsIAccessibleRetrieval); getService(Components.interfaces.nsIAccessibleRetrieval);
var attrs = new accAttributes("item1"); //////////////////////////////////////////////////////////////////////////
is(attrs.getAttribute("posinset"), "1", "Wrong posinset on item1."); // xul:listbox (bug 417317)
is(attrs.getAttribute("setsize"), "2", "Wrong setsize on item1."); testGroupAtts("item1", "1", "2");
testGroupAtts("item2", "2", "2");
attrs = new accAttributes("item2"); //////////////////////////////////////////////////////////////////////////
is(attrs.getAttribute("posinset"), "2", "Wrong posinset on item2."); // ARIA menu (bug 441888)
is(attrs.getAttribute("setsize"), "2", "Wrong setsize on item2."); testGroupAtts("aria-menuitem", "1", "3");
testGroupAtts("aria-menuitemcheckbox", "2", "3");
testGroupAtts("aria-menuitemradio", "3", "3");
testGroupAtts("aria-menuitem2", "1", "1");
SimpleTest.finish(); SimpleTest.finish();
} }
@ -69,5 +80,19 @@
<listitem label="item1" id="item1"/> <listitem label="item1" id="item1"/>
<listitem label="item2" id="item2"/> <listitem label="item2" id="item2"/>
</listbox> </listbox>
<vbox>
<description role="menuitem" id="aria-menuitem"
value="conventional menuitem"/>
<description role="menuitemcheckbox" id="aria-menuitemcheckbox"
value="conventional checkbox menuitem"/>
<description role="menuitem" hidden="true"/>
<description role="menuitemradio" id="aria-menuitemradio"
value="conventional radio menuitem"/>
<description role="separator"
value="conventional separator"/>
<description role="menuitem" id="aria-menuitem2"
value="conventional menuitem"/>
</vbox>
</window> </window>

View File

@ -0,0 +1,111 @@
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=441737
-->
<head>
<title>nsIAccessibleDocument chrome tests</title>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript">
const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval;
const nsIAccessibleRole = Components.interfaces.nsIAccessibleRole;
const nsIAccessibleDocument = Components.interfaces.nsIAccessibleDocument;
const nsIDOMDocument = Components.interfaces.nsIDOMDocument;
const nsIDOMWindow = Components.interfaces.nsIDOMWindow;
// needed state flag
const state_focusable =
Components.interfaces.nsIAccessibleStates.STATE_FOCUSABLE;
const state_readonly =
Components.interfaces.nsIAccessibleStates.STATE_READONLY;
var gAccRetrieval = null;
function doTest()
{
gAccRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(nsIAccessibleRetrieval);
// Get accessible for body tag.
var docAcc = null;
try {
docAcc = gAccRetrieval.getAccessibleFor(document).
QueryInterface(nsIAccessibleDocument);
} catch(e) {}
ok(docAcc, "No accessible with interface for document!");
if (docAcc) {
// nsIAccessible
is(docAcc.name, "nsIAccessibleDocument chrome tests",
"Name for document accessible not correct!");
is(docAcc.role, nsIAccessibleRole.ROLE_DOCUMENT,
"Wrong role for document!");
// check if it is focusable, read-only.
var state = {}, extraState = {}
docAcc.getFinalState(state, extraState);
var desiredStates = (state_focusable | state_readonly);
is(state.value & desiredStates, desiredStates,
"Wrong state bits for document!");
// No actions wanted on doc
is(docAcc.numActions, 0, "Wrong number of actions for document!");
// attributes should contain tag:body
attributes = docAcc.attributes;
is(attributes.getStringProperty("tag"), "BODY",
"Wrong attribute on document!");
// nsIAccessibleDocument
is(docAcc.URL, "chrome://mochikit/content/a11y/accessible/test_nsIAccessibleDocument.html",
"Wrong URL for document!");
is(docAcc.title, "nsIAccessibleDocument chrome tests",
"Wrong title for document!");
is(docAcc.mimeType, "text/html",
"Wrong mime type for document!");
// nsDocAccessible::getDocType currently returns NS_ERROR_FAILURE.
// See bug 442005. After fixing, please remove this comment and
// uncomment the below two lines to enable the test.
// is(docAcc.docType, "HTML",
// "Wrong type of document!");
// Test for correct nsIDOMDocument retrieval.
var domDoc = null;
try {
domDoc = docAcc.document.QueryInterface(nsIDOMDocument);
} catch(e) {}
ok(domDoc, "no nsIDOMDocument for this doc accessible!");
is(domDoc, document, "Document nodes do not match!");
// Test for correct nsIDOMWindow retrieval.
var domWindow = null;
try {
domWindow = docAcc.window.QueryInterface(nsIDOMWindow);
} catch(e) {}
ok(domWindow, "no nsIDOMWindow for this doc accessible!");
is(domWindow, window, "Window nodes do not match!");
}
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=441737"
title="nsAccessibleDocument chrome tests">
Mozilla Bug 441737
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -160,16 +160,7 @@ ifdef _MSC_VER
WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
endif endif
ifndef BUILD_STATIC_LIBS ifdef BUILD_STATIC_LIBS
ifdef NS_TRACE_MALLOC
# when libxul is enabled, trace-malloc is part of it
ifndef MOZ_ENABLE_LIBXUL
EXTRA_DSO_LIBS += tracemalloc
endif
endif
else
include $(topsrcdir)/config/static-config.mk include $(topsrcdir)/config/static-config.mk
EXTRA_DEPS += \ EXTRA_DEPS += \

View File

@ -239,9 +239,7 @@ pref("browser.download.manager.showAlertOnComplete", true);
pref("browser.download.manager.showAlertInterval", 2000); pref("browser.download.manager.showAlertInterval", 2000);
pref("browser.download.manager.retention", 2); pref("browser.download.manager.retention", 2);
pref("browser.download.manager.showWhenStarting", true); pref("browser.download.manager.showWhenStarting", true);
pref("browser.download.manager.useWindow", true);
pref("browser.download.manager.closeWhenDone", false); pref("browser.download.manager.closeWhenDone", false);
pref("browser.download.manager.openDelay", 0);
pref("browser.download.manager.focusWhenStarting", false); pref("browser.download.manager.focusWhenStarting", false);
pref("browser.download.manager.flashCount", 2); pref("browser.download.manager.flashCount", 2);
pref("browser.download.manager.addToRecentDocs", true); pref("browser.download.manager.addToRecentDocs", true);

View File

@ -505,11 +505,12 @@ endif
DEHYDRA_SCRIPT = $(topsrcdir)/xpcom/analysis/static-checking.js DEHYDRA_SCRIPT = $(topsrcdir)/xpcom/analysis/static-checking.js
DEHYDRA_MODULES = \ DEHYDRA_MODULES = \
$(topsrcdir)/xpcom/analysis/stack.js \ $(topsrcdir)/xpcom/analysis/final.js \
$(NULL) $(NULL)
TREEHYDRA_MODULES = \ TREEHYDRA_MODULES = \
$(topsrcdir)/xpcom/analysis/outparams.js \ $(topsrcdir)/xpcom/analysis/outparams.js \
$(topsrcdir)/xpcom/analysis/stack.js \
$(NULL) $(NULL)
DEHYDRA_ARGS = \ DEHYDRA_ARGS = \

View File

@ -58,6 +58,7 @@
#include "nsIScriptGlobalObject.h" #include "nsIScriptGlobalObject.h"
#include "nsIDOMEvent.h" #include "nsIDOMEvent.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsTextFragment.h"
struct nsNativeKeyEvent; // Don't include nsINativeKeyBindings.h here: it will force strange compilation error! struct nsNativeKeyEvent; // Don't include nsINativeKeyBindings.h here: it will force strange compilation error!
@ -98,6 +99,7 @@ class nsIPref;
class nsVoidArray; class nsVoidArray;
struct JSRuntime; struct JSRuntime;
class nsICaseConversion; class nsICaseConversion;
class nsIUGenCategory;
class nsIWidget; class nsIWidget;
class nsPIDOMWindow; class nsPIDOMWindow;
#ifdef MOZ_XTF #ifdef MOZ_XTF
@ -364,10 +366,16 @@ public:
PRBool aTrimTrailing = PR_TRUE); PRBool aTrimTrailing = PR_TRUE);
/** /**
* Returns true if aChar is of class Ps, Pi, Po, Pf, or Pe. (Does not * Returns true if aChar is of class Ps, Pi, Po, Pf, or Pe.
* currently handle non-BMP characters.)
*/ */
static PRBool IsPunctuationMark(PRUnichar aChar); static PRBool IsPunctuationMark(PRUint32 aChar);
static PRBool IsPunctuationMarkAt(const nsTextFragment* aFrag, PRUint32 aOffset);
/**
* Returns true if aChar is of class Lu, Ll, Lt, Lm, Lo, Nd, Nl or No
*/
static PRBool IsAlphanumeric(PRUint32 aChar);
static PRBool IsAlphanumericAt(const nsTextFragment* aFrag, PRUint32 aOffset);
/* /*
* Is the character an HTML whitespace character? * Is the character an HTML whitespace character?
@ -577,6 +585,11 @@ public:
return sCaseConv; return sCaseConv;
} }
static nsIUGenCategory* GetGenCat()
{
return sGenCat;
}
/** /**
* @return PR_TRUE if aContent has an attribute aName in namespace aNameSpaceID, * @return PR_TRUE if aContent has an attribute aName in namespace aNameSpaceID,
* and the attribute value is non-empty. * and the attribute value is non-empty.
@ -1352,6 +1365,7 @@ private:
static nsILineBreaker* sLineBreaker; static nsILineBreaker* sLineBreaker;
static nsIWordBreaker* sWordBreaker; static nsIWordBreaker* sWordBreaker;
static nsICaseConversion* sCaseConv; static nsICaseConversion* sCaseConv;
static nsIUGenCategory* sGenCat;
// Holds pointers to nsISupports* that should be released at shutdown // Holds pointers to nsISupports* that should be released at shutdown
static nsVoidArray* sPtrsToPtrsToRelease; static nsVoidArray* sPtrsToPtrsToRelease;
@ -1379,7 +1393,7 @@ private:
nsContentUtils::DropJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz)) nsContentUtils::DropJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz))
class nsCxPusher class NS_STACK_CLASS nsCxPusher
{ {
public: public:
nsCxPusher(); nsCxPusher();

View File

@ -1102,7 +1102,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)
* event is dispatched, if necessary, when the outermost mozAutoSubtreeModified * event is dispatched, if necessary, when the outermost mozAutoSubtreeModified
* object is deleted. * object is deleted.
*/ */
class mozAutoSubtreeModified class NS_STACK_CLASS mozAutoSubtreeModified
{ {
public: public:
/** /**

View File

@ -51,10 +51,19 @@ class nsCycleCollectionCallback;
/** /**
* Class to track what content is referenced by a given ID. * Class to track what content is referenced by a given ID.
* *
* To use it, call Reset() to set it up to watch a given URI. Call get()
* anytime to determine the referenced element (which may be null if
* the element isn't found). When the element changes, ContentChanged
* will be called, so subclass this class if you want to receive that
* notification. ContentChanged runs at safe-for-script time, i.e. outside
* of the content update. Call Unlink() if you want to stop watching
* for changes (get() will then return null).
*
* By default this is a single-shot tracker --- i.e., when ContentChanged * By default this is a single-shot tracker --- i.e., when ContentChanged
* fires, we will automatically stop tracking. Override IsPersistent * fires, we will automatically stop tracking. get() will continue to return
* to return PR_TRUE if you want to keep tracking after the content for * the changed-to element.
* an ID has changed. * Override IsPersistent to return PR_TRUE if you want to keep tracking after
* the first change.
*/ */
class nsReferencedElement { class nsReferencedElement {
public: public:
@ -65,9 +74,27 @@ public:
mPendingNotification->Clear(); mPendingNotification->Clear();
} }
} }
/**
* Find which element, if any, is referenced.
*/
nsIContent* get() { return mContent; } nsIContent* get() { return mContent; }
/**
* Set up the reference. This can be called multiple times to
* change which reference is being tracked, but these changes
* do not trigger ContentChanged.
* @param aFrom the source element for context
* @param aURI the URI containing a hash-reference to the element
* @param aWatch if false, then we do not set up the notifications to track
* changes, so ContentChanged won't fire and get() will always return the same
* value, the current element for the ID.
*/
void Reset(nsIContent* aFrom, nsIURI* aURI, PRBool aWatch = PR_TRUE); void Reset(nsIContent* aFrom, nsIURI* aURI, PRBool aWatch = PR_TRUE);
/**
* Clears the reference. ContentChanged is not triggered. get() will return
* null.
*/
void Unlink(); void Unlink();
void Traverse(nsCycleCollectionTraversalCallback* aCB); void Traverse(nsCycleCollectionTraversalCallback* aCB);
@ -75,7 +102,8 @@ public:
protected: protected:
/** /**
* Override this to be notified of content changes. Don't forget * Override this to be notified of content changes. Don't forget
* to call this method to change mContent. * to call this superclass method to change mContent. This is called
* at script-runnable time.
*/ */
virtual void ContentChanged(nsIContent* aFrom, nsIContent* aTo) { virtual void ContentChanged(nsIContent* aFrom, nsIContent* aTo) {
mContent = aTo; mContent = aTo;

View File

@ -41,7 +41,7 @@
* in which case no updates will be called. The constructor also takes a * in which case no updates will be called. The constructor also takes a
* boolean that can be set to false to prevent notifications. * boolean that can be set to false to prevent notifications.
*/ */
class mozAutoDocUpdate class NS_STACK_CLASS mozAutoDocUpdate
{ {
public: public:
mozAutoDocUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType, mozAutoDocUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType,
@ -94,7 +94,7 @@ private:
* but then have inner mozAutoDocUpdate call the last EndUpdate before. * but then have inner mozAutoDocUpdate call the last EndUpdate before.
* we remove that blocker. See bug 423269. * we remove that blocker. See bug 423269.
*/ */
class mozAutoDocConditionalContentUpdateBatch class NS_STACK_CLASS mozAutoDocConditionalContentUpdateBatch
{ {
public: public:
mozAutoDocConditionalContentUpdateBatch(nsIDocument* aDocument, mozAutoDocConditionalContentUpdateBatch(nsIDocument* aDocument,

View File

@ -119,7 +119,7 @@ NS_INTERFACE_MAP_BEGIN(nsContentAreaDragDrop)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
class nsTransferableFactory class NS_STACK_CLASS nsTransferableFactory
{ {
public: public:
nsTransferableFactory(nsIDOMEvent* inMouseEvent, nsTransferableFactory(nsIDOMEvent* inMouseEvent,

View File

@ -154,6 +154,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsGenericHTMLElement.h" #include "nsGenericHTMLElement.h"
#include "nsAttrValue.h" #include "nsAttrValue.h"
#include "nsReferencedElement.h" #include "nsReferencedElement.h"
#include "nsIUGenCategory.h"
#ifdef IBMBIDI #ifdef IBMBIDI
#include "nsIBidiKeyboard.h" #include "nsIBidiKeyboard.h"
@ -195,6 +196,7 @@ PRBool nsContentUtils::sTriedToGetContentPolicy = PR_FALSE;
nsILineBreaker *nsContentUtils::sLineBreaker; nsILineBreaker *nsContentUtils::sLineBreaker;
nsIWordBreaker *nsContentUtils::sWordBreaker; nsIWordBreaker *nsContentUtils::sWordBreaker;
nsICaseConversion *nsContentUtils::sCaseConv; nsICaseConversion *nsContentUtils::sCaseConv;
nsIUGenCategory *nsContentUtils::sGenCat;
nsVoidArray *nsContentUtils::sPtrsToPtrsToRelease; nsVoidArray *nsContentUtils::sPtrsToPtrsToRelease;
nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND]; nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND];
PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND]; PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND];
@ -298,6 +300,9 @@ nsContentUtils::Init()
rv = CallGetService(NS_UNICHARUTIL_CONTRACTID, &sCaseConv); rv = CallGetService(NS_UNICHARUTIL_CONTRACTID, &sCaseConv);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = CallGetService(NS_UNICHARCATEGORY_CONTRACTID, &sGenCat);
NS_ENSURE_SUCCESS(rv, rv);
// Ignore failure and just don't load images // Ignore failure and just don't load images
rv = CallGetService("@mozilla.org/image/loader;1", &sImgLoader); rv = CallGetService("@mozilla.org/image/loader;1", &sImgLoader);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
@ -676,15 +681,55 @@ nsContentUtils::CopyNewlineNormalizedUnicodeTo(nsReadingIterator<PRUnichar>& aSr
// Updated to fix the regression (bug 263411). The list contains // Updated to fix the regression (bug 263411). The list contains
// characters of the following Unicode character classes : Ps, Pi, Po, Pf, Pe. // characters of the following Unicode character classes : Ps, Pi, Po, Pf, Pe.
// (ref.: http://www.w3.org/TR/2004/CR-CSS21-20040225/selector.html#first-letter) // (ref.: http://www.w3.org/TR/2004/CR-CSS21-20040225/selector.html#first-letter)
// Note that the file does NOT yet include non-BMP characters. #include "punct_marks.x-ccmap"
#include "punct_marks.ccmap" DEFINE_X_CCMAP(gPuncCharsCCMapExt, const);
DEFINE_CCMAP(gPuncCharsCCMap, const);
// static // static
PRBool PRBool
nsContentUtils::IsPunctuationMark(PRUnichar aChar) nsContentUtils::IsPunctuationMark(PRUint32 aChar)
{ {
return CCMAP_HAS_CHAR(gPuncCharsCCMap, aChar); return CCMAP_HAS_CHAR_EXT(gPuncCharsCCMapExt, aChar);
}
// static
PRBool
nsContentUtils::IsPunctuationMarkAt(const nsTextFragment* aFrag, PRUint32 aOffset)
{
PRUnichar h = aFrag->CharAt(aOffset);
if (!IS_SURROGATE(h)) {
return IsPunctuationMark(h);
}
if (NS_IS_HIGH_SURROGATE(h) && aOffset + 1 < aFrag->GetLength()) {
PRUnichar l = aFrag->CharAt(aOffset + 1);
if (NS_IS_LOW_SURROGATE(l)) {
return IsPunctuationMark(SURROGATE_TO_UCS4(h, l));
}
}
return PR_FALSE;
}
// static
PRBool nsContentUtils::IsAlphanumeric(PRUint32 aChar)
{
nsIUGenCategory::nsUGenCategory cat = sGenCat->Get(aChar);
return (cat == nsIUGenCategory::kLetter || cat == nsIUGenCategory::kNumber);
}
// static
PRBool nsContentUtils::IsAlphanumericAt(const nsTextFragment* aFrag, PRUint32 aOffset)
{
PRUnichar h = aFrag->CharAt(aOffset);
if (!IS_SURROGATE(h)) {
return IsAlphanumeric(h);
}
if (NS_IS_HIGH_SURROGATE(h) && aOffset + 1 < aFrag->GetLength()) {
PRUnichar l = aFrag->CharAt(aOffset + 1);
if (NS_IS_LOW_SURROGATE(l)) {
return IsAlphanumeric(SURROGATE_TO_UCS4(h, l));
}
}
return PR_FALSE;
} }
/* static */ /* static */
@ -802,6 +847,7 @@ nsContentUtils::Shutdown()
NS_IF_RELEASE(sLineBreaker); NS_IF_RELEASE(sLineBreaker);
NS_IF_RELEASE(sWordBreaker); NS_IF_RELEASE(sWordBreaker);
NS_IF_RELEASE(sCaseConv); NS_IF_RELEASE(sCaseConv);
NS_IF_RELEASE(sGenCat);
#ifdef MOZ_XTF #ifdef MOZ_XTF
NS_IF_RELEASE(sXTFService); NS_IF_RELEASE(sXTFService);
#endif #endif

View File

@ -3057,7 +3057,7 @@ nsDocument::SetScriptHandlingObject(nsIScriptGlobalObject* aScriptObject)
"Wrong script object!"); "Wrong script object!");
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aScriptObject); nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aScriptObject);
NS_ASSERTION(!win || win->IsInnerWindow(), "Should have inner window here!"); NS_ASSERTION(!win || win->IsInnerWindow(), "Should have inner window here!");
mScriptObject = do_GetWeakReference(aScriptObject); mScopeObject = mScriptObject = do_GetWeakReference(aScriptObject);
if (aScriptObject) { if (aScriptObject) {
mHasHadScriptHandlingObject = PR_TRUE; mHasHadScriptHandlingObject = PR_TRUE;
} }

View File

@ -323,10 +323,11 @@ nsNodeUtils::GetUserData(nsINode *aNode, const nsAString &aKey,
return NS_OK; return NS_OK;
} }
struct nsHandlerData struct NS_STACK_CLASS nsHandlerData
{ {
PRUint16 mOperation; PRUint16 mOperation;
nsCOMPtr<nsIDOMNode> mSource, mDest; nsCOMPtr<nsIDOMNode> mSource;
nsCOMPtr<nsIDOMNode> mDest;
}; };
static void static void

View File

@ -762,15 +762,27 @@ nsObjectLoadingContent::HasNewFrame(nsIObjectFrame* aFrame)
{ {
LOG(("OBJLC [%p]: Got frame %p (mInstantiating=%i)\n", this, aFrame, LOG(("OBJLC [%p]: Got frame %p (mInstantiating=%i)\n", this, aFrame,
mInstantiating)); mInstantiating));
if (!mInstantiating && aFrame && mType == eType_Plugin) {
// "revoke" any existing instantiate event as it likely has out of
// date data (frame pointer etc).
mPendingInstantiateEvent = nsnull;
nsCOMPtr<nsIPluginInstance> instance;
aFrame->GetPluginInstance(*getter_AddRefs(instance));
if (instance) {
// The frame already has a plugin instance, that means the plugin
// has already been instantiated.
return NS_OK;
}
if (!mInstantiating && mType == eType_Plugin) {
// Asynchronously call Instantiate // Asynchronously call Instantiate
// This can go away once plugin loading moves to content // This can go away once plugin loading moves to content
// This must be done asynchronously to ensure that the frame is correctly // This must be done asynchronously to ensure that the frame is correctly
// initialized (has a view etc) // initialized (has a view etc)
// "revoke" any existing instantiate event.
mPendingInstantiateEvent = nsnull;
// When in a plugin document, the document will take care of calling // When in a plugin document, the document will take care of calling
// instantiate // instantiate
nsCOMPtr<nsIPluginDocument> pDoc (do_QueryInterface(GetOurDocument())); nsCOMPtr<nsIPluginDocument> pDoc (do_QueryInterface(GetOurDocument()));

View File

@ -54,10 +54,10 @@
#include "nsIRunnable.h" #include "nsIRunnable.h"
#include "nsIChannelClassifier.h" #include "nsIChannelClassifier.h"
struct nsAsyncInstantiateEvent; class nsAsyncInstantiateEvent;
class AutoNotifier; class AutoNotifier;
class AutoFallback; class AutoFallback;
class AutoSetInstantiatingToFalse; class AutoSetInstantiatingToFalse;
/** /**
* INVARIANTS OF THIS CLASS * INVARIANTS OF THIS CLASS

View File

@ -789,7 +789,7 @@ nsresult nsRange::SelectNodeContents(nsIDOMNode* aN)
// start/end points in the future, we can switchover relatively // start/end points in the future, we can switchover relatively
// easy. // easy.
class RangeSubtreeIterator class NS_STACK_CLASS RangeSubtreeIterator
{ {
private: private:

View File

@ -190,7 +190,7 @@ public:
* before handling the system event group. * before handling the system event group.
* This is used in nsPresShell. * This is used in nsPresShell.
*/ */
class nsDispatchingCallback { class NS_STACK_CLASS nsDispatchingCallback {
public: public:
virtual void HandleEvent(nsEventChainPostVisitor& aVisitor) = 0; virtual void HandleEvent(nsEventChainPostVisitor& aVisitor) = 0;
}; };

View File

@ -2929,7 +2929,7 @@ nsEventStateManager::SetCursor(PRInt32 aCursor, imgIContainer* aContainer,
return NS_OK; return NS_OK;
} }
class nsESMEventCB : public nsDispatchingCallback class NS_STACK_CLASS nsESMEventCB : public nsDispatchingCallback
{ {
public: public:
nsESMEventCB(nsIContent* aTarget) : mTarget(aTarget) {} nsESMEventCB(nsIContent* aTarget) : mTarget(aTarget) {}

View File

@ -61,7 +61,7 @@ struct nsRect;
* This class answers to NS_QUERY_* events from actual contents. * This class answers to NS_QUERY_* events from actual contents.
*/ */
class nsQueryContentEventHandler { class NS_STACK_CLASS nsQueryContentEventHandler {
public: public:
nsQueryContentEventHandler(nsPresContext *aPresContext); nsQueryContentEventHandler(nsPresContext *aPresContext);

View File

@ -190,7 +190,7 @@ private:
nsCheapInt32Set mIndices; nsCheapInt32Set mIndices;
}; };
class nsSafeOptionListMutation class NS_STACK_CLASS nsSafeOptionListMutation
{ {
public: public:
/** /**

View File

@ -79,7 +79,7 @@
* filters. PLEASE NOTE that nsSVGFilterResource should ONLY be used on the * filters. PLEASE NOTE that nsSVGFilterResource should ONLY be used on the
* stack because it has nsAutoString member. * stack because it has nsAutoString member.
*/ */
class nsSVGFilterResource class NS_STACK_CLASS nsSVGFilterResource
{ {
public: public:
nsSVGFilterResource(nsSVGFE *aFilter, nsSVGFilterInstance* aInstance); nsSVGFilterResource(nsSVGFE *aFilter, nsSVGFilterInstance* aInstance);
@ -546,16 +546,6 @@ private:
nsresult GetDXY(PRUint32 *aDX, PRUint32 *aDY, const nsSVGFilterInstance& aInstance); nsresult GetDXY(PRUint32 *aDX, PRUint32 *aDY, const nsSVGFilterInstance& aInstance);
void InflateRectForBlur(nsRect* aRect, const nsSVGFilterInstance& aInstance); void InflateRectForBlur(nsRect* aRect, const nsSVGFilterInstance& aInstance);
PRUint8 *SetupPredivide(PRUint32 size) const;
void BoxBlurH(PRUint8 *aInput, PRUint8 *aOutput,
PRInt32 aStride, const nsRect& aRegion,
PRUint32 leftLobe, PRUint32 rightLobe, const PRUint8 *prediv);
void BoxBlurV(PRUint8 *aInput, PRUint8 *aOutput,
PRInt32 aStride, const nsRect& aRegion,
PRUint32 topLobe, PRUint32 bottomLobe, const PRUint8 *prediv);
void GaussianBlur(PRUint8 *aInput, PRUint8 *aOutput, void GaussianBlur(PRUint8 *aInput, PRUint8 *aOutput,
nsSVGFilterResource *aFilterResource, nsSVGFilterResource *aFilterResource,
PRUint32 aDX, PRUint32 aDY); PRUint32 aDX, PRUint32 aDY);
@ -628,101 +618,110 @@ nsSVGFEGaussianBlurElement::SetStdDeviation(float stdDeviationX, float stdDeviat
return NS_OK; return NS_OK;
} }
void /**
nsSVGFEGaussianBlurElement::BoxBlurH(PRUint8 *aInput, PRUint8 *aOutput, * We want to speed up 1/N integer divisions --- integer division is
PRInt32 aStride, const nsRect &aRegion, * often rather slow.
PRUint32 leftLobe, PRUint32 rightLobe, * We know that our input numerators V are constrained to be <= 255*N,
const PRUint8 *prediv) * so the result of dividing by N always fits in 8 bits.
* So we can try approximating the division V/N as V*K/(2^24) (integer
* division, 32-bit multiply). Dividing by 2^24 is a simple shift so it's
* fast. The main problem is choosing a value for K; this function returns
* K's value.
*
* If the result is correct for the extrema, V=0 and V=255*N, then we'll
* be in good shape since both the original function and our approximation
* are linear. V=0 always gives 0 in both cases, no problem there.
* For V=255*N, let's choose the largest K that doesn't cause overflow
* and ensure that it gives the right answer. The constraints are
* (1) 255*N*K < 2^32
* and (2) 255*N*K >= 255*(2^24)
*
* From (1) we find the best value of K is floor((2^32 - 1)/(255*N)).
* (2) tells us when this will be valid:
* N*floor((2^32 - 1)/(255*N)) >= 2^24
* Now, floor(X) > X - 1, so (2) holds if
* N*((2^32 - 1)/(255*N) - 1) >= 2^24
* (2^32 - 1)/255 - 2^24 >= N
* N <= 65793
*
* If all that math confuses you, this should convince you:
* > perl -e 'for($N=1;(255*$N*int(0xFFFFFFFF/(255*$N)))>>24==255;++$N){}print"$N\n"'
* 66052
*
* So this is fine for all reasonable values of N. For larger values of N
* we may as well just use the same approximation and accept the fact that
* the output channel values will be a little low.
*/
static PRUint32 ComputeScaledDivisor(PRUint32 aDivisor)
{ {
PRInt32 boxSize = leftLobe + rightLobe + 1; return PR_UINT32_MAX/(255*aDivisor);
PRInt32 posStart = aRegion.x - leftLobe;
for (PRInt32 y = aRegion.y; y < aRegion.YMost(); y++) {
PRUint32 sums[4] = {0, 0, 0, 0};
PRInt32 lineIndex = aStride * y;
for (PRInt32 i = 0; i < boxSize; i++) {
PRInt32 pos = posStart + i;
pos = PR_MAX(pos, aRegion.x);
pos = PR_MIN(pos, aRegion.XMost() - 1);
PRInt32 index = lineIndex + (pos << 2);
sums[0] += aInput[index ];
sums[1] += aInput[index + 1];
sums[2] += aInput[index + 2];
sums[3] += aInput[index + 3];
}
for (PRInt32 x = aRegion.x; x < aRegion.XMost(); x++) {
PRInt32 index = lineIndex + (x << 2);
aOutput[index ] = prediv[sums[0]];
aOutput[index + 1] = prediv[sums[1]];
aOutput[index + 2] = prediv[sums[2]];
aOutput[index + 3] = prediv[sums[3]];
PRInt32 tmp = x - leftLobe;
PRInt32 last = PR_MAX(tmp, aRegion.x);
PRInt32 next = PR_MIN(tmp + boxSize, aRegion.XMost() - 1);
PRInt32 index2 = lineIndex + (next << 2);
PRInt32 index3 = lineIndex + (last << 2);
sums[0] += aInput[index2 ] - aInput[index3 ];
sums[1] += aInput[index2 + 1] - aInput[index3 + 1];
sums[2] += aInput[index2 + 2] - aInput[index3 + 2];
sums[3] += aInput[index2 + 3] - aInput[index3 + 3];
}
}
} }
void static void
nsSVGFEGaussianBlurElement::BoxBlurV(PRUint8 *aInput, PRUint8 *aOutput, BoxBlur(const PRUint8 *aInput, PRUint8 *aOutput,
PRInt32 aStride, const nsRect &aRegion, PRInt32 aStrideMinor, PRInt32 aStartMinor, PRInt32 aEndMinor,
PRUint32 topLobe, PRUint32 bottomLobe, PRUint32 aLeftLobe, PRUint32 aRightLobe)
const PRUint8 *prediv)
{ {
PRInt32 boxSize = topLobe + bottomLobe + 1; PRUint32 boxSize = aLeftLobe + aRightLobe + 1;
PRInt32 posStart = aRegion.y - topLobe; PRUint32 scaledDivisor = ComputeScaledDivisor(boxSize);
PRUint32 sums[4] = {0, 0, 0, 0};
for (PRInt32 x = aRegion.x; x < aRegion.XMost(); x++) { for (PRUint32 i=0; i < boxSize; i++) {
PRUint32 sums[4] = {0, 0, 0, 0}; PRInt32 pos = aStartMinor - aLeftLobe + i;
PRInt32 fourX = x << 2; pos = PR_MAX(pos, aStartMinor);
for (PRInt32 i = 0; i < boxSize; i++) { pos = PR_MIN(pos, aEndMinor - 1);
PRInt32 pos = posStart + i; #define SUM(j) sums[j] += aInput[aStrideMinor*pos + j];
pos = PR_MAX(pos, aRegion.y); SUM(0); SUM(1); SUM(2); SUM(3);
pos = PR_MIN(pos, aRegion.YMost() - 1); #undef SUM
PRInt32 index = aStride * pos + fourX; }
sums[0] += aInput[index ];
sums[1] += aInput[index + 1]; aOutput += aStrideMinor*aStartMinor;
sums[2] += aInput[index + 2]; if (aStartMinor + boxSize <= aEndMinor) {
sums[3] += aInput[index + 3]; const PRUint8 *lastInput = aInput + aStartMinor*aStrideMinor;
const PRUint8 *nextInput = aInput + (aStartMinor + aRightLobe + 1)*aStrideMinor;
#define OUTPUT(j) aOutput[j] = (sums[j]*scaledDivisor) >> 24;
#define SUM(j) sums[j] += nextInput[j] - lastInput[j];
for (PRInt32 minor = aStartMinor; minor < aStartMinor + aLeftLobe; minor++) {
OUTPUT(0); OUTPUT(1); OUTPUT(2); OUTPUT(3);
SUM(0); SUM(1); SUM(2); SUM(3);
nextInput += aStrideMinor;
aOutput += aStrideMinor;
}
for (PRInt32 minor = aStartMinor + aLeftLobe; minor < aEndMinor - aRightLobe - 1; minor++) {
OUTPUT(0); OUTPUT(1); OUTPUT(2); OUTPUT(3);
SUM(0); SUM(1); SUM(2); SUM(3);
lastInput += aStrideMinor;
nextInput += aStrideMinor;
aOutput += aStrideMinor;
} }
for (PRInt32 y = aRegion.y; y < aRegion.YMost(); y++) { // nextInput is now aInput + aEndMinor*aStrideMinor. Set it back to
PRInt32 index = aStride * y + fourX; // aInput + (aEndMinor - 1)*aStrideMinor so we read the last pixel in every
aOutput[index ] = prediv[sums[0]]; // iteration of the next loop.
aOutput[index + 1] = prediv[sums[1]]; nextInput -= aStrideMinor;
aOutput[index + 2] = prediv[sums[2]]; for (PRInt32 minor = aEndMinor - aRightLobe - 1; minor < aEndMinor; minor++) {
aOutput[index + 3] = prediv[sums[3]]; OUTPUT(0); OUTPUT(1); OUTPUT(2); OUTPUT(3);
SUM(0); SUM(1); SUM(2); SUM(3);
lastInput += aStrideMinor;
aOutput += aStrideMinor;
#undef SUM
}
} else {
for (PRInt32 minor = aStartMinor; minor < aEndMinor; minor++) {
PRInt32 tmp = minor - aLeftLobe;
PRInt32 last = PR_MAX(tmp, aStartMinor);
PRInt32 next = PR_MIN(tmp + boxSize, aEndMinor - 1);
PRInt32 tmp = y - topLobe; OUTPUT(0); OUTPUT(1); OUTPUT(2); OUTPUT(3);
PRInt32 last = PR_MAX(tmp, aRegion.y); #define SUM(j) sums[j] += aInput[aStrideMinor*next + j] - \
PRInt32 next = PR_MIN(tmp + boxSize, aRegion.YMost() - 1); aInput[aStrideMinor*last + j];
PRInt32 index2 = aStride * next + fourX; SUM(0); SUM(1); SUM(2); SUM(3);
PRInt32 index3 = aStride * last + fourX; aOutput += aStrideMinor;
sums[0] += aInput[index2 ] - aInput[index3 ]; #undef SUM
sums[1] += aInput[index2 + 1] - aInput[index3 + 1]; #undef OUTPUT
sums[2] += aInput[index2 + 2] - aInput[index3 + 2];
sums[3] += aInput[index2 + 3] - aInput[index3 + 3];
} }
} }
} }
PRUint8 *
nsSVGFEGaussianBlurElement::SetupPredivide(PRUint32 size) const
{
PRUint8 *tmp = new PRUint8[size * 256];
if (tmp) {
for (PRUint32 i = 0; i < 256; i++)
memset(tmp + i * size, i, size);
}
return tmp;
}
nsresult nsresult
nsSVGFEGaussianBlurElement::GetDXY(PRUint32 *aDX, PRUint32 *aDY, nsSVGFEGaussianBlurElement::GetDXY(PRUint32 *aDX, PRUint32 *aDY,
const nsSVGFilterInstance& aInstance) const nsSVGFilterInstance& aInstance)
@ -753,12 +752,11 @@ nsSVGFEGaussianBlurElement::GaussianBlur(PRUint8 *aInput, PRUint8 *aOutput,
nsSVGFilterResource *aFilterResource, nsSVGFilterResource *aFilterResource,
PRUint32 aDX, PRUint32 aDY) PRUint32 aDX, PRUint32 aDY)
{ {
NS_ASSERTION(aDX > 0 && aDY > 0, "Invalid stdDeviation!");
nsAutoArrayPtr<PRUint8> tmp(new PRUint8[aFilterResource->GetDataSize()]); nsAutoArrayPtr<PRUint8> tmp(new PRUint8[aFilterResource->GetDataSize()]);
if (!tmp) if (!tmp)
return; return;
memset(tmp, 0, aFilterResource->GetDataSize()); memset(tmp, 0, aFilterResource->GetDataSize());
nsRect rect = aFilterResource->GetSurfaceRect(); nsRect rect = aFilterResource->GetSurfaceRect();
#ifdef DEBUG_tor #ifdef DEBUG_tor
fprintf(stderr, "FILTER GAUSS rect: %d,%d %dx%d\n", fprintf(stderr, "FILTER GAUSS rect: %d,%d %dx%d\n",
@ -767,53 +765,29 @@ nsSVGFEGaussianBlurElement::GaussianBlur(PRUint8 *aInput, PRUint8 *aOutput,
PRUint32 stride = aFilterResource->GetDataStride(); PRUint32 stride = aFilterResource->GetDataStride();
if (aDX & 1) { if (aDX == 0) {
// odd aFilterResource->CopyImageSubregion(tmp, aInput);
nsAutoArrayPtr<PRUint8> prediv(SetupPredivide(2 * (aDX / 2) + 1));
if (!prediv)
return;
BoxBlurH(aInput, tmp, stride, rect, aDX/2, aDX/2, prediv);
BoxBlurH(tmp, aOutput, stride, rect, aDX/2, aDX/2, prediv);
BoxBlurH(aOutput, tmp, stride, rect, aDX/2, aDX/2, prediv);
} else { } else {
// even PRInt32 longLobe = aDX/2;
if (aDX == 0) { PRInt32 shortLobe = (aDX & 1) ? longLobe : longLobe - 1;
aFilterResource->CopyImageSubregion(tmp, aInput); for (PRInt32 major = rect.y; major < rect.YMost(); ++major) {
} else { PRInt32 ms = major*stride;
nsAutoArrayPtr<PRUint8> prediv(SetupPredivide(2 * (aDX / 2) + 1)); BoxBlur(aInput + ms, tmp + ms, 4, rect.x, rect.XMost(), longLobe, shortLobe);
nsAutoArrayPtr<PRUint8> prediv2(SetupPredivide(2 * (aDX / 2))); BoxBlur(tmp + ms, aOutput + ms, 4, rect.x, rect.XMost(), shortLobe, longLobe);
if (!prediv || !prediv2) BoxBlur(aOutput + ms, tmp + ms, 4, rect.x, rect.XMost(), longLobe, longLobe);
return;
BoxBlurH(aInput, tmp, stride, rect, aDX/2, aDX/2 - 1, prediv2);
BoxBlurH(tmp, aOutput, stride, rect, aDX/2 - 1, aDX/2, prediv2);
BoxBlurH(aOutput, tmp, stride, rect, aDX/2, aDX/2, prediv);
} }
} }
if (aDY & 1) { if (aDY == 0) {
// odd aFilterResource->CopyImageSubregion(aOutput, tmp);
nsAutoArrayPtr<PRUint8> prediv(SetupPredivide(2 * (aDY / 2) + 1));
if (!prediv)
return;
BoxBlurV(tmp, aOutput, stride, rect, aDY/2, aDY/2, prediv);
BoxBlurV(aOutput, tmp, stride, rect, aDY/2, aDY/2, prediv);
BoxBlurV(tmp, aOutput, stride, rect, aDY/2, aDY/2, prediv);
} else { } else {
// even PRInt32 longLobe = aDY/2;
if (aDY == 0) { PRInt32 shortLobe = (aDY & 1) ? longLobe : longLobe - 1;
aFilterResource->CopyImageSubregion(aOutput, tmp); for (PRInt32 major = rect.x; major < rect.XMost(); ++major) {
} else { PRInt32 ms = major*4;
nsAutoArrayPtr<PRUint8> prediv(SetupPredivide(2 * (aDY / 2) + 1)); BoxBlur(tmp + ms, aOutput + ms, stride, rect.y, rect.YMost(), longLobe, shortLobe);
nsAutoArrayPtr<PRUint8> prediv2(SetupPredivide(2 * (aDY / 2))); BoxBlur(aOutput + ms, tmp + ms, stride, rect.y, rect.YMost(), shortLobe, longLobe);
if (!prediv || !prediv2) BoxBlur(tmp + ms, aOutput + ms, stride, rect.y, rect.YMost(), longLobe, longLobe);
return;
BoxBlurV(tmp, aOutput, stride, rect, aDY/2, aDY/2 - 1, prediv2);
BoxBlurV(aOutput, tmp, stride, rect, aDY/2 - 1, aDY/2, prediv2);
BoxBlurV(tmp, aOutput, stride, rect, aDY/2, aDY/2, prediv);
} }
} }
} }

View File

@ -70,13 +70,13 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsSVGUseElement,
nsAutoScriptBlocker scriptBlocker; nsAutoScriptBlocker scriptBlocker;
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOriginal) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOriginal)
tmp->DestroyAnonymousContent(); tmp->DestroyAnonymousContent();
tmp->RemoveListener(); tmp->UnlinkSource();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsSVGUseElement, NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsSVGUseElement,
nsSVGUseElementBase) nsSVGUseElementBase)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOriginal) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOriginal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mClone) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mClone)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSourceContent) tmp->mSource.Traverse(&cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_ADDREF_INHERITED(nsSVGUseElement,nsSVGUseElementBase) NS_IMPL_ADDREF_INHERITED(nsSVGUseElement,nsSVGUseElementBase)
@ -99,13 +99,13 @@ NS_INTERFACE_MAP_END_INHERITING(nsSVGUseElementBase)
// Implementation // Implementation
nsSVGUseElement::nsSVGUseElement(nsINodeInfo *aNodeInfo) nsSVGUseElement::nsSVGUseElement(nsINodeInfo *aNodeInfo)
: nsSVGUseElementBase(aNodeInfo) : nsSVGUseElementBase(aNodeInfo), mSource(this)
{ {
} }
nsSVGUseElement::~nsSVGUseElement() nsSVGUseElement::~nsSVGUseElement()
{ {
RemoveListener(); UnlinkSource();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -232,7 +232,7 @@ nsSVGUseElement::ContentRemoved(nsIDocument *aDocument,
void void
nsSVGUseElement::NodeWillBeDestroyed(const nsINode *aNode) nsSVGUseElement::NodeWillBeDestroyed(const nsINode *aNode)
{ {
RemoveListener(); UnlinkSource();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -247,17 +247,15 @@ nsSVGUseElement::CreateAnonymousContent()
mClone = nsnull; mClone = nsnull;
nsCOMPtr<nsIContent> targetContent = LookupHref(); if (mSource.get()) {
mSource.get()->RemoveMutationObserver(this);
}
LookupHref();
nsIContent* targetContent = mSource.get();
if (!targetContent) if (!targetContent)
return nsnull; return nsnull;
PRBool needAddObserver = PR_FALSE;
if (mSourceContent != targetContent) {
RemoveListener();
needAddObserver = PR_TRUE;
}
// make sure target is valid type for <use> // make sure target is valid type for <use>
// QIable nsSVGGraphicsElement would eliminate enumerating all elements // QIable nsSVGGraphicsElement would eliminate enumerating all elements
nsIAtom *tag = targetContent->Tag(); nsIAtom *tag = targetContent->Tag();
@ -377,10 +375,7 @@ nsSVGUseElement::CreateAnonymousContent()
} }
} }
if (needAddObserver) { targetContent->AddMutationObserver(this);
targetContent->AddMutationObserver(this);
}
mSourceContent = targetContent;
mClone = newcontent; mClone = newcontent;
return mClone; return mClone;
} }
@ -415,18 +410,18 @@ nsSVGUseElement::SyncWidthHeight(PRUint8 aAttrEnum)
} }
} }
nsIContent * void
nsSVGUseElement::LookupHref() nsSVGUseElement::LookupHref()
{ {
const nsString &href = mStringAttributes[HREF].GetAnimValue(); const nsString &href = mStringAttributes[HREF].GetAnimValue();
if (href.IsEmpty()) if (href.IsEmpty())
return nsnull; return;
nsCOMPtr<nsIURI> targetURI, baseURI = GetBaseURI(); nsCOMPtr<nsIURI> targetURI, baseURI = GetBaseURI();
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), href, nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), href,
GetCurrentDoc(), baseURI); GetCurrentDoc(), baseURI);
return nsContentUtils::GetReferencedElement(targetURI, this); mSource.Reset(this, targetURI);
} }
void void
@ -436,16 +431,16 @@ nsSVGUseElement::TriggerReclone()
if (!doc) return; if (!doc) return;
nsIPresShell *presShell = doc->GetPrimaryShell(); nsIPresShell *presShell = doc->GetPrimaryShell();
if (!presShell) return; if (!presShell) return;
presShell->RecreateFramesFor(this); presShell->PostRecreateFramesFor(this);
} }
void void
nsSVGUseElement::RemoveListener() nsSVGUseElement::UnlinkSource()
{ {
if (mSourceContent) { if (mSource.get()) {
mSourceContent->RemoveMutationObserver(this); mSource.get()->RemoveMutationObserver(this);
mSourceContent = nsnull;
} }
mSource.Unlink();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -45,12 +45,14 @@
#include "nsSVGLength2.h" #include "nsSVGLength2.h"
#include "nsSVGString.h" #include "nsSVGString.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsReferencedElement.h"
class nsIContent; class nsIContent;
class nsINodeInfo; class nsINodeInfo;
#define NS_SVG_USE_ELEMENT_IMPL_CID \ #define NS_SVG_USE_ELEMENT_IMPL_CID \
{ 0xa95c13d3, 0xc193, 0x465f, {0x81, 0xf0, 0x02, 0x6d, 0x67, 0x05, 0x54, 0x58 } } { 0x55fb86fe, 0xd81f, 0x4ae4, \
{ 0x80, 0x3f, 0xeb, 0x90, 0xfe, 0xe0, 0x7a, 0xe9 } }
nsresult nsresult
NS_NewSVGSVGElement(nsIContent **aResult, nsINodeInfo *aNodeInfo); NS_NewSVGSVGElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
@ -104,14 +106,25 @@ public:
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const; NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
protected: protected:
class SourceReference : public nsReferencedElement {
public:
SourceReference(nsSVGUseElement* aContainer) : mContainer(aContainer) {}
protected:
virtual void ContentChanged(nsIContent* aFrom, nsIContent* aTo) {
nsReferencedElement::ContentChanged(aFrom, aTo);
mContainer->TriggerReclone();
}
private:
nsSVGUseElement* mContainer;
};
virtual LengthAttributesInfo GetLengthInfo(); virtual LengthAttributesInfo GetLengthInfo();
virtual StringAttributesInfo GetStringInfo(); virtual StringAttributesInfo GetStringInfo();
void SyncWidthHeight(PRUint8 aAttrEnum); void SyncWidthHeight(PRUint8 aAttrEnum);
nsIContent *LookupHref(); void LookupHref();
void TriggerReclone(); void TriggerReclone();
void RemoveListener(); void UnlinkSource();
enum { X, Y, WIDTH, HEIGHT }; enum { X, Y, WIDTH, HEIGHT };
nsSVGLength2 mLengthAttributes[4]; nsSVGLength2 mLengthAttributes[4];
@ -123,7 +136,7 @@ protected:
nsCOMPtr<nsIContent> mOriginal; // if we've been cloned, our "real" copy nsCOMPtr<nsIContent> mOriginal; // if we've been cloned, our "real" copy
nsCOMPtr<nsIContent> mClone; // cloned tree nsCOMPtr<nsIContent> mClone; // cloned tree
nsCOMPtr<nsIContent> mSourceContent; // observed element SourceReference mSource; // observed element
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsSVGUseElement, NS_SVG_USE_ELEMENT_IMPL_CID) NS_DEFINE_STATIC_IID_ACCESSOR(nsSVGUseElement, NS_SVG_USE_ELEMENT_IMPL_CID)

View File

@ -87,7 +87,7 @@ private:
// Class that will automatically call WillModify and DidModify in its ctor // Class that will automatically call WillModify and DidModify in its ctor
// and dtor respectively (for functions that have multiple exit points). // and dtor respectively (for functions that have multiple exit points).
class nsSVGValueAutoNotifier class NS_STACK_CLASS nsSVGValueAutoNotifier
{ {
public: public:
nsSVGValueAutoNotifier(nsSVGValue* aVal, nsSVGValueAutoNotifier(nsSVGValue* aVal,

View File

@ -1740,8 +1740,11 @@ nsXULDocument::RemoveSubtreeFromDocument(nsIContent* aElement)
return rv; return rv;
} }
// 2. Remove the element from the resource-to-element map // 2. Remove the element from the resource-to-element map.
// Also remove it from the id map, since we added it in
// AddElementToDocumentPre().
RemoveElementFromRefMap(aElement); RemoveElementFromRefMap(aElement);
RemoveFromIdTable(aElement);
// 3. If the element is a 'command updater', then remove the // 3. If the element is a 'command updater', then remove the
// element from the document's command dispatcher. // element from the document's command dispatcher.

View File

@ -1580,7 +1580,7 @@ nsXULTemplateBuilder::ParseAttribute(const nsAString& aAttributeValue,
} }
struct SubstituteTextClosure { struct NS_STACK_CLASS SubstituteTextClosure {
SubstituteTextClosure(nsIXULTemplateResult* aResult, nsAString& aString) SubstituteTextClosure(nsIXULTemplateResult* aResult, nsAString& aString)
: result(aResult), str(aString) {} : result(aResult), str(aString) {}

View File

@ -53,7 +53,7 @@
// http://www.mozilla.org/mailnews/arch/mork/grammar.txt // http://www.mozilla.org/mailnews/arch/mork/grammar.txt
// http://www.jwz.org/hacks/mork.pl // http://www.jwz.org/hacks/mork.pl
class nsMorkReader class NS_STACK_CLASS nsMorkReader
{ {
public: public:
// This string type has built-in storage for the hex string representation // This string type has built-in storage for the hex string representation

View File

@ -8440,7 +8440,7 @@ nsDocShell::WalkHistoryEntries(nsISHEntry *aRootEntry,
} }
// callback data for WalkHistoryEntries // callback data for WalkHistoryEntries
struct CloneAndReplaceData struct NS_STACK_CLASS CloneAndReplaceData
{ {
CloneAndReplaceData(PRUint32 aCloneID, nsISHEntry *aReplaceEntry, CloneAndReplaceData(PRUint32 aCloneID, nsISHEntry *aReplaceEntry,
nsISHEntry *aDestTreeParent) nsISHEntry *aDestTreeParent)

View File

@ -90,7 +90,7 @@ public:
NS_DEFINE_STATIC_IID_ACCESSOR(nsIFocusController, NS_IFOCUSCONTROLLER_IID) NS_DEFINE_STATIC_IID_ACCESSOR(nsIFocusController, NS_IFOCUSCONTROLLER_IID)
class nsFocusSuppressor { class NS_STACK_CLASS nsFocusSuppressor {
public: public:
~nsFocusSuppressor() ~nsFocusSuppressor()
{ {
@ -128,7 +128,7 @@ private:
const char *mReason; const char *mReason;
}; };
class nsFocusScrollSuppressor class NS_STACK_CLASS nsFocusScrollSuppressor
{ {
public: public:
nsFocusScrollSuppressor(nsIFocusController* aController = nsnull) nsFocusScrollSuppressor(nsIFocusController* aController = nsnull)

View File

@ -47,7 +47,7 @@
interface nsIDOMElement; interface nsIDOMElement;
[scriptable, uuid(993da427-2ac3-4766-8485-21a236d258e4)] [scriptable, uuid(ef136142-9925-45f4-a3e4-6f0d275c6aa8)]
interface nsIDOMWindowUtils : nsISupports { interface nsIDOMWindowUtils : nsISupports {
/** /**
@ -160,6 +160,15 @@ interface nsIDOMWindowUtils : nsISupports {
in AString aCharacters, in AString aCharacters,
in AString aUnmodifiedCharacters); in AString aUnmodifiedCharacters);
/**
* See nsIWidget::ActivateNativeMenuItemAt
*
* Cannot be accessed from unprivileged context (not content-accessible)
* Will throw a DOM security error if called without UniversalXPConnect
* privileges.
*/
void activateNativeMenuItemAt(in AString indexString);
/** /**
* Focus the element aElement. The element should be in the same document * Focus the element aElement. The element should be in the same document
* that the window is displaying. Pass null to blur the element, if any, * that the window is displaying. Pass null to blur the element, if any,

View File

@ -46,7 +46,7 @@
// functions and a fully inline implementation should keep the cost down. // functions and a fully inline implementation should keep the cost down.
// [Note that a fully inline implementation is necessary for use by other // [Note that a fully inline implementation is necessary for use by other
// languages, which do not link against the layout component module] // languages, which do not link against the layout component module]
class nsScriptObjectHolder { class NS_STACK_CLASS nsScriptObjectHolder {
public: public:
// A constructor that will cause a reference to |ctx| to be stored in // A constructor that will cause a reference to |ctx| to be stored in
// the object. Only use for short-lived object holders. // the object. Only use for short-lived object holders.

View File

@ -4510,10 +4510,14 @@ nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
const char *name = JS_GET_CLASS(cx, JSVAL_TO_OBJECT(*vp))->name; const char *name = JS_GET_CLASS(cx, JSVAL_TO_OBJECT(*vp))->name;
// The list of Window class names here need to be kept in sync // The list of Window class names here need to be kept in sync
// with the actual class names! // with the actual class names! The class name
// XPCCrossOriginWrapper needs to be handled here too as XOWs
// define child frame names with a XOW as the value, and thus
// we'll need to get through here with XOWs class name too.
if ((*name == 'W' && strcmp(name, "Window") == 0) || if ((*name == 'W' && strcmp(name, "Window") == 0) ||
(*name == 'C' && strcmp(name, "ChromeWindow") == 0) || (*name == 'C' && strcmp(name, "ChromeWindow") == 0) ||
(*name == 'M' && strcmp(name, "ModalContentWindow") == 0)) { (*name == 'M' && strcmp(name, "ModalContentWindow") == 0) ||
(*name == 'X' && strcmp(name, "XPCCrossOriginWrapper") == 0)) {
nsCOMPtr<nsIXPConnectWrappedNative> vpwrapper; nsCOMPtr<nsIXPConnectWrappedNative> vpwrapper;
sXPConnect->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(*vp), sXPConnect->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(*vp),
getter_AddRefs(vpwrapper)); getter_AddRefs(vpwrapper));

View File

@ -308,6 +308,22 @@ nsDOMWindowUtils::SendNativeKeyEvent(PRInt32 aNativeKeyboardLayout,
aModifiers, aCharacters, aUnmodifiedCharacters); aModifiers, aCharacters, aUnmodifiedCharacters);
} }
NS_IMETHODIMP
nsDOMWindowUtils::ActivateNativeMenuItemAt(const nsAString& indexString)
{
PRBool hasCap = PR_FALSE;
if (NS_FAILED(nsContentUtils::GetSecurityManager()->IsCapabilityEnabled("UniversalXPConnect", &hasCap))
|| !hasCap)
return NS_ERROR_DOM_SECURITY_ERR;
// get the widget to send the event to
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
return widget->ActivateNativeMenuItemAt(indexString);
}
nsIWidget* nsIWidget*
nsDOMWindowUtils::GetWidget() nsDOMWindowUtils::GetWidget()
{ {

View File

@ -275,13 +275,14 @@ nsDOMOfflineResourceList::Disconnect()
NS_IMETHODIMP NS_IMETHODIMP
nsDOMOfflineResourceList::GetLength(PRUint32 *aLength) nsDOMOfflineResourceList::GetLength(PRUint32 *aLength)
{ {
if (!mManifestURI) {
*aLength = 0;
return NS_OK;
}
nsresult rv = Init(); nsresult rv = Init();
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
rv = CacheKeys(); rv = CacheKeys();
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -295,10 +296,6 @@ nsDOMOfflineResourceList::Item(PRUint32 aIndex, nsAString& aURI)
nsresult rv = Init(); nsresult rv = Init();
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
SetDOMStringToNull(aURI); SetDOMStringToNull(aURI);
rv = CacheKeys(); rv = CacheKeys();

View File

@ -50,6 +50,7 @@ _TEST_FILES = \
test_badManifestMagic.html \ test_badManifestMagic.html \
test_badManifestMime.html \ test_badManifestMime.html \
test_missingFile.html \ test_missingFile.html \
test_noManifest.html \
test_simpleManifest.html \ test_simpleManifest.html \
test_identicalManifest.html \ test_identicalManifest.html \
test_changingManifest.html \ test_changingManifest.html \

View File

@ -0,0 +1,44 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>bad manifest content type</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript">
function expectInvalidState(fn, desc) {
var gotInvalidState = false;
try {
fn();
} catch(e) {
if (e.code == DOMException.INVALID_STATE_ERR) {
gotInvalidState = true;
}
}
ok(gotInvalidState, desc);
}
is(typeof(applicationCache), "object");
is(applicationCache.length, 0, "applicationCache.length should be 0");
is(applicationCache.status, 0, "applicationCache.status should be 0 (UNCACHED)");
expectInvalidState(function() { applicationCache.add("http://localhost:8888/MochiKit/packed.js"); },
"applicationCache.add should throw INVALID_STATE_ERR");
expectInvalidState(function() { applicationCache.remove("http://localhost:8888/MochiKit/packed.js"); },
"applicationCache.remove should throw INVALID_STATE_ERR");
expectInvalidState(function() { applicationCache.update(); },
"applicationCache.update should throw INVALID_STATE_ERR");
expectInvalidState(function() { applicationCache.swapCache(); },
"applicationCache.update should throw INVALID_STATE_ERR");
</script>
</head>
<body>
</body>
</html>

View File

@ -77,6 +77,8 @@ _TEST_FILES = \
test_bug430276.html \ test_bug430276.html \
iframe_bug430276.html \ iframe_bug430276.html \
iframe_bug430276-2.html \ iframe_bug430276-2.html \
test_bug440572.html \
iframe_bug440572.html \
$(NULL) $(NULL)
libs:: $(_TEST_FILES) libs:: $(_TEST_FILES)

View File

@ -0,0 +1,17 @@
<html>
<body>
<script>
var success = 0;
try {
parent[name].success = 1;
} catch (e) {
parent.postMessage(e, "http://localhost:8888");
}
parent.postMessage(success ? "success" : "failure", "http://localhost:8888");
</script>
<p>Move on, nothing to see here...</p>
</body>
</html>

View File

@ -0,0 +1,48 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=440572
-->
<head>
<title>Test for Bug 440572</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body onload="runtests()">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=440572">Mozilla Bug 440572</a>
<script class="testbody" type="text/javascript">
/** Test for Bug 440572 **/
var messages = [];
function receiveMessage(e)
{
is(e.origin, "http://example.org", "wrong sender!");
messages.push(e.data);
}
window.addEventListener("message", receiveMessage, false);
function runtests()
{
for (i in messages) {
is(messages[i], "success", "test in frame failed.");
}
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
<br>
<iframe name="test" src="http://example.org:80/tests/dom/tests/mochitest/bugs/iframe_bug440572.html"></iframe>
<br>
<iframe name="content" src="http://example.org:80/tests/dom/tests/mochitest/bugs/iframe_bug440572.html"></iframe>
<br>
<iframe name="dump" src="http://example.org:80/tests/dom/tests/mochitest/bugs/iframe_bug440572.html"></iframe>
</body>
</html>

View File

@ -56,7 +56,7 @@ class nsPlaintextEditor;
* stack based helper class for batching a collection of txns inside a * stack based helper class for batching a collection of txns inside a
* placeholder txn. * placeholder txn.
*/ */
class nsAutoPlaceHolderBatch class NS_STACK_CLASS nsAutoPlaceHolderBatch
{ {
private: private:
nsCOMPtr<nsIEditor> mEd; nsCOMPtr<nsIEditor> mEd;
@ -82,7 +82,7 @@ class nsAutoEditBatch : public nsAutoPlaceHolderBatch
* stack based helper class for saving/restoring selection. Note that this * stack based helper class for saving/restoring selection. Note that this
* assumes that the nodes involved are still around afterwards! * assumes that the nodes involved are still around afterwards!
*/ */
class nsAutoSelectionReset class NS_STACK_CLASS nsAutoSelectionReset
{ {
private: private:
/** ref-counted reference to the selection that we are supposed to restore */ /** ref-counted reference to the selection that we are supposed to restore */
@ -103,7 +103,7 @@ class nsAutoSelectionReset
/*************************************************************************** /***************************************************************************
* stack based helper class for StartOperation()/EndOperation() sandwich * stack based helper class for StartOperation()/EndOperation() sandwich
*/ */
class nsAutoRules class NS_STACK_CLASS nsAutoRules
{ {
public: public:
@ -134,7 +134,7 @@ class nsAutoRules
* stack based helper class for turning off active selection adjustment * stack based helper class for turning off active selection adjustment
* by low level transactions * by low level transactions
*/ */
class nsAutoTxnsConserveSelection class NS_STACK_CLASS nsAutoTxnsConserveSelection
{ {
public: public:
@ -163,7 +163,7 @@ class nsAutoTxnsConserveSelection
/*************************************************************************** /***************************************************************************
* stack based helper class for batching reflow and paint requests. * stack based helper class for batching reflow and paint requests.
*/ */
class nsAutoUpdateViewBatch class NS_STACK_CLASS nsAutoUpdateViewBatch
{ {
public: public:
@ -201,7 +201,7 @@ class nsBoolDomIterFunctor
virtual PRBool operator()(nsIDOMNode* aNode)=0; virtual PRBool operator()(nsIDOMNode* aNode)=0;
}; };
class nsDOMIterator class NS_STACK_CLASS nsDOMIterator
{ {
public: public:
nsDOMIterator(); nsDOMIterator();
@ -239,7 +239,7 @@ class nsTrivialFunctor : public nsBoolDomIterFunctor
/****************************************************************************** /******************************************************************************
* general dom point utility struct * general dom point utility struct
*****************************************************************************/ *****************************************************************************/
struct DOMPoint struct NS_STACK_CLASS DOMPoint
{ {
nsCOMPtr<nsIDOMNode> node; nsCOMPtr<nsIDOMNode> node;
PRInt32 offset; PRInt32 offset;

View File

@ -135,7 +135,7 @@ class nsRangeUpdater
* preservation of dom points across editor actions * preservation of dom points across editor actions
*/ */
class nsAutoTrackDOMPoint class NS_STACK_CLASS nsAutoTrackDOMPoint
{ {
private: private:
nsRangeUpdater &mRU; nsRangeUpdater &mRU;
@ -170,7 +170,7 @@ class nsAutoTrackDOMPoint
* Will/DidReplaceContainer() * Will/DidReplaceContainer()
*/ */
class nsAutoReplaceContainerSelNotify class NS_STACK_CLASS nsAutoReplaceContainerSelNotify
{ {
private: private:
nsRangeUpdater &mRU; nsRangeUpdater &mRU;
@ -198,7 +198,7 @@ class nsAutoReplaceContainerSelNotify
* Will/DidRemoveContainer() * Will/DidRemoveContainer()
*/ */
class nsAutoRemoveContainerSelNotify class NS_STACK_CLASS nsAutoRemoveContainerSelNotify
{ {
private: private:
nsRangeUpdater &mRU; nsRangeUpdater &mRU;
@ -233,7 +233,7 @@ class nsAutoRemoveContainerSelNotify
* Will/DidInsertContainer() * Will/DidInsertContainer()
*/ */
class nsAutoInsertContainerSelNotify class NS_STACK_CLASS nsAutoInsertContainerSelNotify
{ {
private: private:
nsRangeUpdater &mRU; nsRangeUpdater &mRU;
@ -257,7 +257,7 @@ class nsAutoInsertContainerSelNotify
* Will/DidMoveNode() * Will/DidMoveNode()
*/ */
class nsAutoMoveNodeSelNotify class NS_STACK_CLASS nsAutoMoveNodeSelNotify
{ {
private: private:
nsRangeUpdater &mRU; nsRangeUpdater &mRU;

View File

@ -69,7 +69,7 @@
/*************************************************************************** /***************************************************************************
* stack based helper class for restoring selection after table edit * stack based helper class for restoring selection after table edit
*/ */
class nsSetSelectionAfterTableEdit class NS_STACK_CLASS nsSetSelectionAfterTableEdit
{ {
private: private:
nsCOMPtr<nsITableEditor> mEd; nsCOMPtr<nsITableEditor> mEd;
@ -99,7 +99,7 @@ class nsSetSelectionAfterTableEdit
}; };
// Stack-class to turn on/off selection batching for table selection // Stack-class to turn on/off selection batching for table selection
class nsSelectionBatcher class NS_STACK_CLASS nsSelectionBatcher
{ {
private: private:
nsCOMPtr<nsISelectionPrivate> mSelection; nsCOMPtr<nsISelectionPrivate> mSelection;

View File

@ -67,7 +67,7 @@ class nsHTMLEditor;
// will only render as one space (in non-preformatted stlye html), yet both // will only render as one space (in non-preformatted stlye html), yet both
// spaces count as NormalWS. Together, they render as the one visible space. // spaces count as NormalWS. Together, they render as the one visible space.
class nsWSRunObject class NS_STACK_CLASS nsWSRunObject
{ {
public: public:
@ -226,7 +226,7 @@ class nsWSRunObject
// always within a textnode that is one of the nodes stored in the list // always within a textnode that is one of the nodes stored in the list
// in the wsRunObject. For convenience, the character at that point is also // in the wsRunObject. For convenience, the character at that point is also
// stored in the struct. // stored in the struct.
struct WSPoint struct NS_STACK_CLASS WSPoint
{ {
nsCOMPtr<nsIContent> mTextNode; nsCOMPtr<nsIContent> mTextNode;
PRInt16 mOffset; PRInt16 mOffset;

View File

@ -2356,7 +2356,7 @@ public:
} }
}; };
struct FixRedirectData struct NS_STACK_CLASS FixRedirectData
{ {
nsCOMPtr<nsIChannel> mNewChannel; nsCOMPtr<nsIChannel> mNewChannel;
nsCOMPtr<nsIURI> mOriginalURI; nsCOMPtr<nsIURI> mOriginalURI;

View File

@ -268,7 +268,7 @@ void nsWatcherWindowEnumerator::WindowRemoved(nsWatcherWindowEntry *inInfo) {
********************** JSContextAutoPopper ********************* ********************** JSContextAutoPopper *********************
****************************************************************/ ****************************************************************/
class JSContextAutoPopper { class NS_STACK_CLASS JSContextAutoPopper {
public: public:
JSContextAutoPopper(); JSContextAutoPopper();
~JSContextAutoPopper(); ~JSContextAutoPopper();

View File

@ -188,6 +188,11 @@ _cairo_quartz_font_face_scaled_font_create (void *abstract_face,
quartz_CGFontMetrics *m; quartz_CGFontMetrics *m;
m = CGFontGetHMetricsPtr (font_face->cgFont); m = CGFontGetHMetricsPtr (font_face->cgFont);
if (!m) {
status = _cairo_error(CAIRO_STATUS_NULL_POINTER);
goto FINISH;
}
fs_metrics.ascent = (m->ascent / ems); fs_metrics.ascent = (m->ascent / ems);
fs_metrics.descent = - (m->descent / ems); fs_metrics.descent = - (m->descent / ems);
fs_metrics.height = fs_metrics.ascent + fs_metrics.descent + (m->leading / ems); fs_metrics.height = fs_metrics.ascent + fs_metrics.descent + (m->leading / ems);

View File

@ -85,6 +85,7 @@ public:
PRBool TestCharacterMap(PRUint32 aCh); PRBool TestCharacterMap(PRUint32 aCh);
MacOSFontEntry* GetFontEntry(); MacOSFontEntry* GetFontEntry();
PRBool Valid() { return mValid; }
protected: protected:
const gfxFontStyle *mFontStyle; const gfxFontStyle *mFontStyle;
@ -93,6 +94,7 @@ protected:
nsRefPtr<MacOSFontEntry> mFontEntry; nsRefPtr<MacOSFontEntry> mFontEntry;
PRBool mValid;
PRBool mHasMirroring; PRBool mHasMirroring;
PRBool mHasMirroringLookedUp; PRBool mHasMirroringLookedUp;

View File

@ -56,8 +56,8 @@ public:
already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size, already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size,
gfxASurface::gfxImageFormat imageFormat); gfxASurface::gfxImageFormat imageFormat);
already_AddRefed<gfxASurface> gfxPlatformMac::OptimizeImage(gfxImageSurface *aSurface, already_AddRefed<gfxASurface> OptimizeImage(gfxImageSurface *aSurface,
gfxASurface::gfxImageFormat format); gfxASurface::gfxImageFormat format);
nsresult ResolveFontName(const nsAString& aFontName, nsresult ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback, FontResolverCallback aCallback,
@ -84,8 +84,8 @@ public:
PRUint32 GetAntiAliasingThreshold() { return mFontAntiAliasingThreshold; } PRUint32 GetAntiAliasingThreshold() { return mFontAntiAliasingThreshold; }
private: private:
void gfxPlatformMac::AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], PRUint32 &aLen, void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], PRUint32 &aLen,
eFontPrefLang aCharLang, eFontPrefLang aPageLang); eFontPrefLang aCharLang, eFontPrefLang aPageLang);
virtual cmsHPROFILE GetPlatformCMSOutputProfile(); virtual cmsHPROFILE GetPlatformCMSOutputProfile();

View File

@ -94,7 +94,7 @@ gfxAtsuiFont::gfxAtsuiFont(MacOSFontEntry *aFontEntry,
const gfxFontStyle *fontStyle, PRBool aNeedsBold) const gfxFontStyle *fontStyle, PRBool aNeedsBold)
: gfxFont(aFontEntry->Name(), fontStyle), : gfxFont(aFontEntry->Name(), fontStyle),
mFontStyle(fontStyle), mATSUStyle(nsnull), mFontEntry(aFontEntry), mFontStyle(fontStyle), mATSUStyle(nsnull), mFontEntry(aFontEntry),
mHasMirroring(PR_FALSE), mHasMirroringLookedUp(PR_FALSE), mAdjustedSize(0.0f) mValid(PR_TRUE), mHasMirroring(PR_FALSE), mHasMirroringLookedUp(PR_FALSE), mAdjustedSize(0.0f)
{ {
ATSUFontID fontID = mFontEntry->GetFontID(); ATSUFontID fontID = mFontEntry->GetFontID();
ATSFontRef fontRef = FMGetATSFontRefFromFont(fontID); ATSFontRef fontRef = FMGetATSFontRefFromFont(fontID);
@ -149,8 +149,17 @@ gfxAtsuiFont::gfxAtsuiFont(MacOSFontEntry *aFontEntry,
mScaledFont = cairo_scaled_font_create(mFontFace, &sizeMatrix, &ctm, fontOptions); mScaledFont = cairo_scaled_font_create(mFontFace, &sizeMatrix, &ctm, fontOptions);
cairo_font_options_destroy(fontOptions); cairo_font_options_destroy(fontOptions);
NS_ASSERTION(cairo_scaled_font_status(mScaledFont) == CAIRO_STATUS_SUCCESS,
"Failed to create scaled font"); cairo_status_t cairoerr = cairo_scaled_font_status(mScaledFont);
if (cairoerr != CAIRO_STATUS_SUCCESS) {
mValid = PR_FALSE;
#ifdef DEBUG
char warnBuf[1024];
sprintf(warnBuf, "Failed to create scaled font: %s status: %d", NS_ConvertUTF16toUTF8(mName).get(), cairoerr);
NS_WARNING(warnBuf);
#endif
}
} }
@ -415,6 +424,7 @@ gfxAtsuiFont::HasMirroringInfo()
} }
PRBool gfxAtsuiFont::TestCharacterMap(PRUint32 aCh) { PRBool gfxAtsuiFont::TestCharacterMap(PRUint32 aCh) {
if (!mValid) return PR_FALSE;
return mFontEntry->TestCharacterMap(aCh); return mFontEntry->TestCharacterMap(aCh);
} }
@ -436,9 +446,14 @@ GetOrMakeFont(MacOSFontEntry *aFontEntry, const gfxFontStyle *aStyle, PRBool aNe
// the font entry name is the psname, not the family name // the font entry name is the psname, not the family name
nsRefPtr<gfxFont> font = gfxFontCache::GetCache()->Lookup(aFontEntry->Name(), aStyle); nsRefPtr<gfxFont> font = gfxFontCache::GetCache()->Lookup(aFontEntry->Name(), aStyle);
if (!font) { if (!font) {
font = new gfxAtsuiFont(aFontEntry, aStyle, aNeedsBold); gfxAtsuiFont *newFont = new gfxAtsuiFont(aFontEntry, aStyle, aNeedsBold);
if (!font) if (!newFont)
return nsnull; return nsnull;
if (!newFont->Valid()) {
delete newFont;
return nsnull;
}
font = newFont;
gfxFontCache::GetCache()->AddNew(font); gfxFontCache::GetCache()->AddNew(font);
} }
gfxFont *f = nsnull; gfxFont *f = nsnull;
@ -835,6 +850,7 @@ gfxAtsuiFontGroup::WhichPrefFontSupportsChar(PRUint32 aCh)
// if ch in cmap, create and return a gfxFont // if ch in cmap, create and return a gfxFont
if (fe && fe->TestCharacterMap(aCh)) { if (fe && fe->TestCharacterMap(aCh)) {
nsRefPtr<gfxAtsuiFont> prefFont = GetOrMakeFont(fe, &mStyle, needsBold); nsRefPtr<gfxAtsuiFont> prefFont = GetOrMakeFont(fe, &mStyle, needsBold);
if (!prefFont) continue;
mLastPrefFamily = family; mLastPrefFamily = family;
mLastPrefFont = prefFont; mLastPrefFont = prefFont;
mLastPrefLang = charLang; mLastPrefLang = charLang;

View File

@ -54,9 +54,7 @@ public:
virtual ~nsScriptableUnicodeConverter(); virtual ~nsScriptableUnicodeConverter();
protected: protected:
// charsets are ALWAYS very short, so its actually better to use nsCString mCharset;
// nsCAutoString here
nsCAutoString mCharset;
nsCOMPtr<nsIUnicodeEncoder> mEncoder; nsCOMPtr<nsIUnicodeEncoder> mEncoder;
nsCOMPtr<nsIUnicodeDecoder> mDecoder; nsCOMPtr<nsIUnicodeDecoder> mDecoder;

View File

@ -329,7 +329,7 @@ $(PROGRAM).pure: $(PROG_OBJS) $(LIBRARY)
$(OTHER_LIBS) $(PROG_LIBS) $(OTHER_LIBS) $(PROG_LIBS)
ifndef PREBUILT_CPUCFG ifndef PREBUILT_CPUCFG
$(HFILES) $(CPPFILES): $(OBJDIR)/jsautocfg.h $(filter-out jscpucfg.h $(OBJDIR)/jsautocfg.h, $(HFILES)) $(CPPFILES): $(OBJDIR)/jsautocfg.h
$(OBJDIR)/jsautocfg.h: $(OBJDIR)/jscpucfg $(OBJDIR)/jsautocfg.h: $(OBJDIR)/jscpucfg
rm -f $@ rm -f $@

View File

@ -126,8 +126,8 @@ OPTIMIZER = -O2 -GL
INTERP_OPTIMIZER = -O2 -GL INTERP_OPTIMIZER = -O2 -GL
LDFLAGS += -LTCG LDFLAGS += -LTCG
else else
OPTIMIZER = -Os OPTIMIZER = -Os -fno-exceptions -fno-rtti
INTERP_OPTIMIZER = -Os INTERP_OPTIMIZER = -Os -fno-exceptions -fno-rtti
endif endif
DEFINES += -UDEBUG -DNDEBUG -UDEBUG_$(USER) DEFINES += -UDEBUG -DNDEBUG -UDEBUG_$(USER)
OBJDIR_TAG = _OPT OBJDIR_TAG = _OPT
@ -136,8 +136,8 @@ ifdef USE_MSVC
OPTIMIZER = -Zi OPTIMIZER = -Zi
INTERP_OPTIMIZER = -Zi INTERP_OPTIMIZER = -Zi
else else
OPTIMIZER = -g3 OPTIMIZER = -g3 -fno-exceptions -fno-rtti
INTERP_OPTIMIZER = -g3 INTERP_OPTIMIZER = -g3 -fno-exceptions -fno-rtti
endif endif
DEFINES += -DDEBUG -DDEBUG_$(USER) DEFINES += -DDEBUG -DDEBUG_$(USER)
OBJDIR_TAG = _DBG OBJDIR_TAG = _DBG

View File

@ -305,3 +305,4 @@ MSG_DEF(JSMSG_NULL_OR_UNDEFINED, 222, 2, JSEXN_TYPEERR, "{0} is {1}")
MSG_DEF(JSMSG_LET_DECL_NOT_IN_BLOCK, 223, 0, JSEXN_SYNTAXERR, "let declaration not directly within block") MSG_DEF(JSMSG_LET_DECL_NOT_IN_BLOCK, 223, 0, JSEXN_SYNTAXERR, "let declaration not directly within block")
MSG_DEF(JSMSG_BAD_OBJECT_INIT, 224, 0, JSEXN_SYNTAXERR, "invalid object initializer") MSG_DEF(JSMSG_BAD_OBJECT_INIT, 224, 0, JSEXN_SYNTAXERR, "invalid object initializer")
MSG_DEF(JSMSG_CANT_SET_ARRAY_ATTRS, 225, 0, JSEXN_INTERNALERR, "can't set attributes on indexed array properties") MSG_DEF(JSMSG_CANT_SET_ARRAY_ATTRS, 225, 0, JSEXN_INTERNALERR, "can't set attributes on indexed array properties")
MSG_DEF(JSMSG_EVAL_ARITY, 226, 0, JSEXN_TYPEERR, "eval accepts only one parameter")

View File

@ -103,8 +103,8 @@ JS_BEGIN_EXTERN_C
#define JSVAL_INT_POW2(n) ((jsval)1 << (n)) #define JSVAL_INT_POW2(n) ((jsval)1 << (n))
#define JSVAL_INT_MIN (-JSVAL_INT_POW2(30)) #define JSVAL_INT_MIN (-JSVAL_INT_POW2(30))
#define JSVAL_INT_MAX (JSVAL_INT_POW2(30) - 1) #define JSVAL_INT_MAX (JSVAL_INT_POW2(30) - 1)
#define INT_FITS_IN_JSVAL(i) ((jsuint)(i) + JSVAL_INT_MAX + 1 <= \ #define INT_FITS_IN_JSVAL(i) ((jsuint)(i) - (jsuint)JSVAL_INT_MIN <= \
2 * JSVAL_INT_MAX + 1) (jsuint)(JSVAL_INT_MAX - JSVAL_INT_MIN))
#define JSVAL_TO_INT(v) ((jsint)(v) >> 1) #define JSVAL_TO_INT(v) ((jsint)(v) >> 1)
#define INT_TO_JSVAL(i) (((jsval)(i) << 1) | JSVAL_INT) #define INT_TO_JSVAL(i) (((jsval)(i) << 1) | JSVAL_INT)

View File

@ -116,11 +116,8 @@
JS_STATIC_ASSERT(sizeof(JSScopeProperty) > 4 * sizeof(jsval)); JS_STATIC_ASSERT(sizeof(JSScopeProperty) > 4 * sizeof(jsval));
static JSBool
MakeArraySlow(JSContext *cx, JSObject *obj);
#define ENSURE_SLOW_ARRAY(cx, obj) \ #define ENSURE_SLOW_ARRAY(cx, obj) \
(OBJ_GET_CLASS(cx, obj) == &js_SlowArrayClass || MakeArraySlow(cx, obj)) (OBJ_GET_CLASS(cx, obj) == &js_SlowArrayClass || js_MakeArraySlow(cx, obj))
/* /*
* Determine if the id represents an array index or an XML property index. * Determine if the id represents an array index or an XML property index.
@ -417,7 +414,7 @@ SetArrayElement(JSContext *cx, JSObject *obj, jsuint index, jsval v)
if (OBJ_IS_DENSE_ARRAY(cx, obj)) { if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
if (INDEX_TOO_SPARSE(obj, index)) { if (INDEX_TOO_SPARSE(obj, index)) {
if (!MakeArraySlow(cx, obj)) if (!js_MakeArraySlow(cx, obj))
return JS_FALSE; return JS_FALSE;
} else { } else {
@ -701,13 +698,29 @@ array_getProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
if (!js_IdIsIndex(ID_TO_VALUE(id), &i) || i >= ARRAY_DENSE_LENGTH(obj) || if (!js_IdIsIndex(ID_TO_VALUE(id), &i) || i >= ARRAY_DENSE_LENGTH(obj) ||
obj->dslots[i] == JSVAL_HOLE) { obj->dslots[i] == JSVAL_HOLE) {
JSObject *obj2;
JSProperty *prop;
JSScopeProperty *sprop;
JSObject *proto = STOBJ_GET_PROTO(obj); JSObject *proto = STOBJ_GET_PROTO(obj);
if (!proto) { if (!proto) {
*vp = JSVAL_VOID; *vp = JSVAL_VOID;
return JS_TRUE; return JS_TRUE;
} }
return OBJ_GET_PROPERTY(cx, proto, id, vp); *vp = JSVAL_VOID;
if (js_LookupPropertyWithFlags(cx, proto, id, 0, &obj2, &prop) < 0)
return JS_FALSE;
if (prop) {
if (OBJ_IS_NATIVE(obj2)) {
sprop = (JSScopeProperty *) prop;
if (!js_NativeGet(cx, obj, obj2, sprop, vp))
return JS_FALSE;
}
OBJ_DROP_PROPERTY(cx, obj2, prop);
}
return JS_TRUE;
} }
*vp = obj->dslots[i]; *vp = obj->dslots[i];
@ -763,7 +776,7 @@ array_setProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
return js_SetProperty(cx, obj, id, vp); return js_SetProperty(cx, obj, id, vp);
if (!js_IdIsIndex(id, &i) || INDEX_TOO_SPARSE(obj, i)) { if (!js_IdIsIndex(id, &i) || INDEX_TOO_SPARSE(obj, i)) {
if (!MakeArraySlow(cx, obj)) if (!js_MakeArraySlow(cx, obj))
return JS_FALSE; return JS_FALSE;
return js_SetProperty(cx, obj, id, vp); return js_SetProperty(cx, obj, id, vp);
} }
@ -912,8 +925,8 @@ array_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
case JSENUMERATE_INIT: case JSENUMERATE_INIT:
JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj)); JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
length = ARRAY_DENSE_LENGTH(obj); length = ARRAY_DENSE_LENGTH(obj);
if (idp && !IndexToId(cx, length, idp)) if (idp)
return JS_FALSE; *idp = INT_TO_JSVAL(obj->fslots[JSSLOT_ARRAY_COUNT]);
ii = NULL; ii = NULL;
for (i = 0; i != length; ++i) { for (i = 0; i != length; ++i) {
if (obj->dslots[i] == JSVAL_HOLE) { if (obj->dslots[i] == JSVAL_HOLE) {
@ -1109,8 +1122,8 @@ JSClass js_SlowArrayClass = {
/* /*
* Convert an array object from fast-and-dense to slow-and-flexible. * Convert an array object from fast-and-dense to slow-and-flexible.
*/ */
static JSBool JSBool
MakeArraySlow(JSContext *cx, JSObject *obj) js_MakeArraySlow(JSContext *cx, JSObject *obj)
{ {
JSObjectMap *map, *oldmap; JSObjectMap *map, *oldmap;
uint32 i, length; uint32 i, length;
@ -2059,7 +2072,7 @@ array_push(JSContext *cx, uintN argc, jsval *vp)
length = obj->fslots[JSSLOT_ARRAY_LENGTH]; length = obj->fslots[JSSLOT_ARRAY_LENGTH];
if (INDEX_TOO_SPARSE(obj, length)) { if (INDEX_TOO_SPARSE(obj, length)) {
if (!MakeArraySlow(cx, obj)) if (!js_MakeArraySlow(cx, obj))
return JS_FALSE; return JS_FALSE;
return array_push_slowly(cx, obj, argc, vp); return array_push_slowly(cx, obj, argc, vp);
} }
@ -2085,23 +2098,16 @@ array_pop(JSContext *cx, uintN argc, jsval *vp)
if (!obj) if (!obj)
return JS_FALSE; return JS_FALSE;
if (OBJ_IS_DENSE_ARRAY(cx, obj)) { if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
*vp = JSVAL_VOID;
index = obj->fslots[JSSLOT_ARRAY_LENGTH]; index = obj->fslots[JSSLOT_ARRAY_LENGTH];
if (index == 0) if (index == 0) {
*vp = JSVAL_VOID;
return JS_TRUE; return JS_TRUE;
index--;
if (index < ARRAY_DENSE_LENGTH(obj)) {
*vp = obj->dslots[index];
JS_ASSERT(*vp != JSVAL_HOLE);
if (index == 0) {
JS_free(cx, obj->dslots - 1);
obj->dslots = NULL;
} else {
ARRAY_SET_DENSE_LENGTH(obj, index);
}
obj->fslots[JSSLOT_ARRAY_COUNT]--;
} }
index--;
if (!GetArrayElement(cx, obj, index, &hole, vp))
return JS_FALSE;
if (!hole && !DeleteArrayElement(cx, obj, index))
return JS_FALSE;
obj->fslots[JSSLOT_ARRAY_LENGTH] = index; obj->fslots[JSSLOT_ARRAY_LENGTH] = index;
return JS_TRUE; return JS_TRUE;
} }

View File

@ -71,6 +71,9 @@ js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector,
extern JSObject * extern JSObject *
js_NewSlowArrayObject(JSContext *cx); js_NewSlowArrayObject(JSContext *cx);
extern JSBool
js_MakeArraySlow(JSContext *cx, JSObject *obj);
#define JSSLOT_ARRAY_LENGTH JSSLOT_PRIVATE #define JSSLOT_ARRAY_LENGTH JSSLOT_PRIVATE
#define JSSLOT_ARRAY_COUNT (JSSLOT_ARRAY_LENGTH + 1) #define JSSLOT_ARRAY_COUNT (JSSLOT_ARRAY_LENGTH + 1)
#define JSSLOT_ARRAY_LOOKUP_HOLDER (JSSLOT_ARRAY_COUNT + 1) #define JSSLOT_ARRAY_LOOKUP_HOLDER (JSSLOT_ARRAY_COUNT + 1)

View File

@ -61,10 +61,12 @@ JS_BEGIN_EXTERN_C
/* /*
* js_GetSrcNote cache to avoid O(n^2) growth in finding a source note for a * js_GetSrcNote cache to avoid O(n^2) growth in finding a source note for a
* given pc in a script. * given pc in a script. We use the script->code pointer to tag the cache,
* instead of the script address itself, so that source notes are always found
* by offset from the bytecode with which they were generated.
*/ */
typedef struct JSGSNCache { typedef struct JSGSNCache {
JSScript *script; jsbytecode *code;
JSDHashTable table; JSDHashTable table;
#ifdef JS_GSNMETER #ifdef JS_GSNMETER
uint32 hits; uint32 hits;
@ -79,7 +81,7 @@ typedef struct JSGSNCache {
#define GSN_CACHE_CLEAR(cache) \ #define GSN_CACHE_CLEAR(cache) \
JS_BEGIN_MACRO \ JS_BEGIN_MACRO \
(cache)->script = NULL; \ (cache)->code = NULL; \
if ((cache)->table.ops) { \ if ((cache)->table.ops) { \
JS_DHashTableFinish(&(cache)->table); \ JS_DHashTableFinish(&(cache)->table); \
(cache)->table.ops = NULL; \ (cache)->table.ops = NULL; \
@ -163,9 +165,14 @@ typedef struct JSPropertyTreeEntry {
} JSPropertyTreeEntry; } JSPropertyTreeEntry;
/* /*
* Forward declaration for opaque JSRuntime.nativeIteratorStates. * Private type used to enumerate properties of a native JS object.
*/ */
typedef struct JSNativeIteratorState JSNativeIteratorState; struct JSNativeEnumerator {
jsint next_index; /* index into jsid array */
JSIdArray *ida; /* all property ids in enumeration */
JSNativeEnumerator *next; /* double-linked list support */
JSNativeEnumerator **prevp;
};
typedef struct JSSetSlotRequest JSSetSlotRequest; typedef struct JSSetSlotRequest JSSetSlotRequest;
@ -378,9 +385,9 @@ struct JSRuntime {
/* /*
* A helper list for the GC, so it can mark native iterator states. See * A helper list for the GC, so it can mark native iterator states. See
* js_TraceNativeIteratorStates for details. * js_TraceNativeEnumerators for details.
*/ */
JSNativeIteratorState *nativeIteratorStates; JSNativeEnumerator *nativeEnumerators;
#ifndef JS_THREADSAFE #ifndef JS_THREADSAFE
/* /*

View File

@ -4251,6 +4251,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
case TOK_FOR: case TOK_FOR:
beq = 0; /* suppress gcc warnings */ beq = 0; /* suppress gcc warnings */
jmp = -1;
pn2 = pn->pn_left; pn2 = pn->pn_left;
js_PushStatement(&cg->treeContext, &stmtInfo, STMT_FOR_LOOP, top); js_PushStatement(&cg->treeContext, &stmtInfo, STMT_FOR_LOOP, top);
@ -4302,14 +4303,8 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
* object depending on the loop variant (for-in, for-each-in, or * object depending on the loop variant (for-in, for-each-in, or
* destructuring for-in). * destructuring for-in).
*/ */
#if JS_HAS_DESTRUCTURING JS_ASSERT(pn->pn_op == JSOP_ITER);
JS_ASSERT(pn->pn_op == JSOP_FORIN || if (js_Emit2(cx, cg, PN_OP(pn), (uint8) pn->pn_iflags) < 0)
pn->pn_op == JSOP_FOREACHKEYVAL ||
pn->pn_op == JSOP_FOREACH);
#else
JS_ASSERT(pn->pn_op == JSOP_FORIN || pn->pn_op == JSOP_FOREACH);
#endif
if (js_Emit1(cx, cg, PN_OP(pn)) < 0)
return JS_FALSE; return JS_FALSE;
top = CG_OFFSET(cg); top = CG_OFFSET(cg);
@ -4498,7 +4493,24 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
if (beq < 0) if (beq < 0)
return JS_FALSE; return JS_FALSE;
} }
/* Emit code for the loop body. */
if (!js_EmitTree(cx, cg, pn->pn_right))
return JS_FALSE;
/* Emit the loop-closing jump and fixup all jump offsets. */
jmp = EmitJump(cx, cg, JSOP_GOTO, top - CG_OFFSET(cg));
if (jmp < 0)
return JS_FALSE;
if (beq > 0)
CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);
/* Set the SRC_WHILE note offset so we can find the closing jump. */
JS_ASSERT(noteIndex != -1);
if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, jmp - beq))
return JS_FALSE;
} else { } else {
/* C-style for (init; cond; update) ... loop. */
op = JSOP_POP; op = JSOP_POP;
pn3 = pn2->pn_kid1; pn3 = pn2->pn_kid1;
if (!pn3) { if (!pn3) {
@ -4535,33 +4547,19 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
return JS_FALSE; return JS_FALSE;
} }
top = CG_OFFSET(cg); if (pn2->pn_kid2) {
SET_STATEMENT_TOP(&stmtInfo, top); /* Goto the loop condition, which branches back to iterate. */
if (!pn2->pn_kid2) { jmp = EmitJump(cx, cg, JSOP_GOTO, 0);
/* No loop condition: flag this fact in the source notes. */ if (jmp < 0)
if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, 0))
return JS_FALSE;
} else {
if (!js_EmitTree(cx, cg, pn2->pn_kid2))
return JS_FALSE;
if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0,
CG_OFFSET(cg) - top)) {
return JS_FALSE;
}
beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
if (beq < 0)
return JS_FALSE; return JS_FALSE;
} }
top = CG_OFFSET(cg);
SET_STATEMENT_TOP(&stmtInfo, top);
/* Set pn3 (used below) here to avoid spurious gcc warnings. */ /* Emit code for the loop body. */
pn3 = pn2->pn_kid3; if (!js_EmitTree(cx, cg, pn->pn_right))
} return JS_FALSE;
/* Emit code for the loop body. */
if (!js_EmitTree(cx, cg, pn->pn_right))
return JS_FALSE;
if (pn2->pn_type != TOK_IN) {
/* Set the second note offset so we can find the update part. */ /* Set the second note offset so we can find the update part. */
JS_ASSERT(noteIndex != -1); JS_ASSERT(noteIndex != -1);
if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 1, if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 1,
@ -4569,14 +4567,15 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
return JS_FALSE; return JS_FALSE;
} }
if (pn3) { /* Set loop and enclosing "update" offsets, for continue. */
/* Set loop and enclosing "update" offsets, for continue. */ stmt = &stmtInfo;
stmt = &stmtInfo; do {
do { stmt->update = CG_OFFSET(cg);
stmt->update = CG_OFFSET(cg); } while ((stmt = stmt->down) != NULL && stmt->type == STMT_LABEL);
} while ((stmt = stmt->down) != NULL &&
stmt->type == STMT_LABEL);
/* Check for update code to do before the condition (if any). */
pn3 = pn2->pn_kid3;
if (pn3) {
op = JSOP_POP; op = JSOP_POP;
#if JS_HAS_DESTRUCTURING #if JS_HAS_DESTRUCTURING
if (pn3->pn_type == TOK_ASSIGN && if (pn3->pn_type == TOK_ASSIGN &&
@ -4600,24 +4599,37 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
} }
} }
/* Set the first note offset so we can find the loop condition. */
if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0,
CG_OFFSET(cg) - top)) {
return JS_FALSE;
}
if (pn2->pn_kid2) {
/* Fix up the goto from top to target the loop condition. */
JS_ASSERT(jmp >= 0);
CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, jmp);
if (!js_EmitTree(cx, cg, pn2->pn_kid2))
return JS_FALSE;
}
/* The third note offset helps us find the loop-closing jump. */ /* The third note offset helps us find the loop-closing jump. */
if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 2, if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 2,
CG_OFFSET(cg) - top)) { CG_OFFSET(cg) - top)) {
return JS_FALSE; return JS_FALSE;
} }
}
/* Emit the loop-closing jump and fixup all jump offsets. */ if (pn2->pn_kid2) {
jmp = EmitJump(cx, cg, JSOP_GOTO, top - CG_OFFSET(cg)); beq = EmitJump(cx, cg, JSOP_IFNE, top - CG_OFFSET(cg));
if (jmp < 0) if (beq < 0)
return JS_FALSE; return JS_FALSE;
if (beq > 0) } else {
CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq); /* No loop condition -- emit the loop-closing jump. */
if (pn2->pn_type == TOK_IN) { jmp = EmitJump(cx, cg, JSOP_GOTO, top - CG_OFFSET(cg));
/* Set the SRC_WHILE note offset so we can find the closing jump. */ if (jmp < 0)
JS_ASSERT(noteIndex != -1); return JS_FALSE;
if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, jmp - beq)) }
return JS_FALSE;
} }
/* Now fixup all breaks and continues (before for/in's JSOP_ENDITER). */ /* Now fixup all breaks and continues (before for/in's JSOP_ENDITER). */

View File

@ -583,6 +583,10 @@ JSClass js_ArgumentsClass = {
JS_CLASS_TRACE(args_or_call_trace), NULL JS_CLASS_TRACE(args_or_call_trace), NULL
}; };
#define JSSLOT_SCRIPTED_FUNCTION (JSSLOT_PRIVATE + 1)
#define JSSLOT_CALL_ARGUMENTS (JSSLOT_PRIVATE + 2)
#define CALL_CLASS_FIXED_RESERVED_SLOTS 2
JSObject * JSObject *
js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent) js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent)
{ {
@ -603,10 +607,12 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent)
/* Create the call object and link it to its stack frame. */ /* Create the call object and link it to its stack frame. */
callobj = js_NewObject(cx, &js_CallClass, NULL, parent, 0); callobj = js_NewObject(cx, &js_CallClass, NULL, parent, 0);
if (!callobj || !JS_SetPrivate(cx, callobj, fp)) { if (!callobj)
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
return NULL; return NULL;
}
JS_SetPrivate(cx, callobj, fp);
STOBJ_SET_SLOT(callobj, JSSLOT_SCRIPTED_FUNCTION,
OBJECT_TO_JSVAL(FUN_OBJECT(fp->fun)));
fp->callobj = callobj; fp->callobj = callobj;
/* Make callobj be the scope chain and the variables object. */ /* Make callobj be the scope chain and the variables object. */
@ -616,44 +622,78 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent)
return callobj; return callobj;
} }
static JSBool JSFunction *
call_enumerate(JSContext *cx, JSObject *obj); js_GetCallObjectFunction(JSObject *obj)
{
jsval v;
JS_ASSERT(STOBJ_GET_CLASS(obj) == &js_CallClass);
v = STOBJ_GET_SLOT(obj, JSSLOT_SCRIPTED_FUNCTION);
if (JSVAL_IS_VOID(v)) {
/* Newborn or prototype object. */
return NULL;
}
JS_ASSERT(!JSVAL_IS_PRIMITIVE(v));
return (JSFunction *) JSVAL_TO_OBJECT(v);
}
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
js_PutCallObject(JSContext *cx, JSStackFrame *fp) js_PutCallObject(JSContext *cx, JSStackFrame *fp)
{ {
JSObject *callobj; JSObject *callobj;
JSBool ok; JSBool ok;
jsid argsid; JSFunction *fun;
jsval aval; uintN n;
JSScope *scope;
/* /*
* Reuse call_enumerate here to reflect all actual args and vars into the * Since for a call object all fixed slots happen to be taken, we can copy
* call object from fp. * arguments and variables straight into JSObject.dslots.
*/ */
JS_STATIC_ASSERT(JS_INITIAL_NSLOTS - JSSLOT_PRIVATE ==
1 + CALL_CLASS_FIXED_RESERVED_SLOTS);
callobj = fp->callobj; callobj = fp->callobj;
if (!callobj) if (!callobj)
return JS_TRUE; return JS_TRUE;
ok = call_enumerate(cx, callobj);
/* /*
* Get the arguments object to snapshot fp's actual argument values. * Get the arguments object to snapshot fp's actual argument values.
*/ */
ok = JS_TRUE;
if (fp->argsobj) { if (fp->argsobj) {
if (!TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) { if (!TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {
argsid = ATOM_TO_JSID(cx->runtime->atomState.argumentsAtom); STOBJ_SET_SLOT(callobj, JSSLOT_CALL_ARGUMENTS,
aval = OBJECT_TO_JSVAL(fp->argsobj); OBJECT_TO_JSVAL(fp->argsobj));
ok &= js_SetProperty(cx, callobj, argsid, &aval);
} }
ok &= js_PutArgsObject(cx, fp); ok &= js_PutArgsObject(cx, fp);
} }
fun = fp->fun;
JS_ASSERT(fun == js_GetCallObjectFunction(callobj));
n = JS_GET_LOCAL_NAME_COUNT(fun);
if (n != 0) {
JS_LOCK_OBJ(cx, callobj);
n += JS_INITIAL_NSLOTS;
if (n > STOBJ_NSLOTS(callobj))
ok &= js_ReallocSlots(cx, callobj, n, JS_TRUE);
scope = OBJ_SCOPE(callobj);
if (ok) {
memcpy(callobj->dslots, fp->argv, fun->nargs * sizeof(jsval));
memcpy(callobj->dslots + fun->nargs, fp->vars,
fun->u.i.nvars * sizeof(jsval));
if (scope->object == callobj && n > scope->map.freeslot)
scope->map.freeslot = n;
}
JS_UNLOCK_SCOPE(cx, scope);
}
/* /*
* Clear the private pointer to fp, which is about to go away (js_Invoke). * Clear the private pointer to fp, which is about to go away (js_Invoke).
* Do this last because the call_enumerate and js_GetProperty calls above * Do this last because js_GetProperty calls above need to follow the
* need to follow the private slot to find fp. * private slot to find fp.
*/ */
ok &= JS_SetPrivate(cx, callobj, NULL); JS_SetPrivate(cx, callobj, NULL);
fp->callobj = NULL; fp->callobj = NULL;
return ok; return ok;
} }
@ -661,28 +701,16 @@ js_PutCallObject(JSContext *cx, JSStackFrame *fp)
static JSBool static JSBool
call_enumerate(JSContext *cx, JSObject *obj) call_enumerate(JSContext *cx, JSObject *obj)
{ {
JSStackFrame *fp;
JSFunction *fun; JSFunction *fun;
uintN n, i, slot; uintN n, i;
void *mark; void *mark;
jsuword *names; jsuword *names;
JSBool ok; JSBool ok;
JSAtom *name; JSAtom *name;
JSObject *pobj; JSObject *pobj;
JSProperty *prop; JSProperty *prop;
jsval v;
fp = (JSStackFrame *) JS_GetPrivate(cx, obj); fun = js_GetCallObjectFunction(obj);
if (!fp)
return JS_TRUE;
JS_ASSERT(GET_FUNCTION_PRIVATE(cx, fp->callee) == fp->fun);
/*
* Reflect actual args from fp->argv for formal parameters, and local vars
* and functions in fp->vars for declared variables and nested-at-top-level
* local functions.
*/
fun = fp->fun;
n = JS_GET_LOCAL_NAME_COUNT(fun); n = JS_GET_LOCAL_NAME_COUNT(fun);
if (n == 0) if (n == 0)
return JS_TRUE; return JS_TRUE;
@ -715,11 +743,7 @@ call_enumerate(JSContext *cx, JSObject *obj)
* JSPROP_PERMANENT. * JSPROP_PERMANENT.
*/ */
JS_ASSERT(prop && pobj == obj); JS_ASSERT(prop && pobj == obj);
slot = ((JSScopeProperty *) prop)->slot;
OBJ_DROP_PROPERTY(cx, pobj, prop); OBJ_DROP_PROPERTY(cx, pobj, prop);
v = (i < fun->nargs) ? fp->argv[i] : fp->vars[i - fun->nargs];
LOCKED_OBJ_SET_SLOT(obj, slot, v);
} }
ok = JS_TRUE; ok = JS_TRUE;
@ -738,36 +762,53 @@ static JSBool
CallPropertyOp(JSContext *cx, JSObject *obj, jsid id, jsval *vp, CallPropertyOp(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
JSCallPropertyKind kind, JSBool setter) JSCallPropertyKind kind, JSBool setter)
{ {
JSStackFrame *fp;
JSFunction *fun; JSFunction *fun;
JSStackFrame *fp;
uintN i; uintN i;
jsval *array; jsval *array;
fp = (JSStackFrame *) JS_GetPrivate(cx, obj); if (STOBJ_GET_CLASS(obj) != &js_CallClass)
if (!fp)
return JS_TRUE; return JS_TRUE;
fun = fp->fun;
JS_ASSERT(fun && FUN_INTERPRETED(fun)); fun = js_GetCallObjectFunction(obj);
fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
if (kind == JSCPK_ARGUMENTS) { if (kind == JSCPK_ARGUMENTS) {
if (setter) { if (setter) {
SET_OVERRIDE_BIT(fp, CALL_ARGUMENTS); if (fp)
} else if (!TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) { SET_OVERRIDE_BIT(fp, CALL_ARGUMENTS);
JSObject *argsobj; STOBJ_SET_SLOT(obj, JSSLOT_CALL_ARGUMENTS, *vp);
} else {
if (fp && !TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {
JSObject *argsobj;
argsobj = js_GetArgsObject(cx, fp); argsobj = js_GetArgsObject(cx, fp);
if (!argsobj) if (!argsobj)
return JS_FALSE; return JS_FALSE;
*vp = OBJECT_TO_JSVAL(argsobj); *vp = OBJECT_TO_JSVAL(argsobj);
} else {
*vp = STOBJ_GET_SLOT(obj, JSSLOT_CALL_ARGUMENTS);
}
} }
return JS_TRUE; return JS_TRUE;
} }
JS_ASSERT((int16) JSVAL_TO_INT(id) == JSVAL_TO_INT(id)); JS_ASSERT((int16) JSVAL_TO_INT(id) == JSVAL_TO_INT(id));
i = (uint16) JSVAL_TO_INT(id); i = (uint16) JSVAL_TO_INT(id);
JS_ASSERT_IF(kind == JSCPK_ARG, i < fun->nargs); JS_ASSERT_IF(kind == JSCPK_ARG, i < fun->nargs);
JS_ASSERT_IF(kind == JSCPK_VAR, i < fun->u.i.nvars); JS_ASSERT_IF(kind == JSCPK_VAR, i < fun->u.i.nvars);
if (!fp) {
i += CALL_CLASS_FIXED_RESERVED_SLOTS;
if (kind == JSCPK_VAR)
i += fun->nargs;
else
JS_ASSERT(kind == JSCPK_ARG);
return setter
? JS_SetReservedSlot(cx, obj, i, *vp)
: JS_GetReservedSlot(cx, obj, i, vp);
}
JS_ASSERT(fun->u.i.nvars == fp->nvars); JS_ASSERT(fun->u.i.nvars == fp->nvars);
if (kind == JSCPK_ARG) { if (kind == JSCPK_ARG) {
array = fp->argv; array = fp->argv;
@ -822,48 +863,39 @@ static JSBool
call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags, call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
JSObject **objp) JSObject **objp)
{ {
JSStackFrame *fp;
JSFunction *fun; JSFunction *fun;
jsid id; jsid id;
JSLocalKind localKind; JSLocalKind localKind;
JSPropertyOp getter, setter; JSPropertyOp getter, setter;
uintN slot, attrs; uintN slot, attrs;
jsval *vp;
fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
if (!fp)
return JS_TRUE;
fun = fp->fun;
JS_ASSERT(fun);
JS_ASSERT(GET_FUNCTION_PRIVATE(cx, fp->callee) == fun);
if (!JSVAL_IS_STRING(idval)) if (!JSVAL_IS_STRING(idval))
return JS_TRUE; return JS_TRUE;
fun = js_GetCallObjectFunction(obj);
if (!fun)
return JS_TRUE;
if (!js_ValueToStringId(cx, idval, &id)) if (!js_ValueToStringId(cx, idval, &id))
return JS_FALSE; return JS_FALSE;
localKind = js_LookupLocal(cx, fun, JSID_TO_ATOM(id), &slot); localKind = js_LookupLocal(cx, fun, JSID_TO_ATOM(id), &slot);
if (localKind != JSLOCAL_NONE) { if (localKind != JSLOCAL_NONE) {
JS_ASSERT((uint16) slot == slot); JS_ASSERT((uint16) slot == slot);
attrs = JSPROP_PERMANENT | JSPROP_SHARED;
if (localKind == JSLOCAL_ARG) { if (localKind == JSLOCAL_ARG) {
JS_ASSERT(slot < fun->nargs); JS_ASSERT(slot < fun->nargs);
vp = fp->argv;
getter = js_GetCallArg; getter = js_GetCallArg;
setter = SetCallArg; setter = SetCallArg;
attrs = JSPROP_PERMANENT;
} else { } else {
JS_ASSERT(localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST); JS_ASSERT(localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST);
JS_ASSERT(fun->u.i.nvars == fp->nvars);
JS_ASSERT(slot < fun->u.i.nvars); JS_ASSERT(slot < fun->u.i.nvars);
vp = fp->vars;
getter = js_GetCallVar; getter = js_GetCallVar;
setter = SetCallVar; setter = SetCallVar;
attrs = (localKind == JSLOCAL_CONST) if (localKind == JSLOCAL_CONST)
? JSPROP_PERMANENT | JSPROP_READONLY attrs |= JSPROP_READONLY;
: JSPROP_PERMANENT;
} }
if (!js_DefineNativeProperty(cx, obj, id, vp[slot], getter, setter, if (!js_DefineNativeProperty(cx, obj, id, JSVAL_VOID, getter, setter,
attrs, SPROP_HAS_SHORTID, (int16) slot, attrs, SPROP_HAS_SHORTID, (int16) slot,
NULL)) { NULL)) {
return JS_FALSE; return JS_FALSE;
@ -879,7 +911,8 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
if (id == ATOM_TO_JSID(cx->runtime->atomState.argumentsAtom)) { if (id == ATOM_TO_JSID(cx->runtime->atomState.argumentsAtom)) {
if (!js_DefineNativeProperty(cx, obj, id, JSVAL_VOID, if (!js_DefineNativeProperty(cx, obj, id, JSVAL_VOID,
GetCallArguments, SetCallArguments, GetCallArguments, SetCallArguments,
JSPROP_PERMANENT, 0, 0, NULL)) { JSPROP_PERMANENT | JSPROP_SHARED,
0, 0, NULL)) {
return JS_FALSE; return JS_FALSE;
} }
*objp = obj; *objp = obj;
@ -903,9 +936,20 @@ call_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
return JS_TRUE; return JS_TRUE;
} }
static uint32
call_reserveSlots(JSContext *cx, JSObject *obj)
{
JSFunction *fun;
fun = js_GetCallObjectFunction(obj);
return JS_GET_LOCAL_NAME_COUNT(fun);
}
JS_FRIEND_DATA(JSClass) js_CallClass = { JS_FRIEND_DATA(JSClass) js_CallClass = {
js_Call_str, js_Call_str,
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_IS_ANONYMOUS | JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(CALL_CLASS_FIXED_RESERVED_SLOTS) |
JSCLASS_NEW_RESOLVE | JSCLASS_IS_ANONYMOUS |
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Call), JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Call),
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
@ -914,7 +958,7 @@ JS_FRIEND_DATA(JSClass) js_CallClass = {
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
JS_CLASS_TRACE(args_or_call_trace), NULL, JS_CLASS_TRACE(args_or_call_trace), call_reserveSlots
}; };
/* /*

View File

@ -2865,7 +2865,7 @@ js_TraceRuntime(JSTracer *trc, JSBool allAtoms)
if (rt->gcLocksHash) if (rt->gcLocksHash)
JS_DHashTableEnumerate(rt->gcLocksHash, gc_lock_traversal, trc); JS_DHashTableEnumerate(rt->gcLocksHash, gc_lock_traversal, trc);
js_TraceAtomState(trc, allAtoms); js_TraceAtomState(trc, allAtoms);
js_TraceNativeIteratorStates(trc); js_TraceNativeEnumerators(trc);
js_TraceRuntimeNumberState(trc); js_TraceRuntimeNumberState(trc);
iter = NULL; iter = NULL;

View File

@ -1483,12 +1483,6 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
frame.callee = NULL; frame.callee = NULL;
frame.fun = NULL; frame.fun = NULL;
frame.thisp = chain; frame.thisp = chain;
OBJ_TO_OUTER_OBJECT(cx, frame.thisp);
if (!frame.thisp) {
ok = JS_FALSE;
goto out;
}
flags |= JSFRAME_COMPUTED_THIS;
frame.argc = 0; frame.argc = 0;
frame.argv = NULL; frame.argv = NULL;
frame.nvars = script->ngvars; frame.nvars = script->ngvars;
@ -1538,6 +1532,15 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
} }
cx->fp = &frame; cx->fp = &frame;
if (!down) {
OBJ_TO_OUTER_OBJECT(cx, frame.thisp);
if (!frame.thisp) {
ok = JS_FALSE;
goto out2;
}
frame.flags |= JSFRAME_COMPUTED_THIS;
}
if (hook) { if (hook) {
hookData = hook(cx, &frame, JS_TRUE, 0, hookData = hook(cx, &frame, JS_TRUE, 0,
cx->debugHooks->executeHookData); cx->debugHooks->executeHookData);
@ -1551,6 +1554,8 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
if (hook) if (hook)
hook(cx, &frame, JS_FALSE, &ok, hookData); hook(cx, &frame, JS_FALSE, &ok, hookData);
} }
out2:
if (mark) if (mark)
js_FreeRawStack(cx, mark); js_FreeRawStack(cx, mark);
cx->fp = oldfp; cx->fp = oldfp;
@ -2550,7 +2555,6 @@ js_Interpret(JSContext *cx)
uint32 slot; uint32 slot;
jsval *vp, lval, rval, ltmp, rtmp; jsval *vp, lval, rval, ltmp, rtmp;
jsid id; jsid id;
JSObject *iterobj;
JSProperty *prop; JSProperty *prop;
JSScopeProperty *sprop; JSScopeProperty *sprop;
JSString *str, *str2; JSString *str, *str2;
@ -3142,32 +3146,13 @@ js_Interpret(JSContext *cx)
OBJ_DROP_PROPERTY(cx, obj2, prop); OBJ_DROP_PROPERTY(cx, obj2, prop);
END_CASE(JSOP_IN) END_CASE(JSOP_IN)
BEGIN_CASE(JSOP_FOREACH) BEGIN_CASE(JSOP_ITER)
flags = JSITER_ENUMERATE | JSITER_FOREACH; flags = regs.pc[1];
goto value_to_iter;
#if JS_HAS_DESTRUCTURING
BEGIN_CASE(JSOP_FOREACHKEYVAL)
flags = JSITER_ENUMERATE | JSITER_FOREACH | JSITER_KEYVALUE;
goto value_to_iter;
#endif
BEGIN_CASE(JSOP_FORIN)
/*
* Set JSITER_ENUMERATE to indicate that for-in loop should use
* the enumeration protocol's iterator for compatibility if an
* explicit iterator is not given via the optional __iterator__
* method.
*/
flags = JSITER_ENUMERATE;
value_to_iter:
JS_ASSERT(regs.sp > fp->spbase); JS_ASSERT(regs.sp > fp->spbase);
if (!js_ValueToIterator(cx, flags, &regs.sp[-1])) if (!js_ValueToIterator(cx, flags, &regs.sp[-1]))
goto error; goto error;
JS_ASSERT(!JSVAL_IS_PRIMITIVE(regs.sp[-1])); JS_ASSERT(!JSVAL_IS_PRIMITIVE(regs.sp[-1]));
JS_ASSERT(JSOP_FORIN_LENGTH == js_CodeSpec[op].length); END_CASE(JSOP_ITER)
END_CASE(JSOP_FORIN)
BEGIN_CASE(JSOP_FORPROP) BEGIN_CASE(JSOP_FORPROP)
/* /*
@ -3211,9 +3196,7 @@ js_Interpret(JSContext *cx)
* JSObject that contains the iteration state. * JSObject that contains the iteration state.
*/ */
JS_ASSERT(!JSVAL_IS_PRIMITIVE(regs.sp[i])); JS_ASSERT(!JSVAL_IS_PRIMITIVE(regs.sp[i]));
iterobj = JSVAL_TO_OBJECT(regs.sp[i]); if (!js_CallIteratorNext(cx, JSVAL_TO_OBJECT(regs.sp[i]), &rval))
if (!js_CallIteratorNext(cx, iterobj, &rval))
goto error; goto error;
if (rval == JSVAL_HOLE) { if (rval == JSVAL_HOLE) {
rval = JSVAL_FALSE; rval = JSVAL_FALSE;
@ -6801,7 +6784,6 @@ js_Interpret(JSContext *cx)
# endif # endif
# if !JS_HAS_DESTRUCTURING # if !JS_HAS_DESTRUCTURING
L_JSOP_FOREACHKEYVAL:
L_JSOP_ENUMCONSTELEM: L_JSOP_ENUMCONSTELEM:
# endif # endif
@ -6836,6 +6818,9 @@ js_Interpret(JSContext *cx)
L_JSOP_DEFXMLNS: L_JSOP_DEFXMLNS:
# endif # endif
L_JSOP_UNUSED186:
L_JSOP_UNUSED213:
#else /* !JS_THREADED_INTERP */ #else /* !JS_THREADED_INTERP */
default: default:
#endif #endif

View File

@ -48,6 +48,11 @@
JS_BEGIN_EXTERN_C JS_BEGIN_EXTERN_C
/*
* NB: these flag bits are encoded into the bytecode stream in the immediate
* operand of JSOP_ITER, so don't change them without advancing jsxdrapi.h's
* JSXDR_BYTECODE_VERSION.
*/
#define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterator */ #define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterator */
#define JSITER_FOREACH 0x2 /* return [key, value] pair rather than key */ #define JSITER_FOREACH 0x2 /* return [key, value] pair rather than key */
#define JSITER_KEYVALUE 0x4 /* destructuring for-in wants [key, value] */ #define JSITER_KEYVALUE 0x4 /* destructuring for-in wants [key, value] */

View File

@ -1215,14 +1215,12 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (caller && !caller->varobj && !js_GetCallObject(cx, caller, NULL)) if (caller && !caller->varobj && !js_GetCallObject(cx, caller, NULL))
return JS_FALSE; return JS_FALSE;
/* /* eval no longer takes an optional trailing argument. */
* Script.prototype.compile/exec and Object.prototype.eval all take an if (argc >= 2 &&
* optional trailing argument that overrides the scope object. !JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING | JSREPORT_STRICT,
*/ js_GetErrorMessage, NULL,
if (argc >= 2) { JSMSG_EVAL_ARITY)) {
if (!js_ValueToObject(cx, argv[1], &scopeobj)) return JS_FALSE;
return JS_FALSE;
argv[1] = OBJECT_TO_JSVAL(scopeobj);
} }
/* From here on, control must exit through label out with ok set. */ /* From here on, control must exit through label out with ok set. */
@ -1434,6 +1432,9 @@ obj_watch(JSContext *cx, uintN argc, jsval *vp)
if (attrs & JSPROP_READONLY) if (attrs & JSPROP_READONLY)
return JS_TRUE; return JS_TRUE;
*vp = JSVAL_VOID; *vp = JSVAL_VOID;
if (OBJ_IS_DENSE_ARRAY(cx, obj) && !js_MakeArraySlow(cx, obj))
return JS_FALSE;
return JS_SetWatchPoint(cx, obj, userid, obj_watch_handler, callable); return JS_SetWatchPoint(cx, obj, userid, obj_watch_handler, callable);
} }
@ -1951,10 +1952,6 @@ js_CloneBlockObject(JSContext *cx, JSObject *proto, JSObject *parent,
return clone; return clone;
} }
static JSBool
js_ReallocSlots(JSContext *cx, JSObject *obj, uint32 nslots,
JSBool exactAllocation);
JSBool JSBool
js_PutBlockObject(JSContext *cx, JSBool normalUnwind) js_PutBlockObject(JSContext *cx, JSBool normalUnwind)
{ {
@ -2304,7 +2301,7 @@ FreeSlots(JSContext *cx, JSObject *obj)
#define DYNAMIC_WORDS_TO_SLOTS(words) \ #define DYNAMIC_WORDS_TO_SLOTS(words) \
(JS_ASSERT((words) > 1), (words) - 1 + JS_INITIAL_NSLOTS) (JS_ASSERT((words) > 1), (words) - 1 + JS_INITIAL_NSLOTS)
static JSBool JSBool
js_ReallocSlots(JSContext *cx, JSObject *obj, uint32 nslots, js_ReallocSlots(JSContext *cx, JSObject *obj, uint32 nslots,
JSBool exactAllocation) JSBool exactAllocation)
{ {
@ -4155,14 +4152,6 @@ js_SetIdArrayLength(JSContext *cx, JSIdArray *ida, jsint length)
return rida; return rida;
} }
/* Private type used to iterate over all properties of a native JS object */
struct JSNativeIteratorState {
jsint next_index; /* index into jsid array */
JSIdArray *ida; /* all property ids in enumeration */
JSNativeIteratorState *next; /* double-linked list support */
JSNativeIteratorState **prevp;
};
/* /*
* This function is used to enumerate the properties of native JSObjects * This function is used to enumerate the properties of native JSObjects
* and those host objects that do not define a JSNewEnumerateOp-style iterator * and those host objects that do not define a JSNewEnumerateOp-style iterator
@ -4180,7 +4169,7 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
jsint i, length; jsint i, length;
JSScope *scope; JSScope *scope;
JSIdArray *ida; JSIdArray *ida;
JSNativeIteratorState *state; JSNativeEnumerator *state;
rt = cx->runtime; rt = cx->runtime;
clasp = OBJ_GET_CLASS(cx, obj); clasp = OBJ_GET_CLASS(cx, obj);
@ -4245,8 +4234,7 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
} }
JS_UNLOCK_OBJ(cx, obj); JS_UNLOCK_OBJ(cx, obj);
state = (JSNativeIteratorState *) state = (JSNativeEnumerator *)JS_malloc(cx, sizeof(JSNativeEnumerator));
JS_malloc(cx, sizeof(JSNativeIteratorState));
if (!state) { if (!state) {
JS_DestroyIdArray(cx, ida); JS_DestroyIdArray(cx, ida);
return JS_FALSE; return JS_FALSE;
@ -4255,10 +4243,10 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
state->next_index = 0; state->next_index = 0;
JS_LOCK_RUNTIME(rt); JS_LOCK_RUNTIME(rt);
state->next = rt->nativeIteratorStates; state->next = rt->nativeEnumerators;
if (state->next) if (state->next)
state->next->prevp = &state->next; state->next->prevp = &state->next;
state->prevp = &rt->nativeIteratorStates; state->prevp = &rt->nativeEnumerators;
*state->prevp = state; *state->prevp = state;
JS_UNLOCK_RUNTIME(rt); JS_UNLOCK_RUNTIME(rt);
@ -4268,7 +4256,7 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
break; break;
case JSENUMERATE_NEXT: case JSENUMERATE_NEXT:
state = (JSNativeIteratorState *) JSVAL_TO_PRIVATE(*statep); state = (JSNativeEnumerator *) JSVAL_TO_PRIVATE(*statep);
ida = state->ida; ida = state->ida;
length = ida->length; length = ida->length;
if (state->next_index != length) { if (state->next_index != length) {
@ -4278,10 +4266,10 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
/* FALL THROUGH */ /* FALL THROUGH */
case JSENUMERATE_DESTROY: case JSENUMERATE_DESTROY:
state = (JSNativeIteratorState *) JSVAL_TO_PRIVATE(*statep); state = (JSNativeEnumerator *) JSVAL_TO_PRIVATE(*statep);
JS_LOCK_RUNTIME(rt); JS_LOCK_RUNTIME(rt);
JS_ASSERT(rt->nativeIteratorStates); JS_ASSERT(rt->nativeEnumerators);
JS_ASSERT(*state->prevp == state); JS_ASSERT(*state->prevp == state);
if (state->next) { if (state->next) {
JS_ASSERT(state->next->prevp == &state->next); JS_ASSERT(state->next->prevp == &state->next);
@ -4299,12 +4287,12 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
} }
void void
js_TraceNativeIteratorStates(JSTracer *trc) js_TraceNativeEnumerators(JSTracer *trc)
{ {
JSNativeIteratorState *state; JSNativeEnumerator *state;
jsid *cursor, *end, id; jsid *cursor, *end, id;
state = trc->context->runtime->nativeIteratorStates; state = trc->context->runtime->nativeEnumerators;
if (!state) if (!state)
return; return;

View File

@ -621,7 +621,7 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
jsval *statep, jsid *idp); jsval *statep, jsid *idp);
extern void extern void
js_TraceNativeIteratorStates(JSTracer *trc); js_TraceNativeEnumerators(JSTracer *trc);
extern JSBool extern JSBool
js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
@ -689,6 +689,13 @@ js_GetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot);
extern JSBool extern JSBool
js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v); js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v);
/*
* obj must be locked.
*/
extern JSBool
js_ReallocSlots(JSContext *cx, JSObject *obj, uint32 nslots,
JSBool exactAllocation);
extern JSObject * extern JSObject *
js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller); js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller);

View File

@ -62,7 +62,7 @@
#include "jsdbgapi.h" #include "jsdbgapi.h"
#include "jsemit.h" #include "jsemit.h"
#include "jsfun.h" #include "jsfun.h"
#include "jslock.h" #include "jsiter.h"
#include "jsobj.h" #include "jsobj.h"
#include "jsopcode.h" #include "jsopcode.h"
#include "jsregexp.h" #include "jsregexp.h"
@ -1985,31 +1985,42 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
cond = js_GetSrcNoteOffset(sn, 0); cond = js_GetSrcNoteOffset(sn, 0);
next = js_GetSrcNoteOffset(sn, 1); next = js_GetSrcNoteOffset(sn, 1);
tail = js_GetSrcNoteOffset(sn, 2); tail = js_GetSrcNoteOffset(sn, 2);
LOCAL_ASSERT(tail + GetJumpOffset(pc+tail, pc+tail) == 0);
/*
* If this loop has a condition, then pc points at a goto
* targeting the condition.
*/
if (cond != tail) {
LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
pc += (*pc == JSOP_GOTO)
? JSOP_GOTO_LENGTH
: JSOP_GOTOX_LENGTH;
}
LOCAL_ASSERT(tail == -GetJumpOffset(pc+tail, pc+tail));
/* Print the keyword and the possibly empty init-part. */ /* Print the keyword and the possibly empty init-part. */
js_printf(jp, "\tfor (%s;", rval); js_printf(jp, "\tfor (%s;", rval);
if (pc[cond] == JSOP_IFEQ || pc[cond] == JSOP_IFEQX) { if (cond != tail) {
/* Decompile the loop condition. */ /* Decompile the loop condition. */
DECOMPILE_CODE(pc, cond); DECOMPILE_CODE(pc + cond, tail - cond);
js_printf(jp, " %s", POP_STR()); js_printf(jp, " %s", POP_STR());
} }
/* Need a semicolon whether or not there was a cond. */ /* Need a semicolon whether or not there was a cond. */
js_puts(jp, ";"); js_puts(jp, ";");
if (pc[next] != JSOP_GOTO && pc[next] != JSOP_GOTOX) { if (next != cond) {
/* Decompile the loop updater. */ /* Decompile the loop updater. */
DECOMPILE_CODE(pc + next, tail - next - 1); DECOMPILE_CODE(pc + next,
cond - next - JSOP_POP_LENGTH);
js_printf(jp, " %s", POP_STR()); js_printf(jp, " %s", POP_STR());
} }
/* Do the loop body. */ /* Do the loop body. */
js_printf(jp, ") {\n"); js_printf(jp, ") {\n");
jp->indent += 4; jp->indent += 4;
oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0; DECOMPILE_CODE(pc, next);
DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);
jp->indent -= 4; jp->indent -= 4;
js_printf(jp, "\t}\n"); js_printf(jp, "\t}\n");
@ -3834,32 +3845,34 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
* 1. It is the complete expression consumed by a control * 1. It is the complete expression consumed by a control
* flow bytecode such as JSOP_TABLESWITCH whose syntax * flow bytecode such as JSOP_TABLESWITCH whose syntax
* always parenthesizes the controlling expression. * always parenthesizes the controlling expression.
* 2. It is the sole argument to a function call. * 2. It is the condition of a loop other than a for (;;).
* 3. It is the condition of an if statement and not of a * 3. It is the sole argument to a function call.
* 4. It is the condition of an if statement and not of a
* ?: expression. * ?: expression.
* *
* But (first, before anything else) always parenthesize * But (first, before anything else) always parenthesize
* if this genexp runs up against endpc and the next op is * if this genexp runs up against endpc and the next op is
* not a while or do-while loop JSOP_IFNE* opcode. In such * not a loop condition (JSOP_IFNE*) opcode. In such cases,
* cases, this Decompile activation has been recursively * this Decompile activation has been recursively called by
* called by a comma operator, &&, or || bytecode. * a comma operator, &&, or || bytecode.
*/ */
LOCAL_ASSERT(pc + len < endpc || pc2 = pc + len;
LOCAL_ASSERT(pc2 < endpc ||
endpc < outer->code + outer->length); endpc < outer->code + outer->length);
LOCAL_ASSERT(ss2.top == 1); LOCAL_ASSERT(ss2.top == 1);
ss2.opcodes[0] = JSOP_POP; ss2.opcodes[0] = JSOP_POP;
if (pc + len == endpc && if (pc2 == endpc &&
((JSOp) *endpc != JSOP_IFNE && (JSOp) *endpc != JSOP_IFNE &&
(JSOp) *endpc != JSOP_IFNEX)) { (JSOp) *endpc != JSOP_IFNEX) {
op = JSOP_SETNAME; op = JSOP_SETNAME;
} else { } else {
op = (JSOp) pc[len]; op = (JSOp) *pc2;
op = ((js_CodeSpec[op].format & JOF_PARENHEAD) || op = ((js_CodeSpec[op].format & JOF_PARENHEAD) ||
((js_CodeSpec[op].format & JOF_INVOKE) && ((js_CodeSpec[op].format & JOF_INVOKE) &&
GET_ARGC(pc + len) == 1) || GET_ARGC(pc2) == 1) ||
(((op == JSOP_IFEQ || op == JSOP_IFEQX) && ((op == JSOP_IFEQ || op == JSOP_IFEQX) &&
(sn2 = js_GetSrcNote(outer, pc + len)) && (sn2 = js_GetSrcNote(outer, pc2)) &&
SN_TYPE(sn2) != SRC_COND))) SN_TYPE(sn2) != SRC_COND))
? JSOP_POP ? JSOP_POP
: JSOP_SETNAME; : JSOP_SETNAME;
@ -4515,8 +4528,9 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
inXML = JS_FALSE; inXML = JS_FALSE;
break; break;
case JSOP_FOREACH: case JSOP_ITER:
foreach = JS_TRUE; foreach = (pc[1] & (JSITER_FOREACH | JSITER_KEYVALUE)) ==
JSITER_FOREACH;
todo = -2; todo = -2;
break; break;

View File

@ -234,9 +234,10 @@ OPDEF(JSOP_ARGDEC, 101,"argdec", NULL, 3, 0, 1, 15, JOF_QARG |
OPDEF(JSOP_VARDEC, 102,"vardec", NULL, 3, 0, 1, 15, JOF_QVAR |JOF_NAME|JOF_DEC|JOF_POST) OPDEF(JSOP_VARDEC, 102,"vardec", NULL, 3, 0, 1, 15, JOF_QVAR |JOF_NAME|JOF_DEC|JOF_POST)
/* /*
* Initialize for-in iterator. See also JSOP_FOREACH and JSOP_FOREACHKEYVAL. * Initialize for-in iterator using the JSITER_* flag bits in this op's uint8
* immediate operand. See also JSOP_ENDITER.
*/ */
OPDEF(JSOP_FORIN, 103,"forin", NULL, 1, 1, 1, 0, JOF_BYTE) OPDEF(JSOP_ITER, 103,"iter", NULL, 2, 1, 1, 0, JOF_2BYTE)
/* ECMA-compliant for/in ops. */ /* ECMA-compliant for/in ops. */
OPDEF(JSOP_FORNAME, 104,"forname", NULL, 3, 0, 1, 19, JOF_ATOM|JOF_NAME|JOF_FOR) OPDEF(JSOP_FORNAME, 104,"forname", NULL, 3, 0, 1, 19, JOF_ATOM|JOF_NAME|JOF_FOR)
@ -410,7 +411,7 @@ OPDEF(JSOP_XMLCOMMENT, 182,"xmlcomment", NULL, 3, 0, 1, 19, JOF_ATOM)
OPDEF(JSOP_XMLPI, 183,"xmlpi", NULL, 3, 1, 1, 19, JOF_ATOM) OPDEF(JSOP_XMLPI, 183,"xmlpi", NULL, 3, 1, 1, 19, JOF_ATOM)
OPDEF(JSOP_CALLPROP, 184,"callprop", NULL, 3, 1, 2, 18, JOF_ATOM|JOF_PROP|JOF_CALLOP) OPDEF(JSOP_CALLPROP, 184,"callprop", NULL, 3, 1, 2, 18, JOF_ATOM|JOF_PROP|JOF_CALLOP)
OPDEF(JSOP_GETFUNNS, 185,"getfunns", NULL, 1, 0, 1, 19, JOF_BYTE) OPDEF(JSOP_GETFUNNS, 185,"getfunns", NULL, 1, 0, 1, 19, JOF_BYTE)
OPDEF(JSOP_FOREACH, 186,"foreach", NULL, 1, 1, 1, 0, JOF_BYTE) OPDEF(JSOP_UNUSED186, 186,"unused186", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_DELDESC, 187,"deldesc", NULL, 1, 2, 1, 17, JOF_BYTE |JOF_ELEM|JOF_DEL) OPDEF(JSOP_DELDESC, 187,"deldesc", NULL, 1, 2, 1, 17, JOF_BYTE |JOF_ELEM|JOF_DEL)
/* /*
@ -477,7 +478,7 @@ OPDEF(JSOP_GENERATOR, 210,"generator", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_YIELD, 211,"yield", NULL, 1, 1, 1, 1, JOF_BYTE) OPDEF(JSOP_YIELD, 211,"yield", NULL, 1, 1, 1, 1, JOF_BYTE)
OPDEF(JSOP_ARRAYPUSH, 212,"arraypush", NULL, 3, 1, 0, 3, JOF_LOCAL) OPDEF(JSOP_ARRAYPUSH, 212,"arraypush", NULL, 3, 1, 0, 3, JOF_LOCAL)
OPDEF(JSOP_FOREACHKEYVAL, 213,"foreachkeyval",NULL, 1, 1, 1, 0, JOF_BYTE) OPDEF(JSOP_UNUSED213, 213,"unused213", NULL, 1, 0, 0, 0, JOF_BYTE)
/* /*
* Variant of JSOP_ENUMELEM for destructuring const (const [a, b] = ...). * Variant of JSOP_ENUMELEM for destructuring const (const [a, b] = ...).

View File

@ -66,6 +66,7 @@
#include "jsemit.h" #include "jsemit.h"
#include "jsfun.h" #include "jsfun.h"
#include "jsinterp.h" #include "jsinterp.h"
#include "jsiter.h"
#include "jslock.h" #include "jslock.h"
#include "jsnum.h" #include "jsnum.h"
#include "jsobj.h" #include "jsobj.h"
@ -2674,10 +2675,11 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
return NULL; return NULL;
js_PushStatement(tc, &stmtInfo, STMT_FOR_LOOP, -1); js_PushStatement(tc, &stmtInfo, STMT_FOR_LOOP, -1);
pn->pn_op = JSOP_FORIN; pn->pn_op = JSOP_ITER;
pn->pn_iflags = 0;
if (js_MatchToken(cx, ts, TOK_NAME)) { if (js_MatchToken(cx, ts, TOK_NAME)) {
if (CURRENT_TOKEN(ts).t_atom == cx->runtime->atomState.eachAtom) if (CURRENT_TOKEN(ts).t_atom == cx->runtime->atomState.eachAtom)
pn->pn_op = JSOP_FOREACH; pn->pn_iflags = JSITER_FOREACH;
else else
js_UngetToken(ts); js_UngetToken(ts);
} }
@ -2687,7 +2689,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
tt = js_PeekToken(cx, ts); tt = js_PeekToken(cx, ts);
ts->flags &= ~TSF_OPERAND; ts->flags &= ~TSF_OPERAND;
if (tt == TOK_SEMI) { if (tt == TOK_SEMI) {
if (pn->pn_op == JSOP_FOREACH) if (pn->pn_iflags & JSITER_FOREACH)
goto bad_for_each; goto bad_for_each;
/* No initializer -- set first kid of left sub-node to null. */ /* No initializer -- set first kid of left sub-node to null. */
@ -2743,6 +2745,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
* the TCF_IN_FOR_INIT flag in our JSTreeContext. * the TCF_IN_FOR_INIT flag in our JSTreeContext.
*/ */
if (pn1 && js_MatchToken(cx, ts, TOK_IN)) { if (pn1 && js_MatchToken(cx, ts, TOK_IN)) {
pn->pn_iflags |= JSITER_ENUMERATE;
stmtInfo.type = STMT_FOR_IN_LOOP; stmtInfo.type = STMT_FOR_IN_LOOP;
/* Check that the left side of the 'in' is valid. */ /* Check that the left side of the 'in' is valid. */
@ -2751,7 +2754,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
? (pn1->pn_count > 1 || pn1->pn_op == JSOP_DEFCONST ? (pn1->pn_count > 1 || pn1->pn_op == JSOP_DEFCONST
#if JS_HAS_DESTRUCTURING #if JS_HAS_DESTRUCTURING
|| (JSVERSION_NUMBER(cx) == JSVERSION_1_7 && || (JSVERSION_NUMBER(cx) == JSVERSION_1_7 &&
pn->pn_op == JSOP_FORIN && pn->pn_op == JSOP_ITER &&
!(pn->pn_iflags & JSITER_FOREACH) &&
(pn1->pn_head->pn_type == TOK_RC || (pn1->pn_head->pn_type == TOK_RC ||
(pn1->pn_head->pn_type == TOK_RB && (pn1->pn_head->pn_type == TOK_RB &&
pn1->pn_head->pn_count != 2) || pn1->pn_head->pn_count != 2) ||
@ -2764,7 +2768,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn1->pn_type != TOK_DOT && pn1->pn_type != TOK_DOT &&
#if JS_HAS_DESTRUCTURING #if JS_HAS_DESTRUCTURING
((JSVERSION_NUMBER(cx) == JSVERSION_1_7 && ((JSVERSION_NUMBER(cx) == JSVERSION_1_7 &&
pn->pn_op == JSOP_FORIN) pn->pn_op == JSOP_ITER &&
!(pn->pn_iflags & JSITER_FOREACH))
? (pn1->pn_type != TOK_RB || pn1->pn_count != 2) ? (pn1->pn_type != TOK_RB || pn1->pn_count != 2)
: (pn1->pn_type != TOK_RB && pn1->pn_type != TOK_RC)) && : (pn1->pn_type != TOK_RB && pn1->pn_type != TOK_RC)) &&
#endif #endif
@ -2830,8 +2835,9 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
* Destructuring for-in requires [key, value] enumeration * Destructuring for-in requires [key, value] enumeration
* in JS1.7. * in JS1.7.
*/ */
if (pn->pn_op != JSOP_FOREACH) JS_ASSERT(pn->pn_op == JSOP_ITER);
pn->pn_op = JSOP_FOREACHKEYVAL; if (!(pn->pn_iflags & JSITER_FOREACH))
pn->pn_iflags |= JSITER_FOREACH | JSITER_KEYVALUE;
} }
break; break;
#endif #endif
@ -2845,7 +2851,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
return NULL; return NULL;
pn->pn_left = pn2; pn->pn_left = pn2;
} else { } else {
if (pn->pn_op == JSOP_FOREACH) if (pn->pn_iflags & JSITER_FOREACH)
goto bad_for_each; goto bad_for_each;
pn->pn_op = JSOP_NOP; pn->pn_op = JSOP_NOP;
@ -2860,6 +2866,22 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn2 = Expr(cx, ts, tc); pn2 = Expr(cx, ts, tc);
if (!pn2) if (!pn2)
return NULL; return NULL;
if (pn2->pn_type == TOK_LP &&
pn2->pn_head->pn_type == TOK_FUNCTION &&
(pn2->pn_head->pn_flags & TCF_GENEXP_LAMBDA)) {
/*
* A generator expression as loop condition is useless.
* It won't be called, and as an object it evaluates to
* true in boolean contexts without any conversion hook
* being called.
*
* This useless condition elimination is mandatory, to
* help the decompiler. See bug 442342.
*/
RecycleTree(pn2, tc);
pn2 = NULL;
}
} }
/* Parse the update expression or null into pn3. */ /* Parse the update expression or null into pn3. */
@ -4169,10 +4191,11 @@ ComprehensionTail(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
if (!pn2) if (!pn2)
return NULL; return NULL;
pn2->pn_op = JSOP_FORIN; pn2->pn_op = JSOP_ITER;
pn2->pn_iflags = JSITER_ENUMERATE;
if (js_MatchToken(cx, ts, TOK_NAME)) { if (js_MatchToken(cx, ts, TOK_NAME)) {
if (CURRENT_TOKEN(ts).t_atom == rt->atomState.eachAtom) if (CURRENT_TOKEN(ts).t_atom == rt->atomState.eachAtom)
pn2->pn_op = JSOP_FOREACH; pn2->pn_iflags |= JSITER_FOREACH;
else else
js_UngetToken(ts); js_UngetToken(ts);
} }
@ -4195,8 +4218,10 @@ ComprehensionTail(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
if (JSVERSION_NUMBER(cx) == JSVERSION_1_7) { if (JSVERSION_NUMBER(cx) == JSVERSION_1_7) {
/* Destructuring requires [key, value] enumeration in JS1.7. */ /* Destructuring requires [key, value] enumeration in JS1.7. */
if (pn2->pn_op != JSOP_FOREACH) JS_ASSERT(pn2->pn_op == JSOP_ITER);
pn2->pn_op = JSOP_FOREACHKEYVAL; JS_ASSERT(pn2->pn_iflags & JSITER_ENUMERATE);
if (!(pn2->pn_iflags & JSITER_FOREACH))
pn2->pn_iflags |= JSITER_FOREACH | JSITER_KEYVALUE;
} }
break; break;
#endif #endif

View File

@ -302,6 +302,7 @@ struct JSParseNode {
JSParseNode *left; JSParseNode *left;
JSParseNode *right; JSParseNode *right;
jsval val; /* switch case value */ jsval val; /* switch case value */
uintN iflags; /* JSITER_* flags for TOK_FOR node */
} binary; } binary;
struct { /* one kid if unary */ struct { /* one kid if unary */
JSParseNode *kid; JSParseNode *kid;
@ -346,6 +347,7 @@ struct JSParseNode {
#define pn_left pn_u.binary.left #define pn_left pn_u.binary.left
#define pn_right pn_u.binary.right #define pn_right pn_u.binary.right
#define pn_val pn_u.binary.val #define pn_val pn_u.binary.val
#define pn_iflags pn_u.binary.iflags
#define pn_kid pn_u.unary.kid #define pn_kid pn_u.unary.kid
#define pn_num pn_u.unary.num #define pn_num pn_u.unary.num
#define pn_hidden pn_u.unary.hidden #define pn_hidden pn_u.unary.hidden

View File

@ -92,6 +92,7 @@ typedef struct JSArgumentFormatMap JSArgumentFormatMap;
typedef struct JSCodeGenerator JSCodeGenerator; typedef struct JSCodeGenerator JSCodeGenerator;
typedef struct JSGCThing JSGCThing; typedef struct JSGCThing JSGCThing;
typedef struct JSGenerator JSGenerator; typedef struct JSGenerator JSGenerator;
typedef struct JSNativeEnumerator JSNativeEnumerator;
typedef struct JSParseContext JSParseContext; typedef struct JSParseContext JSParseContext;
typedef struct JSParsedObjectBox JSParsedObjectBox; typedef struct JSParsedObjectBox JSParsedObjectBox;
typedef struct JSParseNode JSParseNode; typedef struct JSParseNode JSParseNode;

View File

@ -1532,7 +1532,7 @@ js_DestroyScript(JSContext *cx, JSScript *script)
if (script->principals) if (script->principals)
JSPRINCIPALS_DROP(cx, script->principals); JSPRINCIPALS_DROP(cx, script->principals);
if (JS_GSN_CACHE(cx).script == script) if (JS_GSN_CACHE(cx).code == script->code)
JS_CLEAR_GSN_CACHE(cx); JS_CLEAR_GSN_CACHE(cx);
/* /*
@ -1638,7 +1638,7 @@ js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc)
if ((uint32)target >= script->length) if ((uint32)target >= script->length)
return NULL; return NULL;
if (JS_GSN_CACHE(cx).script == script) { if (JS_GSN_CACHE(cx).code == script->code) {
JS_METER_GSN_CACHE(cx, hits); JS_METER_GSN_CACHE(cx, hits);
entry = (GSNCacheEntry *) entry = (GSNCacheEntry *)
JS_DHashTableOperate(&JS_GSN_CACHE(cx).table, pc, JS_DHashTableOperate(&JS_GSN_CACHE(cx).table, pc,
@ -1660,7 +1660,7 @@ js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc)
} }
} }
if (JS_GSN_CACHE(cx).script != script && if (JS_GSN_CACHE(cx).code != script->code &&
script->length >= GSN_CACHE_THRESHOLD) { script->length >= GSN_CACHE_THRESHOLD) {
JS_CLEAR_GSN_CACHE(cx); JS_CLEAR_GSN_CACHE(cx);
nsrcnotes = 0; nsrcnotes = 0;
@ -1686,7 +1686,7 @@ js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc)
entry->sn = sn; entry->sn = sn;
} }
} }
JS_GSN_CACHE(cx).script = script; JS_GSN_CACHE(cx).code = script->code;
JS_METER_GSN_CACHE(cx, fills); JS_METER_GSN_CACHE(cx, fills);
} }
} }

View File

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

View File

@ -491,7 +491,7 @@ XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp)
XPCWrappedNativeScope *parentScope = XPCWrappedNativeScope *parentScope =
XPCWrappedNativeScope::FindInJSObjectScope(ccx, parent); XPCWrappedNativeScope::FindInJSObjectScope(ccx, parent);
#ifdef DEBUG_mrbkap #ifdef DEBUG_mrbkap_off
printf("Wrapping object at %p (%s) [%p]\n", printf("Wrapping object at %p (%s) [%p]\n",
(void *)wrappedObj, STOBJ_GET_CLASS(wrappedObj)->name, (void *)wrappedObj, STOBJ_GET_CLASS(wrappedObj)->name,
(void *)parentScope); (void *)parentScope);
@ -508,7 +508,7 @@ XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp)
if (outerObj) { if (outerObj) {
NS_ASSERTION(STOBJ_GET_CLASS(outerObj) == &sXPC_XOW_JSClass.base, NS_ASSERTION(STOBJ_GET_CLASS(outerObj) == &sXPC_XOW_JSClass.base,
"What crazy object are we getting here?"); "What crazy object are we getting here?");
#ifdef DEBUG_mrbkap #ifdef DEBUG_mrbkap_off
printf("But found a wrapper in the map %p!\n", (void *)outerObj); printf("But found a wrapper in the map %p!\n", (void *)outerObj);
#endif #endif
*vp = OBJECT_TO_JSVAL(outerObj); *vp = OBJECT_TO_JSVAL(outerObj);

View File

@ -272,7 +272,7 @@ XPCJSContextStack::SetSafeJSContext(JSContext * aSafeJSContext)
mOwnSafeJSContext == mSafeJSContext && mOwnSafeJSContext == mSafeJSContext &&
mOwnSafeJSContext != aSafeJSContext) mOwnSafeJSContext != aSafeJSContext)
{ {
JS_DestroyContext(mOwnSafeJSContext); JS_DestroyContextNoGC(mOwnSafeJSContext);
mOwnSafeJSContext = nsnull; mOwnSafeJSContext = nsnull;
SyncJSContexts(); SyncJSContexts();
} }

View File

@ -22,16 +22,14 @@ menu-list.txt:
confidential-failures.txt: confidential-failures.txt:
touch confidential-failures.txt touch confidential-failures.txt
failures.txt: public-failures.txt confidential-failures.txt public-failures.txt.expanded: public-failures.txt universe.data
cp public-failures.txt public-failures.txt.save ./pattern-expander.pl public-failures.txt > public-failures.txt.expanded
cp confidential-failures.txt confidential-failures.txt.save
sort < public-failures.txt | uniq | ./create-patterns.pl > public-failures.$$ confidential-failures.txt.expanded: confidential-failures.txt universe.data
mv public-failures.$$ public-failures.txt ./pattern-expander.pl confidential-failures.txt > confidential-failures.txt.expanded
sort < confidential-failures.txt | uniq | ./create-patterns.pl > confidential-failures.$$
mv confidential-failures.$$ confidential-failures.txt failures.txt: public-failures.txt.expanded confidential-failures.txt.expanded
cat public-failures.txt confidential-failures.txt | sort | uniq > failures.txt sort -u public-failures.txt.expanded confidential-failures.txt.expanded > failures.txt
clean: clean:
rm -f menubody.html menu.html menu-list.txt failures.txt excluded-*.tests included-*.tests urllist*.html urllist*.tests rm -f menubody.html menu.html menu-list.txt failures.txt *failures.txt.expanded excluded-*.tests included-*.tests urllist*.html urllist*.tests

223
js/tests/Patterns.pm Normal file
View File

@ -0,0 +1,223 @@
# -*- Mode: Perl; tab-width: 4; indent-tabs-mode: nil; -*-
# ***** 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 JavaScript Testing Utilities
#
# The Initial Developer of the Original Code is
# Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): Bob Clary <bclary@bclary.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
package Patterns;
sub getuniversekey
{
my ($machinerecord, $excludeduniversefield) = @_;
my $i;
my $key = '';
# dbg("getuniversekey: \$machinerecord=" . recordtostring($machinerecord) . ", \$excludeduniversefield=$excludeduniversefield");
for ($i = 0; $i < @universefields; $i++)
{
# dbg("getuniversekey: \$universefields[$i]=$universefields[$i]");
if ($universefields[$i] ne $excludeduniversefield)
{
$key .= $machinerecord->{$universefields[$i]}
}
}
# dbg("getuniversekey=$key");
return $key;
}
sub getuniverse
{
my ($universekey, $excludeduniversefield) = @_;
my $i;
my $value;
my $testrun;
my @universe = ();
my %universehash = ();
dbg("getuniverse: \$universekey=$universekey, \$excludeduniversefield=$excludeduniversefield");
for ($i = 0; $i < @testruns; $i++)
{
$testrun = $testruns[$i];
# dbg("getuniverse: \$testruns[$i]=" . recordtostring($testrun));
$testrununiversekey = getuniversekey($testrun, $excludeduniversefield);
# dbg("getuniverse: \$testrununiversekey=$testrununiversekey");
if ($testrununiversekey =~ /$universekey/)
{
# dbg("getuniverse: matched \$testrununiversekey=$testrununiversekey to \$universekey=$universekey");
$value = $testrun->{$excludeduniversefield};
# dbg("getuniverse: \$testrun->{$excludeduniversefield}=$value");
if (! $universehash{$value} )
{
# dbg("getuniverse: pushing $value");
push @universe, ($value);
$universehash{$value} = 1;
}
}
}
@universe = sort @universe;
dbg("getuniverse=" . join(',', @universe));
return @universe;
}
sub recordtostring
{
my ($record) = @_;
my $j;
my $line = '';
my $field;
for ($j = 0; $j < @recordfields - 1; $j++)
{
$field = $recordfields[$j];
# dbg("recordtostring: \$field=$field, \$record->{$field}=$record->{$field}");
$line .= "$field=$record->{$field}, ";
}
$field = $recordfields[$#recordfields];
# dbg("recordtodtring: \$field=$field, \$record->{$field}= $record->{$field}");
$line .= "$field=$record->{$field}";
return $line;
}
sub dumprecords
{
my $record;
my $line;
my $prevline = '';
my $i;
dbg("dumping records");
# @records = sort sortrecords @records;
for ($i = 0; $i < @records; $i++)
{
$record = $records[$i];
$line = recordtostring($record);
if ($line eq $prevline)
{
# dbg("DUPLICATE $line") if ($DEBUG);
}
else
{
print "$line\n";
$prevline = $line;
}
}
}
sub sortrecords
{
return recordtostring($a) cmp recordtostring($b);
}
sub dbg
{
if ($DEBUG)
{
print STDERR "DEBUG: " . join(" ", @_) . "\n";
}
}
sub copyreference
{
my ($fromreference) = @_;
my $toreference = {};
my $key;
foreach $key (keys %{$fromreference})
{
$toreference->{$key} = $fromreference->{$key};
}
return $toreference;
}
#my @recordfields;
#my @universefields;
#my %machines;
#my @testruns;
BEGIN
{
dbg("begin");
my $test_dir = $ENV{TEST_DIR} || "/work/mozilla/mozilla.com/test.mozilla.com/www";
$DEBUG = $ENV{DEBUG};
@recordfields = ('TEST_ID', 'TEST_BRANCH', 'TEST_BUILDTYPE', 'TEST_TYPE', 'TEST_OS', 'TEST_KERNEL', 'TEST_PROCESSORTYPE', 'TEST_MEMORY', 'TEST_CPUSPEED', 'TEST_TIMEZONE', 'TEST_RESULT', 'TEST_EXITSTATUS', 'TEST_DESCRIPTION');
@sortkeyfields = ('TEST_ID', 'TEST_RESULT', 'TEST_EXITSTATUS', 'TEST_DESCRIPTION', 'TEST_BRANCH', 'TEST_BUILDTYPE', 'TEST_TYPE', 'TEST_OS', 'TEST_KERNEL', 'TEST_PROCESSORTYPE', 'TEST_MEMORY', 'TEST_CPUSPEED', 'TEST_TIMEZONE', );
@universefields = ('TEST_BRANCH', 'TEST_BUILDTYPE', 'TEST_TYPE', 'TEST_OS', 'TEST_KERNEL', 'TEST_PROCESSORTYPE', 'TEST_MEMORY', 'TEST_CPUSPEED', 'TEST_TIMEZONE');
@records = ();
@testruns = ();
open TESTRUNS, "<$test_dir/tests/mozilla.org/js/universe.data" or die "$?";
while (<TESTRUNS>) {
chomp;
my $record = {};
my ($test_os, $test_kernel, $test_processortype, $test_memory, $test_cpuspeed, $test_timezone, $test_branch, $test_buildtype, $test_type) = $_ =~
/^TEST_OS=([^,]*), TEST_KERNEL=([^,]*), TEST_PROCESSORTYPE=([^,]*), TEST_MEMORY=([^,]*), TEST_CPUSPEED=([^,]*), TEST_TIMEZONE=([^,]*), TEST_BRANCH=([^,]*), TEST_BUILDTYPE=([^,]*), TEST_TYPE=([^,]*)/;
$record->{TEST_BRANCH} = $test_branch;
$record->{TEST_BUILDTYPE} = $test_buildtype;
$record->{TEST_TYPE} = $test_type;
$record->{TEST_OS} = $test_os;
$record->{TEST_KERNEL} = $test_kernel;
$record->{TEST_PROCESSORTYPE} = $test_processortype;
$record->{TEST_MEMORY} = $test_memory;
$record->{TEST_CPUSPEED} = $test_cpuspeed;
$record->{TEST_TIMEZONE} = $test_timezone;
push @testruns, ($record);
}
close TESTRUNS;
}
1;

120
js/tests/changes.sh Normal file
View File

@ -0,0 +1,120 @@
#!/bin/bash
# -*- Mode: Shell-script; tab-width: 4; indent-tabs-mode: nil; -*-
# ***** 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 JavaScript Testing Utilities
#
# The Initial Developer of the Original Code is
# Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): Bob Clary <bclary@bclary.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
# usage: changes.sh [prefix]
#
# combines the {prefix}*possible-fixes.log files into {prefix}possible-fixes.log
# and {prefix}*possible-regressions.log files into
# possible-regressions.log.
#
# This script is useful in cases where log files from different machines, branches
# and builds are being investigated.
if cat /dev/null | sed -r 'q' > /dev/null 2>&1; then
SED="sed -r"
elif cat /dev/null | sed -E 'q' > /dev/null 2>&1; then
SED="sed -E"
else
echo "Neither sed -r or sed -E is supported"
exit 2
fi
workfile=`mktemp work.XXXXXXXX`
if [ $? -ne 0 ]; then
echo "Unable to create working temp file"
exit 2
fi
for f in ${1}*results-possible-fixes.log*; do
case $f in
*.log)
CAT=cat
;;
*.log.bz2)
CAT=bzcat
;;
*.log.gz)
CAT=zcat
;;
*.log.zip)
CAT="unzip -c"
;;
*)
echo "unknown log type: $f"
exit 2
;;
esac
$CAT $f | $SED "s|$|:$f|" >> $workfile
done
sort -u $workfile > ${1}possible-fixes.log
rm $workfile
for f in ${1}*results-possible-regressions.log*; do
case $f in
*.log)
CAT=cat
;;
*.log.bz2)
CAT=bzcat
;;
*.log.gz)
CAT=zcat
;;
*.log.zip)
CAT="unzip -c"
;;
*)
echo "unknown log type: $f"
exit 2
;;
esac
$CAT $f >> $workfile
done
sort -u $workfile > ${1}possible-regressions.log
rm $workfile

View File

@ -1,264 +0,0 @@
#!/usr/bin/perl
# -*- Mode: Perl; tab-width: 4; indent-tabs-mode: nil; -*-
# ***** 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 JavaScript Testing Utilities
#
# The Initial Developer of the Original Code is
# Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2007
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): Bob Clary <bclary@bclary.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
# make stderr, stdout unbuffered
select STDERR; $| = 1;
select STDOUT; $| = 1;
my $regchars = '\[\^\-\]\|\{\}\?\*\+\.\<\>\$\(\)';
sub escape_patterns;
sub unescape_patterns;
sub debug;
my $debug = $ENV{DEBUG};
my @outputlines = ();
my @inputlines = ();
while (<ARGV>) {
chomp;
# remove irrelevant data the caller is required to remove any
# other data which should not be considered during the
# consolidation such as TEST_MACHINE, etc.
s/TEST_DATE=[^,]*,/TEST_DATE=.*,/;
push @inputlines, ($_);
}
my @fieldnames = ('TEST_BRANCH', 'TEST_BUILDTYPE', 'TEST_TYPE', 'TEST_OS', 'TEST_PROCESSORTYPE', 'TEST_KERNEL', 'TEST_TIMEZONE');
my $pass = 0;
my $changed = 1;
while ($changed) {
# repeated loop until no changes are made.
++$pass;
$changed = 0;
debug "pass $pass, " . ($#inputlines + 1) . " inputlines, " . ($#outputlines + 1) . " outputlines\n";
foreach $field (@fieldnames) {
debug "pass $pass, processing $field, " . ($#inputlines + 1) . " inputlines, " . ($#outputlines + 1) . " outputlines\n";
# process each field across all lines so that later consolidations
# will match consolidated field values
while ($inputline = shift(@inputlines)) {
debug "inputline $inputline\n";
# get the current field value from the current input line
($inputvalue) = $inputline =~ /$field=\(?([^,\)]*)\)?,/;
if ($inputvalue eq '.*') {
# if the current input value is the any wildcard,
# then there is no need to perform a consolidation
# on the field.
push @outputlines, ($inputline);
next;
}
# turn "off" any regular expression characters in the input line
$pattern = escape_pattern($inputline);
# Make the current field in the current pattern an any
# wildcard so that it will match any value. We are looking
# for all other lines that only differ from the current line by
# the current field value
$pattern =~ s/$field=[^,]*,/$field=.*,/;
# find the matches to the current pattern
debug "pattern: $pattern\n";
@matched = grep /$pattern/, (@inputlines, @outputlines);
@unmatched = grep !/$pattern/, @inputlines;
debug "" . ($#matched + 1) . " matched, " . ($#unmatched + 1) . " unmatched, " . ($#inputlines + 1) . " inputlines, " . ($#outputlines + 1) . " outputlines\n";
if (@matched) {
# the input line matched others
$outputvalue = $inputvalue;
foreach $matchline (@matched) {
($matchvalue) = $matchline =~ /$field=\(?([^,\)]*)\)?,/;
if ( $inputvalue !~ /$matchvalue/ && $matchvalue !~ /$inputvalue/) {
# the current match value and input value
# do not overlap so add the match
# field value as regular expression
# alternation | to the current field value
debug "adding regexp alternation to $field: inputvalue: $inputvalue, matchvalue: $matchvalue";
$outputvalue .= "|$matchvalue";
}
} # foreach matchline
# replace the current inputs field value with the
# consolidated value
if ($outputvalue =~ /\|/) {
$outputvalue = "(" . join('|', sort(split(/\|/, $outputvalue))) . ")";
}
$inputline =~ s/$field=[^,]*,/$field=$outputvalue,/;
debug "$inputline\n";
$changes = 1;
}
push @outputlines, ($inputline);
@inputlines = @unmatched;
} # while inputline
@inputlines = @outputlines;
@outputlines = ();
} # foreach field
}
@inputlines = sort @inputlines;
my $output = join"\n", @inputlines;
debug "output: " . ($#inputlines + 1) . " lines\n";
print "$output\n";
### # look for over specified failures
###
### $field = 'TEST_DESCRIPTION';
###
### while ($inputline = shift(@inputlines)) {
###
### debug "inputline $inputline\n";
###
### # turn "off" any regular expression characters in the input line
###
### $pattern = escape_pattern($inputline);
###
### # Make the TEST_DESCRIPTION field in the current pattern an any
### # wildcard so that it will match any value. We are looking
### # for all other lines that only differ from the current line by
### # the TEST_DESCRIPTION. These will be the potentially overspecified
### # failures.
###
### $pattern =~ s/$field=[^,]*,/$field=.*,/;
###
### # find the matches to the current pattern
###
### debug "pattern: $pattern\n";
###
### @matched = grep /$pattern/, @inputlines;
### @unmatched = grep !/$pattern/, @inputlines;
###
### debug "" . ($#matched + 1) . " matched, " . ($#unmatched + 1) . " unmatched, " . ($#inputlines + 1) . " inputlines, " . ($#outputlines + 1) . " outputlines\n";
###
### if (@matched) {
###
### # the inputline overspecifies an error
###
### push @matched, ($inputline);
###
### foreach $matchline (@matched) {
###
### print STDERR "OVERSPECIFIED? : $matchline\n";
###
### } # foreach matchline
###
### }
###
### @inputlines = @unmatched;
###
### } # while inputline
###
sub escape_pattern {
# unlike the known-failures.pl, this escape escapes the entire
# line to make it not contain any active regular expression patterns
# so that any matched will be literal and not regular
my $line = shift;
chomp;
# replace unescaped regular expression characters in the
# description so they are not interpreted as regexp chars
# when matching descriptions. leave the escaped regexp chars
# `regexp alone so they can be unescaped later and used in
# pattern matching.
# see perldoc perlre
$line =~ s/\\/\\\\/g;
# escape regexpchars
$line =~ s/([$regchars])/\\$1/g;
return "$line";
}
sub debug {
my $msg;
if ($debug) {
$msg = shift;
print "DEBUG: $msg\n";
}
}

View File

@ -1,4 +1,6 @@
# #!/bin/bash -e
# -*- Mode: Shell-script; tab-width: 4; indent-tabs-mode: nil; -*-
# ***** BEGIN LICENSE BLOCK ***** # ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
# #
@ -12,15 +14,14 @@
# for the specific language governing rights and limitations under the # for the specific language governing rights and limitations under the
# License. # License.
# #
# The Original Code is Mozilla code. # The Original Code is Mozilla JavaScript Testing Utilities
# #
# The Initial Developer of the Original Code is # The Initial Developer of the Original Code is
# Mozilla Corporation. # Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2008 # Portions created by the Initial Developer are Copyright (C) 2007
# the Initial Developer. All Rights Reserved. # the Initial Developer. All Rights Reserved.
# #
# Contributor(s): # Contributor(s): Bob Clary <bclary@bclary.com>
# Shawn Wilsher <me@shawnwilsher.com> (Original Author)
# #
# Alternatively, the contents of this file may be used under the terms of # Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or # either the GNU General Public License Version 2 or later (the "GPL"), or
@ -36,19 +37,12 @@
# #
# ***** END LICENSE BLOCK ***** # ***** END LICENSE BLOCK *****
DEPTH = ../../../../.. # usage: get-universe.sh logfile(s) > universe.data
topsrcdir = @top_srcdir@ #
srcdir = @srcdir@ # get-universe.sh reads the processed javascript logs and writes to
VPATH = @srcdir@ # stdout the unique set of fields to be used as the "universe" of test
relativesrcdir = toolkit/mozapps/downloads/tests/browser # run data. These values are used by pattern-expander.pl and
# pattern-extracter.pl to encode the known failure files into regular
# expressions.
include $(DEPTH)/config/autoconf.mk sed 's|.*\(TEST_BRANCH.*\), \(TEST_OS.*\), TEST_RESULT.*|\2, \1|' $@ | sort -u
include $(topsrcdir)/config/rules.mk
_BROWSER_FILES = \
browser_bug_406857.js \
browser_bug_412360.js \
$(NULL)
libs:: $(_BROWSER_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)

View File

@ -78,7 +78,7 @@ needParens("switch (x) { case xx: }");
needParens("return xx;"); needParens("return xx;");
needParens("yield xx;"); needParens("yield xx;");
needParens("for (xx;;) { }"); needParens("for (xx;;) { }");
needParens("for (;xx;) { }"); needParens("for (;xx;) { }", "function anonymous() {\n for (;;) {\n }\n}");
needParens("for (;;xx) { }"); needParens("for (;;xx) { }");
needParens("for (i in xx) { }"); needParens("for (i in xx) { }");
needParens("throw xx"); needParens("throw xx");
@ -211,7 +211,7 @@ function doesNotNeedParens(pat)
// print("Skipping the over-parenthesization test, because I don't know how to test for over-parenthesization when the pattern doesn't have parens snugly around it.") // print("Skipping the over-parenthesization test, because I don't know how to test for over-parenthesization when the pattern doesn't have parens snugly around it.")
} }
function needParens(pat) function needParens(pat, exp)
{ {
print("Testing " + pat); print("Testing " + pat);
@ -242,8 +242,8 @@ function needParens(pat)
} }
reportCompare(expect, actual, summary + ': needParens ' + ft); reportCompare(expect, actual, summary + ': needParens ' + ft);
roundTripTest(f); roundTripTest(f, exp);
overParenTest(f); overParenTest(f, exp);
} }
function rejectLHS(pat) function rejectLHS(pat)
@ -268,9 +268,11 @@ function rejectLHS(pat)
} }
function overParenTest(f) function overParenTest(f, exp)
{ {
var uf = "" + f; var uf = "" + f;
if (uf == exp)
return;
reportCompare(false, uf.indexOf(genexpParened) == -1, summary + reportCompare(false, uf.indexOf(genexpParened) == -1, summary +
': overParenTest genexp snugly in parentheses: ' + uf); ': overParenTest genexp snugly in parentheses: ' + uf);
@ -301,7 +303,7 @@ function sanityCheck(pat)
reportCompare(expect, actual, summary + ': sanityCheck ' + pat); reportCompare(expect, actual, summary + ': sanityCheck ' + pat);
} }
function roundTripTest(f) function roundTripTest(f, exp)
{ {
// Decompile // Decompile
var uf = "" + f; var uf = "" + f;
@ -321,7 +323,7 @@ function roundTripTest(f)
} }
// Decompile again and make sure the decompilations match exactly. // Decompile again and make sure the decompilations match exactly.
expect = uf; expect = exp || uf;
actual = "" + euf; actual = "" + euf;
reportCompare(expect, actual, summary + ': roundTripTest no round-trip change'); reportCompare(expect, actual, summary + ': roundTripTest no round-trip change');
} }

View File

@ -49,7 +49,7 @@ sub unescape_pattern;
# option arguments # option arguments
my $option_desc = "b=s branch>b T=s buildtype>T t=s testtype>t l=s rawlogfile>l f=s failurelogfile>f o=s os>o r=s patterns>r z=s timezone>z O=s outputprefix>O A=s arch>A K=s kernel>K D debug>D"; my $option_desc = "b=s branch>b T=s buildtype>T t=s testtype>t o=s os>o K=s kernel>K A=s arch>A M=s memory>M S=s speed>S z=s timezone>z l=s rawlogfile>l f=s failurelogfile>f r=s patterns>r O=s outputprefix>O D debug>D";
my $testid; my $testid;
my $branch; my $branch;
@ -63,6 +63,8 @@ my $timezone;
my $outputprefix; my $outputprefix;
my $arch; my $arch;
my $kernel; my $kernel;
my $memory;
my $cpuspeed;
my $debug = $ENV{DEBUG}; my $debug = $ENV{DEBUG};
# pattern variables # pattern variables
@ -81,6 +83,10 @@ my $knownfailurearchpattern;
my $failurearchpattern; my $failurearchpattern;
my $knownfailurekernelpattern; my $knownfailurekernelpattern;
my $failurekernelpattern; my $failurekernelpattern;
my $knownfailurememorypattern;
my $failurememorypattern;
my $knownfailurecpuspeedpattern;
my $failurecpuspeedpattern;
my @patterns; my @patterns;
my $pattern; my $pattern;
@ -144,7 +150,7 @@ foreach $includedfile ( @includedfiles ) {
} }
debug "loading patterns $patterns"; debug "loading patterns $patterns";
debug "pattern filter: /^TEST_ID=[^,]*, TEST_BRANCH=$knownfailurebranchpattern, TEST_RESULT=[^,]*, TEST_BUILDTYPE=$knownfailurebuildtypepattern, TEST_TYPE=$knownfailuretesttypepattern, TEST_OS=$knownfailureospattern, TEST_MACHINE=[^,]*, TEST_PROCESSORTYPE=$knownfailurearchpattern, TEST_KERNEL=$knownfailurekernelpattern, TEST_DATE=[^,]*, TEST_TIMEZONE=$knownfailuretimezonepattern,/\n"; debug "pattern filter: ^TEST_ID=[^,]*, TEST_BRANCH=$knownfailurebranchpattern, TEST_BUILDTYPE=$knownfailurebuildtypepattern, TEST_TYPE=$knownfailuretesttypepattern, TEST_OS=$knownfailureospattern, TEST_KERNEL=$knownfailurekernelpattern, TEST_PROCESSORTYPE=$knownfailurearchpattern, TEST_MEMORY=$knownfailurememorypattern, TEST_CPUSPEED=$knownfailurecpuspeedpattern, TEST_TIMEZONE=$knownfailuretimezonepattern,";
open PATTERNS, "<$patterns" or die "Unable to open known failure patterns file $patterns: $!\n"; open PATTERNS, "<$patterns" or die "Unable to open known failure patterns file $patterns: $!\n";
while (<PATTERNS>) { while (<PATTERNS>) {
@ -158,7 +164,7 @@ while (<PATTERNS>) {
{ {
debug "test $testid was not included during this run"; debug "test $testid was not included during this run";
} }
elsif ($_ =~ /^TEST_ID=[^,]*, TEST_BRANCH=$knownfailurebranchpattern, TEST_RESULT=[^,]*, TEST_BUILDTYPE=$knownfailurebuildtypepattern, TEST_TYPE=$knownfailuretesttypepattern, TEST_OS=$knownfailureospattern, TEST_MACHINE=[^,]*, TEST_PROCESSORTYPE=$knownfailurearchpattern, TEST_KERNEL=$knownfailurekernelpattern, TEST_DATE=[^,]*, TEST_TIMEZONE=$knownfailuretimezonepattern,/) { elsif ($_ =~ /^TEST_ID=[^,]*, TEST_BRANCH=$knownfailurebranchpattern, TEST_BUILDTYPE=$knownfailurebuildtypepattern, TEST_TYPE=$knownfailuretesttypepattern, TEST_OS=$knownfailureospattern, TEST_KERNEL=$knownfailurekernelpattern, TEST_PROCESSORTYPE=$knownfailurearchpattern, TEST_MEMORY=$knownfailurememorypattern, TEST_CPUSPEED=$knownfailurecpuspeedpattern, TEST_TIMEZONE=$knownfailuretimezonepattern,/) {
debug "adding pattern : $_"; debug "adding pattern : $_";
push @patterns, (escape_pattern($_)); push @patterns, (escape_pattern($_));
} }
@ -171,7 +177,7 @@ close PATTERNS;
# create a working copy of the current failures which match the users selection # create a working copy of the current failures which match the users selection
debug "failure filter: ^TEST_ID=[^,]*, TEST_BRANCH=$failurebranchpattern, TEST_RESULT=FAIL[^,]*, TEST_BUILDTYPE=$failurebuildtypepattern, TEST_TYPE=$failuretesttypepattern, TEST_OS=$failureospattern, TEST_MACHINE=[^,]*, TEST_PROCESSORTYPE=$failurearchpattern, TEST_KERNEL=$failurekernelpattern, TEST_DATE=[^,]*, TEST_TIMEZONE=$failuretimezonepattern,"; debug "failure filter: ^TEST_ID=[^,]*, TEST_BRANCH=$failurebranchpattern, TEST_BUILDTYPE=$failurebuildtypepattern, TEST_TYPE=$failuretesttypepattern, TEST_OS=$failureospattern, TEST_KERNEL=$failurekernelpattern, TEST_PROCESSORTYPE=$failurearchpattern, TEST_MEMORY=$failurememorypattern, TEST_CPUSPEED=$failurecpuspeedpattern, TEST_TIMEZONE=$failuretimezonepattern, TEST_RESULT=FAIL[^,]*,/";
if (defined($rawlogfile)) { if (defined($rawlogfile)) {
@ -189,7 +195,7 @@ if (defined($rawlogfile)) {
print ALLLOG "$_\n"; print ALLLOG "$_\n";
if ($_ =~ /^TEST_ID=[^,]*, TEST_BRANCH=$failurebranchpattern, TEST_RESULT=FAIL[^,]*, TEST_BUILDTYPE=$failurebuildtypepattern, TEST_TYPE=$failuretesttypepattern, TEST_OS=$failureospattern, TEST_MACHINE=[^,]*, TEST_PROCESSORTYPE=$failurearchpattern, TEST_KERNEL=$failurekernelpattern, TEST_DATE=[^,]*, TEST_TIMEZONE=$failuretimezonepattern,/) { if ($_ =~ /^TEST_ID=[^,]*, TEST_BRANCH=$failurebranchpattern, TEST_BUILDTYPE=$failurebuildtypepattern, TEST_TYPE=$failuretesttypepattern, TEST_OS=$failureospattern, TEST_KERNEL=$failurekernelpattern, TEST_PROCESSORTYPE=$failurearchpattern, TEST_MEMORY=$failurememorypattern, TEST_CPUSPEED=$failurecpuspeedpattern, TEST_TIMEZONE=$failuretimezonepattern, TEST_RESULT=FAIL[^,]*,/) {
debug "failure: $_"; debug "failure: $_";
push @failures, ($_); push @failures, ($_);
print FAILURELOG "$_\n"; print FAILURELOG "$_\n";
@ -201,17 +207,31 @@ if (defined($rawlogfile)) {
close FAILURELOG; close FAILURELOG;
die "FATAL ERROR in post-process-logs.pl" if $inputrc != 0; die "FATAL ERROR in post-process-logs.pl" if $inputrc != 0;
} }
else { else
{
debug "loading failures $failurelogfile"; debug "loading failures $failurelogfile";
open FAILURES, "<$failurelogfile" or die "Unable to open current failure log $failurelogfile: $!\n"; my $failurelogfilemode;
if ($failurelogfile =~ /\.bz2$/)
{
$failurelogfilemode = "bzcat $failurelogfile|";
}
elsif ($failurelogfile =~ /\.gz$/)
{
$failurelogfilemode = "zcat $failurelogfile|";
}
else
{
$failurelogfilemode = "<$failurelogfile";
}
open FAILURES, "$failurelogfilemode" or die "Unable to open current failure log $failurelogfile: $!\n";
while (<FAILURES>) { while (<FAILURES>) {
chomp; chomp;
if ($_ =~ /^TEST_ID=[^,]*, TEST_BRANCH=$failurebranchpattern, TEST_RESULT=FAIL[^,]*, TEST_BUILDTYPE=$failurebuildtypepattern, TEST_TYPE=$failuretesttypepattern, TEST_OS=$failureospattern, TEST_MACHINE=[^,]*, TEST_PROCESSORTYPE=$failurearchpattern, TEST_KERNEL=$failurekernelpattern, TEST_DATE=[^,]*, TEST_TIMEZONE=$failuretimezonepattern,/) { if ($_ =~ /^TEST_ID=[^,]*, TEST_BRANCH=$failurebranchpattern, TEST_BUILDTYPE=$failurebuildtypepattern, TEST_TYPE=$failuretesttypepattern, TEST_OS=$failureospattern, TEST_KERNEL=$failurekernelpattern, TEST_PROCESSORTYPE=$failurearchpattern, TEST_MEMORY=$failurememorypattern, TEST_CPUSPEED=$failurecpuspeedpattern, TEST_TIMEZONE=$failuretimezonepattern, TEST_RESULT=FAIL[^,]*,/) {
debug "failure: $_"; debug "failure: $_";
push @failures, ($_); push @failures, ($_);
} }
@ -343,25 +363,35 @@ sub usage {
usage: $msg usage: $msg
known-failures.pl [-b|--branch] branch [-T|--buildtype] buildtype known-failures.pl [-b|--branch] branch
[-t|--testtype] testtype [-o os|--os] [-T|--buildtype] buildtype
[-t|--testtype] testtype
[-o|--os] os
[-K|--kernel] kernel
[-A|--arch] arch
[-M|--memory] memory
[-S|--speed] speed
[-z|--timezone] timezone
[-r|--patterns] patterns
([-f|--failurelogfile] failurelogfile|[-l|--logfile] rawlogfile]) ([-f|--failurelogfile] failurelogfile|[-l|--logfile] rawlogfile])
[-r|--patterns] patterns [-z|--timezone] timezone
[-O|--outputprefix] outputprefix [-O|--outputprefix] outputprefix
[-D]
variable description variable description
=============== ============================================================ =============== ============================================================
-b branch branch 1.8.0, 1.8.1, 1.9.0, all -b branch branch 1.8.0, 1.8.1, 1.9.0, all
-T buildtype build type opt, debug, all -T buildtype build type opt, debug, all
-t testtype test type browser, shell, all -t testtype test type browser, shell, all
-o os operating system nt, darwin, linux, all
-K kernel kernel, all or a specific pattern
-A arch architecture, all or a specific pattern
-M memory memory in Gigabytes, all or a specific pattern
-S speed speed, all or specific pattern
-z timezone -0400, -0700, etc. default to user\'s zone
-l rawlogfile raw logfile -l rawlogfile raw logfile
-f failurelogfile failure logfile -f failurelogfile failure logfile
-o os operating system win32, mac, linux, all
-r patterns known failure patterns -r patterns known failure patterns
-z timezone -0400, -0700, etc. default to user\'s zone
-O outputprefix output files will be generated with this prefix -O outputprefix output files will be generated with this prefix
-A arch architecture, all or a specific pattern
-K kernel kernel, all or a specific pattern
-D turn on debugging output -D turn on debugging output
EOF EOF
@ -385,30 +415,48 @@ sub parse_options {
elsif ($option eq "t") { elsif ($option eq "t") {
$testtype = $value; $testtype = $value;
} }
elsif ($option eq "o") {
$os = $value;
}
elsif ($option eq "K") {
$kernel = $value;
}
elsif ($option eq "A") {
$arch = $value;
}
elsif ($option eq "M") {
$memory = $value;
}
elsif ($option eq "S") {
$cpuspeed = $value;
if ($cpuspeed < 4)
{
$cpuspeed = 'slow';
}
elsif ($cpuspeed < 9)
{
$cpuspeed = 'medium';
}
else
{
$cpuspeed = 'fast';
}
}
elsif ($option eq "z") {
$timezone = $value;
}
elsif ($option eq "r") {
$patterns = $value;
}
elsif ($option eq "l") { elsif ($option eq "l") {
$rawlogfile = $value; $rawlogfile = $value;
} }
elsif ($option eq "f") { elsif ($option eq "f") {
$failurelogfile = $value; $failurelogfile = $value;
} }
elsif ($option eq "o") {
$os = $value;
}
elsif ($option eq "r") {
$patterns = $value;
}
elsif ($option eq "z") {
$timezone = $value;
}
elsif ($option eq "O") { elsif ($option eq "O") {
$outputprefix = $value; $outputprefix = $value;
} }
elsif ($option eq "A") {
$arch = $value;
}
elsif ($option eq "K") {
$kernel = $value;
}
elsif ($option eq "D") { elsif ($option eq "D") {
$debug = 1; $debug = 1;
} }
@ -416,7 +464,7 @@ sub parse_options {
} }
if ($debug) { if ($debug) {
print "branch=$branch, rawlogfile=$rawlogfile failurelogfile=$failurelogfile, os=$os, buildtype=$buildtype, testtype=$testtype, patterns=$patterns, timezone=$timezone, outputprefix=$outputprefix\n"; print "branch=$branch, buildtype=$buildtype, testtype=$testtype, os=$os, kernel=$kernel, arch=$arch, memory=$memory, cpuspeed=$cpuspeed, timezone=$timezone, patterns=$patterns, rawlogfile=$rawlogfile failurelogfile=$failurelogfile, outputprefix=$outputprefix\n";
} }
Getopt::Mixed::cleanup(); Getopt::Mixed::cleanup();
@ -424,15 +472,6 @@ sub parse_options {
usage "missing branch"; usage "missing branch";
} }
if (!defined($rawlogfile) && !defined($failurelogfile)) {
usage "missing logfile";
}
if (!defined($os)) {
usage "missing os";
}
if (!defined($buildtype)) { if (!defined($buildtype)) {
usage "missing buildtype"; usage "missing buildtype";
} }
@ -441,60 +480,61 @@ sub parse_options {
usage "missing testtype"; usage "missing testtype";
} }
if (!defined($patterns)) { if (!defined($os)) {
usage "missing patterns"; usage "missing os";
} }
if (!defined($memory)) {
$memory = 'all';
}
if (!defined($cpuspeed)) {
$cpuspeed = 'all';
}
if (!defined($timezone)) { if (!defined($timezone)) {
usage "missing timezone"; usage "missing timezone";
} }
if (!defined($patterns)) {
usage "missing patterns";
}
if (!defined($rawlogfile) && !defined($failurelogfile)) {
usage "missing logfile";
}
if (!defined($outputprefix)) { if (!defined($outputprefix)) {
usage "missing outputprefix"; usage "missing outputprefix";
} }
if ($branch eq "1.8.0") { if ($branch eq "1.8.0") {
$knownfailurebranchpattern = "([^,]*1\\.8\\.0[^,]*|\\.\\*)"; $knownfailurebranchpattern = "(1\\.8\\.0|\\.\\*)";
$failurebranchpattern = "1\\.8\\.0"; $failurebranchpattern = "1\\.8\\.0";
} }
if ($branch eq "1.8.1") { elsif ($branch eq "1.8.1") {
$knownfailurebranchpattern = "([^,]*1\\.8\\.1[^,]*|\\.\\*)"; $knownfailurebranchpattern = "(1\\.8\\.1|\\.\\*)";
$failurebranchpattern = "1\\.8\\.1"; $failurebranchpattern = "1\\.8\\.1";
} }
elsif ($branch eq "1.9.0") { elsif ($branch eq "1.9.0") {
$knownfailurebranchpattern = "([^,]*1\\.9\\.0[^,]*|\\.\\*)"; $knownfailurebranchpattern = "(1\\.9\\.0|\\.\\*)";
$failurebranchpattern = "1\\.9\\.0"; $failurebranchpattern = "1\\.9\\.0";
} }
elsif ($branch eq "1.9.1") {
$knownfailurebranchpattern = "(1\\.9\\.1|\\.\\*)";
$failurebranchpattern = "1\\.9\\.1";
}
elsif ($branch eq "all") { elsif ($branch eq "all") {
$knownfailurebranchpattern = "[^,]*"; $knownfailurebranchpattern = "[^,]*";
$failurebranchpattern = "[^,]*"; $failurebranchpattern = "[^,]*";
} }
if ($os eq "win32") {
$knownfailureospattern = "([^,]*win32[^,]*|\\.\\*)";
$failureospattern = "win32";
}
elsif ($os eq "mac") {
$knownfailureospattern = "([^,]*mac[^,]*|\\.\\*)";
$failureospattern = "mac";
}
elsif ($os eq "linux") {
$knownfailureospattern = "([^,]*linux[^,]*|\\.\\*)";
$failureospattern = "linux";
}
elsif ($os eq "all") {
$knownfailureospattern = "[^,]*";
$failureospattern = "[^,]*";
}
if ($buildtype eq "opt") { if ($buildtype eq "opt") {
$knownfailurebuildtypepattern = "([^,]*opt[^,]*|\\.\\*)"; $knownfailurebuildtypepattern = "(opt|\\.\\*)";
$failurebuildtypepattern = "opt"; $failurebuildtypepattern = "opt";
} }
elsif ($buildtype eq "debug") { elsif ($buildtype eq "debug") {
$knownfailurebuildtypepattern = "([^,]*debug[^,]*|\\.\\*)"; $knownfailurebuildtypepattern = "(debug|\\.\\*)";
$failurebuildtypepattern = "debug"; $failurebuildtypepattern = "debug";
} }
elsif ($buildtype eq "all") { elsif ($buildtype eq "all") {
@ -503,11 +543,11 @@ sub parse_options {
} }
if ($testtype eq "shell") { if ($testtype eq "shell") {
$knownfailuretesttypepattern = "([^,]*shell[^,]*|\\.\\*)"; $knownfailuretesttypepattern = "(shell|\\.\\*)";
$failuretesttypepattern = "shell"; $failuretesttypepattern = "shell";
} }
elsif ($testtype eq "browser") { elsif ($testtype eq "browser") {
$knownfailuretesttypepattern = "([^,]*browser[^,]*|\\.\\*)"; $knownfailuretesttypepattern = "(browser|\\.\\*)";
$failuretesttypepattern = "browser"; $failuretesttypepattern = "browser";
} }
elsif ($testtype eq "all") { elsif ($testtype eq "all") {
@ -515,17 +555,34 @@ sub parse_options {
$failuretesttypepattern = "[^,]*"; $failuretesttypepattern = "[^,]*";
} }
if ($timezone eq "all") { if ($os eq "nt") {
$knownfailuretimezonepattern = "[^,]*"; $knownfailureospattern = "(nt|\\.\\*)";
$failuretimezonepattern = "[^,]*"; $failureospattern = "nt";
}
elsif ($os eq "darwin") {
$knownfailureospattern = "(darwin|\\.\\*)";
$failureospattern = "darwin";
}
elsif ($os eq "linux") {
$knownfailureospattern = "(linux|\\.\\*)";
$failureospattern = "linux";
}
elsif ($os eq "all") {
$knownfailureospattern = "[^,]*";
$failureospattern = "[^,]*";
}
if ($kernel ne "all") {
$knownfailurekernelpattern = "(" . $kernel . "|\\.\\*)";
$failurekernelpattern = "$kernel";
} }
else { else {
$knownfailuretimezonepattern = "([^,]*" . $timezone . "[^,]*|\\.\\*)"; $knownfailurekernelpattern = "[^,]*";
$failuretimezonepattern = "$timezone"; $failurekernelpattern = "[^,]*";
} }
if ($arch ne "all") { if ($arch ne "all") {
$knownfailurearchpattern = "([^,]*" . $arch . "[^,]*|\\.\\*)"; $knownfailurearchpattern = "(" . $arch . "|\\.\\*)";
$failurearchpattern = "$arch"; $failurearchpattern = "$arch";
} }
else { else {
@ -533,13 +590,31 @@ sub parse_options {
$failurearchpattern = "[^,]*"; $failurearchpattern = "[^,]*";
} }
if ($kernel ne "all") { if ($memory ne "all") {
$knownfailurekernelpattern = "([^,]*" . $kernel . "[^,]*|\\.\\*)"; $knownfailurememorypattern = "(" . $memory . "|\\.\\*)";
$failurekernelpattern = "$kernel"; $failurememorypattern = "$memory";
} }
else { else {
$knownfailurekernelpattern = "[^,]*"; $knownfailurememorypattern = "[^,]*";
$failurekernelpattern = "[^,]*"; $failurememorypattern = "[^,]*";
}
if ($cpuspeed ne "all") {
$knownfailurecpuspeedpattern = "(" . $cpuspeed . "|\\.\\*)";
$failurecpuspeedpattern = "$cpuspeed";
}
else {
$knownfailurecpuspeedpattern = "[^,]*";
$failurecpuspeedpattern = "[^,]*";
}
if ($timezone eq "all") {
$knownfailuretimezonepattern = "[^,]*";
$failuretimezonepattern = "[^,]*";
}
else {
$knownfailuretimezonepattern = "(" . $timezone . "|\\.\\*)";
$failuretimezonepattern = "$timezone";
} }

View File

@ -0,0 +1,159 @@
#!/usr/bin/perl -w
# -*- Mode: Perl; tab-width: 4; indent-tabs-mode: nil; -*-
# ***** 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 JavaScript Testing Utilities
#
# The Initial Developer of the Original Code is
# Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): Bob Clary <bclary@bclary.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
# usage: pattern-expander.pl knownfailures > knownfailures.expanded
#
# pattern-expander.pl reads the specified knownfailures file and
# writes to stdout an expanded set of failures where the wildcards
# ".*" are replaced with the set of possible values specified in the
# universe.data file.
use lib "/work/mozilla/mozilla.com/test.mozilla.com/www/tests/mozilla.org/js";
use Patterns;
package Patterns;
processfile();
sub processfile
{
my ($i, $j);
while (<ARGV>) {
chomp;
$record = {};
my ($test_id, $test_branch, $test_buildtype, $test_type, $test_os, $test_kernel, $test_processortype, $test_memory, $test_cpuspeed, $test_timezone, $test_result, $test_exitstatus, $test_description) = $_ =~
/TEST_ID=([^,]*), TEST_BRANCH=([^,]*), TEST_BUILDTYPE=([^,]*), TEST_TYPE=([^,]*), TEST_OS=([^,]*), TEST_KERNEL=([^,]*), TEST_PROCESSORTYPE=([^,]*), TEST_MEMORY=([^,]*), TEST_CPUSPEED=([^,]*), TEST_TIMEZONE=([^,]*), TEST_RESULT=([^,]*), TEST_EXITSTATUS=([^,]*), TEST_DESCRIPTION=(.*)/;
$record->{TEST_ID} = $test_id;
$record->{TEST_BRANCH} = $test_branch;
$record->{TEST_BUILDTYPE} = $test_buildtype;
$record->{TEST_TYPE} = $test_type;
$record->{TEST_OS} = $test_os;
$record->{TEST_KERNEL} = $test_kernel;
$record->{TEST_PROCESSORTYPE} = $test_processortype;
$record->{TEST_MEMORY} = $test_memory;
$record->{TEST_CPUSPEED} = $test_cpuspeed;
$record->{TEST_TIMEZONE} = $test_timezone;
$record->{TEST_RESULT} = $test_result;
$record->{TEST_EXITSTATUS} = $test_exitstatus;
$record->{TEST_DESCRIPTION} = $test_description;
dbg("processfile: \$_=$_");
my @list1 = ();
my @list2 = ();
my $iuniversefield;
my $universefield;
$item1 = copyreference($record);
dbg("processfile: check copyreference");
dbg("processfile: \$record=" . recordtostring($record));
dbg("processfile: \$item1=" . recordtostring($item1));
push @list1, ($item1);
for ($iuniversefield = 0; $iuniversefield < @universefields; $iuniversefield++)
{
$universefield = $universefields[$iuniversefield];
dbg("processfile: \$universefields[$iuniversefield]=$universefield, \$record->{$universefield}=$record->{$universefield}");
for ($j = 0; $j < @list1; $j++)
{
$item1 = $list1[$j];
dbg("processfile: item1 \$list1[$j]=" . recordtostring($item1));
# create a reference to a copy of the hash referenced by $item1
if ($item1->{$universefield} ne '.*')
{
dbg("processfile: literal value");
$item2 = copyreference($item1);
dbg("processfile: check copyreference");
dbg("processfile: \$item1=" . recordtostring($item1));
dbg("processfile: \$item2=" . recordtostring($item2));
dbg("processfile: pushing existing record to list 2: " . recordtostring($item2));
push @list2, ($item2);
}
else
{
dbg("processfile: wildcard value");
$keyfielduniversekey = getuniversekey($item1, $universefield);
@keyfielduniverse = getuniverse($keyfielduniversekey, $universefield);
dbg("processfile: \$keyfielduniversekey=$keyfielduniversekey, \@keyfielduniverse=" . join(',', @keyfielduniverse));
for ($i = 0; $i < @keyfielduniverse; $i++)
{
$item2 = copyreference($item1);
dbg("processfile: check copyreference");
dbg("processfile: \$item1=" . recordtostring($item1));
dbg("processfile: \$item2=" . recordtostring($item2));
$item2->{$universefield} = $keyfielduniverse[$i];
dbg("processfile: pushing new record to list 2 " . recordtostring($item2));
push @list2, ($item2);
}
}
for ($i = 0; $i < @list1; $i++)
{
dbg("processfile: \$list1[$i]=" . recordtostring($list1[$i]));
}
for ($i = 0; $i < @list2; $i++)
{
dbg("processfile: \$list2[$i]=" . recordtostring($list2[$i]));
}
}
@list1 = @list2;
@list2 = ();
}
for ($j = 0; $j < @list1; $j++)
{
$item1 = $list1[$j];
push @records, ($item1);
}
}
@records = sort sortrecords @records;
dumprecords();
}

View File

@ -0,0 +1,217 @@
#!/usr/bin/perl -w
# -*- Mode: Perl; tab-width: 4; indent-tabs-mode: nil; -*-
# ***** 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 JavaScript Testing Utilities
#
# The Initial Developer of the Original Code is
# Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): Bob Clary <bclary@bclary.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
# usage: pattern-extracter.pl knownfailures.expanded > knownfailures
#
# pattern-extracter.pl reads the specified expanded knownfailures file
# (see pattern-expander.pl) and writes to stdout a set of knownfailures
# where repetitions of values found in the universe.data file are
# replaced with wildcards ".*".
use lib "/work/mozilla/mozilla.com/test.mozilla.com/www/tests/mozilla.org/js";
use Patterns;
package Patterns;
my $universefield;
processfile();
sub processfile
{
my $recordcurr = {};
my $recordprev;
my @output;
my $keycurr = '';
my $keyprev = '';
my @values = ();
my $universefielduniversekey; # universekey for universefield
my @universefielduniverse;
my $i;
my $j;
my $v;
while (<ARGV>) {
chomp;
$recordcurr = {};
my ($test_id, $test_branch, $test_buildtype, $test_type, $test_os, $test_kernel, $test_processortype, $test_memory, $test_cpuspeed, $test_timezone, $test_result, $test_exitstatus, $test_description) = $_ =~
/TEST_ID=([^,]*), TEST_BRANCH=([^,]*), TEST_BUILDTYPE=([^,]*), TEST_TYPE=([^,]*), TEST_OS=([^,]*), TEST_KERNEL=([^,]*), TEST_PROCESSORTYPE=([^,]*), TEST_MEMORY=([^,]*), TEST_CPUSPEED=([^,]*), TEST_TIMEZONE=([^,]*), TEST_RESULT=([^,]*), TEST_EXITSTATUS=([^,]*), TEST_DESCRIPTION=(.*)/;
$recordcurr->{TEST_ID} = $test_id;
$recordcurr->{TEST_BRANCH} = $test_branch;
$recordcurr->{TEST_BUILDTYPE} = $test_buildtype;
$recordcurr->{TEST_TYPE} = $test_type;
$recordcurr->{TEST_OS} = $test_os;
$recordcurr->{TEST_KERNEL} = $test_kernel;
$recordcurr->{TEST_PROCESSORTYPE} = $test_processortype;
$recordcurr->{TEST_MEMORY} = $test_memory;
$recordcurr->{TEST_CPUSPEED} = $test_cpuspeed;
$recordcurr->{TEST_TIMEZONE} = $test_timezone;
$recordcurr->{TEST_RESULT} = $test_result;
$recordcurr->{TEST_EXITSTATUS} = $test_exitstatus;
$recordcurr->{TEST_DESCRIPTION} = $test_description;
push @records, ($recordcurr);
}
for ($j = $#universefields; $j >= 0; $j--)
{
$universefield = $universefields[$j];
@records = sort {getkey($a, $universefield) cmp getkey($b, $universefield);} @records;
$recordprev = $records[0];
$keyprev = getkey($recordprev, $universefield);
@values = ();
my $recordtemp;
my $keytemp;
dbg("processfile: begin processing records for \$universefields[$j]=$universefield");
for ($i = 0; $i < @records; $i++)
{
$recordcurr = $records[$i];
$keycurr = getkey($recordcurr, $universefield);
dbg("processfile: processing record[$i]");
dbg("processfile: recordprev: " . recordtostring($recordprev));
dbg("processfile: recordcurr: " . recordtostring($recordcurr));
dbg("processfile: \$keyprev=$keyprev");
dbg("processfile: \$keycurr=$keycurr");
if ($keycurr ne $keyprev)
{
# key changed, must output previous record
dbg("processfile: new key");
$universefielduniversekey = getuniversekey($recordprev, $universefield);
@universefielduniverse = getuniverse($universefielduniversekey, $universefield);
dbg("processfile: \@values: ". join(',', @values));
dbg("processfile: \$universefielduniversekey=$universefielduniversekey, \@universefielduniverse=" . join(',', @universefielduniverse));
@values = ('.*') if (arraysequal(\@values, \@universefielduniverse));
dbg("processfile: \@values=" . join(',', @values));
for ($v = 0; $v < @values; $v++)
{
dbg("processfile: stuffing $values[$v]");
$recordtemp = copyreference($recordprev);
$recordtemp->{$universefield} = $values[$v];
dbg("processfile: stuffed $recordtemp->{$universefield}");
dbg("processfile: recordprev: " . recordtostring($recordprev));
dbg("processfile: output: " . recordtostring($recordtemp));
push @output, ($recordtemp);
}
@values = ();
}
dbg("processfile: collecting \$recordcurr->{$universefield}=$recordcurr->{$universefield}");
push @values, ($recordcurr->{$universefield});
$keyprev = $keycurr;
$recordprev = $recordcurr;
}
dbg("processfile: finish processing records for \$universefields[$j]=$universefield");
if (@values)
{
dbg("processfile: last record for \$universefields[$j]=$universefield has pending values");
$universefielduniversekey = getuniversekey($recordprev, $universefield);
@universefielduniverse = getuniverse($universefielduniversekey, $universefield);
dbg("processfile: \@values: ". join(',', @values));
dbg("processfile: \$universefielduniversekey=$universefielduniversekey, \@universefielduniverse=" . join(',', @universefielduniverse));
@values = ('.*') if (arraysequal(\@values, \@universefielduniverse));
dbg("processfile: \@values=" . join(',', @values));
for ($v = 0; $v < @values; $v++)
{
dbg("processfile: stuffing $values[$v]");
$recordtemp = copyreference($recordprev);
$recordtemp->{$universefield} = $values[$v];
dbg("processfile: stuffed $recordprev->{$universefield}");
dbg("processfile: recordprev: " . recordtostring($recordprev));
dbg("processfile: output: " . recordtostring($recordtemp));
push @output, ($recordtemp);
}
@values = ();
}
@records = @output;
@output = ();
}
@records = sort sortrecords @records;
dumprecords();
}
sub getkey
{
my ($record, $universefield) = @_;
my $i;
my $key = '';
for ($i = 0; $i < @sortkeyfields; $i++)
{
if ($sortkeyfields[$i] ne $universefield)
{
$key .= $record->{$sortkeyfields[$i]}
}
}
return $key;
}
sub arraysequal
{
my ($larrayref, $rarrayref) = @_;
my $i;
dbg("arraysequal: checking if " . (join ',', @{$larrayref}) . " is equal to " . (join ',', @{$rarrayref}));
return 0 if (@{$larrayref} != @{$rarrayref});
for ($i = 0; $i < @{$larrayref}; $i++)
{
return 0 if ($rarrayref->[$i] ne $larrayref->[$i]);
}
dbg("arraysequal: equal");
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@ -38,13 +38,13 @@
# ***** END LICENSE BLOCK ***** # ***** END LICENSE BLOCK *****
if [[ -z "$TEST_DIR" ]]; then if [[ -z "$TEST_DIR" ]]; then
cat <<EOF cat <<EOF
`basename $0`: error `basename $0`: error
TEST_DIR, the location of the Sisyphus framework, TEST_DIR, the location of the Sisyphus framework,
is required to be set prior to calling this script. is required to be set prior to calling this script.
EOF EOF
exit 2 exit 2
fi fi
if [[ ! -e $TEST_DIR/bin/library.sh ]]; then if [[ ! -e $TEST_DIR/bin/library.sh ]]; then
@ -74,6 +74,14 @@ testlogfiles The test log to be processed. If testlogfiles is a file
pattern it must be single quoted to prevent the shell from pattern it must be single quoted to prevent the shell from
expanding it before it is passed to the script. expanding it before it is passed to the script.
kernel optional. The machine kernel as specified by uname -r
If not specified, the script will attempt to determine the
value from the TEST_KERNEL line in the log.
'all' - do not filter on machine kernel. Use this for
Windows.
For Linux distros, use the value of uname -r
and replace the minor version numbers with .* as in
2.6.23.1-21.fc7 -> 2.6.23.*fc7
arch optional. The machine architecture as specified by uname -p arch optional. The machine architecture as specified by uname -p
If not specified, the script will attempt to determine the If not specified, the script will attempt to determine the
value from the TEST_PROCESSORTYPE line in each log. value from the TEST_PROCESSORTYPE line in each log.
@ -83,25 +91,17 @@ arch optional. The machine architecture as specified by uname -p
'i386' - Mac Intel 'i386' - Mac Intel
'powerpc' - Mac PowerPC 'powerpc' - Mac PowerPC
kernel optional. The machine kernel as specified by uname -r
If not specified, the script will attempt to determine the
value from the TEST_KERNEL line in the log.
'all' - do not filter on machine kernel. Use this for
Windows.
For Linux distros, use the value of uname -r
and replace the minor version numbers with .* as in
2.6.23.1-21.fc7 -> 2.6.23.*fc7
EOF EOF
exit 2 exit 2
} }
while getopts "l:A:K:" optname; while getopts "l:A:K:" optname;
do do
case $optname in case $optname in
l) testlogfiles=$OPTARG;; l) testlogfiles=$OPTARG;;
A) optarch=$OPTARG;; A) optarch=$OPTARG;;
K) optkernel=$OPTARG;; K) optkernel=$OPTARG;;
esac esac
done done
if [[ -z "$testlogfiles" ]]; then if [[ -z "$testlogfiles" ]]; then
@ -112,6 +112,24 @@ for testlogfile in `ls $testlogfiles`; do
debug "testlogfile=$testlogfile" debug "testlogfile=$testlogfile"
case $testlogfile in
*.log)
worktestlogfile=$testlogfile
;;
*.log.bz2)
worktestlogfile=`mktemp $testlogfile.XXXXXX`
bunzip2 -c $testlogfile > $worktestlogfile
;;
*.log.gz)
worktestlogfile=`mktemp $testlogfile.XXXXXX`
gunzip -c $testlogfile > $worktestlogfile
;;
*)
echo "unknown log type: $f"
exit 2
;;
esac
case "$testlogfile" in case "$testlogfile" in
*,js,*) testtype=shell;; *,js,*) testtype=shell;;
*,firefox,*) testtype=browser;; *,firefox,*) testtype=browser;;
@ -133,8 +151,9 @@ for testlogfile in `ls $testlogfiles`; do
*,1.8.0*) branch=1.8.0;; *,1.8.0*) branch=1.8.0;;
*,1.8.1*) branch=1.8.1;; *,1.8.1*) branch=1.8.1;;
*,1.9.0*) branch=1.9.0;; *,1.9.0*) branch=1.9.0;;
*,1.9.1*) branch=1.9.1;;
*) *)
branch=`grep '^environment: TEST_BRANCH=' $testlogfile | sed 's|.*TEST_BRANCH=\(.*\)|\1|'` branch=`grep -m 1 '^environment: TEST_BRANCH=' $worktestlogfile | sed 's|.*TEST_BRANCH=\(.*\)|\1|'`
if [[ -z "$branch" ]]; then if [[ -z "$branch" ]]; then
error "unknown branch in logfile $testlogfile" $LINENO error "unknown branch in logfile $testlogfile" $LINENO
fi fi
@ -144,11 +163,11 @@ for testlogfile in `ls $testlogfiles`; do
debug "branch=$branch" debug "branch=$branch"
case "$testlogfile" in case "$testlogfile" in
*,win32,*) OSID=win32;; *,nt,*) OSID=nt;;
*,linux,*) OSID=linux;; *,linux,*) OSID=linux;;
*,mac,*) OSID=mac;; *,darwin,*) OSID=darwin;;
*) *)
OSID=`grep '^environment: OSID=' $testlogfile | sed 's|.*OSID=\(.*\)|\1|'` OSID=`grep -m 1 '^environment: OSID=' $worktestlogfile | sed 's|.*OSID=\(.*\)|\1|'`
if [[ -z "$OSID" ]]; then if [[ -z "$OSID" ]]; then
error "unknown OS in logfile $testlogfile" $LINENO error "unknown OS in logfile $testlogfile" $LINENO
fi fi
@ -160,11 +179,9 @@ for testlogfile in `ls $testlogfiles`; do
if [[ -n "$optkernel" ]]; then if [[ -n "$optkernel" ]]; then
kernel="$optkernel" kernel="$optkernel"
else else
if [[ "$OSID" == "win32" ]]; then kernel=`grep -m 1 '^environment: TEST_KERNEL=' $worktestlogfile | sed 's|.*TEST_KERNEL=\(.*\)|\1|'`
kernel=all if [[ "$OSID" == "linux" ]]; then
else kernel=`echo $kernel | sed 's|\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*|\1.\2.\3|'`
kernel=`grep '^environment: TEST_KERNEL=' $testlogfile | sed 's|.*TEST_KERNEL=\(.*\)|\1|'`
kernel=`echo $kernel | sed 's|\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)[-.0-9]*\.\([a-zA-Z0-9]*\)|\1.\2.\3.*\4|'`
fi fi
fi fi
@ -173,15 +190,14 @@ for testlogfile in `ls $testlogfiles`; do
if [[ -n "$optarch" ]]; then if [[ -n "$optarch" ]]; then
arch="$optarch" arch="$optarch"
else else
if [[ "$OSID" == "win32" ]]; then arch=`grep -m 1 '^environment: TEST_PROCESSORTYPE=' $worktestlogfile | sed 's|.*TEST_PROCESSORTYPE=\(.*\)|\1|'`
arch=all
else
arch=`grep '^environment: TEST_PROCESSORTYPE=' $testlogfile | sed 's|.*TEST_PROCESSORTYPE=\(.*\)|\1|'`
fi
fi fi
debug "arch=$arch" debug "arch=$arch"
memory=`grep -m 1 '^environment: TEST_MEMORY=' $worktestlogfile | sed 's|.*TEST_MEMORY=\(.*\)|\1|'`
speed=`grep -m 1 '^environment: TEST_CPUSPEED=' $worktestlogfile | sed 's|.*TEST_CPUSPEED=\(.*\)|\1|'`
timezone=`basename $testlogfile | sed 's|^[-0-9]*\([-+]\)\([0-9]\{4,4\}\),.*|\1\2|'` timezone=`basename $testlogfile | sed 's|^[-0-9]*\([-+]\)\([0-9]\{4,4\}\),.*|\1\2|'`
debug "timezone=$timezone" debug "timezone=$timezone"
@ -191,9 +207,25 @@ for testlogfile in `ls $testlogfiles`; do
includetests="included-$branch-$testtype-$buildtype.tests" includetests="included-$branch-$testtype-$buildtype.tests"
excludetests="excluded-$branch-$testtype-$buildtype.tests" excludetests="excluded-$branch-$testtype-$buildtype.tests"
grep '^include: ' $testlogfile | sed 's|include: ||' > $TEST_DIR/tests/mozilla.org/js/$includetests grep '^include: ' $worktestlogfile | sed 's|include: ||' > $TEST_DIR/tests/mozilla.org/js/$includetests
grep '^exclude: ' $testlogfile | sed 's|exclude: ||' > $TEST_DIR/tests/mozilla.org/js/$excludetests grep '^exclude: ' $worktestlogfile | sed 's|exclude: ||' > $TEST_DIR/tests/mozilla.org/js/$excludetests
$TEST_DIR/tests/mozilla.org/js/known-failures.pl -b "$branch" -T "$buildtype" -t "$testtype" -o "$OSID" -z "$timezone" -l "$testlogfile" -A "$arch" -K "$kernel" -r "$TEST_JSDIR/failures.txt" -O "$outputprefix" $TEST_DIR/tests/mozilla.org/js/known-failures.pl \
-b "$branch" \
-T "$buildtype" \
-t "$testtype" \
-o "$OSID" \
-K "$kernel" \
-A "$arch" \
-M "$memory" \
-S "$speed" \
-z "$timezone" \
-r "$TEST_JSDIR/failures.txt" \
-l "$worktestlogfile" \
-O "$outputprefix"
if [[ "$testlogfile" != "$worktestlogfile" ]]; then
rm $worktestlogfile
unset worktestlogfile
fi
done done

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,82 @@
#!/bin/bash
# -*- Mode: Shell-script; tab-width: 4; indent-tabs-mode: nil; -*-
# ***** 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 JavaScript Testing Utilities
#
# The Initial Developer of the Original Code is
# Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): Bob Clary <bclary@bclary.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
if [[ ! -e "$1" || ! -e "$2" ]]; then
cat <<EOF
Usage: remove-fixed-failures.sh possible-fixes.log failures.log
possible-fixes.log contains the possible fixes from the most recent
test run.
failures.log contains the current known failures.
remove-fixed-failures.sh removes each pattern in possible-fixes.log
from failures.log.
The original failures.log is saved as failures.log.orig for safe keeping.
EOF
exit 1
fi
fixes="$1"
failures="$2"
# save the original failures file in case of an error
cp $failures $failures.orig
# create a temporary file to contain the current list
# of failures.
workfailures=`mktemp working-failures.XXXXX`
workfixes=`mktemp working-fixes.XXXXX`
trap "rm -f $workfailures; rm -f $temp" EXIT
# create working copy of the failures file
cp $failures $workfailures
cp $fixes $workfixes
sed -i 's|:[^:]*\.log||' $workfixes;
grep -Fv -f $workfixes ${workfailures} > ${workfailures}.temp
mv $workfailures.temp $workfailures
mv $workfailures $failures

View File

@ -38,13 +38,13 @@
# ***** END LICENSE BLOCK ***** # ***** END LICENSE BLOCK *****
if [[ -z "$TEST_DIR" ]]; then if [[ -z "$TEST_DIR" ]]; then
cat <<EOF cat <<EOF
`basename $0`: error `basename $0`: error
TEST_DIR, the location of the Sisyphus framework, TEST_DIR, the location of the Sisyphus framework,
is required to be set prior to calling this script. is required to be set prior to calling this script.
EOF EOF
exit 2 exit 2
fi fi
if [[ ! -e $TEST_DIR/bin/library.sh ]]; then if [[ ! -e $TEST_DIR/bin/library.sh ]]; then
@ -66,15 +66,17 @@ TEST_JSDIR=`dirname $0`
usage() usage()
{ {
cat <<EOF cat <<EOF
usage: runtests.sh -p products -b branches -T buildtypes -B buildcommands -e extra [-v] \\ usage: runtests.sh -p products -b branches -e extra\\
-S -R -X excludetests -I includetests -c -t -T buildtypes -B buildcommands \\
[-v] [-S] [-X excludetests] [-I includetests] [-c] [-t] \\
[-Z n]
variable description variable description
=============== ============================================================ =============== ============================================================
-p products space separated list of js, firefox -p products space separated list of js, firefox
-b branches space separated list of branches 1.8.0, 1.8.1, 1.9.0 -b branches space separated list of branches 1.8.0, 1.8.1, 1.9.0, 1.9.1
-T buildtypes space separated list of build types opt debug
-e extra optional. extra qualifier to pick build tree and mozconfig. -e extra optional. extra qualifier to pick build tree and mozconfig.
-T buildtypes space separated list of build types opt debug
-B buildcommands optional space separated list of build commands -B buildcommands optional space separated list of build commands
clean, checkout, build. If not specified, defaults to clean, checkout, build. If not specified, defaults to
'clean checkout build'. 'clean checkout build'.
@ -83,10 +85,6 @@ variable description
-v optional. verbose - copies log file output to stdout. -v optional. verbose - copies log file output to stdout.
-S optional. summary - output tailered for use with -S optional. summary - output tailered for use with
Buildbot|Tinderbox Buildbot|Tinderbox
-R optional. by default the browser test will start Firefox
Spider and execute the tests one after another in the same
process. -R will start an new instance of Firefox for each
test. This has no effect for shell based tests.
-X excludetests optional. By default the test will exclude the -X excludetests optional. By default the test will exclude the
tests listed in spidermonkey-n-\$branch.tests, tests listed in spidermonkey-n-\$branch.tests,
performance-\$branch.tests. excludetests is a list of either performance-\$branch.tests. excludetests is a list of either
@ -97,8 +95,6 @@ variable description
list of either individual tests, manifest files or list of either individual tests, manifest files or
sub-directories which will override the default inclusion sub-directories which will override the default inclusion
list. list.
-Z n optional. Set gczeal to n. Currently, only valid for
Gecko 1.9.0 and later.
-c optional. By default the test will exclude tests -c optional. By default the test will exclude tests
which crash on this branch, test type, build type and which crash on this branch, test type, build type and
operating system. -c will include tests which crash. operating system. -c will include tests which crash.
@ -108,6 +104,8 @@ variable description
-t optional. By default the test will exclude tests -t optional. By default the test will exclude tests
which time out on this branch, test type, build type and which time out on this branch, test type, build type and
operating system. -t will include tests which timeout. operating system. -t will include tests which timeout.
-Z n optional. Set gczeal to n. Currently, only valid for
debug builds of Gecko 1.8.1.15, 1.9.0 and later.
if an argument contains more than one value, it must be quoted. if an argument contains more than one value, it must be quoted.
EOF EOF
@ -116,7 +114,7 @@ EOF
verbose=0 verbose=0
while getopts "p:b:T:B:e:X:I:Z:vSRct" optname; while getopts "p:b:T:B:e:X:I:Z:vSct" optname;
do do
case $optname in case $optname in
p) products=$OPTARG;; p) products=$OPTARG;;
@ -127,7 +125,6 @@ do
B) buildcommands=$OPTARG;; B) buildcommands=$OPTARG;;
v) verbose=1 v) verbose=1
verboseflag="-v";; verboseflag="-v";;
R) restart=1;;
S) summary=1;; S) summary=1;;
X) excludetests=$OPTARG;; X) excludetests=$OPTARG;;
I) includetests=$OPTARG;; I) includetests=$OPTARG;;
@ -180,24 +177,6 @@ if [[ -n "$fatalerrors" ]]; then
error "`tail -n 20 ${testlogarray[$itestlog]}`" $LINENO error "`tail -n 20 ${testlogarray[$itestlog]}`" $LINENO
fi fi
case "$OSID" in
win32)
arch=all
kernel=all
;;
linux)
arch="`uname -p`"
kernel="`uname -r | sed 's|\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)[-.0-9]*\.\([a-zA-Z0-9]*\)|\1.\2.\3.*\4|'`"
;;
mac)
arch="`uname -p`"
kernel=all
;;
*)
error "$OSID not supported" $LINENO
;;
esac
for testlogfile in $testlogfiles; do for testlogfile in $testlogfiles; do
if [[ -n "$DEBUG" ]]; then if [[ -n "$DEBUG" ]]; then
@ -209,29 +188,45 @@ for testlogfile in $testlogfiles; do
*,firefox,*) testtype=browser;; *,firefox,*) testtype=browser;;
*) error "unknown testtype in logfile $testlogfile" $LINENO;; *) error "unknown testtype in logfile $testlogfile" $LINENO;;
esac esac
case "$testlogfile" in case "$testlogfile" in
*,opt,*) buildtype=opt;; *,opt,*) buildtype=opt;;
*,debug,*) buildtype=debug;; *,debug,*) buildtype=debug;;
*,nightly,*) buildtype=opt;;
*) error "unknown buildtype in logfile $testlogfile" $LINENO;; *) error "unknown buildtype in logfile $testlogfile" $LINENO;;
esac esac
case "$testlogfile" in case "$testlogfile" in
*,1.8.0*) branch=1.8.0;; *,1.8.0*) branch=1.8.0;;
*,1.8.1*) branch=1.8.1;; *,1.8.1*) branch=1.8.1;;
*,1.9.0*) branch=1.9.0;; *,1.9.0*) branch=1.9.0;;
*,1.9.1*) branch=1.9.1;;
*) error "unknown branch in logfile $testlogfile" $LINENO;; *) error "unknown branch in logfile $testlogfile" $LINENO;;
esac esac
outputprefix=$testlogfile outputprefix=$testlogfile
if [[ -n "$DEBUG" ]]; then if [[ -n "$DEBUG" ]]; then
dumpvars branch buildtype testtype OSID testlogfile arch kernel outputprefix dumpvars branch buildtype testtype OSID testlogfile TEST_PROCESSORTYPE TEST_KERNEL outputprefix
fi fi
if ! $TEST_DIR/tests/mozilla.org/js/known-failures.pl -b $branch -T $buildtype -t $testtype -o "$OSID" -z `date +%z` -l $testlogfile -A "$arch" -K "$kernel" -r $TEST_JSDIR/failures.txt -O $outputprefix; then if ! $TEST_DIR/tests/mozilla.org/js/known-failures.pl \
-b $branch \
-T $buildtype \
-t $testtype \
-o "$OSID" \
-K "$TEST_KERNEL" \
-A "$TEST_PROCESSORTYPE" \
-M "$TEST_MEMORY" \
-S "$TEST_CPUSPEED" \
-z `date +%z` \
-l $testlogfile \
-r $TEST_JSDIR/failures.txt \
-O $outputprefix; then
error "known-failures.pl" $LINENO error "known-failures.pl" $LINENO
fi fi
if [[ -n "$summary" ]]; then if [[ -n "$summary" ]]; then
# use let to work around mac problem where numbers were # use let to work around mac problem where numbers were
# output with leading characters. # output with leading characters.
# if let's arg evaluates to 0, let will return 1 # if let's arg evaluates to 0, let will return 1
@ -252,6 +247,6 @@ for testlogfile in $testlogfiles; do
echo -e "\nTinderboxPrint:<div title=\"$testlogfile\">\n" echo -e "\nTinderboxPrint:<div title=\"$testlogfile\">\n"
echo -e "\nTinderboxPrint:js tests<br/>$branch $buildtype $testtype<br/>$npass/$nfail<br/>F:$nfixes R:$nregressions" echo -e "\nTinderboxPrint:js tests<br/>$branch $buildtype $testtype<br/>$npass/$nfail<br/>F:$nfixes R:$nregressions"
echo -e "\nTinderboxPrint:</div>\n" echo -e "\nTinderboxPrint:</div>\n"
fi fi
done done

View File

@ -160,8 +160,8 @@ TestCase.prototype.dump = function () {
'result: ' + (this.passed ? 'PASSED':'FAILED') + ' ' + 'result: ' + (this.passed ? 'PASSED':'FAILED') + ' ' +
'type: ' + this.type + ' ' + 'type: ' + this.type + ' ' +
'description: ' + toPrinted(this.description) + ' ' + 'description: ' + toPrinted(this.description) + ' ' +
'expected: ' + toPrinted(this.expect) + ' ' + // 'expected: ' + toPrinted(this.expect) + ' ' +
'actual: ' + toPrinted(this.actual) + ' ' + // 'actual: ' + toPrinted(this.actual) + ' ' +
'reason: ' + toPrinted(this.reason) + '\n'); 'reason: ' + toPrinted(this.reason) + '\n');
}; };
@ -232,10 +232,47 @@ function toPrinted(value)
{ {
value = String(value); value = String(value);
} }
value = value.replace(/\\n/g, 'NL').replace(/\n/g, 'NL').replace(/\\r/g, 'CR'); value = value.replace(/\\n/g, 'NL')
.replace(/\n/g, 'NL')
.replace(/\\r/g, 'CR')
.replace(/[^\x20-\x7E]+/g, escapeString);
return value; return value;
} }
function escapeString (str)
{
var a, b, c, d;
var len = str.length;
var result = "";
var digits = ["0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", "A", "B", "C", "D", "E", "F"];
for (var i=0; i<len; i++)
{
var ch = str.charCodeAt(i);
a = digits[ch & 0xf];
ch >>= 4;
b = digits[ch & 0xf];
ch >>= 4;
if (ch)
{
c = digits[ch & 0xf];
ch >>= 4;
d = digits[ch & 0xf];
result += "\\u" + d + c + b + a;
}
else
{
result += "\\x" + b + a;
}
}
return result;
}
/* /*
* Compare expected result to actual result, if they differ (in value and/or * Compare expected result to actual result, if they differ (in value and/or
* type) report a failure. If description is provided, include it in the * type) report a failure. If description is provided, include it in the
@ -245,9 +282,15 @@ function reportCompare (expected, actual, description) {
var expected_t = typeof expected; var expected_t = typeof expected;
var actual_t = typeof actual; var actual_t = typeof actual;
var output = ""; var output = "";
if ((VERBOSE) && (typeof description != "undefined")) if (typeof description == "undefined")
{
description = '';
}
else if (VERBOSE)
{
printStatus ("Comparing '" + description + "'"); printStatus ("Comparing '" + description + "'");
}
if (expected_t != actual_t) if (expected_t != actual_t)
{ {
@ -271,19 +314,16 @@ function reportCompare (expected, actual, description) {
"' matched actual value '" + toPrinted(actual) + "'"); "' matched actual value '" + toPrinted(actual) + "'");
} }
if (typeof description == "undefined")
description = '';
var testcase = new TestCase(gTestfile, description, expected, actual); var testcase = new TestCase(gTestfile, description, expected, actual);
testcase.reason = output; testcase.reason = output;
if (testcase.passed) if (testcase.passed)
{ {
print('PASSED! ' + description); print(PASSED + description);
} }
else else
{ {
reportFailure (output); reportFailure (description + " : " + output);
} }
return testcase.passed; return testcase.passed;
@ -300,8 +340,14 @@ function reportMatch (expectedRegExp, actual, description) {
var actual_t = typeof actual; var actual_t = typeof actual;
var output = ""; var output = "";
if ((VERBOSE) && (typeof description != "undefined")) if (typeof description == "undefined")
{
description = '';
}
else if (VERBOSE)
{
printStatus ("Comparing '" + description + "'"); printStatus ("Comparing '" + description + "'");
}
if (expected_t != actual_t) if (expected_t != actual_t)
{ {
@ -326,19 +372,16 @@ function reportMatch (expectedRegExp, actual, description) {
"' matched actual value '" + toPrinted(actual) + "'"); "' matched actual value '" + toPrinted(actual) + "'");
} }
if (typeof description == "undefined")
description = '';
var testcase = new TestCase(gTestfile, description, true, matches); var testcase = new TestCase(gTestfile, description, true, matches);
testcase.reason = output; testcase.reason = output;
if (testcase.passed) if (testcase.passed)
{ {
print('PASSED! ' + description); print(PASSED + description);
} }
else else
{ {
reportFailure (output); reportFailure (description + " : " + output);
} }
return testcase.passed; return testcase.passed;

File diff suppressed because it is too large Load Diff

View File

@ -1,336 +0,0 @@
#!/bin/bash -e
# -*- Mode: Shell-script; tab-width: 4; indent-tabs-mode: nil; -*-
# ***** 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 JavaScript Testing Utilities
#
# The Initial Developer of the Original Code is
# Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2007
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): Bob Clary <bclary@bclary.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
if [[ -z "$TEST_DIR" ]]; then
cat <<EOF
`basename $0`: error
TEST_DIR, the location of the Sisyphus framework,
is required to be set prior to calling this script.
EOF
exit 2
fi
if [[ ! -e $TEST_DIR/bin/library.sh ]]; then
echo "TEST_DIR=$TEST_DIR"
echo ""
echo "This script requires the Sisyphus testing framework. Please "
echo "cvs check out the Sisyphys framework from mozilla/testing/sisyphus"
echo "and set the environment variable TEST_DIR to the directory where it"
echo "located."
echo ""
exit 2
fi
source $TEST_DIR/bin/library.sh
TEST_JSDIR=`dirname $0`
TEST_JSEACH_TIMEOUT=${TEST_JSEACH_TIMEOUT:-485}
TEST_JSEACH_PAGE_TIMEOUT=${TEST_JSEACH_PAGE_TIMEOUT:-480}
TEST_JSALL_TIMEOUT=${TEST_JSALL_TIMEOUT:-21600}
TEST_WWW_JS=`echo $TEST_JSDIR|sed "s|$TEST_DIR||"`
#
# options processing
#
usage()
{
cat <<EOF
usage: $SCRIPT -p product -b branch -T buildtype -x executablepath -N profilename \\
-R -X excludetests -I includetests -c -t -F [-d datafiles]
variable description
=============== ============================================================
-p product required. firefox|thunderbird
-b branch required. 1.8.0|1.8.1|1.9.0
-T buildtype required. one of opt debug
-x executablepath required. directory-tree containing executable 'product'
-N profilename required. profile name
-R optional. by default the browser test will start Firefox
spider and execute the tests one after another in the same
process. -R will start an new instance of Firefox for each
test.
-X excludetests optional. By default the test will exclude the
tests listed in spidermonkey-n-\$branch.tests,
performance-\$branch.tests. excludetests is a list of either
individual tests, manifest files or sub-directories which
will override the default exclusion list.
-I includetests optional. By default the test will include the
JavaScript tests appropriate for the branch. includetests is a
list of either individual tests, manifest files or
sub-directories which will override the default inclusion
list.
-Z n Set gczeal to n. Only valid for Gecko 1.9.0 and later.
-c optional. By default the test will exclude tests
which crash on this branch, test type, build type and
operating system. -c will include tests which crash.
Typically this should only be used in combination with -R.
This has no effect on shell based tests which execute crash
tests regardless.
-t optional. By default the test will exclude tests
which time out on this branch, test type, build type and
operating system. -t will include tests which timeout.
-F optional. Just generate file lists without running any tests.
-d datafiles optional. one or more filenames of files containing
environment variable definitions to be included.
note that the environment variables should have the same
names as in the "variable" column.
if an argument contains more than one value, it must be quoted.
EOF
exit 2
}
while getopts "p:b:T:x:N:d:X:I:Z:RctF" optname
do
case $optname in
p) product=$OPTARG;;
b) branch=$OPTARG;;
T) buildtype=$OPTARG;;
N) profilename=$OPTARG;;
x) executablepath=$OPTARG;;
R) restart=1;;
X) excludetests=$OPTARG;;
I) includetests=$OPTARG;;
c) crashes=1;;
t) timeouts=1;;
F) filesonly=1;;
Z) gczeal=";gczeal=$OPTARG";;
d) datafiles=$OPTARG;;
esac
done
# include environment variables
if [[ -n "$datafiles" ]]; then
for datafile in $datafiles; do
source $datafile
done
fi
dumpvars product branch buildtype profilename executablepath restart excludetests includetests crashes timeouts filesonly gczeal datafiles | sed "s|^|arguments: |"
if [[ -z "$product" || -z "$branch" || -z "$executablepath" || -z "$profilename" ]]; then
usage
fi
executable=`get_executable $product $branch $executablepath`
pushd $TEST_JSDIR
rm -f finished-$branch-browser-$buildtype
if ! make failures.txt; then
error "during make failures.txt" $LINENO
fi
includetestsfile="included-$branch-browser-$buildtype.tests"
rm -f $includetestsfile
touch $includetestsfile
if [[ -z "$includetests" ]]; then
# by default include tests appropriate for the branch
includetests="e4x ecma ecma_2 ecma_3 js1_1 js1_2 js1_3 js1_4 js1_5 js1_6"
case "$branch" in
1.8.0)
;;
1.8.1)
includetests="$includetests js1_7"
;;
1.9.0)
includetests="$includetests js1_7 js1_8"
;;
esac
fi
for i in $includetests; do
if [[ -f "$i" ]]; then
echo "# including $i" >> $includetestsfile
if echo $i | grep -q '\.js$'; then
echo $i >> $includetestsfile
else
cat $i >> $includetestsfile
fi
elif [[ -d "$i" ]]; then
find $i -name '*.js' -print | egrep -v '(shell|browser|template|jsref|userhook.*|\.#.*)\.js' | sed 's/^\.\///' | sort >> $includetestsfile
fi
done
excludetestsfile="excluded-$branch-browser-$buildtype.tests"
rm -f $excludetestsfile
touch $excludetestsfile
if [[ -z "$excludetests" ]]; then
excludetests="spidermonkey-n-$branch.tests performance-$branch.tests"
fi
for e in $excludetests; do
if [[ -f "$e" ]]; then
echo "# excluding $e" >> $excludetestsfile
if echo $e | grep -q '\.js$'; then
echo $e >> $excludetestsfile
else
cat $e >> $excludetestsfile
fi
elif [[ -d "$e" ]]; then
find $e -name '*.js' -print | egrep -v '(shell|browser|template|jsref|userhook.*|\.#.*)\.js' | sed 's/^\.\///' | sort >> $excludetestsfile
fi
done
case "$OSID" in
win32)
arch='.*'
kernel='.*'
;;
linux)
arch="`uname -p`"
kernel="`uname -r | sed 's|\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)[-.0-9]*\.\([a-zA-Z0-9]*\)|\1.\2.\3.*\4|'`"
;;
mac)
arch="`uname -p`"
kernel='[^,]*'
;;
*)
error "$OSID not supported" $LINENO
;;
esac
if [[ -z "$timeouts" ]]; then
echo "# exclude tests that time out" >> $excludetestsfile
egrep "TEST_BRANCH=([^,]*$branch[^,]*|[.][*]), TEST_RESULT=FAILED, TEST_BUILDTYPE=([^,]*$buildtype[^,]*|[.][*]), TEST_TYPE=([^,]*browser[^,]*|[.][*]), TEST_OS=([^,]*$OSID[^,]*|[.][*]), .*, TEST_PROCESSORTYPE=([^,]*$arch[^,]*|[.][*]), TEST_KERNEL=([^,]*$kernel[^,]*|[.][*]), .*, TEST_DESCRIPTION=.*EXIT STATUS: TIMED OUT" \
failures.txt | sed 's/TEST_ID=\([^,]*\),.*/\1/' | sort | uniq >> $excludetestsfile
fi
if [[ -z "$crashes" ]]; then
echo "# exclude tests that crash" >> $excludetestsfile
pattern="TEST_BRANCH=([^,]*$branch[^,]*|[.][*]), TEST_RESULT=FAILED, TEST_BUILDTYPE=([^,]*$buildtype[^,]*|[.][*]), TEST_TYPE=([^,]*browser[^,]*|[.][*]), TEST_OS=([^,]*$OSID[^,]*|[.][*]), .*, TEST_PROCESSORTYPE=([^,]*$arch[^,]*|[.][*]), TEST_KERNEL=([^,]*$kernel[^,]*|[.][*]), .*, TEST_DESCRIPTION=.*"
case "$buildtype" in
opt)
pattern="${pattern}EXIT STATUS: CRASHED"
;;
debug)
pattern="${pattern}(EXIT STATUS: CRASHED|Assertion failure:)"
;;
esac
egrep "$pattern" failures.txt | sed 's/TEST_ID=\([^,]*\),.*/\1/' | sort | uniq >> $excludetestsfile
fi
urllist="urllist-$branch-browser-$buildtype.tests"
urlhtml="urllist-$branch-browser-$buildtype.html"
rm -f $urllist $urlhtml
cat > $urlhtml <<EOF
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>JavaScript Tests</title>
</head>
<body>
<ul>
EOF
cat $includetestsfile | while read jsfile
do
if echo $jsfile | grep -q '^#'; then
continue
fi
if ! grep -q $jsfile $excludetestsfile; then
result=`echo $jsfile | sed 's/.*js\([0-9]\)_\([0-9]\).*/\1.\2/'`
case $result in
1.5) version=";version=1.5";;
1.6) version=";version=1.6";;
1.7) version=";version=1.7";;
1.8) version=";version=1.8";;
1.9) version=";version=1.9";;
2.0) version=";version=2.0";;
*) version="";;
esac
echo "http://$TEST_HTTP/$TEST_WWW_JS/js-test-driver-standards.html?test=$jsfile;language=type;text/javascript$version$gczeal" >> $urllist
echo "<li><a href='http://$TEST_HTTP/$TEST_WWW_JS/js-test-driver-standards.html?test=$jsfile;language=type;text/javascript$version$gczeal'>$jsfile</a></li>" >> $urlhtml
fi
done
cat >> $urlhtml <<EOF
</ul>
</body>
</html>
EOF
chmod a+r $urlhtml
cat $includetestsfile | sed 's|^|include: |'
cat $excludetestsfile | sed 's|^|exclude: |'
if [[ -z "$filesonly" ]]; then
if [[ "$restart" == "1" ]]; then
cat "$urllist" | while read url;
do
edit-talkback.sh -p "$product" -b "$branch" -x "$executablepath" -i "$url"
if time timed_run.py $TEST_JSEACH_TIMEOUT "$url" \
"$executable" -P "$profilename" \
-spider -start -quit \
-uri "$url" \
-depth 0 -timeout "$TEST_JSEACH_PAGE_TIMEOUT" \
-hook "http://$TEST_HTTP/$TEST_WWW_JS/userhookeach.js"; then
true;
fi
done
else
edit-talkback.sh -p "$product" -b "$branch" -x "$executablepath" -i "http://$TEST_HTTP/$TEST_WWW_JS/$urlhtml"
if ! time timed_run.py $TEST_JSALL_TIMEOUT "http://$TEST_HTTP/$TEST_WWW_JS/$urlhtml" \
"$executable" -P "$profilename" \
-spider -start -quit \
-uri "http://$TEST_HTTP/$TEST_WWW_JS/$urlhtml" \
-depth 1 -timeout "$TEST_JSEACH_PAGE_TIMEOUT" \
-hook "http://$TEST_HTTP/$TEST_WWW_JS/userhookeach.js"; then
error "timed_run.py ended abnormally: $?" $LINENO
fi
fi
fi
popd

View File

@ -1,261 +0,0 @@
#!/bin/bash -e
# -*- Mode: Shell-script; tab-width: 4; indent-tabs-mode: nil; -*-
# ***** 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 JavaScript Testing Utilities
#
# The Initial Developer of the Original Code is
# Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2007
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): Bob Clary <bclary@bclary.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
if [[ -z "$TEST_DIR" ]]; then
cat <<EOF
`basename $0`: error
TEST_DIR, the location of the Sisyphus framework,
is required to be set prior to calling this script.
EOF
exit 2
fi
if [[ ! -e $TEST_DIR/bin/library.sh ]]; then
echo "TEST_DIR=$TEST_DIR"
echo ""
echo "This script requires the Sisyphus testing framework. Please "
echo "cvs check out the Sisyphys framework from mozilla/testing/sisyphus"
echo "and set the environment variable TEST_DIR to the directory where it"
echo "located."
echo ""
exit 2
fi
source $TEST_DIR/bin/library.sh
TEST_JSDIR=`dirname $0`
TEST_JSSHELL_TIMEOUT=${TEST_JSSHELL_TIMEOUT:-480}
#
# options processing
#
usage()
{
cat <<EOF
usage: $SCRIPT -b branch -s sourcepath -T buildtype [-d datafiles]
variable description
=============== ===========================================================
-p product required. js
-b branch required. 1.8.0|1.8.1|1.9.0
-s sourcepath required. path to js shell source directory mozilla/js/src
-T buildtype required. one of opt debug
-X excludetests optional. By default the test will exclude the
tests listed in spidermonkey-n-\$branch.tests,
performance-\$branch.tests. excludetests is a list of either
individual tests, manifest files or sub-directories which
will override the default exclusion list.
-I includetests optional. By default the test will include the
JavaScript tests appropriate for the branch. includetests is a
list of either individual tests, manifest files or
sub-directories which will override the default inclusion
list.
-Z n optional. Set gczeal to n. Currently, only valid for
Gecko 1.9.0 and later.
-c optional. By default the test will exclude tests
which crash on this branch, test type, build type and
operating system. -c will include tests which crash.
Typically this should only be used in combination with -R.
This has no effect on shell based tests which execute crash
tests regardless.
-t optional. By default the test will exclude tests
which time out on this branch, test type, build type and
operating system. -t will include tests which timeout.
-d datafiles optional. one or more filenames of files containing
environment variable definitions to be included.
EOF
exit 2
}
while getopts "b:s:T:d:X:I:Z:ct" optname
do
case $optname in
b) branch=$OPTARG;;
s) sourcepath=$OPTARG;;
T) buildtype=$OPTARG;;
X) excludetests=$OPTARG;;
I) includetests=$OPTARG;;
C) crashes=1;;
T) timeouts=1;;
Z) gczeal="-Z $OPTARG";;
d) datafiles=$OPTARG;;
esac
done
# include environment variables
if [[ -n "$datafiles" ]]; then
for datafile in $datafiles; do
source $datafile
done
fi
dumpvars branch sourcepath buildtype excludetests includetests crashes timeouts gczeal datafiles | sed "s|^|arguments: |"
if [[ -z "$branch" || -z "$sourcepath" || -z "$buildtype" ]]; then
usage
fi
pushd $TEST_JSDIR
rm -f finished-$branch-shell-$buildtype
. config.sh
executable="$sourcepath/$JS_OBJDIR/js$EXE_EXT"
if ! make failures.txt; then
error "during make failures.txt" $LINENO
fi
#includetestsfile=`mktemp includetestsfile.XXXXX`
includetestsfile="included-$branch-shell-$buildtype.tests"
rm -f $includetestsfile
touch $includetestsfile
if [[ -z "$includetests" ]]; then
# by default include tests appropriate for the branch
includetests="e4x ecma ecma_2 ecma_3 js1_1 js1_2 js1_3 js1_4 js1_5 js1_6"
case "$branch" in
1.8.0)
;;
1.8.1)
includetests="$includetests js1_7"
;;
1.9.0)
includetests="$includetests js1_7 js1_8"
;;
esac
fi
for i in $includetests; do
if [[ -f "$i" ]]; then
echo "# including $i" >> $includetestsfile
if echo $i | grep -q '\.js$'; then
echo $i >> $includetestsfile
else
cat $i >> $includetestsfile
fi
elif [[ -d "$i" ]]; then
find $i -name '*.js' -print | egrep -v '(shell|browser|template|jsref|userhook.*|\.#.*)\.js' | sed 's/^\.\///' | sort >> $includetestsfile
fi
done
#excludetestsfile=`mktemp excludetestsfile.XXXXX`
excludetestsfile="excluded-$branch-shell-$buildtype.tests"
rm -f $excludetestsfile
touch $excludetestsfile
if [[ -z "$excludetests" ]]; then
excludetests="spidermonkey-n-$branch.tests performance-$branch.tests"
fi
for e in $excludetests; do
if [[ -f "$e" ]]; then
echo "# excluding $e" >> $excludetestsfile
if echo $e | grep -q '\.js$'; then
echo $e >> $excludetestsfile
else
cat $e >> $excludetestsfile
fi
elif [[ -d "$e" ]]; then
find $e -name '*.js' -print | egrep -v '(shell|browser|template|userhook.*|\.#.*).js' | sed 's/^\.\///' | sort >> $excludetestsfile
fi
done
case "$OSID" in
win32)
arch='.*'
kernel='.*'
;;
linux)
arch="`uname -p`"
kernel="`uname -r | sed 's|\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)[-.0-9]*\.\([a-zA-Z0-9]*\)|\1.\2.\3.*\4|'`"
;;
mac)
arch="`uname -p`"
kernel='[^,]*'
;;
*)
error "$product-$branch-$buildtype: $OSID not supported" $LINENO
;;
esac
if [[ -z "$timeouts" ]]; then
echo "# exclude tests that time out" >> $excludetestsfile
egrep "TEST_BRANCH=([^,]*$branch[^,]*|[.][*]), TEST_RESULT=FAILED, TEST_BUILDTYPE=([^,]*$buildtype[^,]*|[.][*]), TEST_TYPE=([^,]*shell[^,]*|[.][*]), TEST_OS=([^,]*$OSID[^,]*|[.][*]), .*, TEST_PROCESSORTYPE=([^,]*$arch[^,]*|[.][*]), TEST_KERNEL=([^,]*$kernel[^,]*|[.][*]), .*, TEST_DESCRIPTION=.*EXIT STATUS: TIMED OUT" \
failures.txt | sed 's/TEST_ID=\([^,]*\),.*/\1/' | sort | uniq >> $excludetestsfile
fi
if [[ -z "$crashes" ]]; then
echo "# exclude tests that crash" >> $excludetestsfile
pattern="TEST_BRANCH=([^,]*$branch[^,]*|[.][*]), TEST_RESULT=FAILED, TEST_BUILDTYPE=([^,]*$buildtype[^,]*|[.][*]), TEST_TYPE=([^,]*shell[^,]*|[.][*]), TEST_OS=([^,]*$OSID[^,]*|[.][*]), .*, TEST_PROCESSORTYPE=([^,]*$arch[^,]*|[.][*]), TEST_KERNEL=([^,]*$kernel[^,]*|[.][*]), .*, TEST_DESCRIPTION=.*"
case "$buildtype" in
opt)
pattern="${pattern}EXIT STATUS: CRASHED"
;;
debug)
pattern="${pattern}(EXIT STATUS: CRASHED|Assertion failure:)"
;;
esac
egrep "$pattern" failures.txt | sed 's/TEST_ID=\([^,]*\),.*/\1/' | sort | uniq >> $excludetestsfile
fi
cat $includetestsfile | sed 's|^|include: |'
cat $excludetestsfile | sed 's|^|exclude: |'
if ! time perl jsDriver.pl \
-l $includetestsfile \
-L $excludetestsfile \
-s $executable \
-e sm$buildtype \
-o "-S 524288 $gczeal" \
-R \
-T $TEST_JSSHELL_TIMEOUT \
-f /dev/null \
-Q; then
error "$product-$branch-$buildtype-$OSID: jsDriver.pl" $LINENO
fi
popd

View File

@ -38,13 +38,13 @@
# ***** END LICENSE BLOCK ***** # ***** END LICENSE BLOCK *****
if [[ -z "$TEST_DIR" ]]; then if [[ -z "$TEST_DIR" ]]; then
cat <<EOF cat <<EOF
`basename $0`: error `basename $0`: error
TEST_DIR, the location of the Sisyphus framework, TEST_DIR, the location of the Sisyphus framework,
is required to be set prior to calling this script. is required to be set prior to calling this script.
EOF EOF
exit 2 exit 2
fi fi
if [[ ! -e $TEST_DIR/bin/library.sh ]]; then if [[ ! -e $TEST_DIR/bin/library.sh ]]; then
@ -63,55 +63,351 @@ source $TEST_DIR/bin/library.sh
TEST_JSDIR=`dirname $0` TEST_JSDIR=`dirname $0`
TEST_JSSHELL_TIMEOUT=${TEST_JSSHELL_TIMEOUT:-480}
TEST_JSEACH_TIMEOUT=${TEST_JSEACH_TIMEOUT:-485}
TEST_JSEACH_PAGE_TIMEOUT=${TEST_JSEACH_PAGE_TIMEOUT:-480}
TEST_JSALL_TIMEOUT=${TEST_JSALL_TIMEOUT:-21600}
TEST_WWW_JS=`echo $TEST_JSDIR|sed "s|$TEST_DIR||"`
# #
# options processing # options processing
# #
usage() usage()
{ {
cat <<EOF cat <<EOF
usage: $SCRIPT -d datafiles usage: test.sh -p product -b branch -T buildtype -x executablepath -N profilename \\
[-X excludetests] [-I includetests] [-c] [-t] [-F] [-d datafiles]
This script is used to dispatch to either test-browser.sh
for browser based JavaScript tests or test-shell.js for
shell based JavaScript tests. It ignores all input arguments
except -d datafiles which it uses to pass data to the
appropriate script.
variable description variable description
=============== ============================================================ =============== ============================================================
-p product required. firefox|thunderbird|js
-b branch required. 1.8.0|1.8.1|1.9.0|1.9.1
-s sourcepath required for shell. path to js shell source directory mozilla/js/src
-T buildtype required. one of opt debug
-x executablepath required for browser. directory-tree containing executable 'product'
-N profilename required for browser. profile name
-X excludetests optional. By default the test will exclude the
tests listed in spidermonkey-n-\$branch.tests,
performance-\$branch.tests. excludetests is a list of either
individual tests, manifest files or sub-directories which
will override the default exclusion list.
-I includetests optional. By default the test will include the
JavaScript tests appropriate for the branch. includetests is a
list of either individual tests, manifest files or
sub-directories which will override the default inclusion
list.
-c optional. By default the test will exclude tests
which crash on this branch, test type, build type and
operating system. -c will include tests which crash.
Typically this should only be used in combination with -R.
This has no effect on shell based tests which execute crash
tests regardless.
-t optional. By default the test will exclude tests
which time out on this branch, test type, build type and
operating system. -t will include tests which timeout.
-Z n optional. Set gczeal to n. Currently, only valid for
debug builds of Gecko 1.8.1.15, 1.9.0 and later.
-F optional. Just generate file lists without running any tests.
-d datafiles optional. one or more filenames of files containing -d datafiles optional. one or more filenames of files containing
environment variable definitions to be included. environment variable definitions to be included.
-Z n optional. Set gczeal to n. Currently, only valid for
Gecko 1.9.0 and later. note that the environment variables should have the same
names as in the "variable" column.
if an argument contains more than one value, it must be quoted. if an argument contains more than one value, it must be quoted.
EOF EOF
exit 2 exit 2
} }
unset datafiles while getopts "p:b:s:T:x:N:d:X:I:Z:RctF" optname
while getopts "d:Z:" optname ;
do do
case $optname in case $optname in
p)
product=$OPTARG;;
b)
branch=$OPTARG;;
T)
buildtype=$OPTARG;;
s)
sourcepath=$OPTARG;;
N)
profilename=$OPTARG;;
x)
executablepath=$OPTARG;;
X)
excludetests=$OPTARG;;
I)
includetests=$OPTARG;;
c)
crashes=1;;
t)
timeouts=1;;
F)
filesonly=1;;
Z)
gczealshell="-Z $OPTARG"
gczealbrowser=";gczeal=$OPTARG"
;;
d) datafiles=$OPTARG;; d) datafiles=$OPTARG;;
Z) gczeal="-Z $OPTARG";;
esac esac
done done
if [[ -z "$datafiles" ]]; then # include environment variables
usage if [[ -n "$datafiles" ]]; then
for datafile in $datafiles; do
source $datafile
done
fi fi
for data in $datafiles; do if [[ -n "$gczeal" && "$buildtype" != "debug" ]]; then
source $data error "gczeal is supported for buildtype debug and not $buildtype"
done fi
case "$product" in dumpvars product branch buildtype sourcepath profilename executablepath excludetests includetests crashes timeouts filesonly gczeal datafiles | sed "s|^|arguments: |"
firefox) testscript=$TEST_JSDIR/test-browser.sh;;
js) testscript=$TEST_JSDIR/test-shell.sh;; pushd $TEST_JSDIR
*) echo "unknown product [$product]"
exit 2 case $product in
js)
if [[ -z "$branch" || -z "$buildtype" || -z "$sourcepath" ]]; then
usage
fi
source config.sh
testtype=shell
executable="$sourcepath/$JS_OBJDIR/js$EXE_EXT"
;;
firefox|thunderbird)
if [[ -z "$branch" || -z "$buildtype" || -z "$executablepath" || -z "$profilename" ]]; then
usage
fi
testtype=browser
executable=`get_executable $product $branch $executablepath`
;;
*)
echo "Unknown product: $product"
usage
;; ;;
esac esac
$testscript -d "$datafiles" $gczeal rm -f finished-$branch-$testtype-$buildtype
if ! make failures.txt; then
error "during make failures.txt" $LINENO
fi
includetestsfile="included-$branch-$testtype-$buildtype.tests"
rm -f $includetestsfile
touch $includetestsfile
if [[ -z "$includetests" ]]; then
# by default include tests appropriate for the branch
includetests="e4x ecma ecma_2 ecma_3 js1_1 js1_2 js1_3 js1_4 js1_5 js1_6"
case "$branch" in
1.8.0)
;;
1.8.1)
includetests="$includetests js1_7"
;;
1.9.0)
includetests="$includetests js1_7 js1_8"
;;
1.9.1)
includetests="$includetests js1_7 js1_8"
;;
esac
fi
for i in $includetests; do
if [[ -f "$i" ]]; then
echo "# including $i" >> $includetestsfile
if echo $i | grep -q '\.js$'; then
echo $i >> $includetestsfile
else
cat $i >> $includetestsfile
fi
elif [[ -d "$i" ]]; then
find $i -name '*.js' -print | egrep -v '(shell|browser|template|jsref|userhook.*|\.#.*)\.js' | sed 's/^\.\///' | sort >> $includetestsfile
fi
done
excludetestsfile="excluded-$branch-$testtype-$buildtype.tests"
rm -f $excludetestsfile
touch $excludetestsfile
if [[ -z "$excludetests" ]]; then
excludetests="spidermonkey-n-$branch.tests performance-$branch.tests"
fi
for e in $excludetests; do
if [[ -f "$e" ]]; then
echo "# excluding $e" >> $excludetestsfile
if echo $e | grep -q '\.js$'; then
echo $e >> $excludetestsfile
else
cat $e >> $excludetestsfile
fi
elif [[ -d "$e" ]]; then
find $e -name '*.js' -print | egrep -v '(shell|browser|template|jsref|userhook.*|\.#.*)\.js' | sed 's/^\.\///' | sort >> $excludetestsfile
fi
done
# convert the numeric speed rating to a prose value
if [[ $TEST_CPUSPEED -lt 4 ]]; then
TEST_CPUSPEED=slow
elif [[ $TEST_CPUSPEED -lt 9 ]]; then
TEST_CPUSPEED=medium
else
TEST_CPUSPEED=fast
fi
pattern="TEST_BRANCH=($branch|[.][*]), TEST_BUILDTYPE=($buildtype|[.][*]), TEST_TYPE=($testtype|[.][*]), TEST_OS=($OSID|[.][*]), TEST_KERNEL=($TEST_KERNEL|[.][*]), TEST_PROCESSORTYPE=($TEST_PROCESSORTYPE|[.][*]), TEST_MEMORY=($TEST_MEMORY|[.][*]), TEST_CPUSPEED=($TEST_CPUSPEED|[.][*]),"
if [[ -z "$timeouts" ]]; then
echo "# exclude tests that time out" >> $excludetestsfile
echo "$pattern .*TEST_EXITSTATUS=TIMED OUT," >> $excludetestsfile
egrep "$pattern .*TEST_EXITSTATUS=TIMED OUT," failures.txt | \
sed 's/.*TEST_ID=\([^,]*\),.*/\1/' | sort -u >> $excludetestsfile
fi
if [[ -z "$crashes" ]]; then
echo "# exclude tests that crash" >> $excludetestsfile
echo "$pattern .*TEST_EXITSTATUS=(CRASHED|ABNORMAL)" >> $excludetestsfile
egrep "$pattern .*TEST_EXITSTATUS=(CRASHED|ABNORMAL)" failures.txt | \
sed 's/.*TEST_ID=\([^,]*\),.*/\1/' | sort -u >> $excludetestsfile
fi
cat $includetestsfile | sed 's|^|include: |'
cat $excludetestsfile | sed 's|^|exclude: |'
case $testtype in
shell)
echo "JavaScriptTest: Begin Run"
cat $includetestsfile | while read jsfile
do
if echo $jsfile | grep -q '^#'; then
continue
fi
if ! grep -q $jsfile $excludetestsfile; then
result=`echo $jsfile | sed 's/.*js\([0-9]\)_\([0-9]\).*/\1.\2/'`
case $result in
1.5) version="150";;
1.6) version="160";;
1.7) version="170";;
1.8) version="180";;
1.9) version="190";;
2.0) version="200";;
*) version="150";;
esac
subsuitetestdir=`dirname $jsfile`
suitetestdir=`dirname $subsuitetestdir`
echo "JavaScriptTest: Begin Test $jsfile"
if eval $TIMECOMMAND timed_run.py $TEST_JSEACH_TIMEOUT \"$jsfile\" \
$EXECUTABLE_DRIVER \
$executable -v $version \
-S 524288 \
$gczealshell \
-f ./shell.js \
-f $suitetestdir/shell.js \
-f $subsuitetestdir/shell.js \
-f ./$jsfile \
-f ./js-test-driver-end.js; then
true
else
rc=$?
fi
if [[ $rc == 99 ]]; then
error "User Interrupt"
fi
echo "JavaScriptTest: End Test $jsfile"
fi
done
echo "JavaScriptTest: End Run"
;;
browser)
urllist="urllist-$branch-$testtype-$buildtype.tests"
urlhtml="urllist-$branch-$testtype-$buildtype.html"
rm -f $urllist $urlhtml
cat > $urlhtml <<EOF
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>JavaScript Tests</title>
</head>
<body>
<ul>
EOF
cat $includetestsfile | while read jsfile
do
if echo $jsfile | grep -q '^#'; then
continue
fi
if ! grep -q $jsfile $excludetestsfile; then
result=`echo $jsfile | sed 's/.*js\([0-9]\)_\([0-9]\).*/\1.\2/'`
case $result in
1.5) version=";version=1.5";;
1.6) version=";version=1.6";;
1.7) version=";version=1.7";;
1.8) version=";version=1.8";;
1.9) version=";version=1.9";;
2.0) version=";version=2.0";;
*) version="";;
esac
echo "http://$TEST_HTTP/$TEST_WWW_JS/js-test-driver-standards.html?test=$jsfile;language=type;text/javascript$version$gczealbrowser" >> $urllist
echo "<li><a href='http://$TEST_HTTP/$TEST_WWW_JS/js-test-driver-standards.html?test=$jsfile;language=type;text/javascript$version$gczealbrowser'>$jsfile</a></li>" >> $urlhtml
fi
done
cat >> $urlhtml <<EOF
</ul>
</body>
</html>
EOF
chmod a+r $urlhtml
if [[ -z "$filesonly" ]]; then
echo "JavaScriptTest: Begin Run"
cat "$urllist" | while read url;
do
edit-talkback.sh -p "$product" -b "$branch" -x "$executablepath" -i "$url"
jsfile=`echo $url | sed "s|http://$TEST_HTTP/$TEST_WWW_JS/js-test-driver-standards.html?test=\([^;]*\);.*|\1|"`
echo "JavaScriptTest: Begin Test $jsfile"
if eval $TIMECOMMAND timed_run.py $TEST_JSEACH_TIMEOUT \"$jsfile\" \
$EXECUTABLE_DRIVER \
\"$executable\" -P \"$profilename\" \
-spider -start -quit \
-uri \"$url\" \
-depth 0 -timeout \"$TEST_JSEACH_PAGE_TIMEOUT\" \
-hook \"http://$TEST_HTTP/$TEST_WWW_JS/userhookeach.js\"; then
true
else
rc=$?
fi
if [[ $rc == 99 ]]; then
error "User Interrupt"
fi
echo "JavaScriptTest: End Test $jsfile"
done
echo "JavaScriptTest: End Run"
fi
;;
*)
;;
esac
popd

180
js/tests/universe.data Normal file
View File

@ -0,0 +1,180 @@
TEST_OS=darwin, TEST_KERNEL=8.11.0, TEST_PROCESSORTYPE=powerpc32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=8.11.0, TEST_PROCESSORTYPE=powerpc32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=8.11.0, TEST_PROCESSORTYPE=powerpc32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=8.11.0, TEST_PROCESSORTYPE=powerpc32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=8.11.0, TEST_PROCESSORTYPE=powerpc32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=8.11.0, TEST_PROCESSORTYPE=powerpc32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=8.11.0, TEST_PROCESSORTYPE=powerpc32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=8.11.0, TEST_PROCESSORTYPE=powerpc32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=8.11.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=8.11.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=8.11.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=8.11.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=8.11.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=8.11.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=8.11.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=8.11.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.3.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=darwin, TEST_KERNEL=9.4.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=4, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=1, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=1, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=1, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=1, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=1, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=1, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=1, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=1, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=4, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=4, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=4, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=4, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=4, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=4, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=4, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.18, TEST_PROCESSORTYPE=intel64, TEST_MEMORY=4, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0700, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.22, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.22, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.22, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.22, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.22, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.22, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.22, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.22, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=1, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=3, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=3, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=3, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=3, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=3, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=3, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=3, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=linux, TEST_KERNEL=2.6.25, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=3, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=amd32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0700, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=fast, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.8.1, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=5.1, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=medium, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=6.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=6.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=debug, TEST_TYPE=shell
TEST_OS=nt, TEST_KERNEL=6.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=browser
TEST_OS=nt, TEST_KERNEL=6.0, TEST_PROCESSORTYPE=intel32, TEST_MEMORY=2, TEST_CPUSPEED=slow, TEST_TIMEZONE=-0400, TEST_BRANCH=1.9.0, TEST_BUILDTYPE=opt, TEST_TYPE=shell

View File

@ -54,7 +54,6 @@ function userOnStart()
try try
{ {
dlog('userOnStart'); dlog('userOnStart');
cdump('JavaScriptTest: Begin Run');
registerDialogCloser(); registerDialogCloser();
} }
catch(ex) catch(ex)
@ -72,7 +71,6 @@ function userOnBeforePage()
gCurrentTestId = /test=(.*);language/.exec(gSpider.mCurrentUrl.mUrl)[1]; gCurrentTestId = /test=(.*);language/.exec(gSpider.mCurrentUrl.mUrl)[1];
gCurrentTestValid = true; gCurrentTestValid = true;
cdump('JavaScriptTest: Begin Test ' + gCurrentTestId);
gCurrentTestStart = new Date(); gCurrentTestStart = new Date();
} }
catch(ex) catch(ex)
@ -90,7 +88,6 @@ function userOnAfterPage()
dlog('userOnAfterPage'); dlog('userOnAfterPage');
gPageStop = new Date(); gPageStop = new Date();
cdump(gSpider.mCurrentUrl.mUrl + ': PAGE STATUS: NORMAL (' + ((gPageStop - gPageStart)/1000).toFixed(0) + ' seconds)');
checkTestCompleted(); checkTestCompleted();
} }
catch(ex) catch(ex)
@ -106,7 +103,6 @@ function userOnStop()
try try
{ {
// close any pending dialogs // close any pending dialogs
cdump('JavaScriptTest: End Run');
closeDialog(); closeDialog();
unregisterDialogCloser(); unregisterDialogCloser();
} }
@ -119,7 +115,6 @@ function userOnStop()
function userOnPageTimeout() function userOnPageTimeout()
{ {
gPageStop = new Date(); gPageStop = new Date();
cdump(gSpider.mCurrentUrl.mUrl + ': PAGE STATUS: TIMED OUT (' + ((gPageStop - gPageStart)/1000).toFixed(0) + ' seconds)');
if (typeof gSpider.mDocument != 'undefined') if (typeof gSpider.mDocument != 'undefined')
{ {
try try
@ -137,7 +132,6 @@ function userOnPageTimeout()
cdump('Spider: WARNING ERROR: userOnPageTimeout: ' + ex); cdump('Spider: WARNING ERROR: userOnPageTimeout: ' + ex);
} }
} }
cdump('JavaScriptTest: End Test ' + gCurrentTestId);
} }
function checkTestCompleted() function checkTestCompleted()
@ -181,7 +175,6 @@ function checkTestCompleted()
{ {
} }
cdump('JavaScriptTest: ' + gCurrentTestId + ' Elapsed time ' + ((gCurrentTestStop - gCurrentTestStart)/1000).toFixed(2) + ' seconds'); cdump('JavaScriptTest: ' + gCurrentTestId + ' Elapsed time ' + ((gCurrentTestStop - gCurrentTestStart)/1000).toFixed(2) + ' seconds');
cdump('JavaScriptTest: End Test ' + gCurrentTestId);
gPageCompleted = true; gPageCompleted = true;
} }

View File

@ -1127,7 +1127,7 @@ private:
// Structure used for maintaining state information during the // Structure used for maintaining state information during the
// frame construction process // frame construction process
class nsFrameConstructorState { class NS_STACK_CLASS nsFrameConstructorState {
public: public:
nsPresContext *mPresContext; nsPresContext *mPresContext;
nsIPresShell *mPresShell; nsIPresShell *mPresShell;
@ -1731,7 +1731,7 @@ MoveChildrenTo(nsFrameManager* aFrameManager,
// Structure used to ensure that bindings are properly enqueued in the // Structure used to ensure that bindings are properly enqueued in the
// binding manager's attached queue. // binding manager's attached queue.
struct nsAutoEnqueueBinding struct NS_STACK_CLASS nsAutoEnqueueBinding
{ {
nsAutoEnqueueBinding(nsIDocument* aDocument) : nsAutoEnqueueBinding(nsIDocument* aDocument) :
mDocument(aDocument) mDocument(aDocument)

View File

@ -52,7 +52,7 @@
* node APIs, since it handles XBL-generated anonymous content as * node APIs, since it handles XBL-generated anonymous content as
* well. * well.
*/ */
class ChildIterator class NS_STACK_CLASS ChildIterator
{ {
protected: protected:
nsCOMPtr<nsIContent> mContent; nsCOMPtr<nsIContent> mContent;

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