From 74d5ca2e351ac320dbb484bfe32eee284fdafbad Mon Sep 17 00:00:00 2001 From: Brian Hackett Date: Wed, 29 Sep 2010 06:27:34 -0700 Subject: [PATCH 001/115] Improved JM call path, bug 587707. r=lw,dvander --- js/src/jscntxt.cpp | 19 +-- js/src/jscntxt.h | 4 + js/src/jscntxtinlines.h | 43 +++--- js/src/jsfun.cpp | 2 + js/src/jsinterp.cpp | 59 +++++++- js/src/jsinterp.h | 76 ++++++++-- js/src/jsinterpinlines.h | 74 ++++----- js/src/jsiter.cpp | 2 +- js/src/methodjit/BaseAssembler.h | 29 ++-- js/src/methodjit/BytecodeAnalyzer.cpp | 5 + js/src/methodjit/BytecodeAnalyzer.h | 8 +- js/src/methodjit/Compiler.cpp | 191 ++++++++++++++---------- js/src/methodjit/Compiler.h | 20 ++- js/src/methodjit/FrameState.cpp | 43 ++++++ js/src/methodjit/FrameState.h | 6 + js/src/methodjit/InlineFrameAssembler.h | 10 +- js/src/methodjit/InvokeHelpers.cpp | 51 +++---- js/src/methodjit/MethodJIT.cpp | 165 ++++++++------------ js/src/methodjit/MonoIC.cpp | 29 ++-- js/src/methodjit/MonoIC.h | 2 +- js/src/methodjit/NunboxAssembler.h | 8 + js/src/methodjit/PunboxAssembler.h | 5 + js/src/methodjit/StubCalls-inl.h | 20 +-- js/src/methodjit/StubCalls.cpp | 4 +- js/src/methodjit/TrampolineCompiler.cpp | 31 ++-- js/src/methodjit/TrampolineMasmX64.asm | 19 +-- js/src/methodjit/TrampolineSUNWX64.s | 31 ++-- js/src/methodjit/TrampolineSUNWX86.s | 29 ++-- 28 files changed, 561 insertions(+), 424 deletions(-) diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 02a419e7e0fc..01a68827a398 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -434,7 +434,7 @@ void FrameRegsIter::incSlow(JSStackFrame *fp, JSStackFrame *prev) { JS_ASSERT(prev); - JS_ASSERT(curpc == prev->savedpc_); + JS_ASSERT(curpc == curfp->pc(cx, fp)); JS_ASSERT(fp == curseg->getInitialFrame()); /* @@ -2035,16 +2035,10 @@ void JSContext::pushSegmentAndFrame(js::StackSegment *newseg, JSFrameRegs &newregs) { JS_ASSERT(regs != &newregs); - if (hasActiveSegment()) { - JS_ASSERT(regs->fp->savedpc_ == JSStackFrame::sInvalidpc); - regs->fp->savedpc_ = regs->pc; + if (hasActiveSegment()) currentSegment->suspend(regs); - } newseg->setPreviousInContext(currentSegment); currentSegment = newseg; -#ifdef DEBUG - newregs.fp->savedpc_ = JSStackFrame::sInvalidpc; -#endif setCurrentRegs(&newregs); newseg->joinContext(this, newregs.fp); } @@ -2054,7 +2048,6 @@ JSContext::popSegmentAndFrame() { JS_ASSERT(currentSegment->maybeContext() == this); JS_ASSERT(currentSegment->getInitialFrame() == regs->fp); - JS_ASSERT(regs->fp->savedpc_ == JSStackFrame::sInvalidpc); currentSegment->leaveContext(); currentSegment = currentSegment->getPreviousInContext(); if (currentSegment) { @@ -2063,9 +2056,6 @@ JSContext::popSegmentAndFrame() } else { setCurrentRegs(currentSegment->getSuspendedRegs()); currentSegment->resume(); -#ifdef DEBUG - regs->fp->savedpc_ = JSStackFrame::sInvalidpc; -#endif } } else { JS_ASSERT(regs->fp->prev() == NULL); @@ -2078,8 +2068,6 @@ JSContext::saveActiveSegment() { JS_ASSERT(hasActiveSegment()); currentSegment->save(regs); - JS_ASSERT(regs->fp->savedpc_ == JSStackFrame::sInvalidpc); - regs->fp->savedpc_ = regs->pc; setCurrentRegs(NULL); } @@ -2089,9 +2077,6 @@ JSContext::restoreSegment() js::StackSegment *ccs = currentSegment; setCurrentRegs(ccs->getSuspendedRegs()); ccs->restore(); -#ifdef DEBUG - regs->fp->savedpc_ = JSStackFrame::sInvalidpc; -#endif } JSGenerator * diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index fa745a547878..4f869917b772 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -883,6 +883,7 @@ JS_STATIC_ASSERT(StackSpace::CAPACITY_VALS % StackSpace::COMMIT_VALS == 0); */ class FrameRegsIter { + JSContext *cx; StackSegment *curseg; JSStackFrame *curfp; Value *cursp; @@ -2090,6 +2091,9 @@ struct JSContext /* Undoes calls to suspendActiveSegment. */ void restoreSegment(); + /* Get the frame whose prev() is fp, which may be in any segment. */ + inline JSStackFrame *computeNextFrame(JSStackFrame *fp); + /* * Perform a linear search of all frames in all segments in the given context * for the given frame, returning the segment, if found, and null otherwise. diff --git a/js/src/jscntxtinlines.h b/js/src/jscntxtinlines.h index 8cff08e975f7..c5134c05387e 100644 --- a/js/src/jscntxtinlines.h +++ b/js/src/jscntxtinlines.h @@ -71,6 +71,21 @@ JSContext::ensureGeneratorStackSpace() return ok; } +JSStackFrame * +JSContext::computeNextFrame(JSStackFrame *fp) +{ + JSStackFrame *next = NULL; + for (js::StackSegment *ss = currentSegment; ; ss = ss->getPreviousInContext()) { + JSStackFrame *end = ss->getInitialFrame()->prev(); + for (JSStackFrame *f = ss->getCurrentFrame(); f != end; next = f, f = f->prev()) { + if (f == fp) + return next; + } + if (end != ss->getPreviousInContext()->getCurrentFrame()) + next = NULL; + } +} + namespace js { JS_REQUIRES_STACK JS_ALWAYS_INLINE JSFrameRegs * @@ -309,16 +324,10 @@ StackSpace::pushInvokeFrame(JSContext *cx, const CallArgs &args, JS_ASSERT(firstUnused() == args.argv() + args.argc()); JSStackFrame *fp = fg->regs_.fp; - JSStackFrame *prev = cx->maybefp(); - fp->prev_ = prev; + fp->setPrev(cx->regs); if (JS_UNLIKELY(!currentSegment->inContext())) { cx->pushSegmentAndFrame(currentSegment, fg->regs_); } else { -#ifdef DEBUG - fp->savedpc_ = JSStackFrame::sInvalidpc; - JS_ASSERT(prev->savedpc_ == JSStackFrame::sInvalidpc); -#endif - prev->savedpc_ = cx->regs->pc; fg->prevRegs_ = cx->regs; cx->setCurrentRegs(&fg->regs_); } @@ -339,10 +348,8 @@ StackSpace::popInvokeFrame(const InvokeFrameGuard &fg) } else { JS_ASSERT(&fg.regs_ == cx->regs); JS_ASSERT(fp->prev_ == fg.prevRegs_->fp); + JS_ASSERT(fp->prevpc() == fg.prevRegs_->pc); cx->setCurrentRegs(fg.prevRegs_); -#ifdef DEBUG - cx->fp()->savedpc_ = JSStackFrame::sInvalidpc; -#endif } } @@ -384,11 +391,8 @@ StackSpace::pushInlineFrame(JSContext *cx, JSScript *script, JSStackFrame *fp, JS_ASSERT(isCurrentAndActive(cx)); JS_ASSERT(cx->regs == regs && script == fp->script()); - regs->fp->savedpc_ = regs->pc; - fp->prev_ = regs->fp; -#ifdef DEBUG - fp->savedpc_ = JSStackFrame::sInvalidpc; -#endif + fp->setPrev(regs); + regs->fp = fp; regs->pc = script->code; regs->sp = fp->slots() + script->nfixed; @@ -400,17 +404,13 @@ StackSpace::popInlineFrame(JSContext *cx, JSStackFrame *prev, Value *newsp) JS_ASSERT(isCurrentAndActive(cx)); JS_ASSERT(cx->hasActiveSegment()); JS_ASSERT(cx->regs->fp->prev_ == prev); - JS_ASSERT(cx->regs->fp->savedpc_ == JSStackFrame::sInvalidpc); JS_ASSERT(!cx->regs->fp->hasImacropc()); JS_ASSERT(prev->base() <= newsp && newsp <= cx->regs->fp->formalArgsEnd()); JSFrameRegs *regs = cx->regs; + regs->pc = prev->pc(cx, regs->fp); regs->fp = prev; - regs->pc = prev->savedpc_; regs->sp = newsp; -#ifdef DEBUG - prev->savedpc_ = JSStackFrame::sInvalidpc; -#endif } JS_ALWAYS_INLINE Value * @@ -442,6 +442,7 @@ StackSpace::getStackLimit(JSContext *cx) JS_REQUIRES_STACK inline FrameRegsIter::FrameRegsIter(JSContext *cx) + : cx(cx) { curseg = cx->getCurrentSegment(); if (JS_UNLIKELY(!curseg || !curseg->isActive())) { @@ -463,7 +464,7 @@ FrameRegsIter::operator++() if (!prev) return *this; - curpc = prev->savedpc_; + curpc = curfp->pc(cx, fp); if (JS_UNLIKELY(fp == curseg->getInitialFrame())) { incSlow(fp, prev); diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 548eaf4473f5..c31d5d4e0ccf 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -274,6 +274,7 @@ js_PutArgsObject(JSContext *cx, JSStackFrame *fp) } else { JS_ASSERT(!argsobj.getPrivate()); } + fp->clearArgsObj(); } #ifdef JS_TRACER @@ -1157,6 +1158,7 @@ js_PutCallObject(JSContext *cx, JSStackFrame *fp) } callobj.setPrivate(NULL); + fp->clearCallObj(); } JSBool JS_FASTCALL diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 171242f8c2ff..5b78f376f24e 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -93,6 +93,10 @@ #include "jsautooplen.h" +#if defined(JS_METHODJIT) && defined(JS_MONOIC) +#include "methodjit/MonoIC.h" +#endif + using namespace js; using namespace js::gc; @@ -100,10 +104,61 @@ using namespace js::gc; #if !JS_LONE_INTERPRET ^ defined jsinvoke_cpp___ #ifdef DEBUG -jsbytecode *const JSStackFrame::sInvalidpc = (jsbytecode *)0xbeef; JSObject *const JSStackFrame::sInvalidScopeChain = (JSObject *)0xbeef; #endif +jsbytecode * +JSStackFrame::pc(JSContext *cx, JSStackFrame *next) +{ + JS_ASSERT_IF(next, next->prev_ == this); + JS_ASSERT(cx->containingSegment(this) != NULL); + + JSFrameRegs *regs; + if (cx->regs) { + regs = cx->regs; + } else { + StackSegment *segment = cx->getCurrentSegment(); + regs = segment->getSuspendedRegs(); + } + + if (this == regs->fp) + return regs->pc; + + if (!next) + next = cx->computeNextFrame(this); + + if (next->flags_ & JSFRAME_HAS_PREVPC) + return next->prevpc_; + +#if defined(JS_METHODJIT) && defined(JS_MONOIC) + JSScript *script = this->script(); + size_t low = 0; + size_t high = script->jit->nCallICs; + while (high > low + 1) { + /* Could overflow here on a script with 2 billion calls. Oh well. */ + size_t mid = (high + low) / 2; + void *entry = script->callICs[mid].funGuard.executableAddress(); + + /* + * Use >= here as the return address of the call is likely to be + * the start address of the next (possibly IC'ed) operation. + */ + if (entry >= next->ncode_) + high = mid; + else + low = mid; + } + + js::mjit::ic::CallICInfo &callIC = script->callICs[low]; + + JS_ASSERT((uint8*)callIC.funGuard.executableAddress() + callIC.joinPointOffset == next->ncode_); + return callIC.pc; +#else + JS_NOT_REACHED("Unknown PC for frame"); + return NULL; +#endif +} + /* * We can't determine in advance which local variables can live on the stack and * be freed when their dynamic scope ends, and which will be closed over and @@ -670,7 +725,7 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script, JSObject *initialVarObj; if (prev) { JS_ASSERT(chain == &prev->scopeChain()); - frame.fp()->initEvalFrame(script, prev, flags); + frame.fp()->initEvalFrame(script, prev, prev->pc(cx), flags); /* * We want to call |prev->varobj()|, but this requires knowing the diff --git a/js/src/jsinterp.h b/js/src/jsinterp.h index d1c0cb164406..33e645b8b536 100644 --- a/js/src/jsinterp.h +++ b/js/src/jsinterp.h @@ -91,10 +91,22 @@ enum JSFrameFlags /* Lazy frame initialization */ JSFRAME_HAS_IMACRO_PC = 0x8000, /* frame has imacpc value available */ - JSFRAME_HAS_CALL_OBJ = 0x10000, /* frame has a callobj in JSStackFrame::exec */ + JSFRAME_HAS_CALL_OBJ = 0x10000, /* frame has a callobj reachable from scopeChain_ */ JSFRAME_HAS_ARGS_OBJ = 0x20000, /* frame has an argsobj in JSStackFrame::args */ JSFRAME_HAS_HOOK_DATA = 0x40000, /* frame has hookData_ set */ - JSFRAME_HAS_ANNOTATION = 0x80000 /* frame has annotation_ set */ + JSFRAME_HAS_ANNOTATION = 0x80000, /* frame has annotation_ set */ + + /* + * Whether the prevpc_ value is valid. If not set, the ncode_ value is + * valid and prevpc_ can be recovered using it. + */ + JSFRAME_HAS_PREVPC = 0x100000, + + /* + * For use by compiled functions, at function exit indicates whether rval_ + * has been assigned to. Otherwise the return value is carried in registers. + */ + JSFRAME_RVAL_ASSIGNED = 0x200000 }; /* @@ -116,16 +128,16 @@ struct JSStackFrame } args; JSObject *scopeChain_; /* current scope chain */ JSStackFrame *prev_; /* previous cx->regs->fp */ - jsbytecode *savedpc_; /* only valid if cx->fp != this */ + void *ncode_; /* return address for method JIT */ /* Lazily initialized */ - js::Value rval_; /* (TODO bug 595073) return value of the frame */ + js::Value rval_; /* return value of the frame */ + jsbytecode *prevpc_; /* pc of previous frame*/ jsbytecode *imacropc_; /* pc of macro caller */ void *hookData_; /* closure returned by call hook */ void *annotation_; /* perhaps remove with bug 546848 */ /* TODO: remove */ - void *ncode_; /* bug 535912 */ JSObject *blockChain_; /* bug 540675 */ #if JS_BITS_PER_WORD == 32 @@ -195,7 +207,8 @@ struct JSStackFrame inline void initCallFrameLatePrologue(); /* Used for eval. */ - inline void initEvalFrame(JSScript *script, JSStackFrame *prev, uint32 flags); + inline void initEvalFrame(JSScript *script, JSStackFrame *prev, + jsbytecode *prevpc, uint32 flags); inline void initGlobalFrame(JSScript *script, JSObject &chain, uint32 flags); /* Used when activating generators. */ @@ -222,8 +235,26 @@ struct JSStackFrame return prev_; } - void repointGeneratorFrameDown(JSStackFrame *prev) { + void setPrev(JSStackFrame *prev, jsbytecode *prevpc) { + JS_ASSERT(flags_ & JSFRAME_HAS_PREVPC); prev_ = prev; + if (prev) { + prevpc_ = prevpc; + JS_ASSERT_IF(!prev->isDummyFrame() && !prev->hasImacropc(), + uint32(prevpc - prev->script()->code) < prev->script()->length); + } + } + + void setPrev(JSFrameRegs *regs) { + JS_ASSERT(flags_ & JSFRAME_HAS_PREVPC); + if (regs) { + prev_ = regs->fp; + prevpc_ = regs->pc; + JS_ASSERT_IF(!prev_->isDummyFrame() && !prev_->hasImacropc(), + uint32(prevpc_ - prev_->script()->code) < prev_->script()->length); + } else { + prev_ = NULL; + } } /* @@ -249,7 +280,16 @@ struct JSStackFrame * the bytecode being executed for the frame. */ - jsbytecode *pc(JSContext *cx) const; + /* + * Get the frame's current bytecode, assuming |this| is in |cx|. + * next is frame whose prev == this, NULL if not known or if this == cx->fp(). + */ + jsbytecode *pc(JSContext *cx, JSStackFrame *next = NULL); + + jsbytecode *prevpc() { + JS_ASSERT((prev_ != NULL) && (flags_ & JSFRAME_HAS_PREVPC)); + return prevpc_; + } JSScript *script() const { JS_ASSERT(isScriptFrame()); @@ -367,7 +407,8 @@ struct JSStackFrame return hasArgsObj() ? &argsObj() : NULL; } - void setArgsObj(JSObject &obj); + inline void setArgsObj(JSObject &obj); + inline void clearArgsObj(); /* * This value @@ -469,6 +510,7 @@ struct JSStackFrame inline JSObject *maybeCallObj() const; inline void setScopeChainNoCallObj(JSObject &obj); inline void setScopeChainAndCallObj(JSObject &obj); + inline void clearCallObj(); /* Block chain */ @@ -570,12 +612,21 @@ struct JSStackFrame return &rval_; } + void setAssignedReturnValue(const js::Value &v) { + flags_ |= JSFRAME_RVAL_ASSIGNED; + setReturnValue(v); + } + /* Native-code return address */ void *nativeReturnAddress() const { return ncode_; } + void setNativeReturnAddress(void *addr) { + ncode_ = addr; + } + void **addressOfNativeReturnAddress() { return &ncode_; } @@ -717,10 +768,6 @@ struct JSStackFrame return offsetof(JSStackFrame, prev_); } - static size_t offsetOfSavedpc() { - return offsetof(JSStackFrame, savedpc_); - } - static size_t offsetOfReturnValue() { return offsetof(JSStackFrame, rval_); } @@ -763,9 +810,6 @@ struct JSStackFrame void methodjitStaticAsserts(); #ifdef DEBUG - /* Magic value to represent invalid JSStackFrame::savedpc entry. */ - static jsbytecode *const sInvalidpc; - /* Poison scopeChain value set before a frame is flushed. */ static JSObject *const sInvalidScopeChain; #endif diff --git a/js/src/jsinterpinlines.h b/js/src/jsinterpinlines.h index 00bdc0a7b9da..9b81f592c34c 100644 --- a/js/src/jsinterpinlines.h +++ b/js/src/jsinterpinlines.h @@ -50,11 +50,11 @@ JSStackFrame::initCallFrame(JSContext *cx, JSObject &callee, JSFunction *fun, JS_ASSERT(fun == callee.getFunctionPrivate()); /* Initialize stack frame members. */ - flags_ = JSFRAME_FUNCTION | flagsArg; + flags_ = JSFRAME_FUNCTION | JSFRAME_HAS_PREVPC | flagsArg; exec.fun = fun; args.nactual = nactual; /* only need to write if over/under-flow */ scopeChain_ = callee.getParent(); - /* savedpc_, prev_ initialized by push*Frame */ + /* prevpc_, prev_ initialized by push*Frame */ JS_ASSERT(!hasImacropc()); JS_ASSERT(!hasHookData()); rval_.setUndefined(); @@ -66,7 +66,7 @@ JSStackFrame::initCallFrame(JSContext *cx, JSObject &callee, JSFunction *fun, inline void JSStackFrame::initCallFrameCallerHalf(JSContext *cx, JSObject &scopeChain, - uint32 nactual, uint32 flagsArg) + uint32 nactual, uint32 flagsArg) { JS_ASSERT((flagsArg & ~(JSFRAME_CONSTRUCTING | JSFRAME_FUNCTION | @@ -74,9 +74,6 @@ JSStackFrame::initCallFrameCallerHalf(JSContext *cx, JSObject &scopeChain, JSFRAME_UNDERFLOW_ARGS)) == 0); JSFrameRegs *regs = cx->regs; - /* Save caller pc. */ - regs->fp->savedpc_ = regs->pc; - /* Initialize the caller half of the stack frame members. */ flags_ = JSFRAME_FUNCTION | flagsArg; args.nactual = nactual; /* only need to write if over/under-flow */ @@ -99,9 +96,6 @@ JSStackFrame::initCallFrameEarlyPrologue(JSFunction *fun, void *ncode) /* Initialize state that gets set early in a jitted function's prologue. */ exec.fun = fun; ncode_ = ncode; -#ifdef DEBUG - savedpc_ = JSStackFrame::sInvalidpc; -#endif } /* @@ -118,41 +112,43 @@ JSStackFrame::initCallFrameLatePrologue() } inline void -JSStackFrame::initEvalFrame(JSScript *script, JSStackFrame *downFrame, uint32 flagsArg) +JSStackFrame::initEvalFrame(JSScript *script, JSStackFrame *prev, + jsbytecode *prevpc, uint32 flagsArg) { JS_ASSERT(flagsArg & JSFRAME_EVAL); JS_ASSERT((flagsArg & ~(JSFRAME_EVAL | JSFRAME_DEBUGGER)) == 0); - JS_ASSERT(downFrame->flags_ & (JSFRAME_FUNCTION | JSFRAME_GLOBAL)); + JS_ASSERT(prev->flags_ & (JSFRAME_FUNCTION | JSFRAME_GLOBAL)); /* Copy (callee, thisv). */ js::Value *dstvp = (js::Value *)this - 2; - js::Value *srcvp = downFrame->flags_ & (JSFRAME_GLOBAL | JSFRAME_EVAL) - ? (js::Value *)downFrame - 2 - : downFrame->formalArgs() - 2; + js::Value *srcvp = prev->flags_ & (JSFRAME_GLOBAL | JSFRAME_EVAL) + ? (js::Value *)prev - 2 + : prev->formalArgs() - 2; dstvp[0] = srcvp[0]; dstvp[1] = srcvp[1]; - JS_ASSERT_IF(downFrame->flags_ & JSFRAME_FUNCTION, + JS_ASSERT_IF(prev->flags_ & JSFRAME_FUNCTION, dstvp[0].toObject().isFunction()); /* Initialize stack frame members. */ - flags_ = flagsArg | (downFrame->flags_ & (JSFRAME_FUNCTION | - JSFRAME_GLOBAL | - JSFRAME_HAS_CALL_OBJ)); + flags_ = flagsArg | JSFRAME_HAS_PREVPC | + (prev->flags_ & (JSFRAME_FUNCTION | + JSFRAME_GLOBAL | + JSFRAME_HAS_CALL_OBJ)); if (isFunctionFrame()) { - exec = downFrame->exec; + exec = prev->exec; args.script = script; } else { exec.script = script; } - scopeChain_ = &downFrame->scopeChain(); - JS_ASSERT_IF(isFunctionFrame(), &callObj() == &downFrame->callObj()); - /* savedpc initialized by pushExecuteFrame */ - prev_ = downFrame; + scopeChain_ = &prev->scopeChain(); + JS_ASSERT_IF(isFunctionFrame(), &callObj() == &prev->callObj()); + + setPrev(prev, prevpc); JS_ASSERT(!hasImacropc()); JS_ASSERT(!hasHookData()); rval_.setUndefined(); blockChain_ = NULL; - setAnnotation(downFrame->annotation()); + setAnnotation(prev->annotation()); } inline void @@ -166,11 +162,11 @@ JSStackFrame::initGlobalFrame(JSScript *script, JSObject &chain, uint32 flagsArg vp[1].setUndefined(); /* Set after frame pushed using thisObject */ /* Initialize stack frame members. */ - flags_ = flagsArg | JSFRAME_GLOBAL; + flags_ = flagsArg | JSFRAME_GLOBAL | JSFRAME_HAS_PREVPC; exec.script = script; args.script = (JSScript *)0xbad; scopeChain_ = &chain; - /* savedpc initialized by pushExecuteFrame */ + prev_ = NULL; JS_ASSERT(!hasImacropc()); JS_ASSERT(!hasHookData()); @@ -183,8 +179,8 @@ inline void JSStackFrame::initDummyFrame(JSContext *cx, JSObject &chain) { js::PodZero(this); - flags_ = JSFRAME_DUMMY; - prev_ = cx->maybefp(); + flags_ = JSFRAME_DUMMY | JSFRAME_HAS_PREVPC; + setPrev(cx->regs); chain.isGlobal(); setScopeChainNoCallObj(chain); } @@ -288,13 +284,6 @@ JSStackFrame::varobj(JSContext *cx) const return isFunctionFrame() ? callObj() : cx->activeSegment()->getInitialVarObj(); } -inline jsbytecode * -JSStackFrame::pc(JSContext *cx) const -{ - JS_ASSERT(cx->regs && cx->containingSegment(this) != NULL); - return (cx->regs->fp == this) ? cx->regs->pc : savedpc_; -} - inline uintN JSStackFrame::numActualArgs() const { @@ -336,6 +325,14 @@ JSStackFrame::setArgsObj(JSObject &obj) flags_ |= JSFRAME_HAS_ARGS_OBJ; } +inline void +JSStackFrame::clearArgsObj() +{ + JS_ASSERT(hasArgsObj()); + args.nactual = args.obj->getArgsInitialLength(); + flags_ ^= JSFRAME_HAS_ARGS_OBJ; +} + inline void JSStackFrame::setScopeChainNoCallObj(JSObject &obj) { @@ -360,6 +357,13 @@ JSStackFrame::setScopeChainAndCallObj(JSObject &obj) flags_ |= JSFRAME_HAS_CALL_OBJ; } +inline void +JSStackFrame::clearCallObj() +{ + JS_ASSERT(hasCallObj()); + flags_ ^= JSFRAME_HAS_CALL_OBJ; +} + inline JSObject & JSStackFrame::callObj() const { diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index 033fbddf9b50..33e569b508b6 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -1271,7 +1271,7 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, JSObject *obj, /* Copy frame onto the stack. */ stackfp->stealFrameAndSlots(stackvp, genfp, genvp, gen->regs.sp); - stackfp->repointGeneratorFrameDown(cx->maybefp()); + stackfp->setPrev(cx->regs); stackfp->unsetFloatingGenerator(); RebaseRegsFromTo(&gen->regs, genfp, stackfp); MUST_FLOW_THROUGH("restore"); diff --git a/js/src/methodjit/BaseAssembler.h b/js/src/methodjit/BaseAssembler.h index b7f3d12baea7..c6d5f98f8767 100644 --- a/js/src/methodjit/BaseAssembler.h +++ b/js/src/methodjit/BaseAssembler.h @@ -310,7 +310,10 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::ARMRegiste /* regs->sp = sp */ storePtr(ClobberInCall, - FrameAddress(offsetof(VMFrame, regs) + offsetof(JSFrameRegs, sp))); + FrameAddress(offsetof(VMFrame, regs.sp))); + + /* regs->fp = fp */ + storePtr(JSFrameReg, FrameAddress(offsetof(VMFrame, regs.fp))); } void setupVMFrame() { @@ -332,23 +335,6 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::ARMRegiste return MacroAssembler::call(reg); } - void restoreReturnAddress() - { -#ifndef JS_CPU_ARM - /* X86 and X64's "ret" instruction expects a return address on the stack. */ - push(Address(JSFrameReg, JSStackFrame::offsetOfncode())); -#else - /* ARM returns either using its link register (LR) or directly from the stack, but masm.ret() - * always emits a return to LR. */ - load32(Address(JSFrameReg, JSStackFrame::offsetOfncode()), JSC::ARMRegisters::lr); -#endif - } - - void saveReturnAddress(RegisterID reg) - { - storePtr(reg, Address(JSFrameReg, JSStackFrame::offsetOfncode())); - } - void finalize(uint8 *ncode) { JSC::JITCode jc(ncode, size()); JSC::CodeBlock cb(jc); @@ -367,6 +353,13 @@ static const JSC::MacroAssembler::RegisterID JSReturnReg_Type = BaseAssembler::J static const JSC::MacroAssembler::RegisterID JSReturnReg_Data = BaseAssembler::JSReturnReg_Data; static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = BaseAssembler::JSParamReg_Argc; +struct FrameFlagsAddress : JSC::MacroAssembler::Address +{ + FrameFlagsAddress() + : Address(JSFrameReg, JSStackFrame::offsetOfFlags()) + {} +}; + } /* namespace mjit */ } /* namespace js */ diff --git a/js/src/methodjit/BytecodeAnalyzer.cpp b/js/src/methodjit/BytecodeAnalyzer.cpp index 84e0262d7d2e..d5586ae243e6 100644 --- a/js/src/methodjit/BytecodeAnalyzer.cpp +++ b/js/src/methodjit/BytecodeAnalyzer.cpp @@ -111,6 +111,11 @@ BytecodeAnalyzer::analyze(uint32 index) case JSOP_TRAP: return false; + case JSOP_SETRVAL: + case JSOP_POPV: + usesRval = true; + break; + case JSOP_DEFAULT: case JSOP_GOTO: offs = (pc + JSOP_GOTO_LENGTH) - script->code; diff --git a/js/src/methodjit/BytecodeAnalyzer.h b/js/src/methodjit/BytecodeAnalyzer.h index 3bc219680d39..fa672a240900 100644 --- a/js/src/methodjit/BytecodeAnalyzer.h +++ b/js/src/methodjit/BytecodeAnalyzer.h @@ -65,10 +65,14 @@ namespace js OpcodeStatus *ops; Vector doList; + /* Whether there are POPV/SETRVAL bytecodes which can write to the frame's rval. */ + bool usesRval; + public: BytecodeAnalyzer(JSContext *cx, JSScript *script) : cx(cx), script(script), ops(NULL), - doList(ContextAllocPolicy(cx)) + doList(ContextAllocPolicy(cx)), + usesRval(false) { } ~BytecodeAnalyzer(); @@ -78,6 +82,8 @@ namespace js public: + bool usesReturnValue() const { return usesRval; } + inline const OpcodeStatus & operator [](uint32 offs) const { JS_ASSERT(offs < script->length); return ops[offs]; diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index 3f071cc559b4..7b57e7973847 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -83,6 +83,7 @@ mjit::Compiler::Compiler(JSContext *cx, JSScript *script, JSFunction *fun, JSObj #if defined JS_POLYIC pics(ContextAllocPolicy(cx)), #endif + callPatches(ContextAllocPolicy(cx)), callSites(ContextAllocPolicy(cx)), doubleList(ContextAllocPolicy(cx)), escapingList(ContextAllocPolicy(cx)), @@ -178,27 +179,11 @@ mjit::TryCompile(JSContext *cx, JSScript *script, JSFunction *fun, JSObject *sco return status; } -JSC::MacroAssembler::RegisterID -mjit::Compiler::takeHWReturnAddress(Assembler &masm) -{ -#ifndef JS_CPU_ARM - JS_STATIC_ASSERT(JSParamReg_Argc != Registers::ReturnReg); - masm.pop(Registers::ReturnReg); - return Registers::ReturnReg; -#else - return JSC::ARMRegisters::lr; -#endif -} - CompileStatus mjit::Compiler::generatePrologue() { invokeLabel = masm.label(); - RegisterID retAddr = takeHWReturnAddress(masm); - restoreFrameRegs(masm); - masm.saveReturnAddress(retAddr); - /* * If there is no function, then this can only be called via JaegerShot(), * which expects an existing frame to be initialized like the interpreter. @@ -211,17 +196,11 @@ mjit::Compiler::generatePrologue() * either argc >= nargs or the arity check has corrected the frame. */ invokeLabel = masm.label(); - RegisterID retAddr = takeHWReturnAddress(masm); - masm.saveReturnAddress(retAddr); -#ifdef DEBUG - masm.storePtr(ImmPtr(JSStackFrame::sInvalidpc), Address(JSFrameReg, JSStackFrame::offsetOfSavedpc())); -#endif Label fastPath = masm.label(); - /* Store these early on so slow paths can access them. */ + /* Store this early on so slow paths can access it. */ masm.storePtr(ImmPtr(fun), Address(JSFrameReg, JSStackFrame::offsetOfExec())); - masm.storePtr(JSFrameReg, FrameAddress(offsetof(VMFrame, regs.fp))); { /* @@ -231,11 +210,6 @@ mjit::Compiler::generatePrologue() * This loops back to entry point #2. */ arityLabel = stubcc.masm.label(); - RegisterID retAddr = takeHWReturnAddress(stubcc.masm); - stubcc.masm.saveReturnAddress(retAddr); -#ifdef DEBUG - stubcc.masm.storePtr(ImmPtr(JSStackFrame::sInvalidpc), Address(JSFrameReg, JSStackFrame::offsetOfSavedpc())); -#endif Jump argMatch = stubcc.masm.branch32(Assembler::Equal, JSParamReg_Argc, Imm32(fun->nargs)); stubcc.crossJump(argMatch, fastPath); @@ -440,10 +414,10 @@ mjit::Compiler::finishThisUp() script->callICs[i].slowPathStart = stubCode.locationOf(callICs[i].slowPathStart); /* Compute the hot call offset. */ - uint32 offset = fullCode.locationOf(callICs[i].hotCall) - + uint32 offset = fullCode.locationOf(callICs[i].hotJump) - fullCode.locationOf(callICs[i].funGuard); - script->callICs[i].hotCallOffset = offset; - JS_ASSERT(script->callICs[i].hotCallOffset == offset); + script->callICs[i].hotJumpOffset = offset; + JS_ASSERT(script->callICs[i].hotJumpOffset == offset); /* Compute the join point offset. */ offset = fullCode.locationOf(callICs[i].joinPoint) - @@ -483,6 +457,24 @@ mjit::Compiler::finishThisUp() } #endif /* JS_MONOIC */ + for (size_t i = 0; i < callPatches.length(); i++) { + void *joinPoint = fullCode.locationOf(callPatches[i].joinPoint).executableAddress(); + + /* Patch the write of ncode in the hot path. */ + JSC::CodeLocationDataLabelPtr fastNcode = + fullCode.locationOf(callPatches[i].fastNcodePatch); + JSC::RepatchBuffer fastRepatch((uint8*)fastNcode.executableAddress() - 32, 64, false); + fastRepatch.repatch(fastNcode, joinPoint); + + /* Patch the write of ncode in the slow path. */ + if (callPatches[i].hasSlowNcode) { + JSC::CodeLocationDataLabelPtr slowNcode = + stubCode.locationOf(callPatches[i].slowNcodePatch); + JSC::RepatchBuffer slowRepatch((uint8*)slowNcode.executableAddress() - 32, 64, false); + slowRepatch.repatch(slowNcode, joinPoint); + } + } + #if defined JS_POLYIC script->jit->nPICs = pics.length(); if (pics.length()) { @@ -666,6 +658,12 @@ mjit::Compiler::generateMethod() BEGIN_CASE(JSOP_POPV) BEGIN_CASE(JSOP_SETRVAL) { + RegisterID reg = frame.allocReg(); + masm.load32(FrameFlagsAddress(), reg); + masm.or32(Imm32(JSFRAME_RVAL_ASSIGNED), reg); + masm.store32(reg, FrameFlagsAddress()); + frame.freeReg(reg); + FrameEntry *fe = frame.peek(-1); frame.storeTo(fe, Address(JSFrameReg, JSStackFrame::offsetOfReturnValue()), true); frame.pop(); @@ -673,12 +671,7 @@ mjit::Compiler::generateMethod() END_CASE(JSOP_POPV) BEGIN_CASE(JSOP_RETURN) - { - FrameEntry *fe = frame.peek(-1); - frame.storeTo(fe, Address(JSFrameReg, JSStackFrame::offsetOfReturnValue()), true); - frame.pop(); - emitReturn(); - } + emitReturn(frame.peek(-1)); END_CASE(JSOP_RETURN) BEGIN_CASE(JSOP_GOTO) @@ -1490,7 +1483,7 @@ mjit::Compiler::generateMethod() END_CASE(JSOP_DEFLOCALFUN) BEGIN_CASE(JSOP_RETRVAL) - emitReturn(); + emitReturn(NULL); END_CASE(JSOP_RETRVAL) BEGIN_CASE(JSOP_GETGNAME) @@ -1550,7 +1543,7 @@ mjit::Compiler::generateMethod() BEGIN_CASE(JSOP_STOP) /* Safe point! */ - emitReturn(); + emitReturn(NULL); goto done; END_CASE(JSOP_STOP) @@ -1805,21 +1798,39 @@ mjit::Compiler::jsop_getglobal(uint32 index) } void -mjit::Compiler::emitReturn() +mjit::Compiler::emitFinalReturn(Assembler &masm) +{ + masm.loadPtr(Address(JSFrameReg, JSStackFrame::offsetOfncode()), Registers::ReturnReg); + masm.jump(Registers::ReturnReg); +} + +void +mjit::Compiler::loadReturnValue(Assembler &masm) { /* - * if (!f.inlineCallCount) - * return; + * Load a return value from POPV or SETRVAL into the return registers, + * otherwise return undefined. */ - Jump noInlineCalls = masm.branchPtr(Assembler::Equal, - FrameAddress(offsetof(VMFrame, entryFp)), - JSFrameReg); - stubcc.linkExit(noInlineCalls, Uses(frame.frameDepth())); - stubcc.masm.restoreReturnAddress(); - stubcc.masm.ret(); + masm.loadValueAsComponents(UndefinedValue(), JSReturnReg_Type, JSReturnReg_Data); + if (analysis.usesReturnValue()) { + Jump rvalClear = masm.branchTest32(Assembler::Zero, + FrameFlagsAddress(), + Imm32(JSFRAME_RVAL_ASSIGNED)); + Address rvalAddress(JSFrameReg, JSStackFrame::offsetOfReturnValue()); + masm.loadValueAsComponents(rvalAddress, + JSReturnReg_Type, JSReturnReg_Data); + rvalClear.linkTo(masm.label(), &masm); + } +} +void +mjit::Compiler::emitReturn(FrameEntry *fe) +{ JS_ASSERT_IF(!fun, JSOp(*PC) == JSOP_STOP); + /* Only the top of the stack can be returned. */ + JS_ASSERT_IF(fe, fe == frame.peek(-1)); + /* * If there's a function object, deal with the fact that it can escape. * Note that after we've placed the call object, all tracked state can @@ -1832,42 +1843,44 @@ mjit::Compiler::emitReturn() if (fun) { if (fun->isHeavyweight()) { /* There will always be a call object. */ - prepareStubCall(Uses(0)); - stubCall(stubs::PutCallObject); - frame.discardFrame(); + prepareStubCall(Uses(fe ? 1 : 0)); + stubCall(stubs::PutActivationObjects); + + if (fe) { + masm.loadValueAsComponents(frame.addressOf(fe), + JSReturnReg_Type, JSReturnReg_Data); + emitFinalReturn(masm); + frame.discardFrame(); + return; + } } else { /* if (hasCallObj() || hasArgsObj()) stubs::PutActivationObjects() */ Jump putObjs = masm.branchTest32(Assembler::NonZero, Address(JSFrameReg, JSStackFrame::offsetOfFlags()), Imm32(JSFRAME_HAS_CALL_OBJ | JSFRAME_HAS_ARGS_OBJ)); stubcc.linkExit(putObjs, Uses(frame.frameDepth())); - frame.discardFrame(); stubcc.leave(); stubcc.call(stubs::PutActivationObjects); - stubcc.rejoin(Changes(0)); + + if (fe) { + stubcc.masm.loadValueAsComponents(frame.addressOf(fe), + JSReturnReg_Type, JSReturnReg_Data); + } else { + loadReturnValue(stubcc.masm); + } + + emitFinalReturn(stubcc.masm); } } - /* - * r = fp->prev - * f.fp = r - */ - masm.loadPtr(Address(JSFrameReg, JSStackFrame::offsetOfPrev()), Registers::ReturnReg); - masm.storePtr(Registers::ReturnReg, FrameAddress(offsetof(VMFrame, regs.fp))); + if (fe) + frame.storeTo(fe, JSReturnReg_Data, JSReturnReg_Type, Registers::ReturnReg); + else + loadReturnValue(masm); - JS_STATIC_ASSERT(Registers::ReturnReg != JSReturnReg_Data); - JS_STATIC_ASSERT(Registers::ReturnReg != JSReturnReg_Type); - - Address rval(JSFrameReg, JSStackFrame::offsetOfReturnValue()); - masm.loadValueAsComponents(rval, JSReturnReg_Type, JSReturnReg_Data); - masm.restoreReturnAddress(); - masm.move(Registers::ReturnReg, JSFrameReg); -#ifdef DEBUG - masm.storePtr(ImmPtr(JSStackFrame::sInvalidpc), - Address(JSFrameReg, JSStackFrame::offsetOfSavedpc())); -#endif - masm.ret(); + emitFinalReturn(masm); + frame.discardFrame(); } void @@ -1955,6 +1968,9 @@ mjit::Compiler::emitPrimitiveTestForNew(uint32 argc) void mjit::Compiler::emitUncachedCall(uint32 argc, bool callingNew) { + CallPatchInfo callPatch; + callPatch.hasSlowNcode = false; + RegisterID r0 = Registers::ReturnReg; VoidPtrStubUInt32 stub = callingNew ? stubs::UncachedNew : stubs::UncachedCall; @@ -1966,12 +1982,21 @@ mjit::Compiler::emitUncachedCall(uint32 argc, bool callingNew) Jump notCompiled = masm.branchTestPtr(Assembler::Zero, r0, r0); - masm.call(r0); + masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.fp)), JSFrameReg); + callPatch.fastNcodePatch = + masm.storePtrWithPatch(ImmPtr(NULL), + Address(JSFrameReg, JSStackFrame::offsetOfncode())); + + masm.jump(r0); + #if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64) masm.callLabel = masm.label(); #endif ADD_CALLSITE(false); + callPatch.joinPoint = masm.label(); + masm.loadPtr(Address(JSFrameReg, JSStackFrame::offsetOfPrev()), JSFrameReg); + if (callingNew) emitPrimitiveTestForNew(argc); @@ -1982,6 +2007,7 @@ mjit::Compiler::emitUncachedCall(uint32 argc, bool callingNew) stubcc.linkExitDirect(notCompiled, stubcc.masm.label()); stubcc.rejoin(Changes(0)); + callPatches.append(callPatch); } /* See MonoIC.cpp, CallCompiler for more information on call ICs. */ @@ -2006,6 +2032,8 @@ mjit::Compiler::inlineCallHelper(uint32 argc, bool callingNew) CallGenInfo callIC(argc); uint32 callICIndex = callICs.length(); + CallPatchInfo callPatch; + /* * Save constant |this| to optimize thisv stores for common call cases * like CALL[LOCAL, GLOBAL, ARG] which push NULL. @@ -2062,7 +2090,6 @@ mjit::Compiler::inlineCallHelper(uint32 argc, bool callingNew) Jump j = masm.branchPtrWithPatch(Assembler::NotEqual, dataReg, callIC.funGuard); callIC.funJump = j; - Jump oolCallDone; Jump rejoin1, rejoin2; { stubcc.linkExitDirect(j, stubcc.masm.label()); @@ -2130,8 +2157,11 @@ mjit::Compiler::inlineCallHelper(uint32 argc, bool callingNew) Registers::ReturnReg); stubcc.masm.move(Imm32(argc), JSParamReg_Argc); stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.fp)), JSFrameReg); - stubcc.masm.call(Registers::ReturnReg); - oolCallDone = stubcc.masm.jump(); + callPatch.hasSlowNcode = true; + callPatch.slowNcodePatch = + stubcc.masm.storePtrWithPatch(ImmPtr(NULL), + Address(JSFrameReg, JSStackFrame::offsetOfncode())); + stubcc.masm.jump(Registers::ReturnReg); /* Catch-all case, for natives this will turn into a MIC. */ if (notObjectJump.isSet()) @@ -2163,12 +2193,11 @@ mjit::Compiler::inlineCallHelper(uint32 argc, bool callingNew) flags |= JSFRAME_CONSTRUCTING; InlineFrameAssembler inlFrame(masm, callIC, flags); - inlFrame.assemble(); + callPatch.fastNcodePatch = inlFrame.assemble(NULL); - callIC.hotCall = masm.call(); - stubcc.crossJump(oolCallDone, masm.label()); - - callIC.joinPoint = masm.label(); + callIC.hotJump = masm.jump(); + callIC.joinPoint = callPatch.joinPoint = masm.label(); + masm.loadPtr(Address(JSFrameReg, JSStackFrame::offsetOfPrev()), JSFrameReg); /* * Functions invoked with |new| can return primitive values. @@ -2188,6 +2217,7 @@ mjit::Compiler::inlineCallHelper(uint32 argc, bool callingNew) stubcc.rejoin(Changes(0)); callICs.append(callIC); + callPatches.append(callPatch); #else emitUncachedCall(argc, callingNew); #endif @@ -2739,6 +2769,7 @@ mjit::Compiler::jsop_callprop_str(JSAtom *atom) /* Force into a register because getprop won't expect a constant. */ RegisterID reg = frame.allocReg(); + masm.move(ImmPtr(obj), reg); frame.pushTypedPayload(JSVAL_TYPE_OBJECT, reg); diff --git a/js/src/methodjit/Compiler.h b/js/src/methodjit/Compiler.h index f543abb83f61..03bcb3695bb1 100644 --- a/js/src/methodjit/Compiler.h +++ b/js/src/methodjit/Compiler.h @@ -120,7 +120,7 @@ class Compiler uint32 argc; DataLabelPtr funGuard; Jump funJump; - Call hotCall; + Jump hotJump; Call oolCall; Label joinPoint; Label slowJoinPoint; @@ -135,6 +135,17 @@ class Compiler private: #endif + /* + * Writes of call return addresses which needs to be delayed until the final + * absolute address of the join point is known. + */ + struct CallPatchInfo { + Label joinPoint; + DataLabelPtr fastNcodePatch; + DataLabelPtr slowNcodePatch; + bool hasSlowNcode; + }; + #if defined JS_POLYIC struct PICGenInfo { PICGenInfo(ic::PICInfo::Kind kind) : kind(kind) @@ -215,6 +226,7 @@ class Compiler #if defined JS_POLYIC js::Vector pics; #endif + js::Vector callPatches; js::Vector callSites; js::Vector doubleList; js::Vector escapingList; @@ -253,8 +265,6 @@ class Compiler void addCallSite(uint32 id, bool stub); /* Emitting helpers. */ - RegisterID takeHWReturnAddress(Assembler &masm); - void restoreReturnAddress(Assembler &masm); void restoreFrameRegs(Assembler &masm); void emitStubCmpOp(BoolStub stub, jsbytecode *target, JSOp fused); void iter(uintN flags); @@ -271,7 +281,9 @@ class Compiler void jsop_getprop_slow(); void jsop_getarg(uint32 index); void jsop_this(); - void emitReturn(); + void emitReturn(FrameEntry *fe); + void emitFinalReturn(Assembler &masm); + void loadReturnValue(Assembler &masm); void dispatchCall(VoidPtrStubUInt32 stub, uint32 argc); void interruptCheckHelper(); void emitUncachedCall(uint32 argc, bool callingNew); diff --git a/js/src/methodjit/FrameState.cpp b/js/src/methodjit/FrameState.cpp index 5c965648f9d6..ff34ecb31d83 100644 --- a/js/src/methodjit/FrameState.cpp +++ b/js/src/methodjit/FrameState.cpp @@ -327,6 +327,49 @@ FrameState::storeTo(FrameEntry *fe, Address address, bool popped) #endif } +void FrameState::storeTo(FrameEntry *fe, RegisterID dataReg, RegisterID typeReg, RegisterID tempReg) +{ + JS_ASSERT(dataReg != typeReg && dataReg != tempReg && typeReg != tempReg); + + if (fe->isConstant()) { + masm.loadValueAsComponents(fe->getValue(), typeReg, dataReg); + return; + } + + if (fe->isCopy()) + fe = fe->copyOf(); + + if (fe->isTypeKnown()) { + RegisterID data = tempRegForData(fe); + if (data != dataReg) + masm.move(data, dataReg); + masm.move(ImmType(fe->getKnownType()), typeReg); + return; + } + + RegisterID data = tempRegForData(fe); + RegisterID type = tempRegForType(fe); + if (data == typeReg && type == dataReg) { + masm.move(type, tempReg); + masm.move(data, dataReg); + masm.move(tempReg, typeReg); + } else if (data != dataReg) { + if (type == typeReg) { + masm.move(data, dataReg); + } else if (type != dataReg) { + masm.move(data, dataReg); + if (type != typeReg) + masm.move(type, typeReg); + } else { + JS_ASSERT(data != typeReg); + masm.move(type, typeReg); + masm.move(data, dataReg); + } + } else if (type != typeReg) { + masm.move(type, typeReg); + } +} + #ifdef DEBUG void FrameState::assertValidRegisterState() const diff --git a/js/src/methodjit/FrameState.h b/js/src/methodjit/FrameState.h index c316cc4d0556..1fbd60fd0658 100644 --- a/js/src/methodjit/FrameState.h +++ b/js/src/methodjit/FrameState.h @@ -586,6 +586,12 @@ class FrameState */ void storeTo(FrameEntry *fe, Address address, bool popHint = false); + /* + * Fully stores a FrameEntry into two arbitrary registers. tempReg may be + * used as a temporary. + */ + void storeTo(FrameEntry *fe, RegisterID dataReg, RegisterID typeReg, RegisterID tempReg); + /* * Stores the top stack slot back to a slot. */ diff --git a/js/src/methodjit/InlineFrameAssembler.h b/js/src/methodjit/InlineFrameAssembler.h index 4fcf6c7d2483..833d3a40d689 100644 --- a/js/src/methodjit/InlineFrameAssembler.h +++ b/js/src/methodjit/InlineFrameAssembler.h @@ -71,6 +71,7 @@ class InlineFrameAssembler { typedef JSC::MacroAssembler::Address Address; typedef JSC::MacroAssembler::Imm32 Imm32; typedef JSC::MacroAssembler::ImmPtr ImmPtr; + typedef JSC::MacroAssembler::DataLabelPtr DataLabelPtr; Assembler &masm; uint32 frameDepth; // script->nfixed + stack depth at caller call site @@ -105,24 +106,27 @@ class InlineFrameAssembler { tempRegs.takeReg(funObjReg); } - inline void assemble() + DataLabelPtr assemble(void *ncode) { JS_ASSERT((flags & ~JSFRAME_CONSTRUCTING) == 0); RegisterID t0 = tempRegs.takeAnyReg(); - masm.storePtr(ImmPtr(pc), Address(JSFrameReg, JSStackFrame::offsetOfSavedpc())); - AdjustedFrame adj(sizeof(JSStackFrame) + frameDepth * sizeof(Value)); masm.store32(Imm32(JSFRAME_FUNCTION | flags), adj.addrOf(JSStackFrame::offsetOfFlags())); masm.loadPtr(Address(funObjReg, offsetof(JSObject, parent)), t0); masm.storePtr(t0, adj.addrOf(JSStackFrame::offsetOfScopeChain())); masm.storePtr(JSFrameReg, adj.addrOf(JSStackFrame::offsetOfPrev())); + DataLabelPtr ncodePatch = + masm.storePtrWithPatch(ImmPtr(ncode), adj.addrOf(JSStackFrame::offsetOfncode())); + /* Adjust JSFrameReg. Callee fills in the rest. */ masm.addPtr(Imm32(sizeof(JSStackFrame) + sizeof(Value) * frameDepth), JSFrameReg); tempRegs.putReg(t0); + + return ncodePatch; } }; diff --git a/js/src/methodjit/InvokeHelpers.cpp b/js/src/methodjit/InvokeHelpers.cpp index 947e77ff61e2..4a08ac26521d 100644 --- a/js/src/methodjit/InvokeHelpers.cpp +++ b/js/src/methodjit/InvokeHelpers.cpp @@ -65,6 +65,7 @@ #include "jsobjinlines.h" #include "jscntxtinlines.h" #include "jsatominlines.h" +#include "StubCalls-inl.h" #include "jsautooplen.h" @@ -72,19 +73,8 @@ using namespace js; using namespace js::mjit; using namespace JSC; -#define THROW() \ - do { \ - void *ptr = JS_FUNC_TO_DATA_PTR(void *, JaegerThrowpoline); \ - *f.returnAddressLocation() = ptr; \ - return; \ - } while (0) - -#define THROWV(v) \ - do { \ - void *ptr = JS_FUNC_TO_DATA_PTR(void *, JaegerThrowpoline); \ - *f.returnAddressLocation() = ptr; \ - return v; \ - } while (0) +static bool +InlineReturn(VMFrame &f, JSBool ok, JSBool popFrame = JS_TRUE); static jsbytecode * FindExceptionHandler(JSContext *cx) @@ -179,8 +169,16 @@ top: return NULL; } +/* + * Clean up a frame and return. popFrame indicates whether to additionally pop + * the frame and store the return value on the caller's stack. The frame will + * normally be popped by the caller on return from a call into JIT code, + * so must be popped here when that caller code will not execute. This can be + * either because of a call into an un-JITable script, or because the call is + * throwing an exception. + */ static bool -InlineReturn(VMFrame &f, JSBool ok) +InlineReturn(VMFrame &f, JSBool ok, JSBool popFrame) { JSContext *cx = f.cx; JSStackFrame *fp = f.regs.fp; @@ -213,9 +211,11 @@ InlineReturn(VMFrame &f, JSBool ok) if (fp->isConstructing() && fp->returnValue().isPrimitive()) fp->setReturnValue(fp->thisValue()); - Value *newsp = fp->actualArgs() - 1; - newsp[-1] = fp->returnValue(); - cx->stack().popInlineFrame(cx, fp->prev(), newsp); + if (popFrame) { + Value *newsp = fp->actualArgs() - 1; + newsp[-1] = fp->returnValue(); + cx->stack().popInlineFrame(cx, fp->prev(), newsp); + } return ok; } @@ -317,10 +317,11 @@ stubs::FixupArity(VMFrame &f, uint32 nactual) void *ncode = oldfp->nativeReturnAddress(); /* Pop the inline frame. */ - RemovePartialFrame(cx, oldfp); + f.fp() = oldfp->prev(); + f.regs.sp = (Value*) oldfp; /* Reserve enough space for a callee frame. */ - JSStackFrame *newfp = cx->stack().getInlineFrameWithinLimit(cx, cx->regs->sp, nactual, + JSStackFrame *newfp = cx->stack().getInlineFrameWithinLimit(cx, (Value*) oldfp, nactual, fun, fun->script(), &flags, f.entryFp, &f.stackLimit); if (!newfp) @@ -356,11 +357,10 @@ stubs::CompileFunction(VMFrame &f, uint32 nactual) /* * FixupArity/RemovePartialFrame expect to be called after the early - * prologue. Pass null for ncode: either we will jump into jit code, which - * will set ncode, or we will jump into js::Interpret, which does not care - * about ncode. + * prologue. Pass the existing value for ncode, it has already been set + * by the jit code calling into this stub. */ - fp->initCallFrameEarlyPrologue(fun, NULL); + fp->initCallFrameEarlyPrologue(fun, fp->nativeReturnAddress()); /* Empty script does nothing. */ if (script->isEmpty()) { @@ -897,11 +897,12 @@ RunTracer(VMFrame &f) if (op == JSOP_RETURN && !entryFrame->isBailedAtReturn()) entryFrame->setReturnValue(f.regs.sp[-1]); - /* Don't pop the frame if it's maybe owned by an Invoke. */ + /* Cleanup activation objects on the frame unless it's owned by an Invoke. */ if (f.fp() != f.entryFp) { - if (!InlineReturn(f, JS_TRUE)) + if (!InlineReturn(f, JS_TRUE, JS_FALSE)) THROWV(NULL); } + void *retPtr = JS_FUNC_TO_DATA_PTR(void *, InjectJaegerReturn); *f.returnAddressLocation() = retPtr; return NULL; diff --git a/js/src/methodjit/MethodJIT.cpp b/js/src/methodjit/MethodJIT.cpp index 52d62dfa8178..bca47771b46c 100644 --- a/js/src/methodjit/MethodJIT.cpp +++ b/js/src/methodjit/MethodJIT.cpp @@ -61,14 +61,14 @@ JSStackFrame::methodjitStaticAsserts() #if defined(JS_CPU_X86) JS_STATIC_ASSERT(offsetof(JSStackFrame, rval_) == 0x18); JS_STATIC_ASSERT(offsetof(JSStackFrame, rval_) + 4 == 0x1C); - JS_STATIC_ASSERT(offsetof(JSStackFrame, ncode_) == 0x2C); + JS_STATIC_ASSERT(offsetof(JSStackFrame, ncode_) == 0x14); /* ARM uses decimal literals. */ JS_STATIC_ASSERT(offsetof(JSStackFrame, rval_) == 24); JS_STATIC_ASSERT(offsetof(JSStackFrame, rval_) + 4 == 28); - JS_STATIC_ASSERT(offsetof(JSStackFrame, ncode_) == 44); + JS_STATIC_ASSERT(offsetof(JSStackFrame, ncode_) == 20); #elif defined(JS_CPU_X64) JS_STATIC_ASSERT(offsetof(JSStackFrame, rval_) == 0x30); - JS_STATIC_ASSERT(offsetof(JSStackFrame, ncode_) == 0x50); + JS_STATIC_ASSERT(offsetof(JSStackFrame, ncode_) == 0x28); #endif } @@ -76,13 +76,11 @@ JSStackFrame::methodjitStaticAsserts() * Explanation of VMFrame activation and various helper thunks below. * * JaegerTrampoline - Executes a method JIT-compiled JSFunction. This function - * creates a VMFrame on the machine stack and calls into JIT'd code. The JIT'd - * code will eventually return to the VMFrame. + * creates a VMFrame on the machine stack and jumps into JIT'd code. The JIT'd + * code will eventually jump back to the VMFrame. * * - Called from C++ function EnterMethodJIT. - * - Parameters: cx, fp, code, stackLimit, safePoint - * - Notes: safePoint is used in combination with SafePointTrampoline, - * explained further down. + * - Parameters: cx, fp, code, stackLimit * * JaegerThrowpoline - Calls into an exception handler from JIT'd code, and if a * scripted exception handler is not found, unwinds the VMFrame and returns @@ -100,19 +98,6 @@ JSStackFrame::methodjitStaticAsserts() * at. Because the jit-code ABI conditions are satisfied, we can just jump to * that point. * - * - * SafePointTrampoline - Inline script calls link their return addresses through - * JSStackFrame::ncode. This includes the return address that unwinds back - * to JaegerTrampoline. However, the tracer integration code often wants to - * enter a method JIT'd function at an arbitrary safe point. Safe points - * do not have the return address linking code that the method prologue has. - * SafePointTrampoline is a thunk which correctly links the initial return - * address. It is used in JaegerShotAtSafePoint, and passed as the "script - * code" parameter. Using the "safePoint" parameter to JaegerTrampoline, it - * correctly jumps to the intended point in the method. - * - * - Used by JaegerTrampoline() - * * InjectJaegerReturn - Implements the tail of InlineReturn. This is needed for * tracer integration, where a "return" opcode might not be a safe-point, * and thus the return path must be injected by hijacking the stub return @@ -126,11 +111,15 @@ static const size_t STUB_CALLS_FOR_OP_COUNT = 255; static uint32 StubCallsForOp[STUB_CALLS_FOR_OP_COUNT]; #endif +extern "C" void JaegerTrampolineReturn(); + extern "C" void JS_FASTCALL PushActiveVMFrame(VMFrame &f) { f.previous = JS_METHODJIT_DATA(f.cx).activeFrame; JS_METHODJIT_DATA(f.cx).activeFrame = &f; + + f.regs.fp->setNativeReturnAddress(JS_FUNC_TO_DATA_PTR(void*, JaegerTrampolineReturn)); } extern "C" void JS_FASTCALL @@ -229,10 +218,7 @@ SYMBOL_STRING(JaegerTrampoline) ":" "\n" /* Space for the rest of the VMFrame. */ "subq $0x28, %rsp" "\n" - /* - * This is actually part of the VMFrame, but we need to save |r8| for - * SafePointTrampoline. - */ + /* This is actually part of the VMFrame. */ "pushq %r8" "\n" /* Set cx->regs and set the active frame. Save rdx and align frame in one. */ @@ -242,10 +228,16 @@ SYMBOL_STRING(JaegerTrampoline) ":" "\n" "movq %rsp, %rdi" "\n" "call " SYMBOL_STRING_VMFRAME(PushActiveVMFrame) "\n" - /* - * Jump into into the JIT'd code. - */ - "call *0(%rsp)" "\n" + /* Jump into the JIT'd code. */ + "jmp *0(%rsp)" "\n" +); + +asm volatile ( +".text\n" +".globl " SYMBOL_STRING(JaegerTrampolineReturn) "\n" +SYMBOL_STRING(JaegerTrampolineReturn) ":" "\n" + "or %rdx, %rcx" "\n" + "movq %rcx, 0x30(%rbx)" "\n" "movq %rsp, %rdi" "\n" "call " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n" @@ -285,21 +277,12 @@ SYMBOL_STRING(JaegerThrowpoline) ":" "\n" JS_STATIC_ASSERT(offsetof(VMFrame, regs.fp) == 0x38); -asm volatile ( -".text\n" -".globl " SYMBOL_STRING(SafePointTrampoline) "\n" -SYMBOL_STRING(SafePointTrampoline) ":" "\n" - "popq %rax" "\n" - "movq %rax, 0x50(%rbx)" "\n" - "jmp *8(%rsp)" "\n" -); - asm volatile ( ".text\n" ".globl " SYMBOL_STRING(InjectJaegerReturn) "\n" SYMBOL_STRING(InjectJaegerReturn) ":" "\n" "movq 0x30(%rbx), %rcx" "\n" /* load fp->rval_ into typeReg */ - "movq 0x50(%rbx), %rax" "\n" /* fp->ncode_ */ + "movq 0x28(%rbx), %rax" "\n" /* fp->ncode_ */ /* Reimplementation of PunboxAssembler::loadValueAsComponents() */ "movq %r14, %rdx" "\n" /* payloadReg = payloadMaskReg */ @@ -349,7 +332,15 @@ SYMBOL_STRING(JaegerTrampoline) ":" "\n" "movl %esp, %ecx" "\n" "call " SYMBOL_STRING_VMFRAME(PushActiveVMFrame) "\n" - "call *16(%ebp)" "\n" + "jmp *16(%ebp)" "\n" +); + +asm volatile ( +".text\n" +".globl " SYMBOL_STRING(JaegerTrampolineReturn) "\n" +SYMBOL_STRING(JaegerTrampolineReturn) ":" "\n" + "movl %edx, 0x18(%ebx)" "\n" + "movl %ecx, 0x1C(%ebx)" "\n" "movl %esp, %ecx" "\n" "call " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n" @@ -399,23 +390,9 @@ asm volatile ( SYMBOL_STRING(InjectJaegerReturn) ":" "\n" "movl 0x18(%ebx), %edx" "\n" /* fp->rval_ data */ "movl 0x1C(%ebx), %ecx" "\n" /* fp->rval_ type */ - "movl 0x2C(%ebx), %eax" "\n" /* fp->ncode_ */ + "movl 0x14(%ebx), %eax" "\n" /* fp->ncode_ */ "movl 0x1C(%esp), %ebx" "\n" /* f.fp */ - "pushl %eax" "\n" - "ret" "\n" -); - -/* - * Take the fifth parameter from JaegerShot() and jump to it. This makes it so - * we can jump into arbitrary JIT code, which won't have the frame-fixup prologue. - */ -asm volatile ( -".text\n" -".globl " SYMBOL_STRING(SafePointTrampoline) "\n" -SYMBOL_STRING(SafePointTrampoline) ":" "\n" - "popl %eax" "\n" - "movl %eax, 0x2C(%ebx)" "\n" - "jmp *24(%ebp)" "\n" + "jmp *%eax" "\n" ); # elif defined(JS_CPU_ARM) @@ -448,31 +425,13 @@ FUNCTION_HEADER_EXTRA ".globl " SYMBOL_STRING(InjectJaegerReturn) "\n" SYMBOL_STRING(InjectJaegerReturn) ":" "\n" /* Restore frame regs. */ - "ldr lr, [r11, #44]" "\n" /* fp->ncode */ + "ldr lr, [r11, #20]" "\n" /* fp->ncode */ "ldr r1, [r11, #24]" "\n" /* fp->rval data */ "ldr r2, [r11, #28]" "\n" /* fp->rval type */ "ldr r11, [sp, #28]" "\n" /* load f.fp */ "bx lr" "\n" ); -asm volatile ( -".text\n" -FUNCTION_HEADER_EXTRA -".globl " SYMBOL_STRING(SafePointTrampoline) "\n" -SYMBOL_STRING(SafePointTrampoline) ":" - /* - * On entry to SafePointTrampoline: - * r11 = fp - * sp[80] = safePoint - */ - "ldr ip, [sp, #80]" "\n" - /* Save the return address (in JaegerTrampoline) to fp->ncode. */ - "str lr, [r11, #44]" "\n" - /* Jump to 'safePoint' via 'ip' because a load into the PC from an address on - * the stack looks like a return, and may upset return stack prediction. */ - "bx ip" "\n" -); - asm volatile ( ".text\n" FUNCTION_HEADER_EXTRA @@ -484,7 +443,6 @@ SYMBOL_STRING(JaegerTrampoline) ":" "\n" * r1 = fp * r2 = code * r3 = stackLimit - * sp[0] = safePoint * * The VMFrame for ARM looks like this: * [ lr ] \ @@ -521,7 +479,7 @@ SYMBOL_STRING(JaegerTrampoline) ":" "\n" /* Preserve 'code' (r2) in an arbitrary callee-saved register. */ " mov r4, r2" "\n" - /* Preserve 'fp' (r1) in r11 (JSFrameReg) for SafePointTrampoline. */ + /* Preserve 'fp' (r1) in r11 (JSFrameReg). */ " mov r11, r1" "\n" " mov r0, sp" "\n" @@ -530,7 +488,16 @@ SYMBOL_STRING(JaegerTrampoline) ":" "\n" " blx " SYMBOL_STRING_VMFRAME(PushActiveVMFrame)"\n" /* Call the compiled JavaScript function. */ -" blx r4" "\n" +" bx r4" "\n" +); + +asm volatile ( +".text\n" +FUNCTION_HEADER_EXTRA +".globl " SYMBOL_STRING(JaegerTrampolineReturn) "\n" +SYMBOL_STRING(JaegerTrampolineReturn) ":" "\n" +" str r1, [r11, #24]" "\n" /* fp->rval data */ +" str r2, [r11, #28]" "\n" /* fp->rval type */ /* Tidy up. */ " mov r0, sp" "\n" @@ -608,24 +575,14 @@ extern "C" { __asm { mov edx, [ebx + 0x18]; mov ecx, [ebx + 0x1C]; - mov eax, [ebx + 0x2C]; + mov eax, [ebx + 0x14]; mov ebx, [esp + 0x1C]; - push eax; - ret; - } - } - - __declspec(naked) void SafePointTrampoline() - { - __asm { - pop eax; - mov [ebx + 0x2C], eax; - jmp [ebp + 24]; + jmp eax; } } __declspec(naked) JSBool JaegerTrampoline(JSContext *cx, JSStackFrame *fp, void *code, - Value *stackLimit, void *safePoint) + Value *stackLimit) { __asm { /* Prologue. */ @@ -651,7 +608,15 @@ extern "C" { mov ecx, esp; call PushActiveVMFrame; - call [ebp + 16]; + jmp dword ptr [ebp + 16]; + } + } + + __declspec(naked) void JaegerTrampolineReturn() + { + __asm { + mov [ebx + 0x18], edx; + mov [ebx + 0x1C], ecx; mov ecx, esp; call PopActiveVMFrame; @@ -756,11 +721,10 @@ ThreadData::Finish() } extern "C" JSBool JaegerTrampoline(JSContext *cx, JSStackFrame *fp, void *code, - Value *stackLimit, void *safePoint); -extern "C" void SafePointTrampoline(); + Value *stackLimit); static inline JSBool -EnterMethodJIT(JSContext *cx, JSStackFrame *fp, void *code, void *safePoint) +EnterMethodJIT(JSContext *cx, JSStackFrame *fp, void *code) { JS_ASSERT(cx->regs); JS_CHECK_RECURSION(cx, return JS_FALSE;); @@ -769,8 +733,7 @@ EnterMethodJIT(JSContext *cx, JSStackFrame *fp, void *code, void *safePoint) Profiler prof; JSScript *script = fp->script(); - JaegerSpew(JSpew_Prof, "%s jaeger script: %s, line %d\n", - safePoint ? "dropping" : "entering", + JaegerSpew(JSpew_Prof, "%s jaeger script, line %d\n", script->filename, script->lineno); prof.start(); #endif @@ -786,7 +749,7 @@ EnterMethodJIT(JSContext *cx, JSStackFrame *fp, void *code, void *safePoint) JSFrameRegs *oldRegs = cx->regs; JSAutoResolveFlags rf(cx, JSRESOLVE_INFER); - JSBool ok = JaegerTrampoline(cx, fp, code, stackLimit, safePoint); + JSBool ok = JaegerTrampoline(cx, fp, code, stackLimit); cx->setCurrentRegs(oldRegs); @@ -814,7 +777,7 @@ mjit::JaegerShot(JSContext *cx) JS_ASSERT(cx->regs->pc == script->code); - return EnterMethodJIT(cx, cx->fp(), script->jit->invoke, NULL); + return EnterMethodJIT(cx, cx->fp(), script->jit->invoke); } JSBool @@ -824,9 +787,7 @@ js::mjit::JaegerShotAtSafePoint(JSContext *cx, void *safePoint) JS_ASSERT(!TRACE_RECORDER(cx)); #endif - void *code = JS_FUNC_TO_DATA_PTR(void *, SafePointTrampoline); - - return EnterMethodJIT(cx, cx->fp(), code, safePoint); + return EnterMethodJIT(cx, cx->fp(), safePoint); } template diff --git a/js/src/methodjit/MonoIC.cpp b/js/src/methodjit/MonoIC.cpp index 9085385a93f8..1a23505dba86 100644 --- a/js/src/methodjit/MonoIC.cpp +++ b/js/src/methodjit/MonoIC.cpp @@ -317,7 +317,7 @@ class CallCompiler RegisterID t0 = inlFrame.tempRegs.takeAnyReg(); /* Generate the inline frame creation. */ - inlFrame.assemble(); + inlFrame.assemble(ic.funGuard.labelAtOffset(ic.joinPointOffset).executableAddress()); /* funPtrReg is still valid. Check if a compilation is needed. */ Address scriptAddr(ic.funPtrReg, offsetof(JSFunction, u) + @@ -338,35 +338,25 @@ class CallCompiler JSC::MacroAssembler::Call tryCompile = masm.stubCall(JS_FUNC_TO_DATA_PTR(void *, stubs::CompileFunction), script->code, ic.frameDepth); + masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.fp)), JSFrameReg); Jump notCompiled = masm.branchTestPtr(Assembler::Zero, Registers::ReturnReg, Registers::ReturnReg); - masm.call(Registers::ReturnReg); - Jump done = masm.jump(); + masm.jump(Registers::ReturnReg); hasCode.linkTo(masm.label(), &masm); /* Get nmap[ARITY], set argc, call. */ masm.move(Imm32(ic.argc), JSParamReg_Argc); masm.loadPtr(Address(t0, offsetof(JITScript, arityCheck)), t0); - masm.call(t0); - - /* Rejoin with the fast path. */ - Jump rejoin = masm.jump(); - - /* Worst case - function didn't compile. */ - notCompiled.linkTo(masm.label(), &masm); - masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.fp)), JSFrameReg); - notCompiled = masm.jump(); + masm.jump(t0); JSC::ExecutablePool *ep = poolForSize(masm.size(), CallICInfo::Pool_ScriptStub); if (!ep) return false; JSC::LinkBuffer buffer(&masm, ep); - buffer.link(rejoin, ic.funGuard.labelAtOffset(ic.joinPointOffset)); - buffer.link(done, ic.funGuard.labelAtOffset(ic.joinPointOffset)); buffer.link(notCompiled, ic.slowPathStart.labelAtOffset(ic.slowJoinOffset)); buffer.link(tryCompile, JSC::FunctionPtr(JS_FUNC_TO_DATA_PTR(void *, stubs::CompileFunction))); @@ -392,8 +382,8 @@ class CallCompiler ic.fastGuardedObject = obj; repatch.repatch(ic.funGuard, obj); - repatch.relink(ic.funGuard.callAtOffset(ic.hotCallOffset), - JSC::FunctionPtr(script->ncode)); + repatch.relink(ic.funGuard.jumpAtOffset(ic.hotJumpOffset), + JSC::CodeLocationLabel(script->ncode)); JaegerSpew(JSpew_PICs, "patched CALL path %p (obj: %p)\n", start, ic.fastGuardedObject); } @@ -486,12 +476,15 @@ class CallCompiler /* Store pc. */ masm.storePtr(ImmPtr(cx->regs->pc), - FrameAddress(offsetof(VMFrame, regs) + offsetof(JSFrameRegs, pc))); + FrameAddress(offsetof(VMFrame, regs.pc))); /* Store sp. */ uint32 spOffset = sizeof(JSStackFrame) + ic.frameDepth * sizeof(Value); masm.addPtr(Imm32(spOffset), JSFrameReg, t0); - masm.storePtr(t0, FrameAddress(offsetof(VMFrame, regs) + offsetof(JSFrameRegs, sp))); + masm.storePtr(t0, FrameAddress(offsetof(VMFrame, regs.sp))); + + /* Store fp. */ + masm.storePtr(JSFrameReg, FrameAddress(offsetof(VMFrame, regs.fp))); /* Grab cx early on to avoid stack mucking on x86. */ #ifdef JS_CPU_X86 diff --git a/js/src/methodjit/MonoIC.h b/js/src/methodjit/MonoIC.h index 085bf9aed65a..485e21aab9ba 100644 --- a/js/src/methodjit/MonoIC.h +++ b/js/src/methodjit/MonoIC.h @@ -145,7 +145,7 @@ struct CallICInfo { JSC::CodeLocationJump funJump; /* Offset to inline scripted call, from funGuard. */ - uint32 hotCallOffset : 16; + uint32 hotJumpOffset : 16; uint32 joinPointOffset : 16; /* Out of line slow call. */ diff --git a/js/src/methodjit/NunboxAssembler.h b/js/src/methodjit/NunboxAssembler.h index 847e55f48566..f3f781fbcf9b 100644 --- a/js/src/methodjit/NunboxAssembler.h +++ b/js/src/methodjit/NunboxAssembler.h @@ -145,6 +145,14 @@ class Assembler : public BaseAssembler return l; } + void loadValueAsComponents(const Value &val, RegisterID type, RegisterID payload) { + jsval_layout jv; + jv.asBits = JSVAL_BITS(Jsvalify(val)); + + move(ImmTag(jv.s.tag), type); + move(Imm32(jv.s.payload.u32), payload); + } + /* * Stores type first, then payload. */ diff --git a/js/src/methodjit/PunboxAssembler.h b/js/src/methodjit/PunboxAssembler.h index 2e5ba4418c7e..a23e47ec4d07 100644 --- a/js/src/methodjit/PunboxAssembler.h +++ b/js/src/methodjit/PunboxAssembler.h @@ -125,6 +125,11 @@ class Assembler : public BaseAssembler return l; } + void loadValueAsComponents(const Value &val, RegisterID type, RegisterID payload) { + move(Imm64(val.asRawBits() & 0xFFFF800000000000), type); + move(Imm64(val.asRawBits() & 0x00007FFFFFFFFFFF), payload); + } + template void storeValueFromComponents(RegisterID type, RegisterID payload, T address) { move(type, Registers::ValueReg); diff --git a/js/src/methodjit/StubCalls-inl.h b/js/src/methodjit/StubCalls-inl.h index 0bff7f1876c5..15c6ee4577fc 100644 --- a/js/src/methodjit/StubCalls-inl.h +++ b/js/src/methodjit/StubCalls-inl.h @@ -44,19 +44,15 @@ namespace js { namespace mjit { -#define THROW() \ - do { \ - void *ptr = JS_FUNC_TO_DATA_PTR(void *, JaegerThrowpoline); \ - *f.returnAddressLocation() = ptr; \ - return; \ - } while (0) +static inline void +ThrowException(VMFrame &f) +{ + void *ptr = JS_FUNC_TO_DATA_PTR(void *, JaegerThrowpoline); + *f.returnAddressLocation() = ptr; +} -#define THROWV(v) \ - do { \ - void *ptr = JS_FUNC_TO_DATA_PTR(void *, JaegerThrowpoline); \ - *f.returnAddressLocation() = ptr; \ - return v; \ - } while (0) +#define THROW() do { ThrowException(f); return; } while (0) +#define THROWV(v) do { ThrowException(f); return v; } while (0) static inline JSObject * ValueToObject(JSContext *cx, Value *vp) diff --git a/js/src/methodjit/StubCalls.cpp b/js/src/methodjit/StubCalls.cpp index ce9d465fd391..9b37c5f5ea2c 100644 --- a/js/src/methodjit/StubCalls.cpp +++ b/js/src/methodjit/StubCalls.cpp @@ -1346,7 +1346,7 @@ stubs::Debugger(VMFrame &f, jsbytecode *pc) case JSTRAP_RETURN: f.cx->throwing = JS_FALSE; - f.cx->fp()->setReturnValue(rval); + f.cx->fp()->setAssignedReturnValue(rval); #if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64) *f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *, JS_METHODJIT_DATA(f.cx).trampolines.forceReturnFast); @@ -1386,7 +1386,7 @@ stubs::Trap(VMFrame &f, jsbytecode *pc) case JSTRAP_RETURN: f.cx->throwing = JS_FALSE; - f.cx->fp()->setReturnValue(rval); + f.cx->fp()->setAssignedReturnValue(rval); #if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64) *f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *, JS_METHODJIT_DATA(f.cx).trampolines.forceReturnFast); diff --git a/js/src/methodjit/TrampolineCompiler.cpp b/js/src/methodjit/TrampolineCompiler.cpp index af1e8cb5495d..e7dd63ee2364 100644 --- a/js/src/methodjit/TrampolineCompiler.cpp +++ b/js/src/methodjit/TrampolineCompiler.cpp @@ -118,31 +118,22 @@ bool TrampolineCompiler::generateForceReturn(Assembler &masm) { /* if (hasArgsObj() || hasCallObj()) stubs::PutActivationObjects() */ - Jump noActObjs = masm.branchTest32(Assembler::Zero, - Address(JSFrameReg, JSStackFrame::offsetOfFlags()), + Jump noActObjs = masm.branchTest32(Assembler::Zero, FrameFlagsAddress(), Imm32(JSFRAME_HAS_CALL_OBJ | JSFRAME_HAS_ARGS_OBJ)); masm.stubCall(stubs::PutActivationObjects, NULL, 0); noActObjs.linkTo(masm.label(), &masm); - /* - * r = fp->prev - * f.fp = r - */ - masm.loadPtr(Address(JSFrameReg, JSStackFrame::offsetOfPrev()), Registers::ReturnReg); - masm.storePtr(Registers::ReturnReg, FrameAddress(offsetof(VMFrame, regs.fp))); + /* Store any known return value */ + masm.loadValueAsComponents(UndefinedValue(), JSReturnReg_Type, JSReturnReg_Data); + Jump rvalClear = masm.branchTest32(Assembler::Zero, + FrameFlagsAddress(), Imm32(JSFRAME_RVAL_ASSIGNED)); + Address rvalAddress(JSFrameReg, JSStackFrame::offsetOfReturnValue()); + masm.loadValueAsComponents(rvalAddress, JSReturnReg_Type, JSReturnReg_Data); + rvalClear.linkTo(masm.label(), &masm); - Address rval(JSFrameReg, JSStackFrame::offsetOfReturnValue()); - masm.loadValueAsComponents(rval, JSReturnReg_Type, JSReturnReg_Data); - - masm.restoreReturnAddress(); - - masm.move(Registers::ReturnReg, JSFrameReg); -#ifdef DEBUG - masm.storePtr(ImmPtr(JSStackFrame::sInvalidpc), - Address(JSFrameReg, JSStackFrame::offsetOfSavedpc())); -#endif - - masm.ret(); + /* Return to the caller */ + masm.loadPtr(Address(JSFrameReg, JSStackFrame::offsetOfncode()), Registers::ReturnReg); + masm.jump(Registers::ReturnReg); return true; } diff --git a/js/src/methodjit/TrampolineMasmX64.asm b/js/src/methodjit/TrampolineMasmX64.asm index 09392a9a9d43..464d1bfa13d5 100644 --- a/js/src/methodjit/TrampolineMasmX64.asm +++ b/js/src/methodjit/TrampolineMasmX64.asm @@ -84,8 +84,7 @@ JaegerTrampoline PROC FRAME ; Space for the rest of the VMFrame. sub rsp, 28h - ; This is actually part of VMFrame, but we need to save 5th param for - ; SafePointTrampoline + ; This is actually part of the VMFrame. mov r10, [rbp+8*5+8] push r10 @@ -99,7 +98,13 @@ JaegerTrampoline PROC FRAME add rsp, 20h ; Jump into the JIT code. - call qword ptr [rsp] + jmp qword ptr [rsp] +JaegerTrampoline ENDP + +; void JaegerTrampolineReturn(); +JaegerTrampolineReturn PROC FRAME + or rcx, rdx + mov [rbx + 0x30], rcx sub rsp, 20h lea rcx, [rsp+20h] call PopActiveVMFrame @@ -147,14 +152,6 @@ throwpoline_exit: JaegerThrowpoline ENDP -; void SafePointTrampoline(); -SafePointTrampoline PROC FRAME - .ENDPROLOG - pop rax - mov qword ptr [rbx+50h], rax ; fp->ncode_ - jmp qword ptr [rsp+8] -SafePointTrampoline ENDP - ; void InjectJaegerReturn(); InjectJaegerReturn PROC FRAME diff --git a/js/src/methodjit/TrampolineSUNWX64.s b/js/src/methodjit/TrampolineSUNWX64.s index 1e4c88806803..b34f6a673b10 100644 --- a/js/src/methodjit/TrampolineSUNWX64.s +++ b/js/src/methodjit/TrampolineSUNWX64.s @@ -71,10 +71,7 @@ JaegerTrampoline: /* Space for the rest of the VMFrame. */ subq $0x28, %rsp - /* - * This is actually part of the VMFrame, but we need to save |r8| for - * SafePointTrampoline. - */ + /* This is actually part of the VMFrame. */ pushq %r8 /* Set cx->regs and set the active frame. Save rdx and align frame in one. */ @@ -84,10 +81,16 @@ JaegerTrampoline: movq %rsp, %rdi call PushActiveVMFrame - /* - * Jump into into the JIT'd code. - */ - call *0(%rsp) + /* Jump into into the JIT'd code. */ + jmp *0(%rsp) +.size JaegerTrampoline, . - JaegerTrampoline + +/ void JaegerTrampolineReturn() +.global JaegerTrampolineReturn +.type JaegerTrampolineReturn, @function +JaegerTrampolineReturn: + or %rdx, %rcx + movq %rcx, 0x30(%rbx) movq %rsp, %rdi call PopActiveVMFrame @@ -100,7 +103,7 @@ JaegerTrampoline: popq %rbp movq $1, %rax ret -.size JaegerTrampoline, . - JaegerTrampoline +.size JaegerTrampolineReturn, . - JaegerTrampolineReturn / void *JaegerThrowpoline(js::VMFrame *vmFrame) @@ -126,19 +129,11 @@ JaegerThrowpoline: ret .size JaegerThrowpoline, . - JaegerThrowpoline -.global SafePointTrampoline -.type SafePointTrampoline, @function -SafePointTrampoline: - popq %rax - movq %rax, 0x50(%rbx) - jmp *8(%rsp) -.size SafePointTrampoline, . - SafePointTrampoline - .global InjectJaegerReturn .type InjectJaegerReturn, @function InjectJaegerReturn: movq 0x30(%rbx), %rcx /* load fp->rval_ into typeReg */ - movq 0x50(%rbx), %rax /* fp->ncode_ */ + movq 0x28(%rbx), %rax /* fp->ncode_ */ /* Reimplementation of PunboxAssembler::loadValueAsComponents() */ movq %r14, %rdx /* payloadReg = payloadMaskReg */ diff --git a/js/src/methodjit/TrampolineSUNWX86.s b/js/src/methodjit/TrampolineSUNWX86.s index 1f18a869e170..16ee60fcb6bc 100644 --- a/js/src/methodjit/TrampolineSUNWX86.s +++ b/js/src/methodjit/TrampolineSUNWX86.s @@ -65,7 +65,15 @@ JaegerTrampoline: call SetVMFrameRegs call PushActiveVMFrame popl %edx - call *16(%ebp) + jmp *16(%ebp) +.size JaegerTrampoline, . - JaegerTrampoline + +/ void JaegerTrampolineReturn() +.global JaegerTrampolineReturn +.type JaegerTrampolineReturn, @function +JaegerTrampolineReturn: + movl %edx, 0x18(%ebx) + movl %ecx, 0x1C(%ebx) pushl %esp call PopActiveVMFrame @@ -76,7 +84,7 @@ JaegerTrampoline: popl %ebp movl $1, %eax ret -.size JaegerTrampoline, . - JaegerTrampoline +.size JaegerTrampolineReturn, . - JaegerTrampolineReturn / void *JaegerThrowpoline(js::VMFrame *vmFrame) @@ -117,24 +125,11 @@ throwpoline_exit: InjectJaegerReturn: movl 0x18(%ebx), %edx /* fp->rval_ data */ movl 0x1C(%ebx), %ecx /* fp->rval_ type */ - movl 0x2C(%ebx), %eax /* fp->ncode_ */ + movl 0x14(%ebx), %eax /* fp->ncode_ */ /* For Sun Studio there is no fast call. */ /* We add the stack by 8 before. */ addl $0x8, %esp /* Restore frame regs. */ movl 0x1C(%esp), %ebx /* f.fp */ - pushl %eax - ret + jmp *%eax .size InjectJaegerReturn, . - InjectJaegerReturn - -/* - * Take the fifth parameter from JaegerShot() and jump to it. This makes it so - * we can jump into arbitrary JIT code, which won't have the frame-fixup prologue. - */ -.global SafePointTrampoline -.type SafePointTrampoline, @function -SafePointTrampoline: - popl %eax - movl %eax, 0x2C(%ebx) - jmp *24(%ebp) -.size SafePointTrampoline, . - SafePointTrampoline From 3d03f356f7dab7b87d0f7b538ae2c286e6c55ee5 Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Wed, 29 Sep 2010 09:23:04 -0700 Subject: [PATCH 002/115] Bug 600032 - TM: set right compartment for Jetpack r=gregor --- js/jetpack/JetpackChild.cpp | 27 ++++++++++++++++++++++----- js/jetpack/JetpackParent.cpp | 18 ++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/js/jetpack/JetpackChild.cpp b/js/jetpack/JetpackChild.cpp index 6eb0340f643e..263cd4cd74ac 100644 --- a/js/jetpack/JetpackChild.cpp +++ b/js/jetpack/JetpackChild.cpp @@ -137,9 +137,15 @@ JetpackChild::Init(base::ProcessHandle aParentProcessHandle, JS_SetContextPrivate(mCx, this); JSObject* implGlobal = JS_NewCompartmentAndGlobalObject(mCx, const_cast(&sGlobalClass), NULL); + if (!implGlobal) + return false; + + JSAutoEnterCompartment ac; + if (!ac.enter(mCx, implGlobal)) + return false; + jsval ctypes; - if (!implGlobal || - !JS_InitStandardClasses(mCx, implGlobal) || + if (!JS_InitStandardClasses(mCx, implGlobal) || #ifdef BUILD_CTYPES !JS_InitCTypesClass(mCx, implGlobal) || !JS_GetProperty(mCx, implGlobal, "ctypes", &ctypes) || @@ -173,6 +179,12 @@ JetpackChild::RecvSendMessage(const nsString& messageName, const nsTArray& data) { JSAutoRequest request(mCx); + + JSObject *global = JS_GetGlobalObject(mCx); + JSAutoEnterCompartment ac; + if (!ac.enter(mCx, global)) + return false; + return JetpackActorCommon::RecvMessage(mCx, messageName, data, NULL); } @@ -181,9 +193,14 @@ JetpackChild::RecvEvalScript(const nsString& code) { JSAutoRequest request(mCx); - js::AutoValueRooter ignored(mCx); - (void) JS_EvaluateUCScript(mCx, JS_GetGlobalObject(mCx), code.get(), - code.Length(), "", 1, ignored.jsval_addr()); + JSObject *global = JS_GetGlobalObject(mCx); + JSAutoEnterCompartment ac; + if (!ac.enter(mCx, global)) + return false; + + jsval ignored; + (void) JS_EvaluateUCScript(mCx, global, code.get(), + code.Length(), "", 1, &ignored); return true; } diff --git a/js/jetpack/JetpackParent.cpp b/js/jetpack/JetpackParent.cpp index 65032e4c1457..8c1f4c983e90 100644 --- a/js/jetpack/JetpackParent.cpp +++ b/js/jetpack/JetpackParent.cpp @@ -92,6 +92,10 @@ JetpackParent::SendMessage(const nsAString& aMessageName) JSAutoRequest request(cx); + JSAutoEnterCompartment ac; + if (!ac.enter(cx, JS_GetGlobalObject(cx))) + return false; + for (PRUint32 i = 1; i < argc; ++i) if (!jsval_to_Variant(cx, argv[i], data.AppendElement())) return NS_ERROR_INVALID_ARG; @@ -162,6 +166,11 @@ JetpackParent::RecvSendMessage(const nsString& messageName, { AutoCXPusher cxp(mContext); JSAutoRequest request(mContext); + + JSAutoEnterCompartment ac; + if (!ac.enter(mContext, JS_GetGlobalObject(mContext))) + return false; + return JetpackActorCommon::RecvMessage(mContext, messageName, data, NULL); } @@ -172,6 +181,11 @@ JetpackParent::AnswerCallMessage(const nsString& messageName, { AutoCXPusher cxp(mContext); JSAutoRequest request(mContext); + + JSAutoEnterCompartment ac; + if (!ac.enter(mContext, JS_GetGlobalObject(mContext))) + return false; + return JetpackActorCommon::RecvMessage(mContext, messageName, data, results); } @@ -188,6 +202,10 @@ JetpackParent::CreateHandle(nsIVariant** aResult) JSAutoRequest request(mContext); + JSAutoEnterCompartment ac; + if (!ac.enter(mContext, JS_GetGlobalObject(mContext))) + return false; + JSObject* hobj = handle->ToJSObject(mContext); if (!hobj) return NS_ERROR_FAILURE; From 0646cb2f9acf8a7f12eb54344983d639cede404e Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 29 Sep 2010 10:06:32 -0700 Subject: [PATCH 003/115] Fix some FrameState functions not passing tracked FEs (bug 600163, r=dmandelin). --- js/src/methodjit/FrameState.cpp | 4 ++-- js/src/trace-test/tests/jaeger/bug600139.js | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 js/src/trace-test/tests/jaeger/bug600139.js diff --git a/js/src/methodjit/FrameState.cpp b/js/src/methodjit/FrameState.cpp index ff34ecb31d83..4077757051b2 100644 --- a/js/src/methodjit/FrameState.cpp +++ b/js/src/methodjit/FrameState.cpp @@ -1287,7 +1287,7 @@ FrameState::shimmy(uint32 n) { JS_ASSERT(sp - n >= spBase); int32 depth = 0 - int32(n); - storeTop(&sp[depth - 1], true); + storeTop(peek(depth - 1), true); popn(n); } @@ -1296,7 +1296,7 @@ FrameState::shift(int32 n) { JS_ASSERT(n < 0); JS_ASSERT(sp + n - 1 >= spBase); - storeTop(&sp[n - 1], true); + storeTop(peek(n - 1), true); pop(); } diff --git a/js/src/trace-test/tests/jaeger/bug600139.js b/js/src/trace-test/tests/jaeger/bug600139.js new file mode 100644 index 000000000000..d8e261930670 --- /dev/null +++ b/js/src/trace-test/tests/jaeger/bug600139.js @@ -0,0 +1,11 @@ +// |trace-test| error: ReferenceError +// vim: set ts=4 sw=4 tw=99 et: +function f(a, b, c) { + if (!a.__SSi) { + throw Components.returnCode = Cr.NS_ERROR_INVALID_ARG; + } + this.restoreWindow(a, b, c); + eval(); +} +dis(f); +f(1, 2, 3); From 72bae9ae977c4d5b55f8456ce9eb7b96d4246d2f Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Wed, 29 Sep 2010 11:31:52 -0700 Subject: [PATCH 004/115] Bug 576172 - TM: don't try to add peers or branches if abort flushed the jit cache (r=gal) --- js/src/jstracer.cpp | 53 +++++++++++++++++++++++++++++---------------- js/src/jstracer.h | 8 ++++--- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index c52cd3cdb251..5f2ada361d5e 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -2585,7 +2585,7 @@ TraceRecorder::finishSuccessfully() } /* This function aborts a recorder and any pending outer recorders. */ -JS_REQUIRES_STACK AbortableRecordingStatus +JS_REQUIRES_STACK TraceRecorder::AbortResult TraceRecorder::finishAbort(const char* reason) { JS_ASSERT(traceMonitor->recorder == this); @@ -2627,9 +2627,11 @@ TraceRecorder::finishAbort(const char* reason) localtm->recorder = NULL; delete this; - if (localtm->outOfMemory() || OverfullJITCache(localtm)) + if (localtm->outOfMemory() || OverfullJITCache(localtm)) { ResetJIT(localcx, FR_OOM); - return ARECORD_ABORTED; + return JIT_RESET; + } + return NORMAL_ABORT; } /* Add debug information to a LIR instruction as we emit it. */ @@ -6128,7 +6130,9 @@ TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCall jsbytecode* outer = (jsbytecode*) outerFragment->ip; uint32 outerArgc = outerFragment->argc; JS_ASSERT(entryFrameArgc(cx) == first->argc); - AbortRecording(cx, "No compatible inner tree"); + + if (AbortRecording(cx, "No compatible inner tree") == JIT_RESET) + return MONITOR_NOT_RECORDING; return RecordingIfTrue(RecordTree(cx, first, outer, outerArgc, globalSlots)); } @@ -6195,10 +6199,13 @@ TraceRecorder::attemptTreeCall(TreeFragment* f, uintN& inlineCallCount) case LOOP_EXIT: /* If the inner tree exited on an unknown loop exit, grow the tree around it. */ if (innermostNestedGuard) { - AbortRecording(cx, "Inner tree took different side exit, abort current " - "recording and grow nesting tree"); - return AttemptToExtendTree(localCx, innermostNestedGuard, lr, outer) ? - ARECORD_CONTINUE : ARECORD_ABORTED; + if (AbortRecording(cx, "Inner tree took different side exit, abort current " + "recording and grow nesting tree") == JIT_RESET) { + return ARECORD_ABORTED; + } + return AttemptToExtendTree(localCx, innermostNestedGuard, lr, outer) + ? ARECORD_CONTINUE + : ARECORD_ABORTED; } JS_ASSERT(oldInlineCallCount == inlineCallCount); @@ -6211,23 +6218,31 @@ TraceRecorder::attemptTreeCall(TreeFragment* f, uintN& inlineCallCount) { /* Abort recording so the inner loop can become type stable. */ JSObject* _globalObj = globalObj; - AbortRecording(cx, "Inner tree is trying to stabilize, abort outer recording"); - return AttemptToStabilizeTree(localCx, _globalObj, lr, outer, outerFragment->argc) ? - ARECORD_CONTINUE : ARECORD_ABORTED; + if (AbortRecording(cx, "Inner tree is trying to stabilize, " + "abort outer recording") == JIT_RESET) { + return ARECORD_ABORTED; + } + return AttemptToStabilizeTree(localCx, _globalObj, lr, outer, outerFragment->argc) + ? ARECORD_CONTINUE + : ARECORD_ABORTED; } case OVERFLOW_EXIT: traceMonitor->oracle->markInstructionUndemotable(cx->regs->pc); /* FALL THROUGH */ case BRANCH_EXIT: - case CASE_EXIT: { + case CASE_EXIT: /* Abort recording the outer tree, extend the inner tree. */ - AbortRecording(cx, "Inner tree is trying to grow, abort outer recording"); - return AttemptToExtendTree(localCx, lr, NULL, outer) ? ARECORD_CONTINUE : ARECORD_ABORTED; - } + if (AbortRecording(cx, "Inner tree is trying to grow, " + "abort outer recording") == JIT_RESET) { + return ARECORD_ABORTED; + } + return AttemptToExtendTree(localCx, lr, NULL, outer) + ? ARECORD_CONTINUE + : ARECORD_ABORTED; case NESTED_EXIT: - JS_NOT_REACHED("NESTED_EXIT should be replaced by innermost side exit"); + JS_NOT_REACHED("NESTED_EXIT should be replaced by innermost side exit"); default: debug_only_printf(LC_TMTracer, "exit_type=%s\n", getExitName(lr->exitType)); AbortRecording(cx, "Inner tree not suitable for calling"); @@ -7362,14 +7377,14 @@ TraceRecorder::monitorRecording(JSOp op) return status; } -JS_REQUIRES_STACK void +JS_REQUIRES_STACK TraceRecorder::AbortResult AbortRecording(JSContext* cx, const char* reason) { #ifdef DEBUG JS_ASSERT(TRACE_RECORDER(cx)); - TRACE_RECORDER(cx)->finishAbort(reason); + return TRACE_RECORDER(cx)->finishAbort(reason); #else - TRACE_RECORDER(cx)->finishAbort("[no reason]"); + return TRACE_RECORDER(cx)->finishAbort("[no reason]"); #endif } diff --git a/js/src/jstracer.h b/js/src/jstracer.h index 4bee97e32e85..a6bbb417d8e0 100644 --- a/js/src/jstracer.h +++ b/js/src/jstracer.h @@ -1405,7 +1405,9 @@ class TraceRecorder /* The destructor should only be called through finish*, not directly. */ ~TraceRecorder(); JS_REQUIRES_STACK AbortableRecordingStatus finishSuccessfully(); - JS_REQUIRES_STACK AbortableRecordingStatus finishAbort(const char* reason); + + enum AbortResult { NORMAL_ABORT, JIT_RESET }; + JS_REQUIRES_STACK AbortResult finishAbort(const char* reason); friend class ImportBoxedStackSlotVisitor; friend class ImportUnboxedStackSlotVisitor; @@ -1422,7 +1424,7 @@ class TraceRecorder friend MonitorResult MonitorLoopEdge(JSContext*, uintN&); friend TracePointAction MonitorTracePoint(JSContext*, uintN &inlineCallCount, bool &blacklist); - friend void AbortRecording(JSContext*, const char*); + friend AbortResult AbortRecording(JSContext*, const char*); friend class BoxArg; friend void TraceMonitor::sweep(); @@ -1509,7 +1511,7 @@ MonitorLoopEdge(JSContext* cx, uintN& inlineCallCount); extern JS_REQUIRES_STACK TracePointAction MonitorTracePoint(JSContext*, uintN& inlineCallCount, bool& blacklist); -extern JS_REQUIRES_STACK void +extern JS_REQUIRES_STACK TraceRecorder::AbortResult AbortRecording(JSContext* cx, const char* reason); extern void From b4175052b7b71cb334ff26b0715ffa29de7feb11 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 29 Sep 2010 12:04:29 -0700 Subject: [PATCH 005/115] Fix ICs on method-valued shape properties (bug 600424, r=dmandelin). --HG-- extra : rebase_source : 70218ae27fbca50181bc578d3388559b487ca75a --- js/src/methodjit/PolyIC.cpp | 44 +++++++++++++++++++-- js/src/trace-test/tests/jaeger/bug600424.js | 14 +++++++ 2 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 js/src/trace-test/tests/jaeger/bug600424.js diff --git a/js/src/methodjit/PolyIC.cpp b/js/src/methodjit/PolyIC.cpp index c50c8e99e924..7643cb8709e5 100644 --- a/js/src/methodjit/PolyIC.cpp +++ b/js/src/methodjit/PolyIC.cpp @@ -85,6 +85,14 @@ class PICStubCompiler : type(type), f(f), script(script), pic(pic) { } + bool isCallOp() const + { + if (pic.kind == ic::PICInfo::CALL) + return true; + JSOp op = JSOp(*f.regs.pc); + return !!(js_CodeSpec[op].format & JOF_CALLOP); + } + bool disable(const char *reason, VoidStub stub) { return disable(reason, JS_FUNC_TO_DATA_PTR(void *, stub)); @@ -884,6 +892,8 @@ class GetPropCompiler : public PICStubCompiler return disable("proto walk on String.prototype"); if (!shape->hasDefaultGetterOrIsMethod()) return disable("getter"); + if (shape->isMethod() && !isCallOp()) + return disable("method valued shape"); if (!shape->hasSlot()) return disable("invalid slot"); @@ -918,7 +928,12 @@ class GetPropCompiler : public PICStubCompiler masm.loadShape(pic.objReg, pic.shapeReg); Jump shapeMismatch = masm.branch32(Assembler::NotEqual, pic.shapeReg, Imm32(obj->shape())); - masm.loadSlot(pic.objReg, pic.objReg, shape->slot, pic.shapeReg, pic.objReg); + if (!shape->isMethod()) { + masm.loadSlot(pic.objReg, pic.objReg, shape->slot, pic.shapeReg, pic.objReg); + } else { + masm.loadValueAsComponents(ObjectValue(shape->methodObject()), pic.shapeReg, + pic.objReg); + } Jump done = masm.jump(); @@ -1120,7 +1135,12 @@ class GetPropCompiler : public PICStubCompiler } /* Load the value out of the object. */ - masm.loadSlot(pic.objReg, pic.objReg, shape->slot, pic.shapeReg, pic.objReg); + if (!shape->isMethod()) { + masm.loadSlot(pic.objReg, pic.objReg, shape->slot, pic.shapeReg, pic.objReg); + } else { + masm.loadValueAsComponents(ObjectValue(shape->methodObject()), pic.shapeReg, + pic.objReg); + } Jump done = masm.jump(); JSC::ExecutablePool *ep = getExecPool(masm.size()); @@ -1213,6 +1233,8 @@ class GetPropCompiler : public PICStubCompiler const Shape *shape = (const Shape *)prop; if (!shape->hasDefaultGetterOrIsMethod()) return disable("getter"); + if (shape->isMethod() && !isCallOp()) + return disable("method valued shape"); if (!shape->hasSlot()) return disable("invalid slot"); @@ -1476,7 +1498,12 @@ class GetElemCompiler : public PICStubCompiler } /* Load the value out of the object. */ - masm.loadSlot(pic.objReg, pic.objReg, shape->slot, pic.shapeReg, pic.objReg); + if (!shape->isMethod()) { + masm.loadSlot(pic.objReg, pic.objReg, shape->slot, pic.shapeReg, pic.objReg); + } else { + masm.loadValueAsComponents(ObjectValue(shape->methodObject()), pic.shapeReg, + pic.objReg); + } Jump done = masm.jump(); JSC::ExecutablePool *ep = getExecPool(masm.size()); @@ -1557,6 +1584,8 @@ class GetElemCompiler : public PICStubCompiler const Shape *shape = (const Shape *)prop; if (!shape->hasDefaultGetterOrIsMethod()) return disable("getter"); + if (shape->isMethod() && !isCallOp()) + return disable("method valued shape"); if (!shape->hasSlot()) return disable("invalid slot"); @@ -1665,7 +1694,12 @@ class ScopeNameCompiler : public PICStubCompiler masm.loadShape(pic.objReg, pic.shapeReg); Jump finalShape = masm.branch32(Assembler::NotEqual, pic.shapeReg, Imm32(holder->shape())); - masm.loadSlot(pic.objReg, pic.objReg, shape->slot, pic.shapeReg, pic.objReg); + if (!shape->isMethod()) { + masm.loadSlot(pic.objReg, pic.objReg, shape->slot, pic.shapeReg, pic.objReg); + } else { + masm.loadValueAsComponents(ObjectValue(shape->methodObject()), pic.shapeReg, + pic.objReg); + } Jump done = masm.jump(); @@ -1848,6 +1882,8 @@ class ScopeNameCompiler : public PICStubCompiler if (!shape->hasDefaultGetterOrIsMethod()) return disable("getter"); + if (shape->isMethod() && !isCallOp()) + return disable("method valued shape"); if (!shape->hasSlot()) return disable("invalid slot"); diff --git a/js/src/trace-test/tests/jaeger/bug600424.js b/js/src/trace-test/tests/jaeger/bug600424.js new file mode 100644 index 000000000000..44bb4e7c9b4c --- /dev/null +++ b/js/src/trace-test/tests/jaeger/bug600424.js @@ -0,0 +1,14 @@ +// vim: set ts=4 sw=4 tw=99 et: +function f(a) { + var x = { + g: function () { + return this.a; + } + }; + x.g.prototype.a = a; + assertEq(x.g.prototype.a, a); + return x; +} +f(1); +f(2); +f(3); From 6c8390ed8ca783f67c9bb6bc76805479d69bbde6 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 27 Sep 2010 11:14:36 -0700 Subject: [PATCH 006/115] Added test case for bug 597378 (a=NPOTB). --- js/src/trace-test/tests/jaeger/bug597378.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 js/src/trace-test/tests/jaeger/bug597378.js diff --git a/js/src/trace-test/tests/jaeger/bug597378.js b/js/src/trace-test/tests/jaeger/bug597378.js new file mode 100644 index 000000000000..454935bb9320 --- /dev/null +++ b/js/src/trace-test/tests/jaeger/bug597378.js @@ -0,0 +1,12 @@ +// vim: set ts=4 sw=4 tw=99 et: +function f(a, b) { + var o = a; + var q = b; + var p; + do { } while (0); + p = o; + q = p + 1 < q ? p + 1 : 0; + assertEq(q, 0); +} +f(3, 4); + From aee7415f786ef9fce0c9b2253df268db10ecfd99 Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Wed, 29 Sep 2010 12:28:05 -0700 Subject: [PATCH 007/115] Bug 600580 - TM: set right compartment in _newJSDContext r=gregor --- js/jsd/jsd_high.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/js/jsd/jsd_high.c b/js/jsd/jsd_high.c index 1be77ae24bed..52dd4091ee32 100644 --- a/js/jsd/jsd_high.c +++ b/js/jsd/jsd_high.c @@ -139,17 +139,20 @@ _newJSDContext(JSRuntime* jsrt, JS_BeginRequest(jsdc->dumbContext); - if( scopeobj ) - call = JS_EnterCrossCompartmentCall(jsdc->dumbContext, scopeobj); - jsdc->glob = JS_NewGlobalObject(jsdc->dumbContext, &global_class); - if( call ) - JS_LeaveCrossCompartmentCall(call); + jsdc->glob = JS_NewCompartmentAndGlobalObject(jsdc->dumbContext, &global_class, NULL); if( ! jsdc->glob ) goto label_newJSDContext_failure; + call = JS_EnterCrossCompartmentCall(jsdc->dumbContext, scopeobj); + if( ! call ) + goto label_newJSDContext_failure; + if( ! JS_InitStandardClasses(jsdc->dumbContext, jsdc->glob) ) goto label_newJSDContext_failure; + if( call ) + JS_LeaveCrossCompartmentCall(call); + JS_EndRequest(jsdc->dumbContext); jsdc->data = NULL; From 89b77ca30a6929e4f4a5f68da0f910b8cf40dc89 Mon Sep 17 00:00:00 2001 From: Gregor Wagner Date: Wed, 29 Sep 2010 13:39:22 -0700 Subject: [PATCH 008/115] Back out 94e52cdc2157 --- js/jsd/jsd_high.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/js/jsd/jsd_high.c b/js/jsd/jsd_high.c index 52dd4091ee32..83f6a2062842 100644 --- a/js/jsd/jsd_high.c +++ b/js/jsd/jsd_high.c @@ -139,20 +139,18 @@ _newJSDContext(JSRuntime* jsrt, JS_BeginRequest(jsdc->dumbContext); - jsdc->glob = JS_NewCompartmentAndGlobalObject(jsdc->dumbContext, &global_class, NULL); - if( ! jsdc->glob ) - goto label_newJSDContext_failure; + if( scopeobj ) + call = JS_EnterCrossCompartmentCall(jsdc->dumbContext, scopeobj); + jsdc->glob = JS_NewGlobalObject(jsdc->dumbContext, &global_class); + if( call ) + JS_LeaveCrossCompartmentCall(call); - call = JS_EnterCrossCompartmentCall(jsdc->dumbContext, scopeobj); - if( ! call ) + if( ! jsdc->glob ) goto label_newJSDContext_failure; if( ! JS_InitStandardClasses(jsdc->dumbContext, jsdc->glob) ) goto label_newJSDContext_failure; - if( call ) - JS_LeaveCrossCompartmentCall(call); - JS_EndRequest(jsdc->dumbContext); jsdc->data = NULL; From 1f33d7694b3be4b978675d7dc3408d680865af20 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 13 Sep 2010 22:33:44 -0700 Subject: [PATCH 009/115] Add local and argument closure information to JSScript (bug 592973, r=brendan+dmandelin). --HG-- extra : rebase_source : 3d36a7908230006f2b048835f7526962fac2b32b --- js/src/Makefile.in | 2 +- js/src/jsemit.cpp | 61 +++++--- js/src/jsemit.h | 8 +- js/src/jsfun.cpp | 79 ++++++----- js/src/jsinterp.cpp | 3 +- js/src/jsobj.cpp | 2 +- js/src/jsobj.h | 1 + js/src/jsopcode.tbl | 2 - js/src/jsparse.cpp | 12 +- js/src/jsparse.h | 1 + js/src/jsreflect.cpp | 2 +- js/src/jsscript.cpp | 131 +++++++++++++++--- js/src/jsscript.h | 68 +++++---- js/src/jstracer.cpp | 6 - js/src/jsxdrapi.h | 2 +- js/src/methodjit/Compiler.cpp | 94 +++++++------ js/src/methodjit/Compiler.h | 3 +- js/src/methodjit/FrameState-inl.h | 22 +-- js/src/methodjit/FrameState.cpp | 12 +- js/src/methodjit/FrameState.h | 9 +- js/src/methodjit/MethodJIT.h | 2 - js/src/trace-test/tests/jaeger/bug592973-1.js | 12 ++ js/src/trace-test/tests/jaeger/bug592973-2.js | 7 + js/src/trace-test/tests/jaeger/bug592973-3.js | 8 ++ 24 files changed, 367 insertions(+), 182 deletions(-) create mode 100644 js/src/trace-test/tests/jaeger/bug592973-1.js create mode 100644 js/src/trace-test/tests/jaeger/bug592973-2.js create mode 100644 js/src/trace-test/tests/jaeger/bug592973-3.js diff --git a/js/src/Makefile.in b/js/src/Makefile.in index d8dca2b9595a..d46f046eef87 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -861,7 +861,7 @@ endif ifdef ENABLE_TRACEJIT # Imacro compilation. -$(CURDIR)/imacros.c.out: $(srcdir)/imacro_asm.py $(srcdir)/imacros.jsasm +$(CURDIR)/imacros.c.out: $(srcdir)/imacro_asm.py $(srcdir)/imacros.jsasm jsopcode.tbl $(PYTHON) $< $(srcdir)/imacros.jsasm $(CURDIR)/imacros.c.out $(addsuffix .$(OBJ_SUFFIX),jstracer): $(CURDIR)/imacros.c.out diff --git a/js/src/jsemit.cpp b/js/src/jsemit.cpp index ef29845290f1..ffd3ef50737d 100644 --- a/js/src/jsemit.cpp +++ b/js/src/jsemit.cpp @@ -103,7 +103,9 @@ JSCodeGenerator::JSCodeGenerator(Parser *parser, emitLevel(0), constMap(parser->context), constList(parser->context), - globalUses(ContextAllocPolicy(parser->context)) + globalUses(ContextAllocPolicy(parser->context)), + closedArgs(ContextAllocPolicy(parser->context)), + closedVars(ContextAllocPolicy(parser->context)) { flags = TCF_COMPILING; memset(&prolog, 0, sizeof prolog); @@ -1811,6 +1813,12 @@ EmitSlotIndexOp(JSContext *cx, JSOp op, uintN slot, uintN index, return bigSuffix == JSOP_NOP || js_Emit1(cx, cg, bigSuffix) >= 0; } +bool +JSCodeGenerator::shouldNoteClosedName(JSParseNode *pn) +{ + return !callsEval() && pn->pn_defn && pn->isClosed(); +} + /* * Adjust the slot for a block local to account for the number of variables * that share the same index space with locals. Due to the incremental code @@ -1866,14 +1874,16 @@ EmitEnterBlock(JSContext *cx, JSParseNode *pn, JSCodeGenerator *cg) JS_ASSERT(pnu->pn_cookie.isFree()); } #endif + + /* + * If this variable is closed over, and |eval| is not present, then + * then set a bit in dslots so the Method JIT can deoptimize this + * slot. + */ + bool isClosed = cg->shouldNoteClosedName(dn); + blockObj->setSlot(slot, BooleanValue(isClosed)); } - /* - * Shrink slots to free blockObj->dslots and ensure a prompt safe crash if - * by accident some code tries to get a slot from a compiler-created Block - * prototype instead of from a clone. - */ - blockObj->shrinkSlots(cx, base); return true; } @@ -3639,7 +3649,7 @@ js_EmitFunctionScript(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body) return js_EmitTree(cx, cg, body) && js_Emit1(cx, cg, JSOP_STOP) >= 0 && - js_NewScriptFromCG(cx, cg); + JSScript::NewScriptFromCG(cx, cg); } /* A macro for inlining at the top of js_EmitTree (whence it came). */ @@ -3708,13 +3718,11 @@ MaybeEmitVarDecl(JSContext *cx, JSCodeGenerator *cg, JSOp prologOp, } if (JOF_OPTYPE(pn->pn_op) == JOF_LOCAL && - !(cg->flags & TCF_FUN_CALLS_EVAL) && - pn->pn_defn && - (((JSDefinition *)pn)->pn_dflags & PND_CLOSED)) + pn->pn_cookie.slot() < cg->fun->u.i.nvars && + cg->shouldNoteClosedName(pn)) { - CG_SWITCH_TO_PROLOG(cg); - EMIT_UINT16_IMM_OP(JSOP_DEFUPVAR, pn->pn_cookie.asInteger()); - CG_SWITCH_TO_MAIN(cg); + if (!cg->closedVars.append(pn->pn_cookie.slot())) + return JS_FALSE; } if (result) @@ -4543,10 +4551,10 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) JS_ASSERT(index < JS_BIT(20)); pn->pn_index = index; op = FUN_FLAT_CLOSURE(fun) ? JSOP_DEFLOCALFUN_FC : JSOP_DEFLOCALFUN; - if ((pn->pn_dflags & PND_CLOSED) && !(cg->flags & TCF_FUN_CALLS_EVAL)) { - CG_SWITCH_TO_PROLOG(cg); - EMIT_UINT16_IMM_OP(JSOP_DEFUPVAR, pn->pn_cookie.asInteger()); - CG_SWITCH_TO_MAIN(cg); + if (pn->isClosed() && + !cg->callsEval() && + !cg->closedVars.append(pn->pn_cookie.slot())) { + return JS_FALSE; } if (!EmitSlotIndexOp(cx, op, slot, index, cg)) return JS_FALSE; @@ -4555,8 +4563,21 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) } case TOK_ARGSBODY: - ok = js_EmitTree(cx, cg, pn->last()); + { + JSParseNode *pnlast = pn->last(); + for (JSParseNode *pn2 = pn->pn_head; pn2 != pnlast; pn2 = pn2->pn_next) { + if (!pn2->pn_defn) + continue; + if (!BindNameToSlot(cx, cg, pn2)) + return JS_FALSE; + if (JOF_OPTYPE(pn2->pn_op) == JOF_QARG && cg->shouldNoteClosedName(pn2)) { + if (!cg->closedArgs.append(pn2->pn_cookie.slot())) + return JS_FALSE; + } + } + ok = js_EmitTree(cx, cg, pnlast); break; + } case TOK_UPVARS: JS_ASSERT(cg->lexdeps.count == 0); @@ -5620,7 +5641,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) * functions, see bug 419662. */ JS_ASSERT(pnchild->pn_type == TOK_SEMI); - JS_ASSERT(pnchild->pn_kid->pn_type == TOK_COMMA); + JS_ASSERT(pnchild->pn_kid->pn_type == TOK_VAR); if (!js_EmitTree(cx, cg, pnchild)) return JS_FALSE; pnchild = pnchild->pn_next; diff --git a/js/src/jsemit.h b/js/src/jsemit.h index c428b2de20b6..cf38590db18c 100644 --- a/js/src/jsemit.h +++ b/js/src/jsemit.h @@ -371,7 +371,6 @@ struct JSTreeContext { /* tree context for semantic checks */ } bool callsEval() const { - JS_ASSERT(inFunction()); return flags & TCF_FUN_CALLS_EVAL; } @@ -549,6 +548,11 @@ struct JSCodeGenerator : public JSTreeContext GlobalUseVector globalUses; /* per-script global uses */ JSAtomList globalMap; /* per-script map of global name to globalUses vector */ + /* Vectors of pn_cookie slot values. */ + typedef js::Vector SlotVector; + SlotVector closedArgs; + SlotVector closedVars; + /* * Initialize cg to allocate bytecode space from codePool, source note * space from notePool, and all other arena-allocated temporaries from @@ -595,6 +599,8 @@ struct JSCodeGenerator : public JSTreeContext } bool compilingForEval() { return !!(flags & TCF_COMPILE_FOR_EVAL); } + + bool shouldNoteClosedName(JSParseNode *pn); }; #define CG_TS(cg) TS((cg)->parser) diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index c31d5d4e0ccf..a9e06aa8c145 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -390,24 +390,26 @@ WrapEscapingClosure(JSContext *cx, JSStackFrame *fp, JSFunction *fun) uintN nsrcnotes = (sn - snbase) + 1; /* NB: GC must not occur before wscript is homed in wfun->u.i.script. */ - JSScript *wscript = js_NewScript(cx, script->length, nsrcnotes, - script->atomMap.length, - (script->objectsOffset != 0) - ? script->objects()->length - : 0, - fun->u.i.nupvars, - (script->regexpsOffset != 0) - ? script->regexps()->length - : 0, - (script->trynotesOffset != 0) - ? script->trynotes()->length - : 0, - (script->constOffset != 0) - ? script->consts()->length - : 0, - (script->globalsOffset != 0) - ? script->globals()->length - : 0); + JSScript *wscript = JSScript::NewScript(cx, script->length, nsrcnotes, + script->atomMap.length, + (script->objectsOffset != 0) + ? script->objects()->length + : 0, + fun->u.i.nupvars, + (script->regexpsOffset != 0) + ? script->regexps()->length + : 0, + (script->trynotesOffset != 0) + ? script->trynotes()->length + : 0, + (script->constOffset != 0) + ? script->consts()->length + : 0, + (script->globalsOffset != 0) + ? script->globals()->length + : 0, + script->nClosedArgs, + script->nClosedVars); if (!wscript) return NULL; @@ -433,6 +435,8 @@ WrapEscapingClosure(JSContext *cx, JSStackFrame *fp, JSFunction *fun) memcpy(wscript->globals()->vector, script->globals()->vector, wscript->globals()->length * sizeof(GlobalSlotArray::Entry)); } + if (script->nClosedArgs + script->nClosedVars != 0) + script->copyClosedSlotsTo(wscript); if (wfun->u.i.nupvars != 0) { JS_ASSERT(wfun->u.i.nupvars == wscript->upvars()->length); @@ -472,10 +476,6 @@ WrapEscapingClosure(JSContext *cx, JSStackFrame *fp, JSFunction *fun) * Fill in the rest of wscript. This means if you add members to JSScript * you must update this code. FIXME: factor into JSScript::clone method. */ - wscript->noScriptRval = script->noScriptRval; - wscript->savedCallerFun = script->savedCallerFun; - wscript->hasSharps = script->hasSharps; - wscript->strictModeCode = script->strictModeCode; wscript->setVersion(script->getVersion()); wscript->nfixed = script->nfixed; wscript->filename = script->filename; @@ -483,6 +483,14 @@ WrapEscapingClosure(JSContext *cx, JSStackFrame *fp, JSFunction *fun) wscript->nslots = script->nslots; wscript->staticLevel = script->staticLevel; wscript->principals = script->principals; + wscript->noScriptRval = script->noScriptRval; + wscript->savedCallerFun = script->savedCallerFun; + wscript->hasSharps = script->hasSharps; + wscript->strictModeCode = script->strictModeCode; + wscript->compileAndGo = script->compileAndGo; + wscript->usesEval = script->usesEval; + wscript->usesArguments = script->usesArguments; + wscript->warnedAboutTwoArgumentEval = script->warnedAboutTwoArgumentEval; if (wscript->principals) JSPRINCIPALS_HOLD(cx, wscript->principals); #ifdef CHECK_SCRIPT_OWNER @@ -1131,21 +1139,30 @@ js_PutCallObject(JSContext *cx, JSStackFrame *fp) uint32 nargs = fun->nargs; uint32 nvars = fun->u.i.nvars; -#ifdef JS_METHODJIT JS_STATIC_ASSERT(JS_INITIAL_NSLOTS == JSSLOT_PRIVATE + JSObject::CALL_RESERVED_SLOTS + 1); + JSScript *script = fun->u.i.script; memcpy(callobj.dslots, fp->formalArgs(), nargs * sizeof(Value)); - if (!script->jit || script->usesEval || script->debugMode) { - memcpy(callobj.dslots + nargs, fp->slots(), nvars * sizeof(Value)); - } else if (script->jit) { - for (uint32 i = 0; i < script->jit->nescaping; i++) { - uint32 e = script->jit->escaping[i]; + if (script->usesEval || script->debugMode) { + CopyValuesToCallObject(callobj, nargs, fp->formalArgs(), nvars, fp->slots()); + } else { + /* + * For each arg & var that is closed over, copy it from the stack + * into the call object. + */ + JSScript *script = fun->u.i.script; + uint32 nclosed = script->nClosedArgs; + for (uint32 i = 0; i < nclosed; i++) { + uint32 e = script->getClosedArg(i); + callobj.dslots[e] = fp->formalArg(e); + } + + nclosed = script->nClosedVars; + for (uint32 i = 0; i < nclosed; i++) { + uint32 e = script->getClosedVar(i); callobj.dslots[nargs + e] = fp->slots()[e]; } } -#else - CopyValuesToCallObject(callobj, nargs, fp->formalArgs(), nvars, fp->slots()); -#endif } /* Clear private pointers to fp, which is about to go away (js_Invoke). */ diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 5b78f376f24e..7d368fba610a 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -2465,8 +2465,7 @@ END_CASE(JSOP_TRACE) /* ADD_EMPTY_CASE is not used here as JSOP_LINENO_LENGTH == 3. */ BEGIN_CASE(JSOP_LINENO) -BEGIN_CASE(JSOP_DEFUPVAR) -END_CASE(JSOP_DEFUPVAR) +END_CASE(JSOP_LINENO) BEGIN_CASE(JSOP_PUSH) PUSH_UNDEFINED(); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 93b732ceab9e..ddec555775d6 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -3183,7 +3183,7 @@ js_PutBlockObject(JSContext *cx, JSBool normalUnwind) JS_ASSERT(count >= 1); if (normalUnwind) { - uintN slot = JSSLOT_BLOCK_DEPTH + 1; + uintN slot = JSSLOT_BLOCK_FIRST_FREE_SLOT; uintN flen = JS_MIN(count, JS_INITIAL_NSLOTS - slot); uintN stop = slot + flen; diff --git a/js/src/jsobj.h b/js/src/jsobj.h index fc0a6d644d31..62c03b418eb2 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -1247,6 +1247,7 @@ inline bool JSObject::isBlock() const { return getClass() == &js_BlockClass; } * outlives the frame). */ static const uint32 JSSLOT_BLOCK_DEPTH = JSSLOT_PRIVATE + 1; +static const uint32 JSSLOT_BLOCK_FIRST_FREE_SLOT = JSSLOT_BLOCK_DEPTH + 1; inline bool JSObject::isStaticBlock() const diff --git a/js/src/jsopcode.tbl b/js/src/jsopcode.tbl index ff44f0001846..417fd0863459 100644 --- a/js/src/jsopcode.tbl +++ b/js/src/jsopcode.tbl @@ -611,5 +611,3 @@ OPDEF(JSOP_GLOBALDEC, 244,"globaldec", NULL, 3, 0, 1, 15, JOF_GLOBAL OPDEF(JSOP_CALLGLOBAL, 245,"callglobal", NULL, 3, 0, 2, 19, JOF_GLOBAL|JOF_NAME|JOF_CALLOP) OPDEF(JSOP_FORGLOBAL, 246,"forglobal", NULL, 3, 1, 1, 19, JOF_GLOBAL|JOF_NAME|JOF_FOR|JOF_TMPSLOT) -OPDEF(JSOP_DEFUPVAR, 247,"defupvar", NULL, 3, 0, 0, 19, JOF_LOCAL|JOF_NAME) - diff --git a/js/src/jsparse.cpp b/js/src/jsparse.cpp index e0e3c93cb4cd..4e5dd3fc52bf 100644 --- a/js/src/jsparse.cpp +++ b/js/src/jsparse.cpp @@ -983,7 +983,7 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *calle #ifdef JS_ARENAMETER JS_DumpArenaStats(stdout); #endif - script = js_NewScriptFromCG(cx, &cg); + script = JSScript::NewScriptFromCG(cx, &cg); if (script && funbox && script != script->emptyScript()) script->savedCallerFun = true; @@ -1551,9 +1551,9 @@ static JSParseNode * MakeDefIntoUse(JSDefinition *dn, JSParseNode *pn, JSAtom *atom, JSTreeContext *tc) { /* - * If dn is var, const, or let, and it has an initializer, then we must - * rewrite it to be an assignment node, whose freshly allocated left-hand - * side becomes a use of pn. + * If dn is arg, or in [var, const, let] and has an initializer, then we + * must rewrite it to be an assignment node, whose freshly allocated + * left-hand side becomes a use of pn. */ if (dn->isBindingForm()) { JSParseNode *rhs = dn->expr(); @@ -2610,7 +2610,7 @@ LeaveFunction(JSParseNode *fn, JSTreeContext *funtc, JSAtom *funAtom = NULL, * Make sure to deoptimize lexical dependencies that are polluted * by eval or with, to safely statically bind globals (see bug 561923). */ - if ((funtc->flags & TCF_FUN_CALLS_EVAL) || + if (funtc->callsEval() || (outer_ale && tc->innermostWith && ALE_DEFN(outer_ale)->pn_pos < tc->innermostWith->pn_pos)) { DeoptimizeUsesWithin(dn, fn->pn_pos); @@ -2785,7 +2785,7 @@ Parser::functionArguments(JSTreeContext &funtc, JSFunctionBox *funbox, JSFunctio list = ListNode::create(&funtc); if (!list) return false; - list->pn_type = TOK_COMMA; + list->pn_type = TOK_VAR; list->makeEmpty(); *listp = list; } diff --git a/js/src/jsparse.h b/js/src/jsparse.h index c77ce3bf75d2..bbfd41fd40c4 100644 --- a/js/src/jsparse.h +++ b/js/src/jsparse.h @@ -535,6 +535,7 @@ public: bool isDeoptimized() const { return test(PND_DEOPTIMIZED); } bool isAssigned() const { return test(PND_ASSIGNED); } bool isFunArg() const { return test(PND_FUNARG); } + bool isClosed() const { return test(PND_CLOSED); } /* Defined below, see after struct JSDefinition. */ void setFunArg(); diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp index dc2a45e11377..f4cdf9c45b80 100644 --- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -2664,7 +2664,7 @@ ASTSerializer::functionArgsAndBody(JSParseNode *pn, NodeVector &args, Value *bod LOCAL_ASSERT(head && PN_TYPE(head) == TOK_SEMI); pndestruct = head->pn_kid; - LOCAL_ASSERT(pndestruct && PN_TYPE(pndestruct) == TOK_COMMA); + LOCAL_ASSERT(pndestruct && PN_TYPE(pndestruct) == TOK_VAR); } else { pndestruct = NULL; } diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 61164ea69cd5..9ca7bf3fc796 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -79,13 +79,17 @@ static const jsbytecode emptyScriptCode[] = {JSOP_STOP, SRC_NULL}; JS_INIT_STATIC_CLIST(NULL), const_cast(emptyScriptCode), 1, JSVERSION_DEFAULT, 0, 0, 0, 0, 0, 0, 0, true, false, false, false, false, - false, true, + false, /* usesEval */ + false, /* usesArguments */ + true, /* warnedAboutTwoArgumentEval */ #ifdef JS_METHODJIT - /* debugMode */ - false, + false, /* debugMode */ #endif const_cast(emptyScriptCode), - {0, NULL}, NULL, 0, 0, 0, NULL, {NULL}, + {0, NULL}, NULL, 0, 0, 0, + 0, /* nClosedArgs */ + 0, /* nClosedVars */ + NULL, {NULL}, #ifdef CHECK_SCRIPT_OWNER reinterpret_cast(1) #endif @@ -93,6 +97,16 @@ static const jsbytecode emptyScriptCode[] = {JSOP_STOP, SRC_NULL}; #if JS_HAS_XDR +enum ScriptBits { + NoScriptRval, + SavedCallerFun, + HasSharps, + StrictModeCode, + UsesEval, + CompileAndGo, + UsesArguments +}; + JSBool js_XDRScript(JSXDRState *xdr, JSScript **scriptp, bool needMutableScript, JSBool *hasMagic) @@ -103,12 +117,14 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, bool needMutableScript, jsbytecode *code; uint32 length, lineno, nslots, magic; uint32 natoms, nsrcnotes, ntrynotes, nobjects, nupvars, nregexps, nconsts, i; - uint32 prologLength, version; + uint32 prologLength, version, encodedClosedCount; + uint16 nClosedArgs, nClosedVars; JSPrincipals *principals; uint32 encodeable; JSBool filenameWasSaved; jssrcnote *notes, *sn; JSSecurityCallbacks *callbacks; + uint32 scriptBits = 0; cx = xdr->cx; script = *scriptp; @@ -160,7 +176,7 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, bool needMutableScript, * the shorthand (0 length word) for us. Make a new mutable empty * script here and return it immediately. */ - script = js_NewScript(cx, 1, 1, 0, 0, 0, 0, 0, 0, 0); + script = JSScript::NewScript(cx, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); if (!script) return JS_FALSE; @@ -202,6 +218,25 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, bool needMutableScript, ntrynotes = script->trynotes()->length; if (script->constOffset != 0) nconsts = script->consts()->length; + + nClosedArgs = script->nClosedArgs; + nClosedVars = script->nClosedVars; + encodedClosedCount = (nClosedArgs << 16) | nClosedVars; + + if (script->noScriptRval) + scriptBits |= (1 << NoScriptRval); + if (script->savedCallerFun) + scriptBits |= (1 << SavedCallerFun); + if (script->hasSharps) + scriptBits |= (1 << HasSharps); + if (script->strictModeCode) + scriptBits |= (1 << StrictModeCode); + if (script->compileAndGo) + scriptBits |= (1 << CompileAndGo); + if (script->usesEval) + scriptBits |= (1 << UsesEval); + if (script->usesArguments) + scriptBits |= (1 << UsesArguments); } if (!JS_XDRUint32(xdr, &prologLength)) @@ -227,12 +262,20 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, bool needMutableScript, return JS_FALSE; if (!JS_XDRUint32(xdr, &nconsts)) return JS_FALSE; + if (!JS_XDRUint32(xdr, &encodedClosedCount)) + return JS_FALSE; + if (!JS_XDRUint32(xdr, &scriptBits)) + return JS_FALSE; AutoScriptRooter tvr(cx, NULL); if (xdr->mode == JSXDR_DECODE) { - script = js_NewScript(cx, length, nsrcnotes, natoms, nobjects, nupvars, - nregexps, ntrynotes, nconsts, 0); + nClosedArgs = encodedClosedCount >> 16; + nClosedVars = encodedClosedCount & 0xFFFF; + + script = JSScript::NewScript(cx, length, nsrcnotes, natoms, nobjects, nupvars, + nregexps, ntrynotes, nconsts, 0, nClosedArgs, + nClosedVars); if (!script) return JS_FALSE; @@ -244,6 +287,21 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, bool needMutableScript, notes = script->notes(); *scriptp = script; tvr.setScript(script); + + if (scriptBits & (1 << NoScriptRval)) + script->noScriptRval = true; + if (scriptBits & (1 << SavedCallerFun)) + script->savedCallerFun = true; + if (scriptBits & (1 << HasSharps)) + script->hasSharps = true; + if (scriptBits & (1 << StrictModeCode)) + script->strictModeCode = true; + if (scriptBits & (1 << CompileAndGo)) + script->compileAndGo = true; + if (scriptBits & (1 << UsesEval)) + script->usesEval = true; + if (scriptBits & (1 << UsesArguments)) + script->usesArguments = true; } /* @@ -312,6 +370,7 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, bool needMutableScript, script->lineno = (uintN)lineno; script->nslots = (uint16)nslots; script->staticLevel = (uint16)(nslots >> 16); + } for (i = 0; i != natoms; ++i) { @@ -353,6 +412,14 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, bool needMutableScript, if (!js_XDRRegExpObject(xdr, &script->regexps()->vector[i])) goto error; } + for (i = 0; i != nClosedArgs; ++i) { + if (!JS_XDRUint32(xdr, &script->closedSlots[i])) + goto error; + } + for (i = 0; i != nClosedVars; ++i) { + if (!JS_XDRUint32(xdr, &script->closedSlots[nClosedArgs + i])) + goto error; + } if (ntrynotes != 0) { /* @@ -840,15 +907,18 @@ JS_STATIC_ASSERT(sizeof(JSScript) + 2 * sizeof(JSObjectArray) + sizeof(JSUpvarArray) < JS_BIT(8)); JSScript * -js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms, - uint32 nobjects, uint32 nupvars, uint32 nregexps, - uint32 ntrynotes, uint32 nconsts, uint32 nglobals) +JSScript::NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms, + uint32 nobjects, uint32 nupvars, uint32 nregexps, + uint32 ntrynotes, uint32 nconsts, uint32 nglobals, + uint32 nClosedArgs, uint32 nClosedVars) { size_t size, vectorSize; JSScript *script; uint8 *cursor; unsigned constPadding = 0; + uint32 totalClosed = nClosedArgs + nClosedVars; + size = sizeof(JSScript) + sizeof(JSAtom *) * natoms; @@ -862,6 +932,8 @@ js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms, size += sizeof(JSTryNoteArray) + ntrynotes * sizeof(JSTryNote); if (nglobals != 0) size += sizeof(GlobalSlotArray) + nglobals * sizeof(GlobalSlotArray::Entry); + if (totalClosed != 0) + size += totalClosed * sizeof(uint32); if (nconsts != 0) { size += sizeof(JSConstArray); @@ -957,6 +1029,13 @@ js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms, cursor += vectorSize; } + if (totalClosed != 0) { + script->nClosedArgs = nClosedArgs; + script->nClosedVars = nClosedVars; + script->closedSlots = (uint32 *)cursor; + cursor += totalClosed * sizeof(uint32); + } + /* * NB: We allocate the vector of uint32 upvar cookies after all vectors of * pointers, to avoid misalignment on 64-bit platforms. See bug 514645. @@ -995,7 +1074,7 @@ js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms, } JSScript * -js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg) +JSScript::NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg) { uint32 mainLength, prologLength, nsrcnotes, nfixed; JSScript *script; @@ -1072,11 +1151,12 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg) skip_empty: CG_COUNT_FINAL_SRCNOTES(cg, nsrcnotes); - script = js_NewScript(cx, prologLength + mainLength, nsrcnotes, - cg->atomList.count, cg->objectList.length, - cg->upvarList.count, cg->regexpList.length, - cg->ntrynotes, cg->constList.length(), - cg->globalUses.length()); + script = NewScript(cx, prologLength + mainLength, nsrcnotes, + cg->atomList.count, cg->objectList.length, + cg->upvarList.count, cg->regexpList.length, + cg->ntrynotes, cg->constList.length(), + cg->globalUses.length(), cg->closedArgs.length(), + cg->closedVars.length()); if (!script) return NULL; @@ -1126,8 +1206,10 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg) script->strictModeCode = true; if (cg->flags & TCF_COMPILE_N_GO) script->compileAndGo = true; - if (cg->flags & TCF_FUN_CALLS_EVAL) + if (cg->callsEval()) script->usesEval = true; + if (cg->flags & TCF_FUN_USES_ARGUMENTS) + script->usesArguments = true; if (cg->upvarList.count != 0) { JS_ASSERT(cg->upvarList.count <= cg->upvarMap.length); @@ -1143,6 +1225,13 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg) cg->globalUses.length() * sizeof(GlobalSlotArray::Entry)); } + if (script->nClosedArgs) + memcpy(script->closedSlots, &cg->closedArgs[0], script->nClosedArgs * sizeof(uint32)); + if (script->nClosedVars) { + memcpy(&script->closedSlots[script->nClosedArgs], &cg->closedVars[0], + script->nClosedVars * sizeof(uint32)); + } + /* * We initialize fun->u.script to be the script constructed above * so that the debugger has a valid FUN_SCRIPT(fun). @@ -1562,3 +1651,9 @@ JSScript::isValidJitCode(void *jcode) } #endif +void +JSScript::copyClosedSlotsTo(JSScript *other) +{ + memcpy(other->closedSlots, closedSlots, nClosedArgs + nClosedVars); +} + diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 2c6d4e95622f..88321350d88a 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -189,6 +189,30 @@ struct CallSite; #endif struct JSScript { + /* + * Two successively less primitive ways to make a new JSScript. The first + * does *not* call a non-null cx->runtime->newScriptHook -- only the second, + * NewScriptFromCG, calls this optional debugger hook. + * + * The NewScript function can't know whether the script it creates belongs + * to a function, or is top-level or eval code, but the debugger wants access + * to the newly made script's function, if any -- so callers of NewScript + * are responsible for notifying the debugger after successfully creating any + * kind (function or other) of new JSScript. + * + * NB: NewScript always creates a new script; it never returns the empty + * script singleton (JSScript::emptyScript()). Callers who know they can use + * that read-only singleton are responsible for choosing it instead of calling + * NewScript with length and nsrcnotes equal to 1 and other parameters save + * cx all zero. + */ + static JSScript *NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms, + uint32 nobjects, uint32 nupvars, uint32 nregexps, + uint32 ntrynotes, uint32 nconsts, uint32 nglobals, + uint32 nClosedArgs, uint32 nClosedVars); + + static JSScript *NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg); + /* FIXME: bug 586181 */ JSCList links; /* Links for compartment script list */ jsbytecode *code; /* bytecodes and their immediate operands */ @@ -216,6 +240,7 @@ struct JSScript { bool strictModeCode:1; /* code is in strict mode */ bool compileAndGo:1; /* script was compiled with TCF_COMPILE_N_GO */ bool usesEval:1; /* script uses eval() */ + bool usesArguments:1; /* script uses arguments */ bool warnedAboutTwoArgumentEval:1; /* have warned about use of obsolete eval(s, o) in this script */ @@ -229,6 +254,8 @@ struct JSScript { uint32 lineno; /* base line number of script */ uint16 nslots; /* vars plus maximum stack depth */ uint16 staticLevel;/* static level for display maintenance */ + uint16 nClosedArgs; /* number of args which are closed over. */ + uint16 nClosedVars; /* number of vars which are closed over. */ JSPrincipals *principals;/* principals for this script */ union { /* @@ -253,6 +280,10 @@ struct JSScript { #ifdef CHECK_SCRIPT_OWNER JSThread *owner; /* for thread-safe life-cycle assertions */ #endif + + uint32 *closedSlots; /* vector of closed slots; args first, then vars. */ + + public: #ifdef JS_METHODJIT // Note: the other pointers in this group may be non-NULL only if // |execPool| is non-NULL. @@ -373,6 +404,18 @@ struct JSScript { } #endif + uint32 getClosedArg(uint32 index) { + JS_ASSERT(index < nClosedArgs); + return closedSlots[index]; + } + + uint32 getClosedVar(uint32 index) { + JS_ASSERT(index < nClosedVars); + return closedSlots[nClosedArgs + index]; + } + + void copyClosedSlotsTo(JSScript *other); + private: /* * Use const to put this in read-only memory if possible. We are stuck with @@ -448,31 +491,6 @@ js_MarkScriptFilenames(JSRuntime *rt); extern void js_SweepScriptFilenames(JSRuntime *rt); -/* - * Two successively less primitive ways to make a new JSScript. The first - * does *not* call a non-null cx->runtime->newScriptHook -- only the second, - * js_NewScriptFromCG, calls this optional debugger hook. - * - * The js_NewScript function can't know whether the script it creates belongs - * to a function, or is top-level or eval code, but the debugger wants access - * to the newly made script's function, if any -- so callers of js_NewScript - * are responsible for notifying the debugger after successfully creating any - * kind (function or other) of new JSScript. - * - * NB: js_NewScript always creates a new script; it never returns the empty - * script singleton (JSScript::emptyScript()). Callers who know they can use - * that read-only singleton are responsible for choosing it instead of calling - * js_NewScript with length and nsrcnotes equal to 1 and other parameters save - * cx all zero. - */ -extern JSScript * -js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms, - uint32 nobjects, uint32 nupvars, uint32 nregexps, - uint32 ntrynotes, uint32 nconsts, uint32 nglobals); - -extern JSScript * -js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg); - /* * New-script-hook calling is factored from js_NewScriptFromCG so that it * and callers of js_XDRScript can share this code. In the case of callers diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 5f2ada361d5e..58915c0794b8 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -15789,12 +15789,6 @@ TraceRecorder::record_JSOP_GETARGPROP() return getProp(argval(GET_ARGNO(cx->regs->pc))); } -JS_REQUIRES_STACK AbortableRecordingStatus -TraceRecorder::record_JSOP_DEFUPVAR() -{ - return ARECORD_CONTINUE; -} - JS_REQUIRES_STACK AbortableRecordingStatus TraceRecorder::record_JSOP_GETLOCALPROP() { diff --git a/js/src/jsxdrapi.h b/js/src/jsxdrapi.h index 30e125a0054d..70e10b0f9c62 100644 --- a/js/src/jsxdrapi.h +++ b/js/src/jsxdrapi.h @@ -205,7 +205,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id); * before deserialization of bytecode. If the saved version does not match * the current version, abort deserialization and invalidate the file. */ -#define JSXDR_BYTECODE_VERSION (0xb973c0de - 70) +#define JSXDR_BYTECODE_VERSION (0xb973c0de - 71) /* * Library-private functions. diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index 7b57e7973847..4b102279b054 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -53,6 +53,7 @@ #include "jsscriptinlines.h" #include "InlineFrameAssembler.h" #include "jscompartment.h" +#include "jsobjinlines.h" #include "jsautooplen.h" @@ -86,7 +87,6 @@ mjit::Compiler::Compiler(JSContext *cx, JSScript *script, JSFunction *fun, JSObj callPatches(ContextAllocPolicy(cx)), callSites(ContextAllocPolicy(cx)), doubleList(ContextAllocPolicy(cx)), - escapingList(ContextAllocPolicy(cx)), stubcc(cx, *this, frame, script) #if defined JS_TRACER ,addTraceHints(cx->traceJitEnabled) @@ -141,6 +141,9 @@ mjit::Compiler::Compile() script->debugMode = cx->compartment->debugMode; #endif + for (uint32 i = 0; i < script->nClosedVars; i++) + frame.setClosedVar(script->getClosedVar(i)); + CHECK_STATUS(generatePrologue()); CHECK_STATUS(generateMethod()); CHECK_STATUS(generateEpilogue()); @@ -304,7 +307,6 @@ mjit::Compiler::finishThisUp() JSC::LinkBuffer stubCode(result + masm.size(), stubcc.size()); size_t totalBytes = sizeof(JITScript) + - sizeof(uint32) * escapingList.length() + sizeof(void *) * script->length + #if defined JS_MONOIC sizeof(ic::MICInfo) * mics.length() + @@ -330,16 +332,6 @@ mjit::Compiler::finishThisUp() script->jit->nCallSites = callSites.length(); script->jit->invoke = result; - script->jit->nescaping = escapingList.length(); - if (escapingList.length()) { - script->jit->escaping = (uint32 *)cursor; - cursor += sizeof(uint32) * escapingList.length(); - for (uint32 i = 0; i < escapingList.length(); i++) - script->jit->escaping[i] = escapingList[i]; - } else { - script->jit->escaping = NULL; - } - /* Build the pc -> ncode mapping. */ void **nmap = (void **)cursor; script->nmap = nmap; @@ -1548,31 +1540,11 @@ mjit::Compiler::generateMethod() END_CASE(JSOP_STOP) BEGIN_CASE(JSOP_ENTERBLOCK) - { - // If this is an exception entry point, then jsl_InternalThrow has set - // VMFrame::fp to the correct fp for the entry point. We need to copy - // that value here to FpReg so that FpReg also has the correct sp. - // Otherwise, we would simply be using a stale FpReg value. - if (analysis[PC].exceptionEntry) - restoreFrameRegs(masm); - - /* For now, don't bother doing anything for this opcode. */ - JSObject *obj = script->getObject(fullAtomIndex(PC)); - frame.syncAndForgetEverything(); - masm.move(ImmPtr(obj), Registers::ArgReg1); - uint32 n = js_GetEnterBlockStackDefs(cx, script, PC); - stubCall(stubs::EnterBlock); - frame.enterBlock(n); - } - END_CASE(JSOP_ENTERBLOCK) + enterBlock(script->getObject(fullAtomIndex(PC))); + END_CASE(JSOP_ENTERBLOCK); BEGIN_CASE(JSOP_LEAVEBLOCK) - { - uint32 n = js_GetVariableStackUses(op, PC); - prepareStubCall(Uses(n)); - stubCall(stubs::LeaveBlock); - frame.leaveBlock(n); - } + leaveBlock(); END_CASE(JSOP_LEAVEBLOCK) BEGIN_CASE(JSOP_CALLLOCAL) @@ -1668,16 +1640,6 @@ mjit::Compiler::generateMethod() break; END_CASE(JSOP_GLOBALINC) - BEGIN_CASE(JSOP_DEFUPVAR) - { - uint32 slot = GET_SLOTNO(PC); - if (frame.addEscaping(slot) && slot < script->nfixed) { - if (!escapingList.append(slot)) - return Compile_Error; - } - } - END_CASE(JSOP_DEFUPVAR) - default: /* Sorry, this opcode isn't implemented yet. */ #ifdef JS_METHODJIT_SPEW @@ -4224,3 +4186,45 @@ mjit::Compiler::jumpAndTrace(Jump j, jsbytecode *target, Jump *slowOne, Jump *sl #endif } +void +mjit::Compiler::enterBlock(JSObject *obj) +{ + // If this is an exception entry point, then jsl_InternalThrow has set + // VMFrame::fp to the correct fp for the entry point. We need to copy + // that value here to FpReg so that FpReg also has the correct sp. + // Otherwise, we would simply be using a stale FpReg value. + if (analysis[PC].exceptionEntry) + restoreFrameRegs(masm); + + uint32 oldFrameDepth = frame.frameDepth(); + + /* For now, don't bother doing anything for this opcode. */ + frame.syncAndForgetEverything(); + masm.move(ImmPtr(obj), Registers::ArgReg1); + uint32 n = js_GetEnterBlockStackDefs(cx, script, PC); + stubCall(stubs::EnterBlock); + frame.enterBlock(n); + + uintN base = JSSLOT_FREE(&js_BlockClass); + uintN count = OBJ_BLOCK_COUNT(cx, obj); + uintN limit = base + count; + for (uintN slot = base, i = 0; slot < limit; slot++, i++) { + const Value &v = obj->getSlotRef(slot); + if (v.isBoolean() && v.toBoolean()) + frame.setClosedVar(oldFrameDepth + i); + } +} + +void +mjit::Compiler::leaveBlock() +{ + /* + * Note: After bug 535912, we can pass the block obj directly, inline + * PutBlockObject, and do away with the muckiness in PutBlockObject. + */ + uint32 n = js_GetVariableStackUses(JSOP_LEAVEBLOCK, PC); + prepareStubCall(Uses(n)); + stubCall(stubs::LeaveBlock); + frame.leaveBlock(n); +} + diff --git a/js/src/methodjit/Compiler.h b/js/src/methodjit/Compiler.h index 03bcb3695bb1..9d0371cc5366 100644 --- a/js/src/methodjit/Compiler.h +++ b/js/src/methodjit/Compiler.h @@ -229,7 +229,6 @@ class Compiler js::Vector callPatches; js::Vector callSites; js::Vector doubleList; - js::Vector escapingList; StubCompiler stubcc; Label invokeLabel; Label arityLabel; @@ -312,6 +311,8 @@ class Compiler bool jsop_callprop_generic(JSAtom *atom); void jsop_instanceof(); void jsop_name(JSAtom *atom); + void enterBlock(JSObject *obj); + void leaveBlock(); /* Fast arithmetic. */ void jsop_binary(JSOp op, VoidStub stub); diff --git a/js/src/methodjit/FrameState-inl.h b/js/src/methodjit/FrameState-inl.h index 5b6b556fda68..faad1822de65 100644 --- a/js/src/methodjit/FrameState-inl.h +++ b/js/src/methodjit/FrameState-inl.h @@ -713,7 +713,7 @@ FrameState::dupAt(int32 n) inline void FrameState::pushLocal(uint32 n) { - if (!eval && !escaping[n]) { + if (!eval && !isClosedVar(n)) { pushCopyOf(indexOfFe(getLocal(n))); } else { #ifdef DEBUG @@ -745,6 +745,8 @@ FrameState::enterBlock(uint32 n) JS_ASSERT(!tracker.nentries); JS_ASSERT(uint32(sp + n - locals) <= script->nslots); + if (!eval) + memset(&closedVars[uint32(sp - locals)], 0, n * sizeof(*closedVars)); sp += n; } @@ -758,15 +760,11 @@ FrameState::eviscerate(FrameEntry *fe) fe->setCopyOf(NULL); } -inline bool -FrameState::addEscaping(uint32 local) +inline void +FrameState::setClosedVar(uint32 slot) { - if (!eval) { - uint32 already = escaping[local]; - escaping[local] = 1; - return !already; - } - return false; + if (!eval) + closedVars[slot] = true; } inline StateRemat @@ -866,6 +864,12 @@ FrameState::loadDouble(FrameEntry *fe, FPRegisterID fpReg, Assembler &masm) cons masm.loadDouble(address, fpReg); } +inline bool +FrameState::isClosedVar(uint32 slot) +{ + return closedVars[slot]; +} + } /* namspace mjit */ } /* namspace js */ diff --git a/js/src/methodjit/FrameState.cpp b/js/src/methodjit/FrameState.cpp index 4077757051b2..4b26b8929463 100644 --- a/js/src/methodjit/FrameState.cpp +++ b/js/src/methodjit/FrameState.cpp @@ -70,9 +70,9 @@ FrameState::init(uint32 nargs) eval = script->usesEval || cx->compartment->debugMode; - size_t totalBytes = sizeof(FrameEntry) * nslots + // entries[] - sizeof(FrameEntry *) * nslots + // tracker.entries - (eval ? 0 : sizeof(uint32) * nslots); // closedVars[] + size_t totalBytes = sizeof(FrameEntry) * nslots + // entries[] + sizeof(FrameEntry *) * nslots + // tracker.entries + (eval ? 0 : sizeof(JSPackedBool) * nslots); // closedVars[] uint8 *cursor = (uint8 *)cx->calloc(totalBytes); if (!cursor) @@ -93,8 +93,8 @@ FrameState::init(uint32 nargs) cursor += sizeof(FrameEntry *) * nslots; if (!eval && nslots) { - escaping = (uint32 *)cursor; - cursor += sizeof(uint32) * nslots; + closedVars = (JSPackedBool *)cursor; + cursor += sizeof(JSPackedBool) * nslots; } JS_ASSERT(reinterpret_cast(entries) + totalBytes == cursor); @@ -1096,7 +1096,7 @@ FrameState::storeLocal(uint32 n, bool popGuaranteed, bool typeChange) storeTop(local, popGuaranteed, typeChange); - bool closed = eval || escaping[n]; + bool closed = eval || isClosedVar(n); if (closed || inTryBlock) { /* Ensure that the local variable remains synced. */ if (local->isCopy()) { diff --git a/js/src/methodjit/FrameState.h b/js/src/methodjit/FrameState.h index 1fbd60fd0658..d66415ba6ee5 100644 --- a/js/src/methodjit/FrameState.h +++ b/js/src/methodjit/FrameState.h @@ -772,10 +772,9 @@ class FrameState void shift(int32 n); /* - * Notifies the frame of a slot that can escape. Returns whether or not - * the slot was added. + * Notifies the frame of a slot that can escape. */ - inline bool addEscaping(uint32 local); + inline void setClosedVar(uint32 slot); inline void setInTryBlock(bool inTryBlock) { this->inTryBlock = inTryBlock; @@ -835,6 +834,8 @@ class FrameState return uint32(fe - entries); } + inline bool isClosedVar(uint32 slot); + private: JSContext *cx; JSScript *script; @@ -870,7 +871,7 @@ class FrameState mutable ImmutableSync reifier; - uint32 *escaping; + JSPackedBool *closedVars; bool eval; bool inTryBlock; }; diff --git a/js/src/methodjit/MethodJIT.h b/js/src/methodjit/MethodJIT.h index c1da3651549b..68d6dd0f0c31 100644 --- a/js/src/methodjit/MethodJIT.h +++ b/js/src/methodjit/MethodJIT.h @@ -178,8 +178,6 @@ struct JITScript { #endif void *invoke; /* invoke address */ void *arityCheck; /* arity check address */ - uint32 *escaping; /* list of escaping slots */ - uint32 nescaping; /* number of escaping slots */ }; /* Execute a method that has been JIT compiled. */ diff --git a/js/src/trace-test/tests/jaeger/bug592973-1.js b/js/src/trace-test/tests/jaeger/bug592973-1.js new file mode 100644 index 000000000000..470f84ee359b --- /dev/null +++ b/js/src/trace-test/tests/jaeger/bug592973-1.js @@ -0,0 +1,12 @@ +// vim: set ts=4 sw=4 tw=99 et: +function f(x) { + if (x) { + let y; + y = 12; + (function () { + assertEq(y, 12); + })(); + } +} +f(1); + diff --git a/js/src/trace-test/tests/jaeger/bug592973-2.js b/js/src/trace-test/tests/jaeger/bug592973-2.js new file mode 100644 index 000000000000..052c6226854d --- /dev/null +++ b/js/src/trace-test/tests/jaeger/bug592973-2.js @@ -0,0 +1,7 @@ +function f(a) { + function a() { + } +} + +/* Don't assert on JOF_NAME test in BindNameToSlot(). */ + diff --git a/js/src/trace-test/tests/jaeger/bug592973-3.js b/js/src/trace-test/tests/jaeger/bug592973-3.js new file mode 100644 index 000000000000..ae4694955f5c --- /dev/null +++ b/js/src/trace-test/tests/jaeger/bug592973-3.js @@ -0,0 +1,8 @@ +// vim: set ts=4 sw=4 tw=99 et: +function f([a, b, c, d]) { + a = b; + return function () { return a + b + c + d; }; +} + +var F = f(["a", "b", "c", "d"]); +assertEq(F(), "bbcd"); From afde1b864a294d19120b102345410594c4c244ae Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Fri, 1 Oct 2010 00:53:40 +0200 Subject: [PATCH 010/115] Bug 597950 - Part 1: Add API to create a D2D surface from a D3D10 Texture. r=vlad --- gfx/cairo/cairo/src/cairo-d2d-surface.cpp | 83 +++++++++++++++++++++++ gfx/cairo/cairo/src/cairo-win32.h | 16 +++++ 2 files changed, 99 insertions(+) diff --git a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp index 506ab107ae46..48bd68ffef98 100644 --- a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp +++ b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp @@ -3791,6 +3791,89 @@ FAIL_CREATEHANDLE: return _cairo_surface_create_in_error(_cairo_error(status)); } +cairo_surface_t * +cairo_d2d_surface_create_for_texture(cairo_device_t *device, + ID3D10Texture2D *texture, + cairo_content_t content) +{ + cairo_d2d_device_t *d2d_device = reinterpret_cast(device); + cairo_d2d_surface_t *newSurf = static_cast(malloc(sizeof(cairo_d2d_surface_t))); + new (newSurf) cairo_d2d_surface_t(); + + D2D1_ALPHA_MODE alpha = D2D1_ALPHA_MODE_PREMULTIPLIED; + if (content == CAIRO_CONTENT_COLOR) { + _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR); + alpha = D2D1_ALPHA_MODE_IGNORE; + } else { + _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, content); + } + + D2D1_SIZE_U sizePixels; + HRESULT hr; + + D3D10_TEXTURE2D_DESC desc; + RefPtr dxgiSurface; + D2D1_BITMAP_PROPERTIES bitProps; + D2D1_RENDER_TARGET_PROPERTIES props; + + texture->GetDesc(&desc); + + sizePixels.width = desc.Width; + sizePixels.height = desc.Height; + + newSurf->surface = texture; + + /** Create the DXGI surface. */ + hr = newSurf->surface->QueryInterface(IID_IDXGISurface, (void**)&dxgiSurface); + if (FAILED(hr)) { + goto FAIL_CREATE; + } + + props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, + D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, alpha)); + + if (desc.MiscFlags & D3D10_RESOURCE_MISC_GDI_COMPATIBLE) + props.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; + + hr = sD2DFactory->CreateDxgiSurfaceRenderTarget(dxgiSurface, + props, + &newSurf->rt); + + if (FAILED(hr)) { + goto FAIL_CREATE; + } + + bitProps = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, + alpha)); + + if (content != CAIRO_CONTENT_ALPHA) { + /* For some reason creation of shared bitmaps for A8 UNORM surfaces + * doesn't work even though the documentation suggests it does. The + * function will return an error if we try */ + hr = newSurf->rt->CreateSharedBitmap(IID_IDXGISurface, + dxgiSurface, + &bitProps, + &newSurf->surfaceBitmap); + + if (FAILED(hr)) { + goto FAIL_CREATE; + } + } + + newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush); + + newSurf->device = d2d_device; + cairo_addref_device(device); + d2d_device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf); + + return reinterpret_cast(newSurf); + +FAIL_CREATE: + newSurf->~cairo_d2d_surface_t(); + free(newSurf); + return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY)); +} + void cairo_d2d_scroll(cairo_surface_t *surface, int x, int y, cairo_rectangle_t *clip) { if (surface->type != CAIRO_SURFACE_TYPE_D2D) { diff --git a/gfx/cairo/cairo/src/cairo-win32.h b/gfx/cairo/cairo/src/cairo-win32.h index 2e4846701ad4..b5d337a21fc9 100644 --- a/gfx/cairo/cairo/src/cairo-win32.h +++ b/gfx/cairo/cairo/src/cairo-win32.h @@ -217,6 +217,22 @@ cairo_d2d_surface_create(cairo_device_t *device, cairo_public cairo_surface_t * cairo_d2d_surface_create_for_handle(cairo_device_t *device, HANDLE handle, cairo_content_t content); +/** + * Create a D3D surface from an ID3D10Texture2D texture, this is obtained from a + * CreateTexture2D call on a D3D10 device. This has to be an A8R8G8B8 format + * or an A8 format, the treatment of the alpha channel can be indicated using + * the content parameter. + * + * \param device Device used to create the surface + * \param texture Texture that we want to wrap + * \param content Content of the texture + * \return New cairo surface + */ +cairo_public cairo_surface_t * +cairo_d2d_surface_create_for_texture(cairo_device_t *device, + struct ID3D10Texture2D *texture, + cairo_content_t content); + /** * Present the backbuffer for a surface create for an HWND. This needs * to be called when the owner of the original window surface wants to From 81f24452aa9bf430178e3e6b29fad97c4a896a91 Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Fri, 1 Oct 2010 00:53:42 +0200 Subject: [PATCH 011/115] Bug 597950 - Part 2: Expose API to create a D2D surface from a D3D10 Texture. r=vlad --- gfx/thebes/gfxD2DSurface.cpp | 8 ++++++++ gfx/thebes/gfxD2DSurface.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/gfx/thebes/gfxD2DSurface.cpp b/gfx/thebes/gfxD2DSurface.cpp index dfa1ef1884f5..88aa6600b1dd 100644 --- a/gfx/thebes/gfxD2DSurface.cpp +++ b/gfx/thebes/gfxD2DSurface.cpp @@ -54,6 +54,14 @@ gfxD2DSurface::gfxD2DSurface(HANDLE handle, gfxContentType aContent) (cairo_content_t)aContent)); } +gfxD2DSurface::gfxD2DSurface(ID3D10Texture2D *texture, gfxContentType aContent) +{ + Init(cairo_d2d_surface_create_for_texture( + gfxWindowsPlatform::GetPlatform()->GetD2DDevice(), + texture, + (cairo_content_t)aContent)); +} + gfxD2DSurface::gfxD2DSurface(cairo_surface_t *csurf) { Init(csurf, PR_TRUE); diff --git a/gfx/thebes/gfxD2DSurface.h b/gfx/thebes/gfxD2DSurface.h index 3a08ffc5e103..d559da9fd8c4 100644 --- a/gfx/thebes/gfxD2DSurface.h +++ b/gfx/thebes/gfxD2DSurface.h @@ -42,6 +42,8 @@ #include +struct ID3D10Texture2D; + class THEBES_API gfxD2DSurface : public gfxASurface { public: @@ -53,6 +55,8 @@ public: gfxD2DSurface(HANDLE handle, gfxContentType aContent); + gfxD2DSurface(ID3D10Texture2D *texture, gfxContentType aContent); + gfxD2DSurface(cairo_surface_t *csurf); virtual ~gfxD2DSurface(); From be01040ebb197d3bcd8f97c99d2baf762f7a9753 Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Fri, 1 Oct 2010 00:53:44 +0200 Subject: [PATCH 012/115] Bug 546514 - Part 1: Detect presence of D3D10 headers for D3D10 layers. r=vlad --- config/autoconf.mk.in | 1 + configure.in | 2 ++ 2 files changed, 3 insertions(+) diff --git a/config/autoconf.mk.in b/config/autoconf.mk.in index a4400e1fc5f4..47cb8f36241c 100644 --- a/config/autoconf.mk.in +++ b/config/autoconf.mk.in @@ -525,6 +525,7 @@ MOZ_ENABLE_XREMOTE = @MOZ_ENABLE_XREMOTE@ MOZ_ENABLE_DWRITE_FONT = @MOZ_ENABLE_DWRITE_FONT@ MOZ_ENABLE_D2D_SURFACE = @MOZ_ENABLE_D2D_SURFACE@ MOZ_ENABLE_D3D9_LAYER = @MOZ_ENABLE_D3D9_LAYER@ +MOZ_ENABLE_D3D10_LAYER = @MOZ_ENABLE_D3D10_LAYER@ MOZ_GTK2_CFLAGS = @MOZ_GTK2_CFLAGS@ MOZ_GTK2_LIBS = @MOZ_GTK2_LIBS@ diff --git a/configure.in b/configure.in index d495590b8f93..3d4e6c0c5062 100644 --- a/configure.in +++ b/configure.in @@ -8425,6 +8425,7 @@ if test "$MOZ_TREE_CAIRO"; then fi AC_CHECK_HEADER(d3d9.h, MOZ_ENABLE_D3D9_LAYER=1) + AC_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1) AC_TRY_COMPILE([#include ], [int foo = DDLOCK_WAITNOTBUSY;], HAS_DDRAW=1, HAS_DDRAW=) if test -z "$HAS_DDRAW"; then @@ -8474,6 +8475,7 @@ if test "$MOZ_TREE_CAIRO"; then AC_SUBST(MOZ_ENABLE_DWRITE_FONT) AC_SUBST(MOZ_ENABLE_D2D_SURFACE) AC_SUBST(MOZ_ENABLE_D3D9_LAYER) + AC_SUBST(MOZ_ENABLE_D3D10_LAYER) AC_SUBST(CAIRO_FT_CFLAGS) AC_SUBST(HAS_OGLES) From a5835235f925750358cf82e667c2ccad5b28ca55 Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Fri, 1 Oct 2010 00:53:47 +0200 Subject: [PATCH 013/115] Bug 546514 - Part 2: Add #defines for D3D10 layers. r=vlad --- gfx/thebes/Makefile.in | 4 ++++ widget/src/windows/Makefile.in | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/gfx/thebes/Makefile.in b/gfx/thebes/Makefile.in index a1744130a036..ba7013a891ef 100644 --- a/gfx/thebes/Makefile.in +++ b/gfx/thebes/Makefile.in @@ -279,6 +279,10 @@ ifdef MOZ_ENABLE_D3D9_LAYER DEFINES += -DMOZ_ENABLE_D3D9_LAYER endif +ifdef MOZ_ENABLE_D3D10_LAYER +DEFINES += -DMOZ_ENABLE_D3D10_LAYER +endif + ACDEFINES += -UWIN32_LEAN_AND_MEAN endif diff --git a/widget/src/windows/Makefile.in b/widget/src/windows/Makefile.in index 10b3bee49e2e..6f62743722f9 100644 --- a/widget/src/windows/Makefile.in +++ b/widget/src/windows/Makefile.in @@ -112,6 +112,10 @@ ifdef MOZ_ENABLE_D3D9_LAYER DEFINES += -DMOZ_ENABLE_D3D9_LAYER endif +ifdef MOZ_ENABLE_D3D10_LAYER +DEFINES += -DMOZ_ENABLE_D3D10_LAYER +endif + ifdef BUILD_STATIC_LIBS DEFINES += -DMOZ_STATIC_COMPONENT_LIBS endif # BUILD_STATIC_LIBS From 889fee72235889ba1aa1dce8cf7276298a342b2e Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Fri, 1 Oct 2010 00:53:49 +0200 Subject: [PATCH 014/115] Bug 546514 - Part 3: Add D3D10 layers code. r=vlad --- gfx/layers/d3d10/CanvasLayerD3D10.cpp | 273 + gfx/layers/d3d10/CanvasLayerD3D10.h | 93 + gfx/layers/d3d10/ColorLayerD3D10.cpp | 93 + gfx/layers/d3d10/ColorLayerD3D10.h | 60 + gfx/layers/d3d10/ContainerLayerD3D10.cpp | 337 ++ gfx/layers/d3d10/ContainerLayerD3D10.h | 78 + gfx/layers/d3d10/ImageLayerD3D10.cpp | 395 ++ gfx/layers/d3d10/ImageLayerD3D10.h | 155 + gfx/layers/d3d10/LayerManagerD3D10.cpp | 502 ++ gfx/layers/d3d10/LayerManagerD3D10.fx | 248 + gfx/layers/d3d10/LayerManagerD3D10.h | 211 + gfx/layers/d3d10/LayerManagerD3D10Effect.h | 6307 ++++++++++++++++++++ gfx/layers/d3d10/ThebesLayerD3D10.cpp | 339 ++ gfx/layers/d3d10/ThebesLayerD3D10.h | 88 + 14 files changed, 9179 insertions(+) create mode 100644 gfx/layers/d3d10/CanvasLayerD3D10.cpp create mode 100644 gfx/layers/d3d10/CanvasLayerD3D10.h create mode 100644 gfx/layers/d3d10/ColorLayerD3D10.cpp create mode 100644 gfx/layers/d3d10/ColorLayerD3D10.h create mode 100644 gfx/layers/d3d10/ContainerLayerD3D10.cpp create mode 100644 gfx/layers/d3d10/ContainerLayerD3D10.h create mode 100644 gfx/layers/d3d10/ImageLayerD3D10.cpp create mode 100644 gfx/layers/d3d10/ImageLayerD3D10.h create mode 100644 gfx/layers/d3d10/LayerManagerD3D10.cpp create mode 100644 gfx/layers/d3d10/LayerManagerD3D10.fx create mode 100644 gfx/layers/d3d10/LayerManagerD3D10.h create mode 100644 gfx/layers/d3d10/LayerManagerD3D10Effect.h create mode 100644 gfx/layers/d3d10/ThebesLayerD3D10.cpp create mode 100644 gfx/layers/d3d10/ThebesLayerD3D10.h diff --git a/gfx/layers/d3d10/CanvasLayerD3D10.cpp b/gfx/layers/d3d10/CanvasLayerD3D10.cpp new file mode 100644 index 000000000000..91e8cb1a31ca --- /dev/null +++ b/gfx/layers/d3d10/CanvasLayerD3D10.cpp @@ -0,0 +1,273 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Vladimir Vukicevic + * Bas Schouten + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "CanvasLayerD3D10.h" + +#include "gfxImageSurface.h" +#include "gfxWindowsSurface.h" +#include "gfxWindowsPlatform.h" + +namespace mozilla { +namespace layers { + +CanvasLayerD3D10::~CanvasLayerD3D10() +{ +} + +void +CanvasLayerD3D10::Initialize(const Data& aData) +{ + NS_ASSERTION(mSurface == nsnull, "BasicCanvasLayer::Initialize called twice!"); + + if (aData.mSurface) { + mSurface = aData.mSurface; + NS_ASSERTION(aData.mGLContext == nsnull, + "CanvasLayer can't have both surface and GLContext"); + mNeedsYFlip = PR_FALSE; + mDataIsPremultiplied = PR_TRUE; + } else if (aData.mGLContext) { + NS_ASSERTION(aData.mGLContext->IsOffscreen(), "canvas gl context isn't offscreen"); + mGLContext = aData.mGLContext; + mCanvasFramebuffer = mGLContext->GetOffscreenFBO(); + mDataIsPremultiplied = aData.mGLBufferIsPremultiplied; + mNeedsYFlip = PR_TRUE; + } else { + NS_ERROR("CanvasLayer created without mSurface or mGLContext?"); + } + + mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height); + + if (mSurface && mSurface->GetType() == gfxASurface::SurfaceTypeD2D) { + void *data = mSurface->GetData(&gKeyD3D10Texture); + if (data) { + mTexture = static_cast(data); + mIsD2DTexture = true; + device()->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView)); + return; + } + } + + mIsD2DTexture = false; + + CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, mBounds.width, mBounds.height, 1, 1); + desc.Usage = D3D10_USAGE_DYNAMIC; + desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + + HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(mTexture)); + if (FAILED(hr)) { + NS_WARNING("Failed to create texture for CanvasLayer!"); + return; + } + device()->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView)); +} + +void +CanvasLayerD3D10::Updated(const nsIntRect& aRect) +{ + if (mIsD2DTexture) { + mSurface->Flush(); + return; + } + + if (mGLContext) { + // WebGL reads entire surface. + D3D10_MAPPED_TEXTURE2D map; + + HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map); + + if (FAILED(hr)) { + NS_WARNING("Failed to map CanvasLayer texture."); + return; + } + + PRUint8 *destination; + if (map.RowPitch != mBounds.width * 4) { + destination = new PRUint8[mBounds.width * mBounds.height * 4]; + } else { + destination = (PRUint8*)map.pData; + } + + // We have to flush to ensure that any buffered GL operations are + // in the framebuffer before we read. + mGLContext->fFlush(); + + PRUint32 currentFramebuffer = 0; + + mGLContext->fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, (GLint*)¤tFramebuffer); + + // Make sure that we read pixels from the correct framebuffer, regardless + // of what's currently bound. + if (currentFramebuffer != mCanvasFramebuffer) + mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mCanvasFramebuffer); + + // For simplicity, we read the entire framebuffer for now -- in + // the future we should use aRect, though with WebGL we don't + // have an easy way to generate one. + nsRefPtr tmpSurface = + new gfxImageSurface(destination, + gfxIntSize(mBounds.width, mBounds.height), + mBounds.width * 4, + gfxASurface::ImageFormatARGB32); + mGLContext->ReadPixelsIntoImageSurface(0, 0, + mBounds.width, mBounds.height, + tmpSurface); + tmpSurface = nsnull; + + // Put back the previous framebuffer binding. + if (currentFramebuffer != mCanvasFramebuffer) + mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, currentFramebuffer); + + if (map.RowPitch != mBounds.width * 4) { + for (int y = 0; y < mBounds.height; y++) { + memcpy((PRUint8*)map.pData + map.RowPitch * y, + destination + mBounds.width * 4 * y, + mBounds.width * 4); + } + delete [] destination; + } + mTexture->Unmap(0); + } else if (mSurface) { + RECT r; + r.left = aRect.x; + r.top = aRect.y; + r.right = aRect.XMost(); + r.bottom = aRect.YMost(); + + D3D10_MAPPED_TEXTURE2D map; + HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map); + + if (FAILED(hr)) { + NS_WARNING("Failed to lock CanvasLayer texture."); + return; + } + + PRUint8 *startBits; + PRUint32 sourceStride; + + nsRefPtr dstSurface; + + dstSurface = new gfxImageSurface((unsigned char*)map.pData, + gfxIntSize(aRect.width, aRect.height), + map.RowPitch, + gfxASurface::ImageFormatARGB32); + nsRefPtr ctx = new gfxContext(dstSurface); + ctx->Translate(gfxPoint(-aRect.x, -aRect.y)); + ctx->SetOperator(gfxContext::OPERATOR_SOURCE); + ctx->SetSource(mSurface); + ctx->Paint(); + + mTexture->Unmap(0); + } +} + +Layer* +CanvasLayerD3D10::GetLayer() +{ + return this; +} + +void +CanvasLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) +{ + if (!mTexture) { + return; + } + + nsIntRect visibleRect = mVisibleRegion.GetBounds(); + + gfx3DMatrix transform = mTransform * aTransform; + effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64); + effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(GetOpacity() * aOpacity); + + ID3D10EffectTechnique *technique; + + if (mDataIsPremultiplied) { + if (mSurface && mSurface->GetContentType() == gfxASurface::CONTENT_COLOR) { + if (mFilter == gfxPattern::FILTER_NEAREST) { + technique = effect()->GetTechniqueByName("RenderRGBLayerPremulPoint"); + } else { + technique = effect()->GetTechniqueByName("RenderRGBLayerPremul"); + } + } else { + if (mFilter == gfxPattern::FILTER_NEAREST) { + technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPoint"); + } else { + technique = effect()->GetTechniqueByName("RenderRGBALayerPremul"); + } + } + } else { + if (mFilter == gfxPattern::FILTER_NEAREST) { + technique = effect()->GetTechniqueByName("RenderRGBALayerNonPremulPoint"); + } else { + technique = effect()->GetTechniqueByName("RenderRGBALayerNonPremul"); + } + } + + if (mSRView) { + effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(mSRView); + } + + effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector( + ShaderConstantRectD3D10( + (float)mBounds.x, + (float)mBounds.y, + (float)mBounds.width, + (float)mBounds.height) + ); + + if (mNeedsYFlip) { + effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector( + ShaderConstantRectD3D10( + 0, + 1.0f, + 1.0f, + -1.0f) + ); + } + + technique->GetPassByIndex(0)->Apply(0); + device()->Draw(4, 0); + + if (mNeedsYFlip) { + effect()->GetVariableByName("vTextureCoords")->AsVector()-> + SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f)); + } +} + +} /* namespace layers */ +} /* namespace mozilla */ diff --git a/gfx/layers/d3d10/CanvasLayerD3D10.h b/gfx/layers/d3d10/CanvasLayerD3D10.h new file mode 100644 index 000000000000..08c1050bee87 --- /dev/null +++ b/gfx/layers/d3d10/CanvasLayerD3D10.h @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Vladimir Vukicevic + * Bas Schouten + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef GFX_CANVASLAYEROGL_H +#define GFX_CANVASLAYEROGL_H + +#include "LayerManagerD3D10.h" +#include "GLContext.h" +#include "gfxASurface.h" + +namespace mozilla { +namespace layers { + +class THEBES_API CanvasLayerD3D10 : public CanvasLayer, + public LayerD3D10 +{ +public: + CanvasLayerD3D10(LayerManagerD3D10 *aManager) + : CanvasLayer(aManager, NULL), + LayerD3D10(aManager), + mTexture(0), + mDataIsPremultiplied(PR_FALSE), + mNeedsYFlip(PR_FALSE) + { + mImplData = static_cast(this); + } + + ~CanvasLayerD3D10(); + + // CanvasLayer implementation + virtual void Initialize(const Data& aData); + virtual void Updated(const nsIntRect& aRect); + + // LayerD3D10 implementation + virtual Layer* GetLayer(); + virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform); + +private: + typedef mozilla::gl::GLContext GLContext; + + nsRefPtr mSurface; + nsRefPtr mGLContext; + + PRUint32 mCanvasFramebuffer; + + nsRefPtr mTexture; + nsRefPtr mSRView; + + nsIntRect mBounds; + + PRPackedBool mDataIsPremultiplied; + PRPackedBool mNeedsYFlip; + PRPackedBool mIsD2DTexture; +}; + +} /* layers */ +} /* mozilla */ +#endif /* GFX_CANVASLAYERD3D10_H */ diff --git a/gfx/layers/d3d10/ColorLayerD3D10.cpp b/gfx/layers/d3d10/ColorLayerD3D10.cpp new file mode 100644 index 000000000000..69724fcd73b0 --- /dev/null +++ b/gfx/layers/d3d10/ColorLayerD3D10.cpp @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Robert O'Callahan + * Bas Schouten + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ColorLayerD3D10.h" + +namespace mozilla { +namespace layers { + +ColorLayerD3D10::ColorLayerD3D10(LayerManagerD3D10 *aManager) + : ColorLayer(aManager, NULL) + , LayerD3D10(aManager) +{ + mImplData = static_cast(this); +} + +Layer* +ColorLayerD3D10::GetLayer() +{ + return this; +} + +void +ColorLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) +{ + float color[4]; + // color is premultiplied, so we need to adjust all channels + color[0] = (float)(mColor.r * GetOpacity() * aOpacity); + color[1] = (float)(mColor.g * GetOpacity() * aOpacity); + color[2] = (float)(mColor.b * GetOpacity() * aOpacity); + color[3] = (float)(mColor.a * GetOpacity() * aOpacity); + + gfx3DMatrix transform = mTransform * aTransform; + + effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64); + effect()->GetVariableByName("fLayerColor")->AsVector()->SetFloatVector(color); + + ID3D10EffectTechnique *technique; + technique = effect()->GetTechniqueByName("RenderSolidColorLayer"); + + nsIntRegionRectIterator iter(mVisibleRegion); + + const nsIntRect *iterRect; + while ((iterRect = iter.Next())) { + effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector( + ShaderConstantRectD3D10( + (float)iterRect->x, + (float)iterRect->y, + (float)iterRect->width, + (float)iterRect->height) + ); + + technique->GetPassByIndex(0)->Apply(0); + device()->Draw(4, 0); + } +} + +} /* layers */ +} /* mozilla */ diff --git a/gfx/layers/d3d10/ColorLayerD3D10.h b/gfx/layers/d3d10/ColorLayerD3D10.h new file mode 100644 index 000000000000..67676d12966d --- /dev/null +++ b/gfx/layers/d3d10/ColorLayerD3D10.h @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Bas Schouten + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef GFX_COLORLAYERD3D10_H +#define GFX_COLORLAYERD3D10_H + +#include "Layers.h" +#include "LayerManagerD3D10.h" + +namespace mozilla { +namespace layers { + +class ColorLayerD3D10 : public ColorLayer, + public LayerD3D10 +{ +public: + ColorLayerD3D10(LayerManagerD3D10 *aManager); + + /* LayerD3D10 implementation */ + Layer* GetLayer(); + virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform); +}; + +} /* layers */ +} /* mozilla */ +#endif /* GFX_THEBESLAYERD3D10_H */ diff --git a/gfx/layers/d3d10/ContainerLayerD3D10.cpp b/gfx/layers/d3d10/ContainerLayerD3D10.cpp new file mode 100644 index 000000000000..16ee47f05e53 --- /dev/null +++ b/gfx/layers/d3d10/ContainerLayerD3D10.cpp @@ -0,0 +1,337 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Bas Schouten + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ContainerLayerD3D10.h" +#include "nsAlgorithm.h" + +namespace mozilla { +namespace layers { + +ContainerLayerD3D10::ContainerLayerD3D10(LayerManagerD3D10 *aManager) + : ContainerLayer(aManager, NULL) + , LayerD3D10(aManager) +{ + mImplData = static_cast(this); +} + +ContainerLayerD3D10::~ContainerLayerD3D10() +{ + while (mFirstChild) { + RemoveChild(mFirstChild); + } +} + +void +ContainerLayerD3D10::InsertAfter(Layer* aChild, Layer* aAfter) +{ + aChild->SetParent(this); + if (!aAfter) { + Layer *oldFirstChild = GetFirstChild(); + mFirstChild = aChild; + aChild->SetNextSibling(oldFirstChild); + aChild->SetPrevSibling(nsnull); + if (oldFirstChild) { + oldFirstChild->SetPrevSibling(aChild); + } + NS_ADDREF(aChild); + return; + } + for (Layer *child = GetFirstChild(); + child; child = child->GetNextSibling()) { + if (aAfter == child) { + Layer *oldNextSibling = child->GetNextSibling(); + child->SetNextSibling(aChild); + aChild->SetNextSibling(oldNextSibling); + if (oldNextSibling) { + oldNextSibling->SetPrevSibling(aChild); + } + aChild->SetPrevSibling(child); + NS_ADDREF(aChild); + return; + } + } + NS_WARNING("Failed to find aAfter layer!"); +} + +void +ContainerLayerD3D10::RemoveChild(Layer *aChild) +{ + if (GetFirstChild() == aChild) { + mFirstChild = GetFirstChild()->GetNextSibling(); + if (mFirstChild) { + mFirstChild->SetPrevSibling(nsnull); + } + aChild->SetNextSibling(nsnull); + aChild->SetPrevSibling(nsnull); + aChild->SetParent(nsnull); + NS_RELEASE(aChild); + return; + } + Layer *lastChild = nsnull; + for (Layer *child = GetFirstChild(); child; + child = child->GetNextSibling()) { + if (child == aChild) { + // We're sure this is not our first child. So lastChild != NULL. + lastChild->SetNextSibling(child->GetNextSibling()); + if (child->GetNextSibling()) { + child->GetNextSibling()->SetPrevSibling(lastChild); + } + child->SetNextSibling(nsnull); + child->SetPrevSibling(nsnull); + child->SetParent(nsnull); + NS_RELEASE(aChild); + return; + } + lastChild = child; + } +} + +Layer* +ContainerLayerD3D10::GetLayer() +{ + return this; +} + +LayerD3D10* +ContainerLayerD3D10::GetFirstChildD3D10() +{ + if (!mFirstChild) { + return nsnull; + } + return static_cast(mFirstChild->ImplData()); +} + +void +ContainerLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) +{ + float renderTargetOffset[] = { 0, 0 }; + + nsIntRect visibleRect = mVisibleRegion.GetBounds(); + float opacity = GetOpacity() * aOpacity; + gfx3DMatrix transform = mTransform * aTransform; + PRBool useIntermediate = ShouldUseIntermediate(aOpacity, transform); + + nsRefPtr previousRTView; + nsRefPtr renderTexture; + nsRefPtr rtView; + float previousRenderTargetOffset[2]; + nsIntSize previousViewportSize; + + gfx3DMatrix oldViewMatrix; + + if (useIntermediate) { + device()->OMGetRenderTargets(1, getter_AddRefs(previousRTView), NULL); + + D3D10_TEXTURE2D_DESC desc; + memset(&desc, 0, sizeof(D3D10_TEXTURE2D_DESC)); + desc.ArraySize = 1; + desc.MipLevels = 1; + desc.Width = visibleRect.width; + desc.Height = visibleRect.height; + desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE; + desc.SampleDesc.Count = 1; + desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + device()->CreateTexture2D(&desc, NULL, getter_AddRefs(renderTexture)); + + device()->CreateRenderTargetView(renderTexture, NULL, getter_AddRefs(rtView)); + + float black[] = { 0, 0, 0, 0}; + device()->ClearRenderTargetView(rtView, black); + + ID3D10RenderTargetView *rtViewPtr = rtView; + device()->OMSetRenderTargets(1, &rtViewPtr, NULL); + + effect()->GetVariableByName("vRenderTargetOffset")-> + GetRawValue(previousRenderTargetOffset, 0, 8); + + renderTargetOffset[0] = (float)visibleRect.x; + renderTargetOffset[1] = (float)visibleRect.y; + effect()->GetVariableByName("vRenderTargetOffset")-> + SetRawValue(renderTargetOffset, 0, 8); + + previousViewportSize = mD3DManager->GetViewport(); + mD3DManager->SetViewport(nsIntSize(visibleRect.Size())); + } + + /* + * Render this container's contents. + */ + LayerD3D10 *layerToRender = GetFirstChildD3D10(); + while (layerToRender) { + const nsIntRect *clipRect = layerToRender->GetLayer()->GetClipRect(); + + D3D10_RECT oldScissor; + if (clipRect || useIntermediate) { + UINT numRects = 1; + device()->RSGetScissorRects(&numRects, &oldScissor); + + RECT r; + if (clipRect) { + r.left = (LONG)(clipRect->x - renderTargetOffset[0]); + r.top = (LONG)(clipRect->y - renderTargetOffset[1]); + r.right = (LONG)(clipRect->x - renderTargetOffset[0] + clipRect->width); + r.bottom = (LONG)(clipRect->y - renderTargetOffset[1] + clipRect->height); + } else { + // useIntermediate == true + r.left = 0; + r.top = 0; + r.right = visibleRect.width; + r.bottom = visibleRect.height; + } + + D3D10_RECT d3drect; + if (!useIntermediate) { + // Scissor rect should be an intersection of the old and current scissor. + r.left = NS_MAX(oldScissor.left, r.left); + r.right = NS_MIN(oldScissor.right, r.right); + r.top = NS_MAX(oldScissor.top, r.top); + r.bottom = NS_MIN(oldScissor.bottom, r.bottom); + } + + if (r.left >= r.right || r.top >= r.bottom) { + // Entire layer's clipped out, don't bother drawing. + Layer *nextSibling = layerToRender->GetLayer()->GetNextSibling(); + layerToRender = nextSibling ? static_cast(nextSibling-> + ImplData()) + : nsnull; + continue; + } + + d3drect.left = NS_MAX(r.left, 0); + d3drect.top = NS_MAX(r.top, 0); + d3drect.bottom = r.bottom; + d3drect.right = r.right; + + device()->RSSetScissorRects(1, &d3drect); + } + + // SetScissorRect + if (!useIntermediate) { + layerToRender->RenderLayer(opacity, transform); + } else { + layerToRender->RenderLayer(1.0f, gfx3DMatrix()); + } + + if (clipRect || useIntermediate) { + device()->RSSetScissorRects(1, &oldScissor); + } + + Layer *nextSibling = layerToRender->GetLayer()->GetNextSibling(); + layerToRender = nextSibling ? static_cast(nextSibling-> + ImplData()) + : nsnull; + } + + if (useIntermediate) { + mD3DManager->SetViewport(previousViewportSize); + ID3D10RenderTargetView *rtView = previousRTView; + device()->OMSetRenderTargets(1, &rtView, NULL); + effect()->GetVariableByName("vRenderTargetOffset")-> + SetRawValue(previousRenderTargetOffset, 0, 8); + + effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64); + effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(opacity); + + ID3D10EffectTechnique *technique; + technique = effect()->GetTechniqueByName("RenderRGBALayerPremul"); + + effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector( + ShaderConstantRectD3D10( + (float)visibleRect.x, + (float)visibleRect.y, + (float)visibleRect.width, + (float)visibleRect.height) + ); + + technique->GetPassByIndex(0)->Apply(0); + + ID3D10ShaderResourceView *view; + device()->CreateShaderResourceView(renderTexture, NULL, &view); + device()->PSSetShaderResources(0, 1, &view); + device()->Draw(4, 0); + view->Release(); + } +} + +void +ContainerLayerD3D10::LayerManagerDestroyed() +{ + while (mFirstChild) { + GetFirstChildD3D10()->LayerManagerDestroyed(); + RemoveChild(mFirstChild); + } +} + +void +ContainerLayerD3D10::Validate() +{ + Layer *layer = GetFirstChild(); + while (layer) { + static_cast(layer->ImplData())->Validate(); + layer = layer->GetNextSibling(); + } +} + +bool +ContainerLayerD3D10::ShouldUseIntermediate(float aOpacity, + const gfx3DMatrix &aMatrix) +{ + if (aOpacity == 1.0f && aMatrix.IsIdentity()) { + return false; + } + + Layer *firstChild = GetFirstChild(); + + if (!firstChild || (!firstChild->GetNextSibling() && + !firstChild->GetClipRect())) { + // If we forward our transform to a child without using an intermediate, we + // need to be sure that child does not have a clip rect since the clip rect + // needs to be applied after its transform. + return false; + } + + if (aMatrix.IsIdentity() && (!firstChild || !firstChild->GetNextSibling())) { + // If there's no transforms applied and a single child, opacity can always + // be forwarded to our only child. + return false; + } + + return true; +} + +} /* layers */ +} /* mozilla */ diff --git a/gfx/layers/d3d10/ContainerLayerD3D10.h b/gfx/layers/d3d10/ContainerLayerD3D10.h new file mode 100644 index 000000000000..9973ec019e17 --- /dev/null +++ b/gfx/layers/d3d10/ContainerLayerD3D10.h @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Bas Schouten + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef GFX_CONTAINERLAYERD3D10_H +#define GFX_CONTAINERLAYERD3D10_H + +#include "Layers.h" +#include "LayerManagerD3D10.h" + +namespace mozilla { +namespace layers { + +class ContainerLayerD3D10 : public ContainerLayer, + public LayerD3D10 +{ +public: + ContainerLayerD3D10(LayerManagerD3D10 *aManager); + ~ContainerLayerD3D10(); + + nsIntRect GetVisibleRect() { return mVisibleRegion.GetBounds(); } + + /* ContainerLayer implementation */ + virtual void InsertAfter(Layer* aChild, Layer* aAfter); + + virtual void RemoveChild(Layer* aChild); + + /* LayerD3D10 implementation */ + Layer* GetLayer(); + + LayerD3D10* GetFirstChildD3D10(); + + void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform); + void Validate(); + + virtual void LayerManagerDestroyed(); + +private: + bool ShouldUseIntermediate(float aOpacity, const gfx3DMatrix &aTransform); +}; + +} /* layers */ +} /* mozilla */ + +#endif /* GFX_CONTAINERLAYERD3D10_H */ diff --git a/gfx/layers/d3d10/ImageLayerD3D10.cpp b/gfx/layers/d3d10/ImageLayerD3D10.cpp new file mode 100644 index 000000000000..8a06a40391bb --- /dev/null +++ b/gfx/layers/d3d10/ImageLayerD3D10.cpp @@ -0,0 +1,395 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Bas Schouten + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ImageLayerD3D10.h" +#include "gfxImageSurface.h" +#include "yuv_convert.h" + +namespace mozilla { +namespace layers { + +using mozilla::MutexAutoLock; + +ImageContainerD3D10::ImageContainerD3D10(LayerManagerD3D10 *aManager) + : ImageContainer(aManager) + , mActiveImageLock("mozilla.layers.ImageContainerD3D10.mActiveImageLock") +{ +} + +already_AddRefed +ImageContainerD3D10::CreateImage(const Image::Format *aFormats, + PRUint32 aNumFormats) +{ + if (!aNumFormats) { + return nsnull; + } + nsRefPtr img; + if (aFormats[0] == Image::PLANAR_YCBCR) { + img = new PlanarYCbCrImageD3D10(static_cast(mManager)); + } else if (aFormats[0] == Image::CAIRO_SURFACE) { + img = new CairoImageD3D10(static_cast(mManager)); + } + return img.forget(); +} + +void +ImageContainerD3D10::SetCurrentImage(Image *aImage) +{ + MutexAutoLock lock(mActiveImageLock); + + mActiveImage = aImage; +} + +already_AddRefed +ImageContainerD3D10::GetCurrentImage() +{ + MutexAutoLock lock(mActiveImageLock); + + nsRefPtr retval = mActiveImage; + return retval.forget(); +} + +already_AddRefed +ImageContainerD3D10::GetCurrentAsSurface(gfxIntSize *aSize) +{ + MutexAutoLock lock(mActiveImageLock); + if (!mActiveImage) { + return nsnull; + } + + if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) { + PlanarYCbCrImageD3D10 *yuvImage = + static_cast(mActiveImage.get()); + if (yuvImage->HasData()) { + *aSize = yuvImage->mSize; + } + } else if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) { + CairoImageD3D10 *cairoImage = + static_cast(mActiveImage.get()); + *aSize = cairoImage->mSize; + } + + return static_cast(mActiveImage->GetImplData())->GetAsSurface(); +} + +gfxIntSize +ImageContainerD3D10::GetCurrentSize() +{ + MutexAutoLock lock(mActiveImageLock); + if (!mActiveImage) { + return gfxIntSize(0,0); + } + if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) { + PlanarYCbCrImageD3D10 *yuvImage = + static_cast(mActiveImage.get()); + if (!yuvImage->HasData()) { + return gfxIntSize(0,0); + } + return yuvImage->mSize; + + } else if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) { + CairoImageD3D10 *cairoImage = + static_cast(mActiveImage.get()); + return cairoImage->mSize; + } + + return gfxIntSize(0,0); +} + +PRBool +ImageContainerD3D10::SetLayerManager(LayerManager *aManager) +{ + // we can't do anything here for now + return PR_FALSE; +} + +Layer* +ImageLayerD3D10::GetLayer() +{ + return this; +} + +void +ImageLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) +{ + if (!GetContainer()) { + return; + } + + nsRefPtr image = GetContainer()->GetCurrentImage(); + + + gfx3DMatrix transform = mTransform * aTransform; + effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64); + effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(GetOpacity() * aOpacity); + + ID3D10EffectTechnique *technique; + + if (image->GetFormat() == Image::PLANAR_YCBCR) { + PlanarYCbCrImageD3D10 *yuvImage = + static_cast(image.get()); + + if (!yuvImage->HasData()) { + return; + } + + // TODO: At some point we should try to deal with mFilter here, you don't + // really want to use point filtering in the case of NEAREST, since that + // would also use point filtering for Chroma upsampling. Where most likely + // the user would only want point filtering for final RGB image upsampling. + + technique = effect()->GetTechniqueByName("RenderYCbCrLayer"); + + effect()->GetVariableByName("tY")->AsShaderResource()->SetResource(yuvImage->mYView); + effect()->GetVariableByName("tCb")->AsShaderResource()->SetResource(yuvImage->mCbView); + effect()->GetVariableByName("tCr")->AsShaderResource()->SetResource(yuvImage->mCrView); + + effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector( + ShaderConstantRectD3D10( + (float)0, + (float)0, + (float)yuvImage->mSize.width, + (float)yuvImage->mSize.height) + ); + } else if (image->GetFormat() == Image::CAIRO_SURFACE) { + CairoImageD3D10 *cairoImage = + static_cast(image.get()); + + if (mFilter == gfxPattern::FILTER_NEAREST) { + technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPoint"); + } else { + technique = effect()->GetTechniqueByName("RenderRGBALayerPremul"); + } + + if (cairoImage->mSRView) { + effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(cairoImage->mSRView); + } + + effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector( + ShaderConstantRectD3D10( + (float)0, + (float)0, + (float)cairoImage->mSize.width, + (float)cairoImage->mSize.height) + ); + } + + technique->GetPassByIndex(0)->Apply(0); + device()->Draw(4, 0); +} + +PlanarYCbCrImageD3D10::PlanarYCbCrImageD3D10(mozilla::layers::LayerManagerD3D10* aManager) + : PlanarYCbCrImage(static_cast(this)) + , mManager(aManager) + , mHasData(PR_FALSE) +{ +} + +void +PlanarYCbCrImageD3D10::SetData(const PlanarYCbCrImage::Data &aData) +{ + // XXX - For D3D10Ex we really should just copy to systemmem surfaces here. + // For now, we copy the data + int width_shift = 0; + int height_shift = 0; + if (aData.mYSize.width == aData.mCbCrSize.width && + aData.mYSize.height == aData.mCbCrSize.height) { + // YV24 format + width_shift = 0; + height_shift = 0; + mType = gfx::YV24; + } else if (aData.mYSize.width / 2 == aData.mCbCrSize.width && + aData.mYSize.height == aData.mCbCrSize.height) { + // YV16 format + width_shift = 1; + height_shift = 0; + mType = gfx::YV16; + } else if (aData.mYSize.width / 2 == aData.mCbCrSize.width && + aData.mYSize.height / 2 == aData.mCbCrSize.height ) { + // YV12 format + width_shift = 1; + height_shift = 1; + mType = gfx::YV12; + } else { + NS_ERROR("YCbCr format not supported"); + } + + mData = aData; + mData.mCbCrStride = mData.mCbCrSize.width = aData.mPicSize.width >> width_shift; + // Round up the values for width and height to make sure we sample enough data + // for the last pixel - See bug 590735 + if (width_shift && (aData.mPicSize.width & 1)) { + mData.mCbCrStride++; + mData.mCbCrSize.width++; + } + mData.mCbCrSize.height = aData.mPicSize.height >> height_shift; + if (height_shift && (aData.mPicSize.height & 1)) { + mData.mCbCrSize.height++; + } + mData.mYSize = aData.mPicSize; + mData.mYStride = mData.mYSize.width; + + mBuffer = new PRUint8[mData.mCbCrStride * mData.mCbCrSize.height * 2 + + mData.mYStride * mData.mYSize.height]; + mData.mYChannel = mBuffer; + mData.mCbChannel = mData.mYChannel + mData.mYStride * mData.mYSize.height; + mData.mCrChannel = mData.mCbChannel + mData.mCbCrStride * mData.mCbCrSize.height; + + int cbcr_x = aData.mPicX >> width_shift; + int cbcr_y = aData.mPicY >> height_shift; + + for (int i = 0; i < mData.mYSize.height; i++) { + memcpy(mData.mYChannel + i * mData.mYStride, + aData.mYChannel + ((aData.mPicY + i) * aData.mYStride) + aData.mPicX, + mData.mYStride); + } + for (int i = 0; i < mData.mCbCrSize.height; i++) { + memcpy(mData.mCbChannel + i * mData.mCbCrStride, + aData.mCbChannel + ((cbcr_y + i) * aData.mCbCrStride) + cbcr_x, + mData.mCbCrStride); + } + for (int i = 0; i < mData.mCbCrSize.height; i++) { + memcpy(mData.mCrChannel + i * mData.mCbCrStride, + aData.mCrChannel + ((cbcr_y + i) * aData.mCbCrStride) + cbcr_x, + mData.mCbCrStride); + } + + // Fix picture rect to be correct + mData.mPicX = mData.mPicY = 0; + mSize = aData.mPicSize; + + AllocateTextures(); + + mHasData = PR_TRUE; +} + +void +PlanarYCbCrImageD3D10::AllocateTextures() +{ + D3D10_SUBRESOURCE_DATA dataY; + D3D10_SUBRESOURCE_DATA dataCb; + D3D10_SUBRESOURCE_DATA dataCr; + CD3D10_TEXTURE2D_DESC descY(DXGI_FORMAT_R8_UNORM, + mData.mYSize.width, + mData.mYSize.height, 1, 1); + CD3D10_TEXTURE2D_DESC descCbCr(DXGI_FORMAT_R8_UNORM, + mData.mCbCrSize.width, + mData.mCbCrSize.height, 1, 1); + + descY.Usage = descCbCr.Usage = D3D10_USAGE_IMMUTABLE; + + dataY.pSysMem = mData.mYChannel; + dataY.SysMemPitch = mData.mYStride; + dataCb.pSysMem = mData.mCbChannel; + dataCb.SysMemPitch = mData.mCbCrStride; + dataCr.pSysMem = mData.mCrChannel; + dataCr.SysMemPitch = mData.mCbCrStride; + + mManager->device()->CreateTexture2D(&descY, &dataY, getter_AddRefs(mYTexture)); + mManager->device()->CreateTexture2D(&descCbCr, &dataCb, getter_AddRefs(mCbTexture)); + mManager->device()->CreateTexture2D(&descCbCr, &dataCr, getter_AddRefs(mCrTexture)); + mManager->device()->CreateShaderResourceView(mYTexture, NULL, getter_AddRefs(mYView)); + mManager->device()->CreateShaderResourceView(mCbTexture, NULL, getter_AddRefs(mCbView)); + mManager->device()->CreateShaderResourceView(mCrTexture, NULL, getter_AddRefs(mCrView)); +} + +already_AddRefed +PlanarYCbCrImageD3D10::GetAsSurface() +{ + nsRefPtr imageSurface = + new gfxImageSurface(mSize, gfxASurface::ImageFormatRGB24); + + // Convert from YCbCr to RGB now + gfx::ConvertYCbCrToRGB32(mData.mYChannel, + mData.mCbChannel, + mData.mCrChannel, + imageSurface->Data(), + 0, + 0, + mSize.width, + mSize.height, + mData.mYStride, + mData.mCbCrStride, + imageSurface->Stride(), + mType); + + return imageSurface.forget().get(); +} + +CairoImageD3D10::~CairoImageD3D10() +{ +} + +void +CairoImageD3D10::SetData(const CairoImage::Data &aData) +{ + mSize = aData.mSize; + + nsRefPtr imageSurface; + + if (aData.mSurface->GetType() == gfxASurface::SurfaceTypeImage) { + imageSurface = static_cast(aData.mSurface); + } else { + imageSurface = new gfxImageSurface(aData.mSize, + gfxASurface::ImageFormatARGB32); + + nsRefPtr context = new gfxContext(imageSurface); + context->SetSource(aData.mSurface); + context->SetOperator(gfxContext::OPERATOR_SOURCE); + context->Paint(); + } + + D3D10_SUBRESOURCE_DATA data; + + CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, mSize.width, mSize.height, 1, 1); + desc.Usage = D3D10_USAGE_IMMUTABLE; + + data.pSysMem = imageSurface->Data(); + data.SysMemPitch = imageSurface->Stride(); + + mManager->device()->CreateTexture2D(&desc, &data, getter_AddRefs(mTexture)); + mManager->device()->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView)); +} + +already_AddRefed +CairoImageD3D10::GetAsSurface() +{ + return nsnull; +} + +} /* layers */ +} /* mozilla */ diff --git a/gfx/layers/d3d10/ImageLayerD3D10.h b/gfx/layers/d3d10/ImageLayerD3D10.h new file mode 100644 index 000000000000..b3da9a2f6662 --- /dev/null +++ b/gfx/layers/d3d10/ImageLayerD3D10.h @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Bas Schouten + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef GFX_IMAGELAYERD3D10_H +#define GFX_IMAGELAYERD3D10_H + +#include "LayerManagerD3D10.h" +#include "ImageLayers.h" +#include "yuv_convert.h" +#include "mozilla/Mutex.h" + +namespace mozilla { +namespace layers { + +class THEBES_API ImageContainerD3D10 : public ImageContainer +{ +public: + ImageContainerD3D10(LayerManagerD3D10 *aManager); + virtual ~ImageContainerD3D10() {} + + virtual already_AddRefed CreateImage(const Image::Format* aFormats, + PRUint32 aNumFormats); + + virtual void SetCurrentImage(Image* aImage); + + virtual already_AddRefed GetCurrentImage(); + + virtual already_AddRefed GetCurrentAsSurface(gfxIntSize* aSize); + + virtual gfxIntSize GetCurrentSize(); + + virtual PRBool SetLayerManager(LayerManager *aManager); + +private: + typedef mozilla::Mutex Mutex; + + nsRefPtr mActiveImage; + + Mutex mActiveImageLock; +}; + +class THEBES_API ImageLayerD3D10 : public ImageLayer, + public LayerD3D10 +{ +public: + ImageLayerD3D10(LayerManagerD3D10 *aManager) + : ImageLayer(aManager, NULL) + , LayerD3D10(aManager) + { + mImplData = static_cast(this); + } + + // LayerD3D10 Implementation + virtual Layer* GetLayer(); + + virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform); +}; + +class THEBES_API ImageD3D10 +{ +public: + virtual already_AddRefed GetAsSurface() = 0; +}; + +class THEBES_API PlanarYCbCrImageD3D10 : public PlanarYCbCrImage, + public ImageD3D10 +{ +public: + PlanarYCbCrImageD3D10(LayerManagerD3D10 *aManager); + ~PlanarYCbCrImageD3D10() {} + + virtual void SetData(const Data &aData); + + /* + * Upload the data from out mData into our textures. For now we use this to + * make sure the textures are created and filled on the main thread. + */ + void AllocateTextures(); + + PRBool HasData() { return mHasData; } + + virtual already_AddRefed GetAsSurface(); + + nsAutoArrayPtr mBuffer; + LayerManagerD3D10 *mManager; + Data mData; + gfxIntSize mSize; + nsRefPtr mYTexture; + nsRefPtr mCrTexture; + nsRefPtr mCbTexture; + nsRefPtr mYView; + nsRefPtr mCbView; + nsRefPtr mCrView; + PRPackedBool mHasData; + gfx::YUVType mType; +}; + + +class THEBES_API CairoImageD3D10 : public CairoImage, + public ImageD3D10 +{ +public: + CairoImageD3D10(LayerManagerD3D10 *aManager) + : CairoImage(static_cast(this)) + , mManager(aManager) + { } + ~CairoImageD3D10(); + + virtual void SetData(const Data &aData); + + virtual already_AddRefed GetAsSurface(); + + nsRefPtr mTexture; + nsRefPtr mSRView; + gfxIntSize mSize; + LayerManagerD3D10 *mManager; +}; + +} /* layers */ +} /* mozilla */ +#endif /* GFX_IMAGELAYERD3D10_H */ diff --git a/gfx/layers/d3d10/LayerManagerD3D10.cpp b/gfx/layers/d3d10/LayerManagerD3D10.cpp new file mode 100644 index 000000000000..e382cc8df8db --- /dev/null +++ b/gfx/layers/d3d10/LayerManagerD3D10.cpp @@ -0,0 +1,502 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Bas Schouten + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "LayerManagerD3D10.h" +#include "LayerManagerD3D10Effect.h" +#include "gfxWindowsPlatform.h" +#include "gfxD2DSurface.h" +#include "cairo-win32.h" +#include "dxgi.h" + +#include "ContainerLayerD3D10.h" +#include "ThebesLayerD3D10.h" +#include "ColorLayerD3D10.h" +#include "CanvasLayerD3D10.h" +#include "ImageLayerD3D10.h" + +namespace mozilla { +namespace layers { + +typedef HRESULT (WINAPI*D3D10CreateEffectFromMemoryFunc)( + void *pData, + SIZE_T DataLength, + UINT FXFlags, + ID3D10Device *pDevice, + ID3D10EffectPool *pEffectPool, + ID3D10Effect **ppEffect +); + +struct Vertex +{ + float position[2]; +}; + +// {17F88CCB-1F49-4c08-8002-ADA7BD44856D} +static const GUID sEffect = +{ 0x17f88ccb, 0x1f49, 0x4c08, { 0x80, 0x2, 0xad, 0xa7, 0xbd, 0x44, 0x85, 0x6d } }; +// {19599D91-912C-4C2F-A8C5-299DE85FBD34} +static const GUID sInputLayout = +{ 0x19599d91, 0x912c, 0x4c2f, { 0xa8, 0xc5, 0x29, 0x9d, 0xe8, 0x5f, 0xbd, 0x34 } }; +// {293157D2-09C7-4680-AE27-C28E370E418B} +static const GUID sVertexBuffer = +{ 0x293157d2, 0x9c7, 0x4680, { 0xae, 0x27, 0xc2, 0x8e, 0x37, 0xe, 0x41, 0x8b } }; + +cairo_user_data_key_t gKeyD3D10Texture; + +LayerManagerD3D10::LayerManagerD3D10(nsIWidget *aWidget) + : mWidget(aWidget) +{ +} + +LayerManagerD3D10::~LayerManagerD3D10() +{ +} + +bool +LayerManagerD3D10::Initialize() +{ + HRESULT hr; + + cairo_device_t *device = gfxWindowsPlatform::GetPlatform()->GetD2DDevice(); + if (!device) { + return false; + } + + mDevice = cairo_d2d_device_get_device(device); + + UINT size = 4; + if (FAILED(mDevice->GetPrivateData(sEffect, &size, mEffect.StartAssignment()))) { + D3D10CreateEffectFromMemoryFunc createEffect = (D3D10CreateEffectFromMemoryFunc) + GetProcAddress(LoadLibraryA("d3d10_1.dll"), "D3D10CreateEffectFromMemory"); + + if (!createEffect) { + return false; + } + + hr = createEffect((void*)g_main, + sizeof(g_main), + D3D10_EFFECT_SINGLE_THREADED, + mDevice, + NULL, + getter_AddRefs(mEffect)); + + if (FAILED(hr)) { + return false; + } + + mDevice->SetPrivateDataInterface(sEffect, mEffect); + } + + size = 4; + if (FAILED(mDevice->GetPrivateData(sInputLayout, &size, mInputLayout.StartAssignment()))) { + D3D10_INPUT_ELEMENT_DESC layout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + }; + D3D10_PASS_DESC passDesc; + mEffect->GetTechniqueByName("RenderRGBLayerPremul")->GetPassByIndex(0)-> + GetDesc(&passDesc); + + hr = mDevice->CreateInputLayout(layout, + sizeof(layout) / sizeof(D3D10_INPUT_ELEMENT_DESC), + passDesc.pIAInputSignature, + passDesc.IAInputSignatureSize, + getter_AddRefs(mInputLayout)); + + if (FAILED(hr)) { + return false; + } + + mDevice->SetPrivateDataInterface(sInputLayout, mInputLayout); + } + + size = 4; + if (FAILED(mDevice->GetPrivateData(sVertexBuffer, &size, mVertexBuffer.StartAssignment()))) { + Vertex vertices[] = { {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0} }; + CD3D10_BUFFER_DESC bufferDesc(sizeof(vertices), D3D10_BIND_VERTEX_BUFFER); + D3D10_SUBRESOURCE_DATA data; + data.pSysMem = (void*)vertices; + + hr = mDevice->CreateBuffer(&bufferDesc, &data, getter_AddRefs(mVertexBuffer)); + + if (FAILED(hr)) { + return false; + } + + mDevice->SetPrivateDataInterface(sVertexBuffer, mVertexBuffer); + } + + nsRefPtr dxgiDevice; + nsRefPtr dxgiAdapter; + nsRefPtr dxgiFactory; + + mDevice->QueryInterface(dxgiDevice.StartAssignment()); + dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter)); + + dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment())); + + DXGI_SWAP_CHAIN_DESC swapDesc; + ::ZeroMemory(&swapDesc, sizeof(swapDesc)); + + swapDesc.BufferDesc.Width = 0; + swapDesc.BufferDesc.Height = 0; + swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + swapDesc.BufferDesc.RefreshRate.Numerator = 60; + swapDesc.BufferDesc.RefreshRate.Denominator = 1; + swapDesc.SampleDesc.Count = 1; + swapDesc.SampleDesc.Quality = 0; + swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapDesc.BufferCount = 1; + swapDesc.OutputWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW); + swapDesc.Windowed = TRUE; + + /** + * Create a swap chain, this swap chain will contain the backbuffer for + * the window we draw to. The front buffer is the full screen front + * buffer. + */ + hr = dxgiFactory->CreateSwapChain(dxgiDevice, &swapDesc, getter_AddRefs(mSwapChain)); + + if (FAILED(hr)) { + return false; + } + + return true; +} + +void +LayerManagerD3D10::SetRoot(Layer *aRoot) +{ + mRoot = aRoot; +} + +void +LayerManagerD3D10::BeginTransaction() +{ +} + +void +LayerManagerD3D10::BeginTransactionWithTarget(gfxContext* aTarget) +{ + mTarget = aTarget; +} + +void +LayerManagerD3D10::EndTransaction(DrawThebesLayerCallback aCallback, + void* aCallbackData) +{ + mCurrentCallbackInfo.Callback = aCallback; + mCurrentCallbackInfo.CallbackData = aCallbackData; + Render(); + mCurrentCallbackInfo.Callback = nsnull; + mCurrentCallbackInfo.CallbackData = nsnull; + mTarget = nsnull; +} + +already_AddRefed +LayerManagerD3D10::CreateThebesLayer() +{ + nsRefPtr layer = new ThebesLayerD3D10(this); + return layer.forget(); +} + +already_AddRefed +LayerManagerD3D10::CreateContainerLayer() +{ + nsRefPtr layer = new ContainerLayerD3D10(this); + return layer.forget(); +} + +already_AddRefed +LayerManagerD3D10::CreateImageLayer() +{ + nsRefPtr layer = new ImageLayerD3D10(this); + return layer.forget(); +} + +already_AddRefed +LayerManagerD3D10::CreateColorLayer() +{ + nsRefPtr layer = new ColorLayerD3D10(this); + return layer.forget(); +} + +already_AddRefed +LayerManagerD3D10::CreateCanvasLayer() +{ + nsRefPtr layer = new CanvasLayerD3D10(this); + return layer.forget(); +} + +already_AddRefed +LayerManagerD3D10::CreateImageContainer() +{ + nsRefPtr layer = new ImageContainerD3D10(this); + return layer.forget(); +} + +static void ReleaseTexture(void *texture) +{ + static_cast(texture)->Release(); +} + +already_AddRefed +LayerManagerD3D10::CreateOptimalSurface(const gfxIntSize &aSize, + gfxASurface::gfxImageFormat aFormat) +{ + if ((aFormat != gfxASurface::ImageFormatRGB24 && + aFormat != gfxASurface::ImageFormatARGB32)) { + return LayerManager::CreateOptimalSurface(aSize, aFormat); + } + + nsRefPtr texture; + + CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1); + desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE; + desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE; + + HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(texture)); + + if (FAILED(hr)) { + NS_WARNING("Failed to create new texture for CreateOptimalSurface!"); + return LayerManager::CreateOptimalSurface(aSize, aFormat); + } + + nsRefPtr surface = + new gfxD2DSurface(texture, aFormat == gfxASurface::ImageFormatRGB24 ? + gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA); + + if (!surface || surface->CairoStatus()) { + return LayerManager::CreateOptimalSurface(aSize, aFormat); + } + + surface->SetData(&gKeyD3D10Texture, + texture.forget().get(), + ReleaseTexture); + + return surface.forget(); +} + +void +LayerManagerD3D10::SetViewport(const nsIntSize &aViewport) +{ + mViewport = aViewport; + + D3D10_VIEWPORT viewport; + viewport.MaxDepth = 1.0f; + viewport.MinDepth = 0; + viewport.Width = aViewport.width; + viewport.Height = aViewport.height; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + + mDevice->RSSetViewports(1, &viewport); + + gfx3DMatrix projection; + /* + * Matrix to transform to viewport space ( <-1.0, 1.0> topleft, + * <1.0, -1.0> bottomright) + */ + projection._11 = 2.0f / aViewport.width; + projection._22 = -2.0f / aViewport.height; + projection._33 = 1.0f; + projection._41 = -1.0f; + projection._42 = 1.0f; + projection._44 = 1.0f; + + HRESULT hr = mEffect->GetVariableByName("mProjection")-> + SetRawValue(&projection._11, 0, 64); + + if (FAILED(hr)) { + NS_WARNING("Failed to set projection matrix."); + } +} + +void +LayerManagerD3D10::SetupPipeline() +{ + VerifyBufferSize(); + UpdateRenderTarget(); + + nsIntRect rect; + mWidget->GetClientBounds(rect); + + HRESULT hr; + + hr = mEffect->GetVariableByName("vTextureCoords")->AsVector()-> + SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f)); + + if (FAILED(hr)) { + NS_WARNING("Failed to set Texture Coordinates."); + return; + } + + ID3D10RenderTargetView *view = mRTView; + mDevice->OMSetRenderTargets(1, &view, NULL); + mDevice->IASetInputLayout(mInputLayout); + + UINT stride = sizeof(Vertex); + UINT offset = 0; + ID3D10Buffer *buffer = mVertexBuffer; + mDevice->IASetVertexBuffers(0, 1, &buffer, &stride, &offset); + mDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + SetViewport(nsIntSize(rect.width, rect.height)); +} + +void +LayerManagerD3D10::UpdateRenderTarget() +{ + if (mRTView) { + return; + } + + HRESULT hr; + + nsRefPtr backBuf; + + hr = mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)backBuf.StartAssignment()); + if (FAILED(hr)) { + return; + } + + mDevice->CreateRenderTargetView(backBuf, NULL, getter_AddRefs(mRTView)); +} + +void +LayerManagerD3D10::VerifyBufferSize() +{ + DXGI_SWAP_CHAIN_DESC swapDesc; + mSwapChain->GetDesc(&swapDesc); + + nsIntRect rect; + mWidget->GetClientBounds(rect); + + if (swapDesc.BufferDesc.Width == rect.width && + swapDesc.BufferDesc.Height == rect.height) { + return; + } + + mRTView = nsnull; + mSwapChain->ResizeBuffers(1, rect.width, rect.height, + DXGI_FORMAT_B8G8R8A8_UNORM, 0); + +} + +void +LayerManagerD3D10::Render() +{ + if (mRoot) { + static_cast(mRoot->ImplData())->Validate(); + } + + SetupPipeline(); + + float black[] = { 0, 0, 0, 0 }; + device()->ClearRenderTargetView(mRTView, black); + + nsIntRect rect; + mWidget->GetClientBounds(rect); + + if (mRoot) { + const nsIntRect *clipRect = mRoot->GetClipRect(); + D3D10_RECT r; + if (clipRect) { + r.left = (LONG)clipRect->x; + r.top = (LONG)clipRect->y; + r.right = (LONG)(clipRect->x + clipRect->width); + r.bottom = (LONG)(clipRect->y + clipRect->height); + } else { + r.left = r.top = 0; + r.right = rect.width; + r.bottom = rect.height; + } + device()->RSSetScissorRects(1, &r); + + static_cast(mRoot->ImplData())->RenderLayer(1, gfx3DMatrix()); + } + + if (mTarget) { + PaintToTarget(); + } else { + mSwapChain->Present(0, 0); + } +} + +void +LayerManagerD3D10::PaintToTarget() +{ + nsRefPtr backBuf; + + mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)backBuf.StartAssignment()); + + D3D10_TEXTURE2D_DESC bbDesc; + backBuf->GetDesc(&bbDesc); + + CD3D10_TEXTURE2D_DESC softDesc(bbDesc.Format, bbDesc.Width, bbDesc.Height); + softDesc.MipLevels = 1; + softDesc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; + softDesc.Usage = D3D10_USAGE_STAGING; + softDesc.BindFlags = 0; + + nsRefPtr readTexture; + + device()->CreateTexture2D(&softDesc, NULL, getter_AddRefs(readTexture)); + + device()->CopyResource(readTexture, backBuf); + + D3D10_MAPPED_TEXTURE2D map; + readTexture->Map(0, D3D10_MAP_READ, 0, &map); + + nsRefPtr tmpSurface = + new gfxImageSurface((unsigned char*)map.pData, + gfxIntSize(bbDesc.Width, bbDesc.Height), + map.RowPitch, + gfxASurface::ImageFormatARGB32); + + mTarget->SetSource(tmpSurface); + mTarget->SetOperator(gfxContext::OPERATOR_SOURCE); + mTarget->Paint(); +} + +LayerD3D10::LayerD3D10(LayerManagerD3D10 *aManager) + : mD3DManager(aManager) +{ +} + +} +} diff --git a/gfx/layers/d3d10/LayerManagerD3D10.fx b/gfx/layers/d3d10/LayerManagerD3D10.fx new file mode 100644 index 000000000000..8a4cc7ff10c6 --- /dev/null +++ b/gfx/layers/d3d10/LayerManagerD3D10.fx @@ -0,0 +1,248 @@ +typedef float4 rect; +cbuffer PerLayer { + rect vTextureCoords; + rect vLayerQuad; + float fLayerOpacity; + float4x4 mLayerTransform; +} + +cbuffer PerOccasionalLayer { + float4 vRenderTargetOffset; + float4 fLayerColor; +} + +cbuffer PerLayerManager { + float4x4 mProjection; +} + +BlendState Premul +{ + AlphaToCoverageEnable = FALSE; + BlendEnable[0] = TRUE; + SrcBlend = One; + DestBlend = Inv_Src_Alpha; + BlendOp = Add; + SrcBlendAlpha = One; + DestBlendAlpha = Inv_Src_Alpha; + BlendOpAlpha = Add; + RenderTargetWriteMask[0] = 0x0F; // All +}; + +BlendState NonPremul +{ + AlphaToCoverageEnable = FALSE; + BlendEnable[0] = TRUE; + SrcBlend = Src_Alpha; + DestBlend = Inv_Src_Alpha; + BlendOp = Add; + SrcBlendAlpha = One; + DestBlendAlpha = Inv_Src_Alpha; + BlendOpAlpha = Add; + RenderTargetWriteMask[0] = 0x0F; // All +}; + +RasterizerState LayerRast +{ + ScissorEnable = True; +}; + +Texture2D tRGB; +Texture2D tY; +Texture2D tCb; +Texture2D tCr; + +SamplerState LayerTextureSamplerLinear +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Wrap; + AddressV = Wrap; +}; + +SamplerState LayerTextureSamplerPoint +{ + Filter = MIN_MAG_MIP_POINT; + AddressU = Wrap; + AddressV = Wrap; +}; + +struct VS_INPUT { + float2 vPosition : POSITION; +}; + +struct VS_OUTPUT { + float4 vPosition : SV_Position; + float2 vTexCoords : TEXCOORD0; +}; + +VS_OUTPUT LayerQuadVS(const VS_INPUT aVertex) +{ + VS_OUTPUT outp; + outp.vPosition.z = 0; + outp.vPosition.w = 1; + + // We use 4 component floats to uniquely describe a rectangle, by the structure + // of x, y, width, height. This allows us to easily generate the 4 corners + // of any rectangle from the 4 corners of the 0,0-1,1 quad that we use as the + // stream source for our LayerQuad vertex shader. We do this by doing: + // Xout = x + Xin * width + // Yout = y + Yin * height + float2 position = vLayerQuad.xy; + float2 size = vLayerQuad.zw; + outp.vPosition.x = position.x + aVertex.vPosition.x * size.x; + outp.vPosition.y = position.y + aVertex.vPosition.y * size.y; + + outp.vPosition = mul(mLayerTransform, outp.vPosition); + outp.vPosition = outp.vPosition - vRenderTargetOffset; + + outp.vPosition = mul(mProjection, outp.vPosition); + + position = vTextureCoords.xy; + size = vTextureCoords.zw; + outp.vTexCoords.x = position.x + aVertex.vPosition.x * size.x; + outp.vTexCoords.y = position.y + aVertex.vPosition.y * size.y; + return outp; +} + +float4 RGBAShaderLinear(const VS_OUTPUT aVertex) : SV_Target +{ + return tRGB.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords) * fLayerOpacity; +} + +float4 RGBAShaderPoint(const VS_OUTPUT aVertex) : SV_Target +{ + return tRGB.Sample(LayerTextureSamplerPoint, aVertex.vTexCoords) * fLayerOpacity; +} + +float4 RGBShaderLinear(const VS_OUTPUT aVertex) : SV_Target +{ + float4 result; + result = tRGB.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords) * fLayerOpacity; + result.a = fLayerOpacity; + return result; +} + +float4 RGBShaderPoint(const VS_OUTPUT aVertex) : SV_Target +{ + float4 result; + result = tRGB.Sample(LayerTextureSamplerPoint, aVertex.vTexCoords) * fLayerOpacity; + result.a = fLayerOpacity; + return result; +} + +float4 YCbCrShader(const VS_OUTPUT aVertex) : SV_Target +{ + float4 yuv; + float4 color; + + yuv.r = tCr.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords).r - 0.5; + yuv.g = tY.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords).r - 0.0625; + yuv.b = tCb.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords).r - 0.5; + + color.r = yuv.g * 1.164 + yuv.r * 1.596; + color.g = yuv.g * 1.164 - 0.813 * yuv.r - 0.391 * yuv.b; + color.b = yuv.g * 1.164 + yuv.b * 2.018; + color.a = 1.0f; + + return color * fLayerOpacity; +} + +float4 SolidColorShader(const VS_OUTPUT aVertex) : SV_Target +{ + return fLayerColor; +} + +technique10 RenderRGBLayerPremul +{ + pass P0 + { + SetRasterizerState( LayerRast ); + SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBShaderLinear() ) ); + } +} + +technique10 RenderRGBLayerPremulPoint +{ + pass P0 + { + SetRasterizerState( LayerRast ); + SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBShaderPoint() ) ); + } +} + +technique10 RenderRGBALayerPremul +{ + pass P0 + { + SetRasterizerState( LayerRast ); + SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderLinear() ) ); + } +} + +technique10 RenderRGBALayerNonPremul +{ + pass P0 + { + SetRasterizerState( LayerRast ); + SetBlendState( NonPremul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderLinear() ) ); + } +} + +technique10 RenderRGBALayerPremulPoint +{ + pass P0 + { + SetRasterizerState( LayerRast ); + SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderPoint() ) ); + } +} + +technique10 RenderRGBALayerNonPremulPoint +{ + pass P0 + { + SetRasterizerState( LayerRast ); + SetBlendState( NonPremul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderPoint() ) ); + } +} + +technique10 RenderYCbCrLayer +{ + pass P0 + { + SetRasterizerState( LayerRast ); + SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0_level_9_3, YCbCrShader() ) ); + } +} + +technique10 RenderSolidColorLayer +{ + pass P0 + { + SetRasterizerState( LayerRast ); + SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0_level_9_3, SolidColorShader() ) ); + } +} diff --git a/gfx/layers/d3d10/LayerManagerD3D10.h b/gfx/layers/d3d10/LayerManagerD3D10.h new file mode 100644 index 000000000000..bcdcbea2b73d --- /dev/null +++ b/gfx/layers/d3d10/LayerManagerD3D10.h @@ -0,0 +1,211 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Bas Schouten + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef GFX_LAYERMANAGERD3D10_H +#define GFX_LAYERMANAGERD3D10_H + +#include "Layers.h" + +#include +#include + +#include "gfxContext.h" +#include "nsIWidget.h" + +namespace mozilla { +namespace layers { + +/** + * This structure is used to pass rectangles to our shader constant. We can use + * this for passing rectangular areas to SetVertexShaderConstant. In the format + * of a 4 component float(x,y,width,height). Our vertex shader can then use + * this to construct rectangular positions from the 0,0-1,1 quad that we source + * it with. + */ +struct ShaderConstantRectD3D10 +{ + float mX, mY, mWidth, mHeight; + ShaderConstantRectD3D10(float aX, float aY, float aWidth, float aHeight) + : mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight) + { } + + // For easy passing to SetVertexShaderConstantF. + operator float* () { return &mX; } +}; + +extern cairo_user_data_key_t gKeyD3D10Texture; + +/* + * This is the LayerManager used for Direct3D 9. For now this will render on + * the main thread. + */ +class THEBES_API LayerManagerD3D10 : public LayerManager { +public: + LayerManagerD3D10(nsIWidget *aWidget); + virtual ~LayerManagerD3D10(); + + /* + * Initializes the layer manager, this is when the layer manager will + * actually access the device and attempt to create the swap chain used + * to draw to the window. If this method fails the device cannot be used. + * This function is not threadsafe. + * + * \return True is initialization was succesful, false when it was not. + */ + bool Initialize(); + + /* + * LayerManager implementation. + */ + virtual void SetRoot(Layer *aLayer); + + void BeginTransaction(); + + void BeginTransactionWithTarget(gfxContext* aTarget); + + struct CallbackInfo { + DrawThebesLayerCallback Callback; + void *CallbackData; + }; + + void EndTransaction(DrawThebesLayerCallback aCallback, + void* aCallbackData); + + const CallbackInfo &GetCallbackInfo() { return mCurrentCallbackInfo; } + + virtual already_AddRefed CreateThebesLayer(); + + virtual already_AddRefed CreateContainerLayer(); + + virtual already_AddRefed CreateImageLayer(); + + virtual already_AddRefed CreateColorLayer(); + + virtual already_AddRefed CreateCanvasLayer(); + + virtual already_AddRefed CreateImageContainer(); + + virtual already_AddRefed + CreateOptimalSurface(const gfxIntSize &aSize, + gfxASurface::gfxImageFormat imageFormat); + + virtual LayersBackend GetBackendType() { return LAYERS_D3D10; } + virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Direct3D 10"); } + +#ifdef MOZ_LAYERS_HAVE_LOG + virtual const char* Name() const { return "D3D9"; } +#endif // MOZ_LAYERS_HAVE_LOG + + // Public helpers + + ID3D10Device1 *device() const { return mDevice; } + + ID3D10Effect *effect() const { return mEffect; } + + void SetViewport(const nsIntSize &aViewport); + const nsIntSize &GetViewport() { return mViewport; } + +private: + void SetupPipeline(); + void UpdateRenderTarget(); + void VerifyBufferSize(); + + void Render(); + + nsRefPtr mDevice; + + nsRefPtr mEffect; + nsRefPtr mInputLayout; + nsRefPtr mVertexBuffer; + + nsRefPtr mRTView; + + nsRefPtr mSwapChain; + + nsIWidget *mWidget; + + CallbackInfo mCurrentCallbackInfo; + + nsIntSize mViewport; + + /* + * Context target, NULL when drawing directly to our swap chain. + */ + nsRefPtr mTarget; + + /* + * Copies the content of our backbuffer to the set transaction target. + */ + void PaintToTarget(); +}; + +/* + * General information and tree management for OGL layers. + */ +class LayerD3D10 +{ +public: + LayerD3D10(LayerManagerD3D10 *aManager); + + virtual LayerD3D10 *GetFirstChildD3D10() { return nsnull; } + + void SetFirstChild(LayerD3D10 *aParent); + + virtual Layer* GetLayer() = 0; + + /** + * This will render a child layer to whatever render target is currently + * active. aOpacity and aTransform will pass any 'carried' transformations + * and/or opacity from the parent. This allows the parent to avoid + * rendering to intermediate surfaces when possible. + */ + virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) = 0; + virtual void Validate() {} + + ID3D10Device1 *device() const { return mD3DManager->device(); } + ID3D10Effect *effect() const { return mD3DManager->effect(); } + + /* Called by the layer manager when it's destroyed */ + virtual void LayerManagerDestroyed() {} +protected: + LayerManagerD3D10 *mD3DManager; +}; + +} /* layers */ +} /* mozilla */ + +#endif /* GFX_LAYERMANAGERD3D9_H */ diff --git a/gfx/layers/d3d10/LayerManagerD3D10Effect.h b/gfx/layers/d3d10/LayerManagerD3D10Effect.h new file mode 100644 index 000000000000..22cd2e461a6b --- /dev/null +++ b/gfx/layers/d3d10/LayerManagerD3D10Effect.h @@ -0,0 +1,6307 @@ +#if 0 +// +// FX Version: fx_4_0 +// Child effect (requires effect pool): false +// +// 3 local buffer(s) +// +cbuffer PerLayer +{ + float4 vTextureCoords; // Offset: 0, size: 16 + float4 vLayerQuad; // Offset: 16, size: 16 + float fLayerOpacity; // Offset: 32, size: 4 + float4x4 mLayerTransform; // Offset: 48, size: 64 +} + +cbuffer PerOccasionalLayer +{ + float4 vRenderTargetOffset; // Offset: 0, size: 16 + float4 fLayerColor; // Offset: 16, size: 16 +} + +cbuffer PerLayerManager +{ + float4x4 mProjection; // Offset: 0, size: 64 +} + +// +// 9 local object(s) +// +BlendState Premul +{ + AlphaToCoverageEnable = bool(FALSE /* 0 */); + BlendEnable[0] = bool(TRUE /* 1 */); + SrcBlend[0] = uint(ONE /* 2 */); + DestBlend[0] = uint(INV_SRC_ALPHA /* 6 */); + BlendOp[0] = uint(ADD /* 1 */); + SrcBlendAlpha[0] = uint(ONE /* 2 */); + DestBlendAlpha[0] = uint(INV_SRC_ALPHA /* 6 */); + BlendOpAlpha[0] = uint(ADD /* 1 */); + RenderTargetWriteMask[0] = byte(0x0f); +}; +BlendState NonPremul +{ + AlphaToCoverageEnable = bool(FALSE /* 0 */); + BlendEnable[0] = bool(TRUE /* 1 */); + SrcBlend[0] = uint(SRC_ALPHA /* 5 */); + DestBlend[0] = uint(INV_SRC_ALPHA /* 6 */); + BlendOp[0] = uint(ADD /* 1 */); + SrcBlendAlpha[0] = uint(ONE /* 2 */); + DestBlendAlpha[0] = uint(INV_SRC_ALPHA /* 6 */); + BlendOpAlpha[0] = uint(ADD /* 1 */); + RenderTargetWriteMask[0] = byte(0x0f); +}; +RasterizerState LayerRast +{ + ScissorEnable = bool(TRUE /* 1 */); +}; +Texture2D tRGB; +Texture2D tY; +Texture2D tCb; +Texture2D tCr; +SamplerState LayerTextureSamplerLinear +{ + Filter = uint(MIN_MAG_MIP_LINEAR /* 21 */); + AddressU = uint(WRAP /* 1 */); + AddressV = uint(WRAP /* 1 */); +}; +SamplerState LayerTextureSamplerPoint +{ + Filter = uint(MIN_MAG_MIP_POINT /* 0 */); + AddressU = uint(WRAP /* 1 */); + AddressV = uint(WRAP /* 1 */); +}; + +// +// 8 technique(s) +// +technique10 RenderRGBLayerPremul +{ + pass P0 + { + RasterizerState = LayerRast; + AB_BlendFactor = float4(0, 0, 0, 0); + AB_SampleMask = uint(0xffffffff); + BlendState = Premul; + VertexShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 + // float4 vLayerQuad; // Offset: 16 Size: 16 + // float fLayerOpacity; // Offset: 32 Size: 4 [unused] + // float4x4 mLayerTransform; // Offset: 48 Size: 64 + // + // } + // + // cbuffer PerOccasionalLayer + // { + // + // float4 vRenderTargetOffset; // Offset: 0 Size: 16 + // float4 fLayerColor; // Offset: 16 Size: 16 [unused] + // + // } + // + // cbuffer PerLayerManager + // { + // + // float4x4 mProjection; // Offset: 0 Size: 64 + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // PerLayer cbuffer NA NA 0 1 + // PerOccasionalLayer cbuffer NA NA 1 1 + // PerLayerManager cbuffer NA NA 2 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // POSITION 0 xy 0 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float xyzw + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c1 cb0 0 2 ( FLT, FLT, FLT, FLT) + // c3 cb0 3 2 ( FLT, FLT, FLT, FLT) + // c5 cb0 6 1 ( FLT, FLT, FLT, FLT) + // c6 cb1 0 1 ( FLT, FLT, FLT, FLT) + // c7 cb2 0 4 ( FLT, FLT, FLT, FLT) + // + // + // Runtime generated constant mappings: + // + // Target Reg Constant Description + // ---------- -------------------------------------------------- + // c0 Vertex Shader position offset + // + // + // Level9 shader bytecode: + // + vs_2_x + dcl_texcoord v0 + mad oT0.xy, v0, c1.zwzw, c1 + mad r0.xy, v0, c2.zwzw, c2 + mul r1, r0.y, c4 + mad r0, c3, r0.x, r1 + add r0, r0, c5 + add r0, r0, -c6 + mul r1, r0.y, c8 + mad r1, c7, r0.x, r1 + mad r1, c9, r0.z, r1 + mad r0, c10, r0.w, r1 + mad oPos.xy, r0.w, c0, r0 + mov oPos.zw, r0 + + // approximately 12 instruction slots used + vs_4_0 + dcl_constantbuffer cb0[7], immediateIndexed + dcl_constantbuffer cb1[1], immediateIndexed + dcl_constantbuffer cb2[4], immediateIndexed + dcl_input v0.xy + dcl_output_siv o0.xyzw, position + dcl_output o1.xy + dcl_temps 2 + mad r0.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx + mul r1.xyzw, r0.yyyy, cb0[4].xyzw + mad r0.xyzw, cb0[3].xyzw, r0.xxxx, r1.xyzw + add r0.xyzw, r0.xyzw, cb0[6].xyzw + add r0.xyzw, r0.xyzw, -cb1[0].xyzw + mul r1.xyzw, r0.yyyy, cb2[1].xyzw + mad r1.xyzw, cb2[0].xyzw, r0.xxxx, r1.xyzw + mad r1.xyzw, cb2[2].xyzw, r0.zzzz, r1.xyzw + mad o0.xyzw, cb2[3].xyzw, r0.wwww, r1.xyzw + mad o1.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx + ret + // Approximately 11 instruction slots used + + }; + GeometryShader = NULL; + PixelShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 [unused] + // float4 vLayerQuad; // Offset: 16 Size: 16 [unused] + // float fLayerOpacity; // Offset: 32 Size: 4 + // float4x4 mLayerTransform; // Offset: 48 Size: 64 [unused] + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // LayerTextureSamplerLinear sampler NA NA 0 1 + // tRGB texture float4 2d 0 1 + // PerLayer cbuffer NA NA 0 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Target 0 xyzw 0 TARGET float xyzw + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c0 cb0 2 1 ( FLT, FLT, FLT, FLT) + // + // + // Sampler/Resource to DX9 shader sampler mappings: + // + // Target Sampler Source Sampler Source Resource + // -------------- --------------- ---------------- + // s0 s0 t0 + // + // + // Level9 shader bytecode: + // + ps_2_x + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mul r0.xyz, r0, c0.x + mov r0.w, c0.x + mov oC0, r0 + + // approximately 4 instruction slots used (1 texture, 3 arithmetic) + ps_4_0 + dcl_constantbuffer cb0[3], immediateIndexed + dcl_sampler s0, mode_default + dcl_resource_texture2d (float,float,float,float) t0 + dcl_input_ps linear v1.xy + dcl_output o0.xyzw + dcl_temps 1 + sample r0.xyzw, v1.xyxx, t0.xyzw, s0 + mul o0.xyz, r0.xyzx, cb0[2].xxxx + mov o0.w, cb0[2].x + ret + // Approximately 4 instruction slots used + + }; + } + +} + +technique10 RenderRGBLayerPremulPoint +{ + pass P0 + { + RasterizerState = LayerRast; + AB_BlendFactor = float4(0, 0, 0, 0); + AB_SampleMask = uint(0xffffffff); + BlendState = Premul; + VertexShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 + // float4 vLayerQuad; // Offset: 16 Size: 16 + // float fLayerOpacity; // Offset: 32 Size: 4 [unused] + // float4x4 mLayerTransform; // Offset: 48 Size: 64 + // + // } + // + // cbuffer PerOccasionalLayer + // { + // + // float4 vRenderTargetOffset; // Offset: 0 Size: 16 + // float4 fLayerColor; // Offset: 16 Size: 16 [unused] + // + // } + // + // cbuffer PerLayerManager + // { + // + // float4x4 mProjection; // Offset: 0 Size: 64 + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // PerLayer cbuffer NA NA 0 1 + // PerOccasionalLayer cbuffer NA NA 1 1 + // PerLayerManager cbuffer NA NA 2 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // POSITION 0 xy 0 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float xyzw + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c1 cb0 0 2 ( FLT, FLT, FLT, FLT) + // c3 cb0 3 2 ( FLT, FLT, FLT, FLT) + // c5 cb0 6 1 ( FLT, FLT, FLT, FLT) + // c6 cb1 0 1 ( FLT, FLT, FLT, FLT) + // c7 cb2 0 4 ( FLT, FLT, FLT, FLT) + // + // + // Runtime generated constant mappings: + // + // Target Reg Constant Description + // ---------- -------------------------------------------------- + // c0 Vertex Shader position offset + // + // + // Level9 shader bytecode: + // + vs_2_x + dcl_texcoord v0 + mad oT0.xy, v0, c1.zwzw, c1 + mad r0.xy, v0, c2.zwzw, c2 + mul r1, r0.y, c4 + mad r0, c3, r0.x, r1 + add r0, r0, c5 + add r0, r0, -c6 + mul r1, r0.y, c8 + mad r1, c7, r0.x, r1 + mad r1, c9, r0.z, r1 + mad r0, c10, r0.w, r1 + mad oPos.xy, r0.w, c0, r0 + mov oPos.zw, r0 + + // approximately 12 instruction slots used + vs_4_0 + dcl_constantbuffer cb0[7], immediateIndexed + dcl_constantbuffer cb1[1], immediateIndexed + dcl_constantbuffer cb2[4], immediateIndexed + dcl_input v0.xy + dcl_output_siv o0.xyzw, position + dcl_output o1.xy + dcl_temps 2 + mad r0.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx + mul r1.xyzw, r0.yyyy, cb0[4].xyzw + mad r0.xyzw, cb0[3].xyzw, r0.xxxx, r1.xyzw + add r0.xyzw, r0.xyzw, cb0[6].xyzw + add r0.xyzw, r0.xyzw, -cb1[0].xyzw + mul r1.xyzw, r0.yyyy, cb2[1].xyzw + mad r1.xyzw, cb2[0].xyzw, r0.xxxx, r1.xyzw + mad r1.xyzw, cb2[2].xyzw, r0.zzzz, r1.xyzw + mad o0.xyzw, cb2[3].xyzw, r0.wwww, r1.xyzw + mad o1.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx + ret + // Approximately 11 instruction slots used + + }; + GeometryShader = NULL; + PixelShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 [unused] + // float4 vLayerQuad; // Offset: 16 Size: 16 [unused] + // float fLayerOpacity; // Offset: 32 Size: 4 + // float4x4 mLayerTransform; // Offset: 48 Size: 64 [unused] + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // LayerTextureSamplerPoint sampler NA NA 0 1 + // tRGB texture float4 2d 0 1 + // PerLayer cbuffer NA NA 0 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Target 0 xyzw 0 TARGET float xyzw + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c0 cb0 2 1 ( FLT, FLT, FLT, FLT) + // + // + // Sampler/Resource to DX9 shader sampler mappings: + // + // Target Sampler Source Sampler Source Resource + // -------------- --------------- ---------------- + // s0 s0 t0 + // + // + // Level9 shader bytecode: + // + ps_2_x + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mul r0.xyz, r0, c0.x + mov r0.w, c0.x + mov oC0, r0 + + // approximately 4 instruction slots used (1 texture, 3 arithmetic) + ps_4_0 + dcl_constantbuffer cb0[3], immediateIndexed + dcl_sampler s0, mode_default + dcl_resource_texture2d (float,float,float,float) t0 + dcl_input_ps linear v1.xy + dcl_output o0.xyzw + dcl_temps 1 + sample r0.xyzw, v1.xyxx, t0.xyzw, s0 + mul o0.xyz, r0.xyzx, cb0[2].xxxx + mov o0.w, cb0[2].x + ret + // Approximately 4 instruction slots used + + }; + } + +} + +technique10 RenderRGBALayerPremul +{ + pass P0 + { + RasterizerState = LayerRast; + AB_BlendFactor = float4(0, 0, 0, 0); + AB_SampleMask = uint(0xffffffff); + BlendState = Premul; + VertexShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 + // float4 vLayerQuad; // Offset: 16 Size: 16 + // float fLayerOpacity; // Offset: 32 Size: 4 [unused] + // float4x4 mLayerTransform; // Offset: 48 Size: 64 + // + // } + // + // cbuffer PerOccasionalLayer + // { + // + // float4 vRenderTargetOffset; // Offset: 0 Size: 16 + // float4 fLayerColor; // Offset: 16 Size: 16 [unused] + // + // } + // + // cbuffer PerLayerManager + // { + // + // float4x4 mProjection; // Offset: 0 Size: 64 + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // PerLayer cbuffer NA NA 0 1 + // PerOccasionalLayer cbuffer NA NA 1 1 + // PerLayerManager cbuffer NA NA 2 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // POSITION 0 xy 0 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float xyzw + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c1 cb0 0 2 ( FLT, FLT, FLT, FLT) + // c3 cb0 3 2 ( FLT, FLT, FLT, FLT) + // c5 cb0 6 1 ( FLT, FLT, FLT, FLT) + // c6 cb1 0 1 ( FLT, FLT, FLT, FLT) + // c7 cb2 0 4 ( FLT, FLT, FLT, FLT) + // + // + // Runtime generated constant mappings: + // + // Target Reg Constant Description + // ---------- -------------------------------------------------- + // c0 Vertex Shader position offset + // + // + // Level9 shader bytecode: + // + vs_2_x + dcl_texcoord v0 + mad oT0.xy, v0, c1.zwzw, c1 + mad r0.xy, v0, c2.zwzw, c2 + mul r1, r0.y, c4 + mad r0, c3, r0.x, r1 + add r0, r0, c5 + add r0, r0, -c6 + mul r1, r0.y, c8 + mad r1, c7, r0.x, r1 + mad r1, c9, r0.z, r1 + mad r0, c10, r0.w, r1 + mad oPos.xy, r0.w, c0, r0 + mov oPos.zw, r0 + + // approximately 12 instruction slots used + vs_4_0 + dcl_constantbuffer cb0[7], immediateIndexed + dcl_constantbuffer cb1[1], immediateIndexed + dcl_constantbuffer cb2[4], immediateIndexed + dcl_input v0.xy + dcl_output_siv o0.xyzw, position + dcl_output o1.xy + dcl_temps 2 + mad r0.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx + mul r1.xyzw, r0.yyyy, cb0[4].xyzw + mad r0.xyzw, cb0[3].xyzw, r0.xxxx, r1.xyzw + add r0.xyzw, r0.xyzw, cb0[6].xyzw + add r0.xyzw, r0.xyzw, -cb1[0].xyzw + mul r1.xyzw, r0.yyyy, cb2[1].xyzw + mad r1.xyzw, cb2[0].xyzw, r0.xxxx, r1.xyzw + mad r1.xyzw, cb2[2].xyzw, r0.zzzz, r1.xyzw + mad o0.xyzw, cb2[3].xyzw, r0.wwww, r1.xyzw + mad o1.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx + ret + // Approximately 11 instruction slots used + + }; + GeometryShader = NULL; + PixelShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 [unused] + // float4 vLayerQuad; // Offset: 16 Size: 16 [unused] + // float fLayerOpacity; // Offset: 32 Size: 4 + // float4x4 mLayerTransform; // Offset: 48 Size: 64 [unused] + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // LayerTextureSamplerLinear sampler NA NA 0 1 + // tRGB texture float4 2d 0 1 + // PerLayer cbuffer NA NA 0 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Target 0 xyzw 0 TARGET float xyzw + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c0 cb0 2 1 ( FLT, FLT, FLT, FLT) + // + // + // Sampler/Resource to DX9 shader sampler mappings: + // + // Target Sampler Source Sampler Source Resource + // -------------- --------------- ---------------- + // s0 s0 t0 + // + // + // Level9 shader bytecode: + // + ps_2_x + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mul r0, r0, c0.x + mov oC0, r0 + + // approximately 3 instruction slots used (1 texture, 2 arithmetic) + ps_4_0 + dcl_constantbuffer cb0[3], immediateIndexed + dcl_sampler s0, mode_default + dcl_resource_texture2d (float,float,float,float) t0 + dcl_input_ps linear v1.xy + dcl_output o0.xyzw + dcl_temps 1 + sample r0.xyzw, v1.xyxx, t0.xyzw, s0 + mul o0.xyzw, r0.xyzw, cb0[2].xxxx + ret + // Approximately 3 instruction slots used + + }; + } + +} + +technique10 RenderRGBALayerNonPremul +{ + pass P0 + { + RasterizerState = LayerRast; + AB_BlendFactor = float4(0, 0, 0, 0); + AB_SampleMask = uint(0xffffffff); + BlendState = NonPremul; + VertexShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 + // float4 vLayerQuad; // Offset: 16 Size: 16 + // float fLayerOpacity; // Offset: 32 Size: 4 [unused] + // float4x4 mLayerTransform; // Offset: 48 Size: 64 + // + // } + // + // cbuffer PerOccasionalLayer + // { + // + // float4 vRenderTargetOffset; // Offset: 0 Size: 16 + // float4 fLayerColor; // Offset: 16 Size: 16 [unused] + // + // } + // + // cbuffer PerLayerManager + // { + // + // float4x4 mProjection; // Offset: 0 Size: 64 + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // PerLayer cbuffer NA NA 0 1 + // PerOccasionalLayer cbuffer NA NA 1 1 + // PerLayerManager cbuffer NA NA 2 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // POSITION 0 xy 0 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float xyzw + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c1 cb0 0 2 ( FLT, FLT, FLT, FLT) + // c3 cb0 3 2 ( FLT, FLT, FLT, FLT) + // c5 cb0 6 1 ( FLT, FLT, FLT, FLT) + // c6 cb1 0 1 ( FLT, FLT, FLT, FLT) + // c7 cb2 0 4 ( FLT, FLT, FLT, FLT) + // + // + // Runtime generated constant mappings: + // + // Target Reg Constant Description + // ---------- -------------------------------------------------- + // c0 Vertex Shader position offset + // + // + // Level9 shader bytecode: + // + vs_2_x + dcl_texcoord v0 + mad oT0.xy, v0, c1.zwzw, c1 + mad r0.xy, v0, c2.zwzw, c2 + mul r1, r0.y, c4 + mad r0, c3, r0.x, r1 + add r0, r0, c5 + add r0, r0, -c6 + mul r1, r0.y, c8 + mad r1, c7, r0.x, r1 + mad r1, c9, r0.z, r1 + mad r0, c10, r0.w, r1 + mad oPos.xy, r0.w, c0, r0 + mov oPos.zw, r0 + + // approximately 12 instruction slots used + vs_4_0 + dcl_constantbuffer cb0[7], immediateIndexed + dcl_constantbuffer cb1[1], immediateIndexed + dcl_constantbuffer cb2[4], immediateIndexed + dcl_input v0.xy + dcl_output_siv o0.xyzw, position + dcl_output o1.xy + dcl_temps 2 + mad r0.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx + mul r1.xyzw, r0.yyyy, cb0[4].xyzw + mad r0.xyzw, cb0[3].xyzw, r0.xxxx, r1.xyzw + add r0.xyzw, r0.xyzw, cb0[6].xyzw + add r0.xyzw, r0.xyzw, -cb1[0].xyzw + mul r1.xyzw, r0.yyyy, cb2[1].xyzw + mad r1.xyzw, cb2[0].xyzw, r0.xxxx, r1.xyzw + mad r1.xyzw, cb2[2].xyzw, r0.zzzz, r1.xyzw + mad o0.xyzw, cb2[3].xyzw, r0.wwww, r1.xyzw + mad o1.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx + ret + // Approximately 11 instruction slots used + + }; + GeometryShader = NULL; + PixelShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 [unused] + // float4 vLayerQuad; // Offset: 16 Size: 16 [unused] + // float fLayerOpacity; // Offset: 32 Size: 4 + // float4x4 mLayerTransform; // Offset: 48 Size: 64 [unused] + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // LayerTextureSamplerLinear sampler NA NA 0 1 + // tRGB texture float4 2d 0 1 + // PerLayer cbuffer NA NA 0 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Target 0 xyzw 0 TARGET float xyzw + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c0 cb0 2 1 ( FLT, FLT, FLT, FLT) + // + // + // Sampler/Resource to DX9 shader sampler mappings: + // + // Target Sampler Source Sampler Source Resource + // -------------- --------------- ---------------- + // s0 s0 t0 + // + // + // Level9 shader bytecode: + // + ps_2_x + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mul r0, r0, c0.x + mov oC0, r0 + + // approximately 3 instruction slots used (1 texture, 2 arithmetic) + ps_4_0 + dcl_constantbuffer cb0[3], immediateIndexed + dcl_sampler s0, mode_default + dcl_resource_texture2d (float,float,float,float) t0 + dcl_input_ps linear v1.xy + dcl_output o0.xyzw + dcl_temps 1 + sample r0.xyzw, v1.xyxx, t0.xyzw, s0 + mul o0.xyzw, r0.xyzw, cb0[2].xxxx + ret + // Approximately 3 instruction slots used + + }; + } + +} + +technique10 RenderRGBALayerPremulPoint +{ + pass P0 + { + RasterizerState = LayerRast; + AB_BlendFactor = float4(0, 0, 0, 0); + AB_SampleMask = uint(0xffffffff); + BlendState = Premul; + VertexShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 + // float4 vLayerQuad; // Offset: 16 Size: 16 + // float fLayerOpacity; // Offset: 32 Size: 4 [unused] + // float4x4 mLayerTransform; // Offset: 48 Size: 64 + // + // } + // + // cbuffer PerOccasionalLayer + // { + // + // float4 vRenderTargetOffset; // Offset: 0 Size: 16 + // float4 fLayerColor; // Offset: 16 Size: 16 [unused] + // + // } + // + // cbuffer PerLayerManager + // { + // + // float4x4 mProjection; // Offset: 0 Size: 64 + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // PerLayer cbuffer NA NA 0 1 + // PerOccasionalLayer cbuffer NA NA 1 1 + // PerLayerManager cbuffer NA NA 2 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // POSITION 0 xy 0 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float xyzw + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c1 cb0 0 2 ( FLT, FLT, FLT, FLT) + // c3 cb0 3 2 ( FLT, FLT, FLT, FLT) + // c5 cb0 6 1 ( FLT, FLT, FLT, FLT) + // c6 cb1 0 1 ( FLT, FLT, FLT, FLT) + // c7 cb2 0 4 ( FLT, FLT, FLT, FLT) + // + // + // Runtime generated constant mappings: + // + // Target Reg Constant Description + // ---------- -------------------------------------------------- + // c0 Vertex Shader position offset + // + // + // Level9 shader bytecode: + // + vs_2_x + dcl_texcoord v0 + mad oT0.xy, v0, c1.zwzw, c1 + mad r0.xy, v0, c2.zwzw, c2 + mul r1, r0.y, c4 + mad r0, c3, r0.x, r1 + add r0, r0, c5 + add r0, r0, -c6 + mul r1, r0.y, c8 + mad r1, c7, r0.x, r1 + mad r1, c9, r0.z, r1 + mad r0, c10, r0.w, r1 + mad oPos.xy, r0.w, c0, r0 + mov oPos.zw, r0 + + // approximately 12 instruction slots used + vs_4_0 + dcl_constantbuffer cb0[7], immediateIndexed + dcl_constantbuffer cb1[1], immediateIndexed + dcl_constantbuffer cb2[4], immediateIndexed + dcl_input v0.xy + dcl_output_siv o0.xyzw, position + dcl_output o1.xy + dcl_temps 2 + mad r0.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx + mul r1.xyzw, r0.yyyy, cb0[4].xyzw + mad r0.xyzw, cb0[3].xyzw, r0.xxxx, r1.xyzw + add r0.xyzw, r0.xyzw, cb0[6].xyzw + add r0.xyzw, r0.xyzw, -cb1[0].xyzw + mul r1.xyzw, r0.yyyy, cb2[1].xyzw + mad r1.xyzw, cb2[0].xyzw, r0.xxxx, r1.xyzw + mad r1.xyzw, cb2[2].xyzw, r0.zzzz, r1.xyzw + mad o0.xyzw, cb2[3].xyzw, r0.wwww, r1.xyzw + mad o1.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx + ret + // Approximately 11 instruction slots used + + }; + GeometryShader = NULL; + PixelShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 [unused] + // float4 vLayerQuad; // Offset: 16 Size: 16 [unused] + // float fLayerOpacity; // Offset: 32 Size: 4 + // float4x4 mLayerTransform; // Offset: 48 Size: 64 [unused] + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // LayerTextureSamplerPoint sampler NA NA 0 1 + // tRGB texture float4 2d 0 1 + // PerLayer cbuffer NA NA 0 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Target 0 xyzw 0 TARGET float xyzw + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c0 cb0 2 1 ( FLT, FLT, FLT, FLT) + // + // + // Sampler/Resource to DX9 shader sampler mappings: + // + // Target Sampler Source Sampler Source Resource + // -------------- --------------- ---------------- + // s0 s0 t0 + // + // + // Level9 shader bytecode: + // + ps_2_x + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mul r0, r0, c0.x + mov oC0, r0 + + // approximately 3 instruction slots used (1 texture, 2 arithmetic) + ps_4_0 + dcl_constantbuffer cb0[3], immediateIndexed + dcl_sampler s0, mode_default + dcl_resource_texture2d (float,float,float,float) t0 + dcl_input_ps linear v1.xy + dcl_output o0.xyzw + dcl_temps 1 + sample r0.xyzw, v1.xyxx, t0.xyzw, s0 + mul o0.xyzw, r0.xyzw, cb0[2].xxxx + ret + // Approximately 3 instruction slots used + + }; + } + +} + +technique10 RenderRGBALayerNonPremulPoint +{ + pass P0 + { + RasterizerState = LayerRast; + AB_BlendFactor = float4(0, 0, 0, 0); + AB_SampleMask = uint(0xffffffff); + BlendState = NonPremul; + VertexShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 + // float4 vLayerQuad; // Offset: 16 Size: 16 + // float fLayerOpacity; // Offset: 32 Size: 4 [unused] + // float4x4 mLayerTransform; // Offset: 48 Size: 64 + // + // } + // + // cbuffer PerOccasionalLayer + // { + // + // float4 vRenderTargetOffset; // Offset: 0 Size: 16 + // float4 fLayerColor; // Offset: 16 Size: 16 [unused] + // + // } + // + // cbuffer PerLayerManager + // { + // + // float4x4 mProjection; // Offset: 0 Size: 64 + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // PerLayer cbuffer NA NA 0 1 + // PerOccasionalLayer cbuffer NA NA 1 1 + // PerLayerManager cbuffer NA NA 2 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // POSITION 0 xy 0 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float xyzw + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c1 cb0 0 2 ( FLT, FLT, FLT, FLT) + // c3 cb0 3 2 ( FLT, FLT, FLT, FLT) + // c5 cb0 6 1 ( FLT, FLT, FLT, FLT) + // c6 cb1 0 1 ( FLT, FLT, FLT, FLT) + // c7 cb2 0 4 ( FLT, FLT, FLT, FLT) + // + // + // Runtime generated constant mappings: + // + // Target Reg Constant Description + // ---------- -------------------------------------------------- + // c0 Vertex Shader position offset + // + // + // Level9 shader bytecode: + // + vs_2_x + dcl_texcoord v0 + mad oT0.xy, v0, c1.zwzw, c1 + mad r0.xy, v0, c2.zwzw, c2 + mul r1, r0.y, c4 + mad r0, c3, r0.x, r1 + add r0, r0, c5 + add r0, r0, -c6 + mul r1, r0.y, c8 + mad r1, c7, r0.x, r1 + mad r1, c9, r0.z, r1 + mad r0, c10, r0.w, r1 + mad oPos.xy, r0.w, c0, r0 + mov oPos.zw, r0 + + // approximately 12 instruction slots used + vs_4_0 + dcl_constantbuffer cb0[7], immediateIndexed + dcl_constantbuffer cb1[1], immediateIndexed + dcl_constantbuffer cb2[4], immediateIndexed + dcl_input v0.xy + dcl_output_siv o0.xyzw, position + dcl_output o1.xy + dcl_temps 2 + mad r0.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx + mul r1.xyzw, r0.yyyy, cb0[4].xyzw + mad r0.xyzw, cb0[3].xyzw, r0.xxxx, r1.xyzw + add r0.xyzw, r0.xyzw, cb0[6].xyzw + add r0.xyzw, r0.xyzw, -cb1[0].xyzw + mul r1.xyzw, r0.yyyy, cb2[1].xyzw + mad r1.xyzw, cb2[0].xyzw, r0.xxxx, r1.xyzw + mad r1.xyzw, cb2[2].xyzw, r0.zzzz, r1.xyzw + mad o0.xyzw, cb2[3].xyzw, r0.wwww, r1.xyzw + mad o1.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx + ret + // Approximately 11 instruction slots used + + }; + GeometryShader = NULL; + PixelShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 [unused] + // float4 vLayerQuad; // Offset: 16 Size: 16 [unused] + // float fLayerOpacity; // Offset: 32 Size: 4 + // float4x4 mLayerTransform; // Offset: 48 Size: 64 [unused] + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // LayerTextureSamplerPoint sampler NA NA 0 1 + // tRGB texture float4 2d 0 1 + // PerLayer cbuffer NA NA 0 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Target 0 xyzw 0 TARGET float xyzw + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c0 cb0 2 1 ( FLT, FLT, FLT, FLT) + // + // + // Sampler/Resource to DX9 shader sampler mappings: + // + // Target Sampler Source Sampler Source Resource + // -------------- --------------- ---------------- + // s0 s0 t0 + // + // + // Level9 shader bytecode: + // + ps_2_x + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mul r0, r0, c0.x + mov oC0, r0 + + // approximately 3 instruction slots used (1 texture, 2 arithmetic) + ps_4_0 + dcl_constantbuffer cb0[3], immediateIndexed + dcl_sampler s0, mode_default + dcl_resource_texture2d (float,float,float,float) t0 + dcl_input_ps linear v1.xy + dcl_output o0.xyzw + dcl_temps 1 + sample r0.xyzw, v1.xyxx, t0.xyzw, s0 + mul o0.xyzw, r0.xyzw, cb0[2].xxxx + ret + // Approximately 3 instruction slots used + + }; + } + +} + +technique10 RenderYCbCrLayer +{ + pass P0 + { + RasterizerState = LayerRast; + AB_BlendFactor = float4(0, 0, 0, 0); + AB_SampleMask = uint(0xffffffff); + BlendState = Premul; + VertexShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 + // float4 vLayerQuad; // Offset: 16 Size: 16 + // float fLayerOpacity; // Offset: 32 Size: 4 [unused] + // float4x4 mLayerTransform; // Offset: 48 Size: 64 + // + // } + // + // cbuffer PerOccasionalLayer + // { + // + // float4 vRenderTargetOffset; // Offset: 0 Size: 16 + // float4 fLayerColor; // Offset: 16 Size: 16 [unused] + // + // } + // + // cbuffer PerLayerManager + // { + // + // float4x4 mProjection; // Offset: 0 Size: 64 + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // PerLayer cbuffer NA NA 0 1 + // PerOccasionalLayer cbuffer NA NA 1 1 + // PerLayerManager cbuffer NA NA 2 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // POSITION 0 xy 0 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float xyzw + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c1 cb0 0 2 ( FLT, FLT, FLT, FLT) + // c3 cb0 3 2 ( FLT, FLT, FLT, FLT) + // c5 cb0 6 1 ( FLT, FLT, FLT, FLT) + // c6 cb1 0 1 ( FLT, FLT, FLT, FLT) + // c7 cb2 0 4 ( FLT, FLT, FLT, FLT) + // + // + // Runtime generated constant mappings: + // + // Target Reg Constant Description + // ---------- -------------------------------------------------- + // c0 Vertex Shader position offset + // + // + // Level9 shader bytecode: + // + vs_2_x + dcl_texcoord v0 + mad oT0.xy, v0, c1.zwzw, c1 + mad r0.xy, v0, c2.zwzw, c2 + mul r1, r0.y, c4 + mad r0, c3, r0.x, r1 + add r0, r0, c5 + add r0, r0, -c6 + mul r1, r0.y, c8 + mad r1, c7, r0.x, r1 + mad r1, c9, r0.z, r1 + mad r0, c10, r0.w, r1 + mad oPos.xy, r0.w, c0, r0 + mov oPos.zw, r0 + + // approximately 12 instruction slots used + vs_4_0 + dcl_constantbuffer cb0[7], immediateIndexed + dcl_constantbuffer cb1[1], immediateIndexed + dcl_constantbuffer cb2[4], immediateIndexed + dcl_input v0.xy + dcl_output_siv o0.xyzw, position + dcl_output o1.xy + dcl_temps 2 + mad r0.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx + mul r1.xyzw, r0.yyyy, cb0[4].xyzw + mad r0.xyzw, cb0[3].xyzw, r0.xxxx, r1.xyzw + add r0.xyzw, r0.xyzw, cb0[6].xyzw + add r0.xyzw, r0.xyzw, -cb1[0].xyzw + mul r1.xyzw, r0.yyyy, cb2[1].xyzw + mad r1.xyzw, cb2[0].xyzw, r0.xxxx, r1.xyzw + mad r1.xyzw, cb2[2].xyzw, r0.zzzz, r1.xyzw + mad o0.xyzw, cb2[3].xyzw, r0.wwww, r1.xyzw + mad o1.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx + ret + // Approximately 11 instruction slots used + + }; + GeometryShader = NULL; + PixelShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 [unused] + // float4 vLayerQuad; // Offset: 16 Size: 16 [unused] + // float fLayerOpacity; // Offset: 32 Size: 4 + // float4x4 mLayerTransform; // Offset: 48 Size: 64 [unused] + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // LayerTextureSamplerLinear sampler NA NA 0 1 + // tY texture float4 2d 0 1 + // tCb texture float4 2d 1 1 + // tCr texture float4 2d 2 1 + // PerLayer cbuffer NA NA 0 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Target 0 xyzw 0 TARGET float xyzw + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c0 cb0 2 1 ( FLT, FLT, FLT, FLT) + // + // + // Sampler/Resource to DX9 shader sampler mappings: + // + // Target Sampler Source Sampler Source Resource + // -------------- --------------- ---------------- + // s0 s0 t0 + // s1 s0 t1 + // s2 s0 t2 + // + // + // Level9 shader bytecode: + // + ps_2_x + def c1, -0.5, -0.0625, 1.59599996, 0.813000023 + def c2, 1.16400003, 2.01799989, 0.391000003, 1 + dcl t0.xy + dcl_2d s0 + dcl_2d s1 + dcl_2d s2 + texld r0, t0, s0 + texld r1, t0, s2 + add r0.y, r1.x, c1.x + mul r0.yz, r0.y, c1.xzww + add r0.x, r0.x, c1.y + mad r0.z, r0.x, c2.x, -r0.z + mad r1.x, r0.x, c2.x, r0.y + texld r2, t0, s1 + add r0.y, r2.x, c1.x + mad r1.y, r0.y, -c2.z, r0.z + mul r0.y, r0.y, c2.y + mad r1.z, r0.x, c2.x, r0.y + mov r1.w, c2.w + mul r0, r1, c0.x + mov oC0, r0 + + // approximately 15 instruction slots used (3 texture, 12 arithmetic) + ps_4_0 + dcl_constantbuffer cb0[3], immediateIndexed + dcl_sampler s0, mode_default + dcl_resource_texture2d (float,float,float,float) t0 + dcl_resource_texture2d (float,float,float,float) t1 + dcl_resource_texture2d (float,float,float,float) t2 + dcl_input_ps linear v1.xy + dcl_output o0.xyzw + dcl_temps 3 + sample r0.xyzw, v1.xyxx, t2.xyzw, s0 + add r0.x, r0.x, l(-0.500000) + mul r0.xy, r0.xxxx, l(1.596000, 0.813000, 0.000000, 0.000000) + sample r1.xyzw, v1.xyxx, t0.xyzw, s0 + add r0.z, r1.x, l(-0.062500) + mad r0.y, r0.z, l(1.164000), -r0.y + mad r1.x, r0.z, l(1.164000), r0.x + sample r2.xyzw, v1.xyxx, t1.xyzw, s0 + add r0.x, r2.x, l(-0.500000) + mad r1.y, -r0.x, l(0.391000), r0.y + mul r0.x, r0.x, l(2.018000) + mad r1.z, r0.z, l(1.164000), r0.x + mov r1.w, l(1.000000) + mul o0.xyzw, r1.xyzw, cb0[2].xxxx + ret + // Approximately 15 instruction slots used + + }; + } + +} + +technique10 RenderSolidColorLayer +{ + pass P0 + { + RasterizerState = LayerRast; + AB_BlendFactor = float4(0, 0, 0, 0); + AB_SampleMask = uint(0xffffffff); + BlendState = Premul; + VertexShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerLayer + // { + // + // float4 vTextureCoords; // Offset: 0 Size: 16 + // float4 vLayerQuad; // Offset: 16 Size: 16 + // float fLayerOpacity; // Offset: 32 Size: 4 [unused] + // float4x4 mLayerTransform; // Offset: 48 Size: 64 + // + // } + // + // cbuffer PerOccasionalLayer + // { + // + // float4 vRenderTargetOffset; // Offset: 0 Size: 16 + // float4 fLayerColor; // Offset: 16 Size: 16 [unused] + // + // } + // + // cbuffer PerLayerManager + // { + // + // float4x4 mProjection; // Offset: 0 Size: 64 + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // PerLayer cbuffer NA NA 0 1 + // PerOccasionalLayer cbuffer NA NA 1 1 + // PerLayerManager cbuffer NA NA 2 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // POSITION 0 xy 0 NONE float xy + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float xyzw + // TEXCOORD 0 xy 1 NONE float xy + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c1 cb0 0 2 ( FLT, FLT, FLT, FLT) + // c3 cb0 3 2 ( FLT, FLT, FLT, FLT) + // c5 cb0 6 1 ( FLT, FLT, FLT, FLT) + // c6 cb1 0 1 ( FLT, FLT, FLT, FLT) + // c7 cb2 0 4 ( FLT, FLT, FLT, FLT) + // + // + // Runtime generated constant mappings: + // + // Target Reg Constant Description + // ---------- -------------------------------------------------- + // c0 Vertex Shader position offset + // + // + // Level9 shader bytecode: + // + vs_2_x + dcl_texcoord v0 + mad oT0.xy, v0, c1.zwzw, c1 + mad r0.xy, v0, c2.zwzw, c2 + mul r1, r0.y, c4 + mad r0, c3, r0.x, r1 + add r0, r0, c5 + add r0, r0, -c6 + mul r1, r0.y, c8 + mad r1, c7, r0.x, r1 + mad r1, c9, r0.z, r1 + mad r0, c10, r0.w, r1 + mad oPos.xy, r0.w, c0, r0 + mov oPos.zw, r0 + + // approximately 12 instruction slots used + vs_4_0 + dcl_constantbuffer cb0[7], immediateIndexed + dcl_constantbuffer cb1[1], immediateIndexed + dcl_constantbuffer cb2[4], immediateIndexed + dcl_input v0.xy + dcl_output_siv o0.xyzw, position + dcl_output o1.xy + dcl_temps 2 + mad r0.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx + mul r1.xyzw, r0.yyyy, cb0[4].xyzw + mad r0.xyzw, cb0[3].xyzw, r0.xxxx, r1.xyzw + add r0.xyzw, r0.xyzw, cb0[6].xyzw + add r0.xyzw, r0.xyzw, -cb1[0].xyzw + mul r1.xyzw, r0.yyyy, cb2[1].xyzw + mad r1.xyzw, cb2[0].xyzw, r0.xxxx, r1.xyzw + mad r1.xyzw, cb2[2].xyzw, r0.zzzz, r1.xyzw + mad o0.xyzw, cb2[3].xyzw, r0.wwww, r1.xyzw + mad o1.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx + ret + // Approximately 11 instruction slots used + + }; + GeometryShader = NULL; + PixelShader = asm { + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // + // Buffer Definitions: + // + // cbuffer PerOccasionalLayer + // { + // + // float4 vRenderTargetOffset; // Offset: 0 Size: 16 [unused] + // float4 fLayerColor; // Offset: 16 Size: 16 + // + // } + // + // + // Resource Bindings: + // + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // PerOccasionalLayer cbuffer NA NA 0 1 + // + // + // + // Input signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Position 0 xyzw 0 POS float + // TEXCOORD 0 xy 1 NONE float + // + // + // Output signature: + // + // Name Index Mask Register SysValue Format Used + // -------------------- ----- ------ -------- -------- ------ ------ + // SV_Target 0 xyzw 0 TARGET float xyzw + // + // + // Constant buffer to DX9 shader constant mappings: + // + // Target Reg Buffer Start Reg # of Regs Data Conversion + // ---------- ------- --------- --------- ---------------------- + // c0 cb0 1 1 ( FLT, FLT, FLT, FLT) + // + // + // Level9 shader bytecode: + // + ps_2_x + mov oC0, c0 + + // approximately 1 instruction slot used + ps_4_0 + dcl_constantbuffer cb0[2], immediateIndexed + dcl_output o0.xyzw + mov o0.xyzw, cb0[1].xyzw + ret + // Approximately 2 instruction slots used + + }; + } + +} + +#endif + +const BYTE g_main[] = +{ + 68, 88, 66, 67, 18, 123, + 251, 150, 69, 183, 40, 21, + 168, 16, 172, 202, 163, 95, + 140, 89, 1, 0, 0, 0, + 71, 106, 0, 0, 1, 0, + 0, 0, 36, 0, 0, 0, + 70, 88, 49, 48, 27, 106, + 0, 0, 1, 16, 255, 254, + 3, 0, 0, 0, 7, 0, + 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 43, 98, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 80, 101, + 114, 76, 97, 121, 101, 114, + 0, 102, 108, 111, 97, 116, + 52, 0, 13, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 16, 0, + 0, 0, 10, 33, 0, 0, + 118, 84, 101, 120, 116, 117, + 114, 101, 67, 111, 111, 114, + 100, 115, 0, 118, 76, 97, + 121, 101, 114, 81, 117, 97, + 100, 0, 102, 108, 111, 97, + 116, 0, 74, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 16, 0, 0, 0, 4, 0, + 0, 0, 9, 9, 0, 0, + 102, 76, 97, 121, 101, 114, + 79, 112, 97, 99, 105, 116, + 121, 0, 102, 108, 111, 97, + 116, 52, 120, 52, 0, 122, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 64, + 0, 0, 0, 64, 0, 0, + 0, 64, 0, 0, 0, 11, + 100, 0, 0, 109, 76, 97, + 121, 101, 114, 84, 114, 97, + 110, 115, 102, 111, 114, 109, + 0, 80, 101, 114, 79, 99, + 99, 97, 115, 105, 111, 110, + 97, 108, 76, 97, 121, 101, + 114, 0, 118, 82, 101, 110, + 100, 101, 114, 84, 97, 114, + 103, 101, 116, 79, 102, 102, + 115, 101, 116, 0, 102, 76, + 97, 121, 101, 114, 67, 111, + 108, 111, 114, 0, 80, 101, + 114, 76, 97, 121, 101, 114, + 77, 97, 110, 97, 103, 101, + 114, 0, 109, 80, 114, 111, + 106, 101, 99, 116, 105, 111, + 110, 0, 66, 108, 101, 110, + 100, 83, 116, 97, 116, 101, + 0, 254, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 80, + 114, 101, 109, 117, 108, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 6, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 6, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 15, 0, 0, 0, + 78, 111, 110, 80, 114, 101, + 109, 117, 108, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 5, 0, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 6, 0, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 6, 0, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 15, 0, 0, 0, 82, 97, + 115, 116, 101, 114, 105, 122, + 101, 114, 83, 116, 97, 116, + 101, 0, 14, 2, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 76, 97, 121, 101, 114, 82, + 97, 115, 116, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 84, 101, + 120, 116, 117, 114, 101, 50, + 68, 0, 80, 2, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 12, 0, 0, 0, + 116, 82, 71, 66, 0, 116, + 89, 0, 116, 67, 98, 0, + 116, 67, 114, 0, 83, 97, + 109, 112, 108, 101, 114, 83, + 116, 97, 116, 101, 0, 134, + 2, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 21, + 0, 0, 0, 76, 97, 121, + 101, 114, 84, 101, 120, 116, + 117, 114, 101, 83, 97, 109, + 112, 108, 101, 114, 76, 105, + 110, 101, 97, 114, 0, 1, + 0, 0, 0, 2, 0, 0, + 0, 21, 0, 0, 0, 1, + 0, 0, 0, 2, 0, 0, + 0, 1, 0, 0, 0, 1, + 0, 0, 0, 2, 0, 0, + 0, 1, 0, 0, 0, 76, + 97, 121, 101, 114, 84, 101, + 120, 116, 117, 114, 101, 83, + 97, 109, 112, 108, 101, 114, + 80, 111, 105, 110, 116, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 82, 101, 110, 100, 101, 114, + 82, 71, 66, 76, 97, 121, + 101, 114, 80, 114, 101, 109, + 117, 108, 0, 80, 48, 0, + 4, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 255, 255, 255, 255, + 4, 7, 0, 0, 68, 88, + 66, 67, 74, 0, 69, 126, + 158, 251, 122, 220, 157, 162, + 154, 166, 138, 69, 197, 120, + 1, 0, 0, 0, 4, 7, + 0, 0, 6, 0, 0, 0, + 56, 0, 0, 0, 144, 1, + 0, 0, 128, 3, 0, 0, + 252, 3, 0, 0, 120, 6, + 0, 0, 172, 6, 0, 0, + 65, 111, 110, 57, 80, 1, + 0, 0, 80, 1, 0, 0, + 0, 2, 254, 255, 236, 0, + 0, 0, 100, 0, 0, 0, + 5, 0, 36, 0, 0, 0, + 96, 0, 0, 0, 96, 0, + 0, 0, 36, 0, 1, 0, + 96, 0, 0, 0, 0, 0, + 2, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 2, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 6, 0, + 1, 0, 5, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 6, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 2, 254, 255, 31, 0, + 0, 2, 5, 0, 0, 128, + 0, 0, 15, 144, 4, 0, + 0, 4, 0, 0, 3, 224, + 0, 0, 228, 144, 1, 0, + 238, 160, 1, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 3, 128, 0, 0, 228, 144, + 2, 0, 238, 160, 2, 0, + 228, 160, 5, 0, 0, 3, + 1, 0, 15, 128, 0, 0, + 85, 128, 4, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 15, 128, 3, 0, 228, 160, + 0, 0, 0, 128, 1, 0, + 228, 128, 2, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 228, 128, 5, 0, 228, 160, + 2, 0, 0, 3, 0, 0, + 15, 128, 0, 0, 228, 128, + 6, 0, 228, 161, 5, 0, + 0, 3, 1, 0, 15, 128, + 0, 0, 85, 128, 8, 0, + 228, 160, 4, 0, 0, 4, + 1, 0, 15, 128, 7, 0, + 228, 160, 0, 0, 0, 128, + 1, 0, 228, 128, 4, 0, + 0, 4, 1, 0, 15, 128, + 9, 0, 228, 160, 0, 0, + 170, 128, 1, 0, 228, 128, + 4, 0, 0, 4, 0, 0, + 15, 128, 10, 0, 228, 160, + 0, 0, 255, 128, 1, 0, + 228, 128, 4, 0, 0, 4, + 0, 0, 3, 192, 0, 0, + 255, 128, 0, 0, 228, 160, + 0, 0, 228, 128, 1, 0, + 0, 2, 0, 0, 12, 192, + 0, 0, 228, 128, 255, 255, + 0, 0, 83, 72, 68, 82, + 232, 1, 0, 0, 64, 0, + 1, 0, 122, 0, 0, 0, + 89, 0, 0, 4, 70, 142, + 32, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 2, 0, + 0, 0, 4, 0, 0, 0, + 95, 0, 0, 3, 50, 16, + 16, 0, 0, 0, 0, 0, + 103, 0, 0, 4, 242, 32, + 16, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 50, 32, 16, 0, + 1, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, + 50, 0, 0, 11, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 0, 0, + 0, 0, 230, 138, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 70, 128, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 56, 0, 0, 8, + 242, 0, 16, 0, 1, 0, + 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 70, 142, + 32, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 50, 0, + 0, 10, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 142, + 32, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 6, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 1, 0, + 0, 0, 0, 0, 0, 8, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 142, + 32, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, + 70, 142, 32, 128, 65, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 56, 0, + 0, 8, 242, 0, 16, 0, + 1, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, + 70, 142, 32, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 50, 0, 0, 10, 242, 0, + 16, 0, 1, 0, 0, 0, + 70, 142, 32, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 50, 0, + 0, 10, 242, 0, 16, 0, + 1, 0, 0, 0, 70, 142, + 32, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 166, 10, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 10, + 242, 32, 16, 0, 0, 0, + 0, 0, 70, 142, 32, 0, + 2, 0, 0, 0, 3, 0, + 0, 0, 246, 15, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, + 50, 0, 0, 11, 50, 32, + 16, 0, 1, 0, 0, 0, + 70, 16, 16, 0, 0, 0, + 0, 0, 230, 138, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 70, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 11, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 68, + 69, 70, 116, 2, 0, 0, + 3, 0, 0, 0, 168, 0, + 0, 0, 3, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 254, 255, 0, 1, 0, 0, + 64, 2, 0, 0, 124, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 133, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 152, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 80, 101, + 114, 76, 97, 121, 101, 114, + 0, 80, 101, 114, 79, 99, + 99, 97, 115, 105, 111, 110, + 97, 108, 76, 97, 121, 101, + 114, 0, 80, 101, 114, 76, + 97, 121, 101, 114, 77, 97, + 110, 97, 103, 101, 114, 0, + 124, 0, 0, 0, 4, 0, + 0, 0, 240, 0, 0, 0, + 112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 133, 0, 0, 0, 2, 0, + 0, 0, 188, 1, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 152, 0, 0, 0, 1, 0, + 0, 0, 28, 2, 0, 0, + 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 80, 1, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, + 2, 0, 0, 0, 96, 1, + 0, 0, 0, 0, 0, 0, + 112, 1, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, + 2, 0, 0, 0, 96, 1, + 0, 0, 0, 0, 0, 0, + 123, 1, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 140, 1, + 0, 0, 0, 0, 0, 0, + 156, 1, 0, 0, 48, 0, + 0, 0, 64, 0, 0, 0, + 2, 0, 0, 0, 172, 1, + 0, 0, 0, 0, 0, 0, + 118, 84, 101, 120, 116, 117, + 114, 101, 67, 111, 111, 114, + 100, 115, 0, 171, 1, 0, + 3, 0, 1, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 118, 76, 97, 121, + 101, 114, 81, 117, 97, 100, + 0, 102, 76, 97, 121, 101, + 114, 79, 112, 97, 99, 105, + 116, 121, 0, 171, 171, 171, + 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 109, 76, + 97, 121, 101, 114, 84, 114, + 97, 110, 115, 102, 111, 114, + 109, 0, 3, 0, 3, 0, + 4, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 236, 1, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, + 2, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, + 16, 2, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, + 118, 82, 101, 110, 100, 101, + 114, 84, 97, 114, 103, 101, + 116, 79, 102, 102, 115, 101, + 116, 0, 1, 0, 3, 0, + 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 102, 76, 97, 121, 101, 114, + 67, 111, 108, 111, 114, 0, + 52, 2, 0, 0, 0, 0, + 0, 0, 64, 0, 0, 0, + 2, 0, 0, 0, 172, 1, + 0, 0, 0, 0, 0, 0, + 109, 80, 114, 111, 106, 101, + 99, 116, 105, 111, 110, 0, + 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, + 41, 32, 72, 76, 83, 76, + 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 57, + 46, 50, 57, 46, 57, 53, + 50, 46, 51, 49, 49, 49, + 0, 171, 171, 171, 73, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 3, 3, + 0, 0, 80, 79, 83, 73, + 84, 73, 79, 78, 0, 171, + 171, 171, 79, 83, 71, 78, + 80, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 3, 12, 0, 0, + 83, 86, 95, 80, 111, 115, + 105, 116, 105, 111, 110, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 171, 171, 171, + 114, 3, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 84, 4, 0, 0, + 68, 88, 66, 67, 243, 1, + 145, 163, 244, 213, 142, 119, + 56, 177, 66, 167, 121, 91, + 183, 98, 1, 0, 0, 0, + 84, 4, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 204, 0, 0, 0, 136, 1, + 0, 0, 4, 2, 0, 0, + 200, 3, 0, 0, 32, 4, + 0, 0, 65, 111, 110, 57, + 140, 0, 0, 0, 140, 0, + 0, 0, 0, 2, 255, 255, + 88, 0, 0, 0, 52, 0, + 0, 0, 1, 0, 40, 0, + 0, 0, 52, 0, 0, 0, + 52, 0, 1, 0, 36, 0, + 0, 0, 52, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 255, 255, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 3, 176, + 31, 0, 0, 2, 0, 0, + 0, 144, 0, 8, 15, 160, + 66, 0, 0, 3, 0, 0, + 15, 128, 0, 0, 228, 176, + 0, 8, 228, 160, 5, 0, + 0, 3, 0, 0, 7, 128, + 0, 0, 228, 128, 0, 0, + 0, 160, 1, 0, 0, 2, + 0, 0, 8, 128, 0, 0, + 0, 160, 1, 0, 0, 2, + 0, 8, 15, 128, 0, 0, + 228, 128, 255, 255, 0, 0, + 83, 72, 68, 82, 180, 0, + 0, 0, 64, 0, 0, 0, + 45, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 90, 0, 0, 3, + 0, 96, 16, 0, 0, 0, + 0, 0, 88, 24, 0, 4, + 0, 112, 16, 0, 0, 0, + 0, 0, 85, 85, 0, 0, + 98, 16, 0, 3, 50, 16, + 16, 0, 1, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 0, 0, 0, 0, + 104, 0, 0, 2, 1, 0, + 0, 0, 69, 0, 0, 9, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 8, + 114, 32, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 6, 128, + 32, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 54, 0, + 0, 6, 130, 32, 16, 0, + 0, 0, 0, 0, 10, 128, + 32, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 82, 68, 69, 70, 188, 1, + 0, 0, 1, 0, 0, 0, + 164, 0, 0, 0, 3, 0, + 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, + 0, 0, 136, 1, 0, 0, + 124, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 150, 0, 0, 0, + 2, 0, 0, 0, 5, 0, + 0, 0, 4, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 1, 0, 0, 0, + 12, 0, 0, 0, 155, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 76, 97, 121, 101, 114, 84, + 101, 120, 116, 117, 114, 101, + 83, 97, 109, 112, 108, 101, + 114, 76, 105, 110, 101, 97, + 114, 0, 116, 82, 71, 66, + 0, 80, 101, 114, 76, 97, + 121, 101, 114, 0, 155, 0, + 0, 0, 4, 0, 0, 0, + 188, 0, 0, 0, 112, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 28, 1, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, + 0, 0, 44, 1, 0, 0, + 0, 0, 0, 0, 60, 1, + 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, + 0, 0, 44, 1, 0, 0, + 0, 0, 0, 0, 71, 1, + 0, 0, 32, 0, 0, 0, + 4, 0, 0, 0, 2, 0, + 0, 0, 88, 1, 0, 0, + 0, 0, 0, 0, 104, 1, + 0, 0, 48, 0, 0, 0, + 64, 0, 0, 0, 0, 0, + 0, 0, 120, 1, 0, 0, + 0, 0, 0, 0, 118, 84, + 101, 120, 116, 117, 114, 101, + 67, 111, 111, 114, 100, 115, + 0, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 118, 76, 97, 121, 101, 114, + 81, 117, 97, 100, 0, 102, + 76, 97, 121, 101, 114, 79, + 112, 97, 99, 105, 116, 121, + 0, 171, 171, 171, 0, 0, + 3, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 109, 76, 97, 121, + 101, 114, 84, 114, 97, 110, + 115, 102, 111, 114, 109, 0, + 3, 0, 3, 0, 4, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 50, + 57, 46, 57, 53, 50, 46, + 51, 49, 49, 49, 0, 171, + 171, 171, 73, 83, 71, 78, + 80, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 3, 3, 0, 0, + 83, 86, 95, 80, 111, 115, + 105, 116, 105, 111, 110, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 171, 171, 171, + 79, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 83, 86, + 95, 84, 97, 114, 103, 101, + 116, 0, 171, 171, 142, 10, + 0, 0, 0, 0, 0, 0, + 82, 101, 110, 100, 101, 114, + 82, 71, 66, 76, 97, 121, + 101, 114, 80, 114, 101, 109, + 117, 108, 80, 111, 105, 110, + 116, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 255, 255, + 255, 255, 4, 7, 0, 0, + 68, 88, 66, 67, 74, 0, + 69, 126, 158, 251, 122, 220, + 157, 162, 154, 166, 138, 69, + 197, 120, 1, 0, 0, 0, + 4, 7, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 144, 1, 0, 0, 128, 3, + 0, 0, 252, 3, 0, 0, + 120, 6, 0, 0, 172, 6, + 0, 0, 65, 111, 110, 57, + 80, 1, 0, 0, 80, 1, + 0, 0, 0, 2, 254, 255, + 236, 0, 0, 0, 100, 0, + 0, 0, 5, 0, 36, 0, + 0, 0, 96, 0, 0, 0, + 96, 0, 0, 0, 36, 0, + 1, 0, 96, 0, 0, 0, + 0, 0, 2, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 2, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 1, 0, 5, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 6, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 4, 0, 7, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 254, 255, + 31, 0, 0, 2, 5, 0, + 0, 128, 0, 0, 15, 144, + 4, 0, 0, 4, 0, 0, + 3, 224, 0, 0, 228, 144, + 1, 0, 238, 160, 1, 0, + 228, 160, 4, 0, 0, 4, + 0, 0, 3, 128, 0, 0, + 228, 144, 2, 0, 238, 160, + 2, 0, 228, 160, 5, 0, + 0, 3, 1, 0, 15, 128, + 0, 0, 85, 128, 4, 0, + 228, 160, 4, 0, 0, 4, + 0, 0, 15, 128, 3, 0, + 228, 160, 0, 0, 0, 128, + 1, 0, 228, 128, 2, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 228, 128, 5, 0, + 228, 160, 2, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 228, 128, 6, 0, 228, 161, + 5, 0, 0, 3, 1, 0, + 15, 128, 0, 0, 85, 128, + 8, 0, 228, 160, 4, 0, + 0, 4, 1, 0, 15, 128, + 7, 0, 228, 160, 0, 0, + 0, 128, 1, 0, 228, 128, + 4, 0, 0, 4, 1, 0, + 15, 128, 9, 0, 228, 160, + 0, 0, 170, 128, 1, 0, + 228, 128, 4, 0, 0, 4, + 0, 0, 15, 128, 10, 0, + 228, 160, 0, 0, 255, 128, + 1, 0, 228, 128, 4, 0, + 0, 4, 0, 0, 3, 192, + 0, 0, 255, 128, 0, 0, + 228, 160, 0, 0, 228, 128, + 1, 0, 0, 2, 0, 0, + 12, 192, 0, 0, 228, 128, + 255, 255, 0, 0, 83, 72, + 68, 82, 232, 1, 0, 0, + 64, 0, 1, 0, 122, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 0, 0, + 0, 0, 7, 0, 0, 0, + 89, 0, 0, 4, 70, 142, + 32, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 2, 0, 0, 0, 4, 0, + 0, 0, 95, 0, 0, 3, + 50, 16, 16, 0, 0, 0, + 0, 0, 103, 0, 0, 4, + 242, 32, 16, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 101, 0, 0, 3, 50, 32, + 16, 0, 1, 0, 0, 0, + 104, 0, 0, 2, 2, 0, + 0, 0, 50, 0, 0, 11, + 50, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, + 0, 0, 0, 0, 230, 138, + 32, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 70, 128, + 32, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 56, 0, + 0, 8, 242, 0, 16, 0, + 1, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, + 70, 142, 32, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 50, 0, 0, 10, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 142, 32, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 0, 0, + 0, 8, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, + 70, 142, 32, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 0, 0, 0, 9, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 142, 32, 128, + 65, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 56, 0, 0, 8, 242, 0, + 16, 0, 1, 0, 0, 0, + 86, 5, 16, 0, 0, 0, + 0, 0, 70, 142, 32, 0, + 2, 0, 0, 0, 1, 0, + 0, 0, 50, 0, 0, 10, + 242, 0, 16, 0, 1, 0, + 0, 0, 70, 142, 32, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, + 50, 0, 0, 10, 242, 0, + 16, 0, 1, 0, 0, 0, + 70, 142, 32, 0, 2, 0, + 0, 0, 2, 0, 0, 0, + 166, 10, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 50, 0, + 0, 10, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 142, + 32, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 246, 15, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 11, + 50, 32, 16, 0, 1, 0, + 0, 0, 70, 16, 16, 0, + 0, 0, 0, 0, 230, 138, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 11, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 82, 68, 69, 70, 116, 2, + 0, 0, 3, 0, 0, 0, + 168, 0, 0, 0, 3, 0, + 0, 0, 28, 0, 0, 0, + 0, 4, 254, 255, 0, 1, + 0, 0, 64, 2, 0, 0, + 124, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 133, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 152, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 80, 101, 114, 76, 97, 121, + 101, 114, 0, 80, 101, 114, + 79, 99, 99, 97, 115, 105, + 111, 110, 97, 108, 76, 97, + 121, 101, 114, 0, 80, 101, + 114, 76, 97, 121, 101, 114, + 77, 97, 110, 97, 103, 101, + 114, 0, 124, 0, 0, 0, + 4, 0, 0, 0, 240, 0, + 0, 0, 112, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 133, 0, 0, 0, + 2, 0, 0, 0, 188, 1, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 152, 0, 0, 0, + 1, 0, 0, 0, 28, 2, + 0, 0, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 80, 1, 0, 0, + 0, 0, 0, 0, 16, 0, + 0, 0, 2, 0, 0, 0, + 96, 1, 0, 0, 0, 0, + 0, 0, 112, 1, 0, 0, + 16, 0, 0, 0, 16, 0, + 0, 0, 2, 0, 0, 0, + 96, 1, 0, 0, 0, 0, + 0, 0, 123, 1, 0, 0, + 32, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 140, 1, 0, 0, 0, 0, + 0, 0, 156, 1, 0, 0, + 48, 0, 0, 0, 64, 0, + 0, 0, 2, 0, 0, 0, + 172, 1, 0, 0, 0, 0, + 0, 0, 118, 84, 101, 120, + 116, 117, 114, 101, 67, 111, + 111, 114, 100, 115, 0, 171, + 1, 0, 3, 0, 1, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 118, 76, + 97, 121, 101, 114, 81, 117, + 97, 100, 0, 102, 76, 97, + 121, 101, 114, 79, 112, 97, + 99, 105, 116, 121, 0, 171, + 171, 171, 0, 0, 3, 0, + 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 109, 76, 97, 121, 101, 114, + 84, 114, 97, 110, 115, 102, + 111, 114, 109, 0, 3, 0, + 3, 0, 4, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 236, 1, 0, 0, + 0, 0, 0, 0, 16, 0, + 0, 0, 2, 0, 0, 0, + 0, 2, 0, 0, 0, 0, + 0, 0, 16, 2, 0, 0, + 16, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, + 0, 0, 118, 82, 101, 110, + 100, 101, 114, 84, 97, 114, + 103, 101, 116, 79, 102, 102, + 115, 101, 116, 0, 1, 0, + 3, 0, 1, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 102, 76, 97, 121, + 101, 114, 67, 111, 108, 111, + 114, 0, 52, 2, 0, 0, + 0, 0, 0, 0, 64, 0, + 0, 0, 2, 0, 0, 0, + 172, 1, 0, 0, 0, 0, + 0, 0, 109, 80, 114, 111, + 106, 101, 99, 116, 105, 111, + 110, 0, 77, 105, 99, 114, + 111, 115, 111, 102, 116, 32, + 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, + 109, 112, 105, 108, 101, 114, + 32, 57, 46, 50, 57, 46, + 57, 53, 50, 46, 51, 49, + 49, 49, 0, 171, 171, 171, + 73, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 3, 3, 0, 0, 80, 79, + 83, 73, 84, 73, 79, 78, + 0, 171, 171, 171, 79, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 3, 12, + 0, 0, 83, 86, 95, 80, + 111, 115, 105, 116, 105, 111, + 110, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 56, 15, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 84, 4, + 0, 0, 68, 88, 66, 67, + 18, 7, 254, 25, 136, 32, + 226, 82, 202, 102, 47, 221, + 83, 73, 192, 155, 1, 0, + 0, 0, 84, 4, 0, 0, + 6, 0, 0, 0, 56, 0, + 0, 0, 204, 0, 0, 0, + 136, 1, 0, 0, 4, 2, + 0, 0, 200, 3, 0, 0, + 32, 4, 0, 0, 65, 111, + 110, 57, 140, 0, 0, 0, + 140, 0, 0, 0, 0, 2, + 255, 255, 88, 0, 0, 0, + 52, 0, 0, 0, 1, 0, + 40, 0, 0, 0, 52, 0, + 0, 0, 52, 0, 1, 0, + 36, 0, 0, 0, 52, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 2, + 255, 255, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 3, 176, 31, 0, 0, 2, + 0, 0, 0, 144, 0, 8, + 15, 160, 66, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 228, 176, 0, 8, 228, 160, + 5, 0, 0, 3, 0, 0, + 7, 128, 0, 0, 228, 128, + 0, 0, 0, 160, 1, 0, + 0, 2, 0, 0, 8, 128, + 0, 0, 0, 160, 1, 0, + 0, 2, 0, 8, 15, 128, + 0, 0, 228, 128, 255, 255, + 0, 0, 83, 72, 68, 82, + 180, 0, 0, 0, 64, 0, + 0, 0, 45, 0, 0, 0, + 89, 0, 0, 4, 70, 142, + 32, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, + 0, 0, 0, 0, 88, 24, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 85, 85, + 0, 0, 98, 16, 0, 3, + 50, 16, 16, 0, 1, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 69, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 1, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 8, 114, 32, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 6, 128, 32, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 54, 0, 0, 6, 130, 32, + 16, 0, 0, 0, 0, 0, + 10, 128, 32, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, + 4, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 82, 68, 69, 70, + 188, 1, 0, 0, 1, 0, + 0, 0, 164, 0, 0, 0, + 3, 0, 0, 0, 28, 0, + 0, 0, 0, 4, 255, 255, + 0, 1, 0, 0, 136, 1, + 0, 0, 124, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 149, 0, + 0, 0, 2, 0, 0, 0, + 5, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 12, 0, 0, 0, + 154, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 76, 97, 121, 101, + 114, 84, 101, 120, 116, 117, + 114, 101, 83, 97, 109, 112, + 108, 101, 114, 80, 111, 105, + 110, 116, 0, 116, 82, 71, + 66, 0, 80, 101, 114, 76, + 97, 121, 101, 114, 0, 171, + 154, 0, 0, 0, 4, 0, + 0, 0, 188, 0, 0, 0, + 112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 28, 1, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 44, 1, + 0, 0, 0, 0, 0, 0, + 60, 1, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 44, 1, + 0, 0, 0, 0, 0, 0, + 71, 1, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 88, 1, + 0, 0, 0, 0, 0, 0, + 104, 1, 0, 0, 48, 0, + 0, 0, 64, 0, 0, 0, + 0, 0, 0, 0, 120, 1, + 0, 0, 0, 0, 0, 0, + 118, 84, 101, 120, 116, 117, + 114, 101, 67, 111, 111, 114, + 100, 115, 0, 171, 1, 0, + 3, 0, 1, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 118, 76, 97, 121, + 101, 114, 81, 117, 97, 100, + 0, 102, 76, 97, 121, 101, + 114, 79, 112, 97, 99, 105, + 116, 121, 0, 171, 171, 171, + 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 109, 76, + 97, 121, 101, 114, 84, 114, + 97, 110, 115, 102, 111, 114, + 109, 0, 3, 0, 3, 0, + 4, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, + 41, 32, 72, 76, 83, 76, + 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 57, + 46, 50, 57, 46, 57, 53, + 50, 46, 51, 49, 49, 49, + 0, 171, 171, 171, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 3, 3, + 0, 0, 83, 86, 95, 80, + 111, 115, 105, 116, 105, 111, + 110, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 97, 114, + 103, 101, 116, 0, 171, 171, + 84, 22, 0, 0, 0, 0, + 0, 0, 82, 101, 110, 100, + 101, 114, 82, 71, 66, 65, + 76, 97, 121, 101, 114, 80, + 114, 101, 109, 117, 108, 0, + 4, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 255, 255, 255, 255, + 4, 7, 0, 0, 68, 88, + 66, 67, 74, 0, 69, 126, + 158, 251, 122, 220, 157, 162, + 154, 166, 138, 69, 197, 120, + 1, 0, 0, 0, 4, 7, + 0, 0, 6, 0, 0, 0, + 56, 0, 0, 0, 144, 1, + 0, 0, 128, 3, 0, 0, + 252, 3, 0, 0, 120, 6, + 0, 0, 172, 6, 0, 0, + 65, 111, 110, 57, 80, 1, + 0, 0, 80, 1, 0, 0, + 0, 2, 254, 255, 236, 0, + 0, 0, 100, 0, 0, 0, + 5, 0, 36, 0, 0, 0, + 96, 0, 0, 0, 96, 0, + 0, 0, 36, 0, 1, 0, + 96, 0, 0, 0, 0, 0, + 2, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 2, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 6, 0, + 1, 0, 5, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 6, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 2, 254, 255, 31, 0, + 0, 2, 5, 0, 0, 128, + 0, 0, 15, 144, 4, 0, + 0, 4, 0, 0, 3, 224, + 0, 0, 228, 144, 1, 0, + 238, 160, 1, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 3, 128, 0, 0, 228, 144, + 2, 0, 238, 160, 2, 0, + 228, 160, 5, 0, 0, 3, + 1, 0, 15, 128, 0, 0, + 85, 128, 4, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 15, 128, 3, 0, 228, 160, + 0, 0, 0, 128, 1, 0, + 228, 128, 2, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 228, 128, 5, 0, 228, 160, + 2, 0, 0, 3, 0, 0, + 15, 128, 0, 0, 228, 128, + 6, 0, 228, 161, 5, 0, + 0, 3, 1, 0, 15, 128, + 0, 0, 85, 128, 8, 0, + 228, 160, 4, 0, 0, 4, + 1, 0, 15, 128, 7, 0, + 228, 160, 0, 0, 0, 128, + 1, 0, 228, 128, 4, 0, + 0, 4, 1, 0, 15, 128, + 9, 0, 228, 160, 0, 0, + 170, 128, 1, 0, 228, 128, + 4, 0, 0, 4, 0, 0, + 15, 128, 10, 0, 228, 160, + 0, 0, 255, 128, 1, 0, + 228, 128, 4, 0, 0, 4, + 0, 0, 3, 192, 0, 0, + 255, 128, 0, 0, 228, 160, + 0, 0, 228, 128, 1, 0, + 0, 2, 0, 0, 12, 192, + 0, 0, 228, 128, 255, 255, + 0, 0, 83, 72, 68, 82, + 232, 1, 0, 0, 64, 0, + 1, 0, 122, 0, 0, 0, + 89, 0, 0, 4, 70, 142, + 32, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 2, 0, + 0, 0, 4, 0, 0, 0, + 95, 0, 0, 3, 50, 16, + 16, 0, 0, 0, 0, 0, + 103, 0, 0, 4, 242, 32, + 16, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 50, 32, 16, 0, + 1, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, + 50, 0, 0, 11, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 0, 0, + 0, 0, 230, 138, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 70, 128, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 56, 0, 0, 8, + 242, 0, 16, 0, 1, 0, + 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 70, 142, + 32, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 50, 0, + 0, 10, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 142, + 32, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 6, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 1, 0, + 0, 0, 0, 0, 0, 8, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 142, + 32, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, + 70, 142, 32, 128, 65, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 56, 0, + 0, 8, 242, 0, 16, 0, + 1, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, + 70, 142, 32, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 50, 0, 0, 10, 242, 0, + 16, 0, 1, 0, 0, 0, + 70, 142, 32, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 50, 0, + 0, 10, 242, 0, 16, 0, + 1, 0, 0, 0, 70, 142, + 32, 0, 2, 0, 0, 0, + 2, 0, 0, 0, 166, 10, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 10, + 242, 32, 16, 0, 0, 0, + 0, 0, 70, 142, 32, 0, + 2, 0, 0, 0, 3, 0, + 0, 0, 246, 15, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, + 50, 0, 0, 11, 50, 32, + 16, 0, 1, 0, 0, 0, + 70, 16, 16, 0, 0, 0, + 0, 0, 230, 138, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 70, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 11, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 68, + 69, 70, 116, 2, 0, 0, + 3, 0, 0, 0, 168, 0, + 0, 0, 3, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 254, 255, 0, 1, 0, 0, + 64, 2, 0, 0, 124, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 133, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 152, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 80, 101, + 114, 76, 97, 121, 101, 114, + 0, 80, 101, 114, 79, 99, + 99, 97, 115, 105, 111, 110, + 97, 108, 76, 97, 121, 101, + 114, 0, 80, 101, 114, 76, + 97, 121, 101, 114, 77, 97, + 110, 97, 103, 101, 114, 0, + 124, 0, 0, 0, 4, 0, + 0, 0, 240, 0, 0, 0, + 112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 133, 0, 0, 0, 2, 0, + 0, 0, 188, 1, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 152, 0, 0, 0, 1, 0, + 0, 0, 28, 2, 0, 0, + 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 80, 1, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, + 2, 0, 0, 0, 96, 1, + 0, 0, 0, 0, 0, 0, + 112, 1, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, + 2, 0, 0, 0, 96, 1, + 0, 0, 0, 0, 0, 0, + 123, 1, 0, 0, 32, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 140, 1, + 0, 0, 0, 0, 0, 0, + 156, 1, 0, 0, 48, 0, + 0, 0, 64, 0, 0, 0, + 2, 0, 0, 0, 172, 1, + 0, 0, 0, 0, 0, 0, + 118, 84, 101, 120, 116, 117, + 114, 101, 67, 111, 111, 114, + 100, 115, 0, 171, 1, 0, + 3, 0, 1, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 118, 76, 97, 121, + 101, 114, 81, 117, 97, 100, + 0, 102, 76, 97, 121, 101, + 114, 79, 112, 97, 99, 105, + 116, 121, 0, 171, 171, 171, + 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 109, 76, + 97, 121, 101, 114, 84, 114, + 97, 110, 115, 102, 111, 114, + 109, 0, 3, 0, 3, 0, + 4, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 236, 1, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, + 2, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, + 16, 2, 0, 0, 16, 0, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, + 118, 82, 101, 110, 100, 101, + 114, 84, 97, 114, 103, 101, + 116, 79, 102, 102, 115, 101, + 116, 0, 1, 0, 3, 0, + 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 102, 76, 97, 121, 101, 114, + 67, 111, 108, 111, 114, 0, + 52, 2, 0, 0, 0, 0, + 0, 0, 64, 0, 0, 0, + 2, 0, 0, 0, 172, 1, + 0, 0, 0, 0, 0, 0, + 109, 80, 114, 111, 106, 101, + 99, 116, 105, 111, 110, 0, + 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, + 41, 32, 72, 76, 83, 76, + 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 57, + 46, 50, 57, 46, 57, 53, + 50, 46, 51, 49, 49, 49, + 0, 171, 171, 171, 73, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 3, 3, + 0, 0, 80, 79, 83, 73, + 84, 73, 79, 78, 0, 171, + 171, 171, 79, 83, 71, 78, + 80, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 3, 12, 0, 0, + 83, 86, 95, 80, 111, 115, + 105, 116, 105, 111, 110, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 171, 171, 171, + 250, 26, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 48, 4, 0, 0, + 68, 88, 66, 67, 158, 107, + 18, 255, 206, 164, 235, 111, + 119, 9, 247, 201, 106, 179, + 84, 67, 1, 0, 0, 0, + 48, 4, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 192, 0, 0, 0, 100, 1, + 0, 0, 224, 1, 0, 0, + 164, 3, 0, 0, 252, 3, + 0, 0, 65, 111, 110, 57, + 128, 0, 0, 0, 128, 0, + 0, 0, 0, 2, 255, 255, + 76, 0, 0, 0, 52, 0, + 0, 0, 1, 0, 40, 0, + 0, 0, 52, 0, 0, 0, + 52, 0, 1, 0, 36, 0, + 0, 0, 52, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 255, 255, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 3, 176, + 31, 0, 0, 2, 0, 0, + 0, 144, 0, 8, 15, 160, + 66, 0, 0, 3, 0, 0, + 15, 128, 0, 0, 228, 176, + 0, 8, 228, 160, 5, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 228, 128, 0, 0, + 0, 160, 1, 0, 0, 2, + 0, 8, 15, 128, 0, 0, + 228, 128, 255, 255, 0, 0, + 83, 72, 68, 82, 156, 0, + 0, 0, 64, 0, 0, 0, + 39, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 90, 0, 0, 3, + 0, 96, 16, 0, 0, 0, + 0, 0, 88, 24, 0, 4, + 0, 112, 16, 0, 0, 0, + 0, 0, 85, 85, 0, 0, + 98, 16, 0, 3, 50, 16, + 16, 0, 1, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 0, 0, 0, 0, + 104, 0, 0, 2, 1, 0, + 0, 0, 69, 0, 0, 9, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 8, + 242, 32, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 6, 128, + 32, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 82, 68, 69, 70, 188, 1, + 0, 0, 1, 0, 0, 0, + 164, 0, 0, 0, 3, 0, + 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, + 0, 0, 136, 1, 0, 0, + 124, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 150, 0, 0, 0, + 2, 0, 0, 0, 5, 0, + 0, 0, 4, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 1, 0, 0, 0, + 12, 0, 0, 0, 155, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 76, 97, 121, 101, 114, 84, + 101, 120, 116, 117, 114, 101, + 83, 97, 109, 112, 108, 101, + 114, 76, 105, 110, 101, 97, + 114, 0, 116, 82, 71, 66, + 0, 80, 101, 114, 76, 97, + 121, 101, 114, 0, 155, 0, + 0, 0, 4, 0, 0, 0, + 188, 0, 0, 0, 112, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 28, 1, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, + 0, 0, 44, 1, 0, 0, + 0, 0, 0, 0, 60, 1, + 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, + 0, 0, 44, 1, 0, 0, + 0, 0, 0, 0, 71, 1, + 0, 0, 32, 0, 0, 0, + 4, 0, 0, 0, 2, 0, + 0, 0, 88, 1, 0, 0, + 0, 0, 0, 0, 104, 1, + 0, 0, 48, 0, 0, 0, + 64, 0, 0, 0, 0, 0, + 0, 0, 120, 1, 0, 0, + 0, 0, 0, 0, 118, 84, + 101, 120, 116, 117, 114, 101, + 67, 111, 111, 114, 100, 115, + 0, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 118, 76, 97, 121, 101, 114, + 81, 117, 97, 100, 0, 102, + 76, 97, 121, 101, 114, 79, + 112, 97, 99, 105, 116, 121, + 0, 171, 171, 171, 0, 0, + 3, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 109, 76, 97, 121, + 101, 114, 84, 114, 97, 110, + 115, 102, 111, 114, 109, 0, + 3, 0, 3, 0, 4, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 50, + 57, 46, 57, 53, 50, 46, + 51, 49, 49, 49, 0, 171, + 171, 171, 73, 83, 71, 78, + 80, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 3, 3, 0, 0, + 83, 86, 95, 80, 111, 115, + 105, 116, 105, 111, 110, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 171, 171, 171, + 79, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 83, 86, + 95, 84, 97, 114, 103, 101, + 116, 0, 171, 171, 22, 34, + 0, 0, 0, 0, 0, 0, + 82, 101, 110, 100, 101, 114, + 82, 71, 66, 65, 76, 97, + 121, 101, 114, 78, 111, 110, + 80, 114, 101, 109, 117, 108, + 0, 4, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 3, + 0, 0, 0, 255, 255, 255, + 255, 4, 7, 0, 0, 68, + 88, 66, 67, 74, 0, 69, + 126, 158, 251, 122, 220, 157, + 162, 154, 166, 138, 69, 197, + 120, 1, 0, 0, 0, 4, + 7, 0, 0, 6, 0, 0, + 0, 56, 0, 0, 0, 144, + 1, 0, 0, 128, 3, 0, + 0, 252, 3, 0, 0, 120, + 6, 0, 0, 172, 6, 0, + 0, 65, 111, 110, 57, 80, + 1, 0, 0, 80, 1, 0, + 0, 0, 2, 254, 255, 236, + 0, 0, 0, 100, 0, 0, + 0, 5, 0, 36, 0, 0, + 0, 96, 0, 0, 0, 96, + 0, 0, 0, 36, 0, 1, + 0, 96, 0, 0, 0, 0, + 0, 2, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 3, + 0, 2, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 6, + 0, 1, 0, 5, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 1, 0, 6, 0, 0, + 0, 0, 0, 2, 0, 0, + 0, 4, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 2, 254, 255, 31, + 0, 0, 2, 5, 0, 0, + 128, 0, 0, 15, 144, 4, + 0, 0, 4, 0, 0, 3, + 224, 0, 0, 228, 144, 1, + 0, 238, 160, 1, 0, 228, + 160, 4, 0, 0, 4, 0, + 0, 3, 128, 0, 0, 228, + 144, 2, 0, 238, 160, 2, + 0, 228, 160, 5, 0, 0, + 3, 1, 0, 15, 128, 0, + 0, 85, 128, 4, 0, 228, + 160, 4, 0, 0, 4, 0, + 0, 15, 128, 3, 0, 228, + 160, 0, 0, 0, 128, 1, + 0, 228, 128, 2, 0, 0, + 3, 0, 0, 15, 128, 0, + 0, 228, 128, 5, 0, 228, + 160, 2, 0, 0, 3, 0, + 0, 15, 128, 0, 0, 228, + 128, 6, 0, 228, 161, 5, + 0, 0, 3, 1, 0, 15, + 128, 0, 0, 85, 128, 8, + 0, 228, 160, 4, 0, 0, + 4, 1, 0, 15, 128, 7, + 0, 228, 160, 0, 0, 0, + 128, 1, 0, 228, 128, 4, + 0, 0, 4, 1, 0, 15, + 128, 9, 0, 228, 160, 0, + 0, 170, 128, 1, 0, 228, + 128, 4, 0, 0, 4, 0, + 0, 15, 128, 10, 0, 228, + 160, 0, 0, 255, 128, 1, + 0, 228, 128, 4, 0, 0, + 4, 0, 0, 3, 192, 0, + 0, 255, 128, 0, 0, 228, + 160, 0, 0, 228, 128, 1, + 0, 0, 2, 0, 0, 12, + 192, 0, 0, 228, 128, 255, + 255, 0, 0, 83, 72, 68, + 82, 232, 1, 0, 0, 64, + 0, 1, 0, 122, 0, 0, + 0, 89, 0, 0, 4, 70, + 142, 32, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 89, + 0, 0, 4, 70, 142, 32, + 0, 1, 0, 0, 0, 1, + 0, 0, 0, 89, 0, 0, + 4, 70, 142, 32, 0, 2, + 0, 0, 0, 4, 0, 0, + 0, 95, 0, 0, 3, 50, + 16, 16, 0, 0, 0, 0, + 0, 103, 0, 0, 4, 242, + 32, 16, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 101, + 0, 0, 3, 50, 32, 16, + 0, 1, 0, 0, 0, 104, + 0, 0, 2, 2, 0, 0, + 0, 50, 0, 0, 11, 50, + 0, 16, 0, 0, 0, 0, + 0, 70, 16, 16, 0, 0, + 0, 0, 0, 230, 138, 32, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 70, 128, 32, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 56, 0, 0, + 8, 242, 0, 16, 0, 1, + 0, 0, 0, 86, 5, 16, + 0, 0, 0, 0, 0, 70, + 142, 32, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 50, + 0, 0, 10, 242, 0, 16, + 0, 0, 0, 0, 0, 70, + 142, 32, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 1, + 0, 0, 0, 0, 0, 0, + 8, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, + 0, 0, 0, 0, 0, 70, + 142, 32, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, + 0, 0, 9, 242, 0, 16, + 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, + 0, 70, 142, 32, 128, 65, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 56, + 0, 0, 8, 242, 0, 16, + 0, 1, 0, 0, 0, 86, + 5, 16, 0, 0, 0, 0, + 0, 70, 142, 32, 0, 2, + 0, 0, 0, 1, 0, 0, + 0, 50, 0, 0, 10, 242, + 0, 16, 0, 1, 0, 0, + 0, 70, 142, 32, 0, 2, + 0, 0, 0, 0, 0, 0, + 0, 6, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, + 0, 1, 0, 0, 0, 50, + 0, 0, 10, 242, 0, 16, + 0, 1, 0, 0, 0, 70, + 142, 32, 0, 2, 0, 0, + 0, 2, 0, 0, 0, 166, + 10, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 1, + 0, 0, 0, 50, 0, 0, + 10, 242, 32, 16, 0, 0, + 0, 0, 0, 70, 142, 32, + 0, 2, 0, 0, 0, 3, + 0, 0, 0, 246, 15, 16, + 0, 0, 0, 0, 0, 70, + 14, 16, 0, 1, 0, 0, + 0, 50, 0, 0, 11, 50, + 32, 16, 0, 1, 0, 0, + 0, 70, 16, 16, 0, 0, + 0, 0, 0, 230, 138, 32, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 70, 128, 32, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 62, 0, 0, + 1, 83, 84, 65, 84, 116, + 0, 0, 0, 11, 0, 0, + 0, 2, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, + 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 82, + 68, 69, 70, 116, 2, 0, + 0, 3, 0, 0, 0, 168, + 0, 0, 0, 3, 0, 0, + 0, 28, 0, 0, 0, 0, + 4, 254, 255, 0, 1, 0, + 0, 64, 2, 0, 0, 124, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 133, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 152, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 80, + 101, 114, 76, 97, 121, 101, + 114, 0, 80, 101, 114, 79, + 99, 99, 97, 115, 105, 111, + 110, 97, 108, 76, 97, 121, + 101, 114, 0, 80, 101, 114, + 76, 97, 121, 101, 114, 77, + 97, 110, 97, 103, 101, 114, + 0, 124, 0, 0, 0, 4, + 0, 0, 0, 240, 0, 0, + 0, 112, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 133, 0, 0, 0, 2, + 0, 0, 0, 188, 1, 0, + 0, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 152, 0, 0, 0, 1, + 0, 0, 0, 28, 2, 0, + 0, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 80, 1, 0, 0, 0, + 0, 0, 0, 16, 0, 0, + 0, 2, 0, 0, 0, 96, + 1, 0, 0, 0, 0, 0, + 0, 112, 1, 0, 0, 16, + 0, 0, 0, 16, 0, 0, + 0, 2, 0, 0, 0, 96, + 1, 0, 0, 0, 0, 0, + 0, 123, 1, 0, 0, 32, + 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 140, + 1, 0, 0, 0, 0, 0, + 0, 156, 1, 0, 0, 48, + 0, 0, 0, 64, 0, 0, + 0, 2, 0, 0, 0, 172, + 1, 0, 0, 0, 0, 0, + 0, 118, 84, 101, 120, 116, + 117, 114, 101, 67, 111, 111, + 114, 100, 115, 0, 171, 1, + 0, 3, 0, 1, 0, 4, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 118, 76, 97, + 121, 101, 114, 81, 117, 97, + 100, 0, 102, 76, 97, 121, + 101, 114, 79, 112, 97, 99, + 105, 116, 121, 0, 171, 171, + 171, 0, 0, 3, 0, 1, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 109, + 76, 97, 121, 101, 114, 84, + 114, 97, 110, 115, 102, 111, + 114, 109, 0, 3, 0, 3, + 0, 4, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 236, 1, 0, 0, 0, + 0, 0, 0, 16, 0, 0, + 0, 2, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 16, 2, 0, 0, 16, + 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 118, 82, 101, 110, 100, + 101, 114, 84, 97, 114, 103, + 101, 116, 79, 102, 102, 115, + 101, 116, 0, 1, 0, 3, + 0, 1, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 102, 76, 97, 121, 101, + 114, 67, 111, 108, 111, 114, + 0, 52, 2, 0, 0, 0, + 0, 0, 0, 64, 0, 0, + 0, 2, 0, 0, 0, 172, + 1, 0, 0, 0, 0, 0, + 0, 109, 80, 114, 111, 106, + 101, 99, 116, 105, 111, 110, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 50, 57, 46, 57, + 53, 50, 46, 51, 49, 49, + 49, 0, 171, 171, 171, 73, + 83, 71, 78, 44, 0, 0, + 0, 1, 0, 0, 0, 8, + 0, 0, 0, 32, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 3, + 3, 0, 0, 80, 79, 83, + 73, 84, 73, 79, 78, 0, + 171, 171, 171, 79, 83, 71, + 78, 80, 0, 0, 0, 2, + 0, 0, 0, 8, 0, 0, + 0, 56, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 3, 0, 0, 0, 0, + 0, 0, 0, 15, 0, 0, + 0, 68, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, + 0, 0, 0, 3, 12, 0, + 0, 83, 86, 95, 80, 111, + 115, 105, 116, 105, 111, 110, + 0, 84, 69, 88, 67, 79, + 79, 82, 68, 0, 171, 171, + 171, 155, 38, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 2, 0, 0, 0, 0, + 0, 0, 0, 48, 4, 0, + 0, 68, 88, 66, 67, 158, + 107, 18, 255, 206, 164, 235, + 111, 119, 9, 247, 201, 106, + 179, 84, 67, 1, 0, 0, + 0, 48, 4, 0, 0, 6, + 0, 0, 0, 56, 0, 0, + 0, 192, 0, 0, 0, 100, + 1, 0, 0, 224, 1, 0, + 0, 164, 3, 0, 0, 252, + 3, 0, 0, 65, 111, 110, + 57, 128, 0, 0, 0, 128, + 0, 0, 0, 0, 2, 255, + 255, 76, 0, 0, 0, 52, + 0, 0, 0, 1, 0, 40, + 0, 0, 0, 52, 0, 0, + 0, 52, 0, 1, 0, 36, + 0, 0, 0, 52, 0, 0, + 0, 0, 0, 0, 0, 2, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 255, + 255, 31, 0, 0, 2, 0, + 0, 0, 128, 0, 0, 3, + 176, 31, 0, 0, 2, 0, + 0, 0, 144, 0, 8, 15, + 160, 66, 0, 0, 3, 0, + 0, 15, 128, 0, 0, 228, + 176, 0, 8, 228, 160, 5, + 0, 0, 3, 0, 0, 15, + 128, 0, 0, 228, 128, 0, + 0, 0, 160, 1, 0, 0, + 2, 0, 8, 15, 128, 0, + 0, 228, 128, 255, 255, 0, + 0, 83, 72, 68, 82, 156, + 0, 0, 0, 64, 0, 0, + 0, 39, 0, 0, 0, 89, + 0, 0, 4, 70, 142, 32, + 0, 0, 0, 0, 0, 3, + 0, 0, 0, 90, 0, 0, + 3, 0, 96, 16, 0, 0, + 0, 0, 0, 88, 24, 0, + 4, 0, 112, 16, 0, 0, + 0, 0, 0, 85, 85, 0, + 0, 98, 16, 0, 3, 50, + 16, 16, 0, 1, 0, 0, + 0, 101, 0, 0, 3, 242, + 32, 16, 0, 0, 0, 0, + 0, 104, 0, 0, 2, 1, + 0, 0, 0, 69, 0, 0, + 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, + 0, 1, 0, 0, 0, 70, + 126, 16, 0, 0, 0, 0, + 0, 0, 96, 16, 0, 0, + 0, 0, 0, 56, 0, 0, + 8, 242, 32, 16, 0, 0, + 0, 0, 0, 70, 14, 16, + 0, 0, 0, 0, 0, 6, + 128, 32, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 3, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 2, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 82, 68, 69, 70, 188, + 1, 0, 0, 1, 0, 0, + 0, 164, 0, 0, 0, 3, + 0, 0, 0, 28, 0, 0, + 0, 0, 4, 255, 255, 0, + 1, 0, 0, 136, 1, 0, + 0, 124, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 150, 0, 0, + 0, 2, 0, 0, 0, 5, + 0, 0, 0, 4, 0, 0, + 0, 255, 255, 255, 255, 0, + 0, 0, 0, 1, 0, 0, + 0, 12, 0, 0, 0, 155, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 76, 97, 121, 101, 114, + 84, 101, 120, 116, 117, 114, + 101, 83, 97, 109, 112, 108, + 101, 114, 76, 105, 110, 101, + 97, 114, 0, 116, 82, 71, + 66, 0, 80, 101, 114, 76, + 97, 121, 101, 114, 0, 155, + 0, 0, 0, 4, 0, 0, + 0, 188, 0, 0, 0, 112, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 28, + 1, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 0, + 0, 0, 0, 44, 1, 0, + 0, 0, 0, 0, 0, 60, + 1, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, + 0, 0, 0, 44, 1, 0, + 0, 0, 0, 0, 0, 71, + 1, 0, 0, 32, 0, 0, + 0, 4, 0, 0, 0, 2, + 0, 0, 0, 88, 1, 0, + 0, 0, 0, 0, 0, 104, + 1, 0, 0, 48, 0, 0, + 0, 64, 0, 0, 0, 0, + 0, 0, 0, 120, 1, 0, + 0, 0, 0, 0, 0, 118, + 84, 101, 120, 116, 117, 114, + 101, 67, 111, 111, 114, 100, + 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 118, 76, 97, 121, 101, + 114, 81, 117, 97, 100, 0, + 102, 76, 97, 121, 101, 114, + 79, 112, 97, 99, 105, 116, + 121, 0, 171, 171, 171, 0, + 0, 3, 0, 1, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 109, 76, 97, + 121, 101, 114, 84, 114, 97, + 110, 115, 102, 111, 114, 109, + 0, 3, 0, 3, 0, 4, + 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 77, + 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, + 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, + 108, 101, 114, 32, 57, 46, + 50, 57, 46, 57, 53, 50, + 46, 51, 49, 49, 49, 0, + 171, 171, 171, 73, 83, 71, + 78, 80, 0, 0, 0, 2, + 0, 0, 0, 8, 0, 0, + 0, 56, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 3, 0, 0, 0, 0, + 0, 0, 0, 15, 0, 0, + 0, 68, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, + 0, 0, 0, 3, 3, 0, + 0, 83, 86, 95, 80, 111, + 115, 105, 116, 105, 111, 110, + 0, 84, 69, 88, 67, 79, + 79, 82, 68, 0, 171, 171, + 171, 79, 83, 71, 78, 44, + 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, + 0, 15, 0, 0, 0, 83, + 86, 95, 84, 97, 114, 103, + 101, 116, 0, 171, 171, 183, + 45, 0, 0, 0, 0, 0, + 0, 82, 101, 110, 100, 101, + 114, 82, 71, 66, 65, 76, + 97, 121, 101, 114, 80, 114, + 101, 109, 117, 108, 80, 111, + 105, 110, 116, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 255, 255, 255, 255, 4, 7, + 0, 0, 68, 88, 66, 67, + 74, 0, 69, 126, 158, 251, + 122, 220, 157, 162, 154, 166, + 138, 69, 197, 120, 1, 0, + 0, 0, 4, 7, 0, 0, + 6, 0, 0, 0, 56, 0, + 0, 0, 144, 1, 0, 0, + 128, 3, 0, 0, 252, 3, + 0, 0, 120, 6, 0, 0, + 172, 6, 0, 0, 65, 111, + 110, 57, 80, 1, 0, 0, + 80, 1, 0, 0, 0, 2, + 254, 255, 236, 0, 0, 0, + 100, 0, 0, 0, 5, 0, + 36, 0, 0, 0, 96, 0, + 0, 0, 96, 0, 0, 0, + 36, 0, 1, 0, 96, 0, + 0, 0, 0, 0, 2, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 2, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 1, 0, + 5, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 6, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 4, 0, + 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, + 254, 255, 31, 0, 0, 2, + 5, 0, 0, 128, 0, 0, + 15, 144, 4, 0, 0, 4, + 0, 0, 3, 224, 0, 0, + 228, 144, 1, 0, 238, 160, + 1, 0, 228, 160, 4, 0, + 0, 4, 0, 0, 3, 128, + 0, 0, 228, 144, 2, 0, + 238, 160, 2, 0, 228, 160, + 5, 0, 0, 3, 1, 0, + 15, 128, 0, 0, 85, 128, + 4, 0, 228, 160, 4, 0, + 0, 4, 0, 0, 15, 128, + 3, 0, 228, 160, 0, 0, + 0, 128, 1, 0, 228, 128, + 2, 0, 0, 3, 0, 0, + 15, 128, 0, 0, 228, 128, + 5, 0, 228, 160, 2, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 228, 128, 6, 0, + 228, 161, 5, 0, 0, 3, + 1, 0, 15, 128, 0, 0, + 85, 128, 8, 0, 228, 160, + 4, 0, 0, 4, 1, 0, + 15, 128, 7, 0, 228, 160, + 0, 0, 0, 128, 1, 0, + 228, 128, 4, 0, 0, 4, + 1, 0, 15, 128, 9, 0, + 228, 160, 0, 0, 170, 128, + 1, 0, 228, 128, 4, 0, + 0, 4, 0, 0, 15, 128, + 10, 0, 228, 160, 0, 0, + 255, 128, 1, 0, 228, 128, + 4, 0, 0, 4, 0, 0, + 3, 192, 0, 0, 255, 128, + 0, 0, 228, 160, 0, 0, + 228, 128, 1, 0, 0, 2, + 0, 0, 12, 192, 0, 0, + 228, 128, 255, 255, 0, 0, + 83, 72, 68, 82, 232, 1, + 0, 0, 64, 0, 1, 0, + 122, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 7, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 89, 0, 0, 4, 70, 142, + 32, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 95, 0, + 0, 3, 50, 16, 16, 0, + 0, 0, 0, 0, 103, 0, + 0, 4, 242, 32, 16, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 101, 0, 0, 3, + 50, 32, 16, 0, 1, 0, + 0, 0, 104, 0, 0, 2, + 2, 0, 0, 0, 50, 0, + 0, 11, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 0, 0, 0, 0, + 230, 138, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 70, 128, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 56, 0, 0, 8, 242, 0, + 16, 0, 1, 0, 0, 0, + 86, 5, 16, 0, 0, 0, + 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 50, 0, 0, 10, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, + 0, 0, 0, 8, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 9, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 142, + 32, 128, 65, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 56, 0, 0, 8, + 242, 0, 16, 0, 1, 0, + 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 70, 142, + 32, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 50, 0, + 0, 10, 242, 0, 16, 0, + 1, 0, 0, 0, 70, 142, + 32, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 6, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 10, + 242, 0, 16, 0, 1, 0, + 0, 0, 70, 142, 32, 0, + 2, 0, 0, 0, 2, 0, + 0, 0, 166, 10, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, + 50, 0, 0, 10, 242, 32, + 16, 0, 0, 0, 0, 0, + 70, 142, 32, 0, 2, 0, + 0, 0, 3, 0, 0, 0, + 246, 15, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 50, 0, + 0, 11, 50, 32, 16, 0, + 1, 0, 0, 0, 70, 16, + 16, 0, 0, 0, 0, 0, + 230, 138, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 70, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, + 11, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 82, 68, 69, 70, + 116, 2, 0, 0, 3, 0, + 0, 0, 168, 0, 0, 0, + 3, 0, 0, 0, 28, 0, + 0, 0, 0, 4, 254, 255, + 0, 1, 0, 0, 64, 2, + 0, 0, 124, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 133, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 152, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 80, 101, 114, 76, + 97, 121, 101, 114, 0, 80, + 101, 114, 79, 99, 99, 97, + 115, 105, 111, 110, 97, 108, + 76, 97, 121, 101, 114, 0, + 80, 101, 114, 76, 97, 121, + 101, 114, 77, 97, 110, 97, + 103, 101, 114, 0, 124, 0, + 0, 0, 4, 0, 0, 0, + 240, 0, 0, 0, 112, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 133, 0, + 0, 0, 2, 0, 0, 0, + 188, 1, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 0, + 0, 0, 1, 0, 0, 0, + 28, 2, 0, 0, 64, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 1, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 2, 0, + 0, 0, 96, 1, 0, 0, + 0, 0, 0, 0, 112, 1, + 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 2, 0, + 0, 0, 96, 1, 0, 0, + 0, 0, 0, 0, 123, 1, + 0, 0, 32, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 140, 1, 0, 0, + 0, 0, 0, 0, 156, 1, + 0, 0, 48, 0, 0, 0, + 64, 0, 0, 0, 2, 0, + 0, 0, 172, 1, 0, 0, + 0, 0, 0, 0, 118, 84, + 101, 120, 116, 117, 114, 101, + 67, 111, 111, 114, 100, 115, + 0, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 118, 76, 97, 121, 101, 114, + 81, 117, 97, 100, 0, 102, + 76, 97, 121, 101, 114, 79, + 112, 97, 99, 105, 116, 121, + 0, 171, 171, 171, 0, 0, + 3, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 109, 76, 97, 121, + 101, 114, 84, 114, 97, 110, + 115, 102, 111, 114, 109, 0, + 3, 0, 3, 0, 4, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 236, 1, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 2, 0, + 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 16, 2, + 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 118, 82, + 101, 110, 100, 101, 114, 84, + 97, 114, 103, 101, 116, 79, + 102, 102, 115, 101, 116, 0, + 1, 0, 3, 0, 1, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 102, 76, + 97, 121, 101, 114, 67, 111, + 108, 111, 114, 0, 52, 2, + 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 2, 0, + 0, 0, 172, 1, 0, 0, + 0, 0, 0, 0, 109, 80, + 114, 111, 106, 101, 99, 116, + 105, 111, 110, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 50, + 57, 46, 57, 53, 50, 46, + 51, 49, 49, 49, 0, 171, + 171, 171, 73, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 3, 3, 0, 0, + 80, 79, 83, 73, 84, 73, + 79, 78, 0, 171, 171, 171, + 79, 83, 71, 78, 80, 0, + 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 68, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 3, 12, 0, 0, 83, 86, + 95, 80, 111, 115, 105, 116, + 105, 111, 110, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 171, 171, 62, 50, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 48, 4, 0, 0, 68, 88, + 66, 67, 61, 89, 104, 203, + 112, 15, 192, 7, 21, 99, + 104, 101, 1, 140, 240, 252, + 1, 0, 0, 0, 48, 4, + 0, 0, 6, 0, 0, 0, + 56, 0, 0, 0, 192, 0, + 0, 0, 100, 1, 0, 0, + 224, 1, 0, 0, 164, 3, + 0, 0, 252, 3, 0, 0, + 65, 111, 110, 57, 128, 0, + 0, 0, 128, 0, 0, 0, + 0, 2, 255, 255, 76, 0, + 0, 0, 52, 0, 0, 0, + 1, 0, 40, 0, 0, 0, + 52, 0, 0, 0, 52, 0, + 1, 0, 36, 0, 0, 0, + 52, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 1, 2, 255, 255, 31, 0, + 0, 2, 0, 0, 0, 128, + 0, 0, 3, 176, 31, 0, + 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 228, 176, 0, 8, + 228, 160, 5, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 228, 128, 0, 0, 0, 160, + 1, 0, 0, 2, 0, 8, + 15, 128, 0, 0, 228, 128, + 255, 255, 0, 0, 83, 72, + 68, 82, 156, 0, 0, 0, + 64, 0, 0, 0, 39, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 90, 0, 0, 3, 0, 96, + 16, 0, 0, 0, 0, 0, + 88, 24, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 85, 85, 0, 0, 98, 16, + 0, 3, 50, 16, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 69, 0, 0, 9, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 1, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 8, 242, 32, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 6, 128, 32, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 68, + 69, 70, 188, 1, 0, 0, + 1, 0, 0, 0, 164, 0, + 0, 0, 3, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 136, 1, 0, 0, 124, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 149, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 4, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 12, 0, + 0, 0, 154, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 76, 97, + 121, 101, 114, 84, 101, 120, + 116, 117, 114, 101, 83, 97, + 109, 112, 108, 101, 114, 80, + 111, 105, 110, 116, 0, 116, + 82, 71, 66, 0, 80, 101, + 114, 76, 97, 121, 101, 114, + 0, 171, 154, 0, 0, 0, + 4, 0, 0, 0, 188, 0, + 0, 0, 112, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 28, 1, 0, 0, + 0, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, + 44, 1, 0, 0, 0, 0, + 0, 0, 60, 1, 0, 0, + 16, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, + 44, 1, 0, 0, 0, 0, + 0, 0, 71, 1, 0, 0, + 32, 0, 0, 0, 4, 0, + 0, 0, 2, 0, 0, 0, + 88, 1, 0, 0, 0, 0, + 0, 0, 104, 1, 0, 0, + 48, 0, 0, 0, 64, 0, + 0, 0, 0, 0, 0, 0, + 120, 1, 0, 0, 0, 0, + 0, 0, 118, 84, 101, 120, + 116, 117, 114, 101, 67, 111, + 111, 114, 100, 115, 0, 171, + 1, 0, 3, 0, 1, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 118, 76, + 97, 121, 101, 114, 81, 117, + 97, 100, 0, 102, 76, 97, + 121, 101, 114, 79, 112, 97, + 99, 105, 116, 121, 0, 171, + 171, 171, 0, 0, 3, 0, + 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 109, 76, 97, 121, 101, 114, + 84, 114, 97, 110, 115, 102, + 111, 114, 109, 0, 3, 0, + 3, 0, 4, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 77, 105, 99, 114, + 111, 115, 111, 102, 116, 32, + 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, + 109, 112, 105, 108, 101, 114, + 32, 57, 46, 50, 57, 46, + 57, 53, 50, 46, 51, 49, + 49, 49, 0, 171, 171, 171, + 73, 83, 71, 78, 80, 0, + 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 68, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 3, 3, 0, 0, 83, 86, + 95, 80, 111, 115, 105, 116, + 105, 111, 110, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 171, 171, 79, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 84, + 97, 114, 103, 101, 116, 0, + 171, 171, 90, 57, 0, 0, + 0, 0, 0, 0, 82, 101, + 110, 100, 101, 114, 82, 71, + 66, 65, 76, 97, 121, 101, + 114, 78, 111, 110, 80, 114, + 101, 109, 117, 108, 80, 111, + 105, 110, 116, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 255, 255, 255, 255, 4, 7, + 0, 0, 68, 88, 66, 67, + 74, 0, 69, 126, 158, 251, + 122, 220, 157, 162, 154, 166, + 138, 69, 197, 120, 1, 0, + 0, 0, 4, 7, 0, 0, + 6, 0, 0, 0, 56, 0, + 0, 0, 144, 1, 0, 0, + 128, 3, 0, 0, 252, 3, + 0, 0, 120, 6, 0, 0, + 172, 6, 0, 0, 65, 111, + 110, 57, 80, 1, 0, 0, + 80, 1, 0, 0, 0, 2, + 254, 255, 236, 0, 0, 0, + 100, 0, 0, 0, 5, 0, + 36, 0, 0, 0, 96, 0, + 0, 0, 96, 0, 0, 0, + 36, 0, 1, 0, 96, 0, + 0, 0, 0, 0, 2, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 2, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 1, 0, + 5, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 6, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 4, 0, + 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, + 254, 255, 31, 0, 0, 2, + 5, 0, 0, 128, 0, 0, + 15, 144, 4, 0, 0, 4, + 0, 0, 3, 224, 0, 0, + 228, 144, 1, 0, 238, 160, + 1, 0, 228, 160, 4, 0, + 0, 4, 0, 0, 3, 128, + 0, 0, 228, 144, 2, 0, + 238, 160, 2, 0, 228, 160, + 5, 0, 0, 3, 1, 0, + 15, 128, 0, 0, 85, 128, + 4, 0, 228, 160, 4, 0, + 0, 4, 0, 0, 15, 128, + 3, 0, 228, 160, 0, 0, + 0, 128, 1, 0, 228, 128, + 2, 0, 0, 3, 0, 0, + 15, 128, 0, 0, 228, 128, + 5, 0, 228, 160, 2, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 228, 128, 6, 0, + 228, 161, 5, 0, 0, 3, + 1, 0, 15, 128, 0, 0, + 85, 128, 8, 0, 228, 160, + 4, 0, 0, 4, 1, 0, + 15, 128, 7, 0, 228, 160, + 0, 0, 0, 128, 1, 0, + 228, 128, 4, 0, 0, 4, + 1, 0, 15, 128, 9, 0, + 228, 160, 0, 0, 170, 128, + 1, 0, 228, 128, 4, 0, + 0, 4, 0, 0, 15, 128, + 10, 0, 228, 160, 0, 0, + 255, 128, 1, 0, 228, 128, + 4, 0, 0, 4, 0, 0, + 3, 192, 0, 0, 255, 128, + 0, 0, 228, 160, 0, 0, + 228, 128, 1, 0, 0, 2, + 0, 0, 12, 192, 0, 0, + 228, 128, 255, 255, 0, 0, + 83, 72, 68, 82, 232, 1, + 0, 0, 64, 0, 1, 0, + 122, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 7, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 89, 0, 0, 4, 70, 142, + 32, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 95, 0, + 0, 3, 50, 16, 16, 0, + 0, 0, 0, 0, 103, 0, + 0, 4, 242, 32, 16, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 101, 0, 0, 3, + 50, 32, 16, 0, 1, 0, + 0, 0, 104, 0, 0, 2, + 2, 0, 0, 0, 50, 0, + 0, 11, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 0, 0, 0, 0, + 230, 138, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 70, 128, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 56, 0, 0, 8, 242, 0, + 16, 0, 1, 0, 0, 0, + 86, 5, 16, 0, 0, 0, + 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 50, 0, 0, 10, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, + 0, 0, 0, 8, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 9, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 142, + 32, 128, 65, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 56, 0, 0, 8, + 242, 0, 16, 0, 1, 0, + 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 70, 142, + 32, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 50, 0, + 0, 10, 242, 0, 16, 0, + 1, 0, 0, 0, 70, 142, + 32, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 6, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 10, + 242, 0, 16, 0, 1, 0, + 0, 0, 70, 142, 32, 0, + 2, 0, 0, 0, 2, 0, + 0, 0, 166, 10, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, + 50, 0, 0, 10, 242, 32, + 16, 0, 0, 0, 0, 0, + 70, 142, 32, 0, 2, 0, + 0, 0, 3, 0, 0, 0, + 246, 15, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 50, 0, + 0, 11, 50, 32, 16, 0, + 1, 0, 0, 0, 70, 16, + 16, 0, 0, 0, 0, 0, + 230, 138, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 70, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, + 11, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 82, 68, 69, 70, + 116, 2, 0, 0, 3, 0, + 0, 0, 168, 0, 0, 0, + 3, 0, 0, 0, 28, 0, + 0, 0, 0, 4, 254, 255, + 0, 1, 0, 0, 64, 2, + 0, 0, 124, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 133, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 152, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 80, 101, 114, 76, + 97, 121, 101, 114, 0, 80, + 101, 114, 79, 99, 99, 97, + 115, 105, 111, 110, 97, 108, + 76, 97, 121, 101, 114, 0, + 80, 101, 114, 76, 97, 121, + 101, 114, 77, 97, 110, 97, + 103, 101, 114, 0, 124, 0, + 0, 0, 4, 0, 0, 0, + 240, 0, 0, 0, 112, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 133, 0, + 0, 0, 2, 0, 0, 0, + 188, 1, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 152, 0, + 0, 0, 1, 0, 0, 0, + 28, 2, 0, 0, 64, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 1, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 2, 0, + 0, 0, 96, 1, 0, 0, + 0, 0, 0, 0, 112, 1, + 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 2, 0, + 0, 0, 96, 1, 0, 0, + 0, 0, 0, 0, 123, 1, + 0, 0, 32, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 140, 1, 0, 0, + 0, 0, 0, 0, 156, 1, + 0, 0, 48, 0, 0, 0, + 64, 0, 0, 0, 2, 0, + 0, 0, 172, 1, 0, 0, + 0, 0, 0, 0, 118, 84, + 101, 120, 116, 117, 114, 101, + 67, 111, 111, 114, 100, 115, + 0, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 118, 76, 97, 121, 101, 114, + 81, 117, 97, 100, 0, 102, + 76, 97, 121, 101, 114, 79, + 112, 97, 99, 105, 116, 121, + 0, 171, 171, 171, 0, 0, + 3, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 109, 76, 97, 121, + 101, 114, 84, 114, 97, 110, + 115, 102, 111, 114, 109, 0, + 3, 0, 3, 0, 4, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 236, 1, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 2, 0, + 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 16, 2, + 0, 0, 16, 0, 0, 0, + 16, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 118, 82, + 101, 110, 100, 101, 114, 84, + 97, 114, 103, 101, 116, 79, + 102, 102, 115, 101, 116, 0, + 1, 0, 3, 0, 1, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 102, 76, + 97, 121, 101, 114, 67, 111, + 108, 111, 114, 0, 52, 2, + 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 2, 0, + 0, 0, 172, 1, 0, 0, + 0, 0, 0, 0, 109, 80, + 114, 111, 106, 101, 99, 116, + 105, 111, 110, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 50, + 57, 46, 57, 53, 50, 46, + 51, 49, 49, 49, 0, 171, + 171, 171, 73, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 3, 3, 0, 0, + 80, 79, 83, 73, 84, 73, + 79, 78, 0, 171, 171, 171, + 79, 83, 71, 78, 80, 0, + 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 68, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 3, 12, 0, 0, 83, 86, + 95, 80, 111, 115, 105, 116, + 105, 111, 110, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 171, 171, 228, 61, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 48, 4, 0, 0, 68, 88, + 66, 67, 61, 89, 104, 203, + 112, 15, 192, 7, 21, 99, + 104, 101, 1, 140, 240, 252, + 1, 0, 0, 0, 48, 4, + 0, 0, 6, 0, 0, 0, + 56, 0, 0, 0, 192, 0, + 0, 0, 100, 1, 0, 0, + 224, 1, 0, 0, 164, 3, + 0, 0, 252, 3, 0, 0, + 65, 111, 110, 57, 128, 0, + 0, 0, 128, 0, 0, 0, + 0, 2, 255, 255, 76, 0, + 0, 0, 52, 0, 0, 0, + 1, 0, 40, 0, 0, 0, + 52, 0, 0, 0, 52, 0, + 1, 0, 36, 0, 0, 0, + 52, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 1, 2, 255, 255, 31, 0, + 0, 2, 0, 0, 0, 128, + 0, 0, 3, 176, 31, 0, + 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 228, 176, 0, 8, + 228, 160, 5, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 228, 128, 0, 0, 0, 160, + 1, 0, 0, 2, 0, 8, + 15, 128, 0, 0, 228, 128, + 255, 255, 0, 0, 83, 72, + 68, 82, 156, 0, 0, 0, + 64, 0, 0, 0, 39, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 90, 0, 0, 3, 0, 96, + 16, 0, 0, 0, 0, 0, + 88, 24, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 85, 85, 0, 0, 98, 16, + 0, 3, 50, 16, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 69, 0, 0, 9, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 1, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 8, 242, 32, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 6, 128, 32, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 68, + 69, 70, 188, 1, 0, 0, + 1, 0, 0, 0, 164, 0, + 0, 0, 3, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 136, 1, 0, 0, 124, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 149, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 4, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 12, 0, + 0, 0, 154, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 76, 97, + 121, 101, 114, 84, 101, 120, + 116, 117, 114, 101, 83, 97, + 109, 112, 108, 101, 114, 80, + 111, 105, 110, 116, 0, 116, + 82, 71, 66, 0, 80, 101, + 114, 76, 97, 121, 101, 114, + 0, 171, 154, 0, 0, 0, + 4, 0, 0, 0, 188, 0, + 0, 0, 112, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 28, 1, 0, 0, + 0, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, + 44, 1, 0, 0, 0, 0, + 0, 0, 60, 1, 0, 0, + 16, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, + 44, 1, 0, 0, 0, 0, + 0, 0, 71, 1, 0, 0, + 32, 0, 0, 0, 4, 0, + 0, 0, 2, 0, 0, 0, + 88, 1, 0, 0, 0, 0, + 0, 0, 104, 1, 0, 0, + 48, 0, 0, 0, 64, 0, + 0, 0, 0, 0, 0, 0, + 120, 1, 0, 0, 0, 0, + 0, 0, 118, 84, 101, 120, + 116, 117, 114, 101, 67, 111, + 111, 114, 100, 115, 0, 171, + 1, 0, 3, 0, 1, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 118, 76, + 97, 121, 101, 114, 81, 117, + 97, 100, 0, 102, 76, 97, + 121, 101, 114, 79, 112, 97, + 99, 105, 116, 121, 0, 171, + 171, 171, 0, 0, 3, 0, + 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 109, 76, 97, 121, 101, 114, + 84, 114, 97, 110, 115, 102, + 111, 114, 109, 0, 3, 0, + 3, 0, 4, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 77, 105, 99, 114, + 111, 115, 111, 102, 116, 32, + 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, + 109, 112, 105, 108, 101, 114, + 32, 57, 46, 50, 57, 46, + 57, 53, 50, 46, 51, 49, + 49, 49, 0, 171, 171, 171, + 73, 83, 71, 78, 80, 0, + 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 68, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 3, 3, 0, 0, 83, 86, + 95, 80, 111, 115, 105, 116, + 105, 111, 110, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 171, 171, 79, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 84, + 97, 114, 103, 101, 116, 0, + 171, 171, 0, 69, 0, 0, + 0, 0, 0, 0, 82, 101, + 110, 100, 101, 114, 89, 67, + 98, 67, 114, 76, 97, 121, + 101, 114, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 3, 0, 0, 0, 255, + 255, 255, 255, 4, 7, 0, + 0, 68, 88, 66, 67, 74, + 0, 69, 126, 158, 251, 122, + 220, 157, 162, 154, 166, 138, + 69, 197, 120, 1, 0, 0, + 0, 4, 7, 0, 0, 6, + 0, 0, 0, 56, 0, 0, + 0, 144, 1, 0, 0, 128, + 3, 0, 0, 252, 3, 0, + 0, 120, 6, 0, 0, 172, + 6, 0, 0, 65, 111, 110, + 57, 80, 1, 0, 0, 80, + 1, 0, 0, 0, 2, 254, + 255, 236, 0, 0, 0, 100, + 0, 0, 0, 5, 0, 36, + 0, 0, 0, 96, 0, 0, + 0, 96, 0, 0, 0, 36, + 0, 1, 0, 96, 0, 0, + 0, 0, 0, 2, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 3, 0, 2, 0, 3, + 0, 0, 0, 0, 0, 0, + 0, 6, 0, 1, 0, 5, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 6, + 0, 0, 0, 0, 0, 2, + 0, 0, 0, 4, 0, 7, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 254, + 255, 31, 0, 0, 2, 5, + 0, 0, 128, 0, 0, 15, + 144, 4, 0, 0, 4, 0, + 0, 3, 224, 0, 0, 228, + 144, 1, 0, 238, 160, 1, + 0, 228, 160, 4, 0, 0, + 4, 0, 0, 3, 128, 0, + 0, 228, 144, 2, 0, 238, + 160, 2, 0, 228, 160, 5, + 0, 0, 3, 1, 0, 15, + 128, 0, 0, 85, 128, 4, + 0, 228, 160, 4, 0, 0, + 4, 0, 0, 15, 128, 3, + 0, 228, 160, 0, 0, 0, + 128, 1, 0, 228, 128, 2, + 0, 0, 3, 0, 0, 15, + 128, 0, 0, 228, 128, 5, + 0, 228, 160, 2, 0, 0, + 3, 0, 0, 15, 128, 0, + 0, 228, 128, 6, 0, 228, + 161, 5, 0, 0, 3, 1, + 0, 15, 128, 0, 0, 85, + 128, 8, 0, 228, 160, 4, + 0, 0, 4, 1, 0, 15, + 128, 7, 0, 228, 160, 0, + 0, 0, 128, 1, 0, 228, + 128, 4, 0, 0, 4, 1, + 0, 15, 128, 9, 0, 228, + 160, 0, 0, 170, 128, 1, + 0, 228, 128, 4, 0, 0, + 4, 0, 0, 15, 128, 10, + 0, 228, 160, 0, 0, 255, + 128, 1, 0, 228, 128, 4, + 0, 0, 4, 0, 0, 3, + 192, 0, 0, 255, 128, 0, + 0, 228, 160, 0, 0, 228, + 128, 1, 0, 0, 2, 0, + 0, 12, 192, 0, 0, 228, + 128, 255, 255, 0, 0, 83, + 72, 68, 82, 232, 1, 0, + 0, 64, 0, 1, 0, 122, + 0, 0, 0, 89, 0, 0, + 4, 70, 142, 32, 0, 0, + 0, 0, 0, 7, 0, 0, + 0, 89, 0, 0, 4, 70, + 142, 32, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 89, + 0, 0, 4, 70, 142, 32, + 0, 2, 0, 0, 0, 4, + 0, 0, 0, 95, 0, 0, + 3, 50, 16, 16, 0, 0, + 0, 0, 0, 103, 0, 0, + 4, 242, 32, 16, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 101, 0, 0, 3, 50, + 32, 16, 0, 1, 0, 0, + 0, 104, 0, 0, 2, 2, + 0, 0, 0, 50, 0, 0, + 11, 50, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, + 0, 0, 0, 0, 0, 230, + 138, 32, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 70, + 128, 32, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 56, + 0, 0, 8, 242, 0, 16, + 0, 1, 0, 0, 0, 86, + 5, 16, 0, 0, 0, 0, + 0, 70, 142, 32, 0, 0, + 0, 0, 0, 4, 0, 0, + 0, 50, 0, 0, 10, 242, + 0, 16, 0, 0, 0, 0, + 0, 70, 142, 32, 0, 0, + 0, 0, 0, 3, 0, 0, + 0, 6, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, + 0, 1, 0, 0, 0, 0, + 0, 0, 8, 242, 0, 16, + 0, 0, 0, 0, 0, 70, + 14, 16, 0, 0, 0, 0, + 0, 70, 142, 32, 0, 0, + 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 9, 242, + 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, + 0, 0, 0, 70, 142, 32, + 128, 65, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 56, 0, 0, 8, 242, + 0, 16, 0, 1, 0, 0, + 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 142, 32, + 0, 2, 0, 0, 0, 1, + 0, 0, 0, 50, 0, 0, + 10, 242, 0, 16, 0, 1, + 0, 0, 0, 70, 142, 32, + 0, 2, 0, 0, 0, 0, + 0, 0, 0, 6, 0, 16, + 0, 0, 0, 0, 0, 70, + 14, 16, 0, 1, 0, 0, + 0, 50, 0, 0, 10, 242, + 0, 16, 0, 1, 0, 0, + 0, 70, 142, 32, 0, 2, + 0, 0, 0, 2, 0, 0, + 0, 166, 10, 16, 0, 0, + 0, 0, 0, 70, 14, 16, + 0, 1, 0, 0, 0, 50, + 0, 0, 10, 242, 32, 16, + 0, 0, 0, 0, 0, 70, + 142, 32, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 246, + 15, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 1, + 0, 0, 0, 50, 0, 0, + 11, 50, 32, 16, 0, 1, + 0, 0, 0, 70, 16, 16, + 0, 0, 0, 0, 0, 230, + 138, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 70, + 128, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 11, + 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 3, + 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 82, 68, 69, 70, 116, + 2, 0, 0, 3, 0, 0, + 0, 168, 0, 0, 0, 3, + 0, 0, 0, 28, 0, 0, + 0, 0, 4, 254, 255, 0, + 1, 0, 0, 64, 2, 0, + 0, 124, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 133, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 152, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 80, 101, 114, 76, 97, + 121, 101, 114, 0, 80, 101, + 114, 79, 99, 99, 97, 115, + 105, 111, 110, 97, 108, 76, + 97, 121, 101, 114, 0, 80, + 101, 114, 76, 97, 121, 101, + 114, 77, 97, 110, 97, 103, + 101, 114, 0, 124, 0, 0, + 0, 4, 0, 0, 0, 240, + 0, 0, 0, 112, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 133, 0, 0, + 0, 2, 0, 0, 0, 188, + 1, 0, 0, 32, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 152, 0, 0, + 0, 1, 0, 0, 0, 28, + 2, 0, 0, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 80, 1, 0, + 0, 0, 0, 0, 0, 16, + 0, 0, 0, 2, 0, 0, + 0, 96, 1, 0, 0, 0, + 0, 0, 0, 112, 1, 0, + 0, 16, 0, 0, 0, 16, + 0, 0, 0, 2, 0, 0, + 0, 96, 1, 0, 0, 0, + 0, 0, 0, 123, 1, 0, + 0, 32, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, + 0, 140, 1, 0, 0, 0, + 0, 0, 0, 156, 1, 0, + 0, 48, 0, 0, 0, 64, + 0, 0, 0, 2, 0, 0, + 0, 172, 1, 0, 0, 0, + 0, 0, 0, 118, 84, 101, + 120, 116, 117, 114, 101, 67, + 111, 111, 114, 100, 115, 0, + 171, 1, 0, 3, 0, 1, + 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 118, + 76, 97, 121, 101, 114, 81, + 117, 97, 100, 0, 102, 76, + 97, 121, 101, 114, 79, 112, + 97, 99, 105, 116, 121, 0, + 171, 171, 171, 0, 0, 3, + 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 109, 76, 97, 121, 101, + 114, 84, 114, 97, 110, 115, + 102, 111, 114, 109, 0, 3, + 0, 3, 0, 4, 0, 4, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 236, 1, 0, + 0, 0, 0, 0, 0, 16, + 0, 0, 0, 2, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 16, 2, 0, + 0, 16, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 118, 82, 101, + 110, 100, 101, 114, 84, 97, + 114, 103, 101, 116, 79, 102, + 102, 115, 101, 116, 0, 1, + 0, 3, 0, 1, 0, 4, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 102, 76, 97, + 121, 101, 114, 67, 111, 108, + 111, 114, 0, 52, 2, 0, + 0, 0, 0, 0, 0, 64, + 0, 0, 0, 2, 0, 0, + 0, 172, 1, 0, 0, 0, + 0, 0, 0, 109, 80, 114, + 111, 106, 101, 99, 116, 105, + 111, 110, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 50, 57, + 46, 57, 53, 50, 46, 51, + 49, 49, 49, 0, 171, 171, + 171, 73, 83, 71, 78, 44, + 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, + 0, 3, 3, 0, 0, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 171, 171, 171, 79, + 83, 71, 78, 80, 0, 0, + 0, 2, 0, 0, 0, 8, + 0, 0, 0, 56, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 15, + 0, 0, 0, 68, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, + 0, 1, 0, 0, 0, 3, + 12, 0, 0, 83, 86, 95, + 80, 111, 115, 105, 116, 105, + 111, 110, 0, 84, 69, 88, + 67, 79, 79, 82, 68, 0, + 171, 171, 171, 125, 73, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 64, + 7, 0, 0, 68, 88, 66, + 67, 222, 117, 213, 158, 196, + 73, 115, 238, 98, 73, 165, + 136, 82, 215, 234, 7, 1, + 0, 0, 0, 64, 7, 0, + 0, 6, 0, 0, 0, 56, + 0, 0, 0, 220, 1, 0, + 0, 44, 4, 0, 0, 168, + 4, 0, 0, 180, 6, 0, + 0, 12, 7, 0, 0, 65, + 111, 110, 57, 156, 1, 0, + 0, 156, 1, 0, 0, 0, + 2, 255, 255, 96, 1, 0, + 0, 60, 0, 0, 0, 1, + 0, 48, 0, 0, 0, 60, + 0, 0, 0, 60, 0, 3, + 0, 36, 0, 0, 0, 60, + 0, 0, 0, 0, 0, 1, + 0, 1, 0, 2, 0, 2, + 0, 0, 0, 2, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 1, 2, 255, 255, 81, + 0, 0, 5, 1, 0, 15, + 160, 0, 0, 0, 191, 0, + 0, 128, 189, 186, 73, 204, + 63, 197, 32, 80, 63, 81, + 0, 0, 5, 2, 0, 15, + 160, 244, 253, 148, 63, 233, + 38, 1, 64, 39, 49, 200, + 62, 0, 0, 128, 63, 31, + 0, 0, 2, 0, 0, 0, + 128, 0, 0, 3, 176, 31, + 0, 0, 2, 0, 0, 0, + 144, 0, 8, 15, 160, 31, + 0, 0, 2, 0, 0, 0, + 144, 1, 8, 15, 160, 31, + 0, 0, 2, 0, 0, 0, + 144, 2, 8, 15, 160, 66, + 0, 0, 3, 0, 0, 15, + 128, 0, 0, 228, 176, 0, + 8, 228, 160, 66, 0, 0, + 3, 1, 0, 15, 128, 0, + 0, 228, 176, 2, 8, 228, + 160, 2, 0, 0, 3, 0, + 0, 2, 128, 1, 0, 0, + 128, 1, 0, 0, 160, 5, + 0, 0, 3, 0, 0, 6, + 128, 0, 0, 85, 128, 1, + 0, 248, 160, 2, 0, 0, + 3, 0, 0, 1, 128, 0, + 0, 0, 128, 1, 0, 85, + 160, 4, 0, 0, 4, 0, + 0, 4, 128, 0, 0, 0, + 128, 2, 0, 0, 160, 0, + 0, 170, 129, 4, 0, 0, + 4, 1, 0, 1, 128, 0, + 0, 0, 128, 2, 0, 0, + 160, 0, 0, 85, 128, 66, + 0, 0, 3, 2, 0, 15, + 128, 0, 0, 228, 176, 1, + 8, 228, 160, 2, 0, 0, + 3, 0, 0, 2, 128, 2, + 0, 0, 128, 1, 0, 0, + 160, 4, 0, 0, 4, 1, + 0, 2, 128, 0, 0, 85, + 128, 2, 0, 170, 161, 0, + 0, 170, 128, 5, 0, 0, + 3, 0, 0, 2, 128, 0, + 0, 85, 128, 2, 0, 85, + 160, 4, 0, 0, 4, 1, + 0, 4, 128, 0, 0, 0, + 128, 2, 0, 0, 160, 0, + 0, 85, 128, 1, 0, 0, + 2, 1, 0, 8, 128, 2, + 0, 255, 160, 5, 0, 0, + 3, 0, 0, 15, 128, 1, + 0, 228, 128, 0, 0, 0, + 160, 1, 0, 0, 2, 0, + 8, 15, 128, 0, 0, 228, + 128, 255, 255, 0, 0, 83, + 72, 68, 82, 72, 2, 0, + 0, 64, 0, 0, 0, 146, + 0, 0, 0, 89, 0, 0, + 4, 70, 142, 32, 0, 0, + 0, 0, 0, 3, 0, 0, + 0, 90, 0, 0, 3, 0, + 96, 16, 0, 0, 0, 0, + 0, 88, 24, 0, 4, 0, + 112, 16, 0, 0, 0, 0, + 0, 85, 85, 0, 0, 88, + 24, 0, 4, 0, 112, 16, + 0, 1, 0, 0, 0, 85, + 85, 0, 0, 88, 24, 0, + 4, 0, 112, 16, 0, 2, + 0, 0, 0, 85, 85, 0, + 0, 98, 16, 0, 3, 50, + 16, 16, 0, 1, 0, 0, + 0, 101, 0, 0, 3, 242, + 32, 16, 0, 0, 0, 0, + 0, 104, 0, 0, 2, 3, + 0, 0, 0, 69, 0, 0, + 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 16, 16, + 0, 1, 0, 0, 0, 70, + 126, 16, 0, 2, 0, 0, + 0, 0, 96, 16, 0, 0, + 0, 0, 0, 0, 0, 0, + 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, + 191, 56, 0, 0, 10, 50, + 0, 16, 0, 0, 0, 0, + 0, 6, 0, 16, 0, 0, + 0, 0, 0, 2, 64, 0, + 0, 186, 73, 204, 63, 197, + 32, 80, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 69, + 0, 0, 9, 242, 0, 16, + 0, 1, 0, 0, 0, 70, + 16, 16, 0, 1, 0, 0, + 0, 70, 126, 16, 0, 0, + 0, 0, 0, 0, 96, 16, + 0, 0, 0, 0, 0, 0, + 0, 0, 7, 66, 0, 16, + 0, 0, 0, 0, 0, 10, + 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, + 0, 128, 189, 50, 0, 0, + 10, 34, 0, 16, 0, 0, + 0, 0, 0, 42, 0, 16, + 0, 0, 0, 0, 0, 1, + 64, 0, 0, 244, 253, 148, + 63, 26, 0, 16, 128, 65, + 0, 0, 0, 0, 0, 0, + 0, 50, 0, 0, 9, 18, + 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, + 0, 244, 253, 148, 63, 10, + 0, 16, 0, 0, 0, 0, + 0, 69, 0, 0, 9, 242, + 0, 16, 0, 2, 0, 0, + 0, 70, 16, 16, 0, 1, + 0, 0, 0, 70, 126, 16, + 0, 1, 0, 0, 0, 0, + 96, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 18, + 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 2, + 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 191, 50, + 0, 0, 10, 34, 0, 16, + 0, 1, 0, 0, 0, 10, + 0, 16, 128, 65, 0, 0, + 0, 0, 0, 0, 0, 1, + 64, 0, 0, 39, 49, 200, + 62, 26, 0, 16, 0, 0, + 0, 0, 0, 56, 0, 0, + 7, 18, 0, 16, 0, 0, + 0, 0, 0, 10, 0, 16, + 0, 0, 0, 0, 0, 1, + 64, 0, 0, 233, 38, 1, + 64, 50, 0, 0, 9, 66, + 0, 16, 0, 1, 0, 0, + 0, 42, 0, 16, 0, 0, + 0, 0, 0, 1, 64, 0, + 0, 244, 253, 148, 63, 10, + 0, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 5, 130, + 0, 16, 0, 1, 0, 0, + 0, 1, 64, 0, 0, 0, + 0, 128, 63, 56, 0, 0, + 8, 242, 32, 16, 0, 0, + 0, 0, 0, 70, 14, 16, + 0, 1, 0, 0, 0, 6, + 128, 32, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, + 84, 116, 0, 0, 0, 15, + 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 2, + 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 82, 68, 69, 70, 4, + 2, 0, 0, 1, 0, 0, + 0, 236, 0, 0, 0, 5, + 0, 0, 0, 28, 0, 0, + 0, 0, 4, 255, 255, 0, + 1, 0, 0, 208, 1, 0, + 0, 188, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 214, 0, 0, + 0, 2, 0, 0, 0, 5, + 0, 0, 0, 4, 0, 0, + 0, 255, 255, 255, 255, 0, + 0, 0, 0, 1, 0, 0, + 0, 12, 0, 0, 0, 217, + 0, 0, 0, 2, 0, 0, + 0, 5, 0, 0, 0, 4, + 0, 0, 0, 255, 255, 255, + 255, 1, 0, 0, 0, 1, + 0, 0, 0, 12, 0, 0, + 0, 221, 0, 0, 0, 2, + 0, 0, 0, 5, 0, 0, + 0, 4, 0, 0, 0, 255, + 255, 255, 255, 2, 0, 0, + 0, 1, 0, 0, 0, 12, + 0, 0, 0, 225, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 76, + 97, 121, 101, 114, 84, 101, + 120, 116, 117, 114, 101, 83, + 97, 109, 112, 108, 101, 114, + 76, 105, 110, 101, 97, 114, + 0, 116, 89, 0, 116, 67, + 98, 0, 116, 67, 114, 0, + 80, 101, 114, 76, 97, 121, + 101, 114, 0, 171, 171, 225, + 0, 0, 0, 4, 0, 0, + 0, 4, 1, 0, 0, 112, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 100, + 1, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 0, + 0, 0, 0, 116, 1, 0, + 0, 0, 0, 0, 0, 132, + 1, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, + 0, 0, 0, 116, 1, 0, + 0, 0, 0, 0, 0, 143, + 1, 0, 0, 32, 0, 0, + 0, 4, 0, 0, 0, 2, + 0, 0, 0, 160, 1, 0, + 0, 0, 0, 0, 0, 176, + 1, 0, 0, 48, 0, 0, + 0, 64, 0, 0, 0, 0, + 0, 0, 0, 192, 1, 0, + 0, 0, 0, 0, 0, 118, + 84, 101, 120, 116, 117, 114, + 101, 67, 111, 111, 114, 100, + 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 118, 76, 97, 121, 101, + 114, 81, 117, 97, 100, 0, + 102, 76, 97, 121, 101, 114, + 79, 112, 97, 99, 105, 116, + 121, 0, 171, 171, 171, 0, + 0, 3, 0, 1, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 109, 76, 97, + 121, 101, 114, 84, 114, 97, + 110, 115, 102, 111, 114, 109, + 0, 3, 0, 3, 0, 4, + 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 77, + 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, + 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, + 108, 101, 114, 32, 57, 46, + 50, 57, 46, 57, 53, 50, + 46, 51, 49, 49, 49, 0, + 171, 171, 171, 73, 83, 71, + 78, 80, 0, 0, 0, 2, + 0, 0, 0, 8, 0, 0, + 0, 56, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 3, 0, 0, 0, 0, + 0, 0, 0, 15, 0, 0, + 0, 68, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 1, + 0, 0, 0, 3, 3, 0, + 0, 83, 86, 95, 80, 111, + 115, 105, 116, 105, 111, 110, + 0, 84, 69, 88, 67, 79, + 79, 82, 68, 0, 171, 171, + 171, 79, 83, 71, 78, 44, + 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, + 0, 15, 0, 0, 0, 83, + 86, 95, 84, 97, 114, 103, + 101, 116, 0, 171, 171, 153, + 80, 0, 0, 0, 0, 0, + 0, 82, 101, 110, 100, 101, + 114, 83, 111, 108, 105, 100, + 67, 111, 108, 111, 114, 76, + 97, 121, 101, 114, 0, 4, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 3, 0, 0, + 0, 255, 255, 255, 255, 4, + 7, 0, 0, 68, 88, 66, + 67, 74, 0, 69, 126, 158, + 251, 122, 220, 157, 162, 154, + 166, 138, 69, 197, 120, 1, + 0, 0, 0, 4, 7, 0, + 0, 6, 0, 0, 0, 56, + 0, 0, 0, 144, 1, 0, + 0, 128, 3, 0, 0, 252, + 3, 0, 0, 120, 6, 0, + 0, 172, 6, 0, 0, 65, + 111, 110, 57, 80, 1, 0, + 0, 80, 1, 0, 0, 0, + 2, 254, 255, 236, 0, 0, + 0, 100, 0, 0, 0, 5, + 0, 36, 0, 0, 0, 96, + 0, 0, 0, 96, 0, 0, + 0, 36, 0, 1, 0, 96, + 0, 0, 0, 0, 0, 2, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 2, + 0, 3, 0, 0, 0, 0, + 0, 0, 0, 6, 0, 1, + 0, 5, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 1, + 0, 6, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 4, + 0, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, + 2, 254, 255, 31, 0, 0, + 2, 5, 0, 0, 128, 0, + 0, 15, 144, 4, 0, 0, + 4, 0, 0, 3, 224, 0, + 0, 228, 144, 1, 0, 238, + 160, 1, 0, 228, 160, 4, + 0, 0, 4, 0, 0, 3, + 128, 0, 0, 228, 144, 2, + 0, 238, 160, 2, 0, 228, + 160, 5, 0, 0, 3, 1, + 0, 15, 128, 0, 0, 85, + 128, 4, 0, 228, 160, 4, + 0, 0, 4, 0, 0, 15, + 128, 3, 0, 228, 160, 0, + 0, 0, 128, 1, 0, 228, + 128, 2, 0, 0, 3, 0, + 0, 15, 128, 0, 0, 228, + 128, 5, 0, 228, 160, 2, + 0, 0, 3, 0, 0, 15, + 128, 0, 0, 228, 128, 6, + 0, 228, 161, 5, 0, 0, + 3, 1, 0, 15, 128, 0, + 0, 85, 128, 8, 0, 228, + 160, 4, 0, 0, 4, 1, + 0, 15, 128, 7, 0, 228, + 160, 0, 0, 0, 128, 1, + 0, 228, 128, 4, 0, 0, + 4, 1, 0, 15, 128, 9, + 0, 228, 160, 0, 0, 170, + 128, 1, 0, 228, 128, 4, + 0, 0, 4, 0, 0, 15, + 128, 10, 0, 228, 160, 0, + 0, 255, 128, 1, 0, 228, + 128, 4, 0, 0, 4, 0, + 0, 3, 192, 0, 0, 255, + 128, 0, 0, 228, 160, 0, + 0, 228, 128, 1, 0, 0, + 2, 0, 0, 12, 192, 0, + 0, 228, 128, 255, 255, 0, + 0, 83, 72, 68, 82, 232, + 1, 0, 0, 64, 0, 1, + 0, 122, 0, 0, 0, 89, + 0, 0, 4, 70, 142, 32, + 0, 0, 0, 0, 0, 7, + 0, 0, 0, 89, 0, 0, + 4, 70, 142, 32, 0, 1, + 0, 0, 0, 1, 0, 0, + 0, 89, 0, 0, 4, 70, + 142, 32, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 95, + 0, 0, 3, 50, 16, 16, + 0, 0, 0, 0, 0, 103, + 0, 0, 4, 242, 32, 16, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 101, 0, 0, + 3, 50, 32, 16, 0, 1, + 0, 0, 0, 104, 0, 0, + 2, 2, 0, 0, 0, 50, + 0, 0, 11, 50, 0, 16, + 0, 0, 0, 0, 0, 70, + 16, 16, 0, 0, 0, 0, + 0, 230, 138, 32, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 70, 128, 32, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 56, 0, 0, 8, 242, + 0, 16, 0, 1, 0, 0, + 0, 86, 5, 16, 0, 0, + 0, 0, 0, 70, 142, 32, + 0, 0, 0, 0, 0, 4, + 0, 0, 0, 50, 0, 0, + 10, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 142, 32, + 0, 0, 0, 0, 0, 3, + 0, 0, 0, 6, 0, 16, + 0, 0, 0, 0, 0, 70, + 14, 16, 0, 1, 0, 0, + 0, 0, 0, 0, 8, 242, + 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 0, + 0, 0, 0, 70, 142, 32, + 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 0, + 9, 242, 0, 16, 0, 0, + 0, 0, 0, 70, 14, 16, + 0, 0, 0, 0, 0, 70, + 142, 32, 128, 65, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 56, 0, 0, + 8, 242, 0, 16, 0, 1, + 0, 0, 0, 86, 5, 16, + 0, 0, 0, 0, 0, 70, + 142, 32, 0, 2, 0, 0, + 0, 1, 0, 0, 0, 50, + 0, 0, 10, 242, 0, 16, + 0, 1, 0, 0, 0, 70, + 142, 32, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 6, + 0, 16, 0, 0, 0, 0, + 0, 70, 14, 16, 0, 1, + 0, 0, 0, 50, 0, 0, + 10, 242, 0, 16, 0, 1, + 0, 0, 0, 70, 142, 32, + 0, 2, 0, 0, 0, 2, + 0, 0, 0, 166, 10, 16, + 0, 0, 0, 0, 0, 70, + 14, 16, 0, 1, 0, 0, + 0, 50, 0, 0, 10, 242, + 32, 16, 0, 0, 0, 0, + 0, 70, 142, 32, 0, 2, + 0, 0, 0, 3, 0, 0, + 0, 246, 15, 16, 0, 0, + 0, 0, 0, 70, 14, 16, + 0, 1, 0, 0, 0, 50, + 0, 0, 11, 50, 32, 16, + 0, 1, 0, 0, 0, 70, + 16, 16, 0, 0, 0, 0, + 0, 230, 138, 32, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 70, 128, 32, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 62, 0, 0, 1, 83, + 84, 65, 84, 116, 0, 0, + 0, 11, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 82, 68, 69, + 70, 116, 2, 0, 0, 3, + 0, 0, 0, 168, 0, 0, + 0, 3, 0, 0, 0, 28, + 0, 0, 0, 0, 4, 254, + 255, 0, 1, 0, 0, 64, + 2, 0, 0, 124, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 133, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 152, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 80, 101, 114, + 76, 97, 121, 101, 114, 0, + 80, 101, 114, 79, 99, 99, + 97, 115, 105, 111, 110, 97, + 108, 76, 97, 121, 101, 114, + 0, 80, 101, 114, 76, 97, + 121, 101, 114, 77, 97, 110, + 97, 103, 101, 114, 0, 124, + 0, 0, 0, 4, 0, 0, + 0, 240, 0, 0, 0, 112, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 133, + 0, 0, 0, 2, 0, 0, + 0, 188, 1, 0, 0, 32, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 152, + 0, 0, 0, 1, 0, 0, + 0, 28, 2, 0, 0, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 80, + 1, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 2, + 0, 0, 0, 96, 1, 0, + 0, 0, 0, 0, 0, 112, + 1, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 2, + 0, 0, 0, 96, 1, 0, + 0, 0, 0, 0, 0, 123, + 1, 0, 0, 32, 0, 0, + 0, 4, 0, 0, 0, 0, + 0, 0, 0, 140, 1, 0, + 0, 0, 0, 0, 0, 156, + 1, 0, 0, 48, 0, 0, + 0, 64, 0, 0, 0, 2, + 0, 0, 0, 172, 1, 0, + 0, 0, 0, 0, 0, 118, + 84, 101, 120, 116, 117, 114, + 101, 67, 111, 111, 114, 100, + 115, 0, 171, 1, 0, 3, + 0, 1, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 118, 76, 97, 121, 101, + 114, 81, 117, 97, 100, 0, + 102, 76, 97, 121, 101, 114, + 79, 112, 97, 99, 105, 116, + 121, 0, 171, 171, 171, 0, + 0, 3, 0, 1, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 109, 76, 97, + 121, 101, 114, 84, 114, 97, + 110, 115, 102, 111, 114, 109, + 0, 3, 0, 3, 0, 4, + 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 236, + 1, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 2, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 16, + 2, 0, 0, 16, 0, 0, + 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 118, + 82, 101, 110, 100, 101, 114, + 84, 97, 114, 103, 101, 116, + 79, 102, 102, 115, 101, 116, + 0, 1, 0, 3, 0, 1, + 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 102, + 76, 97, 121, 101, 114, 67, + 111, 108, 111, 114, 0, 52, + 2, 0, 0, 0, 0, 0, + 0, 64, 0, 0, 0, 2, + 0, 0, 0, 172, 1, 0, + 0, 0, 0, 0, 0, 109, + 80, 114, 111, 106, 101, 99, + 116, 105, 111, 110, 0, 77, + 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, + 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, + 108, 101, 114, 32, 57, 46, + 50, 57, 46, 57, 53, 50, + 46, 51, 49, 49, 49, 0, + 171, 171, 171, 73, 83, 71, + 78, 44, 0, 0, 0, 1, + 0, 0, 0, 8, 0, 0, + 0, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, + 0, 0, 0, 3, 3, 0, + 0, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 171, 171, + 171, 79, 83, 71, 78, 80, + 0, 0, 0, 2, 0, 0, + 0, 8, 0, 0, 0, 56, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, + 0, 15, 0, 0, 0, 68, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, + 0, 0, 0, 1, 0, 0, + 0, 3, 12, 0, 0, 83, + 86, 95, 80, 111, 115, 105, + 116, 105, 111, 110, 0, 84, + 69, 88, 67, 79, 79, 82, + 68, 0, 171, 171, 171, 43, + 88, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, + 0, 216, 2, 0, 0, 68, + 88, 66, 67, 136, 106, 87, + 29, 239, 32, 100, 138, 218, + 2, 105, 91, 143, 165, 252, + 49, 1, 0, 0, 0, 216, + 2, 0, 0, 6, 0, 0, + 0, 56, 0, 0, 0, 132, + 0, 0, 0, 204, 0, 0, + 0, 72, 1, 0, 0, 76, + 2, 0, 0, 164, 2, 0, + 0, 65, 111, 110, 57, 68, + 0, 0, 0, 68, 0, 0, + 0, 0, 2, 255, 255, 20, + 0, 0, 0, 48, 0, 0, + 0, 1, 0, 36, 0, 0, + 0, 48, 0, 0, 0, 48, + 0, 0, 0, 36, 0, 0, + 0, 48, 0, 0, 0, 1, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 255, + 255, 1, 0, 0, 2, 0, + 8, 15, 128, 0, 0, 228, + 160, 255, 255, 0, 0, 83, + 72, 68, 82, 64, 0, 0, + 0, 64, 0, 0, 0, 16, + 0, 0, 0, 89, 0, 0, + 4, 70, 142, 32, 0, 0, + 0, 0, 0, 2, 0, 0, + 0, 101, 0, 0, 3, 242, + 32, 16, 0, 0, 0, 0, + 0, 54, 0, 0, 6, 242, + 32, 16, 0, 0, 0, 0, + 0, 70, 142, 32, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 62, 0, 0, 1, 83, + 84, 65, 84, 116, 0, 0, + 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 82, 68, 69, + 70, 252, 0, 0, 0, 1, + 0, 0, 0, 80, 0, 0, + 0, 1, 0, 0, 0, 28, + 0, 0, 0, 0, 4, 255, + 255, 0, 1, 0, 0, 200, + 0, 0, 0, 60, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 80, + 101, 114, 79, 99, 99, 97, + 115, 105, 111, 110, 97, 108, + 76, 97, 121, 101, 114, 0, + 171, 60, 0, 0, 0, 2, + 0, 0, 0, 104, 0, 0, + 0, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 152, 0, 0, 0, 0, + 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 172, + 0, 0, 0, 0, 0, 0, + 0, 188, 0, 0, 0, 16, + 0, 0, 0, 16, 0, 0, + 0, 2, 0, 0, 0, 172, + 0, 0, 0, 0, 0, 0, + 0, 118, 82, 101, 110, 100, + 101, 114, 84, 97, 114, 103, + 101, 116, 79, 102, 102, 115, + 101, 116, 0, 1, 0, 3, + 0, 1, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 102, 76, 97, 121, 101, + 114, 67, 111, 108, 111, 114, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 50, 57, 46, 57, + 53, 50, 46, 51, 49, 49, + 49, 0, 171, 171, 171, 73, + 83, 71, 78, 80, 0, 0, + 0, 2, 0, 0, 0, 8, + 0, 0, 0, 56, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 15, + 0, 0, 0, 68, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, + 0, 1, 0, 0, 0, 3, + 0, 0, 0, 83, 86, 95, + 80, 111, 115, 105, 116, 105, + 111, 110, 0, 84, 69, 88, + 67, 79, 79, 82, 68, 0, + 171, 171, 171, 79, 83, 71, + 78, 44, 0, 0, 0, 1, + 0, 0, 0, 8, 0, 0, + 0, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, + 0, 0, 0, 15, 0, 0, + 0, 83, 86, 95, 84, 97, + 114, 103, 101, 116, 0, 171, + 171, 71, 95, 0, 0, 0, + 0, 0, 0, 4, 0, 0, + 0, 112, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, + 0, 255, 255, 255, 255, 0, + 0, 0, 0, 48, 0, 0, + 0, 20, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 63, 0, 0, 0, 20, + 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 108, + 0, 0, 0, 80, 0, 0, + 0, 0, 0, 0, 0, 32, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 159, 0, 0, + 0, 131, 0, 0, 0, 0, + 0, 0, 0, 48, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 175, 0, 0, 0, 32, + 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, + 0, 194, 0, 0, 0, 20, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 214, + 0, 0, 0, 20, 0, 0, + 0, 0, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 226, 0, 0, + 0, 64, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 255, 255, 255, 255, 0, + 0, 0, 0, 242, 0, 0, + 0, 131, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 37, 1, 0, 0, 9, + 1, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 9, + 0, 0, 0, 36, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 44, 1, 0, + 0, 37, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 56, 1, 0, 0, 38, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 68, + 1, 0, 0, 39, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 80, 1, 0, + 0, 40, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 92, 1, 0, 0, 41, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 104, + 1, 0, 0, 42, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 116, 1, 0, + 0, 43, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 128, 1, 0, 0, 44, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 140, + 1, 0, 0, 0, 0, 0, + 0, 152, 1, 0, 0, 9, + 1, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 9, + 0, 0, 0, 36, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 162, 1, 0, + 0, 37, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 174, 1, 0, 0, 38, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 186, + 1, 0, 0, 39, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 198, 1, 0, + 0, 40, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 210, 1, 0, 0, 41, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 222, + 1, 0, 0, 42, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 234, 1, 0, + 0, 43, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 246, 1, 0, 0, 44, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 2, + 2, 0, 0, 0, 0, 0, + 0, 58, 2, 0, 0, 30, + 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 1, + 0, 0, 0, 19, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 68, 2, 0, + 0, 0, 0, 0, 0, 118, + 2, 0, 0, 90, 2, 0, + 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, + 0, 123, 2, 0, 0, 90, + 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 0, + 0, 0, 0, 126, 2, 0, + 0, 90, 2, 0, 0, 0, + 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 130, + 2, 0, 0, 90, 2, 0, + 0, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, + 0, 175, 2, 0, 0, 147, + 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 3, + 0, 0, 0, 45, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 201, 2, 0, + 0, 46, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 213, 2, 0, 0, 47, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 225, + 2, 0, 0, 0, 0, 0, + 0, 237, 2, 0, 0, 147, + 2, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 3, + 0, 0, 0, 45, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 6, 3, 0, + 0, 46, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 18, 3, 0, 0, 47, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 30, + 3, 0, 0, 0, 0, 0, + 0, 42, 3, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 63, 3, 0, 0, 7, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, + 0, 58, 2, 0, 0, 10, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 66, + 3, 0, 0, 11, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 102, 3, 0, + 0, 2, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, + 0, 37, 1, 0, 0, 6, + 0, 0, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 122, + 10, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 130, 10, 0, + 0, 7, 0, 0, 0, 0, + 0, 0, 0, 7, 0, 0, + 0, 230, 14, 0, 0, 238, + 14, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 63, + 3, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 58, + 2, 0, 0, 10, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 8, 15, 0, + 0, 11, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 44, 15, 0, 0, 2, + 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 37, + 1, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 7, + 0, 0, 0, 64, 22, 0, + 0, 8, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 72, 22, 0, 0, 7, + 0, 0, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 172, + 26, 0, 0, 180, 26, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 63, 3, 0, + 0, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, + 0, 0, 0, 58, 2, 0, + 0, 10, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 202, 26, 0, 0, 11, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 238, + 26, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 2, + 0, 0, 0, 37, 1, 0, + 0, 6, 0, 0, 0, 0, + 0, 0, 0, 7, 0, 0, + 0, 2, 34, 0, 0, 8, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 10, + 34, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 7, + 0, 0, 0, 74, 38, 0, + 0, 82, 38, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 63, 3, 0, 0, 7, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, + 0, 58, 2, 0, 0, 10, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 107, + 38, 0, 0, 11, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 143, 38, 0, + 0, 2, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, + 0, 152, 1, 0, 0, 6, + 0, 0, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 163, + 45, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 171, 45, 0, + 0, 7, 0, 0, 0, 0, + 0, 0, 0, 7, 0, 0, + 0, 235, 49, 0, 0, 243, + 49, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 63, + 3, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 58, + 2, 0, 0, 10, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 14, 50, 0, + 0, 11, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 50, 50, 0, 0, 2, + 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 37, + 1, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 7, + 0, 0, 0, 70, 57, 0, + 0, 8, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 78, 57, 0, 0, 7, + 0, 0, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 142, + 61, 0, 0, 150, 61, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 63, 3, 0, + 0, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, + 0, 0, 0, 58, 2, 0, + 0, 10, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 180, 61, 0, 0, 11, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 216, + 61, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 2, + 0, 0, 0, 152, 1, 0, + 0, 6, 0, 0, 0, 0, + 0, 0, 0, 7, 0, 0, + 0, 236, 68, 0, 0, 8, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 244, + 68, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 7, + 0, 0, 0, 52, 73, 0, + 0, 60, 73, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 63, 3, 0, 0, 7, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, + 0, 58, 2, 0, 0, 10, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 77, + 73, 0, 0, 11, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 113, 73, 0, + 0, 2, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, + 0, 37, 1, 0, 0, 6, + 0, 0, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 133, + 80, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 141, 80, 0, + 0, 7, 0, 0, 0, 0, + 0, 0, 0, 7, 0, 0, + 0, 221, 87, 0, 0, 229, + 87, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 63, + 3, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 58, + 2, 0, 0, 10, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 251, 87, 0, + 0, 11, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 31, 88, 0, 0, 2, + 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 37, + 1, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 7, + 0, 0, 0, 51, 95, 0, + 0, 8, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 59, 95, 0, 0, 7, + 0, 0, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 35, + 98, 0, 0 +}; diff --git a/gfx/layers/d3d10/ThebesLayerD3D10.cpp b/gfx/layers/d3d10/ThebesLayerD3D10.cpp new file mode 100644 index 000000000000..cf3b1191f67d --- /dev/null +++ b/gfx/layers/d3d10/ThebesLayerD3D10.cpp @@ -0,0 +1,339 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Bas Schouten + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ThebesLayerD3D10.h" +#include "gfxPlatform.h" + +#include "gfxWindowsPlatform.h" +#ifdef CAIRO_HAS_D2D_SURFACE +#include "gfxD2DSurface.h" +#endif + +namespace mozilla { +namespace layers { + +ThebesLayerD3D10::ThebesLayerD3D10(LayerManagerD3D10 *aManager) + : ThebesLayer(aManager, NULL) + , LayerD3D10(aManager) +{ + mImplData = static_cast(this); +} + +ThebesLayerD3D10::~ThebesLayerD3D10() +{ +} + +/** + * Retention threshold - amount of pixels intersection required to enable + * layer content retention. This is a guesstimate. Profiling could be done to + * figure out the optimal threshold. + */ +#define RETENTION_THRESHOLD 16384 + +void +ThebesLayerD3D10::SetVisibleRegion(const nsIntRegion &aRegion) +{ + if (aRegion.IsEqual(mVisibleRegion)) { + return; + } + + HRESULT hr; + + nsIntRegion oldVisibleRegion = mVisibleRegion; + ThebesLayer::SetVisibleRegion(aRegion); + + if (!mTexture) { + // If we don't need to retain content initialize lazily. This is good also + // because we might get mIsOpaqueSurface set later than the first call to + // SetVisibleRegion. + return; + } + + VerifyContentType(); + + nsRefPtr oldTexture = mTexture; + + nsIntRect oldBounds = oldVisibleRegion.GetBounds(); + nsIntRect newBounds = mVisibleRegion.GetBounds(); + + CreateNewTexture(gfxIntSize(newBounds.width, newBounds.height)); + + // Old visible region will become the region that is covered by both the + // old and the new visible region. + oldVisibleRegion.And(oldVisibleRegion, mVisibleRegion); + // No point in retaining parts which were not valid. + oldVisibleRegion.And(oldVisibleRegion, mValidRegion); + + nsIntRect largeRect = oldVisibleRegion.GetLargestRectangle(); + + // If we had no hardware texture before or have no retained area larger than + // the retention threshold, we're not retaining and are done here. If our + // texture creation failed this can mean a device reset is pending and we + // should silently ignore the failure. In the future when device failures + // are properly handled we should test for the type of failure and gracefully + // handle different failures. See bug 569081. + if (!oldTexture || !mTexture || + largeRect.width * largeRect.height < RETENTION_THRESHOLD) { + mValidRegion.SetEmpty(); + return; + } + + nsIntRegion retainedRegion; + nsIntRegionRectIterator iter(oldVisibleRegion); + const nsIntRect *r; + while ((r = iter.Next())) { + if (r->width * r->height > RETENTION_THRESHOLD) { + // Calculate the retained rectangle's position on the old and the new + // surface. + D3D10_BOX box; + box.left = r->x - oldBounds.x; + box.top = r->y - oldBounds.y; + box.right = box.left + r->width; + box.bottom = box.top + r->height; + box.back = 1.0f; + box.front = 0; + + device()->CopySubresourceRegion(mTexture, 0, + r->x - newBounds.x, + r->y - newBounds.y, + 0, + oldTexture, 0, + &box); + + if (SUCCEEDED(hr)) { + retainedRegion.Or(retainedRegion, *r); + } + } + } + + // Areas which were valid and were retained are still valid + mValidRegion.And(mValidRegion, retainedRegion); +} + + +void +ThebesLayerD3D10::InvalidateRegion(const nsIntRegion &aRegion) +{ + mValidRegion.Sub(mValidRegion, aRegion); +} + +void +ThebesLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) +{ + if (!mTexture) { + return; + } + + nsIntRect visibleRect = mVisibleRegion.GetBounds(); + + gfx3DMatrix transform = mTransform * aTransform; + effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64); + effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(GetOpacity() * aOpacity); + + ID3D10EffectTechnique *technique; + if (CanUseOpaqueSurface()) { + technique = effect()->GetTechniqueByName("RenderRGBLayerPremul"); + } else { + technique = effect()->GetTechniqueByName("RenderRGBALayerPremul"); + } + + + nsIntRegionRectIterator iter(mVisibleRegion); + + const nsIntRect *iterRect; + if (mSRView) { + effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(mSRView); + } + + while ((iterRect = iter.Next())) { + effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector( + ShaderConstantRectD3D10( + (float)iterRect->x, + (float)iterRect->y, + (float)iterRect->width, + (float)iterRect->height) + ); + + effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector( + ShaderConstantRectD3D10( + (float)(iterRect->x - visibleRect.x) / (float)visibleRect.width, + (float)(iterRect->y - visibleRect.y) / (float)visibleRect.height, + (float)iterRect->width / (float)visibleRect.width, + (float)iterRect->height / (float)visibleRect.height) + ); + + technique->GetPassByIndex(0)->Apply(0); + device()->Draw(4, 0); + } + + // Set back to default. + effect()->GetVariableByName("vTextureCoords")->AsVector()-> + SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f)); +} + +void +ThebesLayerD3D10::Validate() +{ + if (mVisibleRegion.IsEmpty()) { + return; + } + + VerifyContentType(); + + nsIntRect visibleRect = mVisibleRegion.GetBounds(); + + if (!mTexture) { + CreateNewTexture(gfxIntSize(visibleRect.width, visibleRect.height)); + mValidRegion.SetEmpty(); + } + + if (!mValidRegion.IsEqual(mVisibleRegion)) { + /* We use the bounds of the visible region because we draw the bounds of + * this region when we draw this entire texture. We have to make sure that + * the areas that aren't filled with content get their background drawn. + * This is an issue for opaque surfaces, which otherwise won't get their + * background painted. + */ + nsIntRegion region; + region.Sub(mVisibleRegion, mValidRegion); + + DrawRegion(region); + + mValidRegion = mVisibleRegion; + } +} + +void +ThebesLayerD3D10::LayerManagerDestroyed() +{ + mD3DManager = nsnull; +} + +Layer* +ThebesLayerD3D10::GetLayer() +{ + return this; +} + +void +ThebesLayerD3D10::VerifyContentType() +{ + if (mD2DSurface) { + gfxASurface::gfxContentType type = CanUseOpaqueSurface() ? + gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA; + + if (type != mD2DSurface->GetContentType()) { + mD2DSurface = new gfxD2DSurface(mTexture, type); + + if (!mD2DSurface || mD2DSurface->CairoStatus()) { + NS_WARNING("Failed to create surface for ThebesLayerD3D10."); + mD2DSurface = nsnull; + return; + } + mValidRegion.SetEmpty(); + } + } +} + +void +ThebesLayerD3D10::DrawRegion(const nsIntRegion &aRegion) +{ + HRESULT hr; + nsIntRect visibleRect = mVisibleRegion.GetBounds(); + + if (!mD2DSurface) { + return; + } + + nsRefPtr context = new gfxContext(mD2DSurface); + + nsIntRegionRectIterator iter(aRegion); + context->Translate(gfxPoint(-visibleRect.x, -visibleRect.y)); + context->NewPath(); + const nsIntRect *iterRect; + while ((iterRect = iter.Next())) { + context->Rectangle(gfxRect(iterRect->x, iterRect->y, iterRect->width, iterRect->height)); + } + context->Clip(); + + if (mD2DSurface->GetContentType() != gfxASurface::CONTENT_COLOR) { + context->SetOperator(gfxContext::OPERATOR_CLEAR); + context->Paint(); + context->SetOperator(gfxContext::OPERATOR_OVER); + } + + LayerManagerD3D10::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo(); + cbInfo.Callback(this, context, aRegion, nsIntRegion(), cbInfo.CallbackData); +} + +void +ThebesLayerD3D10::CreateNewTexture(const gfxIntSize &aSize) +{ + if (aSize.width == 0 || aSize.height == 0) { + // Nothing to do. + return; + } + + CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1); + desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE; + desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE; + + HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(mTexture)); + + if (FAILED(hr)) { + NS_WARNING("Failed to create new texture for ThebesLayerD3D10!"); + return; + } + + hr = device()->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView)); + + if (FAILED(hr)) { + NS_WARNING("Failed to create shader resource view for ThebesLayerD3D10."); + } + + mD2DSurface = new gfxD2DSurface(mTexture, CanUseOpaqueSurface() ? + gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA); + + if (!mD2DSurface || mD2DSurface->CairoStatus()) { + NS_WARNING("Failed to create surface for ThebesLayerD3D10."); + mD2DSurface = nsnull; + return; + } +} + +} /* namespace layers */ +} /* namespace mozilla */ diff --git a/gfx/layers/d3d10/ThebesLayerD3D10.h b/gfx/layers/d3d10/ThebesLayerD3D10.h new file mode 100644 index 000000000000..667779ee2ecc --- /dev/null +++ b/gfx/layers/d3d10/ThebesLayerD3D10.h @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Bas Schouten + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef GFX_THEBESLAYERD3D10_H +#define GFX_THEBESLAYERD3D10_H + +#include "Layers.h" +#include "LayerManagerD3D10.h" + +namespace mozilla { +namespace layers { + +class ThebesLayerD3D10 : public ThebesLayer, + public LayerD3D10 +{ +public: + ThebesLayerD3D10(LayerManagerD3D10 *aManager); + virtual ~ThebesLayerD3D10(); + + /* Layer implementation */ + void SetVisibleRegion(const nsIntRegion& aRegion); + + /* ThebesLayer implementation */ + void InvalidateRegion(const nsIntRegion& aRegion); + + /* LayerD3D10 implementation */ + Layer* GetLayer(); + virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform); + virtual void Validate(); + virtual void LayerManagerDestroyed(); + +private: + /* Texture with our surface data */ + nsRefPtr mTexture; + + /* Shader resource view for our texture */ + nsRefPtr mSRView; + + /* Checks if our D2D surface has the right content type */ + void VerifyContentType(); + + /* This contains the thebes surface */ + nsRefPtr mD2DSurface; + + /* Have a region of our layer drawn */ + void DrawRegion(const nsIntRegion &aRegion); + + /* Create a new texture */ + void CreateNewTexture(const gfxIntSize &aSize); +}; + +} /* layers */ +} /* mozilla */ +#endif /* GFX_THEBESLAYERD3D10_H */ From b90c29d4b96da54a5fa72343ab72f34cfd68b69d Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Fri, 1 Oct 2010 00:53:51 +0200 Subject: [PATCH 015/115] Bug 546514 - Part 4: Build D3D10 layers. r=vlad --- gfx/layers/Layers.h | 3 ++- gfx/layers/Makefile.in | 15 +++++++++++++++ gfx/thebes/gfxDllDeps.cpp | 6 ++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 35d513cb9224..5b3e0ed3df42 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -224,7 +224,8 @@ public: enum LayersBackend { LAYERS_BASIC = 0, LAYERS_OPENGL, - LAYERS_D3D9 + LAYERS_D3D9, + LAYERS_D3D10 }; LayerManager() : mDestroyed(PR_FALSE) diff --git a/gfx/layers/Makefile.in b/gfx/layers/Makefile.in index 019cb080a8ae..09dca58a1ff0 100644 --- a/gfx/layers/Makefile.in +++ b/gfx/layers/Makefile.in @@ -43,6 +43,7 @@ VPATH = \ $(srcdir)/basic \ $(srcdir)/opengl \ $(srcdir)/d3d9 \ + $(srcdir)/d3d10 \ $(NULL) include $(DEPTH)/config/autoconf.mk @@ -100,6 +101,20 @@ CPPSRCS += \ Nv3DVUtils.cpp \ $(NULL) endif +ifdef MOZ_ENABLE_D3D10_LAYER +EXPORTS += \ + LayerManagerD3D10.h \ + $(NULL) + +CPPSRCS += \ + LayerManagerD3D10.cpp \ + ThebesLayerD3D10.cpp \ + ContainerLayerD3D10.cpp \ + ImageLayerD3D10.cpp \ + ColorLayerD3D10.cpp \ + CanvasLayerD3D10.cpp \ + $(NULL) +endif endif ifdef MOZ_IPC #{ diff --git a/gfx/thebes/gfxDllDeps.cpp b/gfx/thebes/gfxDllDeps.cpp index 6b3ceaf2efa9..464d3b7427b9 100644 --- a/gfx/thebes/gfxDllDeps.cpp +++ b/gfx/thebes/gfxDllDeps.cpp @@ -5,6 +5,9 @@ #ifdef MOZ_ENABLE_D3D9_LAYER #include "LayerManagerD3D9.h" #endif +#ifdef MOZ_ENABLE_D3D10_LAYER +#include "LayerManagerD3D10.h" +#endif using namespace mozilla; using namespace layers; @@ -16,4 +19,7 @@ void XXXNeverCalled_Layers() #ifdef MOZ_ENABLE_D3D9_LAYER LayerManagerD3D9(nsnull); #endif +#ifdef MOZ_ENABLE_D3D10_LAYER + LayerManagerD3D10(nsnull); +#endif } From e53efd8117d88fc99e24a8bec3132a4e83f6af51 Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Fri, 1 Oct 2010 00:53:53 +0200 Subject: [PATCH 016/115] Bug 546514 - Part 5: Allow turning on D3D10 layers through a pref. r=vlad a=vlad --- modules/libpref/src/init/all.js | 1 + widget/src/windows/nsWindow.cpp | 17 ++++++++++++++++- widget/src/windows/nsWindowGfx.cpp | 5 +++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 18c0d98a07d3..446c877600c7 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -3229,6 +3229,7 @@ pref("gfx.direct2d.disabled", false); pref("gfx.direct2d.force-enabled", false); pref("layers.prefer-opengl", false); +pref("layers.use-d3d10", false); #endif #endif diff --git a/widget/src/windows/nsWindow.cpp b/widget/src/windows/nsWindow.cpp index 32e21a3713fc..938b452c3f27 100644 --- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -174,6 +174,9 @@ #ifdef MOZ_ENABLE_D3D9_LAYER #include "LayerManagerD3D9.h" #endif +#ifdef MOZ_ENABLE_D3D10_LAYER +#include "LayerManagerD3D10.h" +#endif #include "LayerManagerOGL.h" #endif #include "BasicLayers.h" @@ -3185,6 +3188,7 @@ nsWindow::GetLayerManager() PRBool accelerateByDefault = PR_TRUE; PRBool disableAcceleration = PR_FALSE; PRBool preferOpenGL = PR_FALSE; + PRBool useD3D10 = PR_FALSE; if (prefs) { prefs->GetBoolPref("layers.accelerate-all", &accelerateByDefault); @@ -3192,6 +3196,8 @@ nsWindow::GetLayerManager() &disableAcceleration); prefs->GetBoolPref("layers.prefer-opengl", &preferOpenGL); + prefs->GetBoolPref("layers.use-d3d10", + &useD3D10); } const char *acceleratedEnv = PR_GetEnv("MOZ_ACCELERATED"); @@ -3215,8 +3221,17 @@ nsWindow::GetLayerManager() mUseAcceleratedRendering = PR_TRUE; if (mUseAcceleratedRendering) { +#ifdef MOZ_ENABLE_D3D10_LAYER + if (useD3D10) { + nsRefPtr layerManager = + new mozilla::layers::LayerManagerD3D10(this); + if (layerManager->Initialize()) { + mLayerManager = layerManager; + } + } +#endif #ifdef MOZ_ENABLE_D3D9_LAYER - if (!preferOpenGL) { + if (!preferOpenGL && !mLayerManager) { nsRefPtr layerManager = new mozilla::layers::LayerManagerD3D9(this); if (layerManager->Initialize()) { diff --git a/widget/src/windows/nsWindowGfx.cpp b/widget/src/windows/nsWindowGfx.cpp index 016b44133ebd..1417f12d9fab 100644 --- a/widget/src/windows/nsWindowGfx.cpp +++ b/widget/src/windows/nsWindowGfx.cpp @@ -759,6 +759,11 @@ DDRAW_FAILED: } } break; +#endif +#ifdef MOZ_ENABLE_D3D10_LAYER + case LayerManager::LAYERS_D3D10: + result = DispatchWindowEvent(&event, eventStatus); + break; #endif default: NS_ERROR("Unknown layers backend used!"); From 48d746f5414c125c6d1b52cba1d242a2cc0c3d6d Mon Sep 17 00:00:00 2001 From: Bob Moss Date: Thu, 30 Sep 2010 16:47:54 -0700 Subject: [PATCH 017/115] Bug 600266 Change AGENT-ERROR to AGENT-WARNING, add reboot notice and clok command to sutagent r=ctalbert a=NPOTB --- build/mobile/sutagent/android/ASMozStub.java | 8 ++ .../sutagent/android/AndroidManifest.xml | 8 +- .../sutagent/android/DataWorkerThread.java | 19 +++- build/mobile/sutagent/android/DoCommand.java | 102 +++++++++++++++++- .../sutagent/android/RunDataThread.java | 13 +++ .../sutagent/android/SUTAgentAndroid.java | 5 +- 6 files changed, 148 insertions(+), 7 deletions(-) diff --git a/build/mobile/sutagent/android/ASMozStub.java b/build/mobile/sutagent/android/ASMozStub.java index 5372881f3736..ed522f833c9b 100755 --- a/build/mobile/sutagent/android/ASMozStub.java +++ b/build/mobile/sutagent/android/ASMozStub.java @@ -111,4 +111,12 @@ public class ASMozStub extends android.app.Service { System.exit(0); } + + public void SendToDataChannel(String strToSend) + { + if (runDataThrd.isAlive()) + { + runDataThrd.SendToDataChannel(strToSend); + } + } } diff --git a/build/mobile/sutagent/android/AndroidManifest.xml b/build/mobile/sutagent/android/AndroidManifest.xml index 1f2c9e969a01..ddc5dbf5a257 100644 --- a/build/mobile/sutagent/android/AndroidManifest.xml +++ b/build/mobile/sutagent/android/AndroidManifest.xml @@ -5,6 +5,7 @@ android:versionName="1.0" android:sharedUserId="org.mozilla.sharedID"> @@ -25,7 +26,7 @@ - + @@ -59,4 +60,9 @@ + + + + + \ No newline at end of file diff --git a/build/mobile/sutagent/android/DataWorkerThread.java b/build/mobile/sutagent/android/DataWorkerThread.java index cd802a6e2b15..8dea41998b4a 100755 --- a/build/mobile/sutagent/android/DataWorkerThread.java +++ b/build/mobile/sutagent/android/DataWorkerThread.java @@ -55,18 +55,34 @@ public class DataWorkerThread extends Thread private RunDataThread theParent = null; private Socket socket = null; boolean bListening = true; + PrintWriter out = null; + SimpleDateFormat sdf = null; public DataWorkerThread(RunDataThread theParent, Socket workerSocket) { super("DataWorkerThread"); this.theParent = theParent; this.socket = workerSocket; + this.sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss"); } public void StopListening() { bListening = false; } + + public void SendString(String strToSend) + { + if (this.out != null) + { + Calendar cal = Calendar.getInstance(); + String strOut = sdf.format(cal.getTime()); + strOut += " " + strToSend + "\r\n"; + + out.write(strOut); + out.flush(); + } + } private String readLine(BufferedInputStream in) { @@ -135,13 +151,12 @@ public class DataWorkerThread extends Thread { OutputStream cmdOut = socket.getOutputStream(); InputStream cmdIn = socket.getInputStream(); - PrintWriter out = new PrintWriter(cmdOut, true); + this.out = new PrintWriter(cmdOut, true); BufferedInputStream in = new BufferedInputStream(cmdIn); String inputLine, outputLine; DoCommand dc = new DoCommand(theParent.svc); Calendar cal = Calendar.getInstance(); - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss"); sRet = sdf.format(cal.getTime()); sRet += " trace output"; diff --git a/build/mobile/sutagent/android/DoCommand.java b/build/mobile/sutagent/android/DoCommand.java index fe7ae82d7213..4618c0ab3efd 100755 --- a/build/mobile/sutagent/android/DoCommand.java +++ b/build/mobile/sutagent/android/DoCommand.java @@ -60,7 +60,9 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; import java.util.List; +import java.util.TimeZone; import java.util.Timer; import java.util.zip.Adler32; import java.util.zip.CheckedInputStream; @@ -95,6 +97,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.net.Uri; import android.os.Build; +import android.os.Debug; import android.os.Environment; import android.os.StatFs; import android.os.SystemClock; @@ -113,9 +116,9 @@ public class DoCommand { ContextWrapper contextWrapper = null; String currentDir = "/"; - String sErrorPrefix = "##AGENT-ERROR## "; + String sErrorPrefix = "##AGENT-WARNING## "; - private final String prgVersion = "SUTAgentAndroid Version 0.80"; + private final String prgVersion = "SUTAgentAndroid Version 0.85"; public enum Command { @@ -128,6 +131,7 @@ public class DoCommand { OS ("os"), ID ("id"), UPTIME ("uptime"), + SETTIME ("settime"), SYSTIME ("systime"), SCREEN ("screen"), MEMORY ("memory"), @@ -215,10 +219,18 @@ public class DoCommand { strReturn = prgVersion; break; + case CLOK: + strReturn = GetClok(); + break; + case UPDT: strReturn = StartUpdateOMatic(Argv[1], Argv[2]); break; + case SETTIME: + strReturn = SetSystemTime(Argv[1], Argv[2], cmdOut); + break; + case CWD: try { strReturn = new java.io.File(currentDir).getCanonicalPath(); @@ -244,7 +256,7 @@ public class DoCommand { if (Argc == 2) strReturn = GetAppRoot(Argv[1]); else - strReturn = sErrorPrefix + "Wrong number of arguments for cd command!"; + strReturn = sErrorPrefix + "Wrong number of arguments for getapproot command!"; break; case TESTROOT: @@ -1929,6 +1941,84 @@ public class DoCommand { return (sRet); } + public String SetSystemTime(String sDate, String sTime, OutputStream out) + { +// Debug.waitForDebugger(); + String sRet = ""; + +// Intent prgIntent = new Intent(android.provider.Settings.ACTION_DATE_SETTINGS); +// prgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); +// contextWrapper.startActivity(prgIntent); + + // 2010/09/22 + // 15:41:00 + // 0123456789012345678 + + if (((sDate != null) && (sTime != null)) && + (sDate.contains("/") || sDate.contains(".")) && + (sTime.contains(":"))) + { + int year = Integer.parseInt(sDate.substring(0,4)); + int month = Integer.parseInt(sDate.substring(5,7)); + int day = Integer.parseInt(sDate.substring(8,10)); + + int hour = Integer.parseInt(sTime.substring(0,2)); + int mins = Integer.parseInt(sTime.substring(3,5)); + int secs = Integer.parseInt(sTime.substring(6,8)); + + Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT")); + cal.set(year, month - 1, day, hour, mins, secs); + long lMillisecs = cal.getTime().getTime(); + +// boolean bRet = SystemClock.setCurrentTimeMillis(lMillisecs); + String sM = Long.toString(lMillisecs); +// long lm = 1285175618316L; + String sTest = cal.getTime().toGMTString(); + String sMillis = sM.substring(0, sM.length() - 3) + "." + sM.substring(sM.length() - 3); + String [] theArgs = new String [3]; + + theArgs[0] = "su"; + theArgs[1] = "-c"; + theArgs[2] = "date -u " + sMillis; + + try + { + pProc = Runtime.getRuntime().exec(theArgs); + RedirOutputThread outThrd = new RedirOutputThread(pProc, null); + outThrd.start(); + outThrd.join(10000); + sRet = GetSystemTime(); + } + catch (IOException e) + { + sRet = e.getMessage(); + e.printStackTrace(); + } + catch (InterruptedException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + else + { + sRet = "Invalid argument(s)"; + } + + return (sRet); + } + + public String GetClok() + { + long lMillisecs = System.currentTimeMillis(); + String sRet = ""; + + if (lMillisecs > 0) + sRet = Long.toString(lMillisecs); + + return(sRet); + } + public String GetUptime() { String sRet = ""; @@ -2140,6 +2230,9 @@ public class DoCommand { try { + // Tell all of the data channels we are rebooting + ((ASMozStub)this.contextWrapper).SendToDataChannel("Rebooting ..."); + pProc = Runtime.getRuntime().exec(theArgs); RedirOutputThread outThrd = new RedirOutputThread(pProc, out); outThrd.start(); @@ -2551,6 +2644,9 @@ public class DoCommand { "rebt - reboot device\n" + "inst /path/filename.apk - install the referenced apk file\n" + "uninst packagename - uninstall the referenced package\n" + + "updt pkgname pkgfile - unpdate the referenced package\n" + + "clok - the current device time expressed as the number of millisecs since epoch\n" + + "settime date time - sets the device date and time (YYYY/MM/DD HH:MM:SS)\n" + "rebt - reboot device\n" + "quit - disconnect SUTAgent\n" + "exit - close SUTAgent\n" + diff --git a/build/mobile/sutagent/android/RunDataThread.java b/build/mobile/sutagent/android/RunDataThread.java index e30ad0031bd6..dd363a071a7a 100755 --- a/build/mobile/sutagent/android/RunDataThread.java +++ b/build/mobile/sutagent/android/RunDataThread.java @@ -66,6 +66,19 @@ public class RunDataThread extends Thread { bListening = false; } + + public void SendToDataChannel(String strToSend) + { + int nNumWorkers = theWorkers.size(); + for (int lcv = 0; lcv < nNumWorkers; lcv++) + { + if (theWorkers.get(lcv).isAlive()) + { + theWorkers.get(lcv).SendString(strToSend); + } + } + return; + } public void run() { try { diff --git a/build/mobile/sutagent/android/SUTAgentAndroid.java b/build/mobile/sutagent/android/SUTAgentAndroid.java index df3bfc99eaa2..dcd27dc396eb 100755 --- a/build/mobile/sutagent/android/SUTAgentAndroid.java +++ b/build/mobile/sutagent/android/SUTAgentAndroid.java @@ -65,6 +65,7 @@ import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.os.BatteryManager; import android.os.Bundle; +import android.os.Debug; import android.os.PowerManager; import android.telephony.TelephonyManager; import android.util.Log; @@ -133,7 +134,9 @@ public class SUTAgentAndroid extends Activity { super.onCreate(savedInstanceState); setContentView(R.layout.main); - + +// Debug.waitForDebugger(); + // long lHeapSize = VMRuntime.getRuntime().getMinimumHeapSize(); // lHeapSize = 16000000; // VMRuntime.getRuntime().setMinimumHeapSize(lHeapSize); From ccfa5e6be42a4c6baf5645676642d4d6b0af2c0c Mon Sep 17 00:00:00 2001 From: Mounir Lamouri Date: Thu, 30 Sep 2010 16:48:52 -0700 Subject: [PATCH 018/115] Bug 600813 - Remove PUT and DELETE form methods. r=backout a=blocking-b7 --- docshell/base/nsDocShell.cpp | 8 ++++---- docshell/base/nsDocShell.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index f6117aede0ba..3570009af1b0 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -5890,7 +5890,7 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel, } // HTTP channel with unsafe methods should not be redirected to a cross-domain. - if (!ChannelIsSafeHTTPMethod(aNewChannel)) { + if (!ChannelIsSafeMethod(aNewChannel)) { // This code is very similar to the code of nsSameOriginChecker in // nsContentUtils but we can't use nsSameOriginChecker because it // needs to use a channel callback (which we already use). @@ -8791,7 +8791,7 @@ nsDocShell::DoURILoad(nsIURI * aURI, // If a specific HTTP channel has been set and it is not a safe method, // we should prevent cross-origin requests. - if (aHttpMethod && ownerPrincipal && !ChannelIsSafeHTTPMethod(channel)) { + if (aHttpMethod && ownerPrincipal && !ChannelIsSafeMethod(channel)) { if (NS_FAILED(ownerPrincipal->CheckMayLoad(aURI, PR_FALSE))) { return NS_OK; } @@ -10438,11 +10438,11 @@ nsDocShell::ChannelIsPost(nsIChannel* aChannel) /* static */ bool -nsDocShell::ChannelIsSafeHTTPMethod(nsIChannel* aChannel) +nsDocShell::ChannelIsSafeMethod(nsIChannel* aChannel) { nsCOMPtr httpChannel(do_QueryInterface(aChannel)); if (!httpChannel) { - return true; + return false; } nsCAutoString method; diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index da899b5180f6..80e2a5c2d5ec 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -457,9 +457,9 @@ protected: * @param aChannel The channel to test * * @return Whether the channel has a safe HTTP method. - * @note Will return true if the channel isn't an HTTP channel. + * @note Will return false if the channel isn't an HTTP channel. */ - static bool ChannelIsSafeHTTPMethod(nsIChannel* aChannel); + static bool ChannelIsSafeMethod(nsIChannel* aChannel); /** * Helper function that finds the last URI and its transition flags for a From ac97305f97861defd519e4416a257c8d670dc5e0 Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Thu, 30 Sep 2010 16:49:24 -0700 Subject: [PATCH 019/115] Bug 543800 Package chrome style tests into .jar file for Android testing r=ctalbert a=NPOTB --- .../tests/mochitest/events/test_scroll.xul | 4 +-- accessible/tests/mochitest/test_value.html | 2 +- .../content/test/browser_tab_dragdrop2.js | 4 +-- .../tests/browser_privacypane_1.js | 4 +-- .../tests/browser_privacypane_2.js | 4 +-- .../tests/browser_privacypane_3.js | 4 +-- .../tests/browser_privacypane_4.js | 4 +-- .../tests/browser_privacypane_5.js | 4 +-- .../tests/browser_privacypane_6.js | 4 +-- .../tests/browser_privacypane_7.js | 4 +-- .../tests/browser_privacypane_8.js | 4 +-- .../whatwg/postMessage_chrome_helper.html | 35 +++++++++++-------- .../whatwg/test_postMessage_chrome.html | 11 +++++- layout/generic/test/file_bug514732_window.xul | 2 +- layout/generic/test/test_bug514732-2.xul | 3 +- modules/libpr0n/test/browser/head.js | 4 ++- testing/mochitest/chrome-harness.js | 8 ++++- .../tests/chrome/rtlchrome/rtl.manifest | 7 +--- .../test/browser/browser_aboutCrashes.js | 2 +- .../browser/browser_aboutCrashesResubmit.js | 2 +- .../test/browser/browser_bug471404.js | 2 +- xpinstall/tests/browser_auth.js | 4 ++- xpinstall/tests/browser_auth2.js | 4 ++- xpinstall/tests/browser_auth3.js | 4 ++- xpinstall/tests/browser_badhash.js | 4 ++- xpinstall/tests/browser_badhashtype.js | 4 ++- xpinstall/tests/browser_bug540558.js | 4 ++- xpinstall/tests/browser_cancel.js | 4 ++- xpinstall/tests/browser_chrome.js | 4 ++- xpinstall/tests/browser_cookies.js | 5 ++- xpinstall/tests/browser_cookies2.js | 5 ++- xpinstall/tests/browser_cookies3.js | 4 ++- xpinstall/tests/browser_cookies4.js | 4 ++- xpinstall/tests/browser_corrupt.js | 4 ++- xpinstall/tests/browser_empty.js | 4 ++- xpinstall/tests/browser_enabled.js | 4 ++- xpinstall/tests/browser_enabled2.js | 4 ++- xpinstall/tests/browser_enabled3.js | 4 ++- xpinstall/tests/browser_hash.js | 4 ++- xpinstall/tests/browser_installchrome.js | 4 ++- xpinstall/tests/browser_localfile.js | 4 ++- xpinstall/tests/browser_localfile2.js | 4 ++- xpinstall/tests/browser_navigateaway.js | 4 ++- xpinstall/tests/browser_navigateaway2.js | 4 ++- xpinstall/tests/browser_offline.js | 4 ++- xpinstall/tests/browser_opendialog.js | 4 ++- xpinstall/tests/browser_signed_multiple.js | 4 ++- xpinstall/tests/browser_signed_naming.js | 4 ++- xpinstall/tests/browser_signed_tampered.js | 4 ++- xpinstall/tests/browser_signed_trigger.js | 4 ++- xpinstall/tests/browser_signed_untrusted.js | 4 ++- xpinstall/tests/browser_signed_url.js | 4 ++- xpinstall/tests/browser_softwareupdate.js | 4 ++- xpinstall/tests/browser_unsigned_trigger.js | 4 ++- xpinstall/tests/browser_unsigned_url.js | 4 ++- xpinstall/tests/browser_whitelist.js | 4 ++- xpinstall/tests/browser_whitelist2.js | 4 ++- xpinstall/tests/browser_whitelist3.js | 4 ++- xpinstall/tests/browser_whitelist4.js | 4 ++- xpinstall/tests/browser_whitelist5.js | 4 ++- xpinstall/tests/browser_whitelist6.js | 4 ++- xpinstall/tests/harness.js | 12 ++++++- 62 files changed, 201 insertions(+), 91 deletions(-) diff --git a/accessible/tests/mochitest/events/test_scroll.xul b/accessible/tests/mochitest/events/test_scroll.xul index 32e3c907df04..2fec8a662fdc 100644 --- a/accessible/tests/mochitest/events/test_scroll.xul +++ b/accessible/tests/mochitest/events/test_scroll.xul @@ -73,10 +73,10 @@ var jar = getJar(rootDir); if (jar) { var tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - var url = rootDir + "/scroll.html#link1"; + var url = rootDir + "scroll.html#link1"; var tabBrowser = document.getElementById("tabBrowser"); tabBrowser.loadURI(url); } diff --git a/accessible/tests/mochitest/test_value.html b/accessible/tests/mochitest/test_value.html index b648b1f6a4a8..8edb23572516 100644 --- a/accessible/tests/mochitest/test_value.html +++ b/accessible/tests/mochitest/test_value.html @@ -39,7 +39,7 @@ } var rootDir = getRootDirectory(window.location.href); - var href = rootDir.path + "/foo"; + var href = rootDir.path + "foo"; // roles that can't live as nsHTMLLinkAccessibles testValue("aria_menuitem_link", ""); diff --git a/browser/base/content/test/browser_tab_dragdrop2.js b/browser/base/content/test/browser_tab_dragdrop2.js index 461a9ede0f25..21ed9deaa330 100644 --- a/browser/base/content/test/browser_tab_dragdrop2.js +++ b/browser/base/content/test/browser_tab_dragdrop2.js @@ -11,8 +11,8 @@ function test() // Now run the tests again and then close C. // The test results does not matter, all this is just to exercise some code to // catch assertions or crashes. - var uri = "chrome://mochikit/content/browser/" + - "browser/base/content/test/browser_tab_dragdrop2_frame1.xul"; + var chromeroot = getRootDirectory(gTestPath); + var uri = chromeroot + "browser_tab_dragdrop2_frame1.xul"; let window_B = openDialog(location, "_blank", "chrome,all,dialog=no,left=200,top=200,width=200,height=200", uri); window_B.addEventListener("load", function(aEvent) { window_B.removeEventListener("load", arguments.callee, false); diff --git a/browser/components/preferences/tests/browser_privacypane_1.js b/browser/components/preferences/tests/browser_privacypane_1.js index a0cc92b5cf92..0891b8b7e6ad 100644 --- a/browser/components/preferences/tests/browser_privacypane_1.js +++ b/browser/components/preferences/tests/browser_privacypane_1.js @@ -43,9 +43,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_pane_visibility, diff --git a/browser/components/preferences/tests/browser_privacypane_2.js b/browser/components/preferences/tests/browser_privacypane_2.js index f9ac590b9af7..47c6308d3727 100644 --- a/browser/components/preferences/tests/browser_privacypane_2.js +++ b/browser/components/preferences/tests/browser_privacypane_2.js @@ -43,9 +43,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_historymode_retention("remember", undefined), diff --git a/browser/components/preferences/tests/browser_privacypane_3.js b/browser/components/preferences/tests/browser_privacypane_3.js index 215f34758c96..bead9e907cb8 100644 --- a/browser/components/preferences/tests/browser_privacypane_3.js +++ b/browser/components/preferences/tests/browser_privacypane_3.js @@ -42,9 +42,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_custom_retention("rememberHistory", "remember"), diff --git a/browser/components/preferences/tests/browser_privacypane_4.js b/browser/components/preferences/tests/browser_privacypane_4.js index 2fb0bccff640..df46008426eb 100644 --- a/browser/components/preferences/tests/browser_privacypane_4.js +++ b/browser/components/preferences/tests/browser_privacypane_4.js @@ -42,9 +42,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_custom_retention("acceptCookies", "remember"), diff --git a/browser/components/preferences/tests/browser_privacypane_5.js b/browser/components/preferences/tests/browser_privacypane_5.js index 2a99069e3a90..2962c5cb4652 100644 --- a/browser/components/preferences/tests/browser_privacypane_5.js +++ b/browser/components/preferences/tests/browser_privacypane_5.js @@ -42,9 +42,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_locbar_suggestion_retention(-1, undefined), diff --git a/browser/components/preferences/tests/browser_privacypane_6.js b/browser/components/preferences/tests/browser_privacypane_6.js index e2f03eca14c6..7196550c1581 100644 --- a/browser/components/preferences/tests/browser_privacypane_6.js +++ b/browser/components/preferences/tests/browser_privacypane_6.js @@ -42,9 +42,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_privatebrowsing_toggle, diff --git a/browser/components/preferences/tests/browser_privacypane_7.js b/browser/components/preferences/tests/browser_privacypane_7.js index 6da4c02b5f52..3fa4e4877a54 100644 --- a/browser/components/preferences/tests/browser_privacypane_7.js +++ b/browser/components/preferences/tests/browser_privacypane_7.js @@ -42,9 +42,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_privatebrowsing_ui, diff --git a/browser/components/preferences/tests/browser_privacypane_8.js b/browser/components/preferences/tests/browser_privacypane_8.js index 40adbeedb154..3b8249ccdcb6 100644 --- a/browser/components/preferences/tests/browser_privacypane_8.js +++ b/browser/components/preferences/tests/browser_privacypane_8.js @@ -41,9 +41,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ // history mode should be initialized to remember diff --git a/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html b/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html index a6232c7cee7b..daf6e32f9624 100644 --- a/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html +++ b/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html @@ -3,25 +3,32 @@ postMessage chrome message receiver diff --git a/modules/libpr0n/test/browser/head.js b/modules/libpr0n/test/browser/head.js index ac4d525c4c39..528495f6e959 100644 --- a/modules/libpr0n/test/browser/head.js +++ b/modules/libpr0n/test/browser/head.js @@ -5,7 +5,9 @@ const Cu = Components.utils; const RELATIVE_DIR = "modules/libpr0n/test/browser/"; const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR; const TESTROOT2 = "http://example.org/browser/" + RELATIVE_DIR; -const CHROMEROOT = "chrome://mochikit/content/browser/" + RELATIVE_DIR; + +var chrome_root = getRootDirectory(gTestPath); +const CHROMEROOT = chrome_root; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); diff --git a/testing/mochitest/chrome-harness.js b/testing/mochitest/chrome-harness.js index 8beee7f5c364..e01a81008dc3 100644 --- a/testing/mochitest/chrome-harness.js +++ b/testing/mochitest/chrome-harness.js @@ -234,8 +234,14 @@ function getRootDirectory(path, chromeURI) { chromeURI = getChromeURI(path); } var myURL = chromeURI.QueryInterface(Components.interfaces.nsIURL); + var mydir = myURL.directory; - return chromeURI.prePath + myURL.directory; + if (mydir.match('/$') != '/') + { + mydir += '/'; + } + + return chromeURI.prePath + mydir; } //used by tests to determine their directory based off window.location.path diff --git a/toolkit/content/tests/chrome/rtlchrome/rtl.manifest b/toolkit/content/tests/chrome/rtlchrome/rtl.manifest index df898d0f58fc..a4cc6929be4a 100644 --- a/toolkit/content/tests/chrome/rtlchrome/rtl.manifest +++ b/toolkit/content/tests/chrome/rtlchrome/rtl.manifest @@ -1,10 +1,5 @@ -content rtlchrome /content +content rtlchrome / # Override intl.css with our own CSS file override chrome://global/locale/intl.css chrome://rtlchrome/rtl.css override chrome://global/locale/global.dtd chrome://rtlchrome/rtl.dtd - - -# Override intl.css with our own CSS file -override chrome://global/locale/intl.css chrome://mochikit/content/chrome/toolkit/content/tests/chrome/rtlchrome/rtl.css -override chrome://global/locale/global.dtd chrome://mochikit/content/chrome/toolkit/content/tests/chrome/rtlchrome/rtl.dtd diff --git a/toolkit/crashreporter/test/browser/browser_aboutCrashes.js b/toolkit/crashreporter/test/browser/browser_aboutCrashes.js index 267ff9334305..984e5759fdac 100644 --- a/toolkit/crashreporter/test/browser/browser_aboutCrashes.js +++ b/toolkit/crashreporter/test/browser/browser_aboutCrashes.js @@ -3,7 +3,7 @@ var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); var rootDir = getRootDirectory(gTestPath); -scriptLoader.loadSubScript(rootDir + "/aboutcrashes_utils.js", this); +scriptLoader.loadSubScript(rootDir + "aboutcrashes_utils.js", this); function check_crash_list(tab, crashes) { let doc = gBrowser.getBrowserForTab(tab).contentDocument; diff --git a/toolkit/crashreporter/test/browser/browser_aboutCrashesResubmit.js b/toolkit/crashreporter/test/browser/browser_aboutCrashesResubmit.js index c57f4ac43ab3..cc64564e8c2d 100644 --- a/toolkit/crashreporter/test/browser/browser_aboutCrashesResubmit.js +++ b/toolkit/crashreporter/test/browser/browser_aboutCrashesResubmit.js @@ -3,7 +3,7 @@ var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); var rootDir = getRootDirectory(gTestPath); -scriptLoader.loadSubScript(rootDir + "/aboutcrashes_utils.js", this); +scriptLoader.loadSubScript(rootDir + "aboutcrashes_utils.js", this); function cleanup_and_finish() { try { diff --git a/toolkit/crashreporter/test/browser/browser_bug471404.js b/toolkit/crashreporter/test/browser/browser_bug471404.js index d84285a67e03..d6dd370bd057 100644 --- a/toolkit/crashreporter/test/browser/browser_bug471404.js +++ b/toolkit/crashreporter/test/browser/browser_bug471404.js @@ -3,7 +3,7 @@ var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); var rootDir = getRootDirectory(gTestPath); -scriptLoader.loadSubScript(rootDir + "/aboutcrashes_utils.js", this); +scriptLoader.loadSubScript(rootDir + "aboutcrashes_utils.js", this); function check_clear_visible(tab, aVisible) { let doc = gBrowser.getBrowserForTab(tab).contentDocument; diff --git a/xpinstall/tests/browser_auth.js b/xpinstall/tests/browser_auth.js index 740e114bb8ab..bf25cc32e085 100644 --- a/xpinstall/tests/browser_auth.js +++ b/xpinstall/tests/browser_auth.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an install succeeds when authentication is required diff --git a/xpinstall/tests/browser_auth2.js b/xpinstall/tests/browser_auth2.js index 8872649149eb..6a88e62cdc18 100644 --- a/xpinstall/tests/browser_auth2.js +++ b/xpinstall/tests/browser_auth2.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an install fails when authentication is required and bad diff --git a/xpinstall/tests/browser_auth3.js b/xpinstall/tests/browser_auth3.js index 4cfe8252a695..02f1c9e3c954 100644 --- a/xpinstall/tests/browser_auth3.js +++ b/xpinstall/tests/browser_auth3.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an install fails when authentication is required and it is diff --git a/xpinstall/tests/browser_badhash.js b/xpinstall/tests/browser_badhash.js index d1f3789f837f..3ee779933b11 100644 --- a/xpinstall/tests/browser_badhash.js +++ b/xpinstall/tests/browser_badhash.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an install fails when an invalid hash is included diff --git a/xpinstall/tests/browser_badhashtype.js b/xpinstall/tests/browser_badhashtype.js index b514d40a4dee..418ec29c53a2 100644 --- a/xpinstall/tests/browser_badhashtype.js +++ b/xpinstall/tests/browser_badhashtype.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an install fails when an unknown hash type is included diff --git a/xpinstall/tests/browser_bug540558.js b/xpinstall/tests/browser_bug540558.js index c7f6594cb3a9..0048457b0d63 100644 --- a/xpinstall/tests/browser_bug540558.js +++ b/xpinstall/tests/browser_bug540558.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests that calling InstallTrigger.installChrome works diff --git a/xpinstall/tests/browser_cancel.js b/xpinstall/tests/browser_cancel.js index 1a6ef4a60258..54d633332231 100644 --- a/xpinstall/tests/browser_cancel.js +++ b/xpinstall/tests/browser_cancel.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests that cancelling an in progress download works. diff --git a/xpinstall/tests/browser_chrome.js b/xpinstall/tests/browser_chrome.js index c23258c1f639..db463edfdac8 100644 --- a/xpinstall/tests/browser_chrome.js +++ b/xpinstall/tests/browser_chrome.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests that starting a download from chrome works and bypasses the whitelist diff --git a/xpinstall/tests/browser_cookies.js b/xpinstall/tests/browser_cookies.js index b45ba4202e1f..5235fd05abfb 100644 --- a/xpinstall/tests/browser_cookies.js +++ b/xpinstall/tests/browser_cookies.js @@ -1,7 +1,10 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test that an install that requires cookies to be sent fails when no cookies diff --git a/xpinstall/tests/browser_cookies2.js b/xpinstall/tests/browser_cookies2.js index bb1b8487dee0..4e3b28490b22 100644 --- a/xpinstall/tests/browser_cookies2.js +++ b/xpinstall/tests/browser_cookies2.js @@ -1,7 +1,10 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test that an install that requires cookies to be sent succeeds when cookies diff --git a/xpinstall/tests/browser_cookies3.js b/xpinstall/tests/browser_cookies3.js index dbf6467fbe25..0b11729a4db0 100644 --- a/xpinstall/tests/browser_cookies3.js +++ b/xpinstall/tests/browser_cookies3.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test that an install that requires cookies to be sent succeeds when cookies diff --git a/xpinstall/tests/browser_cookies4.js b/xpinstall/tests/browser_cookies4.js index 7412c88e1fab..c5dec917dda8 100644 --- a/xpinstall/tests/browser_cookies4.js +++ b/xpinstall/tests/browser_cookies4.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test that an install that requires cookies to be sent fails when cookies diff --git a/xpinstall/tests/browser_corrupt.js b/xpinstall/tests/browser_corrupt.js index 5b1bb3623955..5e344fa1d590 100644 --- a/xpinstall/tests/browser_corrupt.js +++ b/xpinstall/tests/browser_corrupt.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an install fails when the xpi is corrupt. diff --git a/xpinstall/tests/browser_empty.js b/xpinstall/tests/browser_empty.js index 9ddd3aef9284..02bde7a9d58c 100644 --- a/xpinstall/tests/browser_empty.js +++ b/xpinstall/tests/browser_empty.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an install fails when there is no install script present. diff --git a/xpinstall/tests/browser_enabled.js b/xpinstall/tests/browser_enabled.js index 98831487a4eb..75866a84accc 100644 --- a/xpinstall/tests/browser_enabled.js +++ b/xpinstall/tests/browser_enabled.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an InstallTrigger.enabled is working diff --git a/xpinstall/tests/browser_enabled2.js b/xpinstall/tests/browser_enabled2.js index 11fb9d4a58f0..81c5e1c13d11 100644 --- a/xpinstall/tests/browser_enabled2.js +++ b/xpinstall/tests/browser_enabled2.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an InstallTrigger.enabled is working diff --git a/xpinstall/tests/browser_enabled3.js b/xpinstall/tests/browser_enabled3.js index 7a0844049be8..022acee9a8f1 100644 --- a/xpinstall/tests/browser_enabled3.js +++ b/xpinstall/tests/browser_enabled3.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an InstallTrigger.install call fails when xpinstall is disabled diff --git a/xpinstall/tests/browser_hash.js b/xpinstall/tests/browser_hash.js index 05658b60787d..cf7f662fbd36 100644 --- a/xpinstall/tests/browser_hash.js +++ b/xpinstall/tests/browser_hash.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an install succeeds when a valid hash is included diff --git a/xpinstall/tests/browser_installchrome.js b/xpinstall/tests/browser_installchrome.js index 12d6f98e6a78..6d8d7b293e3a 100644 --- a/xpinstall/tests/browser_installchrome.js +++ b/xpinstall/tests/browser_installchrome.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests that calling InstallTrigger.installChrome works diff --git a/xpinstall/tests/browser_localfile.js b/xpinstall/tests/browser_localfile.js index d7910b0dd82f..fdfa6ed40bf8 100644 --- a/xpinstall/tests/browser_localfile.js +++ b/xpinstall/tests/browser_localfile.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing an local file works when loading the url diff --git a/xpinstall/tests/browser_localfile2.js b/xpinstall/tests/browser_localfile2.js index 2c3fe584b637..91f5cb6b696b 100644 --- a/xpinstall/tests/browser_localfile2.js +++ b/xpinstall/tests/browser_localfile2.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an install fails if the url is a local file when requested from diff --git a/xpinstall/tests/browser_navigateaway.js b/xpinstall/tests/browser_navigateaway.js index d078e03c66e3..59885cba829f 100644 --- a/xpinstall/tests/browser_navigateaway.js +++ b/xpinstall/tests/browser_navigateaway.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests that navigating away from the initiating page during the install diff --git a/xpinstall/tests/browser_navigateaway2.js b/xpinstall/tests/browser_navigateaway2.js index a7c3c67915da..bd1814c9f67b 100644 --- a/xpinstall/tests/browser_navigateaway2.js +++ b/xpinstall/tests/browser_navigateaway2.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests that closing the initiating page during the install doesn't break the diff --git a/xpinstall/tests/browser_offline.js b/xpinstall/tests/browser_offline.js index 845aaf64f191..b51a19865f14 100644 --- a/xpinstall/tests/browser_offline.js +++ b/xpinstall/tests/browser_offline.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests that going offline cancels an in progress download. diff --git a/xpinstall/tests/browser_opendialog.js b/xpinstall/tests/browser_opendialog.js index 90c4d2e9ca94..6f2b515cb016 100644 --- a/xpinstall/tests/browser_opendialog.js +++ b/xpinstall/tests/browser_opendialog.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Test whether an install succeeds when the progress dialog is already open. diff --git a/xpinstall/tests/browser_signed_multiple.js b/xpinstall/tests/browser_signed_multiple.js index 155ed8a1ed3b..2a0e6517723a 100644 --- a/xpinstall/tests/browser_signed_multiple.js +++ b/xpinstall/tests/browser_signed_multiple.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing two signed add-ons in the same trigger works. diff --git a/xpinstall/tests/browser_signed_naming.js b/xpinstall/tests/browser_signed_naming.js index 8dccc724d6e3..aa00c56f9f05 100644 --- a/xpinstall/tests/browser_signed_naming.js +++ b/xpinstall/tests/browser_signed_naming.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests that the correct signer is presented for combinations of O and CN present. diff --git a/xpinstall/tests/browser_signed_tampered.js b/xpinstall/tests/browser_signed_tampered.js index ff9bece2eb1a..9a852180dfa5 100644 --- a/xpinstall/tests/browser_signed_tampered.js +++ b/xpinstall/tests/browser_signed_tampered.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing a signed add-on that has been tampered with after signing. diff --git a/xpinstall/tests/browser_signed_trigger.js b/xpinstall/tests/browser_signed_trigger.js index af2abd89fa82..150a7808e75d 100644 --- a/xpinstall/tests/browser_signed_trigger.js +++ b/xpinstall/tests/browser_signed_trigger.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing an signed add-on through an InstallTrigger call in web diff --git a/xpinstall/tests/browser_signed_untrusted.js b/xpinstall/tests/browser_signed_untrusted.js index dee923fe88c8..c0bdbfef3553 100644 --- a/xpinstall/tests/browser_signed_untrusted.js +++ b/xpinstall/tests/browser_signed_untrusted.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing an add-on signed by an untrusted certificate through an diff --git a/xpinstall/tests/browser_signed_url.js b/xpinstall/tests/browser_signed_url.js index 4359f4001aec..231d098860eb 100644 --- a/xpinstall/tests/browser_signed_url.js +++ b/xpinstall/tests/browser_signed_url.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing an signed add-on by navigating directly to the url diff --git a/xpinstall/tests/browser_softwareupdate.js b/xpinstall/tests/browser_softwareupdate.js index abe7d9a7941d..041b6f40d032 100644 --- a/xpinstall/tests/browser_softwareupdate.js +++ b/xpinstall/tests/browser_softwareupdate.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests that calling InstallTrigger.startSoftwareUpdate works diff --git a/xpinstall/tests/browser_unsigned_trigger.js b/xpinstall/tests/browser_unsigned_trigger.js index e6aa17e03e7d..b0086f52fbd5 100644 --- a/xpinstall/tests/browser_unsigned_trigger.js +++ b/xpinstall/tests/browser_unsigned_trigger.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing an unsigned add-on through an InstallTrigger call in web diff --git a/xpinstall/tests/browser_unsigned_url.js b/xpinstall/tests/browser_unsigned_url.js index ff38bc48a706..a71b8cb2b8bf 100644 --- a/xpinstall/tests/browser_unsigned_url.js +++ b/xpinstall/tests/browser_unsigned_url.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing an unsigned add-on by navigating directly to the url diff --git a/xpinstall/tests/browser_whitelist.js b/xpinstall/tests/browser_whitelist.js index 7d2d3d99ccba..0467bc067af5 100644 --- a/xpinstall/tests/browser_whitelist.js +++ b/xpinstall/tests/browser_whitelist.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing an unsigned add-on through an InstallTrigger call in web diff --git a/xpinstall/tests/browser_whitelist2.js b/xpinstall/tests/browser_whitelist2.js index a36f8160270e..170ede59ba97 100644 --- a/xpinstall/tests/browser_whitelist2.js +++ b/xpinstall/tests/browser_whitelist2.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing an unsigned add-on through an InstallTrigger call in web diff --git a/xpinstall/tests/browser_whitelist3.js b/xpinstall/tests/browser_whitelist3.js index 201a980832a9..fef29d90dbb4 100644 --- a/xpinstall/tests/browser_whitelist3.js +++ b/xpinstall/tests/browser_whitelist3.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing an unsigned add-on through a navigation. Should not be diff --git a/xpinstall/tests/browser_whitelist4.js b/xpinstall/tests/browser_whitelist4.js index 97e2d7b8113c..08ee9e7e200f 100644 --- a/xpinstall/tests/browser_whitelist4.js +++ b/xpinstall/tests/browser_whitelist4.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing an unsigned add-on through a navigation. Should be diff --git a/xpinstall/tests/browser_whitelist5.js b/xpinstall/tests/browser_whitelist5.js index 17f48fb1bf80..e9fb58234cf2 100644 --- a/xpinstall/tests/browser_whitelist5.js +++ b/xpinstall/tests/browser_whitelist5.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing an unsigned add-on through a startSoftwareUpdate call in web diff --git a/xpinstall/tests/browser_whitelist6.js b/xpinstall/tests/browser_whitelist6.js index e457c68e02c7..1b5592ddbafc 100644 --- a/xpinstall/tests/browser_whitelist6.js +++ b/xpinstall/tests/browser_whitelist6.js @@ -1,7 +1,9 @@ // Load in the test harness var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader); -scriptLoader.loadSubScript("chrome://mochikit/content/browser/xpinstall/tests/harness.js", this); + +var rootDir = getRootDirectory(window.location.href); +scriptLoader.loadSubScript(rootDir + "harness.js", this); // ---------------------------------------------------------------------------- // Tests installing an unsigned add-on through an installChrome call in web diff --git a/xpinstall/tests/harness.js b/xpinstall/tests/harness.js index f154ed139bec..f958afccca87 100644 --- a/xpinstall/tests/harness.js +++ b/xpinstall/tests/harness.js @@ -1,10 +1,20 @@ const TESTROOT = "http://example.com/browser/xpinstall/tests/"; const TESTROOT2 = "http://example.org/browser/xpinstall/tests/"; -const CHROMEROOT = "chrome://mochikit/content/browser/xpinstall/tests/" const XPINSTALL_URL = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul"; const PROMPT_URL = "chrome://global/content/commonDialog.xul"; const ADDONS_URL = "chrome://mozapps/content/extensions/extensions.xul"; +var rootDir = getRootDirectory(gTestPath); +var path = rootDir.split('/'); +var chromeName = path[0] + '//' + path[2]; +var croot = chromeName + "/content/browser/xpinstall/tests/"; +var jar = getJar(croot); +if (jar) { + var tmpdir = extractJarToTmp(jar); + croot = 'file://' + tmpdir.path + '/'; +} +const CHROMEROOT = croot; + /** * This is a test harness designed to handle responding to UI during the process * of installing an XPI. A test can set callbacks to hear about specific parts From 458c94b78fb961a4faae7e83f41d8732a6fd7517 Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Thu, 30 Sep 2010 16:50:24 -0700 Subject: [PATCH 020/115] Bug 543800 Package chrome style tests into .jar file for Android testing r=ted a=NPOTB --- Makefile.in | 3 - build/macosx/universal/flight.mk | 4 +- testing/mochitest/Makefile.in | 35 ++++++ testing/mochitest/browser-harness.xul | 20 +++- testing/mochitest/chrome-harness.js | 17 +-- testing/mochitest/harness-overlay.xul | 113 ++++++++---------- testing/mochitest/install.rdf | 23 ++++ testing/mochitest/jar.mn | 39 ++++++ testing/mochitest/runtests.py.in | 58 ++++++--- .../mochitest/tests/SimpleTest/Makefile.in | 1 + testing/testsuite-targets.mk | 7 +- 11 files changed, 226 insertions(+), 94 deletions(-) create mode 100644 testing/mochitest/install.rdf create mode 100644 testing/mochitest/jar.mn diff --git a/Makefile.in b/Makefile.in index 56714333347d..e38377c6951a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -120,9 +120,6 @@ export:: ifdef ENABLE_TESTS # Additional makefile targets to call automated test suites include $(topsrcdir)/testing/testsuite-targets.mk -else -# OS X Universal builds will want to call this, so stub it out -package-tests: endif include $(topsrcdir)/config/rules.mk diff --git a/build/macosx/universal/flight.mk b/build/macosx/universal/flight.mk index 3b7619218972..4016eac86b71 100644 --- a/build/macosx/universal/flight.mk +++ b/build/macosx/universal/flight.mk @@ -121,8 +121,8 @@ postflight_all: # A universal .dmg can now be produced by making in either architecture's # INSTALLER_DIR. # Now, repeat the process for the test package. - $(MAKE) -C $(OBJDIR_ARCH_1) UNIVERSAL_BINARY= package-tests - $(MAKE) -C $(OBJDIR_ARCH_2) UNIVERSAL_BINARY= package-tests + $(MAKE) -C $(OBJDIR_ARCH_1) UNIVERSAL_BINARY= CHROME_JAR= package-tests + $(MAKE) -C $(OBJDIR_ARCH_2) UNIVERSAL_BINARY= CHROME_JAR= package-tests rm -rf $(DIST_UNI)/test-package-stage # automation.py differs because it hardcodes a path to # dist/bin. It doesn't matter which one we use. diff --git a/testing/mochitest/Makefile.in b/testing/mochitest/Makefile.in index 9505566ab54f..8e3ce0721664 100644 --- a/testing/mochitest/Makefile.in +++ b/testing/mochitest/Makefile.in @@ -51,6 +51,19 @@ DIRS = MochiKit \ ssltunnel \ $(NULL) + +NO_JS_MANIFEST = 1 +MOZ_CHROME_FILE_FORMAT = jar +DIST_FILES = install.rdf + +# Used in install.rdf +USE_EXTENSION_MANIFEST = 1 + +XPI_NAME = mochijar + +# we turn this off for UNIVERSAL_BINARY +CHROME_JAR = 1 + include $(topsrcdir)/config/rules.mk # We're installing to _tests/testing/mochitest, so this is the depth # necessary for relative objdir paths. @@ -108,6 +121,9 @@ _HANDSHAKE_FILES = \ _DEST_DIR = $(DEPTH)/_tests/$(relativesrcdir) +libs:: + (cd $(DIST)/xpi-stage && tar $(TAR_CREATE_FLAGS) - mochijar) | (cd $(_DEST_DIR) && tar -xf -) + libs:: $(_PYWEBSOCKET_FILES) $(INSTALL) $(foreach f,$^,"$f") $(_DEST_DIR)/pywebsocket @@ -175,6 +191,25 @@ endif PKG_STAGE = $(DIST)/test-package-stage DIST_BIN = $(DIST)/bin +PKG_CHROMEJAR = $(PKG_STAGE)/mochitest/content/ + +ifdef CHROME_JAR +stage-chromejar: + $(NSINSTALL) -D $(PKG_CHROMEJAR) + cp -RL $(DEPTH)/_tests/testing/mochitest/browser $(PKG_CHROMEJAR) + cp -RL $(DEPTH)/_tests/testing/mochitest/chrome $(PKG_CHROMEJAR) +ifdef ACCESSIBILITY + cp -RL $(DEPTH)/_tests/testing/mochitest/a11y $(PKG_CHROMEJAR) +endif + @(cd $(PKG_STAGE)/mochitest && zip -r tests.jar content/) + @(rm -rf $(PKG_CHROMEJAR)) + +stage-package: stage-chromejar +endif + +$(_DEST_DIR): + $(NSINSTALL) -D $@ + stage-package: $(NSINSTALL) -D $(PKG_STAGE)/mochitest && $(NSINSTALL) -D $(PKG_STAGE)/bin/plugins @(cd $(DEPTH)/_tests/testing/mochitest/ && tar $(TAR_CREATE_FLAGS) - *) | (cd $(PKG_STAGE)/mochitest && tar -xf -) diff --git a/testing/mochitest/browser-harness.xul b/testing/mochitest/browser-harness.xul index ced53fd97713..fe4369a117b2 100644 --- a/testing/mochitest/browser-harness.xul +++ b/testing/mochitest/browser-harness.xul @@ -208,15 +208,31 @@ // Returns an array of browserTest objects for all the selected tests function listTests() { + var baseURL = 'chrome://mochitests/content'; + var testsURI = Components.classes["@mozilla.org/file/directory_service;1"] + .getService(Components.interfaces.nsIProperties) + .get("ProfD", Components.interfaces.nsILocalFile); + testsURI.append("tests.manifest"); + var ioSvc = Components.classes["@mozilla.org/network/io-service;1"]. + getService(Components.interfaces.nsIIOService); + var manifestFile = ioSvc.newFileURI(testsURI) + .QueryInterface(Components.interfaces.nsIFileURL).file; + + Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar). + autoRegister(manifestFile); // load server.js in so we can share template functions var scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]. getService(Ci.mozIJSSubScriptLoader); var srvScope = {}; - var baseURL = 'chrome://mochikit/content'; scriptLoader.loadSubScript('chrome://mochikit/content/server.js', srvScope); - var [links, singleTestPath] = getFileListing(baseURL, gConfig.testPath, "browser", srvScope); + var jar = getJar(baseURL); + if (jar != null) { + var [links, singleTestPath] = getMochitestJarListing(baseURL, gConfig.testPath, "browser"); + } else { + var [links, singleTestPath] = getFileListing(baseURL, gConfig.testPath, "browser", srvScope); + } var fileNames = []; var fileNameRegexp = /browser_.+\.js$/; diff --git a/testing/mochitest/chrome-harness.js b/testing/mochitest/chrome-harness.js index e01a81008dc3..70e820e9fbd6 100644 --- a/testing/mochitest/chrome-harness.js +++ b/testing/mochitest/chrome-harness.js @@ -108,6 +108,9 @@ function getMochitestJarListing(basePath, testPath, dir) var fileName = fileHandler.getFileFromURLSpec(getResolvedURI(basePath).JARFile.spec); zReader.open(fileName); //hardcoded 'content' as that is the root dir in the mochikit.jar file + var idx = basePath.indexOf('/content'); + var basePath = basePath.slice(0, idx); + var base = "content/" + dir + "/"; var singleTestPath; @@ -119,7 +122,7 @@ function getMochitestJarListing(basePath, testPath, dir) if (pathEntry.isDirectory) { base = pathToCheck; } else { - singleTestPath = '/' + base + testPath; + singleTestPath = basePath + '/' + base + testPath; var singleObject = {}; singleObject[singleTestPath] = true; return [singleObject, singleTestPath]; @@ -129,7 +132,7 @@ function getMochitestJarListing(basePath, testPath, dir) base = pathToCheck + "/"; } } - var [links, count] = zList(base, zReader, true); + var [links, count] = zList(base, zReader, basePath, true); return [links, null]; } @@ -143,7 +146,7 @@ function getMochitestJarListing(basePath, testPath, dir) * returns: * [json object of {dir:{subdir:{file:true, file:true, ...}}}, count of tests] */ -function zList(base, zReader, recurse) { +function zList(base, zReader, baseJarName, recurse) { var dirs = zReader.findEntries(base + "*"); var links = {}; var count = 0; @@ -162,12 +165,12 @@ function zList(base, zReader, recurse) { var myFile = fileArray[i]; if (myFile.substr(-1) === '/' && recurse) { var childCount = 0; - [links[myFile], childCount] = zList(myFile, zReader, recurse); + [links[myFile], childCount] = zList(myFile, zReader, baseJarName, recurse); count += childCount; } else { if (myFile.indexOf("SimpleTest") == -1) { //we add the '/' so we don't try to run content/content/chrome - links['/' + myFile] = true; + links[baseJarName + '/' + myFile] = true; } } } @@ -283,7 +286,7 @@ function extractJarToTmp(jar) { tmpdir.append("mochikit.tmp"); // parseInt is used because octal escape sequences cause deprecation warnings // in strict mode (which is turned on in debug builds) - tmpdir.createUnique(Components.interfaces.nsIFile.DIRECTORY_TYPE, parseInt("0777", 8)); + tmpdir.createUnique(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777); var zReader = Components.classes["@mozilla.org/libjar/zip-reader;1"]. createInstance(Components.interfaces.nsIZipReader); @@ -311,7 +314,7 @@ function extractJarToTmp(jar) { var targetDir = buildRelativePath(dirs.getNext(), tmpdir, filepath); // parseInt is used because octal escape sequences cause deprecation warnings // in strict mode (which is turned on in debug builds) - targetDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, parseInt("0777", 8)); + targetDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777); } //now do the files diff --git a/testing/mochitest/harness-overlay.xul b/testing/mochitest/harness-overlay.xul index 49bcd9904f06..57fc6d5da52e 100644 --- a/testing/mochitest/harness-overlay.xul +++ b/testing/mochitest/harness-overlay.xul @@ -17,76 +17,59 @@ src="chrome://mochikit/content/tests/SimpleTest/quit.js" /> - - - - - -Mozilla Bug 583288 -

- - -
- - - - - - - - - -
-
-
-
-
-
-
-
- -
- -
-
- -
-
- -
-
- -
-
-
-
-
- - diff --git a/content/html/content/test/test_bug583288-2.html b/content/html/content/test/test_bug583288-2.html deleted file mode 100644 index d7a0592c6823..000000000000 --- a/content/html/content/test/test_bug583288-2.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - - Test for Bug 583288 - - - - - - -Mozilla Bug 583288 -

- - -
- - - - - -
-
-
-
-
-
-
-
-
-
-
-
- - diff --git a/content/html/content/test/test_bug583288-3.html b/content/html/content/test/test_bug583288-3.html deleted file mode 100644 index f9779d7c71a7..000000000000 --- a/content/html/content/test/test_bug583288-3.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - - Test for Bug 583288 - - - - - - -Mozilla Bug 583288 -

- - -
- - - - - -
-
-
-
-
-
-
-
-
-
-
-
- - diff --git a/content/html/content/test/test_bug585508.html b/content/html/content/test/test_bug585508.html index 7d5eac307bcf..adf3c9bc5c49 100644 --- a/content/html/content/test/test_bug585508.html +++ b/content/html/content/test/test_bug585508.html @@ -30,9 +30,11 @@ var methodTestData = [ // Default value. [ "get" ], // Valid values. - [ "get", "post", "put", "delete" ], + [ "get", "post" ], // Invalid values. [ "", " ", "foo" ], + // TODO values, see bug 583289 and bug 583288. + [ "delete", "put" ], ]; function checkAttribute(form, attrName, idlName, data) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 3570009af1b0..c49ea13dcc2d 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -1412,8 +1412,7 @@ nsDocShell::LoadURI(nsIURI * aURI, nsnull, // No SHEntry aFirstParty, nsnull, // No nsIDocShell - nsnull, // No nsIRequest - nsnull); // Use default HTTP method + nsnull); // No nsIRequest } NS_IMETHODIMP @@ -4096,7 +4095,7 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL, return InternalLoad(errorPageURI, nsnull, nsnull, INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nsnull, nsnull, nsnull, nsnull, LOAD_ERROR_PAGE, - nsnull, PR_TRUE, nsnull, nsnull, nsnull); + nsnull, PR_TRUE, nsnull, nsnull); } @@ -4160,8 +4159,7 @@ nsDocShell::Reload(PRUint32 aReloadFlags) nsnull, // No SHEntry PR_TRUE, nsnull, // No nsIDocShell - nsnull, // No nsIRequest - nsnull); // Use default HTTP method + nsnull); // No nsIRequest } @@ -5871,7 +5869,7 @@ nsDocShell::OnLocationChange(nsIWebProgress * aProgress, return NS_OK; } -nsresult +void nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel, nsIChannel* aNewChannel, PRUint32 aRedirectFlags, @@ -5880,44 +5878,13 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel, NS_ASSERTION(aStateFlags & STATE_REDIRECTING, "Calling OnRedirectStateChange when there is no redirect"); if (!(aStateFlags & STATE_IS_DOCUMENT)) - return NS_OK; // not a toplevel document + return; // not a toplevel document nsCOMPtr oldURI, newURI; aOldChannel->GetURI(getter_AddRefs(oldURI)); aNewChannel->GetURI(getter_AddRefs(newURI)); if (!oldURI || !newURI) { - return NS_OK; - } - - // HTTP channel with unsafe methods should not be redirected to a cross-domain. - if (!ChannelIsSafeMethod(aNewChannel)) { - // This code is very similar to the code of nsSameOriginChecker in - // nsContentUtils but we can't use nsSameOriginChecker because it - // needs to use a channel callback (which we already use). - // If nsSameOriginChecker happens to not use a channel callback - // anymore, this code would be a good candidate for refactoring. - nsCOMPtr oldPrincipal; - nsresult rv; - - nsCOMPtr secMan = - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - - rv = secMan->GetChannelPrincipal(aOldChannel, - getter_AddRefs(oldPrincipal)); - NS_ENSURE_SUCCESS(rv, NS_OK); - - NS_ASSERTION(oldPrincipal, "oldPrincipal should not be null!"); - - nsCOMPtr newOriginalURI; - aNewChannel->GetOriginalURI(getter_AddRefs(newOriginalURI)); - - rv = oldPrincipal->CheckMayLoad(newURI, PR_FALSE); - if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) { - rv = oldPrincipal->CheckMayLoad(newOriginalURI, PR_FALSE); - } - - // The requested tried to be redirected, we have to cancel it. - NS_ENSURE_SUCCESS(rv, rv); + return; } // Below a URI visit is saved (see AddURIVisit method doc). @@ -5968,8 +5935,6 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel, mLoadType = LOAD_NORMAL_REPLACE; SetHistoryEntry(&mLSHE, nsnull); } - - return NS_OK; } NS_IMETHODIMP @@ -6341,8 +6306,7 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress, nsnull, // No SHEntry PR_TRUE, // first party site nsnull, // No nsIDocShell - nsnull, // No nsIRequest - nsnull); // Use default HTTP method + nsnull); // No nsIRequest } else { DisplayLoadError(aStatus, url, nsnull, aChannel); @@ -7786,7 +7750,7 @@ public: return mDocShell->InternalLoad(mURI, mReferrer, mOwner, mFlags, nsnull, mTypeHint.get(), mPostData, mHeadersData, mLoadType, - mSHEntry, mFirstParty, nsnull, nsnull, nsnull); + mSHEntry, mFirstParty, nsnull, nsnull); } private: @@ -7820,8 +7784,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, nsISHEntry * aSHEntry, PRBool aFirstParty, nsIDocShell** aDocShell, - nsIRequest** aRequest, - const char* aHttpMethod) + nsIRequest** aRequest) { nsresult rv = NS_OK; @@ -8023,8 +7986,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, aSHEntry, aFirstParty, aDocShell, - aRequest, - aHttpMethod); + aRequest); if (rv == NS_ERROR_NO_CONTENT) { // XXXbz except we never reach this code! if (isNewWindow) { @@ -8459,8 +8421,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, aDocShell, getter_AddRefs(req), (aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0, (aFlags & INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER) != 0, - (aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES) != 0, - aHttpMethod); + (aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES) != 0); if (req && aRequest) NS_ADDREF(*aRequest = req); @@ -8541,8 +8502,7 @@ nsDocShell::DoURILoad(nsIURI * aURI, nsIRequest ** aRequest, PRBool aIsNewWindowTarget, PRBool aBypassClassifier, - PRBool aForceAllowCookies, - const char* aHttpMethod) + PRBool aForceAllowCookies) { nsresult rv; nsCOMPtr uriLoader; @@ -8725,20 +8685,6 @@ nsDocShell::DoURILoad(nsIURI * aURI, // Referrer is currenly only set for link clicks here. httpChannel->SetReferrer(aReferrerURI); } - - // If a specific HTTP method has been requested, set it. - if (aHttpMethod) { - // Tell the cache it _has_ to open a cache entry. - PRUint32 loadFlags; - if (NS_SUCCEEDED(channel->GetLoadFlags(&loadFlags))) { - channel->SetLoadFlags(loadFlags | nsICachingChannel::FORCE_OPEN_CACHE_ENTRY); - } - - // The method name have to be correct. - // Otherwise SetRequestMethod will return a failure. - rv = httpChannel->SetRequestMethod(nsDependentCString(aHttpMethod)); - NS_ENSURE_SUCCESS(rv, rv); - } } // // Set the owner of the channel, but only for channels that can't @@ -8789,14 +8735,6 @@ nsDocShell::DoURILoad(nsIURI * aURI, } } - // If a specific HTTP channel has been set and it is not a safe method, - // we should prevent cross-origin requests. - if (aHttpMethod && ownerPrincipal && !ChannelIsSafeMethod(channel)) { - if (NS_FAILED(ownerPrincipal->CheckMayLoad(aURI, PR_FALSE))) { - return NS_OK; - } - } - nsCOMPtr scriptChannel = do_QueryInterface(channel); if (scriptChannel) { // Allow execution against our context if the principals match @@ -10008,8 +9946,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, PRUint32 aLoadType) aEntry, // SHEntry PR_TRUE, nsnull, // No nsIDocShell - nsnull, // No nsIRequest - nsnull); // Use default HTTP method + nsnull); // No nsIRequest return rv; } @@ -10422,7 +10359,6 @@ NS_IMETHODIMP nsDocShell::MakeEditable(PRBool inWaitForUriLoad) return mEditorData->MakeEditable(inWaitForUriLoad); } -/* static */ bool nsDocShell::ChannelIsPost(nsIChannel* aChannel) { @@ -10436,21 +10372,6 @@ nsDocShell::ChannelIsPost(nsIChannel* aChannel) return method.Equals("POST"); } -/* static */ -bool -nsDocShell::ChannelIsSafeMethod(nsIChannel* aChannel) -{ - nsCOMPtr httpChannel(do_QueryInterface(aChannel)); - if (!httpChannel) { - return false; - } - - nsCAutoString method; - httpChannel->GetRequestMethod(method); - return method.Equals("GET") || method.Equals("POST") || - method.Equals("HEAD"); -} - void nsDocShell::ExtractLastVisit(nsIChannel* aChannel, nsIURI** aURI, @@ -11381,8 +11302,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent, nsIInputStream* aPostDataStream, nsIInputStream* aHeadersDataStream, nsIDocShell** aDocShell, - nsIRequest** aRequest, - const char* aHttpMethod) + nsIRequest** aRequest) { // Initialize the DocShell / Request if (aDocShell) { @@ -11458,8 +11378,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent, nsnull, // No SHEntry PR_TRUE, // first party site aDocShell, // DocShell out-param - aRequest, // Request out-param - aHttpMethod); // HTTP Method + aRequest); // Request out-param if (NS_SUCCEEDED(rv)) { DispatchPings(aContent, referer); } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 80e2a5c2d5ec..2e95717263ac 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -243,8 +243,7 @@ public: nsIInputStream* aPostDataStream = 0, nsIInputStream* aHeadersDataStream = 0, nsIDocShell** aDocShell = 0, - nsIRequest** aRequest = 0, - const char* aHttpMethod = 0); + nsIRequest** aRequest = 0); NS_IMETHOD OnOverLink(nsIContent* aContent, nsIURI* aURI, const PRUnichar* aTargetSpec); @@ -326,8 +325,7 @@ protected: nsIRequest ** aRequest, PRBool aIsNewWindowTarget, PRBool aBypassClassifier, - PRBool aForceAllowCookies, - const char* aHttpMethod); + PRBool aForceAllowCookies); NS_IMETHOD AddHeadersToChannel(nsIInputStream * aHeadersData, nsIChannel * aChannel); virtual nsresult DoChannelLoad(nsIChannel * aChannel, @@ -436,10 +434,10 @@ protected: // overridden from nsDocLoader, this provides more information than the // normal OnStateChange with flags STATE_REDIRECTING - virtual nsresult OnRedirectStateChange(nsIChannel* aOldChannel, - nsIChannel* aNewChannel, - PRUint32 aRedirectFlags, - PRUint32 aStateFlags); + virtual void OnRedirectStateChange(nsIChannel* aOldChannel, + nsIChannel* aNewChannel, + PRUint32 aRedirectFlags, + PRUint32 aStateFlags); /** * Helper function that determines if channel is an HTTP POST. @@ -449,17 +447,7 @@ protected: * * @return True iff channel is an HTTP post. */ - static bool ChannelIsPost(nsIChannel* aChannel); - - /** - * Helper function that determines if the HTTP channel has a safe method - * - * @param aChannel The channel to test - * - * @return Whether the channel has a safe HTTP method. - * @note Will return false if the channel isn't an HTTP channel. - */ - static bool ChannelIsSafeMethod(nsIChannel* aChannel); + bool ChannelIsPost(nsIChannel* aChannel); /** * Helper function that finds the last URI and its transition flags for a diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index 93aee1996abc..1cb5ff4e7d91 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -71,7 +71,7 @@ interface nsIPrincipal; interface nsIWebBrowserPrint; interface nsIVariant; -[scriptable, uuid(0e1e1ee5-5baa-4e27-98af-3197d70d0304)] +[scriptable, uuid(74470127-87eb-4f79-8293-1616fe9cb689)] interface nsIDocShell : nsISupports { /** @@ -155,10 +155,6 @@ interface nsIDocShell : nsISupports * @param aLoadFlags - Flags to modify load behaviour. Flags are defined * in nsIWebNavigation. * @param aSHEntry - Active Session History entry (if loading from SH) - * @param firstParty - - * @param aDocShell - - * @param aRequest - - * @param aHttpMethod - Force the HTTP channel to use a specific HTTP method */ [noscript]void internalLoad(in nsIURI aURI, in nsIURI aReferrer, @@ -172,8 +168,7 @@ interface nsIDocShell : nsISupports in nsISHEntry aSHEntry, in boolean firstParty, out nsIDocShell aDocShell, - out nsIRequest aRequest, - in string aHttpMethod); + out nsIRequest aRequest); /** * Do either a history.pushState() or history.replaceState() operation, diff --git a/netwerk/base/public/nsICachingChannel.idl b/netwerk/base/public/nsICachingChannel.idl index 14631a8c16fe..2da46d6e50c9 100644 --- a/netwerk/base/public/nsICachingChannel.idl +++ b/netwerk/base/public/nsICachingChannel.idl @@ -50,7 +50,7 @@ interface nsIFile; * 3) Support for uniquely identifying cached data in cases when the URL * is insufficient (e.g., HTTP form submission). */ -[scriptable, uuid(b62eecc6-c450-4547-8a85-d60be3672694)] +[scriptable, uuid(830D4BCB-3E46-4011-9BDA-51A5D1AF891F)] interface nsICachingChannel : nsICacheInfoChannel { /** @@ -131,12 +131,6 @@ interface nsICachingChannel : nsICacheInfoChannel * Caching channel specific load flags: */ - /** - * This load flag forces the channel to cache the response to the request, - * even if it is not of type GET, POST, or HEAD. - */ - const unsigned long FORCE_OPEN_CACHE_ENTRY = 1 << 25; - /** * This load flag inhibits fetching from the net. An error of * NS_ERROR_DOCUMENT_NOT_CACHED will be sent to the listener's diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 32a9f17c2415..071df5e99940 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -1980,8 +1980,7 @@ nsHttpChannel::OpenCacheEntry(PRBool offline, PRBool *delayed) mPostID = gHttpHandler->GenerateUniqueID(); } else if ((mRequestHead.Method() != nsHttp::Get) && - (mRequestHead.Method() != nsHttp::Head) && - (!(mLoadFlags & FORCE_OPEN_CACHE_ENTRY))) { + (mRequestHead.Method() != nsHttp::Head)) { // don't use the cache for other types of requests return NS_OK; } diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp index 0dc8331b8267..78e4d9b1c76b 100644 --- a/uriloader/base/nsDocLoader.cpp +++ b/uriloader/base/nsDocLoader.cpp @@ -1609,9 +1609,7 @@ NS_IMETHODIMP nsDocLoader::AsyncOnChannelRedirect(nsIChannel *aOldChannel, #endif /* DEBUG */ } - nsresult rv = OnRedirectStateChange(aOldChannel, aNewChannel, aFlags, - stateFlags); - NS_ENSURE_SUCCESS(rv, rv); + OnRedirectStateChange(aOldChannel, aNewChannel, aFlags, stateFlags); FireOnStateChange(this, aOldChannel, stateFlags, NS_OK); } diff --git a/uriloader/base/nsDocLoader.h b/uriloader/base/nsDocLoader.h index 51c5828253ea..1f5b189cc94c 100644 --- a/uriloader/base/nsDocLoader.h +++ b/uriloader/base/nsDocLoader.h @@ -69,11 +69,11 @@ struct nsListenerInfo; ****************************************************************************/ #define NS_THIS_DOCLOADER_IMPL_CID \ - { \ - 0x306cae1f, \ - 0x90ee, \ - 0x4e51, \ - {0xaf, 0x27, 0x9c, 0x13, 0xde, 0xba, 0x91, 0xb6} \ + { /* b4ec8387-98aa-4c08-93b6-6d23069c06f2 */ \ + 0xb4ec8387, \ + 0x98aa, \ + 0x4c08, \ + {0x93, 0xb6, 0x6d, 0x23, 0x06, 0x9c, 0x06, 0xf2} \ } class nsDocLoader : public nsIDocumentLoader, @@ -179,12 +179,10 @@ protected: // @param aRedirectFlags The flags being sent to OnStateChange that // indicate the type of redirect. // @param aStateFlags The channel flags normally sent to OnStateChange. - // - // @return Something else than NS_OK if the redirection should be cancelled. - virtual nsresult OnRedirectStateChange(nsIChannel* aOldChannel, - nsIChannel* aNewChannel, - PRUint32 aRedirectFlags, - PRUint32 aStateFlags) { return NS_OK; } + virtual void OnRedirectStateChange(nsIChannel* aOldChannel, + nsIChannel* aNewChannel, + PRUint32 aRedirectFlags, + PRUint32 aStateFlags) {} void doStartDocumentLoad(); void doStartURLLoad(nsIRequest *request); diff --git a/webshell/public/nsILinkHandler.h b/webshell/public/nsILinkHandler.h index f3d28a0bc2d3..4b62d4ccc6dd 100644 --- a/webshell/public/nsILinkHandler.h +++ b/webshell/public/nsILinkHandler.h @@ -48,7 +48,7 @@ class nsGUIEvent; // Interface ID for nsILinkHandler #define NS_ILINKHANDLER_IID \ - { 0x1fa72627, 0x646b, 0x4573,{0xb5, 0xc8, 0xb4, 0x65, 0xc6, 0x78, 0xd4, 0x9d}} + { 0x71627c30, 0xd3c5, 0x4ad0,{0xb5, 0x33, 0x6e, 0x01, 0x91, 0xf2, 0x79, 0x32}} /** * Interface used for handling clicks on links @@ -87,7 +87,6 @@ public: * @param aHeadersDataStream ??? * @param aDocShell (out-param) the DocShell that the request was opened on * @param aRequest the request that was opened - * @param aHttpMethod forces the http channel to use a specific method */ NS_IMETHOD OnLinkClickSync(nsIContent* aContent, nsIURI* aURI, @@ -95,8 +94,7 @@ public: nsIInputStream* aPostDataStream = 0, nsIInputStream* aHeadersDataStream = 0, nsIDocShell** aDocShell = 0, - nsIRequest** aRequest = 0, - const char* aHttpMethod = 0) = 0; + nsIRequest** aRequest = 0) = 0; /** * Process a mouse-over a link. From 0e0e895f9e40302cb27f9003b30fa4862d46fdd5 Mon Sep 17 00:00:00 2001 From: Mounir Lamouri Date: Thu, 30 Sep 2010 17:10:19 -0700 Subject: [PATCH 023/115] Merging to tip. a=blocking-b7 --- Makefile.in | 3 - .../tests/mochitest/events/test_scroll.xul | 4 +- accessible/tests/mochitest/test_value.html | 2 +- .../base/content/test/browser_bug561636.js | 37 +++++- .../content/test/browser_tab_dragdrop2.js | 4 +- .../tests/browser_privacypane_1.js | 4 +- .../tests/browser_privacypane_2.js | 4 +- .../tests/browser_privacypane_3.js | 4 +- .../tests/browser_privacypane_4.js | 4 +- .../tests/browser_privacypane_5.js | 4 +- .../tests/browser_privacypane_6.js | 4 +- .../tests/browser_privacypane_7.js | 4 +- .../tests/browser_privacypane_8.js | 4 +- build/macosx/universal/flight.mk | 4 +- build/mobile/sutagent/android/ASMozStub.java | 8 ++ .../sutagent/android/AndroidManifest.xml | 8 +- .../sutagent/android/DataWorkerThread.java | 19 ++- build/mobile/sutagent/android/DoCommand.java | 102 +++++++++++++++- .../sutagent/android/RunDataThread.java | 13 ++ .../sutagent/android/SUTAgentAndroid.java | 5 +- content/base/src/nsGkAtomList.h | 1 + .../content/src/nsIConstraintValidation.cpp | 11 +- content/html/content/test/Makefile.in | 1 + content/html/content/test/test_bug600155.html | 45 +++++++ .../whatwg/postMessage_chrome_helper.html | 35 +++--- .../whatwg/test_postMessage_chrome.html | 11 +- layout/generic/test/file_bug514732_window.xul | 2 +- layout/generic/test/test_bug514732-2.xul | 3 +- modules/libpr0n/test/browser/head.js | 4 +- testing/mochitest/Makefile.in | 35 ++++++ testing/mochitest/browser-harness.xul | 20 +++- testing/mochitest/chrome-harness.js | 25 ++-- testing/mochitest/harness-overlay.xul | 113 ++++++++---------- testing/mochitest/install.rdf | 23 ++++ testing/mochitest/jar.mn | 39 ++++++ testing/mochitest/runtests.py.in | 58 ++++++--- testing/mochitest/server.js | 7 +- .../mochitest/tests/SimpleTest/Makefile.in | 1 + testing/testsuite-targets.mk | 7 +- .../tests/chrome/rtlchrome/rtl.manifest | 7 +- .../test/browser/browser_aboutCrashes.js | 2 +- .../browser/browser_aboutCrashesResubmit.js | 2 +- .../test/browser/browser_bug471404.js | 2 +- xpinstall/tests/browser_auth.js | 4 +- xpinstall/tests/browser_auth2.js | 4 +- xpinstall/tests/browser_auth3.js | 4 +- xpinstall/tests/browser_badhash.js | 4 +- xpinstall/tests/browser_badhashtype.js | 4 +- xpinstall/tests/browser_bug540558.js | 4 +- xpinstall/tests/browser_cancel.js | 4 +- xpinstall/tests/browser_chrome.js | 4 +- xpinstall/tests/browser_cookies.js | 5 +- xpinstall/tests/browser_cookies2.js | 5 +- xpinstall/tests/browser_cookies3.js | 4 +- xpinstall/tests/browser_cookies4.js | 4 +- xpinstall/tests/browser_corrupt.js | 4 +- xpinstall/tests/browser_empty.js | 4 +- xpinstall/tests/browser_enabled.js | 4 +- xpinstall/tests/browser_enabled2.js | 4 +- xpinstall/tests/browser_enabled3.js | 4 +- xpinstall/tests/browser_hash.js | 4 +- xpinstall/tests/browser_installchrome.js | 4 +- xpinstall/tests/browser_localfile.js | 4 +- xpinstall/tests/browser_localfile2.js | 4 +- xpinstall/tests/browser_navigateaway.js | 4 +- xpinstall/tests/browser_navigateaway2.js | 4 +- xpinstall/tests/browser_offline.js | 4 +- xpinstall/tests/browser_opendialog.js | 4 +- xpinstall/tests/browser_signed_multiple.js | 4 +- xpinstall/tests/browser_signed_naming.js | 4 +- xpinstall/tests/browser_signed_tampered.js | 4 +- xpinstall/tests/browser_signed_trigger.js | 4 +- xpinstall/tests/browser_signed_untrusted.js | 4 +- xpinstall/tests/browser_signed_url.js | 4 +- xpinstall/tests/browser_softwareupdate.js | 4 +- xpinstall/tests/browser_unsigned_trigger.js | 4 +- xpinstall/tests/browser_unsigned_url.js | 4 +- xpinstall/tests/browser_whitelist.js | 4 +- xpinstall/tests/browser_whitelist2.js | 4 +- xpinstall/tests/browser_whitelist3.js | 4 +- xpinstall/tests/browser_whitelist4.js | 4 +- xpinstall/tests/browser_whitelist5.js | 4 +- xpinstall/tests/browser_whitelist6.js | 4 +- xpinstall/tests/harness.js | 12 +- 84 files changed, 674 insertions(+), 195 deletions(-) create mode 100644 content/html/content/test/test_bug600155.html create mode 100644 testing/mochitest/install.rdf create mode 100644 testing/mochitest/jar.mn diff --git a/Makefile.in b/Makefile.in index 56714333347d..e38377c6951a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -120,9 +120,6 @@ export:: ifdef ENABLE_TESTS # Additional makefile targets to call automated test suites include $(topsrcdir)/testing/testsuite-targets.mk -else -# OS X Universal builds will want to call this, so stub it out -package-tests: endif include $(topsrcdir)/config/rules.mk diff --git a/accessible/tests/mochitest/events/test_scroll.xul b/accessible/tests/mochitest/events/test_scroll.xul index 32e3c907df04..2fec8a662fdc 100644 --- a/accessible/tests/mochitest/events/test_scroll.xul +++ b/accessible/tests/mochitest/events/test_scroll.xul @@ -73,10 +73,10 @@ var jar = getJar(rootDir); if (jar) { var tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - var url = rootDir + "/scroll.html#link1"; + var url = rootDir + "scroll.html#link1"; var tabBrowser = document.getElementById("tabBrowser"); tabBrowser.loadURI(url); } diff --git a/accessible/tests/mochitest/test_value.html b/accessible/tests/mochitest/test_value.html index b648b1f6a4a8..8edb23572516 100644 --- a/accessible/tests/mochitest/test_value.html +++ b/accessible/tests/mochitest/test_value.html @@ -39,7 +39,7 @@ } var rootDir = getRootDirectory(window.location.href); - var href = rootDir.path + "/foo"; + var href = rootDir.path + "foo"; // roles that can't live as nsHTMLLinkAccessibles testValue("aria_menuitem_link", ""); diff --git a/browser/base/content/test/browser_bug561636.js b/browser/base/content/test/browser_bug561636.js index d8b7f8b9608f..a14169b5e1e3 100644 --- a/browser/base/content/test/browser_bug561636.js +++ b/browser/base/content/test/browser_bug561636.js @@ -355,7 +355,7 @@ function test9() gBrowser.removeTab(tab, {animate: false}); // Next test - executeSoon(finish); + executeSoon(test10); }); }; @@ -372,3 +372,38 @@ function test9() tab.linkedBrowser.loadURI(uri); } + +/** + * In this test, we check that the author defined error message is shown. + */ +function test10() +{ + let uri = "data:text/html,
"; + let tab = gBrowser.addTab(); + + gInvalidFormPopup.addEventListener("popupshown", function() { + gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); + + let doc = gBrowser.contentDocument; + is(doc.activeElement, doc.getElementById('i'), + "First invalid element should be focused"); + + checkPopupShow(); + + is(gInvalidFormPopup.firstChild.nodeValue, "foo", + "The panel should show the author defined error message"); + + // Clean-up and next test. + gBrowser.removeTab(gBrowser.selectedTab, {animate: false}); + executeSoon(finish); + }, false); + + tab.linkedBrowser.addEventListener("load", function(aEvent) { + tab.linkedBrowser.removeEventListener("load", arguments.callee, true); + + gBrowser.contentDocument.getElementById('s').click(); + }, true); + + gBrowser.selectedTab = tab; + gBrowser.selectedTab.linkedBrowser.loadURI(uri); +} diff --git a/browser/base/content/test/browser_tab_dragdrop2.js b/browser/base/content/test/browser_tab_dragdrop2.js index 461a9ede0f25..21ed9deaa330 100644 --- a/browser/base/content/test/browser_tab_dragdrop2.js +++ b/browser/base/content/test/browser_tab_dragdrop2.js @@ -11,8 +11,8 @@ function test() // Now run the tests again and then close C. // The test results does not matter, all this is just to exercise some code to // catch assertions or crashes. - var uri = "chrome://mochikit/content/browser/" + - "browser/base/content/test/browser_tab_dragdrop2_frame1.xul"; + var chromeroot = getRootDirectory(gTestPath); + var uri = chromeroot + "browser_tab_dragdrop2_frame1.xul"; let window_B = openDialog(location, "_blank", "chrome,all,dialog=no,left=200,top=200,width=200,height=200", uri); window_B.addEventListener("load", function(aEvent) { window_B.removeEventListener("load", arguments.callee, false); diff --git a/browser/components/preferences/tests/browser_privacypane_1.js b/browser/components/preferences/tests/browser_privacypane_1.js index a0cc92b5cf92..0891b8b7e6ad 100644 --- a/browser/components/preferences/tests/browser_privacypane_1.js +++ b/browser/components/preferences/tests/browser_privacypane_1.js @@ -43,9 +43,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_pane_visibility, diff --git a/browser/components/preferences/tests/browser_privacypane_2.js b/browser/components/preferences/tests/browser_privacypane_2.js index f9ac590b9af7..47c6308d3727 100644 --- a/browser/components/preferences/tests/browser_privacypane_2.js +++ b/browser/components/preferences/tests/browser_privacypane_2.js @@ -43,9 +43,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_historymode_retention("remember", undefined), diff --git a/browser/components/preferences/tests/browser_privacypane_3.js b/browser/components/preferences/tests/browser_privacypane_3.js index 215f34758c96..bead9e907cb8 100644 --- a/browser/components/preferences/tests/browser_privacypane_3.js +++ b/browser/components/preferences/tests/browser_privacypane_3.js @@ -42,9 +42,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_custom_retention("rememberHistory", "remember"), diff --git a/browser/components/preferences/tests/browser_privacypane_4.js b/browser/components/preferences/tests/browser_privacypane_4.js index 2fb0bccff640..df46008426eb 100644 --- a/browser/components/preferences/tests/browser_privacypane_4.js +++ b/browser/components/preferences/tests/browser_privacypane_4.js @@ -42,9 +42,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_custom_retention("acceptCookies", "remember"), diff --git a/browser/components/preferences/tests/browser_privacypane_5.js b/browser/components/preferences/tests/browser_privacypane_5.js index 2a99069e3a90..2962c5cb4652 100644 --- a/browser/components/preferences/tests/browser_privacypane_5.js +++ b/browser/components/preferences/tests/browser_privacypane_5.js @@ -42,9 +42,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_locbar_suggestion_retention(-1, undefined), diff --git a/browser/components/preferences/tests/browser_privacypane_6.js b/browser/components/preferences/tests/browser_privacypane_6.js index e2f03eca14c6..7196550c1581 100644 --- a/browser/components/preferences/tests/browser_privacypane_6.js +++ b/browser/components/preferences/tests/browser_privacypane_6.js @@ -42,9 +42,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_privatebrowsing_toggle, diff --git a/browser/components/preferences/tests/browser_privacypane_7.js b/browser/components/preferences/tests/browser_privacypane_7.js index 6da4c02b5f52..3fa4e4877a54 100644 --- a/browser/components/preferences/tests/browser_privacypane_7.js +++ b/browser/components/preferences/tests/browser_privacypane_7.js @@ -42,9 +42,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ test_privatebrowsing_ui, diff --git a/browser/components/preferences/tests/browser_privacypane_8.js b/browser/components/preferences/tests/browser_privacypane_8.js index 40adbeedb154..3b8249ccdcb6 100644 --- a/browser/components/preferences/tests/browser_privacypane_8.js +++ b/browser/components/preferences/tests/browser_privacypane_8.js @@ -41,9 +41,9 @@ function test() { let jar = getJar(rootDir); if (jar) { let tmpdir = extractJarToTmp(jar); - rootDir = "file://" + tmpdir.path; + rootDir = "file://" + tmpdir.path + '/'; } - loader.loadSubScript(rootDir + "/privacypane_tests.js", this); + loader.loadSubScript(rootDir + "privacypane_tests.js", this); run_test_subset([ // history mode should be initialized to remember diff --git a/build/macosx/universal/flight.mk b/build/macosx/universal/flight.mk index 3b7619218972..4016eac86b71 100644 --- a/build/macosx/universal/flight.mk +++ b/build/macosx/universal/flight.mk @@ -121,8 +121,8 @@ postflight_all: # A universal .dmg can now be produced by making in either architecture's # INSTALLER_DIR. # Now, repeat the process for the test package. - $(MAKE) -C $(OBJDIR_ARCH_1) UNIVERSAL_BINARY= package-tests - $(MAKE) -C $(OBJDIR_ARCH_2) UNIVERSAL_BINARY= package-tests + $(MAKE) -C $(OBJDIR_ARCH_1) UNIVERSAL_BINARY= CHROME_JAR= package-tests + $(MAKE) -C $(OBJDIR_ARCH_2) UNIVERSAL_BINARY= CHROME_JAR= package-tests rm -rf $(DIST_UNI)/test-package-stage # automation.py differs because it hardcodes a path to # dist/bin. It doesn't matter which one we use. diff --git a/build/mobile/sutagent/android/ASMozStub.java b/build/mobile/sutagent/android/ASMozStub.java index 5372881f3736..ed522f833c9b 100755 --- a/build/mobile/sutagent/android/ASMozStub.java +++ b/build/mobile/sutagent/android/ASMozStub.java @@ -111,4 +111,12 @@ public class ASMozStub extends android.app.Service { System.exit(0); } + + public void SendToDataChannel(String strToSend) + { + if (runDataThrd.isAlive()) + { + runDataThrd.SendToDataChannel(strToSend); + } + } } diff --git a/build/mobile/sutagent/android/AndroidManifest.xml b/build/mobile/sutagent/android/AndroidManifest.xml index 1f2c9e969a01..ddc5dbf5a257 100644 --- a/build/mobile/sutagent/android/AndroidManifest.xml +++ b/build/mobile/sutagent/android/AndroidManifest.xml @@ -5,6 +5,7 @@ android:versionName="1.0" android:sharedUserId="org.mozilla.sharedID"> @@ -25,7 +26,7 @@ - + @@ -59,4 +60,9 @@ + + + + + \ No newline at end of file diff --git a/build/mobile/sutagent/android/DataWorkerThread.java b/build/mobile/sutagent/android/DataWorkerThread.java index cd802a6e2b15..8dea41998b4a 100755 --- a/build/mobile/sutagent/android/DataWorkerThread.java +++ b/build/mobile/sutagent/android/DataWorkerThread.java @@ -55,18 +55,34 @@ public class DataWorkerThread extends Thread private RunDataThread theParent = null; private Socket socket = null; boolean bListening = true; + PrintWriter out = null; + SimpleDateFormat sdf = null; public DataWorkerThread(RunDataThread theParent, Socket workerSocket) { super("DataWorkerThread"); this.theParent = theParent; this.socket = workerSocket; + this.sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss"); } public void StopListening() { bListening = false; } + + public void SendString(String strToSend) + { + if (this.out != null) + { + Calendar cal = Calendar.getInstance(); + String strOut = sdf.format(cal.getTime()); + strOut += " " + strToSend + "\r\n"; + + out.write(strOut); + out.flush(); + } + } private String readLine(BufferedInputStream in) { @@ -135,13 +151,12 @@ public class DataWorkerThread extends Thread { OutputStream cmdOut = socket.getOutputStream(); InputStream cmdIn = socket.getInputStream(); - PrintWriter out = new PrintWriter(cmdOut, true); + this.out = new PrintWriter(cmdOut, true); BufferedInputStream in = new BufferedInputStream(cmdIn); String inputLine, outputLine; DoCommand dc = new DoCommand(theParent.svc); Calendar cal = Calendar.getInstance(); - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss"); sRet = sdf.format(cal.getTime()); sRet += " trace output"; diff --git a/build/mobile/sutagent/android/DoCommand.java b/build/mobile/sutagent/android/DoCommand.java index fe7ae82d7213..4618c0ab3efd 100755 --- a/build/mobile/sutagent/android/DoCommand.java +++ b/build/mobile/sutagent/android/DoCommand.java @@ -60,7 +60,9 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; import java.util.List; +import java.util.TimeZone; import java.util.Timer; import java.util.zip.Adler32; import java.util.zip.CheckedInputStream; @@ -95,6 +97,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.net.Uri; import android.os.Build; +import android.os.Debug; import android.os.Environment; import android.os.StatFs; import android.os.SystemClock; @@ -113,9 +116,9 @@ public class DoCommand { ContextWrapper contextWrapper = null; String currentDir = "/"; - String sErrorPrefix = "##AGENT-ERROR## "; + String sErrorPrefix = "##AGENT-WARNING## "; - private final String prgVersion = "SUTAgentAndroid Version 0.80"; + private final String prgVersion = "SUTAgentAndroid Version 0.85"; public enum Command { @@ -128,6 +131,7 @@ public class DoCommand { OS ("os"), ID ("id"), UPTIME ("uptime"), + SETTIME ("settime"), SYSTIME ("systime"), SCREEN ("screen"), MEMORY ("memory"), @@ -215,10 +219,18 @@ public class DoCommand { strReturn = prgVersion; break; + case CLOK: + strReturn = GetClok(); + break; + case UPDT: strReturn = StartUpdateOMatic(Argv[1], Argv[2]); break; + case SETTIME: + strReturn = SetSystemTime(Argv[1], Argv[2], cmdOut); + break; + case CWD: try { strReturn = new java.io.File(currentDir).getCanonicalPath(); @@ -244,7 +256,7 @@ public class DoCommand { if (Argc == 2) strReturn = GetAppRoot(Argv[1]); else - strReturn = sErrorPrefix + "Wrong number of arguments for cd command!"; + strReturn = sErrorPrefix + "Wrong number of arguments for getapproot command!"; break; case TESTROOT: @@ -1929,6 +1941,84 @@ public class DoCommand { return (sRet); } + public String SetSystemTime(String sDate, String sTime, OutputStream out) + { +// Debug.waitForDebugger(); + String sRet = ""; + +// Intent prgIntent = new Intent(android.provider.Settings.ACTION_DATE_SETTINGS); +// prgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); +// contextWrapper.startActivity(prgIntent); + + // 2010/09/22 + // 15:41:00 + // 0123456789012345678 + + if (((sDate != null) && (sTime != null)) && + (sDate.contains("/") || sDate.contains(".")) && + (sTime.contains(":"))) + { + int year = Integer.parseInt(sDate.substring(0,4)); + int month = Integer.parseInt(sDate.substring(5,7)); + int day = Integer.parseInt(sDate.substring(8,10)); + + int hour = Integer.parseInt(sTime.substring(0,2)); + int mins = Integer.parseInt(sTime.substring(3,5)); + int secs = Integer.parseInt(sTime.substring(6,8)); + + Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT")); + cal.set(year, month - 1, day, hour, mins, secs); + long lMillisecs = cal.getTime().getTime(); + +// boolean bRet = SystemClock.setCurrentTimeMillis(lMillisecs); + String sM = Long.toString(lMillisecs); +// long lm = 1285175618316L; + String sTest = cal.getTime().toGMTString(); + String sMillis = sM.substring(0, sM.length() - 3) + "." + sM.substring(sM.length() - 3); + String [] theArgs = new String [3]; + + theArgs[0] = "su"; + theArgs[1] = "-c"; + theArgs[2] = "date -u " + sMillis; + + try + { + pProc = Runtime.getRuntime().exec(theArgs); + RedirOutputThread outThrd = new RedirOutputThread(pProc, null); + outThrd.start(); + outThrd.join(10000); + sRet = GetSystemTime(); + } + catch (IOException e) + { + sRet = e.getMessage(); + e.printStackTrace(); + } + catch (InterruptedException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + else + { + sRet = "Invalid argument(s)"; + } + + return (sRet); + } + + public String GetClok() + { + long lMillisecs = System.currentTimeMillis(); + String sRet = ""; + + if (lMillisecs > 0) + sRet = Long.toString(lMillisecs); + + return(sRet); + } + public String GetUptime() { String sRet = ""; @@ -2140,6 +2230,9 @@ public class DoCommand { try { + // Tell all of the data channels we are rebooting + ((ASMozStub)this.contextWrapper).SendToDataChannel("Rebooting ..."); + pProc = Runtime.getRuntime().exec(theArgs); RedirOutputThread outThrd = new RedirOutputThread(pProc, out); outThrd.start(); @@ -2551,6 +2644,9 @@ public class DoCommand { "rebt - reboot device\n" + "inst /path/filename.apk - install the referenced apk file\n" + "uninst packagename - uninstall the referenced package\n" + + "updt pkgname pkgfile - unpdate the referenced package\n" + + "clok - the current device time expressed as the number of millisecs since epoch\n" + + "settime date time - sets the device date and time (YYYY/MM/DD HH:MM:SS)\n" + "rebt - reboot device\n" + "quit - disconnect SUTAgent\n" + "exit - close SUTAgent\n" + diff --git a/build/mobile/sutagent/android/RunDataThread.java b/build/mobile/sutagent/android/RunDataThread.java index e30ad0031bd6..dd363a071a7a 100755 --- a/build/mobile/sutagent/android/RunDataThread.java +++ b/build/mobile/sutagent/android/RunDataThread.java @@ -66,6 +66,19 @@ public class RunDataThread extends Thread { bListening = false; } + + public void SendToDataChannel(String strToSend) + { + int nNumWorkers = theWorkers.size(); + for (int lcv = 0; lcv < nNumWorkers; lcv++) + { + if (theWorkers.get(lcv).isAlive()) + { + theWorkers.get(lcv).SendString(strToSend); + } + } + return; + } public void run() { try { diff --git a/build/mobile/sutagent/android/SUTAgentAndroid.java b/build/mobile/sutagent/android/SUTAgentAndroid.java index df3bfc99eaa2..dcd27dc396eb 100755 --- a/build/mobile/sutagent/android/SUTAgentAndroid.java +++ b/build/mobile/sutagent/android/SUTAgentAndroid.java @@ -65,6 +65,7 @@ import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.os.BatteryManager; import android.os.Bundle; +import android.os.Debug; import android.os.PowerManager; import android.telephony.TelephonyManager; import android.util.Log; @@ -133,7 +134,9 @@ public class SUTAgentAndroid extends Activity { super.onCreate(savedInstanceState); setContentView(R.layout.main); - + +// Debug.waitForDebugger(); + // long lHeapSize = VMRuntime.getRuntime().getMinimumHeapSize(); // lHeapSize = 16000000; // VMRuntime.getRuntime().setMinimumHeapSize(lHeapSize); diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index 9a03262a0939..82c80067341f 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -587,6 +587,7 @@ GK_ATOM(mouseover, "mouseover") GK_ATOM(mousethrough, "mousethrough") GK_ATOM(mouseup, "mouseup") GK_ATOM(moz_opaque, "moz-opaque") +GK_ATOM(x_moz_errormessage, "x-moz-errormessage") GK_ATOM(msthemecompatible, "msthemecompatible") GK_ATOM(multicol, "multicol") GK_ATOM(multiple, "multiple") diff --git a/content/html/content/src/nsIConstraintValidation.cpp b/content/html/content/src/nsIConstraintValidation.cpp index c24603fc6648..ca4d18be3b4f 100644 --- a/content/html/content/src/nsIConstraintValidation.cpp +++ b/content/html/content/src/nsIConstraintValidation.cpp @@ -78,7 +78,16 @@ nsIConstraintValidation::GetValidationMessage(nsAString& aValidationMessage) aValidationMessage.Truncate(); if (IsCandidateForConstraintValidation() && !IsValid()) { - if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) { + nsCOMPtr content = do_QueryInterface(this); + NS_ASSERTION(content, "This class should be inherited by HTML elements only!"); + + nsAutoString authorMessage; + content->GetAttr(kNameSpaceID_None, nsGkAtoms::x_moz_errormessage, + authorMessage); + + if (!authorMessage.IsEmpty()) { + aValidationMessage.Assign(authorMessage); + } else if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) { aValidationMessage.Assign(mCustomValidity); } else if (GetValidityState(VALIDITY_STATE_TOO_LONG)) { GetValidationMessage(aValidationMessage, VALIDITY_STATE_TOO_LONG); diff --git a/content/html/content/test/Makefile.in b/content/html/content/test/Makefile.in index 65a64d98741b..e03882d57e05 100644 --- a/content/html/content/test/Makefile.in +++ b/content/html/content/test/Makefile.in @@ -230,6 +230,7 @@ _TEST_FILES = \ test_bug557087-4.html \ test_bug557087-5.html \ test_bug557087-6.html \ + test_bug600155.html \ $(NULL) libs:: $(_TEST_FILES) diff --git a/content/html/content/test/test_bug600155.html b/content/html/content/test/test_bug600155.html new file mode 100644 index 000000000000..16aead12508a --- /dev/null +++ b/content/html/content/test/test_bug600155.html @@ -0,0 +1,45 @@ + + + + + Test for Bug 600155 + + + + + +Mozilla Bug 600155 +

+ +
+
+
+ + diff --git a/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html b/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html index a6232c7cee7b..daf6e32f9624 100644 --- a/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html +++ b/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html @@ -3,25 +3,32 @@ postMessage chrome message receiver diff --git a/modules/libpr0n/test/browser/head.js b/modules/libpr0n/test/browser/head.js index ac4d525c4c39..528495f6e959 100644 --- a/modules/libpr0n/test/browser/head.js +++ b/modules/libpr0n/test/browser/head.js @@ -5,7 +5,9 @@ const Cu = Components.utils; const RELATIVE_DIR = "modules/libpr0n/test/browser/"; const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR; const TESTROOT2 = "http://example.org/browser/" + RELATIVE_DIR; -const CHROMEROOT = "chrome://mochikit/content/browser/" + RELATIVE_DIR; + +var chrome_root = getRootDirectory(gTestPath); +const CHROMEROOT = chrome_root; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); diff --git a/testing/mochitest/Makefile.in b/testing/mochitest/Makefile.in index 9505566ab54f..8e3ce0721664 100644 --- a/testing/mochitest/Makefile.in +++ b/testing/mochitest/Makefile.in @@ -51,6 +51,19 @@ DIRS = MochiKit \ ssltunnel \ $(NULL) + +NO_JS_MANIFEST = 1 +MOZ_CHROME_FILE_FORMAT = jar +DIST_FILES = install.rdf + +# Used in install.rdf +USE_EXTENSION_MANIFEST = 1 + +XPI_NAME = mochijar + +# we turn this off for UNIVERSAL_BINARY +CHROME_JAR = 1 + include $(topsrcdir)/config/rules.mk # We're installing to _tests/testing/mochitest, so this is the depth # necessary for relative objdir paths. @@ -108,6 +121,9 @@ _HANDSHAKE_FILES = \ _DEST_DIR = $(DEPTH)/_tests/$(relativesrcdir) +libs:: + (cd $(DIST)/xpi-stage && tar $(TAR_CREATE_FLAGS) - mochijar) | (cd $(_DEST_DIR) && tar -xf -) + libs:: $(_PYWEBSOCKET_FILES) $(INSTALL) $(foreach f,$^,"$f") $(_DEST_DIR)/pywebsocket @@ -175,6 +191,25 @@ endif PKG_STAGE = $(DIST)/test-package-stage DIST_BIN = $(DIST)/bin +PKG_CHROMEJAR = $(PKG_STAGE)/mochitest/content/ + +ifdef CHROME_JAR +stage-chromejar: + $(NSINSTALL) -D $(PKG_CHROMEJAR) + cp -RL $(DEPTH)/_tests/testing/mochitest/browser $(PKG_CHROMEJAR) + cp -RL $(DEPTH)/_tests/testing/mochitest/chrome $(PKG_CHROMEJAR) +ifdef ACCESSIBILITY + cp -RL $(DEPTH)/_tests/testing/mochitest/a11y $(PKG_CHROMEJAR) +endif + @(cd $(PKG_STAGE)/mochitest && zip -r tests.jar content/) + @(rm -rf $(PKG_CHROMEJAR)) + +stage-package: stage-chromejar +endif + +$(_DEST_DIR): + $(NSINSTALL) -D $@ + stage-package: $(NSINSTALL) -D $(PKG_STAGE)/mochitest && $(NSINSTALL) -D $(PKG_STAGE)/bin/plugins @(cd $(DEPTH)/_tests/testing/mochitest/ && tar $(TAR_CREATE_FLAGS) - *) | (cd $(PKG_STAGE)/mochitest && tar -xf -) diff --git a/testing/mochitest/browser-harness.xul b/testing/mochitest/browser-harness.xul index ced53fd97713..fe4369a117b2 100644 --- a/testing/mochitest/browser-harness.xul +++ b/testing/mochitest/browser-harness.xul @@ -208,15 +208,31 @@ // Returns an array of browserTest objects for all the selected tests function listTests() { + var baseURL = 'chrome://mochitests/content'; + var testsURI = Components.classes["@mozilla.org/file/directory_service;1"] + .getService(Components.interfaces.nsIProperties) + .get("ProfD", Components.interfaces.nsILocalFile); + testsURI.append("tests.manifest"); + var ioSvc = Components.classes["@mozilla.org/network/io-service;1"]. + getService(Components.interfaces.nsIIOService); + var manifestFile = ioSvc.newFileURI(testsURI) + .QueryInterface(Components.interfaces.nsIFileURL).file; + + Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar). + autoRegister(manifestFile); // load server.js in so we can share template functions var scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]. getService(Ci.mozIJSSubScriptLoader); var srvScope = {}; - var baseURL = 'chrome://mochikit/content'; scriptLoader.loadSubScript('chrome://mochikit/content/server.js', srvScope); - var [links, singleTestPath] = getFileListing(baseURL, gConfig.testPath, "browser", srvScope); + var jar = getJar(baseURL); + if (jar != null) { + var [links, singleTestPath] = getMochitestJarListing(baseURL, gConfig.testPath, "browser"); + } else { + var [links, singleTestPath] = getFileListing(baseURL, gConfig.testPath, "browser", srvScope); + } var fileNames = []; var fileNameRegexp = /browser_.+\.js$/; diff --git a/testing/mochitest/chrome-harness.js b/testing/mochitest/chrome-harness.js index 8beee7f5c364..70e820e9fbd6 100644 --- a/testing/mochitest/chrome-harness.js +++ b/testing/mochitest/chrome-harness.js @@ -108,6 +108,9 @@ function getMochitestJarListing(basePath, testPath, dir) var fileName = fileHandler.getFileFromURLSpec(getResolvedURI(basePath).JARFile.spec); zReader.open(fileName); //hardcoded 'content' as that is the root dir in the mochikit.jar file + var idx = basePath.indexOf('/content'); + var basePath = basePath.slice(0, idx); + var base = "content/" + dir + "/"; var singleTestPath; @@ -119,7 +122,7 @@ function getMochitestJarListing(basePath, testPath, dir) if (pathEntry.isDirectory) { base = pathToCheck; } else { - singleTestPath = '/' + base + testPath; + singleTestPath = basePath + '/' + base + testPath; var singleObject = {}; singleObject[singleTestPath] = true; return [singleObject, singleTestPath]; @@ -129,7 +132,7 @@ function getMochitestJarListing(basePath, testPath, dir) base = pathToCheck + "/"; } } - var [links, count] = zList(base, zReader, true); + var [links, count] = zList(base, zReader, basePath, true); return [links, null]; } @@ -143,7 +146,7 @@ function getMochitestJarListing(basePath, testPath, dir) * returns: * [json object of {dir:{subdir:{file:true, file:true, ...}}}, count of tests] */ -function zList(base, zReader, recurse) { +function zList(base, zReader, baseJarName, recurse) { var dirs = zReader.findEntries(base + "*"); var links = {}; var count = 0; @@ -162,12 +165,12 @@ function zList(base, zReader, recurse) { var myFile = fileArray[i]; if (myFile.substr(-1) === '/' && recurse) { var childCount = 0; - [links[myFile], childCount] = zList(myFile, zReader, recurse); + [links[myFile], childCount] = zList(myFile, zReader, baseJarName, recurse); count += childCount; } else { if (myFile.indexOf("SimpleTest") == -1) { //we add the '/' so we don't try to run content/content/chrome - links['/' + myFile] = true; + links[baseJarName + '/' + myFile] = true; } } } @@ -234,8 +237,14 @@ function getRootDirectory(path, chromeURI) { chromeURI = getChromeURI(path); } var myURL = chromeURI.QueryInterface(Components.interfaces.nsIURL); + var mydir = myURL.directory; - return chromeURI.prePath + myURL.directory; + if (mydir.match('/$') != '/') + { + mydir += '/'; + } + + return chromeURI.prePath + mydir; } //used by tests to determine their directory based off window.location.path @@ -277,7 +286,7 @@ function extractJarToTmp(jar) { tmpdir.append("mochikit.tmp"); // parseInt is used because octal escape sequences cause deprecation warnings // in strict mode (which is turned on in debug builds) - tmpdir.createUnique(Components.interfaces.nsIFile.DIRECTORY_TYPE, parseInt("0777", 8)); + tmpdir.createUnique(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777); var zReader = Components.classes["@mozilla.org/libjar/zip-reader;1"]. createInstance(Components.interfaces.nsIZipReader); @@ -305,7 +314,7 @@ function extractJarToTmp(jar) { var targetDir = buildRelativePath(dirs.getNext(), tmpdir, filepath); // parseInt is used because octal escape sequences cause deprecation warnings // in strict mode (which is turned on in debug builds) - targetDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, parseInt("0777", 8)); + targetDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777); } //now do the files diff --git a/testing/mochitest/harness-overlay.xul b/testing/mochitest/harness-overlay.xul index 49bcd9904f06..57fc6d5da52e 100644 --- a/testing/mochitest/harness-overlay.xul +++ b/testing/mochitest/harness-overlay.xul @@ -17,76 +17,59 @@ src="chrome://mochikit/content/tests/SimpleTest/quit.js" /> + + + + +Mozilla Bug 592829 +
+
+
+ + diff --git a/content/xml/document/src/nsXMLContentSink.cpp b/content/xml/document/src/nsXMLContentSink.cpp index 39faef537e85..12ded7c2c30d 100644 --- a/content/xml/document/src/nsXMLContentSink.cpp +++ b/content/xml/document/src/nsXMLContentSink.cpp @@ -871,15 +871,14 @@ nsXMLContentSink::GetCurrentContent() if (mContentStack.Length() == 0) { return nsnull; } - return GetCurrentStackNode().mContent; + return GetCurrentStackNode()->mContent; } -StackNode & +StackNode* nsXMLContentSink::GetCurrentStackNode() { PRInt32 count = mContentStack.Length(); - NS_ASSERTION(count > 0, "Bogus Length()"); - return mContentStack[count-1]; + return count != 0 ? &mContentStack[count-1] : nsnull; } @@ -1116,11 +1115,14 @@ nsXMLContentSink::HandleEndElement(const PRUnichar *aName, FlushText(); - StackNode & sn = GetCurrentStackNode(); + StackNode* sn = GetCurrentStackNode(); + if (!sn) { + return NS_ERROR_UNEXPECTED; + } nsCOMPtr content; - sn.mContent.swap(content); - PRUint32 numFlushed = sn.mNumFlushed; + sn->mContent.swap(content); + PRUint32 numFlushed = sn->mNumFlushed; PopContent(); NS_ASSERTION(content, "failed to pop content"); diff --git a/content/xml/document/src/nsXMLContentSink.h b/content/xml/document/src/nsXMLContentSink.h index 814d7bd7ccab..8c455801712f 100644 --- a/content/xml/document/src/nsXMLContentSink.h +++ b/content/xml/document/src/nsXMLContentSink.h @@ -148,7 +148,7 @@ protected: nsresult AddContentAsLeaf(nsIContent *aContent); nsIContent* GetCurrentContent(); - StackNode & GetCurrentStackNode(); + StackNode* GetCurrentStackNode(); nsresult PushContent(nsIContent *aContent); void PopContent(); PRBool HaveNotifiedForCurrentContent() const; diff --git a/parser/htmlparser/src/nsExpatDriver.cpp b/parser/htmlparser/src/nsExpatDriver.cpp index bb651258d159..0eab65c1b80e 100644 --- a/parser/htmlparser/src/nsExpatDriver.cpp +++ b/parser/htmlparser/src/nsExpatDriver.cpp @@ -1414,7 +1414,10 @@ nsExpatDriver::MaybeStopParser(nsresult aState) mInternalState == NS_ERROR_HTMLPARSER_INTERRUPTED || (mInternalState == NS_ERROR_HTMLPARSER_BLOCK && aState != NS_ERROR_HTMLPARSER_INTERRUPTED)) { - mInternalState = aState; + mInternalState = (aState == NS_ERROR_HTMLPARSER_INTERRUPTED || + aState == NS_ERROR_HTMLPARSER_BLOCK) ? + aState : + NS_ERROR_HTMLPARSER_STOPPARSING; } // If we get an error then we need to stop Expat (by calling XML_StopParser From 5807a1617f99bb4316f844b1d24b19f79d1bb804 Mon Sep 17 00:00:00 2001 From: Mike Kristoffersen Date: Wed, 29 Sep 2010 18:56:46 +0200 Subject: [PATCH 103/115] Bug 561244 - e10s: forward JS 'crypto' calls from content->chrome (Part 1/3 - Adding unique define to disable crypto object) r=jst a=blocking-fennec --HG-- extra : rebase_source : 4ad7c331127b5fc75aebbad45a6a529aabe4f5e6 --- dom/base/nsGlobalWindow.cpp | 14 ++++++++++---- dom/base/nsGlobalWindow.h | 10 ++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 1e95b382bbe5..1d502cfef285 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -104,7 +104,9 @@ #include "nsIHTMLDocument.h" #include "nsIDOMHTMLDocument.h" #include "nsIDOMHTMLElement.h" +#ifndef MOZ_DISABLE_DOMCRYPTO #include "nsIDOMCrypto.h" +#endif #include "nsIDOMDocument.h" #include "nsIDOM3Document.h" #include "nsIDOMNSDocument.h" @@ -391,10 +393,10 @@ static PRBool gDOMWindowDumpEnabled = PR_FALSE; static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID); static const char sJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1"; - +#ifndef MOZ_DISABLE_DOMCRYPTO static const char kCryptoContractID[] = NS_CRYPTO_CONTRACTID; static const char kPkcs11ContractID[] = NS_PKCS11_CONTRACTID; - +#endif static const char sPopStatePrefStr[] = "browser.history.allowPopState"; static PRBool @@ -1652,12 +1654,12 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, NS_ENSURE_TRUE(scx, NS_ERROR_NOT_INITIALIZED); JSContext *cx = (JSContext *)scx->GetNativeContext(); - +#ifndef MOZ_DISABLE_DOMCRYPTO // clear smartcard events, our document has gone away. if (mCrypto) { mCrypto->SetEnableSmartCardEvents(PR_FALSE); } - +#endif if (!mDocument) { // First document load. @@ -3091,6 +3093,9 @@ nsGlobalWindow::RevokeBlobURL(const nsAString& aURL) NS_IMETHODIMP nsGlobalWindow::GetCrypto(nsIDOMCrypto** aCrypto) { +#ifdef MOZ_DISABLE_DOMCRYPTO + return NS_ERROR_NOT_IMPLEMENTED; +#else FORWARD_TO_OUTER(GetCrypto, (aCrypto), NS_ERROR_NOT_INITIALIZED); if (!mCrypto) { @@ -3100,6 +3105,7 @@ nsGlobalWindow::GetCrypto(nsIDOMCrypto** aCrypto) NS_IF_ADDREF(*aCrypto = mCrypto); return NS_OK; +#endif } NS_IMETHODIMP diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 2b14526cfab2..c5ef09447f74 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -86,7 +86,9 @@ #include "nsIScriptSecurityManager.h" #include "nsIEventListenerManager.h" #include "nsIDOMDocument.h" +#ifndef MOZ_DISABLE_DOMCRYPTO #include "nsIDOMCrypto.h" +#endif #include "nsIPrincipal.h" #include "nsPluginArray.h" #include "nsMimeTypeArray.h" @@ -142,6 +144,10 @@ class nsRunnable; class nsDOMOfflineResourceList; class nsGeolocation; +#ifdef MOZ_DISABLE_DOMCRYPTO +class nsIDOMCrypto; +#endif + extern nsresult NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow, PRBool *aIsInterval, @@ -845,9 +851,9 @@ protected: nsString mDefaultStatus; // index 0->language_id 1, so index MAX-1 == language_id MAX nsGlobalWindowObserver* mObserver; - +#ifndef MOZ_DISABLE_DOMCRYPTO nsCOMPtr mCrypto; - +#endif nsCOMPtr mLocalStorage; nsCOMPtr mSessionStorage; From 0b107990c43aae204ca1458f6153c8c7309c8800 Mon Sep 17 00:00:00 2001 From: Mike Kristoffersen Date: Wed, 29 Sep 2010 21:41:29 +0200 Subject: [PATCH 104/115] Bug 561244 - e10s: forward JS 'crypto' calls from content->chrome (Part 2/3 - Making it possible to control the define by option) r=khuey a=blocking-fennec --HG-- extra : rebase_source : 5837be9d88d001b028e738edf9dde83332e80a19 --- configure.in | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/configure.in b/configure.in index 3d4e6c0c5062..cab5fb8ead59 100644 --- a/configure.in +++ b/configure.in @@ -4958,6 +4958,7 @@ MOZ_XTF=1 MOZ_XUL=1 MOZ_ZIPWRITER=1 NS_PRINTING=1 +MOZ_DISABLE_DOMCRYPTO= NSS_DISABLE_DBM= NECKO_WIFI=1 NECKO_COOKIES=1 @@ -6611,6 +6612,13 @@ fi AC_SUBST(MOZ_DISABLE_PARENTAL_CONTROLS) +dnl ======================================================== +dnl = Disable DOMCrypto +dnl ======================================================== +if test -n "$MOZ_DISABLE_DOMCRYPTO"; then + AC_DEFINE(MOZ_DISABLE_DOMCRYPTO) +fi + dnl ======================================================== dnl = dnl = Module specific options From 2acbdf0768e9b889eacea78c92eb3cf7e17d59c4 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 23 Sep 2010 19:28:48 -0400 Subject: [PATCH 105/115] Bug 599198 - Content process throws several catastrophic assertions while initializing XPCOM (bandaide) r=bsmedberg a=blocking-fennec --- ipc/glue/ScopedXREEmbed.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ipc/glue/ScopedXREEmbed.cpp b/ipc/glue/ScopedXREEmbed.cpp index 065440d7aeb3..1f31dbce03e3 100644 --- a/ipc/glue/ScopedXREEmbed.cpp +++ b/ipc/glue/ScopedXREEmbed.cpp @@ -86,6 +86,29 @@ ScopedXREEmbed::Start() localFile = do_QueryInterface(parent); NS_ENSURE_TRUE(localFile,); +#ifdef OS_MACOSX + rv = localFile->GetParent(getter_AddRefs(parent)); + if (NS_FAILED(rv)) + return; + + localFile = do_QueryInterface(parent); + NS_ENSURE_TRUE(localFile,); + + rv = localFile->GetParent(getter_AddRefs(parent)); + if (NS_FAILED(rv)) + return; + + localFile = do_QueryInterface(parent); + NS_ENSURE_TRUE(localFile,); + + rv = localFile->GetParent(getter_AddRefs(parent)); + if (NS_FAILED(rv)) + return; + + localFile = do_QueryInterface(parent); + NS_ENSURE_TRUE(localFile,); +#endif + rv = XRE_InitEmbedding2(localFile, localFile, nsnull); if (NS_FAILED(rv)) return; From b4e1085539412721035b8eddfe35448b0836fad8 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 5 Oct 2010 12:46:03 +0200 Subject: [PATCH 106/115] Bug 601201 - Re-enable the Error Console by default. r=beltzner,robcee --- browser/app/profile/firefox.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 96971e336de3..95f210e3907c 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1042,8 +1042,8 @@ pref("services.sync.prefs.sync.spellchecker.dictionary", true); pref("services.sync.prefs.sync.xpinstall.whitelist.required", true); #endif -// Disable the Error Console -pref("devtools.errorconsole.enabled", false); +// Enable the Error Console (for now, see bug 601201) +pref("devtools.errorconsole.enabled", true); // disable the Inspector pref("devtools.inspector.enabled", false); From df9e75d88d34bf7bd3d3025ce25dcc1b5c3dc4bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Wed, 29 Sep 2010 12:16:32 +0200 Subject: [PATCH 107/115] Bug 597353 - Ensure pinned tabs have the same height and alignment as normal tabs. r=gavin a=b --- browser/base/content/tabbrowser.css | 8 ++++++-- browser/themes/pinstripe/browser/browser.css | 11 +++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/browser/base/content/tabbrowser.css b/browser/base/content/tabbrowser.css index 49df64eda33f..dbc4a0424477 100644 --- a/browser/base/content/tabbrowser.css +++ b/browser/base/content/tabbrowser.css @@ -23,11 +23,15 @@ } .tab-label[pinned] { - display: none; + width: 0; + margin-left: 0 !important; + margin-right: 0 !important; + padding-left: 0 !important; + padding-right: 0 !important; } .tab-stack { - vertical-align: middle; /* for pinned tabs */ + vertical-align: top; /* for pinned tabs */ } tabpanels { diff --git a/browser/themes/pinstripe/browser/browser.css b/browser/themes/pinstripe/browser/browser.css index ff499c47397f..b0bd5f999124 100644 --- a/browser/themes/pinstripe/browser/browser.css +++ b/browser/themes/pinstripe/browser/browser.css @@ -970,13 +970,8 @@ toolbar[mode="icons"] #zoom-in-button { /* tab progress */ -.tab-progress-container { - margin-top: -2px; -} - #tabbrowser-tabs[tabsontop="false"] > .tabbrowser-tab > .tab-stack > .tab-progress-container { -moz-box-pack: end; - margin-bottom: -2px; } /* ----- AUTOCOMPLETE ----- */ @@ -1558,6 +1553,11 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { font-weight: bold; } +.tab-stack { + /* ensure stable tab height with and without toolbarbuttons on the tab bar */ + height: 19px; +} + .tabbrowser-tab, .tabs-newtab-button { -moz-appearance: none; @@ -1574,7 +1574,6 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { -moz-border-left-colors: rgba(0,0,0,.04) rgba(0,0,0,.17) rgba(255,255,255,.1); background-clip: padding-box; text-align: center; - height: 24px; background-image: url(chrome://browser/skin/tabbrowser/tab-bkgnd.png); } From fdc3171cd176d5360c5f18c8268abad92e999948 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Fri, 1 Oct 2010 13:01:52 +0200 Subject: [PATCH 108/115] Bug 586867 - Use resource:///modules/services-sync/ instead of resource://gre/modules/services-sync, as it is an application (not GRE) module. [r=philikon] --- services/sync/Weave.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/sync/Weave.js b/services/sync/Weave.js index 6f21edb69004..a4645d7bf451 100644 --- a/services/sync/Weave.js +++ b/services/sync/Weave.js @@ -86,7 +86,7 @@ WeaveService.prototype = { if (resProt.hasSubstitution("services-sync")) return; - let uri = ioService.newURI("resource://gre/modules/services-sync/", + let uri = ioService.newURI("resource:///modules/services-sync/", null, null); resProt.setSubstitution("services-sync", uri); } From dc0e75b6ad98e8c654ada4c8f04b68b0b2c88496 Mon Sep 17 00:00:00 2001 From: Philipp von Weitershausen Date: Mon, 4 Oct 2010 22:39:08 +0200 Subject: [PATCH 109/115] Bug 600995 - Use a record's "encryption" property only as a fallback, default to the engine's value. [r=mconnor] --- services/sync/modules/base_records/crypto.js | 4 ++-- services/sync/modules/engines.js | 10 ++++++++-- services/sync/modules/type_records/bookmark.js | 2 +- services/sync/tests/unit/test_clients_escape.js | 2 +- services/sync/tests/unit/test_records_crypto.js | 13 +++++++------ services/sync/tests/unit/test_syncengine_sync.js | 16 ++++++++++++++-- 6 files changed, 33 insertions(+), 14 deletions(-) diff --git a/services/sync/modules/base_records/crypto.js b/services/sync/modules/base_records/crypto.js index f081cc778aa4..3217b728d27b 100644 --- a/services/sync/modules/base_records/crypto.js +++ b/services/sync/modules/base_records/crypto.js @@ -76,11 +76,11 @@ CryptoWrapper.prototype = { this.cleartext = null; }, - decrypt: function CryptoWrapper_decrypt(passphrase) { + decrypt: function CryptoWrapper_decrypt(passphrase, keyUri) { let pubkey = PubKeys.getDefaultKey(); let privkey = PrivKeys.get(pubkey.privateKeyUri); - let meta = CryptoMetas.get(this.encryption); + let meta = CryptoMetas.get(keyUri); let symkey = meta.getKey(privkey, passphrase); // Authenticate the encrypted blob with the expected HMAC diff --git a/services/sync/modules/engines.js b/services/sync/modules/engines.js index 5e4bcef8ddbc..0ed525d46e40 100644 --- a/services/sync/modules/engines.js +++ b/services/sync/modules/engines.js @@ -468,7 +468,13 @@ SyncEngine.prototype = { handled.push(item.id); try { - item.decrypt(ID.get("WeaveCryptoID")); + // Short-circuit the key URI to the engine's one in case the WBO's + // might be wrong due to relative URI confusions (bug 600995). + try { + item.decrypt(ID.get("WeaveCryptoID"), this.cryptoMetaURL); + } catch (ex) { + item.decrypt(ID.get("WeaveCryptoID"), item.encryption); + } if (this._reconcile(item)) { count.applied++; this._tracker.ignoreAll = true; @@ -763,7 +769,7 @@ SyncEngine.prototype = { test.sort = "newest"; test.full = true; test.recordHandler = function(record) { - record.decrypt(ID.get("WeaveCryptoID")); + record.decrypt(ID.get("WeaveCryptoID"), this.cryptoMetaURL); canDecrypt = true; }; diff --git a/services/sync/modules/type_records/bookmark.js b/services/sync/modules/type_records/bookmark.js index 37d8290ddfce..6fd270b164b1 100644 --- a/services/sync/modules/type_records/bookmark.js +++ b/services/sync/modules/type_records/bookmark.js @@ -50,7 +50,7 @@ function PlacesItem(uri, type) { this.type = type || "item"; } PlacesItem.prototype = { - decrypt: function PlacesItem_decrypt(passphrase) { + decrypt: function PlacesItem_decrypt(passphrase, keyUri) { // Do the normal CryptoWrapper decrypt, but change types before returning let clear = CryptoWrapper.prototype.decrypt.apply(this, arguments); diff --git a/services/sync/tests/unit/test_clients_escape.js b/services/sync/tests/unit/test_clients_escape.js index 37fc23d31f6e..a8e6f69a3bab 100644 --- a/services/sync/tests/unit/test_clients_escape.js +++ b/services/sync/tests/unit/test_clients_escape.js @@ -51,7 +51,7 @@ function run_test() { do_check_eq(checkCount, serialized.length); _("Making sure the record still looks like it did before"); - record.decrypt(passphrase); + record.decrypt(passphrase, Clients.cryptoMetaURL); do_check_eq(record.id, "ascii"); do_check_eq(record.name, "wéävê"); diff --git a/services/sync/tests/unit/test_records_crypto.js b/services/sync/tests/unit/test_records_crypto.js index 1f15761c9c86..49fb0baf4697 100644 --- a/services/sync/tests/unit/test_records_crypto.js +++ b/services/sync/tests/unit/test_records_crypto.js @@ -74,9 +74,10 @@ function run_test() { log.info("Creating a record"); + let cryptoUri = "http://localhost:8080/crypto/steam"; cryptoWrap = new CryptoWrapper("http://localhost:8080/steam/resource"); - cryptoWrap.encryption = "http://localhost:8080/crypto/steam"; - do_check_eq(cryptoWrap.encryption, "http://localhost:8080/crypto/steam"); + cryptoWrap.encryption = cryptoUri; + do_check_eq(cryptoWrap.encryption, cryptoUri); do_check_eq(cryptoWrap.payload.encryption, "../crypto/steam"); log.info("Encrypting a record"); @@ -87,7 +88,7 @@ function run_test() { log.info("Decrypting the record"); - let payload = cryptoWrap.decrypt(passphrase); + let payload = cryptoWrap.decrypt(passphrase, cryptoUri); do_check_eq(payload.stuff, "my payload here"); do_check_neq(payload, cryptoWrap.payload); // wrap.data.payload is the encrypted one @@ -96,7 +97,7 @@ function run_test() { cryptoWrap.cleartext.stuff = "another payload"; cryptoWrap.encrypt(passphrase); let secondIV = cryptoWrap.IV; - payload = cryptoWrap.decrypt(passphrase); + payload = cryptoWrap.decrypt(passphrase, cryptoUri); do_check_eq(payload.stuff, "another payload"); log.info("Make sure multiple encrypts use different IVs"); @@ -107,7 +108,7 @@ function run_test() { cryptoWrap.data.id = "other"; let error = ""; try { - cryptoWrap.decrypt(passphrase); + cryptoWrap.decrypt(passphrase, cryptoUri); } catch(ex) { error = ex; @@ -119,7 +120,7 @@ function run_test() { cryptoWrap.hmac = "foo"; error = ""; try { - cryptoWrap.decrypt(passphrase); + cryptoWrap.decrypt(passphrase, cryptoUri); } catch(ex) { error = ex; diff --git a/services/sync/tests/unit/test_syncengine_sync.js b/services/sync/tests/unit/test_syncengine_sync.js index 085885df49ad..29327b3fb10e 100644 --- a/services/sync/tests/unit/test_syncengine_sync.js +++ b/services/sync/tests/unit/test_syncengine_sync.js @@ -48,7 +48,6 @@ SteamStore.prototype = { createRecord: function(id, uri) { var record = new SteamRecord(uri); - record.id = id; record.denomination = this.items[id] || "Data for new record: " + id; return record; }, @@ -125,7 +124,7 @@ function encryptPayload(cleartext) { cleartext = JSON.stringify(cleartext); } - return {encryption: "http://localhost:8080/1.0/foo/storage/crypto/steam", + return {encryption: "../crypto/steam", ciphertext: cleartext, // ciphertext == cleartext with fake crypto IV: "irrelevant", hmac: Utils.sha256HMAC(cleartext, null)}; @@ -502,6 +501,15 @@ function test_processIncoming_createFromServer() { 'scotsman', encryptPayload({id: 'scotsman', denomination: "Flying Scotsman"})); + // Two pathological cases involving relative URIs gone wrong. + collection.wbos['../pathological'] = new ServerWBO( + '../pathological', encryptPayload({id: '../pathological', + denomination: "Pathological Case"})); + let wrong_keyuri = encryptPayload({id: "wrong_keyuri", + denomination: "Wrong Key URI"}); + wrong_keyuri.encryption = "../../crypto/steam"; + collection.wbos["wrong_keyuri"] = new ServerWBO("wrong_keyuri", wrong_keyuri); + let server = sync_httpd_setup({ "/1.0/foo/storage/crypto/steam": crypto_steam.handler(), "/1.0/foo/storage/steam": collection.handler(), @@ -520,6 +528,8 @@ function test_processIncoming_createFromServer() { do_check_eq(engine.lastModified, null); do_check_eq(engine._store.items.flying, undefined); do_check_eq(engine._store.items.scotsman, undefined); + do_check_eq(engine._store.items['../pathological'], undefined); + do_check_eq(engine._store.items.wrong_keyuri, undefined); engine._processIncoming(); @@ -530,6 +540,8 @@ function test_processIncoming_createFromServer() { // Local records have been created from the server data. do_check_eq(engine._store.items.flying, "LNER Class A3 4472"); do_check_eq(engine._store.items.scotsman, "Flying Scotsman"); + do_check_eq(engine._store.items['../pathological'], "Pathological Case"); + do_check_eq(engine._store.items.wrong_keyuri, "Wrong Key URI"); } finally { server.stop(do_test_finished); From 53b80cff950b457ac3b91fbed0e882f39ce6e4b3 Mon Sep 17 00:00:00 2001 From: Oleg Romashin Date: Tue, 5 Oct 2010 09:15:49 +0300 Subject: [PATCH 110/115] Bug 599202 - Add support NPP_ImageDraw API for Maemo6. r=dougt a=npodb --HG-- extra : rebase_source : 8486484c5c2bd25a1e1b63859a62bf41787e7004 --- dom/plugins/PluginInstanceChild.cpp | 14 +++++++------- dom/plugins/PluginInstanceChild.h | 2 +- modules/plugin/base/public/npapi.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dom/plugins/PluginInstanceChild.cpp b/dom/plugins/PluginInstanceChild.cpp index 34f39f244548..54759c445054 100644 --- a/dom/plugins/PluginInstanceChild.cpp +++ b/dom/plugins/PluginInstanceChild.cpp @@ -142,7 +142,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface, #ifdef MOZ_X11 , mFlash10Quirks(PR_FALSE) #endif -#if (MOZ_PLATFORM_MAEMO == 5) +#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6) , mMaemoImageRendering(PR_FALSE) #endif { @@ -303,7 +303,7 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar, #endif return NPERR_NO_ERROR; -#if (MOZ_PLATFORM_MAEMO == 5) +#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6) case NPNVSupportsWindowlessLocal: { #ifdef MOZ_WIDGET_QT const char *graphicsSystem = PR_GetEnv("MOZ_QT_GRAPHICSSYSTEM"); @@ -2052,7 +2052,7 @@ PluginInstanceChild::CreateOptSurface(void) mIsTransparent ? gfxASurface::ImageFormatARGB32 : gfxASurface::ImageFormatRGB24; -#if (MOZ_PLATFORM_MAEMO == 5) +#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6) // On Maemo 5, we must send the Visibility event to activate the plugin if (mMaemoImageRendering) { NPEvent pluginEvent; @@ -2128,7 +2128,7 @@ PluginInstanceChild::MaybeCreatePlatformHelperSurface(void) mDoAlphaExtraction = mIsTransparent; } } else if (mCurrentSurface->GetType() == gfxASurface::SurfaceTypeImage) { -#if (MOZ_PLATFORM_MAEMO == 5) +#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6) if (mMaemoImageRendering) { // No helper surface needed, when mMaemoImageRendering is TRUE. // we can rendering directly into image memory @@ -2206,7 +2206,7 @@ PluginInstanceChild::UpdateWindowAttributes(PRBool aForceSetWindow) needWindowUpdate = PR_TRUE; } } -#if (MOZ_PLATFORM_MAEMO == 5) +#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6) else if (curSurface && curSurface->GetType() == gfxASurface::SurfaceTypeImage && mMaemoImageRendering) { // For maemo5 we need to setup window/colormap to 0 @@ -2254,7 +2254,7 @@ PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect, { UpdateWindowAttributes(); #ifdef MOZ_X11 -#if (MOZ_PLATFORM_MAEMO == 5) +#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6) // On maemo5 we do support Image rendering NPAPI if (mMaemoImageRendering && aSurface->GetType() == gfxASurface::SurfaceTypeImage) { @@ -2337,7 +2337,7 @@ PluginInstanceChild::PaintRectToSurface(const nsIntRect& aRect, } if (renderSurface->GetType() != gfxASurface::SurfaceTypeXlib) { // On X11 we can paint to non Xlib surface only with HelperSurface -#if (MOZ_PLATFORM_MAEMO == 5) +#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6) // Don't use mHelperSurface if surface is image and mMaemoImageRendering is TRUE if (!mMaemoImageRendering || renderSurface->GetType() != gfxASurface::SurfaceTypeImage) diff --git a/dom/plugins/PluginInstanceChild.h b/dom/plugins/PluginInstanceChild.h index d1b355ad7059..4545645a276e 100644 --- a/dom/plugins/PluginInstanceChild.h +++ b/dom/plugins/PluginInstanceChild.h @@ -482,7 +482,7 @@ private: // Used with windowless flash plugin only, see bug 574583 PRPackedBool mFlash10Quirks; #endif -#if (MOZ_PLATFORM_MAEMO == 5) +#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6) // Maemo5 Flash does not remember WindowlessLocal state // we should listen for NPP values negotiation and remember it PRPackedBool mMaemoImageRendering; diff --git a/modules/plugin/base/public/npapi.h b/modules/plugin/base/public/npapi.h index be43c230bf07..cf3f20b8f139 100644 --- a/modules/plugin/base/public/npapi.h +++ b/modules/plugin/base/public/npapi.h @@ -426,7 +426,7 @@ typedef enum { #endif , NPNVsupportsCocoaBool = 3001 /* TRUE if the browser supports the Cocoa event model */ #endif -#if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO == 5) +#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6) , NPNVSupportsWindowlessLocal = 2002 #endif } NPNVariable; From 548468988c8a4836ba431ee9cb8a7d0627b12491 Mon Sep 17 00:00:00 2001 From: Oleg Romashin Date: Tue, 5 Oct 2010 09:15:57 +0300 Subject: [PATCH 111/115] Bug 601451 - Allow compile qt port with system cairo which does not have QT_SURFACE compiled. r=joe a=npodb --HG-- extra : rebase_source : a6bc7d01efb4a9d91418a33d43bbaf07139b4a18 --- gfx/thebes/gfxQPainterSurface.cpp | 3 +++ gfx/thebes/gfxQPainterSurface.h | 5 +++++ gfx/thebes/gfxQtPlatform.cpp | 2 ++ widget/src/qt/nsNativeThemeQt.cpp | 6 ++++-- widget/src/qt/nsWindow.cpp | 4 ++++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/gfx/thebes/gfxQPainterSurface.cpp b/gfx/thebes/gfxQPainterSurface.cpp index 099110cd1d61..c10b96c9a312 100644 --- a/gfx/thebes/gfxQPainterSurface.cpp +++ b/gfx/thebes/gfxQPainterSurface.cpp @@ -38,6 +38,8 @@ #include #include "gfxQPainterSurface.h" + +#ifdef CAIRO_HAS_QT_SURFACE #include "gfxImageSurface.h" #include "cairo-qt.h" @@ -106,3 +108,4 @@ gfxQPainterSurface::GetImageSurface() nsRefPtr asurf = new gfxImageSurface(isurf); return asurf.forget(); } +#endif diff --git a/gfx/thebes/gfxQPainterSurface.h b/gfx/thebes/gfxQPainterSurface.h index d8edb4f0f831..3afb3a46c237 100644 --- a/gfx/thebes/gfxQPainterSurface.h +++ b/gfx/thebes/gfxQPainterSurface.h @@ -41,6 +41,9 @@ #include "gfxASurface.h" #include "gfxImageSurface.h" +#include "cairo-features.h" +#ifdef CAIRO_HAS_QT_SURFACE + class QPainter; class QImage; @@ -63,4 +66,6 @@ protected: QPainter *mPainter; }; +#endif + #endif /* GFX_QPAINTERSURFACE_H */ diff --git a/gfx/thebes/gfxQtPlatform.cpp b/gfx/thebes/gfxQtPlatform.cpp index 5f6dfb3943eb..746e3dd21dff 100644 --- a/gfx/thebes/gfxQtPlatform.cpp +++ b/gfx/thebes/gfxQtPlatform.cpp @@ -200,10 +200,12 @@ gfxQtPlatform::CreateOffscreenSurface(const gfxIntSize& size, && 16 == QX11Info().depth()) imageFormat = gfxASurface::ImageFormatRGB16_565; +#ifdef CAIRO_HAS_QT_SURFACE if (mRenderMode == RENDER_QPAINTER) { newSurface = new gfxQPainterSurface(size, imageFormat); return newSurface.forget(); } +#endif if (mRenderMode == RENDER_BUFFERED && sDefaultQtPaintEngineType != QPaintEngine::X11) { diff --git a/widget/src/qt/nsNativeThemeQt.cpp b/widget/src/qt/nsNativeThemeQt.cpp index d92f3d3b37b7..9f87cea8b303 100644 --- a/widget/src/qt/nsNativeThemeQt.cpp +++ b/widget/src/qt/nsNativeThemeQt.cpp @@ -132,6 +132,7 @@ nsNativeThemeQt::DrawWidgetBackground(nsIRenderingContext* aContext, gfxContext* context = aContext->ThebesContext(); nsRefPtr surface = context->CurrentSurface(); +#ifdef CAIRO_HAS_QT_SURFACE if (surface->GetType() == gfxASurface::SurfaceTypeQPainter) { gfxQPainterSurface* qSurface = (gfxQPainterSurface*) (surface.get()); QPainter *painter = qSurface->GetQPainter(); @@ -141,8 +142,9 @@ nsNativeThemeQt::DrawWidgetBackground(nsIRenderingContext* aContext, return DrawWidgetBackground(painter, aContext, aFrame, aWidgetType, aRect, aClipRect); - } - else if (surface->GetType() == gfxASurface::SurfaceTypeImage) { + } else +#endif + if (surface->GetType() == gfxASurface::SurfaceTypeImage) { gfxImageSurface* qSurface = (gfxImageSurface*) (surface.get()); QImage tempQImage(qSurface->Data(), qSurface->Width(), diff --git a/widget/src/qt/nsWindow.cpp b/widget/src/qt/nsWindow.cpp index 55e7c895ced6..75e3cf259b89 100644 --- a/widget/src/qt/nsWindow.cpp +++ b/widget/src/qt/nsWindow.cpp @@ -976,8 +976,10 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption) targetSurface = gBufferSurface; +#ifdef CAIRO_HAS_QT_SURFACE } else if (renderMode == gfxQtPlatform::RENDER_QPAINTER) { targetSurface = new gfxQPainterSurface(aPainter); +#endif } if (NS_UNLIKELY(!targetSurface)) @@ -2443,9 +2445,11 @@ nsWindow::GetThebesSurface() return mThebesSurface; gfxQtPlatform::RenderMode renderMode = gfxQtPlatform::GetPlatform()->GetRenderMode(); +#ifdef CAIRO_HAS_QT_SURFACE if (renderMode == gfxQtPlatform::RENDER_QPAINTER) { mThebesSurface = new gfxQPainterSurface(gfxIntSize(1, 1), gfxASurface::CONTENT_COLOR); } +#endif if (!mThebesSurface) { gfxASurface::gfxImageFormat imageFormat = gfxASurface::ImageFormatRGB24; mThebesSurface = new gfxImageSurface(gfxIntSize(1, 1), imageFormat); From fef75cd21bbe027dbeceabbae9d32f1cde99da73 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 5 Oct 2010 08:32:37 +0200 Subject: [PATCH 112/115] Bug 583209 - Use ctypes.libraryName and don't use a full path to load libnss3 from weavecrypto. [r=dolske] --- services/crypto/WeaveCrypto.js | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/services/crypto/WeaveCrypto.js b/services/crypto/WeaveCrypto.js index 2939a527416c..81859c56e892 100644 --- a/services/crypto/WeaveCrypto.js +++ b/services/crypto/WeaveCrypto.js @@ -107,34 +107,12 @@ WeaveCrypto.prototype = { Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports); // Open the NSS library. - let nssfile = Services.dirsvc.get("GreD", Ci.nsILocalFile); - let os = Services.appinfo.OS; - switch (os) { - case "WINNT": - case "WINMO": - case "WINCE": - nssfile.append("nss3.dll"); - break; - case "Darwin": - nssfile.append("libnss3.dylib"); - break; - case "Linux": - case "SunOS": - case "WebOS": // Palm Pre - nssfile.append("libnss3.so"); - break; - case "Android": - // Android uses a $GREDIR/lib/ subdir. - nssfile.append("lib"); - nssfile.append("libnss3.so"); - break; - default: - throw Components.Exception("unsupported platform: " + os, Cr.NS_ERROR_UNEXPECTED); - } - this.log("Using NSS library " + nssfile.path); + let path = ctypes.libraryName("nss3"); + + this.log("Using NSS library " + path); // XXX really want to be able to pass specific dlopen flags here. - let nsslib = ctypes.open(nssfile.path); + let nsslib = ctypes.open(path); this.log("Initializing NSS types and function declarations..."); From 6fea9c20d7e1147c877180abbb53912bffa4b937 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 5 Oct 2010 13:30:59 -0400 Subject: [PATCH 113/115] Bug 595236 followup - Port the theme changes to Windows; r=dao a=blocking-beta7+ --HG-- extra : rebase_source : 4047dd82c3c7d6c1635b27c31d6593951b9c2330 --- .../gnomestripe/browser/tabview/tabview.css | 22 +++++----- .../winstripe/browser/tabview/tabview.css | 43 +++++++++++++++++++ 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/browser/themes/gnomestripe/browser/tabview/tabview.css b/browser/themes/gnomestripe/browser/tabview/tabview.css index 39f8fc684a3c..b358056aa5da 100644 --- a/browser/themes/gnomestripe/browser/tabview/tabview.css +++ b/browser/themes/gnomestripe/browser/tabview/tabview.css @@ -450,26 +450,26 @@ input.defaultName { opacity: .70; } -#otherresults{ +#otherresults { left: 0px; bottom: 0px; width: 100%; height: 30px; background-color: rgba(0,0,0,.3); - -moz-box-shadow: 0px -1px 0px rgba(255,255,255,.1), inset 0px 2px 5px rgba(0,0,0,.3); + box-shadow: 0px -1px 0px rgba(255,255,255,.1), inset 0px 2px 5px rgba(0,0,0,.3); } -#otherresults .label{ +#otherresults .label { color: #999; - line-height:30px; - margin-left:5px; + line-height: 30px; + margin-left: 5px; margin-right: 5px; } -.inlineMatch{ +.inlineMatch { background-color: #EBEBEB; border-radius: 0.4em; - -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6); border: 1px solid rgba(255, 255, 255, 0.5); padding-left: 3px; padding-right: 3px; @@ -478,17 +478,17 @@ input.defaultName { cursor: pointer; } -.inlineMatch:hover{ +.inlineMatch:hover { opacity: 1.0; } -.inlineMatch>img{ +.inlineMatch > img { margin-right: 5px; position: relative; top: 2px; } -.inlineMatch>span{ - max-width:200px; +.inlineMatch > span { + max-width: 200px; height: 15px; } diff --git a/browser/themes/winstripe/browser/tabview/tabview.css b/browser/themes/winstripe/browser/tabview/tabview.css index d52d14542f6c..78c9863caa1a 100644 --- a/browser/themes/winstripe/browser/tabview/tabview.css +++ b/browser/themes/winstripe/browser/tabview/tabview.css @@ -461,3 +461,46 @@ input.defaultName { .notMainMatch{ opacity: .70; } + +#otherresults { + left: 0px; + bottom: 0px; + width: 100%; + height: 30px; + background-color: rgba(0,0,0,.3); + box-shadow: 0px -1px 0px rgba(255,255,255,.1), inset 0px 2px 5px rgba(0,0,0,.3); +} + +#otherresults .label { + color: #999; + line-height: 30px; + margin-left: 5px; + margin-right: 5px; +} + +.inlineMatch { + background-color: #EBEBEB; + border-radius: 0.4em; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6); + border: 1px solid rgba(255, 255, 255, 0.5); + padding-left: 3px; + padding-right: 3px; + height: 20px; + margin-right: 5px; + cursor: pointer; +} + +.inlineMatch:hover { + opacity: 1.0; +} + +.inlineMatch > img { + margin-right: 5px; + position: relative; + top: 2px; +} + +.inlineMatch > span { + max-width: 200px; + height: 15px; +} From f3b0ef8355c49fdab27b4afbdcb8e2c72e28d5ea Mon Sep 17 00:00:00 2001 From: Gavin Sharp Date: Tue, 5 Oct 2010 11:45:04 -0400 Subject: [PATCH 114/115] Bug 601201: followup to ignore the devtools.console.enabled pref value (treat it as always-on), rather than changing it's default value, r=dolske, a=me --- browser/app/profile/firefox.js | 6 ++---- browser/base/content/browser.js | 3 ++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 95f210e3907c..be708302d24a 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1042,10 +1042,8 @@ pref("services.sync.prefs.sync.spellchecker.dictionary", true); pref("services.sync.prefs.sync.xpinstall.whitelist.required", true); #endif -// Enable the Error Console (for now, see bug 601201) -pref("devtools.errorconsole.enabled", true); - -// disable the Inspector +// Disable the error console and inspector +pref("devtools.errorconsole.enabled", false); pref("devtools.inspector.enabled", false); // Whether the character encoding menu is under the main Firefox button. This diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index a7bcda5751a1..2b988eb288f4 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1582,7 +1582,8 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) { } // Enable Error Console? - let consoleEnabled = gPrefService.getBoolPref("devtools.errorconsole.enabled"); + // XXX Temporarily always-enabled, see bug 601201 + let consoleEnabled = true || gPrefService.getBoolPref("devtools.errorconsole.enabled"); if (consoleEnabled) { document.getElementById("javascriptConsole").hidden = false; document.getElementById("key_errorConsole").removeAttribute("disabled"); From fe05954c7406bcca8c08f49a4c3fab1989316eb4 Mon Sep 17 00:00:00 2001 From: Raymond Lee Date: Tue, 5 Oct 2010 13:58:44 +0800 Subject: [PATCH 115/115] Bug 601863: make "Undo Close Group" button label localizable, r=dietrich, a=blocking --- browser/base/content/tabview/groupitems.js | 2 +- browser/locales/en-US/chrome/browser/tabview.properties | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/browser/base/content/tabview/groupitems.js b/browser/base/content/tabview/groupitems.js index 7317b54f07bc..21a3ab7e984a 100644 --- a/browser/base/content/tabview/groupitems.js +++ b/browser/base/content/tabview/groupitems.js @@ -590,7 +590,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), { this.$undoContainer = iQ("
") .addClass("undo") .attr("type", "button") - .text("Undo Close Group") + .text(tabviewString("groupItem.undoCloseGroup")) .appendTo("body"); let undoClose = iQ("") .addClass("close") diff --git a/browser/locales/en-US/chrome/browser/tabview.properties b/browser/locales/en-US/chrome/browser/tabview.properties index 46f85797ad5a..ef12273d397b 100644 --- a/browser/locales/en-US/chrome/browser/tabview.properties +++ b/browser/locales/en-US/chrome/browser/tabview.properties @@ -1,3 +1,4 @@ tabview.groupItem.newTabButton=New tab tabview.groupItem.defaultName=Name this tab group… -tabview.search.otherWindowTabs=Tabs from other windows \ No newline at end of file +tabview.groupItem.undoCloseGroup=Undo Close Group +tabview.search.otherWindowTabs=Tabs from other windows