diff --git a/.hgignore b/.hgignore index af60947c152..3509e7a2bdb 100644 --- a/.hgignore +++ b/.hgignore @@ -7,6 +7,10 @@ (^|/)ID$ (^|/)\.DS_Store$ +# Vim swap files. +^\.sw.$ +.[^/]*\.sw.$ + # User files that may appear at the root ^\.mozconfig ^mozconfig$ diff --git a/editor/libeditor/html/nsHTMLEditRules.cpp b/editor/libeditor/html/nsHTMLEditRules.cpp index fa2b1189f58..905c1395d2f 100644 --- a/editor/libeditor/html/nsHTMLEditRules.cpp +++ b/editor/libeditor/html/nsHTMLEditRules.cpp @@ -1612,7 +1612,7 @@ nsHTMLEditRules::WillInsertBreak(nsISelection *aSelection, PRBool *aCancel, PRBo } nsCOMPtr listItem = IsInListItem(blockParent); - if (listItem) + if (listItem && listItem != hostNode) { res = ReturnInListItem(aSelection, listItem, node, offset); *aHandled = PR_TRUE; @@ -6507,6 +6507,7 @@ nsHTMLEditRules::MakeTransitionList(nsCOMArray& inArrayOfNodes, /////////////////////////////////////////////////////////////////////////// // IsInListItem: if aNode is the descendant of a listitem, return that li. // But table element boundaries are stoppers on the search. +// Also stops on the active editor host (contenteditable). // Also test if aNode is an li itself. // nsCOMPtr @@ -6520,6 +6521,7 @@ nsHTMLEditRules::IsInListItem(nsIDOMNode *aNode) while (parent) { + if (!mHTMLEditor->IsNodeInActiveEditor(parent)) return nsnull; if (nsHTMLEditUtils::IsTableElement(parent)) return nsnull; if (nsHTMLEditUtils::IsListItem(parent)) return parent; tmp=parent; tmp->GetParentNode(getter_AddRefs(parent)); diff --git a/editor/libeditor/html/tests/Makefile.in b/editor/libeditor/html/tests/Makefile.in index 6f72aa83471..32866c44f95 100644 --- a/editor/libeditor/html/tests/Makefile.in +++ b/editor/libeditor/html/tests/Makefile.in @@ -73,6 +73,7 @@ _TEST_FILES = \ file_bug549262.html \ test_bug550434.html \ test_bug551704.html \ + test_bug570144.html \ test_bug592592.html \ test_bug597784.html \ test_bug599322.html \ diff --git a/editor/libeditor/html/tests/test_bug460740.html b/editor/libeditor/html/tests/test_bug460740.html index 517e9e1a154..5db1ed7db04 100644 --- a/editor/libeditor/html/tests/test_bug460740.html +++ b/editor/libeditor/html/tests/test_bug460740.html @@ -84,8 +84,8 @@ function split(element, caretPos) { // put the caret on the requested position var range = document.createRange(); var sel = window.getSelection(); - range.setStart(element.firstChild, len); - range.setEnd(element.firstChild, len); + range.setStart(element.firstChild, pos); + range.setEnd(element.firstChild, pos); sel.addRange(range); // simulates a [Return] keypress diff --git a/editor/libeditor/html/tests/test_bug570144.html b/editor/libeditor/html/tests/test_bug570144.html new file mode 100644 index 00000000000..e3b98b8d62d --- /dev/null +++ b/editor/libeditor/html/tests/test_bug570144.html @@ -0,0 +1,123 @@ + + + + + Test for Bug 570144 + + + + + +Mozilla Bug 570144 +

+
+ +
+
    +
  1. foo

  2. +
+
    +
  • foo

  • +
+
+
foo
+

bar

+
+
+ +
+
    +
  1. foo

  2. +
+
    +
  • foo

  • +
+
+
foo
+

bar

+
+
+ +
+
    +
  1. foo

  2. +
+
    +
  • foo

  • +
+
+
foo
+

bar

