nsresult txStylesheet::init() { mRootFrame = new ImportFrame; NS_ENSURE_TRUE(mRootFrame, NS_ERROR_OUT_OF_MEMORY); // Create default templates // element/root template mContainerTemplate = new txPushParams; NS_ENSURE_TRUE(mContainerTemplate, NS_ERROR_OUT_OF_MEMORY); nsAutoPtr<txNodeTest> nt(new txNodeTypeTest(txNodeTypeTest::NODE_TYPE)); NS_ENSURE_TRUE(nt, NS_ERROR_OUT_OF_MEMORY); nsAutoPtr<Expr> nodeExpr(new LocationStep(nt, LocationStep::CHILD_AXIS)); NS_ENSURE_TRUE(nodeExpr, NS_ERROR_OUT_OF_MEMORY); nt.forget(); txPushNewContext* pushContext = new txPushNewContext(Move(nodeExpr)); mContainerTemplate->mNext = pushContext; NS_ENSURE_TRUE(pushContext, NS_ERROR_OUT_OF_MEMORY); txApplyDefaultElementTemplate* applyTemplates = new txApplyDefaultElementTemplate; pushContext->mNext = applyTemplates; NS_ENSURE_TRUE(applyTemplates, NS_ERROR_OUT_OF_MEMORY); txLoopNodeSet* loopNodeSet = new txLoopNodeSet(applyTemplates); applyTemplates->mNext = loopNodeSet; NS_ENSURE_TRUE(loopNodeSet, NS_ERROR_OUT_OF_MEMORY); txPopParams* popParams = new txPopParams; pushContext->mBailTarget = loopNodeSet->mNext = popParams; NS_ENSURE_TRUE(popParams, NS_ERROR_OUT_OF_MEMORY); popParams->mNext = new txReturn(); NS_ENSURE_TRUE(popParams->mNext, NS_ERROR_OUT_OF_MEMORY); // attribute/textnode template nt = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE); NS_ENSURE_TRUE(nt, NS_ERROR_OUT_OF_MEMORY); nodeExpr = new LocationStep(nt, LocationStep::SELF_AXIS); NS_ENSURE_TRUE(nodeExpr, NS_ERROR_OUT_OF_MEMORY); nt.forget(); mCharactersTemplate = new txValueOf(Move(nodeExpr), false); NS_ENSURE_TRUE(mCharactersTemplate, NS_ERROR_OUT_OF_MEMORY); mCharactersTemplate->mNext = new txReturn(); NS_ENSURE_TRUE(mCharactersTemplate->mNext, NS_ERROR_OUT_OF_MEMORY); // pi/comment/namespace template mEmptyTemplate = new txReturn(); NS_ENSURE_TRUE(mEmptyTemplate, NS_ERROR_OUT_OF_MEMORY); return NS_OK; }
txStartElement::txStartElement(nsAutoPtr<Expr>&& aName, nsAutoPtr<Expr>&& aNamespace, txNamespaceMap* aMappings) : mName(Move(aName)), mNamespace(Move(aNamespace)), mMappings(aMappings) { }
txStylesheet::GlobalVariable::GlobalVariable(nsAutoPtr<Expr>&& aExpr, nsAutoPtr<txInstruction>&& aInstr, bool aIsParam) : mExpr(Move(aExpr)), mFirstInstruction(Move(aInstr)), mIsParam(aIsParam) { }
static void TestAssignmentFromMozPair() { // Copy assignment Tuple<int, int> a{0, 0}; Pair<int, int> b{42, 42}; a = b; CHECK(Get<0>(a) == 42); CHECK(Get<1>(a) == 42); // Assignment to reference member int i = 0; int j = 0; int k = 42; Tuple<int&, int&> c{i, j}; Pair<int&, int&> d{k, k}; c = d; CHECK(i == 42); CHECK(j == 42); // Move assignment Tuple<UniquePtr<int>, UniquePtr<int>> e{MakeUnique<int>(0), MakeUnique<int>(0)}; Pair<UniquePtr<int>, UniquePtr<int>> f{MakeUnique<int>(42), MakeUnique<int>(42)}; e = Move(f); CHECK(*Get<0>(e) == 42); CHECK(*Get<1>(e) == 42); CHECK(f.first() == nullptr); CHECK(f.second() == nullptr); }
static void TestAssignmentFromStdPair() { // Copy assignment Tuple<int, int> a{0, 0}; pair<int, int> b{42, 42}; a = b; CHECK(Get<0>(a) == 42); CHECK(Get<1>(a) == 42); // Assignment to reference member int i = 0; int j = 0; int k = 42; Tuple<int&, int&> c{i, j}; pair<int&, int&> d{k, k}; c = d; CHECK(i == 42); CHECK(j == 42); // Move assignment. Tuple<UniquePtr<int>, UniquePtr<int>> e{MakeUnique<int>(0), MakeUnique<int>(0)}; // XXX: On some platforms std::pair doesn't support move constructor. pair<UniquePtr<int>, UniquePtr<int>> f; f.first = MakeUnique<int>(42); f.second = MakeUnique<int>(42); e = Move(f); CHECK(*Get<0>(e) == 42); CHECK(*Get<1>(e) == 42); CHECK(f.first == nullptr); CHECK(f.second == nullptr); }
nsresult txRtfHandler::getAsRTF(txAExprResult** aResult) { *aResult = new txResultTreeFragment(Move(mBuffer)); NS_ADDREF(*aResult); return NS_OK; }
nsresult txPushNewContext::addSort(nsAutoPtr<Expr>&& aSelectExpr, nsAutoPtr<Expr>&& aLangExpr, nsAutoPtr<Expr>&& aDataTypeExpr, nsAutoPtr<Expr>&& aOrderExpr, nsAutoPtr<Expr>&& aCaseOrderExpr) { if (SortKey *key = mSortKeys.AppendElement()) { // workaround for not triggering the Copy Constructor key->mSelectExpr = Move(aSelectExpr); key->mLangExpr = Move(aLangExpr); key->mDataTypeExpr = Move(aDataTypeExpr); key->mOrderExpr = Move(aOrderExpr); key->mCaseOrderExpr = Move(aCaseOrderExpr); return NS_OK; } return NS_ERROR_OUT_OF_MEMORY; }
NS_INTERFACE_MAP_END nsXPathExpression::nsXPathExpression(nsAutoPtr<Expr>&& aExpression, txResultRecycler* aRecycler, nsIDOMDocument *aDocument) : mExpression(Move(aExpression)), mRecycler(aRecycler), mDocument(aDocument) { }
txLREAttribute::txLREAttribute(int32_t aNamespaceID, nsIAtom* aLocalName, nsIAtom* aPrefix, nsAutoPtr<Expr>&& aValue) : mNamespaceID(aNamespaceID), mLocalName(aLocalName), mPrefix(aPrefix), mValue(Move(aValue)) { if (aNamespaceID == kNameSpaceID_None) { mLowercaseLocalName = TX_ToLowerCaseAtom(aLocalName); } }
nsresult txStylesheet::addGlobalVariable(txVariableItem* aVariable) { if (mGlobalVariables.get(aVariable->mName)) { return NS_OK; } nsAutoPtr<GlobalVariable> var( new GlobalVariable(Move(aVariable->mValue), Move(aVariable->mFirstInstruction), aVariable->mIsParam)); NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY); nsresult rv = mGlobalVariables.add(aVariable->mName, var); NS_ENSURE_SUCCESS(rv, rv); var.forget(); return NS_OK; }
JS::FormatStackDump(JSContext* cx, JS::UniqueChars&& inBuf, bool showArgs, bool showLocals, bool showThisProps) { int num = 0; JS::UniqueChars buf(Move(inBuf)); for (AllFramesIter i(cx); !i.done(); ++i) { if (i.hasScript()) buf = FormatFrame(cx, i, Move(buf), num, showArgs, showLocals, showThisProps); else buf = FormatWasmFrame(cx, i, Move(buf), num, showArgs); if (!buf) return nullptr; num++; } if (!num) buf = JS_sprintf_append(Move(buf), "JavaScript stack is empty\n"); return buf; }
nsresult txStylesheet::addKey(const txExpandedName& aName, nsAutoPtr<txPattern> aMatch, nsAutoPtr<Expr> aUse) { nsresult rv = NS_OK; txXSLKey* xslKey = mKeys.get(aName); if (!xslKey) { xslKey = new txXSLKey(aName); NS_ENSURE_TRUE(xslKey, NS_ERROR_OUT_OF_MEMORY); rv = mKeys.add(aName, xslKey); if (NS_FAILED(rv)) { delete xslKey; return rv; } } if (!xslKey->addKey(Move(aMatch), Move(aUse))) { return NS_ERROR_OUT_OF_MEMORY; } return NS_OK; }
static JS::UniqueChars FormatWasmFrame(JSContext* cx, const FrameIter& iter, JS::UniqueChars&& inBuf, int num, bool showArgs) { JSAtom* functionDisplayAtom = iter.functionDisplayAtom(); UniqueChars nameStr; if (functionDisplayAtom) nameStr = StringToNewUTF8CharsZ(cx, *functionDisplayAtom); JS::UniqueChars buf = sprintf_append(cx, Move(inBuf), "%d %s()", num, nameStr ? nameStr.get() : "<wasm-function>"); if (!buf) return nullptr; const char* filename = iter.filename(); uint32_t lineno = iter.computeLine(); buf = sprintf_append(cx, Move(buf), " [\"%s\":%d]\n", filename ? filename : "<unknown>", lineno); MOZ_ASSERT(!cx->isExceptionPending()); return buf; }
sprintf_append(JSContext* cx, JS::UniqueChars&& buf, const char* fmt, ...) { va_list ap; va_start(ap, fmt); JS::UniqueChars result = JS_vsprintf_append(Move(buf), fmt, ap); va_end(ap); if (!result) { ReportOutOfMemory(cx); return nullptr; } return result; }
txNumber::txNumber(txXSLTNumber::LevelType aLevel, nsAutoPtr<txPattern>&& aCount, nsAutoPtr<txPattern>&& aFrom, nsAutoPtr<Expr>&& aValue, nsAutoPtr<Expr>&& aFormat, nsAutoPtr<Expr>&& aGroupingSeparator, nsAutoPtr<Expr>&& aGroupingSize) : mLevel(aLevel), mCount(Move(aCount)), mFrom(Move(aFrom)), mValue(Move(aValue)), mFormat(Move(aFormat)), mGroupingSeparator(Move(aGroupingSeparator)), mGroupingSize(Move(aGroupingSize)) { }
static void TestConstruction() { // Default construction Tuple<> a; unused << a; Tuple<int> b; unused << b; // Construction from elements int x = 1, y = 1; Tuple<int, int> c{x, y}; Tuple<int&, const int&> d{x, y}; x = 42; y = 42; CHECK(Get<0>(c) == 1); CHECK(Get<1>(c) == 1); CHECK(Get<0>(d) == 42); CHECK(Get<1>(d) == 42); // Construction from objects convertible to the element types Tuple<int, int> e{1.0, ConvertibleToInt{}}; // Copy construction Tuple<int> x1; Tuple<int> x2{x1}; Tuple<int, int> f(c); CHECK(Get<0>(f) == 1); CHECK(Get<0>(f) == 1); // Move construction Tuple<UniquePtr<int>> g{MakeUnique<int>(42)}; Tuple<UniquePtr<int>> h{Move(g)}; CHECK(Get<0>(g) == nullptr); CHECK(*Get<0>(h) == 42); }
static void TestAssignment() { // Copy assignment Tuple<int> a{0}; Tuple<int> b{42}; a = b; CHECK(Get<0>(a) == 42); // Assignment to reference member int i = 0; int j = 42; Tuple<int&> c{i}; Tuple<int&> d{j}; c = d; CHECK(i == 42); // Move assignment Tuple<UniquePtr<int>> e{MakeUnique<int>(0)}; Tuple<UniquePtr<int>> f{MakeUnique<int>(42)}; e = Move(f); CHECK(*Get<0>(e) == 42); CHECK(Get<0>(f) == nullptr); }
js::SetSourceHook(JSContext* cx, mozilla::UniquePtr<SourceHook> hook) { cx->runtime()->sourceHook.ref() = Move(hook); }
js::ForgetSourceHook(JSContext* cx) { return Move(cx->runtime()->sourceHook.ref()); }
txAttribute::txAttribute(nsAutoPtr<Expr>&& aName, nsAutoPtr<Expr>&& aNamespace, txNamespaceMap* aMappings) : mName(Move(aName)), mNamespace(Move(aNamespace)), mMappings(aMappings) { }
txValueOf::txValueOf(nsAutoPtr<Expr>&& aExpr, bool aDOE) : mExpr(Move(aExpr)), mDOE(aDOE) { }
static bool TestCopyAndMove() { // Check that we get moves when possible for types that can support both moves // and copies. Maybe<BasicValue> mayBasicValue = Some(BasicValue(1)); MOZ_RELEASE_ASSERT(mayBasicValue->GetStatus() == eWasMoveConstructed); MOZ_RELEASE_ASSERT(mayBasicValue->GetTag() == 1); mayBasicValue = Some(BasicValue(2)); MOZ_RELEASE_ASSERT(mayBasicValue->GetStatus() == eWasMoveAssigned); MOZ_RELEASE_ASSERT(mayBasicValue->GetTag() == 2); mayBasicValue.reset(); mayBasicValue.emplace(BasicValue(3)); MOZ_RELEASE_ASSERT(mayBasicValue->GetStatus() == eWasMoveConstructed); MOZ_RELEASE_ASSERT(mayBasicValue->GetTag() == 3); // Check that we get copies when moves aren't possible. Maybe<BasicValue> mayBasicValue2 = Some(*mayBasicValue); MOZ_RELEASE_ASSERT(mayBasicValue2->GetStatus() == eWasCopyConstructed); MOZ_RELEASE_ASSERT(mayBasicValue2->GetTag() == 3); mayBasicValue->SetTag(4); mayBasicValue2 = mayBasicValue; // This test should work again when we fix bug 1052940. //MOZ_RELEASE_ASSERT(mayBasicValue2->GetStatus() == eWasCopyAssigned); MOZ_RELEASE_ASSERT(mayBasicValue2->GetTag() == 4); mayBasicValue->SetTag(5); mayBasicValue2.reset(); mayBasicValue2.emplace(*mayBasicValue); MOZ_RELEASE_ASSERT(mayBasicValue2->GetStatus() == eWasCopyConstructed); MOZ_RELEASE_ASSERT(mayBasicValue2->GetTag() == 5); // Check that Move() works. (Another sanity check for move support.) Maybe<BasicValue> mayBasicValue3 = Some(Move(*mayBasicValue)); MOZ_RELEASE_ASSERT(mayBasicValue3->GetStatus() == eWasMoveConstructed); MOZ_RELEASE_ASSERT(mayBasicValue3->GetTag() == 5); MOZ_RELEASE_ASSERT(mayBasicValue->GetStatus() == eWasMovedFrom); mayBasicValue2->SetTag(6); mayBasicValue3 = Some(Move(*mayBasicValue2)); MOZ_RELEASE_ASSERT(mayBasicValue3->GetStatus() == eWasMoveAssigned); MOZ_RELEASE_ASSERT(mayBasicValue3->GetTag() == 6); MOZ_RELEASE_ASSERT(mayBasicValue2->GetStatus() == eWasMovedFrom); Maybe<BasicValue> mayBasicValue4; mayBasicValue4.emplace(Move(*mayBasicValue3)); MOZ_RELEASE_ASSERT(mayBasicValue4->GetStatus() == eWasMoveConstructed); MOZ_RELEASE_ASSERT(mayBasicValue4->GetTag() == 6); MOZ_RELEASE_ASSERT(mayBasicValue3->GetStatus() == eWasMovedFrom); // Check that we always get copies for types that don't support moves. // XXX(seth): These tests fail but probably shouldn't. For now we'll just // consider using Maybe with types that allow copies but have deleted or // private move constructors, or which do not support copy assignment, to // be supported only to the extent that we need for existing code to work. // These tests should work again when we fix bug 1052940. /* Maybe<UnmovableValue> mayUnmovableValue = Some(UnmovableValue()); MOZ_RELEASE_ASSERT(mayUnmovableValue->GetStatus() == eWasCopyConstructed); mayUnmovableValue = Some(UnmovableValue()); MOZ_RELEASE_ASSERT(mayUnmovableValue->GetStatus() == eWasCopyAssigned); mayUnmovableValue.reset(); mayUnmovableValue.emplace(UnmovableValue()); MOZ_RELEASE_ASSERT(mayUnmovableValue->GetStatus() == eWasCopyConstructed); */ // Check that types that only support moves, but not copies, work. Maybe<UncopyableValue> mayUncopyableValue = Some(UncopyableValue()); MOZ_RELEASE_ASSERT(mayUncopyableValue->GetStatus() == eWasMoveConstructed); mayUncopyableValue = Some(UncopyableValue()); MOZ_RELEASE_ASSERT(mayUncopyableValue->GetStatus() == eWasMoveAssigned); mayUncopyableValue.reset(); mayUncopyableValue.emplace(UncopyableValue()); MOZ_RELEASE_ASSERT(mayUncopyableValue->GetStatus() == eWasMoveConstructed); // Check that types that support neither moves or copies work. Maybe<UncopyableUnmovableValue> mayUncopyableUnmovableValue; mayUncopyableUnmovableValue.emplace(); MOZ_RELEASE_ASSERT(mayUncopyableUnmovableValue->GetStatus() == eWasDefaultConstructed); mayUncopyableUnmovableValue.reset(); mayUncopyableUnmovableValue.emplace(0); MOZ_RELEASE_ASSERT(mayUncopyableUnmovableValue->GetStatus() == eWasConstructed); return true; }
js::ForgetSourceHook(JSContext* cx) { return Move(cx->sourceHook); }
js::SetSourceHook(JSContext* cx, mozilla::UniquePtr<SourceHook> hook) { cx->sourceHook = Move(hook); }
txResultTreeFragment::txResultTreeFragment(nsAutoPtr<txResultBuffer>&& aBuffer) : txAExprResult(nullptr), mBuffer(Move(aBuffer)) { }
js::SetSourceHook(JSRuntime *rt, UniquePtr<SourceHook> hook) { rt->sourceHook = Move(hook); }
static JS::UniqueChars FormatFrame(JSContext* cx, const FrameIter& iter, JS::UniqueChars&& inBuf, int num, bool showArgs, bool showLocals, bool showThisProps) { MOZ_ASSERT(!cx->isExceptionPending()); RootedScript script(cx, iter.script()); jsbytecode* pc = iter.pc(); RootedObject envChain(cx, iter.environmentChain(cx)); JSAutoCompartment ac(cx, envChain); const char* filename = script->filename(); unsigned lineno = PCToLineNumber(script, pc); RootedFunction fun(cx, iter.maybeCallee(cx)); RootedString funname(cx); if (fun) funname = fun->displayAtom(); RootedValue thisVal(cx); if (iter.hasUsableAbstractFramePtr() && iter.isFunctionFrame() && fun && !fun->isArrow() && !fun->isDerivedClassConstructor() && !(fun->isBoundFunction() && iter.isConstructing())) { if (!GetFunctionThis(cx, iter.abstractFramePtr(), &thisVal)) return nullptr; } // print the frame number and function name JS::UniqueChars buf(Move(inBuf)); if (funname) { JSAutoByteString funbytes; char* str = funbytes.encodeLatin1(cx, funname); if (!str) return nullptr; buf = sprintf_append(cx, Move(buf), "%d %s(", num, str); } else if (fun) { buf = sprintf_append(cx, Move(buf), "%d anonymous(", num); } else { buf = sprintf_append(cx, Move(buf), "%d <TOP LEVEL>", num); } if (!buf) return nullptr; if (showArgs && iter.hasArgs()) { PositionalFormalParameterIter fi(script); bool first = true; for (unsigned i = 0; i < iter.numActualArgs(); i++) { RootedValue arg(cx); if (i < iter.numFormalArgs() && fi.closedOver()) { arg = iter.callObj(cx).aliasedBinding(fi); } else if (iter.hasUsableAbstractFramePtr()) { if (script->analyzedArgsUsage() && script->argsObjAliasesFormals() && iter.hasArgsObj()) { arg = iter.argsObj().arg(i); } else { arg = iter.unaliasedActual(i, DONT_CHECK_ALIASING); } } else { arg = MagicValue(JS_OPTIMIZED_OUT); } JSAutoByteString valueBytes; const char* value = FormatValue(cx, arg, valueBytes); if (!value) { if (cx->isThrowingOutOfMemory()) return nullptr; cx->clearPendingException(); } JSAutoByteString nameBytes; const char* name = nullptr; if (i < iter.numFormalArgs()) { MOZ_ASSERT(fi.argumentSlot() == i); if (!fi.isDestructured()) { name = nameBytes.encodeLatin1(cx, fi.name()); if (!name) return nullptr; } else { name = "(destructured parameter)"; } fi++; } if (value) { buf = sprintf_append(cx, Move(buf), "%s%s%s%s%s%s", !first ? ", " : "", name ? name :"", name ? " = " : "", arg.isString() ? "\"" : "", value, arg.isString() ? "\"" : ""); if (!buf) return nullptr; first = false; } else { buf = sprintf_append(cx, Move(buf), " <Failed to get argument while inspecting stack frame>\n"); if (!buf) return nullptr; } } } // print filename and line number buf = sprintf_append(cx, Move(buf), "%s [\"%s\":%d]\n", fun ? ")" : "", filename ? filename : "<unknown>", lineno); if (!buf) return nullptr; // Note: Right now we don't dump the local variables anymore, because // that is hard to support across all the JITs etc. // print the value of 'this' if (showLocals) { if (!thisVal.isUndefined()) { JSAutoByteString thisValBytes; RootedString thisValStr(cx, ToString<CanGC>(cx, thisVal)); if (!thisValStr) { if (cx->isThrowingOutOfMemory()) return nullptr; cx->clearPendingException(); } if (thisValStr) { const char* str = thisValBytes.encodeLatin1(cx, thisValStr); if (!str) return nullptr; buf = sprintf_append(cx, Move(buf), " this = %s\n", str); } else { buf = sprintf_append(cx, Move(buf), " <failed to get 'this' value>\n"); } if (!buf) return nullptr; } } if (showThisProps && thisVal.isObject()) { RootedObject obj(cx, &thisVal.toObject()); AutoIdVector keys(cx); if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY, &keys)) { if (cx->isThrowingOutOfMemory()) return nullptr; cx->clearPendingException(); } RootedId id(cx); for (size_t i = 0; i < keys.length(); i++) { RootedId id(cx, keys[i]); RootedValue key(cx, IdToValue(id)); RootedValue v(cx); if (!GetProperty(cx, obj, obj, id, &v)) { if (cx->isThrowingOutOfMemory()) return nullptr; cx->clearPendingException(); buf = sprintf_append(cx, Move(buf), " <Failed to fetch property while inspecting stack frame>\n"); if (!buf) return nullptr; continue; } JSAutoByteString nameBytes; const char* name = FormatValue(cx, key, nameBytes); if (!name) { if (cx->isThrowingOutOfMemory()) return nullptr; cx->clearPendingException(); } JSAutoByteString valueBytes; const char* value = FormatValue(cx, v, valueBytes); if (!value) { if (cx->isThrowingOutOfMemory()) return nullptr; cx->clearPendingException(); } if (name && value) { buf = sprintf_append(cx, Move(buf), " this.%s = %s%s%s\n", name, v.isString() ? "\"" : "", value, v.isString() ? "\"" : ""); } else { buf = sprintf_append(cx, Move(buf), " <Failed to format values while inspecting stack frame>\n"); } if (!buf) return nullptr; } } MOZ_ASSERT(!cx->isExceptionPending()); return buf; }
txSetVariable::txSetVariable(const txExpandedName& aName, nsAutoPtr<Expr>&& aValue) : mName(aName), mValue(Move(aValue)) { }
js::ForgetSourceHook(JSRuntime *rt) { return Move(rt->sourceHook); }
nsresult txStylesheet::addTemplate(txTemplateItem* aTemplate, ImportFrame* aImportFrame) { NS_ASSERTION(aTemplate, "missing template"); txInstruction* instr = aTemplate->mFirstInstruction; nsresult rv = mTemplateInstructions.add(instr); NS_ENSURE_SUCCESS(rv, rv); // mTemplateInstructions now owns the instructions aTemplate->mFirstInstruction.forget(); if (!aTemplate->mName.isNull()) { rv = mNamedTemplates.add(aTemplate->mName, instr); NS_ENSURE_TRUE(NS_SUCCEEDED(rv) || rv == NS_ERROR_XSLT_ALREADY_SET, rv); } if (!aTemplate->mMatch) { // This is no error, see section 6 Named Templates return NS_OK; } // get the txList for the right mode nsTArray<MatchableTemplate>* templates = aImportFrame->mMatchableTemplates.get(aTemplate->mMode); if (!templates) { nsAutoPtr< nsTArray<MatchableTemplate> > newList( new nsTArray<MatchableTemplate>); NS_ENSURE_TRUE(newList, NS_ERROR_OUT_OF_MEMORY); rv = aImportFrame->mMatchableTemplates.set(aTemplate->mMode, newList); NS_ENSURE_SUCCESS(rv, rv); templates = newList.forget(); } // Add the simple patterns to the list of matchable templates, according // to default priority nsAutoPtr<txPattern> simple = Move(aTemplate->mMatch); nsAutoPtr<txPattern> unionPattern; if (simple->getType() == txPattern::UNION_PATTERN) { unionPattern = Move(simple); simple = unionPattern->getSubPatternAt(0); unionPattern->setSubPatternAt(0, nullptr); } uint32_t unionPos = 1; // only used when unionPattern is set while (simple) { double priority = aTemplate->mPrio; if (mozilla::IsNaN(priority)) { priority = simple->getDefaultPriority(); NS_ASSERTION(!mozilla::IsNaN(priority), "simple pattern without default priority"); } uint32_t i, len = templates->Length(); for (i = 0; i < len; ++i) { if (priority > (*templates)[i].mPriority) { break; } } MatchableTemplate* nt = templates->InsertElementAt(i); NS_ENSURE_TRUE(nt, NS_ERROR_OUT_OF_MEMORY); nt->mFirstInstruction = instr; nt->mMatch = Move(simple); nt->mPriority = priority; if (unionPattern) { simple = unionPattern->getSubPatternAt(unionPos); if (simple) { unionPattern->setSubPatternAt(unionPos, nullptr); } ++unionPos; } } return NS_OK; }