--- a/content/xslt/src/xslt/txStylesheetCompileHandlers.cpp
+++ b/content/xslt/src/xslt/txStylesheetCompileHandlers.cpp
@@ -1198,17 +1198,17 @@ txFnStartTopVariable(PRInt32 aNamespaceI
aState, select);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<txVariableItem> var(
new txVariableItem(name, select, aLocalName == txXSLTAtoms::param));
NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
aState.openInstructionContainer(var);
- rv = aState.pushPtr(var);
+ rv = aState.pushPtr(var, aState.eVariableItem);
NS_ENSURE_SUCCESS(rv, rv);
if (var->mValue) {
// XXX should be gTxErrorHandler?
rv = aState.pushHandlerTable(gTxIgnoreHandler);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
@@ -1224,17 +1224,18 @@ txFnStartTopVariable(PRInt32 aNamespaceI
return NS_OK;
}
nsresult
txFnEndTopVariable(txStylesheetCompilerState& aState)
{
txHandlerTable* prev = aState.mHandlerTable;
aState.popHandlerTable();
- txVariableItem* var = static_cast<txVariableItem*>(aState.popPtr());
+ txVariableItem* var =
+ static_cast<txVariableItem*>(aState.popPtr(aState.eVariableItem));
if (prev == gTxTopVariableHandler) {
// No children were found.
NS_ASSERTION(!var->mValue,
"There shouldn't be a select-expression here");
var->mValue = new txLiteralExpr(EmptyString());
NS_ENSURE_TRUE(var->mValue, NS_ERROR_OUT_OF_MEMORY);
}
@@ -1726,17 +1727,17 @@ txFnStartCopy(PRInt32 aNamespaceID,
nsIAtom* aPrefix,
txStylesheetAttr* aAttributes,
PRInt32 aAttrCount,
txStylesheetCompilerState& aState)
{
nsAutoPtr<txCopy> copy(new txCopy);
NS_ENSURE_TRUE(copy, NS_ERROR_OUT_OF_MEMORY);
- nsresult rv = aState.pushPtr(copy);
+ nsresult rv = aState.pushPtr(copy, aState.eCopy);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<txInstruction> instr(copy.forget());
rv = aState.addInstruction(instr);
NS_ENSURE_SUCCESS(rv, rv);
rv = parseUseAttrSets(aAttributes, aAttrCount, PR_FALSE, aState);
NS_ENSURE_SUCCESS(rv, rv);
@@ -1748,17 +1749,17 @@ nsresult
txFnEndCopy(txStylesheetCompilerState& aState)
{
nsAutoPtr<txInstruction> instr(new txEndElement);
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
nsresult rv = aState.addInstruction(instr);
NS_ENSURE_SUCCESS(rv, rv);
- txCopy* copy = static_cast<txCopy*>(aState.popPtr());
+ txCopy* copy = static_cast<txCopy*>(aState.popPtr(aState.eCopy));
rv = aState.addGotoTarget(©->mBailTarget);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
/*
xsl:copy-of
@@ -1899,54 +1900,54 @@ txFnStartForEach(PRInt32 aNamespaceID,
nsAutoPtr<Expr> select;
rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::select, PR_TRUE,
aState, select);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<txPushNewContext> pushcontext(new txPushNewContext(select));
NS_ENSURE_TRUE(pushcontext, NS_ERROR_OUT_OF_MEMORY);
- rv = aState.pushPtr(pushcontext);
+ rv = aState.pushPtr(pushcontext, aState.ePushNewContext);
NS_ENSURE_SUCCESS(rv, rv);
rv = aState.pushSorter(pushcontext);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<txInstruction> instr(pushcontext.forget());
rv = aState.addInstruction(instr);
NS_ENSURE_SUCCESS(rv, rv);
instr = new txPushNullTemplateRule;
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
- rv = aState.pushPtr(instr);
+ rv = aState.pushPtr(instr, aState.ePushNullTemplateRule);
NS_ENSURE_SUCCESS(rv, rv);
rv = aState.addInstruction(instr);
NS_ENSURE_SUCCESS(rv, rv);
return aState.pushHandlerTable(gTxForEachHandler);
}
nsresult
txFnEndForEach(txStylesheetCompilerState& aState)
{
aState.popHandlerTable();
// This is a txPushNullTemplateRule
txInstruction* pnullrule =
- static_cast<txInstruction*>(aState.popPtr());
+ static_cast<txInstruction*>(aState.popPtr(aState.ePushNullTemplateRule));
nsAutoPtr<txInstruction> instr(new txLoopNodeSet(pnullrule));
nsresult rv = aState.addInstruction(instr);
NS_ENSURE_SUCCESS(rv, rv);
aState.popSorter();
txPushNewContext* pushcontext =
- static_cast<txPushNewContext*>(aState.popPtr());
+ static_cast<txPushNewContext*>(aState.popPtr(aState.ePushNewContext));
aState.addGotoTarget(&pushcontext->mBailTarget);
return NS_OK;
}
nsresult
txFnStartElementContinueTemplate(PRInt32 aNamespaceID,
nsIAtom* aLocalName,
@@ -1991,31 +1992,31 @@ txFnStartIf(PRInt32 aNamespaceID,
nsAutoPtr<Expr> test;
rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::test, PR_TRUE,
aState, test);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<txConditionalGoto> condGoto(new txConditionalGoto(test, nsnull));
NS_ENSURE_TRUE(condGoto, NS_ERROR_OUT_OF_MEMORY);
- rv = aState.pushPtr(condGoto);
+ rv = aState.pushPtr(condGoto, aState.eConditionalGoto);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<txInstruction> instr(condGoto.forget());
rv = aState.addInstruction(instr);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
txFnEndIf(txStylesheetCompilerState& aState)
{
txConditionalGoto* condGoto =
- static_cast<txConditionalGoto*>(aState.popPtr());
+ static_cast<txConditionalGoto*>(aState.popPtr(aState.eConditionalGoto));
return aState.addGotoTarget(&condGoto->mTarget);
}
/*
xsl:message
txPushStringHandler
[children]
@@ -2198,17 +2199,17 @@ txFnStartParam(PRInt32 aNamespaceID,
txExpandedName name;
rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_TRUE,
aState, name);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<txCheckParam> checkParam(new txCheckParam(name));
NS_ENSURE_SUCCESS(rv, rv);
- rv = aState.pushPtr(checkParam);
+ rv = aState.pushPtr(checkParam, aState.eCheckParam);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<txInstruction> instr(checkParam.forget());
rv = aState.addInstruction(instr);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<Expr> select;
rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::select, PR_FALSE,
@@ -2254,17 +2255,18 @@ txFnEndParam(txStylesheetCompilerState&
nsresult rv = aState.addVariable(var->mName);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<txInstruction> instr(var.forget());
rv = aState.addInstruction(instr);
NS_ENSURE_SUCCESS(rv, rv);
- txCheckParam* checkParam = static_cast<txCheckParam*>(aState.popPtr());
+ txCheckParam* checkParam =
+ static_cast<txCheckParam*>(aState.popPtr(aState.eCheckParam));
aState.addGotoTarget(&checkParam->mBailTarget);
return NS_OK;
}
/*
xsl:processing-instruction
@@ -2595,17 +2597,17 @@ txFnStartWhen(PRInt32 aNamespaceID,
nsAutoPtr<Expr> test;
rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::test, PR_TRUE,
aState, test);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<txConditionalGoto> condGoto(new txConditionalGoto(test, nsnull));
NS_ENSURE_TRUE(condGoto, NS_ERROR_OUT_OF_MEMORY);
- rv = aState.pushPtr(condGoto);
+ rv = aState.pushPtr(condGoto, aState.eConditionalGoto);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<txInstruction> instr(condGoto.forget());
rv = aState.addInstruction(instr);
NS_ENSURE_SUCCESS(rv, rv);
return aState.pushHandlerTable(gTxTemplateHandler);
}
@@ -2620,17 +2622,17 @@ txFnEndWhen(txStylesheetCompilerState& a
nsresult rv = aState.mChooseGotoList->add(gotoinstr);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoPtr<txInstruction> instr(gotoinstr.forget());
rv = aState.addInstruction(instr);
NS_ENSURE_SUCCESS(rv, rv);
txConditionalGoto* condGoto =
- static_cast<txConditionalGoto*>(aState.popPtr());
+ static_cast<txConditionalGoto*>(aState.popPtr(aState.eConditionalGoto));
rv = aState.addGotoTarget(&condGoto->mTarget);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
/*
xsl:with-param
--- a/content/xslt/src/xslt/txStylesheetCompiler.cpp
+++ b/content/xslt/src/xslt/txStylesheetCompiler.cpp
@@ -354,17 +354,17 @@ txStylesheetCompiler::startElementIntern
(aNamespaceID == kNameSpaceID_XSLT &&
attr.mNamespaceID == kNameSpaceID_None))) {
// XXX ErrorReport: unknown attribute
return NS_ERROR_XSLT_PARSE_FAILURE;
}
}
}
- rv = pushPtr(const_cast<txElementHandler*>(handler));
+ rv = pushPtr(const_cast<txElementHandler*>(handler), eElementHandler);
NS_ENSURE_SUCCESS(rv, rv);
mElementContext->mDepth++;
return NS_OK;
}
nsresult
@@ -391,17 +391,17 @@ txStylesheetCompiler::endElement()
mInScopeVariables.RemoveElementAt(i);
delete var;
}
}
const txElementHandler* handler =
const_cast<const txElementHandler*>
- (static_cast<txElementHandler*>(popPtr()));
+ (static_cast<txElementHandler*>(popPtr(eElementHandler)));
rv = (handler->mEndFunction)(*this);
NS_ENSURE_SUCCESS(rv, rv);
if (!--mElementContext->mDepth) {
// this will delete the old object
mElementContext = static_cast<txElementContext*>(popObject());
}
@@ -648,45 +648,45 @@ txStylesheetCompilerState::~txStylesheet
for (i = mInScopeVariables.Length() - 1; i >= 0; --i) {
delete mInScopeVariables[i];
}
}
nsresult
txStylesheetCompilerState::pushHandlerTable(txHandlerTable* aTable)
{
- nsresult rv = pushPtr(mHandlerTable);
+ nsresult rv = pushPtr(mHandlerTable, eHandlerTable);
NS_ENSURE_SUCCESS(rv, rv);
mHandlerTable = aTable;
return NS_OK;
}
void
txStylesheetCompilerState::popHandlerTable()
{
- mHandlerTable = static_cast<txHandlerTable*>(popPtr());
+ mHandlerTable = static_cast<txHandlerTable*>(popPtr(eHandlerTable));
}
nsresult
txStylesheetCompilerState::pushSorter(txPushNewContext* aSorter)
{
- nsresult rv = pushPtr(mSorter);
+ nsresult rv = pushPtr(mSorter, ePushNewContext);
NS_ENSURE_SUCCESS(rv, rv);
mSorter = aSorter;
return NS_OK;
}
void
txStylesheetCompilerState::popSorter()
{
- mSorter = static_cast<txPushNewContext*>(popPtr());
+ mSorter = static_cast<txPushNewContext*>(popPtr(ePushNewContext));
}
nsresult
txStylesheetCompilerState::pushChooseGotoList()
{
nsresult rv = pushObject(mChooseGotoList);
NS_ENSURE_SUCCESS(rv, rv);
@@ -712,31 +712,41 @@ txStylesheetCompilerState::pushObject(Tx
TxObject*
txStylesheetCompilerState::popObject()
{
return static_cast<TxObject*>(mObjectStack.pop());
}
nsresult
-txStylesheetCompilerState::pushPtr(void* aPtr)
+txStylesheetCompilerState::pushPtr(void* aPtr, enumStackType aType)
{
#ifdef TX_DEBUG_STACK
- PR_LOG(txLog::xslt, PR_LOG_DEBUG, ("pushPtr: %d\n", aPtr));
+ PR_LOG(txLog::xslt, PR_LOG_DEBUG, ("pushPtr: 0x%x type %u\n", aPtr, aType));
#endif
+ mTypeStack.AppendElement(aType);
return mOtherStack.push(aPtr);
}
void*
-txStylesheetCompilerState::popPtr()
+txStylesheetCompilerState::popPtr(enumStackType aType)
{
+ PRUint32 stacklen = mTypeStack.Length();
+ NS_ABORT_IF_FALSE(stacklen > 0,
+ "Attempt to pop when type stack is empty\n");
+ enumStackType type = mTypeStack.ElementAt(stacklen - 1);
+ mTypeStack.RemoveElementAt(stacklen - 1);
void* value = mOtherStack.pop();
+
#ifdef TX_DEBUG_STACK
- PR_LOG(txLog::xslt, PR_LOG_DEBUG, ("popPtr: %d\n", value));
+ PR_LOG(txLog::xslt, PR_LOG_DEBUG, ("popPtr: 0x%x type %u requested %u\n", value, type, aType));
#endif
+
+ NS_ABORT_IF_FALSE(type == aType,
+ "Expected type does not match top element type on stack");
return value;
}
nsresult
txStylesheetCompilerState::addToplevelItem(txToplevelItem* aItem)
{
return mToplevelIterator.addBefore(aItem);
}
--- a/content/xslt/src/xslt/txStylesheetCompiler.h
+++ b/content/xslt/src/xslt/txStylesheetCompiler.h
@@ -113,26 +113,38 @@ public:
return mEmbedStatus == eInEmbed;
}
void doneEmbedding()
{
mEmbedStatus = eHasEmbed;
}
// Stack functions
+ enum enumStackType
+ {
+ eElementHandler,
+ eHandlerTable,
+ eVariableItem,
+ eCopy,
+ eInstruction,
+ ePushNewContext,
+ eConditionalGoto,
+ eCheckParam,
+ ePushNullTemplateRule
+ };
nsresult pushHandlerTable(txHandlerTable* aTable);
void popHandlerTable();
nsresult pushSorter(txPushNewContext* aSorter);
void popSorter();
nsresult pushChooseGotoList();
void popChooseGotoList();
nsresult pushObject(TxObject* aObject);
TxObject* popObject();
- nsresult pushPtr(void* aPtr);
- void* popPtr();
+ nsresult pushPtr(void* aPtr, enumStackType aType);
+ void* popPtr(enumStackType aType);
// stylesheet functions
nsresult addToplevelItem(txToplevelItem* aItem);
nsresult openInstructionContainer(txInstructionContainer* aContainer);
void closeInstructionContainer();
nsresult addInstruction(nsAutoPtr<txInstruction> aInstruction);
nsresult loadIncludedStylesheet(const nsAString& aURI);
nsresult loadImportedStylesheet(const nsAString& aURI,
@@ -182,16 +194,17 @@ protected:
eInEmbed,
eHasEmbed
} mEmbedStatus;
nsString mStylesheetURI;
PRPackedBool mIsTopCompiler;
PRPackedBool mDoneWithThisStylesheet;
txStack mObjectStack;
txStack mOtherStack;
+ nsTArray<enumStackType> mTypeStack;
private:
txInstruction** mNextInstrPtr;
txListIterator mToplevelIterator;
nsTArray<txInstruction**> mGotoTargetPointers;
};
struct txStylesheetAttr