+
+
+
+ +
+
+
+ + diff --git a/gfx/tests/crashtests/686190-1.html b/gfx/tests/crashtests/686190-1.html new file mode 100644 index 00000000000..26cda094fa8 --- /dev/null +++ b/gfx/tests/crashtests/686190-1.html @@ -0,0 +1,18 @@ + + + + + +xyzzy + + diff --git a/gfx/tests/crashtests/Prototype.ttf b/gfx/tests/crashtests/Prototype.ttf new file mode 100644 index 00000000000..c70bf00f472 Binary files /dev/null and b/gfx/tests/crashtests/Prototype.ttf differ diff --git a/gfx/tests/crashtests/crashtests.list b/gfx/tests/crashtests/crashtests.list index ac7c54dedd8..c7854ee8561 100644 --- a/gfx/tests/crashtests/crashtests.list +++ b/gfx/tests/crashtests/crashtests.list @@ -84,3 +84,4 @@ load 594654-1.xhtml load 595727-1.html load 633453-1.html load 633322-1.html +load 686190-1.html diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 85b869f35f2..4378551c2b7 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -1111,10 +1111,10 @@ struct GlyphBuffer { void Flush(cairo_t *aCR, PRBool aDrawToPath, PRBool aReverse, PRBool aFinish = PR_FALSE) { - // Ensure there's enough room for at least two glyphs in the - // buffer (because we may allocate two glyphs between flushes) - if (!aFinish && mNumGlyphs + 2 <= GLYPH_BUFFER_SIZE) + // Ensure there's enough room for a glyph to be added to the buffer + if (!aFinish && mNumGlyphs < GLYPH_BUFFER_SIZE) { return; + } if (aReverse) { for (PRUint32 i = 0; i < mNumGlyphs/2; ++i) { @@ -1222,6 +1222,7 @@ gfxFont::Draw(gfxTextRun *aTextRun, PRUint32 aStart, PRUint32 aEnd, } glyph->x = ToDeviceUnits(glyphX, devUnitsPerAppUnit); glyph->y = ToDeviceUnits(y, devUnitsPerAppUnit); + glyphs.Flush(cr, aDrawToPath, isRTL); // synthetic bolding by multi-striking with 1-pixel offsets // at least once, more if there's room (large font sizes) @@ -1237,10 +1238,9 @@ gfxFont::Draw(gfxTextRun *aTextRun, PRUint32 aStart, PRUint32 aEnd, devUnitsPerAppUnit); doubleglyph->y = glyph->y; strikeOffset += synBoldOnePixelOffset; + glyphs.Flush(cr, aDrawToPath, isRTL); } while (--strikeCount > 0); } - - glyphs.Flush(cr, aDrawToPath, isRTL); } else { PRUint32 glyphCount = glyphData->GetGlyphCount(); if (glyphCount > 0) { @@ -1275,6 +1275,7 @@ gfxFont::Draw(gfxTextRun *aTextRun, PRUint32 aStart, PRUint32 aEnd, } glyph->x = ToDeviceUnits(glyphX, devUnitsPerAppUnit); glyph->y = ToDeviceUnits(y + details->mYOffset, devUnitsPerAppUnit); + glyphs.Flush(cr, aDrawToPath, isRTL); if (IsSyntheticBold()) { double strikeOffset = synBoldOnePixelOffset; @@ -1289,10 +1290,9 @@ gfxFont::Draw(gfxTextRun *aTextRun, PRUint32 aStart, PRUint32 aEnd, devUnitsPerAppUnit); doubleglyph->y = glyph->y; strikeOffset += synBoldOnePixelOffset; + glyphs.Flush(cr, aDrawToPath, isRTL); } while (--strikeCount > 0); } - - glyphs.Flush(cr, aDrawToPath, isRTL); } x += direction*advance; } diff --git a/js/src/assembler/assembler/X86Assembler.h b/js/src/assembler/assembler/X86Assembler.h index 26b5e1e7572..8bd2028ff04 100644 --- a/js/src/assembler/assembler/X86Assembler.h +++ b/js/src/assembler/assembler/X86Assembler.h @@ -989,7 +989,9 @@ public: void imull_i32r(RegisterID src, int32_t value, RegisterID dst) { - FIXME_INSN_PRINTING; + js::JaegerSpew(js::JSpew_Insns, + IPFX "imull %d, %s, %s\n", + MAYBE_PAD, value, nameIReg(4, src), nameIReg(4, dst)); m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src); m_formatter.immediate32(value); } diff --git a/js/src/jsanalyze.h b/js/src/jsanalyze.h index 5570310b346..5b7ac478dc4 100644 --- a/js/src/jsanalyze.h +++ b/js/src/jsanalyze.h @@ -1031,13 +1031,13 @@ class ScriptAnalysis bool hasPushedTypes(const jsbytecode *pc) { return getCode(pc).pushedTypes != NULL; } - types::TypeBarrier *typeBarriers(uint32 offset) { + types::TypeBarrier *typeBarriers(JSContext *cx, uint32 offset) { if (getCode(offset).typeBarriers) - pruneTypeBarriers(offset); + pruneTypeBarriers(cx, offset); return getCode(offset).typeBarriers; } - types::TypeBarrier *typeBarriers(const jsbytecode *pc) { - return typeBarriers(pc - script->code); + types::TypeBarrier *typeBarriers(JSContext *cx, const jsbytecode *pc) { + return typeBarriers(cx, pc - script->code); } void addTypeBarrier(JSContext *cx, const jsbytecode *pc, types::TypeSet *target, types::Type type); @@ -1045,7 +1045,7 @@ class ScriptAnalysis types::TypeSet *target, JSObject *singleton, jsid singletonId); /* Remove obsolete type barriers at the given offset. */ - void pruneTypeBarriers(uint32 offset); + void pruneTypeBarriers(JSContext *cx, uint32 offset); /* * Remove still-active type barriers at the given offset. If 'all' is set, diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 9cddb207f6c..c185367815b 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1801,7 +1801,7 @@ JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj) * Since ES5 15.1.1.3 undefined can't be deleted. */ atom = rt->atomState.typeAtoms[JSTYPE_VOID]; - if (!obj->nativeContains(ATOM_TO_JSID(atom)) && + if (!obj->nativeContains(cx, ATOM_TO_JSID(atom)) && !obj->defineProperty(cx, ATOM_TO_JSID(atom), UndefinedValue(), PropertyStub, StrictPropertyStub, JSPROP_PERMANENT | JSPROP_READONLY)) { @@ -1877,7 +1877,7 @@ static JSIdArray * EnumerateIfResolved(JSContext *cx, JSObject *obj, JSAtom *atom, JSIdArray *ida, jsint *ip, JSBool *foundp) { - *foundp = obj->nativeContains(ATOM_TO_JSID(atom)); + *foundp = obj->nativeContains(cx, ATOM_TO_JSID(atom)); if (*foundp) ida = AddAtomToArray(cx, atom, ida, ip); return ida; @@ -3347,7 +3347,7 @@ JS_AlreadyHasOwnPropertyById(JSContext *cx, JSObject *obj, jsid id, JSBool *foun return JS_TRUE; } - *foundp = obj->nativeContains(id); + *foundp = obj->nativeContains(cx, id); return JS_TRUE; } diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 01778e63988..75c2239fd58 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -347,7 +347,7 @@ JSObject::arrayGetOwnDataElement(JSContext *cx, size_t i, Value *vp) if (!IndexToId(cx, this, i, &hole, &id)) return false; - const Shape *shape = nativeLookup(id); + const Shape *shape = nativeLookup(cx, id); if (!shape || !shape->isDataDescriptor()) vp->setMagic(JS_ARRAY_HOLE); else @@ -1104,7 +1104,7 @@ static bool AddLengthProperty(JSContext *cx, JSObject *obj) { const jsid lengthId = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom); - JS_ASSERT(!obj->nativeLookup(lengthId)); + JS_ASSERT(!obj->nativeLookup(cx, lengthId)); return obj->addProperty(cx, lengthId, array_length_getter, array_length_setter, SHAPE_INVALID_SLOT, JSPROP_PERMANENT | JSPROP_SHARED, 0, 0); diff --git a/js/src/jsemit.cpp b/js/src/jsemit.cpp index fb3bd0a26c9..5e30a01f0dd 100644 --- a/js/src/jsemit.cpp +++ b/js/src/jsemit.cpp @@ -1718,7 +1718,7 @@ js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp, JSStmtInfo *stmt JSObject *obj = stmt->blockBox->object; JS_ASSERT(obj->isStaticBlock()); - const Shape *shape = obj->nativeLookup(ATOM_TO_JSID(atom)); + const Shape *shape = obj->nativeLookup(tc->parser->context, ATOM_TO_JSID(atom)); if (shape) { JS_ASSERT(shape->hasShortID()); @@ -1779,7 +1779,7 @@ LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom, JS_ASSERT(cg->compileAndGo()); obj = cg->scopeChain(); - const Shape *shape = obj->nativeLookup(ATOM_TO_JSID(atom)); + const Shape *shape = obj->nativeLookup(cx, ATOM_TO_JSID(atom)); if (shape) { /* * We're compiling code that will be executed immediately, @@ -4353,7 +4353,7 @@ static JSBool EmitVariables(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn, JSBool inLetHead, ptrdiff_t *headNoteIndex) { - bool let, forInVar, first; + bool forInVar, first; ptrdiff_t off, noteIndex, tmp; JSParseNode *pn2, *pn3, *next; JSOp op; @@ -4375,7 +4375,7 @@ EmitVariables(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn, * to the start of the block, a 'for (let x = i...) ...' loop evaluates i * in the containing scope, and puts x in the loop body's scope. */ - let = (pn->pn_op == JSOP_NOP); + DebugOnly let = (pn->pn_op == JSOP_NOP); forInVar = (pn->pn_xflags & PNX_FORINVAR) != 0; off = noteIndex = -1; @@ -5954,7 +5954,6 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) case TOK_CATCH: { ptrdiff_t catchStart, guardJump; - JSObject *blockObj; /* * Morph STMT_BLOCK to STMT_CATCH, note the block entry code offset, @@ -5964,7 +5963,6 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) JS_ASSERT(stmt->type == STMT_BLOCK && (stmt->flags & SIF_SCOPE)); stmt->type = STMT_CATCH; catchStart = stmt->update; - blockObj = stmt->blockBox->object; /* Go up one statement info record to the TRY or FINALLY record. */ stmt = stmt->down; diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index d6a2f6bf4df..f73abb9ca3f 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -1207,7 +1207,7 @@ StackFrame::getValidCalleeObject(JSContext *cx, Value *vp) continue; if (thisp->hasMethodBarrier()) { - const Shape *shape = thisp->nativeLookup(ATOM_TO_JSID(fun->methodAtom())); + const Shape *shape = thisp->nativeLookup(cx, ATOM_TO_JSID(fun->methodAtom())); if (shape) { /* * Two cases follow: the method barrier was not crossed @@ -2313,11 +2313,11 @@ LookupInterpretedFunctionPrototype(JSContext *cx, JSObject *funobj) #endif jsid id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom); - const Shape *shape = funobj->nativeLookup(id); + const Shape *shape = funobj->nativeLookup(cx, id); if (!shape) { if (!ResolveInterpretedFunctionPrototype(cx, funobj)) return NULL; - shape = funobj->nativeLookup(id); + shape = funobj->nativeLookup(cx, id); } JS_ASSERT(!shape->configurable()); JS_ASSERT(shape->isDataDescriptor()); diff --git a/js/src/jsfun.h b/js/src/jsfun.h index a151de52a14..e7cebc450b3 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -326,9 +326,9 @@ ClassMethodIsNative(JSContext *cx, JSObject *obj, Class *clasp, jsid methodid, N JS_ASSERT(obj->getClass() == clasp); Value v; - if (!HasDataProperty(obj, methodid, &v)) { + if (!HasDataProperty(cx, obj, methodid, &v)) { JSObject *proto = obj->getProto(); - if (!proto || proto->getClass() != clasp || !HasDataProperty(proto, methodid, &v)) + if (!proto || proto->getClass() != clasp || !HasDataProperty(cx, proto, methodid, &v)) return false; } diff --git a/js/src/jsgcinlines.h b/js/src/jsgcinlines.h index a7d1c40ee63..13887ef6ce6 100644 --- a/js/src/jsgcinlines.h +++ b/js/src/jsgcinlines.h @@ -143,6 +143,15 @@ GetGCObjectKind(size_t numSlots, bool isArray = false) return slotsToThingKind[numSlots]; } +static inline AllocKind +GetGCObjectFixedSlotsKind(size_t numFixedSlots) +{ + extern AllocKind slotsToThingKind[]; + + JS_ASSERT(numFixedSlots < SLOTS_TO_THING_KIND_LIMIT); + return slotsToThingKind[numFixedSlots]; +} + static inline bool IsBackgroundAllocKind(AllocKind kind) { diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 8126c88e78e..8dcb0367950 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -756,16 +756,16 @@ TypeSet::addFilterPrimitives(JSContext *cx, TypeSet *target, FilterKind filter) /* If id is a normal slotful 'own' property of an object, get its shape. */ static inline const Shape * -GetSingletonShape(JSObject *obj, jsid id) +GetSingletonShape(JSContext *cx, JSObject *obj, jsid id) { - const Shape *shape = obj->nativeLookup(id); + const Shape *shape = obj->nativeLookup(cx, id); if (shape && shape->hasDefaultGetterOrIsMethod() && shape->slot != SHAPE_INVALID_SLOT) return shape; return NULL; } void -ScriptAnalysis::pruneTypeBarriers(uint32 offset) +ScriptAnalysis::pruneTypeBarriers(JSContext *cx, uint32 offset) { TypeBarrier **pbarrier = &getCode(offset).typeBarriers; while (*pbarrier) { @@ -777,7 +777,7 @@ ScriptAnalysis::pruneTypeBarriers(uint32 offset) } if (barrier->singleton) { JS_ASSERT(barrier->type.isPrimitive(JSVAL_TYPE_UNDEFINED)); - const Shape *shape = GetSingletonShape(barrier->singleton, barrier->singletonId); + const Shape *shape = GetSingletonShape(cx, barrier->singleton, barrier->singletonId); if (shape && !barrier->singleton->nativeGetSlot(shape->slot).isUndefined()) { /* * When we analyzed the script the singleton had an 'own' @@ -805,7 +805,7 @@ static const uint32 BARRIER_OBJECT_LIMIT = 10; void ScriptAnalysis::breakTypeBarriers(JSContext *cx, uint32 offset, bool all) { - pruneTypeBarriers(offset); + pruneTypeBarriers(cx, offset); TypeBarrier **pbarrier = &getCode(offset).typeBarriers; while (*pbarrier) { @@ -1004,7 +1004,7 @@ PropertyAccess(JSContext *cx, JSScript *script, jsbytecode *pc, TypeObject *obje * to remove the barrier after the property becomes defined, * even if no undefined value is ever observed at pc. */ - const Shape *shape = GetSingletonShape(object->singleton, id); + const Shape *shape = GetSingletonShape(cx, object->singleton, id); if (shape && object->singleton->nativeGetSlot(shape->slot).isUndefined()) script->analysis()->addSingletonTypeBarrier(cx, pc, target, object->singleton, id); } @@ -2728,7 +2728,7 @@ TypeObject::addProperty(JSContext *cx, jsid id, Property **pprop) shape = shape->previous(); } } else { - const Shape *shape = singleton->nativeLookup(id); + const Shape *shape = singleton->nativeLookup(cx, id); if (shape) UpdatePropertyType(cx, &base->types, singleton, shape, false); } diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 5b84020c0ae..6e904fdbdbe 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -3755,9 +3755,9 @@ BEGIN_CASE(JSOP_SETMETHOD) { #ifdef DEBUG if (entry->directHit()) { - JS_ASSERT(obj->nativeContains(*shape)); + JS_ASSERT(obj->nativeContains(cx, *shape)); } else { - JS_ASSERT(obj2->nativeContains(*shape)); + JS_ASSERT(obj2->nativeContains(cx, *shape)); JS_ASSERT(entry->vcapTag() == 1); JS_ASSERT(entry->kshape != entry->vshape()); JS_ASSERT(!shape->hasSlot()); diff --git a/js/src/jslock.cpp b/js/src/jslock.cpp index 9dbfcfbd9c2..a9bb5c2301c 100644 --- a/js/src/jslock.cpp +++ b/js/src/jslock.cpp @@ -592,8 +592,6 @@ static int js_SuspendThread(JSThinLock *tl) { JSFatLock *fl; - PRStatus stat; - if (tl->fat == NULL) fl = tl->fat = GetFatlock(tl); else @@ -602,7 +600,7 @@ js_SuspendThread(JSThinLock *tl) fl->susp++; PR_Lock(fl->slock); js_UnlockGlobal(tl); - stat = PR_WaitCondVar(fl->svar, PR_INTERVAL_NO_TIMEOUT); + DebugOnly stat = PR_WaitCondVar(fl->svar, PR_INTERVAL_NO_TIMEOUT); JS_ASSERT(stat != PR_FAILURE); PR_Unlock(fl->slock); js_LockGlobal(tl); @@ -622,13 +620,11 @@ static void js_ResumeThread(JSThinLock *tl) { JSFatLock *fl = tl->fat; - PRStatus stat; - JS_ASSERT(fl != NULL); JS_ASSERT(fl->susp > 0); PR_Lock(fl->slock); js_UnlockGlobal(tl); - stat = PR_NotifyCondVar(fl->svar); + DebugOnly stat = PR_NotifyCondVar(fl->svar); JS_ASSERT(stat != PR_FAILURE); PR_Unlock(fl->slock); } diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index ce59ee432f6..e129ad03b47 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -3117,7 +3117,7 @@ js_CreateThisFromTrace(JSContext *cx, JSObject *ctor, uintN protoSlot) JS_ASSERT(ctor->isFunction()); JS_ASSERT(ctor->getFunctionPrivate()->isInterpreted()); jsid id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom); - const Shape *shape = ctor->nativeLookup(id); + const Shape *shape = ctor->nativeLookup(cx, id); JS_ASSERT(shape->slot == protoSlot); JS_ASSERT(!shape->configurable()); JS_ASSERT(!shape->isMethod()); @@ -4115,7 +4115,7 @@ DefineStandardSlot(JSContext *cx, JSObject *obj, JSProtoKey key, JSAtom *atom, if (!obj->ensureClassReservedSlots(cx)) return false; - const Shape *shape = obj->nativeLookup(id); + const Shape *shape = obj->nativeLookup(cx, id); if (!shape) { uint32 slot = 2 * JSProto_LIMIT + key; if (!js_SetReservedSlot(cx, obj, slot, v)) @@ -4965,7 +4965,7 @@ PurgeProtoChain(JSContext *cx, JSObject *obj, jsid id) obj = obj->getProto(); continue; } - shape = obj->nativeLookup(id); + shape = obj->nativeLookup(cx, id); if (shape) { PCMETER(JS_PROPERTY_CACHE(cx).pcpurges++); obj->shadowingShapeChange(cx, *shape); @@ -5204,7 +5204,7 @@ DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value, } } - if (const Shape *existingShape = obj->nativeLookup(id)) { + if (const Shape *existingShape = obj->nativeLookup(cx, id)) { if (existingShape->hasSlot()) AbortRecordingIfUnexpectedGlobalWrite(cx, obj, existingShape->slot); @@ -5356,7 +5356,7 @@ CallResolveOp(JSContext *cx, JSObject *start, JSObject *obj, jsid id, uintN flag } if (!obj->nativeEmpty()) { - if (const Shape *shape = obj->nativeLookup(id)) { + if (const Shape *shape = obj->nativeLookup(cx, id)) { *objp = obj; *propp = (JSProperty *) shape; } @@ -5375,7 +5375,7 @@ LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj, jsid id, uintN flags /* Search scopes starting with obj and following the prototype link. */ JSObject *start = obj; while (true) { - const Shape *shape = obj->nativeLookup(id); + const Shape *shape = obj->nativeLookup(cx, id); if (shape) { *objp = obj; *propp = (JSProperty *) shape; @@ -5670,7 +5670,7 @@ js_NativeGetInline(JSContext *cx, JSObject *receiver, JSObject *obj, JSObject *p if (pobj->containsSlot(slot) && (JS_LIKELY(cx->runtime->propertyRemovals == sample) || - pobj->nativeContains(*shape))) { + pobj->nativeContains(cx, *shape))) { if (!pobj->methodWriteBarrier(cx, *shape, *vp)) return false; pobj->nativeSetSlot(slot, *vp); @@ -5737,7 +5737,7 @@ js_NativeSet(JSContext *cx, JSObject *obj, const Shape *shape, bool added, bool if (obj->containsSlot(slot) && (JS_LIKELY(cx->runtime->propertyRemovals == sample) || - obj->nativeContains(*shape))) { + obj->nativeContains(cx, *shape))) { if (!added) { AbortRecordingIfUnexpectedGlobalWrite(cx, obj, slot); if (!obj->methodWriteBarrier(cx, *shape, *vp)) @@ -6348,9 +6348,9 @@ js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool str namespace js { bool -HasDataProperty(JSObject *obj, jsid methodid, Value *vp) +HasDataProperty(JSContext *cx, JSObject *obj, jsid methodid, Value *vp) { - if (const Shape *shape = obj->nativeLookup(methodid)) { + if (const Shape *shape = obj->nativeLookup(cx, methodid)) { if (shape->hasDefaultGetterOrIsMethod() && obj->containsSlot(shape->slot)) { *vp = obj->nativeGetSlot(shape->slot); return true; diff --git a/js/src/jsobj.h b/js/src/jsobj.h index ed164dc8d1d..bf63af2d3f0 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -425,11 +425,11 @@ struct JSObject : js::gc::Cell { public: inline const js::Shape *lastProperty() const; - inline js::Shape **nativeSearch(jsid id, bool adding = false); - inline const js::Shape *nativeLookup(jsid id); + inline js::Shape **nativeSearch(JSContext *cx, jsid id, bool adding = false); + inline const js::Shape *nativeLookup(JSContext *cx, jsid id); - inline bool nativeContains(jsid id); - inline bool nativeContains(const js::Shape &shape); + inline bool nativeContains(JSContext *cx, jsid id); + inline bool nativeContains(JSContext *cx, const js::Shape &shape); enum { DELEGATE = 0x01, @@ -1984,7 +1984,7 @@ namespace js { * store the property value in *vp. */ extern bool -HasDataProperty(JSObject *obj, jsid methodid, js::Value *vp); +HasDataProperty(JSContext *cx, JSObject *obj, jsid methodid, js::Value *vp); extern JSBool CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index 95dea5f366b..656339d44a3 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -143,7 +143,7 @@ JSObject::getProperty(JSContext *cx, JSObject *receiver, jsid id, js::Value *vp) } else { if (!js_GetProperty(cx, this, receiver, id, vp)) return false; - JS_ASSERT_IF(!hasSingletonType() && nativeContains(js_CheckForStringIndex(id)), + JS_ASSERT_IF(!hasSingletonType() && nativeContains(cx, js_CheckForStringIndex(id)), js::types::TypeHasProperty(cx, type(), id, *vp)); } return true; @@ -253,7 +253,7 @@ JSObject::methodReadBarrier(JSContext *cx, const js::Shape &shape, js::Value *vp { JS_ASSERT(canHaveMethodBarrier()); JS_ASSERT(hasMethodBarrier()); - JS_ASSERT(nativeContains(shape)); + JS_ASSERT(nativeContains(cx, shape)); JS_ASSERT(shape.isMethod()); JS_ASSERT(shape.methodObject() == vp->toObject()); JS_ASSERT(shape.writable()); @@ -1007,28 +1007,28 @@ JSObject::setOwnShape(uint32 s) } inline js::Shape ** -JSObject::nativeSearch(jsid id, bool adding) +JSObject::nativeSearch(JSContext *cx, jsid id, bool adding) { - return js::Shape::search(compartment()->rt, &lastProp, id, adding); + return js::Shape::search(cx, &lastProp, id, adding); } inline const js::Shape * -JSObject::nativeLookup(jsid id) +JSObject::nativeLookup(JSContext *cx, jsid id) { JS_ASSERT(isNative()); - return SHAPE_FETCH(nativeSearch(id)); + return SHAPE_FETCH(nativeSearch(cx, id)); } inline bool -JSObject::nativeContains(jsid id) +JSObject::nativeContains(JSContext *cx, jsid id) { - return nativeLookup(id) != NULL; + return nativeLookup(cx, id) != NULL; } inline bool -JSObject::nativeContains(const js::Shape &shape) +JSObject::nativeContains(JSContext *cx, const js::Shape &shape) { - return nativeLookup(shape.propid) == &shape; + return nativeLookup(cx, shape.propid) == &shape; } inline const js::Shape * @@ -1567,7 +1567,12 @@ CopyInitializerObject(JSContext *cx, JSObject *baseobj, types::TypeObject *type) JS_ASSERT(baseobj->getClass() == &ObjectClass); JS_ASSERT(!baseobj->inDictionaryMode()); - JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass, baseobj->getAllocKind()); + gc::AllocKind kind = gc::GetGCObjectFixedSlotsKind(baseobj->numFixedSlots()); +#ifdef JS_THREADSAFE + kind = gc::GetBackgroundAllocKind(kind); +#endif + JS_ASSERT(kind == baseobj->getAllocKind()); + JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass, kind); if (!obj || !obj->ensureSlots(cx, baseobj->numSlots())) return NULL; @@ -1589,7 +1594,7 @@ DefineConstructorAndPrototype(JSContext *cx, GlobalObject *global, JS_ASSERT(proto); jsid id = ATOM_TO_JSID(cx->runtime->atomState.classAtoms[key]); - JS_ASSERT(!global->nativeLookup(id)); + JS_ASSERT(!global->nativeLookup(cx, id)); /* Set these first in case AddTypePropertyId looks for this class. */ global->setSlot(key, ObjectValue(*ctor)); diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index 99d3855a000..67c93a21416 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -1675,7 +1675,7 @@ DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc) ptrdiff_t head; JSContext *cx; JSPrinter *jp; - JSOp op, saveop; + JSOp op; const JSCodeSpec *cs; uintN oplen; jsint i, lasti; @@ -1710,7 +1710,6 @@ DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc) #endif LOAD_OP_DATA(pc); - saveop = op; switch (op) { case JSOP_POP: diff --git a/js/src/jspropertycache.cpp b/js/src/jspropertycache.cpp index 88e8360f89a..1c2ce0cd712 100644 --- a/js/src/jspropertycache.cpp +++ b/js/src/jspropertycache.cpp @@ -70,7 +70,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, JSObject *po * Check for fill from js_SetPropertyHelper where the setter removed shape * from pobj (via unwatch or delete, e.g.). */ - if (!pobj->nativeContains(*shape)) { + if (!pobj->nativeContains(cx, *shape)) { PCMETER(oddfills++); return JS_NO_PROP_CACHE_FILL; } @@ -399,7 +399,7 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject jsid id = ATOM_TO_JSID(atom); id = js_CheckForStringIndex(id); - JS_ASSERT(pobj->nativeContains(id)); + JS_ASSERT(pobj->nativeContains(cx, id)); #endif *pobjp = pobj; return NULL; diff --git a/js/src/jsregexpinlines.h b/js/src/jsregexpinlines.h index fa16a9776c8..1cd52187795 100644 --- a/js/src/jsregexpinlines.h +++ b/js/src/jsregexpinlines.h @@ -783,17 +783,17 @@ JSObject::initRegExp(JSContext *cx, js::RegExp *re) JS_ASSERT(!nativeEmpty()); } - JS_ASSERT(nativeLookup(ATOM_TO_JSID(cx->runtime->atomState.lastIndexAtom))->slot == + JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(cx->runtime->atomState.lastIndexAtom))->slot == JSObject::JSSLOT_REGEXP_LAST_INDEX); - JS_ASSERT(nativeLookup(ATOM_TO_JSID(cx->runtime->atomState.sourceAtom))->slot == + JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(cx->runtime->atomState.sourceAtom))->slot == JSObject::JSSLOT_REGEXP_SOURCE); - JS_ASSERT(nativeLookup(ATOM_TO_JSID(cx->runtime->atomState.globalAtom))->slot == + JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(cx->runtime->atomState.globalAtom))->slot == JSObject::JSSLOT_REGEXP_GLOBAL); - JS_ASSERT(nativeLookup(ATOM_TO_JSID(cx->runtime->atomState.ignoreCaseAtom))->slot == + JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(cx->runtime->atomState.ignoreCaseAtom))->slot == JSObject::JSSLOT_REGEXP_IGNORE_CASE); - JS_ASSERT(nativeLookup(ATOM_TO_JSID(cx->runtime->atomState.multilineAtom))->slot == + JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(cx->runtime->atomState.multilineAtom))->slot == JSObject::JSSLOT_REGEXP_MULTILINE); - JS_ASSERT(nativeLookup(ATOM_TO_JSID(cx->runtime->atomState.stickyAtom))->slot == + JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(cx->runtime->atomState.stickyAtom))->slot == JSObject::JSSLOT_REGEXP_STICKY); setPrivate(re); diff --git a/js/src/jsscope.cpp b/js/src/jsscope.cpp index 79773d716e9..2a8ee600fa4 100644 --- a/js/src/jsscope.cpp +++ b/js/src/jsscope.cpp @@ -170,9 +170,10 @@ PropertyTable::init(JSRuntime *rt, Shape *lastProp) } bool -Shape::hashify(JSRuntime *rt) +Shape::hashify(JSContext *cx) { JS_ASSERT(!hasTable()); + JSRuntime *rt = cx->runtime; PropertyTable *table = rt->new_(entryCount()); if (!table) return false; @@ -366,7 +367,7 @@ Shape::getChild(JSContext *cx, const js::Shape &child, Shape **listp) newShape->setTable(table); } else { if (!newShape->hasTable()) - newShape->hashify(cx->runtime); + newShape->hashify(cx); } return newShape; } @@ -493,7 +494,7 @@ Shape::newDictionaryList(JSContext *cx, Shape **listp) root->listp = listp; JS_ASSERT(root->inDictionary()); - root->hashify(cx->runtime); + root->hashify(cx); return root; } @@ -635,7 +636,7 @@ JSObject::addProperty(JSContext *cx, jsid id, NormalizeGetterAndSetter(cx, this, id, attrs, flags, getter, setter); /* Search for id with adding = true in order to claim its entry. */ - Shape **spp = nativeSearch(id, true); + Shape **spp = nativeSearch(cx, id, true); JS_ASSERT(!SHAPE_FETCH(spp)); return addPropertyInternal(cx, id, getter, setter, slot, attrs, flags, shortid, spp); } @@ -654,7 +655,7 @@ JSObject::addPropertyInternal(JSContext *cx, jsid id, if (lastProp->entryCount() >= PropertyTree::MAX_HEIGHT) { if (!toDictionaryMode(cx)) return NULL; - spp = nativeSearch(id, true); + spp = nativeSearch(cx, id, true); table = lastProp->getTable(); } } else if (lastProp->hasTable()) { @@ -742,7 +743,7 @@ JSObject::putProperty(JSContext *cx, jsid id, NormalizeGetterAndSetter(cx, this, id, attrs, flags, getter, setter); /* Search for id in order to claim its entry if table has been allocated. */ - Shape **spp = nativeSearch(id, true); + Shape **spp = nativeSearch(cx, id, true); Shape *shape = SHAPE_FETCH(spp); if (!shape) { /* @@ -788,7 +789,7 @@ JSObject::putProperty(JSContext *cx, jsid id, if (shape != lastProp && !inDictionaryMode()) { if (!toDictionaryMode(cx)) return NULL; - spp = nativeSearch(shape->propid); + spp = nativeSearch(cx, shape->propid); shape = SHAPE_FETCH(spp); } @@ -893,7 +894,7 @@ JSObject::changeProperty(JSContext *cx, const Shape *shape, uintN attrs, uintN m { JS_ASSERT_IF(inDictionaryMode(), !lastProp->frozen()); JS_ASSERT(!JSID_IS_VOID(shape->propid)); - JS_ASSERT(nativeContains(*shape)); + JS_ASSERT(nativeContains(cx, *shape)); attrs |= shape->attrs & mask; @@ -964,7 +965,7 @@ JSObject::changeProperty(JSContext *cx, const Shape *shape, uintN attrs, uintN m if (newShape) { JS_ASSERT(newShape == lastProp); if (newShape->hasTable()) { - Shape **spp = nativeSearch(shape->propid); + Shape **spp = nativeSearch(cx, shape->propid); JS_ASSERT(SHAPE_FETCH(spp) == newShape); } } @@ -989,7 +990,7 @@ JSObject::changeProperty(JSContext *cx, const Shape *shape, uintN attrs, uintN m bool JSObject::removeProperty(JSContext *cx, jsid id) { - Shape **spp = nativeSearch(id); + Shape **spp = nativeSearch(cx, id); Shape *shape = SHAPE_FETCH(spp); if (!shape) return true; @@ -1006,7 +1007,7 @@ JSObject::removeProperty(JSContext *cx, jsid id) if (shape != lastProp && !inDictionaryMode()) { if (!toDictionaryMode(cx)) return false; - spp = nativeSearch(shape->propid); + spp = nativeSearch(cx, shape->propid); shape = SHAPE_FETCH(spp); } @@ -1036,7 +1037,7 @@ JSObject::removeProperty(JSContext *cx, jsid id) */ const Shape *aprop = lastProp; for (int n = 50; --n >= 0 && aprop->parent; aprop = aprop->parent) - JS_ASSERT_IF(aprop != shape, nativeContains(*aprop)); + JS_ASSERT_IF(aprop != shape, nativeContains(cx, *aprop)); #endif } } diff --git a/js/src/jsscope.h b/js/src/jsscope.h index 5d905080b7f..deb62e3126f 100644 --- a/js/src/jsscope.h +++ b/js/src/jsscope.h @@ -367,7 +367,7 @@ struct Shape : public js::gc::Cell else to obj->lastProp */ }; - static inline js::Shape **search(JSRuntime *rt, js::Shape **startp, jsid id, + static inline js::Shape **search(JSContext *cx, js::Shape **startp, jsid id, bool adding = false); static js::Shape *newDictionaryShape(JSContext *cx, const js::Shape &child, js::Shape **listp); static js::Shape *newDictionaryList(JSContext *cx, js::Shape **listp); @@ -377,7 +377,7 @@ struct Shape : public js::gc::Cell js::Shape *getChild(JSContext *cx, const js::Shape &child, js::Shape **listp); - bool hashify(JSRuntime *rt); + bool hashify(JSContext *cx); void setTable(js::PropertyTable *t) const { JS_ASSERT_IF(t && t->freelist != SHAPE_INVALID_SLOT, t->freelist < slotSpan); @@ -704,14 +704,14 @@ js_GenerateShape(JSContext *cx); namespace js { JS_ALWAYS_INLINE js::Shape ** -Shape::search(JSRuntime *rt, js::Shape **startp, jsid id, bool adding) +Shape::search(JSContext *cx, js::Shape **startp, jsid id, bool adding) { js::Shape *start = *startp; if (start->hasTable()) return start->getTable()->search(id, adding); if (start->numLinearSearches == PropertyTable::MAX_LINEAR_SEARCHES) { - if (start->hashify(rt)) + if (start->hashify(cx)) return start->getTable()->search(id, adding); /* OOM! Don't increment numLinearSearches, to keep hasTable() false. */ JS_ASSERT(!start->hasTable()); diff --git a/js/src/jsscopeinlines.h b/js/src/jsscopeinlines.h index d0ba58f1af6..19e7fec404b 100644 --- a/js/src/jsscopeinlines.h +++ b/js/src/jsscopeinlines.h @@ -164,7 +164,7 @@ StringObject::init(JSContext *cx, JSString *str) } JS_ASSERT(*shapep == lastProperty()); JS_ASSERT(!nativeEmpty()); - JS_ASSERT(nativeLookup(ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))->slot == LENGTH_SLOT); + JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))->slot == LENGTH_SLOT); setStringThis(str); return true; diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 6741c4bc220..146c5c5d113 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -88,7 +88,7 @@ Bindings::lookup(JSContext *cx, JSAtom *name, uintN *indexp) const return NONE; Shape *shape = - SHAPE_FETCH(Shape::search(cx->runtime, const_cast(&lastBinding), + SHAPE_FETCH(Shape::search(cx, const_cast(&lastBinding), ATOM_TO_JSID(name))); if (!shape) return NONE; diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 9303a7e65b4..86c4a728226 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -11556,7 +11556,7 @@ TraceRecorder::callNative(uintN argc, JSOp mode) if (js_GetClassPrototype(cx, NULL, JSProto_RegExp, &proto)) { Value pval; jsid id = ATOM_TO_JSID(cx->runtime->atomState.testAtom); - if (HasDataProperty(proto, id, &pval) && + if (HasDataProperty(cx, proto, id, &pval) && IsNativeFunction(pval, js_regexp_test)) { vp[0] = pval; @@ -12065,7 +12065,7 @@ SafeLookup(JSContext *cx, JSObject* obj, jsid id, JSObject** pobjp, const Shape* if (obj->getOps()->lookupProperty) return false; - if (const Shape *shape = obj->nativeLookup(id)) { + if (const Shape *shape = obj->nativeLookup(cx, id)) { *pobjp = obj; *shapep = shape; return true; @@ -12136,7 +12136,7 @@ TraceRecorder::nativeSet(JSObject* obj, LIns* obj_ins, const Shape* shape, { uint32 slot = shape->slot; JS_ASSERT((slot != SHAPE_INVALID_SLOT) == shape->hasSlot()); - JS_ASSERT_IF(shape->hasSlot(), obj->nativeContains(*shape)); + JS_ASSERT_IF(shape->hasSlot(), obj->nativeContains(cx, *shape)); /* * We do not trace assignment to properties that have both a non-default @@ -12181,7 +12181,7 @@ TraceRecorder::nativeSet(JSObject* obj, LIns* obj_ins, const Shape* shape, // Because the trace is type-specialized to the global object's // slots, no run-time check is needed. Avoid recording a global // shape change, though. - JS_ASSERT(obj->nativeContains(*shape)); + JS_ASSERT(obj->nativeContains(cx, *shape)); if (IsFunctionObject(obj->getSlot(slot))) RETURN_STOP("can't trace set of function-valued global property"); } else { @@ -12521,7 +12521,7 @@ TraceRecorder::recordInitPropertyOp(jsbytecode op) // shape or because the id appears more than once in the initializer), just // set it. The existing property can't be an accessor property: we wouldn't // get here, as JSOP_SETTER can't be recorded. - if (const Shape* shape = obj->nativeLookup(id)) { + if (const Shape* shape = obj->nativeLookup(cx, id)) { // Don't assign a bare (non-cloned) function to an ordinary or method // property. The opposite case, assigning some other value to a method, // is OK. nativeSet emits code that trips the write barrier. @@ -14179,7 +14179,7 @@ TraceRecorder::propTail(JSObject* obj, LIns* obj_ins, JSObject* obj2, PCVal pcva if (pcval.isShape()) { shape = pcval.toShape(); - JS_ASSERT(obj2->nativeContains(*shape)); + JS_ASSERT(obj2->nativeContains(cx, *shape)); if (setflags && !shape->hasDefaultSetter()) RETURN_STOP("non-stub setter"); diff --git a/js/src/jswatchpoint.cpp b/js/src/jswatchpoint.cpp index 0ff985c06e7..9d867fdfca5 100644 --- a/js/src/jswatchpoint.cpp +++ b/js/src/jswatchpoint.cpp @@ -144,7 +144,7 @@ WatchpointMap::triggerWatchpoint(JSContext *cx, JSObject *obj, jsid id, Value *v Value old; old.setUndefined(); if (obj->isNative()) { - if (const Shape *shape = obj->nativeLookup(id)) { + if (const Shape *shape = obj->nativeLookup(cx, id)) { uint32 slot = shape->slot; if (obj->containsSlot(slot)) { if (shape->isMethod()) { @@ -157,7 +157,7 @@ WatchpointMap::triggerWatchpoint(JSContext *cx, JSObject *obj, jsid id, Value *v Value method = ObjectValue(shape->methodObject()); if (!obj->methodReadBarrier(cx, *shape, &method)) return false; - shape = obj->nativeLookup(id); + shape = obj->nativeLookup(cx, id); JS_ASSERT(shape->isDataDescriptor()); JS_ASSERT(!shape->isMethod()); old = method; diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index f331e3b30cd..11caaf1a18d 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -259,7 +259,7 @@ mjit::Compiler::scanInlineCalls(uint32 index, uint32 depth) continue; /* Not inlining at monitored call sites or those with type barriers. */ - if (code->monitoredTypes || code->monitoredTypesReturn || analysis->typeBarriers(pc) != NULL) + if (code->monitoredTypes || code->monitoredTypesReturn || analysis->typeBarriers(cx, pc) != NULL) continue; uint32 argc = GET_ARGC(pc); @@ -5927,7 +5927,7 @@ mjit::Compiler::jsop_getgname(uint32 index) * then bake its address into the jitcode and guard against future * reallocation of the global object's slots. */ - const js::Shape *shape = globalObj->nativeLookup(ATOM_TO_JSID(atom)); + const js::Shape *shape = globalObj->nativeLookup(cx, ATOM_TO_JSID(atom)); if (shape && shape->hasDefaultGetterOrIsMethod() && shape->hasSlot()) { Value *value = &globalObj->getSlotRef(shape->slot); if (!value->isUndefined() && @@ -6150,7 +6150,7 @@ mjit::Compiler::jsop_setgname(JSAtom *atom, bool usePropertyCache, bool popGuara types::TypeSet *types = globalObj->getType(cx)->getProperty(cx, id, false); if (!types) return; - const js::Shape *shape = globalObj->nativeLookup(ATOM_TO_JSID(atom)); + const js::Shape *shape = globalObj->nativeLookup(cx, ATOM_TO_JSID(atom)); if (shape && !shape->isMethod() && shape->hasDefaultSetter() && shape->writable() && shape->hasSlot() && !types->isOwnProperty(cx, globalObj->getType(cx), true)) { @@ -7241,7 +7241,7 @@ mjit::Compiler::hasTypeBarriers(jsbytecode *pc) return js_CodeSpec[*pc].format & JOF_TYPESET; #endif - return analysis->typeBarriers(pc) != NULL; + return analysis->typeBarriers(cx, pc) != NULL; } void diff --git a/js/src/methodjit/FastArithmetic.cpp b/js/src/methodjit/FastArithmetic.cpp index 0e0e968561a..99cebda24d0 100644 --- a/js/src/methodjit/FastArithmetic.cpp +++ b/js/src/methodjit/FastArithmetic.cpp @@ -662,8 +662,6 @@ mjit::Compiler::jsop_binary_full(FrameEntry *lhs, FrameEntry *rhs, JSOp op, case JSOP_MUL: { - JS_ASSERT(reg.isSet()); - MaybeJump storeNegZero; bool maybeNegZero = !ignoreOverflow; bool hasConstant = (lhs->isConstant() || rhs->isConstant()); @@ -680,10 +678,19 @@ mjit::Compiler::jsop_binary_full(FrameEntry *lhs, FrameEntry *rhs, JSOp op, storeNegZero = masm.branch32(Assembler::LessThan, nonConstReg, Imm32(0)); } - if (cannotOverflow) - masm.mul32(reg.reg(), regs.result); - else - overflow = masm.branchMul32(Assembler::Overflow, reg.reg(), regs.result); + if (cannotOverflow) { + if (reg.isSet()) + masm.mul32(reg.reg(), regs.result); + else + masm.mul32(Imm32(value), regs.result, regs.result); + } else { + if (reg.isSet()) { + overflow = masm.branchMul32(Assembler::Overflow, reg.reg(), regs.result); + } else { + overflow = masm.branchMul32(Assembler::Overflow, Imm32(value), regs.result, + regs.result); + } + } if (maybeNegZero) { if (hasConstant) { diff --git a/js/src/methodjit/FrameState.cpp b/js/src/methodjit/FrameState.cpp index 347ba7d083d..65ceb02b14f 100644 --- a/js/src/methodjit/FrameState.cpp +++ b/js/src/methodjit/FrameState.cpp @@ -2653,9 +2653,8 @@ FrameState::allocForBinary(FrameEntry *lhs, FrameEntry *rhs, JSOp op, BinaryAllo } /* - * Data is a little more complicated. If the op is MUL, not all CPUs - * have multiplication on immediates, so a register is needed. Also, - * if the op is not commutative, the LHS _must_ be in a register. + * Allocate data registers. If the op is not commutative, the LHS + * _must_ be in a register. */ JS_ASSERT_IF(lhs->isConstant(), !rhs->isConstant()); JS_ASSERT_IF(rhs->isConstant(), !lhs->isConstant()); @@ -2664,23 +2663,16 @@ FrameState::allocForBinary(FrameEntry *lhs, FrameEntry *rhs, JSOp op, BinaryAllo if (backingLeft->data.inMemory()) { alloc.lhsData = tempRegForData(lhs); pinReg(alloc.lhsData.reg()); - } else if (op == JSOP_MUL || !commu) { + } else if (!commu) { JS_ASSERT(lhs->isConstant()); alloc.lhsData = allocReg(); alloc.extraFree = alloc.lhsData; masm.move(Imm32(lhs->getValue().toInt32()), alloc.lhsData.reg()); } } - if (!alloc.rhsData.isSet()) { - if (backingRight->data.inMemory()) { - alloc.rhsData = tempRegForData(rhs); - pinReg(alloc.rhsData.reg()); - } else if (op == JSOP_MUL) { - JS_ASSERT(rhs->isConstant()); - alloc.rhsData = allocReg(); - alloc.extraFree = alloc.rhsData; - masm.move(Imm32(rhs->getValue().toInt32()), alloc.rhsData.reg()); - } + if (!alloc.rhsData.isSet() && backingRight->data.inMemory()) { + alloc.rhsData = tempRegForData(rhs); + pinReg(alloc.rhsData.reg()); } alloc.lhsNeedsRemat = false; diff --git a/js/src/methodjit/MonoIC.cpp b/js/src/methodjit/MonoIC.cpp index b28c717ab57..bd46a982744 100644 --- a/js/src/methodjit/MonoIC.cpp +++ b/js/src/methodjit/MonoIC.cpp @@ -87,7 +87,7 @@ ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic) JSAtom *atom = f.script()->getAtom(GET_INDEX(f.pc())); jsid id = ATOM_TO_JSID(atom); - const Shape *shape = obj->nativeLookup(id); + const Shape *shape = obj->nativeLookup(f.cx, id); if (!shape || !shape->hasDefaultGetterOrIsMethod() || !shape->hasSlot()) @@ -322,7 +322,7 @@ ic::SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic) JSObject *obj = f.fp()->scopeChain().getGlobal(); JSScript *script = f.script(); JSAtom *atom = script->getAtom(GET_INDEX(f.pc())); - const Shape *shape = obj->nativeLookup(ATOM_TO_JSID(atom)); + const Shape *shape = obj->nativeLookup(f.cx, ATOM_TO_JSID(atom)); LookupStatus status = UpdateSetGlobalName(f, ic, obj, shape); if (status == Lookup_Error) diff --git a/js/src/methodjit/StubCalls.cpp b/js/src/methodjit/StubCalls.cpp index 78989586e90..bd7dfeeb6a3 100644 --- a/js/src/methodjit/StubCalls.cpp +++ b/js/src/methodjit/StubCalls.cpp @@ -182,9 +182,9 @@ stubs::SetName(VMFrame &f, JSAtom *origAtom) { #ifdef DEBUG if (entry->directHit()) { - JS_ASSERT(obj->nativeContains(*shape)); + JS_ASSERT(obj->nativeContains(cx, *shape)); } else { - JS_ASSERT(obj2->nativeContains(*shape)); + JS_ASSERT(obj2->nativeContains(cx, *shape)); JS_ASSERT(entry->vcapTag() == 1); JS_ASSERT(entry->kshape != entry->vshape()); JS_ASSERT(!shape->hasSlot()); diff --git a/js/src/xpconnect/src/xpc.msg b/js/src/xpconnect/src/xpc.msg index b41a9d0bbca..410c3d6914f 100644 --- a/js/src/xpconnect/src/xpc.msg +++ b/js/src/xpconnect/src/xpc.msg @@ -175,6 +175,7 @@ XPC_MSG_DEF(NS_ERROR_IN_PROGRESS , "The requested action coul XPC_MSG_DEF(NS_ERROR_ALREADY_OPENED , "Channel is already open") XPC_MSG_DEF(NS_ERROR_INVALID_CONTENT_ENCODING , "The content encoding of the source document is incorrect") XPC_MSG_DEF(NS_ERROR_CORRUPTED_CONTENT , "Corrupted content was received from server") +XPC_MSG_DEF(NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY, "Couldn't extract first component from potentially corrupted header field") XPC_MSG_DEF(NS_ERROR_ALREADY_CONNECTED , "The connection is already established") XPC_MSG_DEF(NS_ERROR_NOT_CONNECTED , "The connection does not exist") XPC_MSG_DEF(NS_ERROR_CONNECTION_REFUSED , "The connection was refused") diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 90ae7202e94..fc2d939f059 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -1909,7 +1909,12 @@ nsCSSFrameConstructor::ConstructTable(nsFrameConstructorState& aState, innerFrame = NS_NewMathMLmtableFrame(mPresShell, styleContext); else innerFrame = NS_NewTableFrame(mPresShell, styleContext); - + + if (!innerFrame) { + newFrame->Destroy(); + return NS_ERROR_OUT_OF_MEMORY; + } + InitAndRestoreFrame(aState, content, newFrame, nsnull, innerFrame); // Put the newly created frames into the right child list @@ -2479,9 +2484,9 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle // Figure out which frame has the main style for the document element, // assigning it to mRootElementStyleFrame. // Backgrounds should be propagated from that frame to the viewport. - PRBool isChild; - contentFrame->GetParentStyleContextFrame(state.mPresContext, - &mRootElementStyleFrame, &isChild); + mRootElementStyleFrame = contentFrame->GetParentStyleContextFrame(); + bool isChild = mRootElementStyleFrame && + mRootElementStyleFrame->GetParent() == contentFrame; if (!isChild) { mRootElementStyleFrame = mRootElementFrame; } @@ -5788,13 +5793,8 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aSibling, // if we haven't already, construct a style context to find the display type of aContent if (UNSET_DISPLAY == aDisplay) { nsRefPtr styleContext; - nsIFrame* styleParent; - PRBool providerIsChild; - if (NS_FAILED(aSibling-> - GetParentStyleContextFrame(aSibling->PresContext(), - &styleParent, - &providerIsChild)) || - !styleParent) { + nsIFrame* styleParent = aSibling->GetParentStyleContextFrame(); + if (!styleParent) { NS_NOTREACHED("Shouldn't happen"); return PR_FALSE; } @@ -6680,10 +6680,8 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer, if (captionItems.NotEmpty()) { // append the caption to the outer table NS_ASSERTION(nsGkAtoms::tableFrame == frameType, "how did that happen?"); nsIFrame* outerTable = parentFrame->GetParent(); - if (outerTable) { - state.mFrameManager->AppendFrames(outerTable, nsIFrame::kCaptionList, - captionItems); - } + state.mFrameManager->AppendFrames(outerTable, nsIFrame::kCaptionList, + captionItems); } if (frameItems.NotEmpty()) { // append the in-flow kids diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp index f749c186d11..c99b27b1450 100644 --- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -268,7 +268,7 @@ nsFrameManager::Destroy() // Placeholder frame functions nsPlaceholderFrame* -nsFrameManager::GetPlaceholderFrameFor(nsIFrame* aFrame) +nsFrameManager::GetPlaceholderFrameFor(nsIFrame* aFrame) { NS_PRECONDITION(aFrame, "null param unexpected"); @@ -587,10 +587,7 @@ VerifyContextParent(nsPresContext* aPresContext, nsIFrame* aFrame, // as the parent context instead of asking the frame // get the parent context from the frame (indirectly) - nsIFrame* providerFrame = nsnull; - PRBool providerIsChild; - aFrame->GetParentStyleContextFrame(aPresContext, - &providerFrame, &providerIsChild); + nsIFrame* providerFrame = aFrame->GetParentStyleContextFrame(); if (providerFrame) aParentContext = providerFrame->GetStyleContext(); // aParentContext could still be null @@ -808,13 +805,11 @@ nsFrameManager::ReparentStyleContext(nsIFrame* aFrame) // XXXbz can oldContext really ever be null? if (oldContext) { nsRefPtr newContext; - nsIFrame* providerFrame = nsnull; - PRBool providerIsChild = PR_FALSE; - nsIFrame* providerChild = nsnull; - aFrame->GetParentStyleContextFrame(GetPresContext(), &providerFrame, - &providerIsChild); + nsIFrame* providerFrame = aFrame->GetParentStyleContextFrame(); + bool isChild = providerFrame && providerFrame->GetParent() == aFrame; nsStyleContext* newParentContext = nsnull; - if (providerIsChild) { + nsIFrame* providerChild = nsnull; + if (isChild) { ReparentStyleContext(providerFrame); newParentContext = providerFrame->GetStyleContext(); providerChild = providerFrame; @@ -1107,11 +1102,9 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, nsIFrame* resolvedChild = nsnull; // Get the frame providing the parent style context. If it is a // child, then resolve the provider first. - nsIFrame* providerFrame = nsnull; - PRBool providerIsChild = PR_FALSE; - aFrame->GetParentStyleContextFrame(aPresContext, - &providerFrame, &providerIsChild); - if (!providerIsChild) { + nsIFrame* providerFrame = aFrame->GetParentStyleContextFrame(); + bool isChild = providerFrame && providerFrame->GetParent() == aFrame; + if (!isChild) { if (providerFrame) parentContext = providerFrame->GetStyleContext(); else diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 7a4744a30be..cdf7758dd1c 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -6520,15 +6520,6 @@ nsFrame::ConsiderChildOverflow(nsOverflowAreas& aOverflowAreas, } } -NS_IMETHODIMP -nsFrame::GetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild) -{ - return DoGetParentStyleContextFrame(aPresContext, aProviderFrame, aIsChild); -} - - /** * This function takes a "special" frame and _if_ that frame is an anonymous * block created by an ib split it returns the block's preceding inline. This @@ -6575,26 +6566,22 @@ GetIBSpecialSiblingForAnonymousBlock(nsIFrame* aFrame) * Also skip anonymous scrolled-content parents; inherit directly from the * outer scroll frame. */ -static nsresult -GetCorrectedParent(nsPresContext* aPresContext, nsIFrame* aFrame, - nsIFrame** aSpecialParent) +static nsIFrame* +GetCorrectedParent(const nsIFrame* aFrame) { nsIFrame *parent = aFrame->GetParent(); if (!parent) { - *aSpecialParent = nsnull; - } else { - nsIAtom* pseudo = aFrame->GetStyleContext()->GetPseudo(); - // Outer tables are always anon boxes; if we're in here for an outer - // table, that actually means its the _inner_ table that wants to - // know its parent. So get the pseudo of the inner in that case. - if (pseudo == nsCSSAnonBoxes::tableOuter) { - pseudo = aFrame->GetFirstPrincipalChild() - ->GetStyleContext()->GetPseudo(); - } - *aSpecialParent = nsFrame::CorrectStyleParentFrame(parent, pseudo); + return nsnull; } - return NS_OK; + // Outer tables are always anon boxes; if we're in here for an outer + // table, that actually means its the _inner_ table that wants to + // know its parent. So get the pseudo of the inner in that case. + nsIAtom* pseudo = aFrame->GetStyleContext()->GetPseudo(); + if (pseudo == nsCSSAnonBoxes::tableOuter) { + pseudo = aFrame->GetFirstPrincipalChild()->GetStyleContext()->GetPseudo(); + } + return nsFrame::CorrectStyleParentFrame(parent, pseudo); } /* static */ @@ -6659,17 +6646,13 @@ nsFrame::CorrectStyleParentFrame(nsIFrame* aProspectiveParent, return nsnull; } -nsresult -nsFrame::DoGetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild) +nsIFrame* +nsFrame::DoGetParentStyleContextFrame() { - *aIsChild = PR_FALSE; - *aProviderFrame = nsnull; if (mContent && !mContent->GetParent() && !GetStyleContext()->GetPseudo()) { // we're a frame for the root. We have no style context parent. - return NS_OK; + return nsnull; } if (!(mState & NS_FRAME_OUT_OF_FLOW)) { @@ -6679,17 +6662,16 @@ nsFrame::DoGetParentStyleContextFrame(nsPresContext* aPresContext, * inline. We can get to it using GetIBSpecialSiblingForAnonymousBlock. */ if (mState & NS_FRAME_IS_SPECIAL) { - *aProviderFrame = GetIBSpecialSiblingForAnonymousBlock(this); - - if (*aProviderFrame) { - return NS_OK; + nsIFrame* specialSibling = GetIBSpecialSiblingForAnonymousBlock(this); + if (specialSibling) { + return specialSibling; } } // If this frame is one of the blocks that split an inline, we must // return the "special" inline parent, i.e., the parent that this // frame would have if we didn't mangle the frame structure. - return GetCorrectedParent(aPresContext, this, aProviderFrame); + return GetCorrectedParent(this); } // For out-of-flow frames, we must resolve underneath the @@ -6701,22 +6683,15 @@ nsFrame::DoGetParentStyleContextFrame(nsPresContext* aPresContext, // have placeholders. Use their first-in-flow's placeholder. oofFrame = oofFrame->GetFirstInFlow(); } - nsIFrame *placeholder = - aPresContext->FrameManager()->GetPlaceholderFrameFor(oofFrame); + nsIFrame* placeholder = oofFrame->PresContext()->FrameManager()-> + GetPlaceholderFrameFor(oofFrame); if (!placeholder) { NS_NOTREACHED("no placeholder frame for out-of-flow frame"); - GetCorrectedParent(aPresContext, this, aProviderFrame); - return NS_ERROR_FAILURE; + return GetCorrectedParent(this); } - return static_cast(placeholder)-> - GetParentStyleContextFrame(aPresContext, aProviderFrame, aIsChild); + return placeholder->GetParentStyleContextFrame(); } -//----------------------------------------------------------------------------------- - - - - void nsFrame::GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame) { diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index 27d516022f1..5e15177187d 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -268,9 +268,18 @@ public: virtual already_AddRefed CreateAccessible(); #endif - NS_IMETHOD GetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild); + virtual nsIFrame* GetParentStyleContextFrame() { + return DoGetParentStyleContextFrame(); + } + + /** + * Do the work for getting the parent style context frame so that + * other frame's |GetParentStyleContextFrame| methods can call this + * method on *another* frame. (This function handles out-of-flow + * frames by using the frame manager's placeholder map and it also + * handles block-within-inline and generated content wrappers.) + */ + nsIFrame* DoGetParentStyleContextFrame(); virtual PRBool IsEmpty(); virtual PRBool IsSelfEmpty(); @@ -399,15 +408,6 @@ public: nsHTMLReflowMetrics& aMetrics, nsReflowStatus& aStatus); - // Do the work for getting the parent style context frame so that - // other frame's |GetParentStyleContextFrame| methods can call this - // method on *another* frame. (This function handles out-of-flow - // frames by using the frame manager's placeholder map and it also - // handles block-within-inline and generated content wrappers.) - nsresult DoGetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild); - // Incorporate the child overflow areas into aOverflowAreas. // If the child does not have a overflow, use the child area. void ConsiderChildOverflow(nsOverflowAreas& aOverflowAreas, diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index bbb7b98c222..557d2bbda90 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -2396,19 +2396,11 @@ public: * this frame returns a child frame, then the child frame must be sure * to return a grandparent or higher! * - * @param aPresContext: PresContext - * @param aProviderFrame: The frame whose style context should be the - * parent of this frame's style context. Null - * is permitted, and means that this frame's - * style context should be the root of the - * style context tree. - * @param aIsChild: True if |aProviderFrame| is set to a child - * of this frame; false if it is an ancestor or - * null. + * @return The frame whose style context should be the parent of this frame's + * style context. Null is permitted, and means that this frame's + * style context should be the root of the style context tree. */ - NS_IMETHOD GetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild) = 0; + virtual nsIFrame* GetParentStyleContextFrame() = 0; /** * Determines whether a frame is visible for painting; diff --git a/layout/generic/nsPlaceholderFrame.cpp b/layout/generic/nsPlaceholderFrame.cpp index 9b5a1f9c691..7c3789775f8 100644 --- a/layout/generic/nsPlaceholderFrame.cpp +++ b/layout/generic/nsPlaceholderFrame.cpp @@ -191,20 +191,15 @@ nsPlaceholderFrame::CanContinueTextRun() const return mOutOfFlowFrame->CanContinueTextRun(); } -NS_IMETHODIMP -nsPlaceholderFrame::GetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild) +nsIFrame* +nsPlaceholderFrame::GetParentStyleContextFrame() { NS_PRECONDITION(GetParent(), "How can we not have a parent here?"); - *aIsChild = PR_FALSE; // Lie about our pseudo so we can step out of all anon boxes and // pseudo-elements. The other option would be to reimplement the // {ib} split gunk here. - *aProviderFrame = - CorrectStyleParentFrame(GetParent(), nsGkAtoms::placeholderFrame); - return NS_OK; + return CorrectStyleParentFrame(GetParent(), nsGkAtoms::placeholderFrame); } diff --git a/layout/generic/nsPlaceholderFrame.h b/layout/generic/nsPlaceholderFrame.h index a76fd70a1f0..f6a30f2252a 100644 --- a/layout/generic/nsPlaceholderFrame.h +++ b/layout/generic/nsPlaceholderFrame.h @@ -174,9 +174,8 @@ public: } #endif - NS_IMETHOD GetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild); + virtual nsIFrame* GetParentStyleContextFrame(); + /** * @return the out-of-flow for aFrame if aFrame is a placeholder; otherwise * aFrame diff --git a/layout/generic/test/test_bug632379.xul b/layout/generic/test/test_bug632379.xul index b1d60e832b1..b023ce862bc 100644 --- a/layout/generic/test/test_bug632379.xul +++ b/layout/generic/test/test_bug632379.xul @@ -198,8 +198,7 @@ function openSubmenu() synthesizeKey("5", {}); } -SimpleTest.waitForExplicitFinish(); -addLoadEvent(doTest); +SimpleTest.waitForFocus(doTest); ]]> diff --git a/layout/mathml/nsMathMLmtableFrame.cpp b/layout/mathml/nsMathMLmtableFrame.cpp index 8fc565fad9d..38f8933ca73 100644 --- a/layout/mathml/nsMathMLmtableFrame.cpp +++ b/layout/mathml/nsMathMLmtableFrame.cpp @@ -458,8 +458,8 @@ nsMathMLmtableOuterFrame::AttributeChanged(PRInt32 aNameSpaceID, // mtable is simple and only has one (pseudo) row-group inside our inner-table nsIFrame* tableFrame = mFrames.FirstChild(); - if (!tableFrame || tableFrame->GetType() != nsGkAtoms::tableFrame) - return NS_OK; + NS_ASSERTION(tableFrame && tableFrame->GetType() == nsGkAtoms::tableFrame, + "should always have an inner table frame"); nsIFrame* rgFrame = tableFrame->GetFirstPrincipalChild(); if (!rgFrame || rgFrame->GetType() != nsGkAtoms::tableRowGroupFrame) return NS_OK; @@ -548,8 +548,8 @@ nsMathMLmtableOuterFrame::GetRowFrameAt(nsPresContext* aPresContext, // if our inner table says that the index is valid, find the row now if (0 <= aRowIndex && aRowIndex <= rowCount) { nsIFrame* tableFrame = mFrames.FirstChild(); - if (!tableFrame || tableFrame->GetType() != nsGkAtoms::tableFrame) - return nsnull; + NS_ASSERTION(tableFrame && tableFrame->GetType() == nsGkAtoms::tableFrame, + "should always have an inner table frame"); nsIFrame* rgFrame = tableFrame->GetFirstPrincipalChild(); if (!rgFrame || rgFrame->GetType() != nsGkAtoms::tableRowGroupFrame) return nsnull; diff --git a/layout/reftests/svg/sizing/reftest.list b/layout/reftests/svg/sizing/reftest.list index 3dd13ebdce8..40016067607 100644 --- a/layout/reftests/svg/sizing/reftest.list +++ b/layout/reftests/svg/sizing/reftest.list @@ -309,6 +309,6 @@ random-if(Android) == object--auto-auto--px-px.html object--auto-auto--px == dynamic--inline-resize-cb-width.xhtml standalone-sanity-width-300px.svg skip == dynamic--inline-resize-window-height.xhtml pass.svg # XXX breaks the reftest run as the window height somehow is not restored skip == dynamic--inline-resize-window-width.xhtml pass.svg # Fails way too much -fails == dynamic--object-svg-unloaded.xhtml pass.svg +fails random-if(Android) == dynamic--object-svg-unloaded.xhtml pass.svg # == dynamic--object--auto-auto--pct-px.html diff --git a/layout/tables/nsTableColGroupFrame.cpp b/layout/tables/nsTableColGroupFrame.cpp index bb452858eda..04962c4e3a6 100644 --- a/layout/tables/nsTableColGroupFrame.cpp +++ b/layout/tables/nsTableColGroupFrame.cpp @@ -336,10 +336,7 @@ nsTableColGroupFrame::RemoveFrame(ChildListID aListID, nsTableColFrame* nextCol; while (col && col->GetColType() == eColAnonymousCol) { #ifdef DEBUG - nsIFrame* providerFrame; - PRBool isChild; - colFrame->GetParentStyleContextFrame(PresContext(), &providerFrame, - &isChild); + nsIFrame* providerFrame = colFrame->GetParentStyleContextFrame(); if (colFrame->GetStyleContext()->GetParent() == providerFrame->GetStyleContext()) { NS_ASSERTION(col->GetStyleContext() == colFrame->GetStyleContext() && diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 3a6fee2d6e2..0d020cc01ad 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -161,10 +161,8 @@ struct BCPropertyData BCPixelSize mRightCellBorderWidth; }; -NS_IMETHODIMP -nsTableFrame::GetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild) +nsIFrame* +nsTableFrame::GetParentStyleContextFrame() { // Since our parent, the table outer frame, returned this frame, we // must return whatever our parent would normally have returned. @@ -172,13 +170,10 @@ nsTableFrame::GetParentStyleContextFrame(nsPresContext* aPresContext, NS_PRECONDITION(mParent, "table constructed without outer table"); if (!mContent->GetParent() && !GetStyleContext()->GetPseudo()) { // We're the root. We have no style context parent. - *aIsChild = PR_FALSE; - *aProviderFrame = nsnull; - return NS_OK; + return nsnull; } - return static_cast(mParent)-> - DoGetParentStyleContextFrame(aPresContext, aProviderFrame, aIsChild); + return static_cast(GetParent())->DoGetParentStyleContextFrame(); } diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index 35f93035508..8e9b4202e7d 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -349,9 +349,7 @@ public: nsFrameList& GetColGroups(); - NS_IMETHOD GetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild); + virtual nsIFrame* GetParentStyleContextFrame(); /** * Get the "type" of the frame diff --git a/layout/tables/nsTableOuterFrame.cpp b/layout/tables/nsTableOuterFrame.cpp index 3df79d2d839..7ee8adcf11a 100644 --- a/layout/tables/nsTableOuterFrame.cpp +++ b/layout/tables/nsTableOuterFrame.cpp @@ -117,10 +117,8 @@ nsTableCaptionFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext, return result; } -NS_IMETHODIMP -nsTableCaptionFrame::GetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild) +nsIFrame* +nsTableCaptionFrame::GetParentStyleContextFrame() { NS_PRECONDITION(mContent->GetParent(), "How could we not have a parent here?"); @@ -131,17 +129,13 @@ nsTableCaptionFrame::GetParentStyleContextFrame(nsPresContext* aPresContext, if (outerFrame && outerFrame->GetType() == nsGkAtoms::tableOuterFrame) { nsIFrame* innerFrame = outerFrame->GetFirstPrincipalChild(); if (innerFrame) { - *aProviderFrame = - nsFrame::CorrectStyleParentFrame(innerFrame, - GetStyleContext()->GetPseudo()); - *aIsChild = PR_FALSE; - return NS_OK; + return nsFrame::CorrectStyleParentFrame(innerFrame, + GetStyleContext()->GetPseudo()); } } NS_NOTREACHED("Where is our inner table frame?"); - return nsBlockFrame::GetParentStyleContextFrame(aPresContext, aProviderFrame, - aIsChild); + return nsBlockFrame::GetParentStyleContextFrame(); } #ifdef ACCESSIBILITY @@ -245,22 +239,14 @@ nsTableOuterFrame::SetInitialChildList(ChildListID aListID, if (kCaptionList == aListID) { // the frame constructor already checked for table-caption display type mCaptionFrames.SetFrames(aChildList); - mCaptionFrame = mCaptionFrames.FirstChild(); } else { NS_ASSERTION(aListID == kPrincipalList, "wrong childlist"); NS_ASSERTION(mFrames.IsEmpty(), "Frame leak!"); - mInnerTableFrame = nsnull; - if (aChildList.NotEmpty()) { - if (nsGkAtoms::tableFrame == aChildList.FirstChild()->GetType()) { - mInnerTableFrame = (nsTableFrame*)aChildList.FirstChild(); - mFrames.SetFrames(aChildList); - } - else { - NS_ERROR("expected a table frame"); - return NS_ERROR_INVALID_ARG; - } - } + NS_ASSERTION(aChildList.FirstChild() && + nsGkAtoms::tableFrame == aChildList.FirstChild()->GetType(), + "expected a table frame"); + mFrames.SetFrames(aChildList); } return NS_OK; @@ -279,7 +265,6 @@ nsTableOuterFrame::AppendFrames(ChildListID aListID, aFrameList.FirstChild()->GetType() == nsGkAtoms::tableCaptionFrame, "appending non-caption frame to captionList"); mCaptionFrames.AppendFrames(this, aFrameList); - mCaptionFrame = mCaptionFrames.FirstChild(); rv = NS_OK; // Reflow the new caption frame. It's already marked dirty, so @@ -308,7 +293,6 @@ nsTableOuterFrame::InsertFrames(ChildListID aListID, aFrameList.FirstChild()->GetType() == nsGkAtoms::tableCaptionFrame, "inserting non-caption frame into captionList"); mCaptionFrames.InsertFrames(nsnull, aPrevFrame, aFrameList); - mCaptionFrame = mCaptionFrames.FirstChild(); // Reflow the new caption frame. It's already marked dirty, so // just tell the pres shell. @@ -334,12 +318,11 @@ nsTableOuterFrame::RemoveFrame(ChildListID aListID, if (HasSideCaption()) { // The old caption width had an effect on the inner table width so // we're going to need to reflow it. Mark it dirty - mInnerTableFrame->AddStateBits(NS_FRAME_IS_DIRTY); + InnerTableFrame()->AddStateBits(NS_FRAME_IS_DIRTY); } // Remove the frame and destroy it mCaptionFrames.DestroyFrame(aOldFrame); - mCaptionFrame = mCaptionFrames.FirstChild(); PresContext()->PresShell()-> FrameNeedsReflow(this, nsIPresShell::eTreeChange, @@ -360,7 +343,7 @@ nsTableOuterFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // If there's no caption, take a short cut to avoid having to create // the special display list set and then sort it. - if (!mCaptionFrame) + if (mCaptionFrames.IsEmpty()) return BuildDisplayListForInnerTable(aBuilder, aDirtyRect, aLists); nsDisplayListCollection set; @@ -368,7 +351,8 @@ nsTableOuterFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, NS_ENSURE_SUCCESS(rv, rv); nsDisplayListSet captionSet(set, set.BlockBorderBackgrounds()); - rv = BuildDisplayListForChild(aBuilder, mCaptionFrame, aDirtyRect, captionSet); + rv = BuildDisplayListForChild(aBuilder, mCaptionFrames.FirstChild(), + aDirtyRect, captionSet); NS_ENSURE_SUCCESS(rv, rv); // Now we have to sort everything by content order, since the caption @@ -400,15 +384,11 @@ nsTableOuterFrame::SetSelected(PRBool aSelected, SelectionType aType) { nsFrame::SetSelected(aSelected, aType); - if (mInnerTableFrame) { - mInnerTableFrame->SetSelected(aSelected, aType); - } + InnerTableFrame()->SetSelected(aSelected, aType); } -NS_IMETHODIMP -nsTableOuterFrame::GetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild) +nsIFrame* +nsTableOuterFrame::GetParentStyleContextFrame() { // The table outer frame and the (inner) table frame split the style // data by giving the table frame the style context associated with @@ -420,14 +400,7 @@ nsTableOuterFrame::GetParentStyleContextFrame(nsPresContext* aPresContext, // children of the table inherit directly from the inner table, and // the outer table's style context is a leaf. - if (!mInnerTableFrame) { - *aProviderFrame = this; - *aIsChild = PR_FALSE; - return NS_ERROR_FAILURE; - } - *aProviderFrame = mInnerTableFrame; - *aIsChild = PR_TRUE; - return NS_OK; + return InnerTableFrame(); } // INCREMENTAL REFLOW HELPER FUNCTIONS @@ -441,8 +414,9 @@ nsTableOuterFrame::InitChildReflowState(nsPresContext& aPresContext, nsMargin collapsePadding(0,0,0,0); nsMargin* pCollapseBorder = nsnull; nsMargin* pCollapsePadding = nsnull; - if ((aReflowState.frame == mInnerTableFrame) && (mInnerTableFrame->IsBorderCollapse())) { - collapseBorder = mInnerTableFrame->GetIncludedOuterBCBorder(); + if (aReflowState.frame == InnerTableFrame() && + InnerTableFrame()->IsBorderCollapse()) { + collapseBorder = InnerTableFrame()->GetIncludedOuterBCBorder(); pCollapseBorder = &collapseBorder; pCollapsePadding = &collapsePadding; } @@ -495,11 +469,12 @@ GetContainingBlockSize(const nsHTMLReflowState& aOuterRS) nsTableOuterFrame::GetMinWidth(nsRenderingContext *aRenderingContext) { nscoord width = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, - mInnerTableFrame, nsLayoutUtils::MIN_WIDTH); + InnerTableFrame(), nsLayoutUtils::MIN_WIDTH); DISPLAY_MIN_WIDTH(this, width); - if (mCaptionFrame) { + if (mCaptionFrames.NotEmpty()) { nscoord capWidth = - nsLayoutUtils::IntrinsicForContainer(aRenderingContext, mCaptionFrame, + nsLayoutUtils::IntrinsicForContainer(aRenderingContext, + mCaptionFrames.FirstChild(), nsLayoutUtils::MIN_WIDTH); if (HasSideCaption()) { width += capWidth; @@ -519,15 +494,16 @@ nsTableOuterFrame::GetPrefWidth(nsRenderingContext *aRenderingContext) DISPLAY_PREF_WIDTH(this, maxWidth); maxWidth = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, - mInnerTableFrame, nsLayoutUtils::PREF_WIDTH); - if (mCaptionFrame) { + InnerTableFrame(), nsLayoutUtils::PREF_WIDTH); + if (mCaptionFrames.NotEmpty()) { PRUint8 captionSide = GetCaptionSide(); switch(captionSide) { case NS_STYLE_CAPTION_SIDE_LEFT: case NS_STYLE_CAPTION_SIDE_RIGHT: { nscoord capMin = - nsLayoutUtils::IntrinsicForContainer(aRenderingContext, mCaptionFrame, + nsLayoutUtils::IntrinsicForContainer(aRenderingContext, + mCaptionFrames.FirstChild(), nsLayoutUtils::MIN_WIDTH); maxWidth += capMin; } @@ -547,7 +523,8 @@ nsTableOuterFrame::GetPrefWidth(nsRenderingContext *aRenderingContext) iwt = nsLayoutUtils::PREF_WIDTH; } nscoord capPref = - nsLayoutUtils::IntrinsicForContainer(aRenderingContext, mCaptionFrame, + nsLayoutUtils::IntrinsicForContainer(aRenderingContext, + mCaptionFrames.FirstChild(), iwt); maxWidth = NS_MAX(maxWidth, capPref); } @@ -604,22 +581,23 @@ nsTableOuterFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext, PRUint8 captionSide = GetCaptionSide(); nscoord width; if (captionSide == NO_SIDE) { - width = ChildShrinkWrapWidth(aRenderingContext, mInnerTableFrame, + width = ChildShrinkWrapWidth(aRenderingContext, InnerTableFrame(), aCBSize, aAvailableWidth); } else if (captionSide == NS_STYLE_CAPTION_SIDE_LEFT || captionSide == NS_STYLE_CAPTION_SIDE_RIGHT) { - nscoord capWidth = ChildShrinkWrapWidth(aRenderingContext, mCaptionFrame, + nscoord capWidth = ChildShrinkWrapWidth(aRenderingContext, + mCaptionFrames.FirstChild(), aCBSize, aAvailableWidth); width = capWidth + ChildShrinkWrapWidth(aRenderingContext, - mInnerTableFrame, aCBSize, + InnerTableFrame(), aCBSize, aAvailableWidth - capWidth); } else if (captionSide == NS_STYLE_CAPTION_SIDE_TOP || captionSide == NS_STYLE_CAPTION_SIDE_BOTTOM) { nscoord margin; - width = ChildShrinkWrapWidth(aRenderingContext, mInnerTableFrame, + width = ChildShrinkWrapWidth(aRenderingContext, InnerTableFrame(), aCBSize, aAvailableWidth, &margin); nscoord capWidth = ChildShrinkWrapWidth(aRenderingContext, - mCaptionFrame, aCBSize, + mCaptionFrames.FirstChild(), aCBSize, width - margin); if (capWidth > width) width = capWidth; @@ -627,11 +605,11 @@ nsTableOuterFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext, NS_ASSERTION(captionSide == NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE || captionSide == NS_STYLE_CAPTION_SIDE_BOTTOM_OUTSIDE, "unexpected caption-side"); - width = ChildShrinkWrapWidth(aRenderingContext, mInnerTableFrame, + width = ChildShrinkWrapWidth(aRenderingContext, InnerTableFrame(), aCBSize, aAvailableWidth); nscoord capWidth = ChildShrinkWrapWidth(aRenderingContext, - mCaptionFrame, aCBSize, - aAvailableWidth); + mCaptionFrames.FirstChild(), + aCBSize, aAvailableWidth); if (capWidth > width) width = capWidth; } @@ -642,8 +620,8 @@ nsTableOuterFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext, PRUint8 nsTableOuterFrame::GetCaptionSide() { - if (mCaptionFrame) { - return mCaptionFrame->GetStyleTableBorder()->mCaptionSide; + if (mCaptionFrames.NotEmpty()) { + return mCaptionFrames.FirstChild()->GetStyleTableBorder()->mCaptionSide; } else { return NO_SIDE; // no caption @@ -653,7 +631,8 @@ nsTableOuterFrame::GetCaptionSide() PRUint8 nsTableOuterFrame::GetCaptionVerticalAlign() { - const nsStyleCoord& va = mCaptionFrame->GetStyleTextReset()->mVerticalAlign; + const nsStyleCoord& va = + mCaptionFrames.FirstChild()->GetStyleTextReset()->mVerticalAlign; return (va.GetUnit() == eStyleUnit_Enumerated) ? va.GetIntValue() : NS_STYLE_VERTICAL_ALIGN_TOP; @@ -668,13 +647,13 @@ nsTableOuterFrame::SetDesiredSize(PRUint8 aCaptionSide, { aWidth = aHeight = 0; - nsRect innerRect = mInnerTableFrame->GetRect(); + nsRect innerRect = InnerTableFrame()->GetRect(); nscoord innerWidth = innerRect.width; nsRect captionRect(0,0,0,0); nscoord captionWidth = 0; - if (mCaptionFrame) { - captionRect = mCaptionFrame->GetRect(); + if (mCaptionFrames.NotEmpty()) { + captionRect = mCaptionFrames.FirstChild()->GetRect(); captionWidth = captionRect.width; } switch(aCaptionSide) { @@ -715,7 +694,7 @@ nsTableOuterFrame::GetCaptionOrigin(PRUint32 aCaptionSide, (NS_UNCONSTRAINEDSIZE == aCaptionSize.width) || (NS_UNCONSTRAINEDSIZE == aCaptionSize.height)) { return NS_OK; } - if (!mCaptionFrame) return NS_OK; + if (mCaptionFrames.IsEmpty()) return NS_OK; NS_ASSERTION(NS_AUTOMARGIN != aCaptionMargin.left, "The computed caption margin is auto?"); NS_ASSERTION(NS_AUTOMARGIN != aCaptionMargin.top, "The computed caption margin is auto?"); @@ -894,7 +873,7 @@ nsTableOuterFrame::OuterBeginReflowChild(nsPresContext* aPresContext, // work around pixel rounding errors, round down to ensure we don't exceed the avail height in nscoord availHeight = aOuterRS.availableHeight; if (NS_UNCONSTRAINEDSIZE != availHeight) { - if (mCaptionFrame == aChildFrame) { + if (mCaptionFrames.FirstChild() == aChildFrame) { availHeight = NS_UNCONSTRAINEDSIZE; } else { nsMargin margin; @@ -918,14 +897,14 @@ nsTableOuterFrame::OuterBeginReflowChild(nsPresContext* aPresContext, InitChildReflowState(*aPresContext, childRS); // see if we need to reset top of page due to a caption - if (mCaptionFrame) { + if (mCaptionFrames.NotEmpty()) { PRUint8 captionSide = GetCaptionSide(); if (((captionSide == NS_STYLE_CAPTION_SIDE_BOTTOM || captionSide == NS_STYLE_CAPTION_SIDE_BOTTOM_OUTSIDE) && - mCaptionFrame == aChildFrame) || + mCaptionFrames.FirstChild() == aChildFrame) || ((captionSide == NS_STYLE_CAPTION_SIDE_TOP || captionSide == NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE) && - mInnerTableFrame == aChildFrame)) { + InnerTableFrame() == aChildFrame)) { childRS.mFlags.mIsTopOfPage = PR_FALSE; } } @@ -955,9 +934,9 @@ nsTableOuterFrame::UpdateReflowMetrics(PRUint8 aCaptionSide, aMet.width, aMet.height); aMet.SetOverflowAreasToDesiredBounds(); - ConsiderChildOverflow(aMet.mOverflowAreas, mInnerTableFrame); - if (mCaptionFrame) { - ConsiderChildOverflow(aMet.mOverflowAreas, mCaptionFrame); + ConsiderChildOverflow(aMet.mOverflowAreas, InnerTableFrame()); + if (mCaptionFrames.NotEmpty()) { + ConsiderChildOverflow(aMet.mOverflowAreas, mCaptionFrames.FirstChild()); } FinishAndStoreOverflow(&aMet); } @@ -970,12 +949,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPresContext* aPresContext, DO_GLOBAL_REFLOW_COUNT("nsTableOuterFrame"); DISPLAY_REFLOW(aPresContext, this, aOuterRS, aDesiredSize, aStatus); - // We desperately need an inner table frame, - // if this fails fix the frame constructor - if (mFrames.IsEmpty() || !mInnerTableFrame) { - NS_ERROR("incomplete children"); - return NS_ERROR_FAILURE; - } nsresult rv = NS_OK; PRUint8 captionSide = GetCaptionSide(); @@ -999,36 +972,37 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPresContext* aPresContext, nsHTMLReflowState *innerRS = static_cast((void*) innerRSSpace); - nsRect origInnerRect = mInnerTableFrame->GetRect(); - nsRect origInnerVisualOverflow = mInnerTableFrame->GetVisualOverflowRect(); + nsRect origInnerRect = InnerTableFrame()->GetRect(); + nsRect origInnerVisualOverflow = InnerTableFrame()->GetVisualOverflowRect(); PRBool innerFirstReflow = - (mInnerTableFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0; + (InnerTableFrame()->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0; nsRect origCaptionRect; nsRect origCaptionVisualOverflow; PRBool captionFirstReflow; - if (mCaptionFrame) { - origCaptionRect = mCaptionFrame->GetRect(); - origCaptionVisualOverflow = mCaptionFrame->GetVisualOverflowRect(); + if (mCaptionFrames.NotEmpty()) { + origCaptionRect = mCaptionFrames.FirstChild()->GetRect(); + origCaptionVisualOverflow = + mCaptionFrames.FirstChild()->GetVisualOverflowRect(); captionFirstReflow = - (mCaptionFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0; + (mCaptionFrames.FirstChild()->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0; } // ComputeAutoSize has to match this logic. if (captionSide == NO_SIDE) { // We don't have a caption. - OuterBeginReflowChild(aPresContext, mInnerTableFrame, aOuterRS, + OuterBeginReflowChild(aPresContext, InnerTableFrame(), aOuterRS, innerRSSpace, aOuterRS.ComputedWidth()); } else if (captionSide == NS_STYLE_CAPTION_SIDE_LEFT || captionSide == NS_STYLE_CAPTION_SIDE_RIGHT) { // nsTableCaptionFrame::ComputeAutoSize takes care of making side // captions small. Compute the caption's size first, and tell the // table to fit in what's left. - OuterBeginReflowChild(aPresContext, mCaptionFrame, aOuterRS, + OuterBeginReflowChild(aPresContext, mCaptionFrames.FirstChild(), aOuterRS, captionRSSpace, aOuterRS.ComputedWidth()); nscoord innerAvailWidth = aOuterRS.ComputedWidth() - (captionRS->ComputedWidth() + captionRS->mComputedMargin.LeftRight() + captionRS->mComputedBorderPadding.LeftRight()); - OuterBeginReflowChild(aPresContext, mInnerTableFrame, aOuterRS, + OuterBeginReflowChild(aPresContext, InnerTableFrame(), aOuterRS, innerRSSpace, innerAvailWidth); } else if (captionSide == NS_STYLE_CAPTION_SIDE_TOP || @@ -1041,7 +1015,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPresContext* aPresContext, // table box inside it // We don't actually make our anonymous box that width (if we did, // it would break 'auto' margins), but this effectively does that. - OuterBeginReflowChild(aPresContext, mInnerTableFrame, aOuterRS, + OuterBeginReflowChild(aPresContext, InnerTableFrame(), aOuterRS, innerRSSpace, aOuterRS.ComputedWidth()); // It's good that CSS 2.1 says not to include margins, since we // can't, since they already been converted so they exactly @@ -1050,16 +1024,16 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPresContext* aPresContext, // GetCaptionOrigin, though.) nscoord innerBorderWidth = innerRS->ComputedWidth() + innerRS->mComputedBorderPadding.LeftRight(); - OuterBeginReflowChild(aPresContext, mCaptionFrame, aOuterRS, + OuterBeginReflowChild(aPresContext, mCaptionFrames.FirstChild(), aOuterRS, captionRSSpace, innerBorderWidth); } else { NS_ASSERTION(captionSide == NS_STYLE_CAPTION_SIDE_TOP_OUTSIDE || captionSide == NS_STYLE_CAPTION_SIDE_BOTTOM_OUTSIDE, "unexpected caption-side"); // Size the table and the caption independently. - OuterBeginReflowChild(aPresContext, mCaptionFrame, aOuterRS, + OuterBeginReflowChild(aPresContext, mCaptionFrames.FirstChild(), aOuterRS, captionRSSpace, aOuterRS.ComputedWidth()); - OuterBeginReflowChild(aPresContext, mInnerTableFrame, aOuterRS, + OuterBeginReflowChild(aPresContext, InnerTableFrame(), aOuterRS, innerRSSpace, aOuterRS.ComputedWidth()); } @@ -1067,10 +1041,10 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics captionMet; nsSize captionSize; nsMargin captionMargin; - if (mCaptionFrame) { + if (mCaptionFrames.NotEmpty()) { nsReflowStatus capStatus; // don't let the caption cause incomplete - rv = OuterDoReflowChild(aPresContext, mCaptionFrame, *captionRS, - captionMet, capStatus); + rv = OuterDoReflowChild(aPresContext, mCaptionFrames.FirstChild(), + *captionRS, captionMet, capStatus); if (NS_FAILED(rv)) return rv; captionSize.width = captionMet.width; captionSize.height = captionMet.height; @@ -1114,7 +1088,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPresContext* aPresContext, // Then, now that we know how much to reduce the width of the inner // table to account for side captions, reflow the inner table. nsHTMLReflowMetrics innerMet; - rv = OuterDoReflowChild(aPresContext, mInnerTableFrame, *innerRS, + rv = OuterDoReflowChild(aPresContext, InnerTableFrame(), *innerRS, innerMet, aStatus); if (NS_FAILED(rv)) return rv; nsSize innerSize; @@ -1130,12 +1104,12 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPresContext* aPresContext, // XXX Need to recompute inner table's auto margins for the case of side // captions. (Caption's are broken too, but that should be fixed earlier.) - if (mCaptionFrame) { + if (mCaptionFrames.NotEmpty()) { nsPoint captionOrigin; GetCaptionOrigin(captionSide, containSize, innerSize, innerMargin, captionSize, captionMargin, captionOrigin); - FinishReflowChild(mCaptionFrame, aPresContext, captionRS, captionMet, - captionOrigin.x, captionOrigin.y, 0); + FinishReflowChild(mCaptionFrames.FirstChild(), aPresContext, captionRS, + captionMet, captionOrigin.x, captionOrigin.y, 0); captionRS->~nsHTMLReflowState(); } // XXX If the height is constrained then we need to check whether @@ -1144,14 +1118,14 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPresContext* aPresContext, nsPoint innerOrigin; GetInnerOrigin(captionSide, containSize, captionSize, captionMargin, innerSize, innerMargin, innerOrigin); - FinishReflowChild(mInnerTableFrame, aPresContext, innerRS, innerMet, + FinishReflowChild(InnerTableFrame(), aPresContext, innerRS, innerMet, innerOrigin.x, innerOrigin.y, 0); innerRS->~nsHTMLReflowState(); - nsTableFrame::InvalidateFrame(mInnerTableFrame, origInnerRect, + nsTableFrame::InvalidateFrame(InnerTableFrame(), origInnerRect, origInnerVisualOverflow, innerFirstReflow); - if (mCaptionFrame) { - nsTableFrame::InvalidateFrame(mCaptionFrame, origCaptionRect, + if (mCaptionFrames.NotEmpty()) { + nsTableFrame::InvalidateFrame(mCaptionFrames.FirstChild(), origCaptionRect, origCaptionVisualOverflow, captionFirstReflow); } @@ -1181,20 +1155,16 @@ nsTableOuterFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex, PRInt32& aActualRowSpan, PRInt32& aActualColSpan, PRBool& aIsSelected) { - NS_ASSERTION(mInnerTableFrame, "no inner table frame yet?"); - - return mInnerTableFrame->GetCellDataAt(aRowIndex, aColIndex, aCell, - aStartRowIndex, aStartColIndex, - aRowSpan, aColSpan, aActualRowSpan, - aActualColSpan, aIsSelected); + return InnerTableFrame()->GetCellDataAt(aRowIndex, aColIndex, aCell, + aStartRowIndex, aStartColIndex, + aRowSpan, aColSpan, aActualRowSpan, + aActualColSpan, aIsSelected); } NS_IMETHODIMP nsTableOuterFrame::GetTableSize(PRInt32& aRowCount, PRInt32& aColCount) { - NS_ASSERTION(mInnerTableFrame, "no inner table frame yet?"); - - return mInnerTableFrame->GetTableSize(aRowCount, aColCount); + return InnerTableFrame()->GetTableSize(aRowCount, aColCount); } NS_IMETHODIMP @@ -1202,9 +1172,7 @@ nsTableOuterFrame::GetIndexByRowAndColumn(PRInt32 aRow, PRInt32 aColumn, PRInt32 *aIndex) { NS_ENSURE_ARG_POINTER(aIndex); - - NS_ASSERTION(mInnerTableFrame, "no inner table frame yet?"); - return mInnerTableFrame->GetIndexByRowAndColumn(aRow, aColumn, aIndex); + return InnerTableFrame()->GetIndexByRowAndColumn(aRow, aColumn, aIndex); } NS_IMETHODIMP @@ -1213,9 +1181,7 @@ nsTableOuterFrame::GetRowAndColumnByIndex(PRInt32 aIndex, { NS_ENSURE_ARG_POINTER(aRow); NS_ENSURE_ARG_POINTER(aColumn); - - NS_ASSERTION(mInnerTableFrame, "no inner table frame yet?"); - return mInnerTableFrame->GetRowAndColumnByIndex(aIndex, aRow, aColumn); + return InnerTableFrame()->GetRowAndColumnByIndex(aIndex, aRow, aColumn); } /*---------------- end of nsITableLayout implementation ------------------*/ diff --git a/layout/tables/nsTableOuterFrame.h b/layout/tables/nsTableOuterFrame.h index ecba6304100..8bcde836d5e 100644 --- a/layout/tables/nsTableOuterFrame.h +++ b/layout/tables/nsTableOuterFrame.h @@ -41,9 +41,7 @@ #include "nsHTMLContainerFrame.h" #include "nsBlockFrame.h" #include "nsITableLayout.h" - -struct nsStyleTable; -class nsTableFrame; +#include "nsTableFrame.h" class nsTableCaptionFrame : public nsBlockFrame { @@ -59,9 +57,8 @@ public: nsSize aMargin, nsSize aBorder, nsSize aPadding, PRBool aShrinkWrap); - NS_IMETHOD GetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild); + virtual nsIFrame* GetParentStyleContextFrame(); + #ifdef ACCESSIBILITY virtual already_AddRefed CreateAccessible(); #endif @@ -169,9 +166,7 @@ public: void SetSelected(PRBool aSelected, SelectionType aType); - NS_IMETHOD GetParentStyleContextFrame(nsPresContext* aPresContext, - nsIFrame** aProviderFrame, - PRBool* aIsChild); + virtual nsIFrame* GetParentStyleContextFrame(); /*---------------- nsITableLayout methods ------------------------*/ @@ -262,17 +257,15 @@ protected: nscoord aAvailableWidth, nsMargin& aMargin); + nsTableFrame* InnerTableFrame() { + return static_cast(mFrames.FirstChild()); + } + private: - // used to keep track of this frame's children. They are redundant with mFrames, but more convient - nsTableFrame* mInnerTableFrame; nsFrameList mCaptionFrames; - nsIFrame* mCaptionFrame; }; inline PRIntn nsTableOuterFrame::GetSkipSides() const { return 0; } #endif - - - diff --git a/layout/xul/base/src/nsMenuBarListener.cpp b/layout/xul/base/src/nsMenuBarListener.cpp index 430beed3192..7101439a389 100644 --- a/layout/xul/base/src/nsMenuBarListener.cpp +++ b/layout/xul/base/src/nsMenuBarListener.cpp @@ -141,6 +141,11 @@ nsMenuBarListener::ToggleMenuActiveState() nsresult nsMenuBarListener::KeyUp(nsIDOMEvent* aKeyEvent) { + nsCOMPtr keyEvent = do_QueryInterface(aKeyEvent); + if (!keyEvent) { + return NS_OK; + } + InitAccessKey(); //handlers shouldn't be triggered by non-trusted events. @@ -159,7 +164,6 @@ nsMenuBarListener::KeyUp(nsIDOMEvent* aKeyEvent) // On a press of the ALT key by itself, we toggle the menu's // active/inactive state. // Get the ascii key code. - nsCOMPtr keyEvent = do_QueryInterface(aKeyEvent); PRUint32 theChar; keyEvent->GetKeyCode(&theChar); diff --git a/layout/xul/base/src/nsMenuPopupFrame.cpp b/layout/xul/base/src/nsMenuPopupFrame.cpp index 41a6446ae43..90b596f4288 100644 --- a/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/layout/xul/base/src/nsMenuPopupFrame.cpp @@ -146,8 +146,6 @@ nsMenuPopupFrame::Init(nsIContent* aContent, nsresult rv = nsBoxFrame::Init(aContent, aParent, aPrevInFlow); NS_ENSURE_SUCCESS(rv, rv); - nsPresContext* presContext = PresContext(); - // lookup if we're allowed to overlap the OS bar (menubar/taskbar) from the // look&feel object mMenuCanOverlapOSBar = diff --git a/mobile/chrome/content/extensions.js b/mobile/chrome/content/extensions.js index 81d2a31d1f8..ac9a7c7639c 100644 --- a/mobile/chrome/content/extensions.js +++ b/mobile/chrome/content/extensions.js @@ -864,7 +864,7 @@ function searchFailed() { let failLabel = strings.formatStringFromName("addonsSearchFail.label", [brand.GetStringFromName("brandShortName")], 1); - let failButton = strings.GetStringFromName("addonsSearchFail.button"); + let failButton = strings.GetStringFromName("addonsSearchFail.retryButton"); ExtensionsView.displaySectionMessage("repo", failLabel, failButton, true); } diff --git a/mobile/locales/en-US/chrome/browser.properties b/mobile/locales/en-US/chrome/browser.properties index 3d46df353e5..5f8d93ca2a5 100644 --- a/mobile/locales/en-US/chrome/browser.properties +++ b/mobile/locales/en-US/chrome/browser.properties @@ -6,7 +6,7 @@ addonsSearchNone.search=No matches found addonsSearchNone.recommended=No recommended add-ons addonsSearchNone.button=Try Again addonsSearchFail.label=%S couldn't retrieve add-ons -addonsSearchFail.button=OK +addonsSearchFail.retryButton=Retry addonsSearchSuccess2.button=Clear Search addonsBrowseAll.label=Browse all add-ons addonsBrowseAll.description=addons.mozilla.org has many to explore diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index cb7c0ee2f9c..a02732eff85 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1110,6 +1110,7 @@ pref("font.language.group", "chrome://global/locale/intl.propert pref("intl.uidirection.ar", "rtl"); pref("intl.uidirection.he", "rtl"); pref("intl.uidirection.fa", "rtl"); +pref("intl.uidirection.ur", "rtl"); // use en-US hyphenation by default for content tagged with plain lang="en" pref("intl.hyphenation-alias.en", "en-us"); diff --git a/netwerk/base/public/nsNetError.h b/netwerk/base/public/nsNetError.h index 6ca2c5dd3c2..f3262599e0b 100644 --- a/netwerk/base/public/nsNetError.h +++ b/netwerk/base/public/nsNetError.h @@ -152,6 +152,17 @@ #define NS_ERROR_CORRUPTED_CONTENT \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 29) +/** + * While parsing for the first component of a header field using + * syntax as in Content-Disposition or Content-Type, the first component + * was found to be empty, such as in: + * + * Content-Disposition: ; filename=foo + */ +#define NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 34) + + /****************************************************************************** * Connectivity error codes: */ diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index 5e785470280..08e2ed8fc03 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -1943,8 +1943,13 @@ NS_GetContentDispositionFromHeader(const nsACString& aHeader, nsIChannel *aChan nsAutoString dispToken; rv = mimehdrpar->GetParameter(aHeader, "", fallbackCharset, PR_TRUE, nsnull, dispToken); - if (NS_FAILED(rv)) - return nsIChannel::DISPOSITION_ATTACHMENT; + + if (NS_FAILED(rv)) { + // special case (see bug 272541): empty disposition type handled as "inline" + return rv == NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY + ? nsIChannel::DISPOSITION_INLINE + : nsIChannel::DISPOSITION_ATTACHMENT; + } return NS_GetContentDispositionFromToken(dispToken); } diff --git a/netwerk/mime/nsMIMEHeaderParamImpl.cpp b/netwerk/mime/nsMIMEHeaderParamImpl.cpp index 49a79a2d066..c3c725024cc 100644 --- a/netwerk/mime/nsMIMEHeaderParamImpl.cpp +++ b/netwerk/mime/nsMIMEHeaderParamImpl.cpp @@ -57,6 +57,7 @@ #include "nsMIMEHeaderParamImpl.h" #include "nsReadableUtils.h" #include "nsNativeCharsetUtils.h" +#include "nsNetError.h" // static functions declared below are moved from mailnews/mime/src/comi18n.cpp @@ -181,7 +182,8 @@ nsMIMEHeaderParamImpl::GetParameterInternal(const char *aHeaderValue, for (; *str && *str != ';' && !nsCRT::IsAsciiSpace(*str); ++str) ; if (str == start) - return NS_ERROR_UNEXPECTED; + return NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY; + *aResult = (char *) nsMemory::Clone(start, (str - start) + 1); NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); (*aResult)[str - start] = '\0'; // null-terminate diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index b6807982987..ea6e8b21136 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -776,7 +776,7 @@ HttpBaseChannel::nsContentEncodings::PrepareForNext(void) NS_IMETHODIMP HttpBaseChannel::GetRequestMethod(nsACString& aMethod) { - aMethod = mRequestHead.Method(); + mRequestHead.Method()->ToUTF8String(aMethod); return NS_OK; } @@ -785,16 +785,27 @@ HttpBaseChannel::SetRequestMethod(const nsACString& aMethod) { ENSURE_CALLED_BEFORE_ASYNC_OPEN(); - const nsCString& flatMethod = PromiseFlatCString(aMethod); + nsCAutoString upperCaseMethod; + ToUpperCase(aMethod, upperCaseMethod); // Method names are restricted to valid HTTP tokens. - if (!nsHttp::IsValidToken(flatMethod)) + if (!nsHttp::IsValidToken(upperCaseMethod)) return NS_ERROR_INVALID_ARG; - nsHttpAtom atom = nsHttp::ResolveAtom(flatMethod.get()); - if (!atom) - return NS_ERROR_FAILURE; + nsCOMPtr atom = do_GetAtom(upperCaseMethod); + // We've changed method names to case sensitive in bug 477578. Some + // methods are kept case insensitive to keep backward compatibility and + // to satisfy XMLHttpRequest specification which demands it. +#define HTTP_METHOD_ATOM(name_, value_) +#define HTTP_CASE_INSENSITIVE_METHOD_ATOM(name_, value_) \ + if (nsHttp::name_ == atom) {} else +#include "nsHttpAtomList.h" +#undef HTTP_CASE_INSENSITIVE_METHOD_ATOM +#undef HTTP_METHOD_ATOM + { // upper case atom doesn't match any case insensitive atom + atom = do_GetAtom(aMethod); + } mRequestHead.SetMethod(atom); return NS_OK; } @@ -1543,7 +1554,7 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI, PRInt64 len = clen ? nsCRT::atoll(clen) : -1; uploadChannel2->ExplicitSetUploadStream( mUploadStream, nsDependentCString(ctype), len, - nsDependentCString(mRequestHead.Method()), + nsAtomCString(mRequestHead.Method()), mUploadStreamHasHeaders); } else { if (mUploadStreamHasHeaders) { @@ -1570,7 +1581,7 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI, // we set the upload stream above. This means SetRequestMethod() will // be called twice if ExplicitSetUploadStream() gets called above. - httpChannel->SetRequestMethod(nsDependentCString(mRequestHead.Method())); + httpChannel->SetRequestMethod(nsAtomCString(mRequestHead.Method())); } // convey the referrer if one was used for this channel to the next one if (mReferrer) diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index 4b9f27c9dbd..da6f0c6cea1 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -1072,7 +1072,7 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext) SendAsyncOpen(IPC::URI(mURI), IPC::URI(mOriginalURI), IPC::URI(mDocumentURI), IPC::URI(mReferrer), mLoadFlags, - mRequestHeaders, mRequestHead.Method(), + mRequestHeaders, nsAtomCString(mRequestHead.Method()), IPC::InputStream(mUploadStream), mUploadStreamHasHeaders, mPriority, mRedirectionLimit, mAllowPipelining, mForceAllowThirdPartyCookie, mSendResumeAt, diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 4b01e10829f..4b00af3a6eb 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -132,7 +132,7 @@ HttpChannelParent::RecvAsyncOpen(const IPC::URI& aURI, const IPC::URI& aReferrerURI, const PRUint32& loadFlags, const RequestHeaderTuples& requestHeaders, - const nsHttpAtom& requestMethod, + const nsCString& requestMethod, const IPC::InputStream& uploadStream, const PRBool& uploadStreamHasHeaders, const PRUint16& priority, @@ -190,7 +190,7 @@ HttpChannelParent::RecvAsyncOpen(const IPC::URI& aURI, httpChan->SetNotificationCallbacks(channelListener); - httpChan->SetRequestMethod(nsDependentCString(requestMethod.get())); + httpChan->SetRequestMethod(requestMethod); nsCOMPtr stream(uploadStream); if (stream) { diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h index 377ce877970..43b2682fc6e 100644 --- a/netwerk/protocol/http/HttpChannelParent.h +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -86,7 +86,7 @@ protected: const IPC::URI& referrerUri, const PRUint32& loadFlags, const RequestHeaderTuples& requestHeaders, - const nsHttpAtom& requestMethod, + const nsCString& requestMethod, const IPC::InputStream& uploadStream, const PRBool& uploadStreamHasHeaders, const PRUint16& priority, diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl index 70c79e315df..083c617fac1 100644 --- a/netwerk/protocol/http/PHttpChannel.ipdl +++ b/netwerk/protocol/http/PHttpChannel.ipdl @@ -47,7 +47,6 @@ include "prio.h"; using RequestHeaderTuples; using nsHttpResponseHead; -using nsHttpAtom; using IPC::URI; using IPC::InputStream; using PRNetAddr; @@ -70,7 +69,7 @@ parent: URI referrer, PRUint32 loadFlags, RequestHeaderTuples requestHeaders, - nsHttpAtom requestMethod, + nsCString requestMethod, InputStream uploadStream, PRBool uploadStreamHasHeaders, PRUint16 priority, diff --git a/netwerk/protocol/http/nsHttp.cpp b/netwerk/protocol/http/nsHttp.cpp index ca32c3e2abc..04ca507c226 100644 --- a/netwerk/protocol/http/nsHttp.cpp +++ b/netwerk/protocol/http/nsHttp.cpp @@ -42,6 +42,7 @@ #include "mozilla/Mutex.h" #include "nsCRT.h" #include "prbit.h" +#include "nsStaticAtom.h" #if defined(PR_LOGGING) PRLogModuleInfo *gHttpLog = nsnull; @@ -60,6 +61,23 @@ enum { }; #undef HTTP_ATOM +// define all method atoms +#define HTTP_METHOD_ATOM(name_, value_) nsIAtom* nsHttp::name_; +#include "nsHttpAtomList.h" +#undef HTTP_METHOD_ATOM + +#define HTTP_METHOD_ATOM(name_, value_) \ + NS_STATIC_ATOM_BUFFER(name_##_buffer, value_) +#include "nsHttpAtomList.h" +#undef HTTP_METHOD_ATOM + +static const nsStaticAtom methodAtomsInfo[] = { +#define HTTP_METHOD_ATOM(name_, value_) \ + NS_STATIC_ATOM(name_##_buffer, &nsHttp::name_), +#include "nsHttpAtomList.h" +#undef HTTP_METHOD_ATOM +}; + using namespace mozilla; // we keep a linked list of atoms allocated on the heap for easy clean up when @@ -184,6 +202,12 @@ nsHttp::DestroyAtomTable() } } +void +nsHttp::CreateMethodAtoms() +{ + NS_RegisterStaticAtoms(methodAtomsInfo, NS_ARRAY_LENGTH(methodAtomsInfo)); +} + // this function may be called from multiple threads nsHttpAtom nsHttp::ResolveAtom(const char *str) diff --git a/netwerk/protocol/http/nsHttp.h b/netwerk/protocol/http/nsHttp.h index 05e0a95b265..07391219d6d 100644 --- a/netwerk/protocol/http/nsHttp.h +++ b/netwerk/protocol/http/nsHttp.h @@ -67,6 +67,7 @@ #include "nsPromiseFlatString.h" #include "nsURLHelper.h" #include "netCore.h" +#include "nsIAtom.h" #if defined(PR_LOGGING) // @@ -164,6 +165,8 @@ struct nsHttp static nsresult CreateAtomTable(); static void DestroyAtomTable(); + static void CreateMethodAtoms(); + // will dynamically add atoms to the table if they don't already exist static nsHttpAtom ResolveAtom(const char *); static nsHttpAtom ResolveAtom(const nsACString &s) @@ -215,6 +218,10 @@ struct nsHttp #define HTTP_ATOM(_name, _value) static nsHttpAtom _name; #include "nsHttpAtomList.h" #undef HTTP_ATOM + +#define HTTP_METHOD_ATOM(_name, _value) static nsIAtom* _name; +#include "nsHttpAtomList.h" +#undef HTTP_METHOD_ATOM }; //----------------------------------------------------------------------------- diff --git a/netwerk/protocol/http/nsHttpAtomList.h b/netwerk/protocol/http/nsHttpAtomList.h index ddf4bde0490..a97ec660ed9 100644 --- a/netwerk/protocol/http/nsHttpAtomList.h +++ b/netwerk/protocol/http/nsHttpAtomList.h @@ -50,6 +50,7 @@ The second argument to HTTP_ATOM is the string value of the atom. ******/ +#if defined(HTTP_ATOM) HTTP_ATOM(Accept, "Accept") HTTP_ATOM(Accept_Encoding, "Accept-Encoding") HTTP_ATOM(Accept_Language, "Accept-Language") @@ -123,26 +124,40 @@ HTTP_ATOM(Vary, "Vary") HTTP_ATOM(Version, "Version") HTTP_ATOM(WWW_Authenticate, "WWW-Authenticate") HTTP_ATOM(Warning, "Warning") +#endif // methods are atoms too. // // Note: winnt.h defines DELETE macro, so we'll just keep the methods mixedcase // even though they're normally written all uppercase. -- darin -HTTP_ATOM(Connect, "CONNECT") -HTTP_ATOM(Copy, "COPY") -HTTP_ATOM(Delete, "DELETE") -HTTP_ATOM(Get, "GET") -HTTP_ATOM(Head, "HEAD") -HTTP_ATOM(Index, "INDEX") -HTTP_ATOM(Lock, "LOCK") -HTTP_ATOM(M_Post, "M-POST") -HTTP_ATOM(Mkcol, "MKCOL") -HTTP_ATOM(Move, "MOVE") -HTTP_ATOM(Options, "OPTIONS") -HTTP_ATOM(Post, "POST") -HTTP_ATOM(Propfind, "PROPFIND") -HTTP_ATOM(Proppatch, "PROPPATCH") -HTTP_ATOM(Put, "PUT") -HTTP_ATOM(Trace, "TRACE") -HTTP_ATOM(Unlock, "UNLOCK") +#if defined(HTTP_METHOD_ATOM) + +#if !defined(HTTP_CASE_INSENSITIVE_METHOD_ATOM) +#define HTTP_CASE_INSENSITIVE_METHOD_ATOM HTTP_METHOD_ATOM +#define UNDEF_HTTP_CASE_INSENSITIVE_METHOD_ATOM +#endif +HTTP_CASE_INSENSITIVE_METHOD_ATOM(Connect, "CONNECT") +HTTP_METHOD_ATOM (Copy, "COPY") +HTTP_CASE_INSENSITIVE_METHOD_ATOM(Delete, "DELETE") +HTTP_CASE_INSENSITIVE_METHOD_ATOM(Get, "GET") +HTTP_CASE_INSENSITIVE_METHOD_ATOM(Head, "HEAD") +HTTP_METHOD_ATOM (Index, "INDEX") +HTTP_METHOD_ATOM (Lock, "LOCK") +HTTP_METHOD_ATOM (M_Post, "M-POST") +HTTP_METHOD_ATOM (Mkcol, "MKCOL") +HTTP_METHOD_ATOM (Move, "MOVE") +HTTP_CASE_INSENSITIVE_METHOD_ATOM(Options, "OPTIONS") +HTTP_CASE_INSENSITIVE_METHOD_ATOM(Post, "POST") +HTTP_METHOD_ATOM (Propfind, "PROPFIND") +HTTP_METHOD_ATOM (Proppatch, "PROPPATCH") +HTTP_CASE_INSENSITIVE_METHOD_ATOM(Put, "PUT") +HTTP_CASE_INSENSITIVE_METHOD_ATOM(Trace, "TRACE") +HTTP_CASE_INSENSITIVE_METHOD_ATOM(Track, "TRACK") +HTTP_METHOD_ATOM (Unlock, "UNLOCK") +#if defined(UNDEF_HTTP_CASE_INSENSITIVE_METHOD_ATOM) +#undef UNDEF_HTTP_CASE_INSENSITIVE_METHOD_ATOM +#undef HTTP_CASE_INSENSITIVE_METHOD_ATOM +#endif + +#endif diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 6cc90a9e9eb..bf0c6591191 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -2412,7 +2412,9 @@ nsHttpChannel::CheckCache() rv = mCacheEntry->GetMetaDataElement("request-method", getter_Copies(buf)); NS_ENSURE_SUCCESS(rv, rv); - nsHttpAtom method = nsHttp::ResolveAtom(buf); + nsCOMPtr method = do_GetAtom(buf); + NS_ENSURE_TRUE(method, NS_ERROR_OUT_OF_MEMORY); + if (method == nsHttp::Head) { // The cached response does not contain an entity. We can only reuse // the response if the current request is also HEAD. @@ -2981,7 +2983,7 @@ nsHttpChannel::AddCacheEntryHeaders(nsICacheEntryDescriptor *entry) // Store the HTTP request method with the cache entry so we can distinguish // for example GET and HEAD responses. rv = entry->SetMetaDataElement("request-method", - mRequestHead.Method().get()); + nsAtomCString(mRequestHead.Method()).get()); if (NS_FAILED(rv)) return rv; // Store the HTTP authorization scheme used if any... diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index b9fb1b28218..c734a25423a 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -238,6 +238,8 @@ nsHttpHandler::Init() if (NS_FAILED(rv)) return rv; + nsHttp::CreateMethodAtoms(); + mIOService = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) { NS_WARNING("unable to continue without io service"); diff --git a/netwerk/protocol/http/nsHttpRequestHead.cpp b/netwerk/protocol/http/nsHttpRequestHead.cpp index 1ed95515220..ff5a2540788 100644 --- a/netwerk/protocol/http/nsHttpRequestHead.cpp +++ b/netwerk/protocol/http/nsHttpRequestHead.cpp @@ -47,7 +47,7 @@ nsHttpRequestHead::Flatten(nsACString &buf, PRBool pruneProxyHeaders) { // note: the first append is intentional. - buf.Append(mMethod.get()); + buf.Append(nsAtomCString(mMethod)); buf.Append(' '); buf.Append(mRequestURI); buf.AppendLiteral(" HTTP/"); diff --git a/netwerk/protocol/http/nsHttpRequestHead.h b/netwerk/protocol/http/nsHttpRequestHead.h index 168b9f314e7..aa796204d04 100644 --- a/netwerk/protocol/http/nsHttpRequestHead.h +++ b/netwerk/protocol/http/nsHttpRequestHead.h @@ -55,12 +55,12 @@ public: nsHttpRequestHead() : mMethod(nsHttp::Get), mVersion(NS_HTTP_VERSION_1_1) {} ~nsHttpRequestHead() {} - void SetMethod(nsHttpAtom method) { mMethod = method; } + void SetMethod(nsIAtom *method) { mMethod = method; } void SetVersion(nsHttpVersion version) { mVersion = version; } void SetRequestURI(const nsCSubstring &s) { mRequestURI = s; } nsHttpHeaderArray &Headers() { return mHeaders; } - nsHttpAtom Method() { return mMethod; } + nsIAtom *Method() { return mMethod; } nsHttpVersion Version() { return mVersion; } const nsCSubstring &RequestURI() { return mRequestURI; } @@ -77,7 +77,7 @@ public: private: nsHttpHeaderArray mHeaders; - nsHttpAtom mMethod; + nsCOMPtr mMethod; nsHttpVersion mVersion; nsCString mRequestURI; }; diff --git a/netwerk/test/unit/test_bug272541.js b/netwerk/test/unit/test_bug272541.js new file mode 100644 index 00000000000..666f81ed5cd --- /dev/null +++ b/netwerk/test/unit/test_bug272541.js @@ -0,0 +1,37 @@ +/** + * Test for bug 272541: - Empty disposition type treated as "attachment" + */ + +const Cr = Components.results + +var tests = [ + [ /* the actual bug */ + "; filename=foo.html", + Cr.NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY], + [ /* regression check, but see bug 671204 */ + "filename=foo.html", + "filename=foo.html"], + [ /* sanity check */ + "attachment; filename=foo.html", + "attachment"], + ]; + +function run_test() { + + var mhp = Components.classes["@mozilla.org/network/mime-hdrparam;1"] + .getService(Components.interfaces.nsIMIMEHeaderParam); + + var unused = { value : null }; + + for (var i = 0; i < tests.length; ++i) { + dump("Testing " + tests[i] + "\n"); + try { + do_check_eq(mhp.getParameter(tests[i][0], "", "UTF-8", true, unused), + tests[i][1]); + } + catch (e) { + do_check_eq(e.result, tests[i][1]); + } + } +} + diff --git a/netwerk/test/unit/test_bug477578.js b/netwerk/test/unit/test_bug477578.js new file mode 100644 index 00000000000..afd692acbbd --- /dev/null +++ b/netwerk/test/unit/test_bug477578.js @@ -0,0 +1,42 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; + +const testMethods = [ + ["get", "GET"], + ["post", "POST"], + ["head", "HEAD"], + ["put", "PUT"], + ["delete", "DELETE"], + ["connect", "CONNECT"], + ["options", "OPTIONS"], + ["trace", "TRACE"], + ["track", "TRACK"], + ["copy", "copy"], + ["index", "index"], + ["lock", "lock"], + ["m-post", "m-post"], + ["mkcol", "mkcol"], + ["move", "move"], + ["propfind", "propfind"], + ["proppatch", "proppatch"], + ["unlock", "unlock"], + ["link", "link"], + ["foo", "foo"], + ["foO", "foO"], + ["fOo", "fOo"], + ["Foo", "Foo"] +] + +function run_test() { + var ios = + Cc["@mozilla.org/network/io-service;1"]. + getService(Ci.nsIIOService); + + var chan = ios.newChannel("http://localhost/", null, null) + .QueryInterface(Components.interfaces.nsIHttpChannel); + + for (var i = 0; i < testMethods.length; i++) { + chan.requestMethod = testMethods[i][0]; + do_check_eq(chan.requestMethod, testMethods[i][1]); + } +} diff --git a/netwerk/test/unit/xpcshell.ini b/netwerk/test/unit/xpcshell.ini index b2c032f6936..2282ad8f898 100644 --- a/netwerk/test/unit/xpcshell.ini +++ b/netwerk/test/unit/xpcshell.ini @@ -16,6 +16,7 @@ skip-if = os == "android" [test_bug248970_cookie.js] [test_bug261425.js] [test_bug263127.js] +[test_bug272541.js] [test_bug321706.js] [test_bug331825.js] [test_bug336501.js] @@ -44,6 +45,7 @@ skip-if = os == "android" skip-if = os == "android" [test_bug468594.js] [test_bug470716.js] +[test_bug477578.js] [test_bug479413.js] [test_bug479485.js] [test_bug482601.js] diff --git a/toolkit/locales/en-US/chrome/mozapps/downloads/unknownContentType.properties b/toolkit/locales/en-US/chrome/mozapps/downloads/unknownContentType.properties index 6dc7b82938b..f0aa26851ec 100644 --- a/toolkit/locales/en-US/chrome/mozapps/downloads/unknownContentType.properties +++ b/toolkit/locales/en-US/chrome/mozapps/downloads/unknownContentType.properties @@ -50,8 +50,8 @@ selectDownloadDir=Select Download Folder unknownAccept.label=Save File unknownCancel.label=Cancel fileType=%S file -# LOCALIZATION NOTE (fileSizeWithType): first %S is type, second %S is size, and third %S is unit -fileSizeWithType=%1S (%2S %3S) +# LOCALIZATION NOTE (orderedFileSizeWithType): first %S is type, second %S is size, and third %S is unit +orderedFileSizeWithType=%1$S (%2$S %3$S) # LOCALIZATION NOTE (wpsDefaultOS2): OS/2 only, WPS refers to the Workplace Shell and should probably not be translated wpsDefaultOS2=WPS Default diff --git a/toolkit/mozapps/downloads/nsHelperAppDlg.js b/toolkit/mozapps/downloads/nsHelperAppDlg.js index d88b1208d72..62be13dd997 100644 --- a/toolkit/mozapps/downloads/nsHelperAppDlg.js +++ b/toolkit/mozapps/downloads/nsHelperAppDlg.js @@ -616,7 +616,7 @@ nsUnknownContentTypeDialog.prototype = { let [size, unit] = DownloadUtils. convertByteUnits(this.mLauncher.contentLength); type.value = this.dialogElement("strings") - .getFormattedString("fileSizeWithType", + .getFormattedString("orderedFileSizeWithType", [typeString, size, unit]); } else { diff --git a/widget/src/windows/nsNativeDragTarget.cpp b/widget/src/windows/nsNativeDragTarget.cpp index 80a8a662f4c..2a91e7f9525 100644 --- a/widget/src/windows/nsNativeDragTarget.cpp +++ b/widget/src/windows/nsNativeDragTarget.cpp @@ -280,6 +280,8 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource, // Mask effect coming from function call with effect preferred by the source. mMovePreferred = (preferredEffect & DROPEFFECT_MOVE) != 0; + + nsMemory::Free(tempOutData); } else { mMovePreferred = PR_FALSE; } diff --git a/xpcom/io/nsLocalFileWin.cpp b/xpcom/io/nsLocalFileWin.cpp index 668f3ed78aa..108df6194e0 100644 --- a/xpcom/io/nsLocalFileWin.cpp +++ b/xpcom/io/nsLocalFileWin.cpp @@ -105,7 +105,6 @@ unsigned char *_mbsstr( const unsigned char *str, #endif ILCreateFromPathWPtr nsLocalFile::sILCreateFromPathW = NULL; -ILFreePtr nsLocalFile::sILFree = NULL; SHOpenFolderAndSelectItemsPtr nsLocalFile::sSHOpenFolderAndSelectItems = NULL; PRLibrary *nsLocalFile::sLibShell = NULL; @@ -2739,8 +2738,7 @@ nsLocalFile::RevealUsingShell() { // All of these shell32.dll related pointers should be non NULL // on XP and later. - if (!sLibShell || !sILCreateFromPathW || - !sILFree || !sSHOpenFolderAndSelectItems) { + if (!sLibShell || !sILCreateFromPathW || !sSHOpenFolderAndSelectItems) { return NS_ERROR_FAILURE; } @@ -2757,11 +2755,11 @@ nsLocalFile::RevealUsingShell() } const ITEMIDLIST* selection[] = { dir }; - UINT count = sizeof(selection) / sizeof(ITEMIDLIST); + UINT count = PR_ARRAY_SIZE(selection); //Perform the open of the directory. hr = sSHOpenFolderAndSelectItems(dir, count, selection, 0); - sILFree(dir); + CoTaskMemFree(dir); } else { // Obtain the parent path of the item we are revealing. @@ -2781,18 +2779,18 @@ nsLocalFile::RevealUsingShell() // Set the item in the directory to select to the file we want to reveal. ITEMIDLIST *item = sILCreateFromPathW(mResolvedPath.get()); if (!item) { - sILFree(dir); + CoTaskMemFree(dir); return NS_ERROR_FAILURE; } const ITEMIDLIST* selection[] = { item }; - UINT count = sizeof(selection) / sizeof(ITEMIDLIST); + UINT count = PR_ARRAY_SIZE(selection); //Perform the selection of the file. hr = sSHOpenFolderAndSelectItems(dir, count, selection, 0); - sILFree(dir); - sILFree(item); + CoTaskMemFree(dir); + CoTaskMemFree(item); } if (SUCCEEDED(hr)) { @@ -3106,9 +3104,6 @@ nsLocalFile::GlobalInit() PR_FindFunctionSymbol(sLibShell, "ILCreateFromPathW"); - // ILFree is available in XP and up. - sILFree = (ILFreePtr) PR_FindFunctionSymbol(sLibShell, "ILFree"); - // SHOpenFolderAndSelectItems is available in XP and up. sSHOpenFolderAndSelectItems = (SHOpenFolderAndSelectItemsPtr) PR_FindFunctionSymbol(sLibShell, diff --git a/xpcom/io/nsLocalFileWin.h b/xpcom/io/nsLocalFileWin.h index d95fbf46581..bf2c23a98e3 100644 --- a/xpcom/io/nsLocalFileWin.h +++ b/xpcom/io/nsLocalFileWin.h @@ -64,8 +64,7 @@ DEFINE_OLEGUID(IID_IPersistFile, 0x0000010BL, 0, 0); #include typedef LPITEMIDLIST (WINAPI *ILCreateFromPathWPtr)(PCWSTR); -typedef void (WINAPI *ILFreePtr)(LPITEMIDLIST); -typedef HRESULT (WINAPI *SHOpenFolderAndSelectItemsPtr)(LPCITEMIDLIST, UINT, +typedef HRESULT (WINAPI *SHOpenFolderAndSelectItemsPtr)(PCIDLIST_ABSOLUTE, UINT, PCUITEMID_CHILD_ARRAY, DWORD); @@ -140,7 +139,6 @@ private: nsresult RevealUsingShell(); // Uses newer shell API to reveal the path static ILCreateFromPathWPtr sILCreateFromPathW; - static ILFreePtr sILFree; static SHOpenFolderAndSelectItemsPtr sSHOpenFolderAndSelectItems; static PRLibrary *sLibShell; };