Merge mozilla-central to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2014-01-22 14:43:48 +01:00
commit bc6e90f6e6
99 changed files with 1902 additions and 705 deletions

2
.clang-format-ignore Normal file
View File

@ -0,0 +1,2 @@
\mfbt/
\js/

View File

@ -16,8 +16,8 @@ support-files =
[browser_toolbox_options.js]
[browser_toolbox_options_disable_cache.js]
[browser_toolbox_options_disable_js.js]
[browser_toolbox_raise.js]
skip-if = os == "win"
# [browser_toolbox_raise.js] # Bug 962258
# skip-if = os == "win"
[browser_toolbox_ready.js]
[browser_toolbox_select_event.js]
[browser_toolbox_sidebar.js]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -989,7 +989,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
rv = aPrincipal->GetOrigin(getter_Copies(origin));
NS_ENSURE_SUCCESS(rv, rv);
JS::Rooted<JSString*> originValue(cx, JS_InternString(cx, origin.get()));
JS::Rooted<JSString*> originValue(cx, JS_NewStringCopyN(cx, origin.get(), origin.Length()));
JS_DefineProperty(cx, principalObj, "origin", STRING_TO_JSVAL(originValue), nullptr, nullptr, JSPROP_ENUMERATE);
bool browser;

View File

@ -3429,7 +3429,7 @@ nsObjectLoadingContent::TeardownProtoChain()
bool
nsObjectLoadingContent::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
JS::Handle<jsid> aId,
JS::MutableHandle<JS::Value> aValue)
JS::MutableHandle<JSPropertyDescriptor> aDesc)
{
// We don't resolve anything; we just try to make sure we're instantiated

View File

@ -156,7 +156,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
// Helper for WebIDL newResolve
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
JS::Handle<jsid> aId,
JS::MutableHandle<JS::Value> aValue);
JS::MutableHandle<JSPropertyDescriptor> aDesc);
// Helper for WebIDL enumeration
void GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& /* unused */,
mozilla::ErrorResult& aRv);

View File

@ -841,7 +841,7 @@ nsScriptLoader::AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest)
JS::CompileOptions options(cx);
FillCompileOptionsForRequest(aRequest, global, &options);
if (!JS::CanCompileOffThread(cx, options)) {
if (!JS::CanCompileOffThread(cx, options, aRequest->mScriptText.Length())) {
return NS_ERROR_FAILURE;
}

View File

@ -2078,7 +2078,9 @@ HTMLInputElement::GetStepBase() const
}
nsresult
HTMLInputElement::GetValueIfStepped(int32_t aStep, Decimal* aNextStep)
HTMLInputElement::GetValueIfStepped(int32_t aStep,
StepCallerType aCallerType,
Decimal* aNextStep)
{
if (!DoStepDownStepUpApply()) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
@ -2086,7 +2088,11 @@ HTMLInputElement::GetValueIfStepped(int32_t aStep, Decimal* aNextStep)
Decimal step = GetStep();
if (step == kStepAny) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
if (aCallerType != CALLED_FOR_USER_EVENT) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
// Allow the spin buttons and up/down arrow keys to do something sensible:
step = GetDefaultStep();
}
Decimal value = GetValueAsDecimal();
@ -2168,7 +2174,7 @@ HTMLInputElement::ApplyStep(int32_t aStep)
{
Decimal nextStep = Decimal::nan(); // unchanged if value will not change
nsresult rv = GetValueIfStepped(aStep, &nextStep);
nsresult rv = GetValueIfStepped(aStep, CALLED_FOR_SCRIPT, &nextStep);
if (NS_SUCCEEDED(rv) && nextStep.isFinite()) {
SetValue(nextStep);
@ -3603,7 +3609,7 @@ HTMLInputElement::StepNumberControlForUserEvent(int32_t aDirection)
{
Decimal newValue = Decimal::nan(); // unchanged if value will not change
nsresult rv = GetValueIfStepped(aDirection, &newValue);
nsresult rv = GetValueIfStepped(aDirection, CALLED_FOR_USER_EVENT, &newValue);
if (NS_FAILED(rv) || !newValue.isFinite()) {
return; // value should not or will not change

View File

@ -1112,6 +1112,11 @@ protected:
*/
Decimal GetDefaultStep() const;
enum StepCallerType {
CALLED_FOR_USER_EVENT,
CALLED_FOR_SCRIPT
};
/**
* Sets the aValue outparam to the value that this input would take if
* someone tries to step aStep steps and this input's value would change as
@ -1124,7 +1129,9 @@ protected:
* was initiated by a stepUp()/stepDown() call from script under conditions
* that such a call should throw.
*/
nsresult GetValueIfStepped(int32_t aStep, Decimal* aNextStep);
nsresult GetValueIfStepped(int32_t aStepCount,
StepCallerType aCallerType,
Decimal* aNextStep);
/**
* Apply a step change from stepUp or stepDown by multiplying aStep by the

View File

@ -82,7 +82,7 @@ function expectedValueAfterStepUpOrDown(stepFactor, element) {
}
var step = getStep(element);
if (step == "any") {
return value;
step = 1;
}
var minimum = getMinimum(element);
@ -187,6 +187,15 @@ function test() {
expectedVal = 0;
synthesizeKey(key, {});
is(elem.value, expectedVal, "Test " + key + " for number control where scripted preventDefault() should prevent the value changing");
// Test step="any" behavior:
var oldStep = elem.step;
elem.step = "any";
oldVal = elem.value = 0;
expectedVal = expectedValAfterKeyEvent(key, elem);
synthesizeKey(key, {});
is(elem.value, expectedVal, "Test " + key + " for number control with value set to the midpoint and step='any' (" + oldVal + ")");
elem.step = oldStep; // restore
}
}

View File

@ -62,6 +62,20 @@ function test() {
synthesizeMouse(input, SPIN_DOWN_X, SPIN_DOWN_Y, { type: "mouseup" });
is(input.value, 0, "Test mouseup on spin-down button");
// Test step="any" behavior:
input.value = 0;
var oldStep = input.step;
input.step = "any";
synthesizeMouse(input, SPIN_UP_X, SPIN_UP_Y, { type: "mousedown" });
is(input.value, 1, "Test step-up on mousedown on spin-up button with step='any'");
synthesizeMouse(input, SPIN_UP_X, SPIN_UP_Y, { type: "mouseup" });
is(input.value, 1, "Test mouseup on spin-up button with step='any'");
synthesizeMouse(input, SPIN_DOWN_X, SPIN_DOWN_Y, { type: "mousedown" });
is(input.value, 0, "Test step-down on mousedown on spin-down button with step='any'");
synthesizeMouse(input, SPIN_DOWN_X, SPIN_DOWN_Y, { type: "mouseup" });
is(input.value, 0, "Test mouseup on spin-down button with step='any'");
input.step = oldStep; // restore
// Test that preventDefault() works:
function preventDefault(e) {
e.preventDefault();

View File

@ -2656,7 +2656,7 @@ nsXULPrototypeScript::Compile(const char16_t* aText,
JS::ExposeObjectToActiveJS(scope);
}
if (aOffThreadReceiver && JS::CanCompileOffThread(cx, options)) {
if (aOffThreadReceiver && JS::CanCompileOffThread(cx, options, aTextLength)) {
if (!JS::CompileOffThread(cx, scope, options,
static_cast<const jschar*>(aText), aTextLength,
OffThreadScriptReceiverCallback,

View File

@ -17,13 +17,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=929236
<script>
var jsFuns = SpecialPowers.Cu.getJSTestingFunctions();
ok(jsFuns.isAsmJSCompilationAvailable());
ok(jsFuns.isAsmJSCompilationAvailable(), "asm.js compilation is available");
// generate a big ol asm.js module and compile it async so that we can hit
// the asm.js cache.
var code = "function f() { 'use asm';\n";
for (var i = 0; i < 1000; i++)
for (var i = 0; i < 5000; i++)
code += "function g" + i + "() { return " + i + "}\n";
code += "return g42 }\n";
code += "ok(jsFuns.isAsmJSModule(f), 'f is an asm.js module')\n";
@ -31,7 +31,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=929236
code += "ok(jsFuns.isAsmJSFunction(g42), 'g42 is an asm.js function')\n";
code += "ok(g42() === 42, 'g42 returns the correct result')\n";
code += "finishedEvalAsync(f);";
ok(code.length > 10000);
ok(code.length > 100000, "code is long enough to definitely hit the cache");
function evalAsync(code) {
var blob = new Blob([code], {type:"application/javascript"});

View File

@ -23,9 +23,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=944821
// so that we can hit the asm.js cache.
var code = "function f() { 'use asm';\n";
for (var i = 0; i < 1000; i++)
for (var i = 0; i < 5000; i++)
code += "function g" + i + "() { return " + i + "}\n";
ok(code.length > 10000, "code is long enough");
ok(code.length > 100000, "code is long enough to definitely hit the cache");
const N = 4;

View File

@ -20,10 +20,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=941830
ok(jsFuns.isAsmJSCompilationAvailable());
var asmjsCode = "function f() { 'use asm';";
for (var i = 0; i < 1000; i++)
for (var i = 0; i < 5000; i++)
asmjsCode += "function g" + i + "() { return " + i + "}";
asmjsCode += "return g42 }";
ok(asmjsCode.length > 10000);
ok(asmjsCode.length > 100000, "code is long enough to definitely hit the cache");
var workerCode = asmjsCode;
workerCode += "if (f()() !== 42) postMessage('fail'); else postMessage('ok');";

View File

@ -1488,7 +1488,7 @@ Navigator::GetMozAudioChannelManager(ErrorResult& aRv)
bool
Navigator::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
JS::Handle<jsid> aId,
JS::MutableHandle<JS::Value> aValue)
JS::MutableHandle<JSPropertyDescriptor> aDesc)
{
if (!JSID_IS_STRING(aId)) {
return true;
@ -1534,14 +1534,14 @@ Navigator::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
bool hasPermission = CheckPermission("settings-read") ||
CheckPermission("settings-write");
if (!hasPermission) {
aValue.setNull();
FillPropertyDescriptor(aDesc, aObject, JS::NullValue(), false);
return true;
}
}
if (name.EqualsLiteral("mozDownloadManager")) {
if (!CheckPermission("downloads")) {
aValue.setNull();
FillPropertyDescriptor(aDesc, aObject, JS::NullValue(), false);
return true;
}
}
@ -1556,7 +1556,7 @@ Navigator::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
return false;
}
aValue.setObject(*domObject);
FillPropertyDescriptor(aDesc, aObject, JS::ObjectValue(*domObject), false);
return true;
}
@ -1597,7 +1597,7 @@ Navigator::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
return Throw(aCx, NS_ERROR_UNEXPECTED);
}
aValue.set(prop_val);
FillPropertyDescriptor(aDesc, aObject, prop_val, false);
return true;
}

View File

@ -232,7 +232,8 @@ public:
ErrorResult& aRv);
#endif // MOZ_MEDIA_NAVIGATOR
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
JS::Handle<jsid> aId, JS::MutableHandle<JS::Value> aValue);
JS::Handle<jsid> aId,
JS::MutableHandle<JSPropertyDescriptor> aDesc);
void GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
ErrorResult& aRv);

View File

@ -3341,46 +3341,14 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return DefineComponentsShim(cx, obj, win);
}
nsIScriptContext *my_context = win->GetContextInternal();
// Don't resolve standard classes on XrayWrappers, only resolve them if we're
// resolving on the real global object.
if (!xpc::WrapperFactory::IsXrayWrapper(obj)) {
bool isXray = xpc::WrapperFactory::IsXrayWrapper(obj);
if (!isXray) {
bool did_resolve = false;
bool ok = true;
JS::Rooted<JS::Value> exn(cx, JSVAL_VOID);
{
// Resolve standard classes on my_context's JSContext (or on cx,
// if we don't have a my_context yet), in case the two contexts
// have different origins. We want lazy standard class
// initialization to behave as if it were done eagerly, on each
// window's own context (not on some other window-caller's
// context).
AutoPushJSContext my_cx(my_context ? my_context->GetNativeContext() : cx);
JSAutoCompartment ac(my_cx, obj);
ok = JS_ResolveStandardClass(my_cx, obj, id, &did_resolve);
if (!ok) {
// Trust the JS engine (or the script security manager) to set
// the exception in the JS engine.
if (!JS_GetPendingException(my_cx, &exn)) {
return NS_ERROR_UNEXPECTED;
}
// Return NS_OK to avoid stomping over the exception that was passed
// down from the ResolveStandardClass call.
// Note that the order of the JS_ClearPendingException and
// JS_SetPendingException is important in the case that my_cx == cx.
JS_ClearPendingException(my_cx);
}
}
if (!ok) {
JS_SetPendingException(cx, exn);
if (!JS_ResolveStandardClass(cx, obj, id, &did_resolve)) {
// Return NS_OK to avoid stomping over the exception that was passed
// down from the ResolveStandardClass call.
*_retval = false;
return NS_OK;
}
@ -3391,14 +3359,10 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
}
if (!my_context || !my_context->IsContextInitialized()) {
// The context is not yet initialized so there's nothing we can do
// here yet.
return NS_OK;
}
if (sLocation_id == id) {
// WebIDL quickstubs handle location for us, but Xrays don't see those. So if
// we're an Xray, we have to resolve stuff here to make "window.location =
// someString" work.
if (sLocation_id == id && isXray) {
// This must be done even if we're just getting the value of
// window.location (i.e. no checking flags & JSRESOLVE_ASSIGNING
// here) since we must define window.location to prevent the
@ -3429,7 +3393,10 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_OK;
}
if (sTop_id == id) {
// WebIDL quickstubs handle "top" for us, but Xrays don't see those. So if
// we're an Xray and we want "top" to be JSPROP_PERMANENT, we need to resolve
// it here.
if (sTop_id == id && isXray) {
nsCOMPtr<nsIDOMWindow> top;
nsresult rv = win->GetScriptableTop(getter_AddRefs(top));
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -6001,14 +6001,20 @@ class CGNewResolveHook(CGAbstractBindingMethod):
def generate_code(self):
return CGIndenter(CGGeneric(
"JS::Rooted<JS::Value> value(cx);\n"
"if (!self->DoNewResolve(cx, obj, id, &value)) {\n"
"JS::Rooted<JSPropertyDescriptor> desc(cx);\n"
"if (!self->DoNewResolve(cx, obj, id, &desc)) {\n"
" return false;\n"
"}\n"
"if (value.isUndefined()) {\n"
"if (!desc.object()) {\n"
" return true;\n"
"}\n"
"if (!JS_DefinePropertyById(cx, obj, id, value, nullptr, nullptr, JSPROP_ENUMERATE)) {\n"
"// If desc.value() is undefined, then the DoNewResolve call\n"
"// has already defined it on the object. Don't try to also\n"
"// define it.\n"
"if (!desc.value().isUndefined() &&\n"
" !JS_DefinePropertyById(cx, obj, id, desc.value(),\n"
" desc.getter(), desc.setter(),\n"
" desc.attributes())) {\n"
" return false;\n"
"}\n"
"objp.set(obj);\n"
@ -7722,14 +7728,7 @@ class CGResolveOwnPropertyViaNewresolve(CGAbstractBindingMethod):
callArgs="")
def generate_code(self):
return CGIndenter(CGGeneric(
"JS::Rooted<JS::Value> value(cx);\n"
"if (!self->DoNewResolve(cx, obj, id, &value)) {\n"
" return false;\n"
"}\n"
"if (!value.isUndefined()) {\n"
" FillPropertyDescriptor(desc, wrapper, value, /* readonly = */ false);\n"
"}\n"
"return true;"))
"return self->DoNewResolve(cx, wrapper, id, desc);"))
class CGEnumerateOwnProperties(CGAbstractStaticMethod):
def __init__(self, descriptor):

View File

@ -510,6 +510,12 @@ ok(!e.isTrusted, "Event should not be trusted");
is(e.value, 1, "value should be 1");
document.dispatchEvent(e);
is(receivedEvent, e, "Wrong event!");
e = new DeviceLightEvent("hello", {value: Infinity} );
is(e.value, Infinity, "value should be positive infinity");
e = new DeviceLightEvent("hello", {value: -Infinity} );
is(e.value, -Infinity, "value should be negative infinity");
e = new DeviceLightEvent("hello");
is(e.value, Infinity, "Uninitialized value should be positive infinity");
// DeviceOrientationEvent
e = new DeviceOrientationEvent("hello");

View File

@ -7,7 +7,7 @@
[Constructor(DOMString type, optional DeviceLightEventInit eventInitDict)]
interface DeviceLightEvent : Event
{
readonly attribute double value;
readonly attribute unrestricted double value;
};
dictionary DeviceLightEventInit : EventInit

View File

@ -586,6 +586,8 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
WriteParam(aMsg, aParam.mIsRoot);
WriteParam(aMsg, aParam.mHasScrollgrab);
WriteParam(aMsg, aParam.mUpdateScrollOffset);
WriteParam(aMsg, aParam.mDisableScrollingX);
WriteParam(aMsg, aParam.mDisableScrollingY);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
@ -605,7 +607,9 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
ReadParam(aMsg, aIter, &aResult->mPresShellId) &&
ReadParam(aMsg, aIter, &aResult->mIsRoot) &&
ReadParam(aMsg, aIter, &aResult->mHasScrollgrab) &&
ReadParam(aMsg, aIter, &aResult->mUpdateScrollOffset));
ReadParam(aMsg, aIter, &aResult->mUpdateScrollOffset) &&
ReadParam(aMsg, aIter, &aResult->mDisableScrollingX) &&
ReadParam(aMsg, aIter, &aResult->mDisableScrollingY));
}
};

View File

@ -12,6 +12,10 @@
#include "mozilla/gfx/Rect.h" // for RoundedIn
#include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor
namespace IPC {
template <typename T> struct ParamTraits;
} // namespace IPC
namespace mozilla {
namespace layers {
@ -32,6 +36,7 @@ typedef gfx::ScaleFactor<ParentLayerPixel, ScreenPixel> ParentLayerToScreenScale
* atomically with new pixels.
*/
struct FrameMetrics {
friend struct IPC::ParamTraits<mozilla::layers::FrameMetrics>;
public:
// We use IDs to identify frames across processes.
typedef uint64_t ViewID;
@ -51,11 +56,13 @@ public:
, mCumulativeResolution(1)
, mZoom(1)
, mDevPixelsPerCSSPixel(1)
, mMayHaveTouchListeners(false)
, mPresShellId(-1)
, mMayHaveTouchListeners(false)
, mIsRoot(false)
, mHasScrollgrab(false)
, mUpdateScrollOffset(false)
, mDisableScrollingX(false)
, mDisableScrollingY(false)
{}
// Default copy ctor and operator= are fine
@ -75,6 +82,9 @@ public:
mMayHaveTouchListeners == aOther.mMayHaveTouchListeners &&
mPresShellId == aOther.mPresShellId &&
mIsRoot == aOther.mIsRoot &&
mHasScrollgrab == aOther.mHasScrollgrab &&
mDisableScrollingX == aOther.mDisableScrollingX &&
mDisableScrollingY == aOther.mDisableScrollingY &&
mUpdateScrollOffset == aOther.mUpdateScrollOffset;
}
bool operator!=(const FrameMetrics& aOther) const
@ -277,11 +287,11 @@ public:
// resolution.
CSSToLayoutDeviceScale mDevPixelsPerCSSPixel;
uint32_t mPresShellId;
// Whether or not this frame may have touch listeners.
bool mMayHaveTouchListeners;
uint32_t mPresShellId;
// Whether or not this is the root scroll frame for the root content document.
bool mIsRoot;
@ -291,6 +301,36 @@ public:
// Whether mScrollOffset was updated by something other than the APZ code, and
// if the APZC receiving this metrics should update its local copy.
bool mUpdateScrollOffset;
public:
bool GetDisableScrollingX() const
{
return mDisableScrollingX;
}
void SetDisableScrollingX(bool aDisableScrollingX)
{
mDisableScrollingX = aDisableScrollingX;
}
bool GetDisableScrollingY() const
{
return mDisableScrollingY;
}
void SetDisableScrollingY(bool aDisableScrollingY)
{
mDisableScrollingY = aDisableScrollingY;
}
private:
// New fields from now on should be made private and old fields should
// be refactored to be private.
// Allow disabling scrolling in individual axis to support
// |overflow: hidden|.
bool mDisableScrollingX;
bool mDisableScrollingY;
};
/**

View File

@ -169,12 +169,12 @@ TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
return false;
}
mActor = static_cast<TextureChild*>(aForwarder->CreateEmptyTextureChild());
mActor = static_cast<TextureChild*>(aForwarder->CreateTexture(desc, GetFlags()));
MOZ_ASSERT(mActor);
mActor->mForwarder = aForwarder;
mActor->mTextureClient = this;
mShared = true;
return mActor->IPCOpen() &&
mActor->SendInit(desc, GetFlags());
return mActor->IPCOpen();
}
PTextureChild*

View File

@ -36,8 +36,8 @@ public:
~TextureParent();
bool RecvInit(const SurfaceDescriptor& aSharedData,
const TextureFlags& aFlags) MOZ_OVERRIDE;
bool Init(const SurfaceDescriptor& aSharedData,
const TextureFlags& aFlags);
virtual bool RecvRemoveTexture() MOZ_OVERRIDE;
@ -53,9 +53,14 @@ public:
// static
PTextureParent*
TextureHost::CreateIPDLActor(ISurfaceAllocator* aAllocator)
TextureHost::CreateIPDLActor(ISurfaceAllocator* aAllocator,
const SurfaceDescriptor& aSharedData,
TextureFlags aFlags)
{
return new TextureParent(aAllocator);
TextureParent* actor = new TextureParent(aAllocator);
DebugOnly<bool> status = actor->Init(aSharedData, aFlags);
MOZ_ASSERT(status);
return actor;
}
// static
@ -679,8 +684,8 @@ TextureParent::~TextureParent()
}
bool
TextureParent::RecvInit(const SurfaceDescriptor& aSharedData,
const TextureFlags& aFlags)
TextureParent::Init(const SurfaceDescriptor& aSharedData,
const TextureFlags& aFlags)
{
mTextureHost = TextureHost::Create(aSharedData,
mAllocator,

View File

@ -379,7 +379,9 @@ public:
* are for use with the managing IPDL protocols only (so that they can
* implement AllocPTextureParent and DeallocPTextureParent).
*/
static PTextureParent* CreateIPDLActor(ISurfaceAllocator* aAllocator);
static PTextureParent* CreateIPDLActor(ISurfaceAllocator* aAllocator,
const SurfaceDescriptor& aSharedData,
TextureFlags aFlags);
static bool DestroyIPDLActor(PTextureParent* actor);
/**

View File

@ -763,7 +763,7 @@ nsEventStatus AsyncPanZoomController::OnScaleBegin(const PinchGestureInput& aEve
return nsEventStatus_eIgnore;
}
if (!mZoomConstraints.mAllowZoom) {
if (!AllowZoom()) {
return nsEventStatus_eConsumeNoDefault;
}
@ -930,7 +930,7 @@ nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEven
nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
// If mZoomConstraints.mAllowZoom is true we wait for a call to OnSingleTapConfirmed before
// sending event to content
if (controller && !mZoomConstraints.mAllowZoom) {
if (controller && !AllowZoom()) {
int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers);
CSSIntPoint geckoScreenPoint;
if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) {
@ -959,7 +959,7 @@ nsEventStatus AsyncPanZoomController::OnDoubleTap(const TapGestureInput& aEvent)
APZC_LOG("%p got a double-tap in state %d\n", this, mState);
nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
if (controller) {
if (mZoomConstraints.mAllowZoom) {
if (AllowZoom()) {
int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers);
CSSIntPoint geckoScreenPoint;
if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) {
@ -997,10 +997,10 @@ void AsyncPanZoomController::HandlePanningWithTouchAction(double aAngle, TouchBe
if ((aBehavior & AllowedTouchBehavior::VERTICAL_PAN) && (aBehavior & AllowedTouchBehavior::HORIZONTAL_PAN)) {
if (mX.Scrollable() && mY.Scrollable()) {
if (IsCloseToHorizontal(aAngle, AXIS_LOCK_ANGLE)) {
mY.SetScrollingDisabled(true);
mY.SetAxisLocked(true);
SetState(PANNING_LOCKED_X);
} else if (IsCloseToVertical(aAngle, AXIS_LOCK_ANGLE)) {
mX.SetScrollingDisabled(true);
mX.SetAxisLocked(true);
SetState(PANNING_LOCKED_Y);
} else {
SetState(PANNING);
@ -1014,7 +1014,7 @@ void AsyncPanZoomController::HandlePanningWithTouchAction(double aAngle, TouchBe
// Using bigger angle for panning to keep behavior consistent
// with IE.
if (IsCloseToHorizontal(aAngle, ALLOWED_DIRECT_PAN_ANGLE)) {
mY.SetScrollingDisabled(true);
mY.SetAxisLocked(true);
SetState(PANNING_LOCKED_X);
mPanDirRestricted = true;
} else {
@ -1024,7 +1024,7 @@ void AsyncPanZoomController::HandlePanningWithTouchAction(double aAngle, TouchBe
}
} else if (aBehavior & AllowedTouchBehavior::VERTICAL_PAN) {
if (IsCloseToVertical(aAngle, ALLOWED_DIRECT_PAN_ANGLE)) {
mX.SetScrollingDisabled(true);
mX.SetAxisLocked(true);
SetState(PANNING_LOCKED_Y);
mPanDirRestricted = true;
} else {
@ -1039,20 +1039,20 @@ void AsyncPanZoomController::HandlePanning(double aAngle) {
if (!gCrossSlideEnabled && (!mX.Scrollable() || !mY.Scrollable())) {
SetState(PANNING);
} else if (IsCloseToHorizontal(aAngle, AXIS_LOCK_ANGLE)) {
mY.SetScrollingDisabled(true);
mY.SetAxisLocked(true);
if (mX.Scrollable()) {
SetState(PANNING_LOCKED_X);
} else {
SetState(CROSS_SLIDING_X);
mX.SetScrollingDisabled(true);
mX.SetAxisLocked(true);
}
} else if (IsCloseToVertical(aAngle, AXIS_LOCK_ANGLE)) {
mX.SetScrollingDisabled(true);
mX.SetAxisLocked(true);
if (mY.Scrollable()) {
SetState(PANNING_LOCKED_Y);
} else {
SetState(CROSS_SLIDING_Y);
mY.SetScrollingDisabled(true);
mY.SetAxisLocked(true);
}
} else {
SetState(PANNING);
@ -1107,6 +1107,7 @@ void AsyncPanZoomController::UpdateWithTouchAtDevicePoint(const MultiTouchInput&
void AsyncPanZoomController::AttemptScroll(const ScreenPoint& aStartPoint,
const ScreenPoint& aEndPoint,
uint32_t aOverscrollHandoffChainIndex) {
// "start - end" rather than "end - start" because e.g. moving your finger
// down (*positive* direction along y axis) causes the vertical scroll offset
// to *decrease* as the page follows your finger.
@ -1123,8 +1124,12 @@ void AsyncPanZoomController::AttemptScroll(const ScreenPoint& aStartPoint,
CSSPoint cssDisplacement = displacement / zoom;
CSSPoint cssOverscroll;
gfx::Point scrollOffset(mX.AdjustDisplacement(cssDisplacement.x, cssOverscroll.x),
mY.AdjustDisplacement(cssDisplacement.y, cssOverscroll.y));
gfx::Point scrollOffset(mX.AdjustDisplacement(cssDisplacement.x,
cssOverscroll.x,
mFrameMetrics.GetDisableScrollingX()),
mY.AdjustDisplacement(cssDisplacement.y,
cssOverscroll.y,
mFrameMetrics.GetDisableScrollingY()));
overscroll = cssOverscroll * zoom;
if (fabs(scrollOffset.x) > EPSILON || fabs(scrollOffset.y) > EPSILON) {
@ -1182,12 +1187,12 @@ void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
if (fabs(dx) > breakThreshold || fabs(dy) > breakThreshold) {
if (mState == PANNING_LOCKED_X || mState == CROSS_SLIDING_X) {
if (!IsCloseToHorizontal(angle, AXIS_BREAKOUT_ANGLE)) {
mY.SetScrollingDisabled(false);
mY.SetAxisLocked(false);
SetState(PANNING);
}
} else if (mState == PANNING_LOCKED_Y || mState == CROSS_SLIDING_Y) {
if (!IsCloseToVertical(angle, AXIS_BREAKOUT_ANGLE)) {
mX.SetScrollingDisabled(false);
mX.SetAxisLocked(false);
SetState(PANNING);
}
}
@ -1220,8 +1225,10 @@ bool FlingAnimation::Sample(FrameMetrics& aFrameMetrics,
// a larger swipe should move you a shorter distance).
CSSPoint cssOffset = offset / aFrameMetrics.mZoom;
aFrameMetrics.mScrollOffset += CSSPoint::FromUnknownPoint(gfx::Point(
mX.AdjustDisplacement(cssOffset.x, overscroll.x),
mY.AdjustDisplacement(cssOffset.y, overscroll.y)
mX.AdjustDisplacement(cssOffset.x, overscroll.x,
aFrameMetrics.GetDisableScrollingX()),
mY.AdjustDisplacement(cssOffset.y, overscroll.y,
aFrameMetrics.GetDisableScrollingX())
));
return true;
@ -1571,6 +1578,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
mFrameMetrics.mResolution = aLayerMetrics.mResolution;
mFrameMetrics.mCumulativeResolution = aLayerMetrics.mCumulativeResolution;
mFrameMetrics.mHasScrollgrab = aLayerMetrics.mHasScrollgrab;
mFrameMetrics.SetDisableScrollingX(aLayerMetrics.GetDisableScrollingX());
mFrameMetrics.SetDisableScrollingY(aLayerMetrics.GetDisableScrollingY());
// If the layers update was not triggered by our own repaint request, then
// we want to take the new scroll offset.
@ -1812,6 +1821,14 @@ bool AsyncPanZoomController::IsPanningState(PanZoomState aState) {
return (aState == PANNING || aState == PANNING_LOCKED_X || aState == PANNING_LOCKED_Y);
}
bool AsyncPanZoomController::AllowZoom() {
// In addition to looking at the zoom constraints, which comes from the meta
// viewport tag, disallow zooming if we are overflow:hidden in either direction.
ReentrantMonitorAutoEnter lock(mMonitor);
return mZoomConstraints.mAllowZoom
&& !(mFrameMetrics.GetDisableScrollingX() || mFrameMetrics.GetDisableScrollingY());
}
void AsyncPanZoomController::TimeoutContentResponse() {
mContentResponseTimeoutTask = nullptr;
ContentReceivedTouch(false);

View File

@ -580,6 +580,8 @@ private:
bool IsTransformingState(PanZoomState aState);
bool IsPanningState(PanZoomState mState);
bool AllowZoom();
enum AxisLockMode {
FREE, /* No locking at all */
STANDARD, /* Default axis locking mode that remains locked until pan ends*/

View File

@ -101,14 +101,14 @@ Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController)
: mPos(0),
mVelocity(0.0f),
mAcceleration(0),
mScrollingDisabled(false),
mAxisLocked(false),
mAsyncPanZoomController(aAsyncPanZoomController)
{
InitAxisPrefs();
}
void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, const TimeDuration& aTimeDelta) {
float newVelocity = mScrollingDisabled ? 0 : (mPos - aPos) / aTimeDelta.ToMilliseconds();
float newVelocity = mAxisLocked ? 0 : (mPos - aPos) / aTimeDelta.ToMilliseconds();
bool curVelocityBelowThreshold = fabsf(newVelocity) < gVelocityThreshold;
bool directionChange = (mVelocity > 0) != (newVelocity > 0);
@ -132,15 +132,23 @@ void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, const TimeDuration& aTimeD
void Axis::StartTouch(int32_t aPos) {
mStartPos = aPos;
mPos = aPos;
mScrollingDisabled = false;
mAxisLocked = false;
}
float Axis::AdjustDisplacement(float aDisplacement, float& aOverscrollAmountOut) {
if (mScrollingDisabled) {
float Axis::AdjustDisplacement(float aDisplacement, float& aOverscrollAmountOut,
bool aScrollingDisabled) {
if (mAxisLocked) {
aOverscrollAmountOut = 0;
return 0;
}
if (aScrollingDisabled) {
// Scrolling is disabled on this axis, stop scrolling.
aOverscrollAmountOut = aDisplacement;
mAcceleration = 0;
return 0;
}
if (fabsf(mVelocity) < gVelocityThreshold) {
mAcceleration = 0;
}
@ -192,7 +200,7 @@ void Axis::CancelTouch() {
}
bool Axis::Scrollable() {
if (mScrollingDisabled) {
if (mAxisLocked) {
return false;
}
return GetCompositionLength() < GetPageLength();
@ -291,7 +299,7 @@ float Axis::ScaleWillOverscrollAmount(float aScale, float aFocus) {
}
float Axis::GetVelocity() {
return mScrollingDisabled ? 0 : mVelocity;
return mAxisLocked ? 0 : mVelocity;
}
float Axis::GetAccelerationFactor() {

View File

@ -77,8 +77,12 @@ public:
* prevent any displacement from happening). If overscroll ocurred, its amount
* is written to |aOverscrollAmountOut|.
* The adjusted displacement is returned.
*
* aScrollingDisabled is used to indicate that no scrolling should happen
* in this axis. This is used to implement overflow: hidden;
*/
float AdjustDisplacement(float aDisplacement, float& aOverscrollAmountOut);
float AdjustDisplacement(float aDisplacement, float& aOverscrollAmountOut,
bool aScrollingDisabled);
/**
* Gets the distance between the starting position of the touch supplied in
@ -107,7 +111,7 @@ public:
*/
bool Scrollable();
void SetScrollingDisabled(bool aDisabled) { mScrollingDisabled = aDisabled; }
void SetAxisLocked(bool aAxisLocked) { mAxisLocked = aAxisLocked; }
/**
* Gets the overscroll state of the axis in its current position.
@ -190,7 +194,7 @@ protected:
// they are flinging multiple times in a row very quickly, probably trying to
// reach one of the extremes of the page.
int32_t mAcceleration;
bool mScrollingDisabled; // Whether movement on this axis is locked.
bool mAxisLocked; // Whether movement on this axis is locked.
AsyncPanZoomController* mAsyncPanZoomController;
nsTArray<float> mVelocityQueue;
};

View File

@ -96,12 +96,9 @@ public:
const SurfaceDescriptorTiles& aTiledDescriptor) = 0;
/**
* Create an unitialized TextureChild.
*
* This does not trigger the the creation of a TextureHost on the compositor
* side (see PTexture::Init).
* Create a TextureChild/Parent pair as as well as the TextureHost on the parent side.
*/
virtual PTextureChild* CreateEmptyTextureChild() = 0;
virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData, TextureFlags aFlags) = 0;
/**
* Communicate to the compositor that the texture identified by aCompositable

View File

@ -897,7 +897,8 @@ ImageBridgeChild::AllocGrallocBuffer(const IntSize& aSize,
}
PTextureChild*
ImageBridgeChild::AllocPTextureChild()
ImageBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
const TextureFlags&)
{
return TextureClient::CreateIPDLActor();
}
@ -909,9 +910,10 @@ ImageBridgeChild::DeallocPTextureChild(PTextureChild* actor)
}
PTextureChild*
ImageBridgeChild::CreateEmptyTextureChild()
ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
TextureFlags aFlags)
{
return SendPTextureConstructor();
return SendPTextureConstructor(aSharedData, aFlags);
}
static void RemoveTextureSync(TextureClient* aTexture, ReentrantMonitor* aBarrier, bool* aDone)

View File

@ -195,7 +195,7 @@ public:
DeallocPGrallocBufferChild(PGrallocBufferChild* actor) MOZ_OVERRIDE;
virtual PTextureChild*
AllocPTextureChild() MOZ_OVERRIDE;
AllocPTextureChild(const SurfaceDescriptor& aSharedData, const TextureFlags& aFlags) MOZ_OVERRIDE;
virtual bool
DeallocPTextureChild(PTextureChild* actor) MOZ_OVERRIDE;
@ -372,7 +372,8 @@ public:
*/
virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem);
virtual PTextureChild* CreateEmptyTextureChild() MOZ_OVERRIDE;
virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
TextureFlags aFlags) MOZ_OVERRIDE;
protected:
ImageBridgeChild();

View File

@ -191,9 +191,10 @@ bool ImageBridgeParent::DeallocPCompositableParent(PCompositableParent* aActor)
}
PTextureParent*
ImageBridgeParent::AllocPTextureParent()
ImageBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
const TextureFlags& aFlags)
{
return TextureHost::CreateIPDLActor(this);
return TextureHost::CreateIPDLActor(this, aSharedData, aFlags);
}
bool

View File

@ -64,7 +64,8 @@ public:
uint64_t*) MOZ_OVERRIDE;
bool DeallocPCompositableParent(PCompositableParent* aActor) MOZ_OVERRIDE;
virtual PTextureParent* AllocPTextureParent() MOZ_OVERRIDE;
virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
const TextureFlags& aFlags) MOZ_OVERRIDE;
virtual bool DeallocPTextureParent(PTextureParent* actor) MOZ_OVERRIDE;
bool RecvStop() MOZ_OVERRIDE;

View File

@ -98,7 +98,8 @@ LayerTransactionChild::ActorDestroy(ActorDestroyReason why)
}
PTextureChild*
LayerTransactionChild::AllocPTextureChild()
LayerTransactionChild::AllocPTextureChild(const SurfaceDescriptor&,
const TextureFlags&)
{
return TextureClient::CreateIPDLActor();
}

View File

@ -58,7 +58,8 @@ protected:
virtual PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo) MOZ_OVERRIDE;
virtual bool DeallocPCompositableChild(PCompositableChild* actor) MOZ_OVERRIDE;
virtual PTextureChild* AllocPTextureChild() MOZ_OVERRIDE;
virtual PTextureChild* AllocPTextureChild(const SurfaceDescriptor& aSharedData,
const TextureFlags& aFlags) MOZ_OVERRIDE;
virtual bool DeallocPTextureChild(PTextureChild* actor) MOZ_OVERRIDE;
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;

View File

@ -603,9 +603,10 @@ LayerTransactionParent::DeallocPCompositableParent(PCompositableParent* actor)
}
PTextureParent*
LayerTransactionParent::AllocPTextureParent()
LayerTransactionParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
const TextureFlags& aFlags)
{
return TextureHost::CreateIPDLActor(this);
return TextureHost::CreateIPDLActor(this, aSharedData, aFlags);
}
bool

View File

@ -107,7 +107,8 @@ protected:
virtual PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo) MOZ_OVERRIDE;
virtual bool DeallocPCompositableParent(PCompositableParent* actor) MOZ_OVERRIDE;
virtual PTextureParent* AllocPTextureParent() MOZ_OVERRIDE;
virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
const TextureFlags& aFlags) MOZ_OVERRIDE;
virtual bool DeallocPTextureParent(PTextureParent* actor) MOZ_OVERRIDE;
void Attach(ShadowLayerParent* aLayerParent,

View File

@ -51,7 +51,7 @@ parent:
sync Stop();
sync PCompositable(TextureInfo aInfo) returns (uint64_t id);
async PTexture();
async PTexture(SurfaceDescriptor aSharedData, uint32_t aTextureFlags);
};

View File

@ -68,7 +68,7 @@ parent:
returns (MaybeMagicGrallocBufferHandle handle);
async PLayer();
async PCompositable(TextureInfo aTextureInfo);
async PTexture();
async PTexture(SurfaceDescriptor aSharedData, uint32_t aTextureFlags);
// The isFirstPaint flag can be used to indicate that this is the first update
// for a particular document.

View File

@ -26,10 +26,6 @@ child:
async __delete__();
parent:
/**
* Set the shared data and create the TextureHost on the parent side.
*/
async Init(SurfaceDescriptor aSharedData, uint32_t aTextureFlags);
/**
* Asynchronously tell the Compositor side to remove the texture.

View File

@ -963,9 +963,10 @@ void ShadowLayerForwarder::AttachAsyncCompositable(uint64_t aCompositableID,
}
PTextureChild*
ShadowLayerForwarder::CreateEmptyTextureChild()
ShadowLayerForwarder::CreateTexture(const SurfaceDescriptor& aSharedData,
TextureFlags aFlags)
{
return mShadowManager->SendPTextureConstructor();
return mShadowManager->SendPTextureConstructor(aSharedData, aFlags);
}

View File

@ -148,7 +148,8 @@ public:
*/
void Connect(CompositableClient* aCompositable);
virtual PTextureChild* CreateEmptyTextureChild() MOZ_OVERRIDE;
virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
TextureFlags aFlags) MOZ_OVERRIDE;
virtual void CreatedSingleBuffer(CompositableClient* aCompositable,
const SurfaceDescriptor& aDescriptor,

View File

@ -1023,7 +1023,7 @@ gfxPlatform::CreateOffscreenContentDrawTarget(const IntSize& aSize, SurfaceForma
RefPtr<DrawTarget>
gfxPlatform::CreateDrawTargetForData(unsigned char* aData, const IntSize& aSize, int32_t aStride, SurfaceFormat aFormat)
{
NS_ASSERTION(mPreferredCanvasBackend != BackendType::NONE, "No backend.");
NS_ASSERTION(mContentBackend != BackendType::NONE, "No backend.");
if (mContentBackend == BackendType::CAIRO) {
nsRefPtr<gfxImageSurface> image = new gfxImageSurface(aData, gfxIntSize(aSize.width, aSize.height), aStride, SurfaceFormatToImageFormat(aFormat));
return Factory::CreateDrawTargetForCairoSurface(image->CairoSurface(), aSize);

View File

@ -1195,7 +1195,7 @@ RasterImage::ApplyDecodeFlags(uint32_t aNewFlags)
// decode.
if (!(aNewFlags & FLAG_SYNC_DECODE))
return false;
if (!CanForciblyDiscard() || mDecoder || mAnim)
if (!CanForciblyDiscardAndRedecode())
return false;
ForceDiscard();
}
@ -1938,6 +1938,14 @@ RasterImage::CanForciblyDiscard() {
mHasSourceData; // ...have the source data...
}
bool
RasterImage::CanForciblyDiscardAndRedecode() {
return mDiscardable && // ...Enabled at creation time...
mHasSourceData && // ...have the source data...
!mDecoder && // Can't discard with an open decoder
!mAnim; // Can never discard animated images
}
// Helper method to tell us whether the clock is currently running for
// discarding this image. Mainly for assertions.
bool
@ -2374,6 +2382,15 @@ RasterImage::SyncDecode()
if (mDecoder && mDecoder->GetDecodeFlags() != mFrameDecodeFlags) {
nsresult rv = FinishedSomeDecoding(eShutdownIntent_NotNeeded);
CONTAINER_ENSURE_SUCCESS(rv);
if (mDecoded) {
// If we've finished decoding we need to discard so we can re-decode
// with the new flags. If we can't discard then there isn't
// anything we can do.
if (!CanForciblyDiscardAndRedecode())
return NS_ERROR_NOT_AVAILABLE;
ForceDiscard();
}
}
// If we're currently waiting on a new frame for this image, we have to create
@ -2602,7 +2619,7 @@ RasterImage::Draw(gfxContext *aContext,
// We can only draw with the default decode flags
if (mFrameDecodeFlags != DECODE_FLAGS_DEFAULT) {
if (!CanForciblyDiscard() || mDecoder || mAnim)
if (!CanForciblyDiscardAndRedecode())
return NS_ERROR_NOT_AVAILABLE;
ForceDiscard();
@ -2725,7 +2742,7 @@ RasterImage::UnlockImage()
NS_IMETHODIMP
RasterImage::RequestDiscard()
{
if (CanDiscard() && !mDecoder && !mAnim) {
if (CanDiscard() && CanForciblyDiscardAndRedecode()) {
ForceDiscard();
}

View File

@ -762,6 +762,7 @@ private: // data
// Helpers
bool CanDiscard();
bool CanForciblyDiscard();
bool CanForciblyDiscardAndRedecode();
bool DiscardingActive();
bool StoringSourceData() const;

View File

@ -77,7 +77,7 @@ class ScriptAnalysis
#endif
}
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool analyzeBytecode(JSContext *cx);
/*
@ -89,9 +89,9 @@ class ScriptAnalysis
bool isReachable(const jsbytecode *pc) { return maybeCode(pc); }
private:
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool analyzeSSA(JSContext *cx);
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool analyzeLifetimes(JSContext *cx);
/* Accessors for bytecode information. */
@ -154,49 +154,49 @@ class ScriptAnalysis
void printTypes(JSContext *cx);
/* Bytecode helpers */
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
inline bool addJump(JSContext *cx, unsigned offset,
unsigned *currentOffset, unsigned *forwardJump, unsigned *forwardLoop,
unsigned stackDepth);
/* Lifetime helpers */
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
inline bool addVariable(JSContext *cx, LifetimeVariable &var, unsigned offset,
LifetimeVariable **&saved, unsigned &savedCount);
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
inline bool killVariable(JSContext *cx, LifetimeVariable &var, unsigned offset,
LifetimeVariable **&saved, unsigned &savedCount);
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
inline bool extendVariable(JSContext *cx, LifetimeVariable &var, unsigned start, unsigned end);
inline void ensureVariable(LifetimeVariable &var, unsigned until);
/* SSA helpers */
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool makePhi(JSContext *cx, uint32_t slot, uint32_t offset, SSAValue *pv);
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool insertPhi(JSContext *cx, SSAValue &phi, const SSAValue &v);
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool mergeValue(JSContext *cx, uint32_t offset, const SSAValue &v, SlotValue *pv);
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool checkPendingValue(JSContext *cx, const SSAValue &v, uint32_t slot,
Vector<SlotValue> *pending);
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool checkBranchTarget(JSContext *cx, uint32_t targetOffset, Vector<uint32_t> &branchTargets,
SSAValueInfo *values, uint32_t stackDepth);
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool checkExceptionTarget(JSContext *cx, uint32_t catchOffset,
Vector<uint32_t> &exceptionTargets);
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool mergeBranchTarget(JSContext *cx, SSAValueInfo &value, uint32_t slot,
const Vector<uint32_t> &branchTargets, uint32_t currentOffset);
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool mergeExceptionTarget(JSContext *cx, const SSAValue &value, uint32_t slot,
const Vector<uint32_t> &exceptionTargets);
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool mergeAllExceptionTargets(JSContext *cx, SSAValueInfo *values,
const Vector<uint32_t> &exceptionTargets);
JS_WARN_UNUSED_RESULT
MOZ_WARN_UNUSED_RESULT
bool freezeNewValues(JSContext *cx, uint32_t offset);
typedef Vector<SSAValue, 16> SeenVector;

View File

@ -4442,8 +4442,26 @@ JS::Compile(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optio
}
JS_PUBLIC_API(bool)
JS::CanCompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options)
JS::CanCompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options, size_t length)
{
static const unsigned TINY_LENGTH = 1000;
static const unsigned HUGE_LENGTH = 100*1000;
// These are heuristics which the caller may choose to ignore (e.g., for
// testing purposes).
if (!options.forceAsync) {
// Compiling off the main thread inolves creating a new Zone and other
// significant overheads. Don't bother if the script is tiny.
if (length < TINY_LENGTH)
return false;
// If the parsing task would have to wait for GC to complete, it'll probably
// be faster to just start it synchronously on the main thread unless the
// script is huge.
if (OffThreadParsingMustWaitForGC(cx->runtime()) && length < HUGE_LENGTH)
return false;
}
return cx->runtime()->canUseParallelParsing();
}
@ -4452,7 +4470,7 @@ JS::CompileOffThread(JSContext *cx, Handle<JSObject*> obj, const ReadOnlyCompile
const jschar *chars, size_t length,
OffThreadCompileCallback callback, void *callbackData)
{
JS_ASSERT(CanCompileOffThread(cx, options));
JS_ASSERT(CanCompileOffThread(cx, options, length));
return StartOffThreadParseScript(cx, options, chars, length, obj, callback, callbackData);
}

View File

@ -3466,6 +3466,7 @@ class JS_FRIEND_API(ReadOnlyCompileOptions)
extraWarningsOption(false),
werrorOption(false),
asmJSOption(false),
forceAsync(false),
sourcePolicy(SAVE_SOURCE)
{ }
@ -3498,6 +3499,7 @@ class JS_FRIEND_API(ReadOnlyCompileOptions)
bool extraWarningsOption;
bool werrorOption;
bool asmJSOption;
bool forceAsync;
enum SourcePolicy {
NO_SOURCE,
LAZY_SOURCE,
@ -3647,7 +3649,7 @@ extern JS_PUBLIC_API(JSScript *)
Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options, const char *filename);
extern JS_PUBLIC_API(bool)
CanCompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options);
CanCompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options, size_t length);
/*
* Off thread compilation control flow.

View File

@ -126,70 +126,68 @@ Shape::removeChild(Shape *child)
}
Shape *
PropertyTree::getChild(ExclusiveContext *cx, Shape *parent_, const StackShape &child)
PropertyTree::getChild(ExclusiveContext *cx, Shape *parentArg, const StackShape &child)
{
{
Shape *shape = nullptr;
RootedShape parent(cx, parentArg);
JS_ASSERT(parent);
JS_ASSERT(parent_);
Shape *existingShape = nullptr;
/*
* The property tree has extremely low fan-out below its root in
* popular embeddings with real-world workloads. Patterns such as
* defining closures that capture a constructor's environment as
* getters or setters on the new object that is passed in as
* |this| can significantly increase fan-out below the property
* tree root -- see bug 335700 for details.
*/
KidsPointer *kidp = &parent_->kids;
if (kidp->isShape()) {
Shape *kid = kidp->toShape();
if (kid->matches(child))
shape = kid;
} else if (kidp->isHash()) {
if (KidsHash::Ptr p = kidp->toHash()->lookup(child))
shape = *p;
} else {
/* If kidp->isNull(), we always insert. */
}
#ifdef JSGC_INCREMENTAL
if (shape) {
JS::Zone *zone = shape->zone();
if (zone->needsBarrier()) {
/*
* We need a read barrier for the shape tree, since these are weak
* pointers.
*/
Shape *tmp = shape;
MarkShapeUnbarriered(zone->barrierTracer(), &tmp, "read barrier");
JS_ASSERT(tmp == shape);
} else if (zone->isGCSweeping() && !shape->isMarked() &&
!shape->arenaHeader()->allocatedDuringIncremental)
{
/*
* The shape we've found is unreachable and due to be finalized, so
* remove our weak reference to it and don't use it.
*/
JS_ASSERT(parent_->isMarked());
parent_->removeChild(shape);
shape = nullptr;
}
}
#endif
if (shape)
return shape;
/*
* The property tree has extremely low fan-out below its root in
* popular embeddings with real-world workloads. Patterns such as
* defining closures that capture a constructor's environment as
* getters or setters on the new object that is passed in as
* |this| can significantly increase fan-out below the property
* tree root -- see bug 335700 for details.
*/
KidsPointer *kidp = &parent->kids;
if (kidp->isShape()) {
Shape *kid = kidp->toShape();
if (kid->matches(child))
existingShape = kid;
} else if (kidp->isHash()) {
if (KidsHash::Ptr p = kidp->toHash()->lookup(child))
existingShape = *p;
} else {
/* If kidp->isNull(), we always insert. */
}
#ifdef JSGC_INCREMENTAL
if (existingShape) {
JS::Zone *zone = existingShape->zone();
if (zone->needsBarrier()) {
/*
* We need a read barrier for the shape tree, since these are weak
* pointers.
*/
Shape *tmp = existingShape;
MarkShapeUnbarriered(zone->barrierTracer(), &tmp, "read barrier");
JS_ASSERT(tmp == existingShape);
} else if (zone->isGCSweeping() && !existingShape->isMarked() &&
!existingShape->arenaHeader()->allocatedDuringIncremental)
{
/*
* The shape we've found is unreachable and due to be finalized, so
* remove our weak reference to it and don't use it.
*/
JS_ASSERT(parent->isMarked());
parent->removeChild(existingShape);
existingShape = nullptr;
}
}
#endif
if (existingShape)
return existingShape;
StackShape::AutoRooter childRoot(cx, &child);
RootedShape parent(cx, parent_);
Shape *shape = newShape(cx);
if (!shape)
return nullptr;
new (shape) Shape(child, child.numFixedSlots());
new (shape) Shape(child, parent->numFixedSlots());
if (!insertChild(cx, parent, shape))
return nullptr;

View File

@ -82,24 +82,35 @@ Bindings::initWithTemporaryStorage(ExclusiveContext *cx, InternalBindingsHandle
self->numArgs_ = numArgs;
self->numVars_ = numVars;
/*
* Get the initial shape to use when creating CallObjects for this script.
* Since unaliased variables are, by definition, only accessed by local
* operations and never through the scope chain, only give shapes to
* aliased variables. While the debugger may observe any scope object at
* any time, such accesses are mediated by DebugScopeProxy (see
* DebugScopeProxy::handleUnaliasedAccess).
*/
// Get the initial shape to use when creating CallObjects for this script.
// After creation, a CallObject's shape may change completely (via direct eval() or
// other operations that mutate the lexical scope). However, since the
// lexical bindings added to the initial shape are permanent and the
// allocKind/nfixed of a CallObject cannot change, one may assume that the
// slot location (whether in the fixed or dynamic slots) of a variable is
// the same as in the initial shape. (This is assumed by the interpreter and
// JITs when interpreting/compiling aliasedvar ops.)
JS_STATIC_ASSERT(CallObject::RESERVED_SLOTS == 2);
gc::AllocKind allocKind = gc::FINALIZE_OBJECT2_BACKGROUND;
JS_ASSERT(gc::GetGCKindSlots(allocKind) == CallObject::RESERVED_SLOTS);
RootedShape initial(cx,
// Since unaliased variables are, by definition, only accessed by local
// operations and never through the scope chain, only give shapes to
// aliased variables. While the debugger may observe any scope object at
// any time, such accesses are mediated by DebugScopeProxy (see
// DebugScopeProxy::handleUnaliasedAccess).
uint32_t nslots = CallObject::RESERVED_SLOTS;
for (BindingIter bi(self); bi; bi++) {
if (bi->aliased())
nslots++;
}
// Put as many of nslots inline into the object header as possible.
uint32_t nfixed = gc::GetGCKindSlots(gc::GetGCObjectKind(nslots));
// Start with the empty shape and then append one shape per aliased binding.
RootedShape shape(cx,
EmptyShape::getInitialShape(cx, &CallObject::class_, nullptr, nullptr, nullptr,
allocKind, BaseShape::VAROBJ | BaseShape::DELEGATE));
if (!initial)
nfixed, BaseShape::VAROBJ | BaseShape::DELEGATE));
if (!shape)
return false;
self->callObjShape_.init(initial);
#ifdef DEBUG
HashSet<PropertyName *> added(cx);
@ -107,44 +118,41 @@ Bindings::initWithTemporaryStorage(ExclusiveContext *cx, InternalBindingsHandle
return false;
#endif
BindingIter bi(self);
uint32_t slot = CallObject::RESERVED_SLOTS;
for (uint32_t i = 0, n = self->count(); i < n; i++, bi++) {
for (BindingIter bi(self); bi; bi++) {
if (!bi->aliased())
continue;
#ifdef DEBUG
/* The caller ensures no duplicate aliased names. */
// The caller ensures no duplicate aliased names.
JS_ASSERT(!added.has(bi->name()));
if (!added.put(bi->name()))
return false;
#endif
StackBaseShape base(cx, &CallObject::class_, cx->global(), nullptr,
BaseShape::VAROBJ | BaseShape::DELEGATE);
StackBaseShape stackBase(cx, &CallObject::class_, nullptr, nullptr,
BaseShape::VAROBJ | BaseShape::DELEGATE);
UnownedBaseShape *nbase = BaseShape::getUnowned(cx, base);
if (!nbase)
UnownedBaseShape *base = BaseShape::getUnowned(cx, stackBase);
if (!base)
return false;
RootedId id(cx, NameToId(bi->name()));
uint32_t nfixed = gc::GetGCKindSlots(gc::GetGCObjectKind(slot + 1));
unsigned attrs = JSPROP_PERMANENT | JSPROP_ENUMERATE |
unsigned attrs = JSPROP_PERMANENT |
JSPROP_ENUMERATE |
(bi->kind() == CONSTANT ? JSPROP_READONLY : 0);
StackShape child(base, NameToId(bi->name()), slot, attrs, 0, 0);
StackShape child(nbase, id, slot, nfixed, attrs, 0, 0);
Shape *shape = cx->compartment()->propertyTree.getChild(cx, self->callObjShape_, child);
shape = cx->compartment()->propertyTree.getChild(cx, shape, child);
if (!shape)
return false;
self->callObjShape_ = shape;
JS_ASSERT(slot < nslots);
slot++;
}
JS_ASSERT(slot == nslots);
JS_ASSERT(!self->callObjShape_->inDictionary());
JS_ASSERT(!bi);
JS_ASSERT(!shape->inDictionary());
self->callObjShape_.init(shape);
return true;
}

View File

@ -1114,7 +1114,7 @@ class StringSegmentRange
: stack(cx), cur(cx)
{}
JS_WARN_UNUSED_RESULT bool init(JSString *str) {
MOZ_WARN_UNUSED_RESULT bool init(JSString *str) {
JS_ASSERT(stack.empty());
return settle(str);
}
@ -1128,7 +1128,7 @@ class StringSegmentRange
return cur;
}
JS_WARN_UNUSED_RESULT bool popFront() {
MOZ_WARN_UNUSED_RESULT bool popFront() {
JS_ASSERT(!empty());
if (stack.empty()) {
cur = nullptr;

View File

@ -102,14 +102,6 @@
#define JS_NEVER_INLINE MOZ_NEVER_INLINE
#endif
#ifndef JS_WARN_UNUSED_RESULT
# if defined __GNUC__
# define JS_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
# else
# define JS_WARN_UNUSED_RESULT
# endif
#endif
/***********************************************************************
** MACROS: JS_BEGIN_MACRO
** JS_END_MACRO

View File

@ -229,6 +229,18 @@ ParseTask::~ParseTask()
js_delete(errors[i]);
}
bool
js::OffThreadParsingMustWaitForGC(JSRuntime *rt)
{
// Off thread parsing can't occur during incremental collections on the
// atoms compartment, to avoid triggering barriers. (Outside the atoms
// compartment, the compilation will use a new zone that is never
// collected.) If an atoms-zone GC is in progress, hold off on executing the
// parse task until the atoms-zone GC completes (see
// EnqueuePendingParseTasksAfterGC).
return rt->activeGCInAtomsZone();
}
bool
js::StartOffThreadParseScript(JSContext *cx, const ReadOnlyCompileOptions &options,
const jschar *chars, size_t length, HandleObject scopeChain,
@ -299,13 +311,7 @@ js::StartOffThreadParseScript(JSContext *cx, const ReadOnlyCompileOptions &optio
WorkerThreadState &state = *cx->runtime()->workerThreadState;
JS_ASSERT(state.numThreads);
// Off thread parsing can't occur during incremental collections on the
// atoms compartment, to avoid triggering barriers. (Outside the atoms
// compartment, the compilation will use a new zone which doesn't require
// barriers itself.) If an atoms-zone GC is in progress, hold off on
// executing the parse task until the atoms-zone GC completes (see
// EnqueuePendingParseTasksAfterGC).
if (cx->runtime()->activeGCInAtomsZone()) {
if (OffThreadParsingMustWaitForGC(cx->runtime())) {
if (!state.parseWaitingOnGC.append(task.get()))
return false;
} else {
@ -327,7 +333,7 @@ js::StartOffThreadParseScript(JSContext *cx, const ReadOnlyCompileOptions &optio
void
js::EnqueuePendingParseTasksAfterGC(JSRuntime *rt)
{
JS_ASSERT(!rt->activeGCInAtomsZone());
JS_ASSERT(!OffThreadParsingMustWaitForGC(rt));
if (!rt->workerThreadState || rt->workerThreadState->parseWaitingOnGC.empty())
return;

View File

@ -371,6 +371,11 @@ struct ParseTask
~ParseTask();
};
// Return whether, if a new parse task was started, it would need to wait for
// an in-progress GC to complete before starting.
extern bool
OffThreadParsingMustWaitForGC(JSRuntime *rt);
// Compression tasks are allocated on the stack by their triggering thread,
// which will block on the compression completing as the task goes out of scope
// to ensure it completes at the required time.

View File

@ -3304,16 +3304,20 @@ OffThreadCompileScript(JSContext *cx, unsigned argc, jsval *vp)
.setCompileAndGo(true)
.setSourcePolicy(CompileOptions::SAVE_SOURCE);
if (!JS::CanCompileOffThread(cx, options)) {
JS_ReportError(cx, "cannot compile code on worker thread");
return false;
}
// We assume the caller wants caching if at all possible, ignoring
// heuristics that make sense for a real browser.
options.forceAsync = true;
const jschar *chars = JS_GetStringCharsZ(cx, scriptContents);
if (!chars)
return false;
size_t length = JS_GetStringLength(scriptContents);
if (!JS::CanCompileOffThread(cx, options, length)) {
JS_ReportError(cx, "cannot compile code on worker thread");
return false;
}
if (!offThreadState.startIfIdle(cx, scriptContents)) {
JS_ReportError(cx, "called offThreadCompileScript without calling runOffThreadScript"
" to receive prior off-thread compilation");

View File

@ -684,7 +684,7 @@ GlobalObject::addIntrinsicValue(JSContext *cx, HandleId id, HandleValue value)
RootedShape last(cx, holder->lastProperty());
Rooted<UnownedBaseShape*> base(cx, last->base()->unowned());
StackShape child(base, id, slot, holder->numFixedSlots(), 0, 0, 0);
StackShape child(base, id, slot, 0, 0, 0);
RootedShape shape(cx, cx->compartment()->propertyTree.getChild(cx, last, child));
if (!shape)
return false;

View File

@ -620,7 +620,7 @@ JSObject::addPropertyInternal(typename ExecutionModeTraits<mode>::ExclusiveConte
return nullptr;
}
StackShape child(nbase, id, slot, obj->numFixedSlots(), attrs, flags, shortid);
StackShape child(nbase, id, slot, attrs, flags, shortid);
shape = getOrLookupChildProperty<mode>(cx, obj, last, child);
}
@ -704,7 +704,7 @@ js::NewReshapedObject(JSContext *cx, HandleTypeObject type, JSObject *parent,
return nullptr;
}
StackShape child(nbase, id, i, res->numFixedSlots(), JSPROP_ENUMERATE, 0, 0);
StackShape child(nbase, id, i, JSPROP_ENUMERATE, 0, 0);
newShape = cx->compartment()->propertyTree.getChild(cx, newShape, child);
if (!newShape)
return nullptr;
@ -840,7 +840,7 @@ JSObject::putProperty(typename ExecutionModeTraits<mode>::ExclusiveContextType c
* Now that we've possibly preserved slot, check whether all members match.
* If so, this is a redundant "put" and we can return without more work.
*/
if (shape->matchesParamsAfterId(nbase, slot, obj->numFixedSlots(), attrs, flags, shortid))
if (shape->matchesParamsAfterId(nbase, slot, attrs, flags, shortid))
return shape;
/*
@ -901,7 +901,7 @@ JSObject::putProperty(typename ExecutionModeTraits<mode>::ExclusiveContextType c
JS_ASSERT(shape == obj->lastProperty());
/* Find or create a property tree node labeled by our arguments. */
StackShape child(nbase, id, slot, obj->numFixedSlots(), attrs, flags, shortid);
StackShape child(nbase, id, slot, attrs, flags, shortid);
RootedShape parent(cx, shape->parent);
Shape *newShape = getOrLookupChildProperty<mode>(cx, obj, parent, child);

View File

@ -1146,18 +1146,17 @@ class Shape : public gc::BarrieredCell<Shape>
bool matches(const Shape *other) const {
return propid_.get() == other->propid_.get() &&
matchesParamsAfterId(other->base(), other->maybeSlot(), other->numFixedSlots(),
other->attrs, other->flags, other->shortid_);
matchesParamsAfterId(other->base(), other->maybeSlot(), other->attrs, other->flags,
other->shortid_);
}
inline bool matches(const StackShape &other) const;
bool matchesParamsAfterId(BaseShape *base, uint32_t aslot, uint32_t afixed, unsigned aattrs,
unsigned aflags, int ashortid) const
bool matchesParamsAfterId(BaseShape *base, uint32_t aslot, unsigned aattrs, unsigned aflags,
int ashortid) const
{
return base->unowned() == this->base()->unowned() &&
maybeSlot() == aslot &&
numFixedSlots() == afixed &&
attrs == aattrs &&
((flags ^ aflags) & PUBLIC_FLAGS) == 0 &&
shortid_ == ashortid;
@ -1502,17 +1501,15 @@ struct StackShape
UnownedBaseShape *base;
jsid propid;
uint32_t slot_;
uint32_t nfixed_;
uint8_t attrs;
uint8_t flags;
int16_t shortid;
explicit StackShape(UnownedBaseShape *base, jsid propid, uint32_t slot,
uint32_t nfixed, unsigned attrs, unsigned flags, int shortid)
unsigned attrs, unsigned flags, int shortid)
: base(base),
propid(propid),
slot_(slot),
nfixed_(nfixed),
attrs(uint8_t(attrs)),
flags(uint8_t(flags)),
shortid(int16_t(shortid))
@ -1526,7 +1523,6 @@ struct StackShape
: base(shape->base()->unowned()),
propid(shape->propidRef()),
slot_(shape->maybeSlot()),
nfixed_(shape->numFixedSlots()),
attrs(shape->attrs),
flags(shape->flags),
shortid(shape->shortid_)
@ -1548,10 +1544,6 @@ struct StackShape
slot_ = slot;
}
uint32_t numFixedSlots() const {
return nfixed_;
}
HashNumber hash() const {
HashNumber hash = uintptr_t(base);
@ -1560,7 +1552,6 @@ struct StackShape
hash = mozilla::RotateLeft(hash, 4) ^ attrs;
hash = mozilla::RotateLeft(hash, 4) ^ shortid;
hash = mozilla::RotateLeft(hash, 4) ^ slot_;
hash = mozilla::RotateLeft(hash, 4) ^ nfixed_;
hash = mozilla::RotateLeft(hash, 4) ^ JSID_BITS(propid);
return hash;
}
@ -1710,8 +1701,7 @@ inline bool
Shape::matches(const StackShape &other) const
{
return propid_.get() == other.propid &&
matchesParamsAfterId(other.base, other.slot_, other.nfixed_, other.attrs, other.flags,
other.shortid);
matchesParamsAfterId(other.base, other.slot_, other.attrs, other.flags, other.shortid);
}
template<> struct RootKind<Shape *> : SpecificRootKind<Shape *, THING_ROOT_SHAPE> {};

View File

@ -327,74 +327,45 @@ nsXPCWrappedJS::GetNewOrUsed(JS::HandleObject jsObj,
MOZ_CRASH();
AutoJSContext cx;
JSObject2WrappedJSMap* map;
nsXPCWrappedJS* root = nullptr;
nsXPCWrappedJS* wrapper = nullptr;
nsRefPtr<nsXPCWrappedJSClass> clasp;
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
bool release_root = false;
map = rt->GetWrappedJSMap();
JSObject2WrappedJSMap* map = rt->GetWrappedJSMap();
if (!map) {
MOZ_ASSERT(map,"bad map");
return NS_ERROR_FAILURE;
}
nsRefPtr<nsXPCWrappedJSClass> clasp;
nsXPCWrappedJSClass::GetNewOrUsed(cx, aIID, getter_AddRefs(clasp));
if (!clasp)
return NS_ERROR_FAILURE;
// always find the root JSObject
JS::RootedObject rootJSObj(cx, clasp->GetRootJSObject(cx, jsObj));
if (!rootJSObj)
return NS_ERROR_FAILURE;
root = map->Find(rootJSObj);
nsRefPtr<nsXPCWrappedJS> root = map->Find(rootJSObj);
if (root) {
wrapper = root->FindOrFindInherited(aIID);
nsRefPtr<nsXPCWrappedJS> wrapper = root->FindOrFindInherited(aIID);
if (wrapper) {
NS_ADDREF(wrapper);
*wrapperResult = wrapper;
wrapper.forget(wrapperResult);
return NS_OK;
}
} else {
// build the root wrapper
if (rootJSObj == jsObj) {
// the root will do double duty as the interface wrapper
wrapper = root = new nsXPCWrappedJS(cx, jsObj, clasp, nullptr);
} else if (rootJSObj != jsObj) {
map->Add(cx, root);
// Make a new root wrapper, because there is no existing
// root wrapper, and the wrapper we are trying to make isn't
// a root.
nsRefPtr<nsXPCWrappedJSClass> rootClasp;
nsXPCWrappedJSClass::GetNewOrUsed(cx, NS_GET_IID(nsISupports),
getter_AddRefs(rootClasp));
if (!rootClasp)
return NS_ERROR_FAILURE;
*wrapperResult = wrapper;
return NS_OK;
} else {
// just a root wrapper
nsXPCWrappedJSClass* rootClasp = nullptr;
nsXPCWrappedJSClass::GetNewOrUsed(cx, NS_GET_IID(nsISupports),
&rootClasp);
if (!rootClasp)
return NS_ERROR_FAILURE;
root = new nsXPCWrappedJS(cx, rootJSObj, rootClasp, nullptr);
NS_RELEASE(rootClasp);
release_root = true;
map->Add(cx, root);
}
root = new nsXPCWrappedJS(cx, rootJSObj, rootClasp, nullptr);
}
// at this point we have a root and may need to build the specific wrapper
MOZ_ASSERT(root, "bad root");
MOZ_ASSERT(clasp, "bad clasp");
MOZ_ASSERT(!wrapper, "no wrapper found yet");
wrapper = new nsXPCWrappedJS(cx, jsObj, clasp, root);
if (release_root)
NS_RELEASE(root);
*wrapperResult = wrapper;
nsRefPtr<nsXPCWrappedJS> wrapper = new nsXPCWrappedJS(cx, jsObj, clasp, root);
wrapper.forget(wrapperResult);
return NS_OK;
}
@ -413,9 +384,10 @@ nsXPCWrappedJS::nsXPCWrappedJS(JSContext* cx,
// that are subject to finalization. See the top of the file for more
// details.
NS_ADDREF_THIS();
NS_ADDREF_THIS();
if (!IsRootWrapper()) {
if (IsRootWrapper()) {
nsXPConnect::GetRuntimeInstance()->GetWrappedJSMap()->Add(cx, this);
} else {
NS_ADDREF(mRoot);
mNext = mRoot->mNext;
mRoot->mNext = this;

View File

@ -623,10 +623,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
if (scrollableFrame) {
nsRect contentBounds = scrollableFrame->GetScrollRange();
if (scrollableFrame->GetScrollbarStyles().mVertical == NS_STYLE_OVERFLOW_HIDDEN) {
contentBounds.height = 0;
metrics.SetDisableScrollingY(true);
}
if (scrollableFrame->GetScrollbarStyles().mHorizontal == NS_STYLE_OVERFLOW_HIDDEN) {
contentBounds.width = 0;
metrics.SetDisableScrollingX(true);
}
contentBounds.width += scrollableFrame->GetScrollPortRect().width;
contentBounds.height += scrollableFrame->GetScrollPortRect().height;

View File

@ -0,0 +1,5 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<input type="number"> </input>
</body>
</html>

View File

@ -53,4 +53,5 @@ asserts(0-1) load 669767.html
load 682684.xhtml
load 865602.html
load 944198.html
load 949891.xhtml
load 960277-2.html

View File

@ -44,7 +44,7 @@ public:
virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
virtual void ContentStatesChanged(nsEventStates aStates);
virtual bool IsLeaf() const MOZ_OVERRIDE { return false; }
virtual bool IsLeaf() const MOZ_OVERRIDE { return true; }
#ifdef ACCESSIBILITY
virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;

View File

@ -22,6 +22,13 @@
using namespace mozilla::css;
using namespace mozilla::layout;
// Convenience typedefs for helper classes that we forward-declare in .h file
// (so that nsFlexContainerFrame methods can use them as parameters):
typedef nsFlexContainerFrame::FlexItem FlexItem;
typedef nsFlexContainerFrame::FlexLine FlexLine;
typedef nsFlexContainerFrame::FlexboxAxisTracker FlexboxAxisTracker;
typedef nsFlexContainerFrame::StrutInfo StrutInfo;
#ifdef PR_LOGGING
static PRLogModuleInfo*
GetFlexContainerLog()
@ -198,7 +205,7 @@ MarginComponentForSide(nsMargin& aMargin, Side aSide)
IsAxisHorizontal((axisTracker_).GetCrossAxis()) ? (width_) : (height_)
// Encapsulates our flex container's main & cross axes.
class MOZ_STACK_CLASS FlexboxAxisTracker {
class MOZ_STACK_CLASS nsFlexContainerFrame::FlexboxAxisTracker {
public:
FlexboxAxisTracker(nsFlexContainerFrame* aFlexContainerFrame);
@ -273,8 +280,9 @@ private:
// Represents a flex item.
// Includes the various pieces of input that the Flexbox Layout Algorithm uses
// to resolve a flexible width.
class FlexItem {
class nsFlexContainerFrame::FlexItem {
public:
// Normal constructor:
FlexItem(nsIFrame* aChildFrame,
float aFlexGrow, float aFlexShrink, nscoord aMainBaseSize,
nscoord aMainMinSize, nscoord aMainMaxSize,
@ -282,6 +290,9 @@ public:
nsMargin aMargin, nsMargin aBorderPadding,
const FlexboxAxisTracker& aAxisTracker);
// Simplified constructor, to be used only for generating "struts":
FlexItem(nsIFrame* aChildFrame, nscoord aCrossSize);
// Accessors
nsIFrame* Frame() const { return mFrame; }
nscoord GetFlexBaseSize() const { return mFlexBaseSize; }
@ -323,6 +334,10 @@ public:
// cross axis).
bool IsStretched() const { return mIsStretched; }
// Indicates whether this item is a "strut" left behind by an element with
// visibility:collapse.
bool IsStrut() const { return mIsStrut; }
uint8_t GetAlignSelf() const { return mAlignSelf; }
// Returns the flex weight that we should use in the "resolving flexible
@ -540,6 +555,8 @@ protected:
bool mHadMeasuringReflow; // Did this item get a preliminary reflow,
// to measure its desired height?
bool mIsStretched; // See IsStretched() documentation
bool mIsStrut; // Is this item a "strut" left behind by an element
// with visibility:collapse?
uint8_t mAlignSelf; // My "align-self" computed value (with "auto"
// swapped out for parent"s "align-items" value,
// in our constructor).
@ -547,7 +564,7 @@ protected:
// Represents a single flex line in a flex container.
// Manages an array of the FlexItems that are in the line.
class FlexLine {
class nsFlexContainerFrame::FlexLine {
public:
FlexLine()
: mTotalInnerHypotheticalMainSize(0),
@ -611,6 +628,43 @@ private:
nscoord mBaselineOffsetFromCrossStart;
};
// Information about a strut left behind by a FlexItem that's been collapsed
// using "visibility:collapse".
struct nsFlexContainerFrame::StrutInfo {
StrutInfo(uint32_t aItemIdx, nscoord aStrutCrossSize)
: mItemIdx(aItemIdx),
mStrutCrossSize(aStrutCrossSize)
{
}
uint32_t mItemIdx; // Index in the child list.
nscoord mStrutCrossSize; // The cross-size of this strut.
};
static void
BuildStrutInfoFromCollapsedItems(nsTArray<FlexLine>& aLines,
nsTArray<StrutInfo>& aStruts)
{
MOZ_ASSERT(aStruts.IsEmpty(),
"We should only build up StrutInfo once per reflow, so "
"aStruts should be empty when this is called");
uint32_t itemIdxInContainer = 0;
for (uint32_t lineIdx = 0; lineIdx < aLines.Length(); lineIdx++) {
FlexLine& line = aLines[lineIdx];
for (uint32_t i = 0; i < line.mItems.Length(); ++i) {
FlexItem& item = line.mItems[i];
if (NS_STYLE_VISIBILITY_COLLAPSE ==
item.Frame()->StyleVisibility()->mVisible) {
// Note the cross size of the line as the item's strut size.
aStruts.AppendElement(StrutInfo(itemIdxInContainer,
line.GetLineCrossSize()));
}
itemIdxInContainer++;
}
}
}
// Helper-function to find the first non-anonymous-box descendent of aFrame.
static nsIFrame*
GetFirstNonAnonBoxDescendant(nsIFrame* aFrame)
@ -995,9 +1049,12 @@ FlexItem::FlexItem(nsIFrame* aChildFrame,
mHadMaxViolation(false),
mHadMeasuringReflow(false),
mIsStretched(false),
mIsStrut(false),
mAlignSelf(aChildFrame->StylePosition()->mAlignSelf)
{
MOZ_ASSERT(aChildFrame, "expecting a non-null child frame");
MOZ_ASSERT(mFrame, "expecting a non-null child frame");
MOZ_ASSERT(!mFrame->IsAbsolutelyPositioned(),
"abspos child frames should not be treated as flex items");
SetFlexBaseSizeAndMainSize(aFlexBaseSize);
@ -1037,6 +1094,42 @@ FlexItem::FlexItem(nsIFrame* aChildFrame,
}
}
// Simplified constructor for creating a special "strut" FlexItem, for a child
// with visibility:collapse. The strut has 0 main-size, and it only exists to
// impose a minimum cross size on whichever FlexLine it ends up in.
FlexItem::FlexItem(nsIFrame* aChildFrame, nscoord aCrossSize)
: mFrame(aChildFrame),
mFlexGrow(0.0f),
mFlexShrink(0.0f),
// mBorderPadding uses default constructor,
// mMargin uses default constructor,
mFlexBaseSize(0),
mMainMinSize(0),
mMainMaxSize(0),
mCrossMinSize(0),
mCrossMaxSize(0),
mMainSize(0),
mMainPosn(0),
mCrossSize(aCrossSize),
mCrossPosn(0),
mAscent(0),
mShareOfFlexWeightSoFar(0.0f),
mIsFrozen(true),
mHadMinViolation(false),
mHadMaxViolation(false),
mHadMeasuringReflow(false),
mIsStretched(false),
mIsStrut(true), // (this is the constructor for making struts, after all)
mAlignSelf(NS_STYLE_ALIGN_ITEMS_FLEX_START)
{
MOZ_ASSERT(mFrame, "expecting a non-null child frame");
MOZ_ASSERT(NS_STYLE_VISIBILITY_COLLAPSE ==
mFrame->StyleVisibility()->mVisible,
"Should only make struts for children with 'visibility:collapse'");
MOZ_ASSERT(!mFrame->IsAbsolutelyPositioned(),
"abspos child frames should not be treated as flex items");
}
nscoord
FlexItem::GetBaselineOffsetFromOuterCrossStart(
AxisOrientationType aCrossAxis) const
@ -2175,6 +2268,7 @@ nsFlexContainerFrame::GenerateFlexLines(
const nsHTMLReflowState& aReflowState,
nscoord aContentBoxMainSize,
nscoord aAvailableHeightForContent,
const nsTArray<StrutInfo>& aStruts,
const FlexboxAxisTracker& aAxisTracker,
nsTArray<FlexLine>& aLines)
{
@ -2219,6 +2313,14 @@ nsFlexContainerFrame::GenerateFlexLines(
}
}
// Tracks the index of the next strut, in aStruts (and when this hits
// aStruts.Length(), that means there are no more struts):
uint32_t nextStrutIdx = 0;
// Overall index of the current flex item in the flex container. (This gets
// checked against entries in aStruts.)
uint32_t itemIdxInContainer = 0;
for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
nsIFrame* childFrame = e.get();
@ -2228,13 +2330,24 @@ nsFlexContainerFrame::GenerateFlexLines(
curLine = aLines.AppendElement();
}
FlexItem* item = curLine->mItems.AppendElement(
GenerateFlexItemForChild(aPresContext, childFrame,
aReflowState, aAxisTracker));
FlexItem* item;
if (nextStrutIdx < aStruts.Length() &&
aStruts[nextStrutIdx].mItemIdx == itemIdxInContainer) {
// Use the simplified "strut" FlexItem constructor:
item = curLine->mItems.AppendElement(
FlexItem(childFrame, aStruts[nextStrutIdx].mStrutCrossSize));
nextStrutIdx++;
} else {
item = curLine->mItems.AppendElement(
GenerateFlexItemForChild(aPresContext, childFrame,
aReflowState, aAxisTracker));
nsresult rv = ResolveFlexItemMaxContentSizing(aPresContext, *item,
aReflowState, aAxisTracker);
NS_ENSURE_SUCCESS(rv,rv);
}
nsresult rv = ResolveFlexItemMaxContentSizing(aPresContext, *item,
aReflowState, aAxisTracker);
NS_ENSURE_SUCCESS(rv,rv);
nscoord itemInnerHypotheticalMainSize = item->GetMainSize();
nscoord itemOuterHypotheticalMainSize = item->GetMainSize() +
item->GetMarginBorderPaddingSizeInAxis(aAxisTracker.GetMainAxis());
@ -2272,6 +2385,7 @@ nsFlexContainerFrame::GenerateFlexLines(
childFrame->StyleDisplay()->mBreakAfter) {
curLine = aLines.AppendElement();
}
itemIdxInContainer++;
}
return NS_OK;
@ -2608,8 +2722,6 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
return NS_OK;
}
aStatus = NS_FRAME_COMPLETE;
// We (and our children) can only depend on our ancestor's height if we have
// a percent-height, or if we're positioned and we have "top" and "bottom"
// set and have height:auto. (There are actually other cases, too -- e.g. if
@ -2646,9 +2758,6 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
const FlexboxAxisTracker axisTracker(this);
nscoord contentBoxMainSize = GetMainSizeFromReflowState(aReflowState,
axisTracker);
// If we're being fragmented into a constrained height, subtract off
// borderpadding-top from it, to get the available height for our
// content box. (Don't subtract if we're skipping top border/padding,
@ -2661,20 +2770,51 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
availableHeightForContent = std::max(availableHeightForContent, 0);
}
nscoord contentBoxMainSize = GetMainSizeFromReflowState(aReflowState,
axisTracker);
nsAutoTArray<StrutInfo, 1> struts;
nsresult rv = DoFlexLayout(aPresContext, aDesiredSize, aReflowState, aStatus,
contentBoxMainSize, availableHeightForContent,
struts, axisTracker);
if (NS_SUCCEEDED(rv) && !struts.IsEmpty()) {
// We're restarting flex layout, with new knowledge of collapsed items.
rv = DoFlexLayout(aPresContext, aDesiredSize, aReflowState, aStatus,
contentBoxMainSize, availableHeightForContent,
struts, axisTracker);
}
return rv;
}
nsresult
nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
nscoord aContentBoxMainSize,
nscoord aAvailableHeightForContent,
nsTArray<StrutInfo>& aStruts,
const FlexboxAxisTracker& aAxisTracker)
{
aStatus = NS_FRAME_COMPLETE;
// Generate an array of our flex items (already sorted), in a FlexLine.
nsAutoTArray<FlexLine, 1> lines;
nsresult rv = GenerateFlexLines(aPresContext, aReflowState,
contentBoxMainSize, availableHeightForContent,
axisTracker, lines);
aContentBoxMainSize,
aAvailableHeightForContent,
aStruts, aAxisTracker, lines);
NS_ENSURE_SUCCESS(rv, rv);
contentBoxMainSize =
ClampFlexContainerMainSize(aReflowState, axisTracker,
contentBoxMainSize, availableHeightForContent,
aContentBoxMainSize =
ClampFlexContainerMainSize(aReflowState, aAxisTracker,
aContentBoxMainSize, aAvailableHeightForContent,
lines, aStatus);
for (uint32_t i = 0; i < lines.Length(); i++) {
lines[i].ResolveFlexibleLengths(contentBoxMainSize);
lines[i].ResolveFlexibleLengths(aContentBoxMainSize);
}
// Cross Size Determination - Flexbox spec section 9.4
@ -2685,21 +2825,21 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
for (uint32_t i = 0; i < line.mItems.Length(); ++i) {
FlexItem& curItem = line.mItems[i];
// (If the item's already been stretched, then it already knows its
// cross size. Don't bother trying to recalculate it.)
if (!curItem.IsStretched()) {
// (If the item's already been stretched, or it's a strut, then it
// already knows its cross size. Don't bother trying to recalculate it.)
if (!curItem.IsStretched() && !curItem.IsStrut()) {
nsHTMLReflowState childReflowState(aPresContext, aReflowState,
curItem.Frame(),
nsSize(aReflowState.ComputedWidth(),
NS_UNCONSTRAINEDSIZE));
// Override computed main-size
if (IsAxisHorizontal(axisTracker.GetMainAxis())) {
if (IsAxisHorizontal(aAxisTracker.GetMainAxis())) {
childReflowState.SetComputedWidth(curItem.GetMainSize());
} else {
childReflowState.SetComputedHeight(curItem.GetMainSize());
}
nsresult rv = SizeItemInCrossAxis(aPresContext, axisTracker,
nsresult rv = SizeItemInCrossAxis(aPresContext, aAxisTracker,
childReflowState, curItem);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -2709,19 +2849,32 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
// Calculate the cross size and (if necessary) baseline-alignment position
// for each of our flex lines:
for (uint32_t lineIdx = 0; lineIdx < lines.Length(); ++lineIdx) {
lines[lineIdx].ComputeCrossSizeAndBaseline(axisTracker);
lines[lineIdx].ComputeCrossSizeAndBaseline(aAxisTracker);
}
bool isCrossSizeDefinite;
const nscoord contentBoxCrossSize =
ComputeCrossSize(aReflowState, axisTracker, lines,
availableHeightForContent, &isCrossSizeDefinite, aStatus);
ComputeCrossSize(aReflowState, aAxisTracker, lines,
aAvailableHeightForContent, &isCrossSizeDefinite, aStatus);
// Set up state for cross-axis alignment, at a high level (outside the
// scope of a particular flex line)
CrossAxisPositionTracker
crossAxisPosnTracker(lines, aReflowState.mStylePosition->mAlignContent,
contentBoxCrossSize, isCrossSizeDefinite, axisTracker);
contentBoxCrossSize, isCrossSizeDefinite,
aAxisTracker);
// Now that we know the cross size of each line (including
// "align-content:stretch" adjustments, from the CrossAxisPositionTracker
// constructor), we can create struts for any flex items with
// "visibility: collapse" (and restart flex layout).
if (aStruts.IsEmpty()) { // (Don't make struts if we already did)
BuildStrutInfoFromCollapsedItems(lines, aStruts);
if (!aStruts.IsEmpty()) {
// Restart flex layout, using our struts.
return NS_OK;
}
}
// Set the flex container's baseline, from the baseline-alignment position
// of the first line's baseline-aligned items.
@ -2744,7 +2897,7 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
flexContainerAscent = aReflowState.ComputedPhysicalBorderPadding().top +
PhysicalPosFromLogicalPos(firstLineBaselineOffsetWRTContainer,
contentBoxCrossSize,
axisTracker.GetCrossAxis());
aAxisTracker.GetCrossAxis());
}
for (uint32_t lineIdx = 0; lineIdx < lines.Length(); ++lineIdx) {
@ -2753,13 +2906,13 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
// Main-Axis Alignment - Flexbox spec section 9.5
// ==============================================
line.PositionItemsInMainAxis(aReflowState.mStylePosition->mJustifyContent,
contentBoxMainSize,
axisTracker);
aContentBoxMainSize,
aAxisTracker);
// Cross-Axis Alignment - Flexbox spec section 9.6
// ===============================================
line.PositionItemsInCrossAxis(crossAxisPosnTracker.GetPosition(),
axisTracker);
aAxisTracker);
crossAxisPosnTracker.TraverseLine(line);
crossAxisPosnTracker.TraversePackingSpace();
}
@ -2779,10 +2932,10 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
for (uint32_t i = 0; i < line.mItems.Length(); ++i) {
FlexItem& curItem = line.mItems[i];
nsPoint physicalPosn = axisTracker.PhysicalPointFromLogicalPoint(
nsPoint physicalPosn = aAxisTracker.PhysicalPointFromLogicalPoint(
curItem.GetMainPosition(),
curItem.GetCrossPosition(),
contentBoxMainSize,
aContentBoxMainSize,
contentBoxCrossSize);
// Adjust physicalPosn to be relative to the container's border-box
// (i.e. its frame rect), instead of the container's content-box:
@ -2799,7 +2952,7 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
bool didOverrideComputedHeight = false;
// Override computed main-size
if (IsAxisHorizontal(axisTracker.GetMainAxis())) {
if (IsAxisHorizontal(aAxisTracker.GetMainAxis())) {
childReflowState.SetComputedWidth(curItem.GetMainSize());
didOverrideComputedWidth = true;
} else {
@ -2811,7 +2964,7 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
if (curItem.IsStretched()) {
MOZ_ASSERT(curItem.GetAlignSelf() == NS_STYLE_ALIGN_ITEMS_STRETCH,
"stretched item w/o 'align-self: stretch'?");
if (IsAxisHorizontal(axisTracker.GetCrossAxis())) {
if (IsAxisHorizontal(aAxisTracker.GetCrossAxis())) {
childReflowState.SetComputedWidth(curItem.GetCrossSize());
didOverrideComputedWidth = true;
} else {
@ -2884,8 +3037,8 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
}
nsSize desiredContentBoxSize =
axisTracker.PhysicalSizeFromLogicalSizes(contentBoxMainSize,
contentBoxCrossSize);
aAxisTracker.PhysicalSizeFromLogicalSizes(aContentBoxMainSize,
contentBoxCrossSize);
aDesiredSize.Width() = desiredContentBoxSize.width +
containerBorderPadding.LeftRight();

View File

@ -17,11 +17,6 @@ nsIFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
typedef nsContainerFrame nsFlexContainerFrameSuper;
class FlexItem;
class FlexLine;
class FlexboxAxisTracker;
class MainAxisPositionTracker;
class SingleLineCrossAxisPositionTracker;
template <class T> class nsTArray;
class nsFlexContainerFrame : public nsFlexContainerFrameSuper {
@ -34,6 +29,12 @@ class nsFlexContainerFrame : public nsFlexContainerFrameSuper {
nsStyleContext* aContext);
public:
// Forward-decls of helper classes
class FlexItem;
class FlexLine;
class FlexboxAxisTracker;
class StrutInfo;
// nsIFrame overrides
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
@ -64,6 +65,29 @@ protected:
{}
virtual ~nsFlexContainerFrame();
/*
* This method does the bulk of the flex layout, implementing the algorithm
* described at:
* http://dev.w3.org/csswg/css-flexbox/#layout-algorithm
* (with a few initialization pieces happening in the caller, Reflow().
*
* Since this is a helper for Reflow(), this takes all the same parameters
* as Reflow(), plus a few more parameters that Reflow() sets up for us.
*
* (The logic behind the division of work between Reflow and DoFlexLayout is
* as follows: DoFlexLayout() begins at the step that we have to jump back
* to, if we find any visibility:collapse children, and Reflow() does
* everything before that point.)
*/
nsresult DoFlexLayout(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
nscoord aContentBoxMainSize,
nscoord aAvailableHeightForContent,
nsTArray<StrutInfo>& aStruts,
const FlexboxAxisTracker& aAxisTracker);
/**
* Checks whether our child-frame list "mFrames" is sorted, using the given
* IsLessThanOrEqual function, and sorts it if it's not already sorted.
@ -98,6 +122,7 @@ protected:
const nsHTMLReflowState& aReflowState,
nscoord aContentBoxMainSize,
nscoord aAvailableHeightForContent,
const nsTArray<StrutInfo>& aStruts,
const FlexboxAxisTracker& aAxisTracker,
nsTArray<FlexLine>& aLines);

View File

@ -0,0 +1,62 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!-- In this reference case, we get each container to be sized the same as
in the testcase, without any visible baseline alignemnt, by using some
hidden flex items.
-->
<html>
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
width: 50px;
background: yellow;
border: 1px dotted black;
margin: 5px;
align-items: flex-start;
}
.hiddenItemForSizing {
width: 0;
color: transparent;
align-self: baseline;
}
.largeFont {
font-size: 20px;
background: lightblue;
/* Our flex items get padding on opposite sides (top/bottom) so that they
produce a large combined height when baseline-aligned: */
padding-top: 5px;
}
.smallFont {
font-size: 10px;
background: pink;
/* Our flex items get padding on opposite sides (top/bottom) so that they
produce a large combined height when baseline-aligned: */
padding-bottom: 20px;
}
</style>
</head>
<body>
<div class="flexContainer">
<div class="largeFont">a</div>
<!-- Hidden flex items used to determine container's cross size,
based on their baseline-aligned combined cross size: -->
<div class="largeFont hiddenItemForSizing">a</div>
<div class="smallFont hiddenItemForSizing">b</div>
</div>
<div class="flexContainer">
<div class="smallFont">b</div>
<!-- Hidden flex items used to determine container's cross size,
based on their baseline-aligned combined cross size: -->
<div class="largeFont hiddenItemForSizing">a</div>
<div class="smallFont hiddenItemForSizing">b</div>
</div>
</body>
</html>

View File

@ -0,0 +1,54 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Test: Testing that a collapsed flex item participates in baseline alignment only for the purpose of establishing container's cross size</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<link rel="help" href="http://www.w3.org/TR/css3-flexbox/#algo-visibility">
<link rel="match" href="flexbox-collapsed-item-baseline-1-ref.html">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
width: 50px;
background: yellow;
border: 1px dotted black;
margin: 5px;
align-items: baseline;
}
.collapse {
visibility: collapse;
}
.largeFont {
font-size: 20px;
background: lightblue;
/* Our flex items get padding on opposite sides (top/bottom) so that they
produce a large combined height when baseline-aligned: */
padding-top: 5px;
}
.smallFont {
font-size: 10px;
background: pink;
/* Our flex items get padding on opposite sides (top/bottom) so that they
produce a large combined height when baseline-aligned: */
padding-bottom: 20px;
}
</style>
</head>
<body>
<!-- Second item collapsed: -->
<div class="flexContainer">
<div class="largeFont">a</div>
<div class="smallFont collapse">b</div>
</div>
<!-- First item collapsed: -->
<div class="flexContainer">
<div class="largeFont collapse">a</div>
<div class="smallFont">b</div>
</div>
</body>
</html>

View File

@ -0,0 +1,102 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!-- In this reference case, we have blocks in place of the testcase's
flex containers. The testcase's collapsed flex items are entirely
absent here (and the remaining content is sized using exact pixel
values).
-->
<html>
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
background: yellow;
border: 1px dotted black;
float: left;
margin: 5px;
}
.flexContainer > * {
/* All flex items have 20px base size */
width: 20px;
}
.collapse {
flex-basis: 0;
height: 20px;
}
.flexible {
flex: 1 auto;
}
.heightTall {
height: 40px;
background: purple;
}
.heightAuto {
background: teal;
}
.heightShort {
height: 10px;
background: pink;
}
</style>
</head>
<body>
<!-- FIRST ROW: -->
<!-- Just one (collapsed) flex item, which ends up establishing
the container's size (even though it's collapsed): -->
<div class="flexContainer">
<div class="heightTall collapse"></div>
</div>
<div style="clear: both"></div>
<!-- SECOND ROW: -->
<!-- One collapsed flex item, one short flex item.
(Container ends up with collapsed item's height) -->
<div class="flexContainer">
<div class="heightTall collapse"></div>
<div class="heightShort"></div>
</div>
<!-- (same, but with items in opposite order) -->
<div class="flexContainer">
<div class="heightShort"></div>
<div class="heightTall collapse"></div>
</div>
<div style="clear: both"></div>
<!-- THIRD ROW: -->
<!-- One collapsed flex item, one stretched flex item.
(Container and stretched item end up with collapsed item's height) -->
<div class="flexContainer">
<div class="heightTall collapse"></div>
<div class="heightAuto"></div>
</div>
<!-- (again, with items in opposite order) -->
<div class="flexContainer">
<div class="heightAuto"></div>
<div class="heightTall collapse"></div>
</div>
<div style="clear: both"></div>
<!-- FOURTH ROW: -->
<!-- One collapsed flex item, one other flex item; both are flexible.
(The non-collapsed one should take all of the available width.) -->
<div class="flexContainer">
<div class="heightAuto collapse"></div>
<div class="heightTall flexible"></div>
</div>
<!-- (again, with items in opposite order) -->
<div class="flexContainer">
<div class="heightTall flexible"></div>
<div class="heightAuto collapse"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,98 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Test: Testing that visibility:collapse on a flex item in a single-line flex container maintains the containers's cross size, but doesn't otherwise impact flex layout</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<link rel="help" href="http://www.w3.org/TR/css3-flexbox/#algo-visibility">
<link rel="match" href="flexbox-collapsed-item-horiz-1-ref.html">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
background: yellow;
border: 1px dotted black;
float: left;
margin: 5px;
}
.flexContainer > * {
/* All flex items have 20px base size */
width: 20px;
}
.collapse {
visibility: collapse;
}
.flexible {
flex: 1 auto;
}
.heightTall {
height: 40px;
background: purple;
}
.heightAuto {
background: teal;
}
.heightShort {
height: 10px;
background: pink;
}
</style>
</head>
<body>
<!-- FIRST ROW: -->
<!-- Just one (collapsed) flex item, which ends up establishing
the container's size (even though it's collapsed): -->
<div class="flexContainer">
<div class="heightTall collapse"></div>
</div>
<div style="clear: both"></div>
<!-- SECOND ROW: -->
<!-- One collapsed flex item, one short flex item.
(Container ends up with collapsed item's height) -->
<div class="flexContainer">
<div class="heightTall collapse"></div>
<div class="heightShort"></div>
</div>
<!-- (same, but with items in opposite order) -->
<div class="flexContainer">
<div class="heightShort"></div>
<div class="heightTall collapse"></div>
</div>
<div style="clear: both"></div>
<!-- THIRD ROW: -->
<!-- One collapsed flex item, one stretched flex item.
(Container and stretched item end up with collapsed item's height) -->
<div class="flexContainer">
<div class="heightTall collapse"></div>
<div class="heightAuto"></div>
</div>
<!-- (again, with items in opposite order) -->
<div class="flexContainer">
<div class="heightAuto"></div>
<div class="heightTall collapse"></div>
</div>
<div style="clear: both"></div>
<!-- FOURTH ROW: -->
<!-- One collapsed flex item, one other flex item; both are flexible.
(The non-collapsed one should take all of the available width.) -->
<div class="flexContainer">
<div class="heightAuto flexible collapse"></div>
<div class="heightTall flexible"></div>
</div>
<!-- (again, with items in opposite order) -->
<div class="flexContainer">
<div class="heightTall flexible"></div>
<div class="heightAuto flexible collapse"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,108 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
flex-wrap: wrap;
/* These let us show where each flex line begins (and hence, how tall
the flex lines end up) */
align-content: flex-start;
align-items: flex-start;
width: 30px;
background: yellow;
border: 1px dotted black;
float: left;
margin: 5px;
}
.collapsedItem {
width: 0;
height: 25px;
}
.halfWidthItem {
width: 15px;
height: 15px;
background: teal;
}
.fullWidthItem {
width: 30px;
height: 20px;
background: purple;
}
.veryTallItem {
width: 15px;
height: 40px;
background: olive;
}
</style>
</head>
<body>
<!-- FIRST ROW: -->
<!-- One collapsed flex item, at the beginning of a flex line, which
ends up establishing its flex line's cross size: -->
<div class="flexContainer">
<div class="collapsedItem"></div>
<div class="halfWidthItem"></div>
<div class="fullWidthItem"></div>
</div>
<!-- ...and now with it being at the end of that flex line: -->
<div class="flexContainer">
<div class="halfWidthItem"></div>
<div class="collapsedItem"></div>
<div class="fullWidthItem"></div>
</div>
<div style="clear: both"></div>
<!-- SECOND ROW: -->
<!-- One collapsed flex item, initially in its own line. It ends
up being merged into another line after it collapses, due to its
(post-collapse) zero main-size. -->
<div class="flexContainer">
<div class="collapsedItem"></div>
<div class="fullWidthItem"></div>
<div class="fullWidthItem"></div>
</div>
<div class="flexContainer">
<div class="fullWidthItem"></div>
<div class="collapsedItem"></div>
<div class="fullWidthItem"></div>
</div>
<div class="flexContainer">
<div class="fullWidthItem"></div>
<div class="fullWidthItem"></div>
<div class="collapsedItem"></div>
</div>
<div style="clear: both"></div>
<!-- THIRD ROW: -->
<!-- One collapsed flex item, initially in a line with an even-taller item.
The collapsed item ends up shifting into another line after it
collapses, but it carries the taller item's cross size with it, as its
strut size. -->
<div class="flexContainer">
<div class="fullWidthItem"></div>
<div class="collapsedItem" style="height: 40px"></div>
<div class="veryTallItem"></div>
</div>
<!-- ...and now with two (differently-sized) struts in first line:
(the one that's taller - due to being initially grouped with the tall
item - wins out.) -->
<div class="flexContainer">
<div class="collapsedItem"></div>
<div class="fullWidthItem"></div>
<div class="collapsedItem" style="height: 40px"></div>
<div class="veryTallItem"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,111 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Test: Testing that visibility:collapse on a flex item in a multi-line flex container creates struts, and that they can migrate between lines</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<link rel="help" href="http://www.w3.org/TR/css3-flexbox/#algo-visibility">
<link rel="match" href="flexbox-collapsed-item-horiz-2-ref.html">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
flex-wrap: wrap;
/* These let us show where each flex line begins (and hence, how tall
the flex lines end up) */
align-content: flex-start;
align-items: flex-start;
width: 30px;
background: yellow;
border: 1px dotted black;
float: left;
margin: 5px;
}
.collapsedItem {
visibility: collapse;
width: 15px;
height: 25px;
}
.halfWidthItem {
width: 15px;
height: 15px;
background: teal;
}
.fullWidthItem {
width: 30px;
height: 20px;
background: purple;
}
.veryTallItem {
width: 15px;
height: 40px;
background: olive;
}
</style>
</head>
<body>
<!-- FIRST ROW: -->
<!-- One collapsed flex item, at the beginning of a flex line, which
ends up establishing its flex line's cross size: -->
<div class="flexContainer">
<div class="collapsedItem"></div>
<div class="halfWidthItem"></div>
<div class="fullWidthItem"></div>
</div>
<!-- ...and now with it being at the end of that flex line: -->
<div class="flexContainer">
<div class="halfWidthItem"></div>
<div class="collapsedItem"></div>
<div class="fullWidthItem"></div>
</div>
<div style="clear: both"></div>
<!-- SECOND ROW: -->
<!-- One collapsed flex item, initially in its own line. It ends
up being merged into another line after it collapses, due to its
(post-collapse) zero main-size. -->
<div class="flexContainer">
<div class="collapsedItem"></div>
<div class="fullWidthItem"></div>
<div class="fullWidthItem"></div>
</div>
<div class="flexContainer">
<div class="fullWidthItem"></div>
<div class="collapsedItem"></div>
<div class="fullWidthItem"></div>
</div>
<div class="flexContainer">
<div class="fullWidthItem"></div>
<div class="fullWidthItem"></div>
<div class="collapsedItem"></div>
</div>
<div style="clear: both"></div>
<!-- THIRD ROW: -->
<!-- One collapsed flex item, initially in a line with an even-taller item.
The collapsed item ends up shifting into another line after it
collapses, but it carries the taller item's cross size with it, as its
strut size. -->
<div class="flexContainer">
<div class="fullWidthItem"></div>
<div class="collapsedItem"></div>
<div class="veryTallItem"></div>
</div>
<!-- ...and now with two (differently-sized) struts in first line:
(the one that's taller - due to being initially grouped with the tall
item - wins out.) -->
<div class="flexContainer">
<div class="collapsedItem"></div>
<div class="fullWidthItem"></div>
<div class="collapsedItem"></div>
<div class="veryTallItem"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
flex-wrap: wrap;
align-content: stretch; /* Initial value; just here for emphasis */
width: 25px;
height: 60px;
background: yellow;
border: 1px dotted black;
float: left;
margin: 5px;
}
.collapsedItem {
width: 0;
height: 40px;
}
.shortItem {
width: 25px;
height: 10px;
background: purple;
}
.tallItem {
width: 10px;
height: 30px;
background: olive;
}
</style>
</head>
<body>
<div class="flexContainer">
<div class="shortItem"></div>
<div class="collapsedItem"></div>
<div class="tallItem"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,56 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Test: Testing that strut formation (from visibility:collapse) happens *after* lines have been stretched</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<link rel="help" href="http://www.w3.org/TR/css3-flexbox/#algo-visibility">
<link rel="match" href="flexbox-collapsed-item-horiz-3-ref.html">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
flex-wrap: wrap;
align-content: stretch; /* Initial value; just here for emphasis */
width: 25px;
height: 60px;
background: yellow;
border: 1px dotted black;
float: left;
margin: 5px;
}
.collapsedItem {
visibility: collapse;
width: 10px;
}
.shortItem {
width: 25px;
height: 10px;
background: purple;
}
.tallItem {
width: 10px;
height: 30px;
background: olive;
}
</style>
</head>
<body>
<!-- In this testcase, the first flex line initially has a cross-size of
10px, and the second flex line has a cross-size of 30px. Both lines are
stretched by 10px each (to hit the container's total cross-size, 60px).
Then, we handle "visibility:collapse" and convert the collapsed item
into a strut with the second line's stretched cross-size (40px), and we
restart flex layout. This strut then ends up in the *first* line (since
it has 0 main-size), which means both flex lines end up being 40px tall.
-->
<div class="flexContainer">
<div class="shortItem"></div>
<div class="collapsedItem"></div>
<div class="tallItem"></div>
</div>
</body>
</html>

View File

@ -77,6 +77,12 @@ fuzzy-if(Android,158,32) == flexbox-align-self-vert-rtl-1.xhtml flexbox-align-s
== flexbox-break-request-vert-2a.html flexbox-break-request-vert-2-ref.html
== flexbox-break-request-vert-2b.html flexbox-break-request-vert-2-ref.html
# Tests for flex items with "visibility:collapse"
== flexbox-collapsed-item-baseline-1.html flexbox-collapsed-item-baseline-1-ref.html
== flexbox-collapsed-item-horiz-1.html flexbox-collapsed-item-horiz-1-ref.html
== flexbox-collapsed-item-horiz-2.html flexbox-collapsed-item-horiz-2-ref.html
== flexbox-collapsed-item-horiz-3.html flexbox-collapsed-item-horiz-3-ref.html
# Tests for flex-flow shorthand property
== flexbox-flex-flow-1.html flexbox-flex-flow-1-ref.html

View File

@ -1,41 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
LOCAL_INCLUDES += \
-I$(srcdir)/include \
-I$(srcdir)/celt \
-I$(srcdir)/silk \
-I$(srcdir)/src \
$(NULL)
VPATH += \
$(srcdir)/celt \
$(srcdir)/silk \
$(srcdir)/src \
$(NULL)
include $(srcdir)/celt_sources.mk
include $(srcdir)/silk_sources.mk
include $(srcdir)/opus_sources.mk
CSRCS = \
$(notdir $(CELT_SOURCES)) \
$(notdir $(SILK_SOURCES)) \
$(notdir $(OPUS_SOURCES)) \
$(NULL)
ifndef MOZ_SAMPLE_TYPE_FLOAT32
MOZ_OPUS_FIXED = 1
endif
ifdef MOZ_OPUS_FIXED
LOCAL_INCLUDES += -I$(srcdir)/silk/fixed
VPATH += $(srcdir)/silk/fixed
CSRCS += $(notdir $(SILK_SOURCES_FIXED))
else
LOCAL_INCLUDES += -I$(srcdir)/silk/float
VPATH += $(srcdir)/silk/float
CSRCS += $(notdir $(SILK_SOURCES_FLOAT)) \
$(notdir $(OPUS_SOURCES_FLOAT))
endif

View File

@ -1,28 +0,0 @@
CELT_SOURCES = celt/bands.c \
celt/celt.c \
celt/celt_encoder.c \
celt/celt_decoder.c \
celt/cwrs.c \
celt/entcode.c \
celt/entdec.c \
celt/entenc.c \
celt/kiss_fft.c \
celt/laplace.c \
celt/mathops.c \
celt/mdct.c \
celt/modes.c \
celt/pitch.c \
celt/celt_lpc.c \
celt/quant_bands.c \
celt/rate.c \
celt/vq.c
CELT_SOURCES_ARM = \
celt/arm/armcpu.c \
celt/arm/arm_celt_map.c
CELT_SOURCES_ARM_ASM = \
celt/arm/celt_pitch_xcorr_arm.s
CELT_AM_SOURCES_ARM_ASM = \
celt/arm/armopts.s.in

View File

@ -0,0 +1,70 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# This file takes the .mk files from an upstream opus repo and generates the
# sources.mozbuild file. It is invoked as part of update.sh
import sys
import re
def add_value(values, text):
text = text.replace('\\', '')
text = text.strip()
if text:
values.append(text)
def write_values(output, values):
for value in sorted(values, key=lambda x: x.lower()):
output.write(" '%s',\n" % value)
output.write(']\n\n')
def generate_sources_mozbuild(path):
makefiles = [
'celt_sources.mk',
'opus_sources.mk',
'silk_sources.mk',
]
var_definition = re.compile('([A-Z_]*) = (.*)')
with open('sources.mozbuild', 'w') as output:
output.write('# THIS FILE WAS AUTOMATICALLY GENERATED BY %s. DO NOT EDIT.\n' % sys.argv[0])
for makefile in makefiles:
values = []
definition_started = False
with open('%s/%s' % (path, makefile), 'r') as mk:
for line in mk:
line = line.rstrip()
result = var_definition.match(line)
if result:
if definition_started:
write_values(output, values)
values = []
definition_started = True
# Some variable definitions have the first entry on the
# first line. Eg:
#
# CELT_SOURCES = celt/bands.c
#
# So we treat the first group as the variable name and
# the second group as a potential value.
#
# Note that we write the variable name in lower case (so
# "CELT_SOURCES" in the .mk file becomes "celt_sources"
# in the .mozbuild file) because moz.build reserves
# upper-case variable names for build system outputs.
output.write('%s = [\n' % result.group(1).lower())
add_value(values, result.group(2))
else:
add_value(values, line)
write_values(output, values)
if __name__ == '__main__':
if len(sys.argv) != 2:
print "Usage: %s /path/to/opus" % (sys.argv[0])
sys.exit(1)
generate_sources_mozbuild(sys.argv[1])

View File

@ -37,3 +37,30 @@ if CONFIG['OS_ARCH'] == 'SunOS':
if not CONFIG['MOZ_SAMPLE_TYPE_FLOAT32']:
DEFINES['FIXED_POINT'] = 1
DEFINES['DISABLE_FLOAT_API'] = True
LOCAL_INCLUDES += [
'celt',
'include',
'silk',
'src',
]
# sources.mozbuild is generated from gen-sources.py when a new libopus is
# imported.
include('sources.mozbuild')
SOURCES += celt_sources
SOURCES += silk_sources
SOURCES += opus_sources
if CONFIG['MOZ_SAMPLE_TYPE_FLOAT32']:
LOCAL_INCLUDES += [
'silk/float',
]
SOURCES += silk_sources_float
SOURCES += opus_sources_float
else:
LOCAL_INCLUDES += [
'silk/fixed',
]
SOURCES += silk_sources_fixed

View File

@ -1,12 +0,0 @@
OPUS_SOURCES = src/opus.c \
src/opus_decoder.c \
src/opus_encoder.c \
src/opus_multistream.c \
src/opus_multistream_encoder.c \
src/opus_multistream_decoder.c \
src/repacketizer.c
OPUS_SOURCES_FLOAT = \
src/analysis.c \
src/mlp.c \
src/mlp_data.c

View File

@ -1,138 +0,0 @@
SILK_SOURCES = \
silk/CNG.c \
silk/code_signs.c \
silk/init_decoder.c \
silk/decode_core.c \
silk/decode_frame.c \
silk/decode_parameters.c \
silk/decode_indices.c \
silk/decode_pulses.c \
silk/decoder_set_fs.c \
silk/dec_API.c \
silk/enc_API.c \
silk/encode_indices.c \
silk/encode_pulses.c \
silk/gain_quant.c \
silk/interpolate.c \
silk/LP_variable_cutoff.c \
silk/NLSF_decode.c \
silk/NSQ.c \
silk/NSQ_del_dec.c \
silk/PLC.c \
silk/shell_coder.c \
silk/tables_gain.c \
silk/tables_LTP.c \
silk/tables_NLSF_CB_NB_MB.c \
silk/tables_NLSF_CB_WB.c \
silk/tables_other.c \
silk/tables_pitch_lag.c \
silk/tables_pulses_per_block.c \
silk/VAD.c \
silk/control_audio_bandwidth.c \
silk/quant_LTP_gains.c \
silk/VQ_WMat_EC.c \
silk/HP_variable_cutoff.c \
silk/NLSF_encode.c \
silk/NLSF_VQ.c \
silk/NLSF_unpack.c \
silk/NLSF_del_dec_quant.c \
silk/process_NLSFs.c \
silk/stereo_LR_to_MS.c \
silk/stereo_MS_to_LR.c \
silk/check_control_input.c \
silk/control_SNR.c \
silk/init_encoder.c \
silk/control_codec.c \
silk/A2NLSF.c \
silk/ana_filt_bank_1.c \
silk/biquad_alt.c \
silk/bwexpander_32.c \
silk/bwexpander.c \
silk/debug.c \
silk/decode_pitch.c \
silk/inner_prod_aligned.c \
silk/lin2log.c \
silk/log2lin.c \
silk/LPC_analysis_filter.c \
silk/LPC_inv_pred_gain.c \
silk/table_LSF_cos.c \
silk/NLSF2A.c \
silk/NLSF_stabilize.c \
silk/NLSF_VQ_weights_laroia.c \
silk/pitch_est_tables.c \
silk/resampler.c \
silk/resampler_down2_3.c \
silk/resampler_down2.c \
silk/resampler_private_AR2.c \
silk/resampler_private_down_FIR.c \
silk/resampler_private_IIR_FIR.c \
silk/resampler_private_up2_HQ.c \
silk/resampler_rom.c \
silk/sigm_Q15.c \
silk/sort.c \
silk/sum_sqr_shift.c \
silk/stereo_decode_pred.c \
silk/stereo_encode_pred.c \
silk/stereo_find_predictor.c \
silk/stereo_quant_pred.c
SILK_SOURCES_FIXED = \
silk/fixed/LTP_analysis_filter_FIX.c \
silk/fixed/LTP_scale_ctrl_FIX.c \
silk/fixed/corrMatrix_FIX.c \
silk/fixed/encode_frame_FIX.c \
silk/fixed/find_LPC_FIX.c \
silk/fixed/find_LTP_FIX.c \
silk/fixed/find_pitch_lags_FIX.c \
silk/fixed/find_pred_coefs_FIX.c \
silk/fixed/noise_shape_analysis_FIX.c \
silk/fixed/prefilter_FIX.c \
silk/fixed/process_gains_FIX.c \
silk/fixed/regularize_correlations_FIX.c \
silk/fixed/residual_energy16_FIX.c \
silk/fixed/residual_energy_FIX.c \
silk/fixed/solve_LS_FIX.c \
silk/fixed/warped_autocorrelation_FIX.c \
silk/fixed/apply_sine_window_FIX.c \
silk/fixed/autocorr_FIX.c \
silk/fixed/burg_modified_FIX.c \
silk/fixed/k2a_FIX.c \
silk/fixed/k2a_Q16_FIX.c \
silk/fixed/pitch_analysis_core_FIX.c \
silk/fixed/vector_ops_FIX.c \
silk/fixed/schur64_FIX.c \
silk/fixed/schur_FIX.c
SILK_SOURCES_FLOAT = \
silk/float/apply_sine_window_FLP.c \
silk/float/corrMatrix_FLP.c \
silk/float/encode_frame_FLP.c \
silk/float/find_LPC_FLP.c \
silk/float/find_LTP_FLP.c \
silk/float/find_pitch_lags_FLP.c \
silk/float/find_pred_coefs_FLP.c \
silk/float/LPC_analysis_filter_FLP.c \
silk/float/LTP_analysis_filter_FLP.c \
silk/float/LTP_scale_ctrl_FLP.c \
silk/float/noise_shape_analysis_FLP.c \
silk/float/prefilter_FLP.c \
silk/float/process_gains_FLP.c \
silk/float/regularize_correlations_FLP.c \
silk/float/residual_energy_FLP.c \
silk/float/solve_LS_FLP.c \
silk/float/warped_autocorrelation_FLP.c \
silk/float/wrappers_FLP.c \
silk/float/autocorrelation_FLP.c \
silk/float/burg_modified_FLP.c \
silk/float/bwexpander_FLP.c \
silk/float/energy_FLP.c \
silk/float/inner_product_FLP.c \
silk/float/k2a_FLP.c \
silk/float/levinsondurbin_FLP.c \
silk/float/LPC_inv_pred_gain_FLP.c \
silk/float/pitch_analysis_core_FLP.c \
silk/float/scale_copy_vector_FLP.c \
silk/float/scale_vector_FLP.c \
silk/float/schur_FLP.c \
silk/float/sort_FLP.c

View File

@ -0,0 +1,192 @@
# THIS FILE WAS AUTOMATICALLY GENERATED BY gen-sources.py. DO NOT EDIT.
celt_sources = [
'celt/bands.c',
'celt/celt.c',
'celt/celt_decoder.c',
'celt/celt_encoder.c',
'celt/celt_lpc.c',
'celt/cwrs.c',
'celt/entcode.c',
'celt/entdec.c',
'celt/entenc.c',
'celt/kiss_fft.c',
'celt/laplace.c',
'celt/mathops.c',
'celt/mdct.c',
'celt/modes.c',
'celt/pitch.c',
'celt/quant_bands.c',
'celt/rate.c',
'celt/vq.c',
]
celt_sources_arm = [
'celt/arm/arm_celt_map.c',
'celt/arm/armcpu.c',
]
celt_sources_arm_asm = [
'celt/arm/celt_pitch_xcorr_arm.s',
]
celt_am_sources_arm_asm = [
'celt/arm/armopts.s.in',
]
opus_sources = [
'src/opus.c',
'src/opus_decoder.c',
'src/opus_encoder.c',
'src/opus_multistream.c',
'src/opus_multistream_decoder.c',
'src/opus_multistream_encoder.c',
'src/repacketizer.c',
]
opus_sources_float = [
'src/analysis.c',
'src/mlp.c',
'src/mlp_data.c',
]
silk_sources = [
'silk/A2NLSF.c',
'silk/ana_filt_bank_1.c',
'silk/biquad_alt.c',
'silk/bwexpander.c',
'silk/bwexpander_32.c',
'silk/check_control_input.c',
'silk/CNG.c',
'silk/code_signs.c',
'silk/control_audio_bandwidth.c',
'silk/control_codec.c',
'silk/control_SNR.c',
'silk/debug.c',
'silk/dec_API.c',
'silk/decode_core.c',
'silk/decode_frame.c',
'silk/decode_indices.c',
'silk/decode_parameters.c',
'silk/decode_pitch.c',
'silk/decode_pulses.c',
'silk/decoder_set_fs.c',
'silk/enc_API.c',
'silk/encode_indices.c',
'silk/encode_pulses.c',
'silk/gain_quant.c',
'silk/HP_variable_cutoff.c',
'silk/init_decoder.c',
'silk/init_encoder.c',
'silk/inner_prod_aligned.c',
'silk/interpolate.c',
'silk/lin2log.c',
'silk/log2lin.c',
'silk/LP_variable_cutoff.c',
'silk/LPC_analysis_filter.c',
'silk/LPC_inv_pred_gain.c',
'silk/NLSF2A.c',
'silk/NLSF_decode.c',
'silk/NLSF_del_dec_quant.c',
'silk/NLSF_encode.c',
'silk/NLSF_stabilize.c',
'silk/NLSF_unpack.c',
'silk/NLSF_VQ.c',
'silk/NLSF_VQ_weights_laroia.c',
'silk/NSQ.c',
'silk/NSQ_del_dec.c',
'silk/pitch_est_tables.c',
'silk/PLC.c',
'silk/process_NLSFs.c',
'silk/quant_LTP_gains.c',
'silk/resampler.c',
'silk/resampler_down2.c',
'silk/resampler_down2_3.c',
'silk/resampler_private_AR2.c',
'silk/resampler_private_down_FIR.c',
'silk/resampler_private_IIR_FIR.c',
'silk/resampler_private_up2_HQ.c',
'silk/resampler_rom.c',
'silk/shell_coder.c',
'silk/sigm_Q15.c',
'silk/sort.c',
'silk/stereo_decode_pred.c',
'silk/stereo_encode_pred.c',
'silk/stereo_find_predictor.c',
'silk/stereo_LR_to_MS.c',
'silk/stereo_MS_to_LR.c',
'silk/stereo_quant_pred.c',
'silk/sum_sqr_shift.c',
'silk/table_LSF_cos.c',
'silk/tables_gain.c',
'silk/tables_LTP.c',
'silk/tables_NLSF_CB_NB_MB.c',
'silk/tables_NLSF_CB_WB.c',
'silk/tables_other.c',
'silk/tables_pitch_lag.c',
'silk/tables_pulses_per_block.c',
'silk/VAD.c',
'silk/VQ_WMat_EC.c',
]
silk_sources_fixed = [
'silk/fixed/apply_sine_window_FIX.c',
'silk/fixed/autocorr_FIX.c',
'silk/fixed/burg_modified_FIX.c',
'silk/fixed/corrMatrix_FIX.c',
'silk/fixed/encode_frame_FIX.c',
'silk/fixed/find_LPC_FIX.c',
'silk/fixed/find_LTP_FIX.c',
'silk/fixed/find_pitch_lags_FIX.c',
'silk/fixed/find_pred_coefs_FIX.c',
'silk/fixed/k2a_FIX.c',
'silk/fixed/k2a_Q16_FIX.c',
'silk/fixed/LTP_analysis_filter_FIX.c',
'silk/fixed/LTP_scale_ctrl_FIX.c',
'silk/fixed/noise_shape_analysis_FIX.c',
'silk/fixed/pitch_analysis_core_FIX.c',
'silk/fixed/prefilter_FIX.c',
'silk/fixed/process_gains_FIX.c',
'silk/fixed/regularize_correlations_FIX.c',
'silk/fixed/residual_energy16_FIX.c',
'silk/fixed/residual_energy_FIX.c',
'silk/fixed/schur64_FIX.c',
'silk/fixed/schur_FIX.c',
'silk/fixed/solve_LS_FIX.c',
'silk/fixed/vector_ops_FIX.c',
'silk/fixed/warped_autocorrelation_FIX.c',
]
silk_sources_float = [
'silk/float/apply_sine_window_FLP.c',
'silk/float/autocorrelation_FLP.c',
'silk/float/burg_modified_FLP.c',
'silk/float/bwexpander_FLP.c',
'silk/float/corrMatrix_FLP.c',
'silk/float/encode_frame_FLP.c',
'silk/float/energy_FLP.c',
'silk/float/find_LPC_FLP.c',
'silk/float/find_LTP_FLP.c',
'silk/float/find_pitch_lags_FLP.c',
'silk/float/find_pred_coefs_FLP.c',
'silk/float/inner_product_FLP.c',
'silk/float/k2a_FLP.c',
'silk/float/levinsondurbin_FLP.c',
'silk/float/LPC_analysis_filter_FLP.c',
'silk/float/LPC_inv_pred_gain_FLP.c',
'silk/float/LTP_analysis_filter_FLP.c',
'silk/float/LTP_scale_ctrl_FLP.c',
'silk/float/noise_shape_analysis_FLP.c',
'silk/float/pitch_analysis_core_FLP.c',
'silk/float/prefilter_FLP.c',
'silk/float/process_gains_FLP.c',
'silk/float/regularize_correlations_FLP.c',
'silk/float/residual_energy_FLP.c',
'silk/float/scale_copy_vector_FLP.c',
'silk/float/scale_vector_FLP.c',
'silk/float/schur_FLP.c',
'silk/float/solve_LS_FLP.c',
'silk/float/sort_FLP.c',
'silk/float/warped_autocorrelation_FLP.c',
'silk/float/wrappers_FLP.c',
]

View File

@ -43,7 +43,7 @@ for file in ${SRC_FILES}; do
done
# copy files into the target directory
for file in ${STATIC_FILES} ${MK_FILES} ${SRC_FILES} ${HDR_FILES}; do
for file in ${STATIC_FILES} ${SRC_FILES} ${HDR_FILES}; do
cmd="cp $1/${file} ${TARGET}/${file}"
echo ${cmd}
${cmd}
@ -65,5 +65,7 @@ sed -e "s/DEFINES\['OPUS_VERSION'\][ \t]*=[ \t]*'\".*\"'/DEFINES['OPUS_VERSION']
${TARGET}/moz.build > ${TARGET}/moz.build+ && \
mv ${TARGET}/moz.build+ ${TARGET}/moz.build
python gen-sources.py $1
# apply outstanding local patches
# ... no patches to apply ...

View File

@ -485,22 +485,16 @@ public class BrowserToolbar extends GeckoRelativeLayout
}
switch (msg) {
case TITLE:
flags.add(UpdateFlags.TITLE);
break;
case START:
updateBackButton(tab);
updateForwardButton(tab);
break;
case STOP:
updateBackButton(tab);
updateForwardButton(tab);
// Reset the title in case we haven't navigated
// to a new page yet.
flags.add(UpdateFlags.TITLE);
// Fall through.
case START:
case CLOSED:
case ADDED:
updateBackButton(tab);
updateForwardButton(tab);
break;
case SELECTED:
@ -510,13 +504,18 @@ public class BrowserToolbar extends GeckoRelativeLayout
case LOCATION_CHANGE:
// A successful location change will cause Tab to notify
// us of a title change, so we don't update the title here.
refreshState();
break;
flags.add(UpdateFlags.FAVICON);
flags.add(UpdateFlags.SITE_IDENTITY);
flags.add(UpdateFlags.PRIVATE_MODE);
case CLOSED:
case ADDED:
updateBackButton(tab);
updateForwardButton(tab);
setPrivateMode(tab.isPrivate());
break;
case TITLE:
flags.add(UpdateFlags.TITLE);
break;
case FAVICON:
@ -1249,6 +1248,24 @@ public class BrowserToolbar extends GeckoRelativeLayout
mActionItemBar.removeView(actionItem);
}
@Override
public void setPrivateMode(boolean isPrivate) {
super.setPrivateMode(isPrivate);
mTabs.setPrivateMode(isPrivate);
mMenu.setPrivateMode(isPrivate);
mMenuIcon.setPrivateMode(isPrivate);
mUrlEditLayout.setPrivateMode(isPrivate);
if (mBack instanceof BackButton) {
((BackButton) mBack).setPrivateMode(isPrivate);
}
if (mForward instanceof ForwardButton) {
((ForwardButton) mForward).setPrivateMode(isPrivate);
}
}
public void show() {
setVisibility(View.VISIBLE);
}
@ -1257,30 +1274,6 @@ public class BrowserToolbar extends GeckoRelativeLayout
setVisibility(View.GONE);
}
private void refreshState() {
Tab tab = Tabs.getInstance().getSelectedTab();
if (tab != null) {
updateDisplayLayout(tab, EnumSet.of(UpdateFlags.FAVICON,
UpdateFlags.SITE_IDENTITY,
UpdateFlags.PRIVATE_MODE));
updateBackButton(tab);
updateForwardButton(tab);
final boolean isPrivate = tab.isPrivate();
setPrivateMode(isPrivate);
mTabs.setPrivateMode(isPrivate);
mMenu.setPrivateMode(isPrivate);
mMenuIcon.setPrivateMode(isPrivate);
mUrlEditLayout.setPrivateMode(isPrivate);
if (mBack instanceof BackButton)
((BackButton) mBack).setPrivateMode(isPrivate);
if (mForward instanceof ForwardButton)
((ForwardButton) mForward).setPrivateMode(isPrivate);
}
}
public View getDoorHangerAnchor() {
return mUrlDisplayLayout.getDoorHangerAnchor();
}

View File

@ -1 +1 @@
NSPR_4_10_3_BETA1
NSPR_4_10_3_BETA2

View File

@ -10,3 +10,4 @@
*/
#error "Do not include this header file."

View File

@ -1856,7 +1856,11 @@ NSPR_API(PRStatus) PR_CloseFileMap(PRFileMap *fmap);
/*
* Synchronously flush the given memory-mapped address range of the given open
* file to disk.
* file to disk. The function does not return until all modified data have
* been written to disk.
*
* On some platforms, the function will call PR_Sync(fd) internally if it is
* necessary for flushing modified data to disk synchronously.
*/
NSPR_API(PRStatus) PR_SyncMemMap(
PRFileDesc *fd,

View File

@ -3614,14 +3614,9 @@ PRStatus _MD_MemUnmap(void *addr, PRUint32 len)
{
if (munmap(addr, len) == 0) {
return PR_SUCCESS;
} else {
if (errno == EINVAL) {
PR_SetError(PR_INVALID_ARGUMENT_ERROR, errno);
} else {
PR_SetError(PR_UNKNOWN_ERROR, errno);
}
return PR_FAILURE;
}
_PR_MD_MAP_DEFAULT_ERROR(errno);
return PR_FAILURE;
}
PRStatus _MD_CloseFileMap(PRFileMap *fmap)
@ -3643,16 +3638,13 @@ PRStatus _MD_SyncMemMap(
void *addr,
PRUint32 len)
{
/* msync(..., MS_SYNC) alone is sufficient to flush modified data to disk
* synchronously. It is not necessary to call fsync. */
if (msync(addr, len, MS_SYNC) == 0) {
return PR_SUCCESS;
} else {
if (errno == EINVAL) {
PR_SetError(PR_INVALID_ARGUMENT_ERROR, errno);
} else {
PR_SetError(PR_UNKNOWN_ERROR, errno);
}
return PR_FAILURE;
}
_PR_MD_MAP_DEFAULT_ERROR(errno);
return PR_FAILURE;
}
#if defined(_PR_NEED_FAKE_POLL)

View File

@ -982,10 +982,9 @@ PRStatus _MD_MemUnmap(void *addr, PRUint32 len)
{
if (UnmapViewOfFile(addr)) {
return PR_SUCCESS;
} else {
PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
return PR_FAILURE;
}
_PR_MD_MAP_DEFAULT_ERROR(GetLastError());
return PR_FAILURE;
}
PRStatus _MD_CloseFileMap(PRFileMap *fmap)
@ -1000,16 +999,18 @@ PRStatus _MD_SyncMemMap(
void *addr,
PRUint32 len)
{
PROsfd osfd;
osfd = ( fd == (PRFileDesc*)-1 )? -1 : fd->secret->md.osfd;
PROsfd osfd = fd->secret->md.osfd;
/* The FlushViewOfFile page on MSDN says:
* To flush all the dirty pages plus the metadata for the file and
* ensure that they are physically written to disk, call
* FlushViewOfFile and then call the FlushFileBuffers function.
*/
if (FlushViewOfFile(addr, len) && FlushFileBuffers((HANDLE) osfd)) {
return PR_SUCCESS;
} else {
PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
return PR_FAILURE;
}
_PR_MD_MAP_DEFAULT_ERROR(GetLastError());
return PR_FAILURE;
}
/*

View File

@ -229,7 +229,6 @@ EXPORTS ;-
PR_Malloc;
PR_MemMap;
PR_MemUnmap;
PR_SyncMemMap;
PR_MicrosecondsToInterval;
PR_MillisecondsToInterval;
PR_LockOrderedLock;
@ -452,3 +451,7 @@ EXPORTS ;-
PR_GetThreadName;
PR_SetCurrentThreadName;
;+} NSPR_4.8.9;
;+NSPR_4.10.3 {
;+ global:
PR_SyncMemMap;
;+} NSPR_4.9.2;

View File

@ -980,10 +980,11 @@ void _PR_InitThreads(
* nothing.
*/
rv = _PT_PTHREAD_KEY_CREATE(&pt_book.key, _pt_thread_death);
if (0 != rv) PR_Abort();
if (0 != rv)
PR_Assert("0 == rv", __FILE__, __LINE__);
pt_book.keyCreated = PR_TRUE;
rv = pthread_setspecific(pt_book.key, thred);
if (0 != rv) PR_Abort();
PR_ASSERT(0 == rv);
} /* _PR_InitThreads */
#ifdef __GNUC__
@ -1048,7 +1049,8 @@ void _PR_Fini(void)
* PR_Cleanup has been called already. */
if (pt_book.keyCreated)
{
pthread_key_delete(pt_book.key);
rv = pthread_key_delete(pt_book.key);
PR_ASSERT(0 == rv);
pt_book.keyCreated = PR_FALSE;
}
return;
@ -1067,6 +1069,7 @@ void _PR_Fini(void)
}
rv = pthread_key_delete(pt_book.key);
PR_ASSERT(0 == rv);
pt_book.keyCreated = PR_FALSE;
/* TODO: free other resources used by NSPR */
/* _pr_initialized = PR_FALSE; */
} /* _PR_Fini */

View File

@ -197,15 +197,15 @@ PR_IMPLEMENT(void) PR_Lock(PRLock *lock)
PR_ASSERT(!(me->flags & _PR_IDLE_THREAD));
PR_ASSERT(lock != NULL);
#ifdef _PR_GLOBAL_THREADS_ONLY
PR_ASSERT(lock->owner != me);
_PR_MD_LOCK(&lock->ilock);
PR_ASSERT(lock->owner == 0);
lock->owner = me;
return;
#else /* _PR_GLOBAL_THREADS_ONLY */
if (_native_threads_only) {
PR_ASSERT(lock->owner != me);
_PR_MD_LOCK(&lock->ilock);
PR_ASSERT(lock->owner == 0);
lock->owner = me;
return;
}

View File

@ -226,7 +226,8 @@ int err;
/*
* update thread's lock rank
*/
_PR_SET_THREAD_RWLOCK_RANK(rwlock);
if (rwlock->rw_rank != PR_RWLOCK_RANK_NONE)
_PR_SET_THREAD_RWLOCK_RANK(rwlock);
#endif
}
@ -282,7 +283,8 @@ int err;
/*
* update thread's lock rank
*/
_PR_SET_THREAD_RWLOCK_RANK(rwlock);
if (rwlock->rw_rank != PR_RWLOCK_RANK_NONE)
_PR_SET_THREAD_RWLOCK_RANK(rwlock);
#endif
}
@ -347,7 +349,8 @@ int err;
/*
* update thread's lock rank
*/
_PR_UNSET_THREAD_RWLOCK_RANK(rwlock);
if (rwlock->rw_rank != PR_RWLOCK_RANK_NONE)
_PR_UNSET_THREAD_RWLOCK_RANK(rwlock);
#endif
return;
}
@ -429,7 +432,8 @@ _PR_GET_THREAD_RWLOCK_RANK(void)
{
thread_rwlock_stack *lock_stack;
if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key)) == NULL)
lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key);
if (lock_stack == NULL || lock_stack->trs_index == 0)
return (PR_RWLOCK_RANK_NONE);
else
return(lock_stack->trs_stack[lock_stack->trs_index - 1]->rw_rank);
@ -452,9 +456,8 @@ _PR_UNSET_THREAD_RWLOCK_RANK(PRRWLock *rwlock)
PR_ASSERT(lock_stack != NULL);
index = lock_stack->trs_index - 1;
while (index-- >= 0) {
if ((lock_stack->trs_stack[index] == rwlock) && !done) {
for (index = lock_stack->trs_index - 1; index >= 0; index--) {
if (!done && (lock_stack->trs_stack[index] == rwlock)) {
/*
* reset the slot for rwlock
*/
@ -465,7 +468,7 @@ _PR_UNSET_THREAD_RWLOCK_RANK(PRRWLock *rwlock)
* search for the lowest-numbered empty slot, above which there are
* no non-empty slots
*/
if ((lock_stack->trs_stack[index] != NULL) && !new_index)
if (!new_index && (lock_stack->trs_stack[index] != NULL))
new_index = index + 1;
if (done && new_index)
break;

View File

@ -119,6 +119,7 @@ CSRCS = \
randseed.c \
reinit.c \
rmdir.c \
rwlockrank.c \
rwlocktest.c \
sel_spd.c \
selct_er.c \

View File

@ -0,0 +1,120 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* RWLock rank tests
*/
#include "nspr.h"
#include "plgetopt.h"
static int _debug_on;
static PRRWLock *rwlock0;
static PRRWLock *rwlock1;
static PRRWLock *rwlock2;
static void rwtest(void *args)
{
PR_RWLock_Rlock(rwlock1);
PR_RWLock_Unlock(rwlock1);
PR_RWLock_Rlock(rwlock1);
PR_RWLock_Unlock(rwlock1);
// Test correct lock rank.
PR_RWLock_Rlock(rwlock1);
PR_RWLock_Rlock(rwlock2);
PR_RWLock_Unlock(rwlock2);
PR_RWLock_Unlock(rwlock1);
PR_RWLock_Rlock(rwlock1);
PR_RWLock_Rlock(rwlock2);
PR_RWLock_Unlock(rwlock1);
PR_RWLock_Unlock(rwlock2);
PR_RWLock_Rlock(rwlock1);
PR_RWLock_Rlock(rwlock0);
PR_RWLock_Rlock(rwlock2);
PR_RWLock_Unlock(rwlock2);
PR_RWLock_Unlock(rwlock0);
PR_RWLock_Unlock(rwlock1);
#if 0
// Test incorrect lock rank.
PR_RWLock_Rlock(rwlock2);
PR_RWLock_Rlock(rwlock1);
PR_RWLock_Unlock(rwlock1);
PR_RWLock_Unlock(rwlock2);
PR_RWLock_Rlock(rwlock2);
PR_RWLock_Rlock(rwlock0);
PR_RWLock_Rlock(rwlock1);
PR_RWLock_Unlock(rwlock1);
PR_RWLock_Unlock(rwlock0);
PR_RWLock_Unlock(rwlock2);
#endif
}
int main(int argc, char **argv)
{
PRStatus rc;
PRThread *thread;
PLOptStatus os;
PLOptState *opt = PL_CreateOptState(argc, argv, "d");
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
if (PL_OPT_BAD == os) continue;
switch (opt->option) {
case 'd': /* debug mode */
_debug_on = 1;
break;
default:
break;
}
}
PL_DestroyOptState(opt);
rwlock0 = PR_NewRWLock(PR_RWLOCK_RANK_NONE, "Lock 0");
if (rwlock0 == NULL) {
fprintf(stderr, "PR_NewRWLock failed - error %d\n",
(int)PR_GetError());
return 1;
}
rwlock1 = PR_NewRWLock(1, "Lock 1");
if (rwlock1 == NULL) {
fprintf(stderr, "PR_NewRWLock failed - error %d\n",
(int)PR_GetError());
return 1;
}
rwlock2 = PR_NewRWLock(2, "Lock 2");
if (rwlock2 == NULL) {
fprintf(stderr, "PR_NewRWLock failed - error %d\n",
(int)PR_GetError());
return 1;
}
thread = PR_CreateThread(PR_USER_THREAD, rwtest, NULL, PR_PRIORITY_NORMAL,
PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
if (thread == NULL) {
fprintf(stderr, "PR_CreateThread failed - error %d\n",
(int)PR_GetError());
PR_ProcessExit(2);
}
if (_debug_on) {
printf("%s: created thread = %p\n", argv[0], thread);
}
rc = PR_JoinThread(thread);
PR_ASSERT(rc == PR_SUCCESS);
PR_DestroyRWLock(rwlock0);
rwlock0 = NULL;
PR_DestroyRWLock(rwlock1);
rwlock1 = NULL;
PR_DestroyRWLock(rwlock2);
rwlock2 = NULL;
printf("PASS\n");
return 0;
}

View File

@ -132,7 +132,7 @@ int main(int argc, char **argv)
PR_ProcessExit(2);
}
if (_debug_on)
PR_fprintf(output,"%s: created thread = 0x%x\n", argv[0],
PR_fprintf(output,"%s: created thread = %p\n", argv[0],
threads[cnt]);
}

View File

@ -5,6 +5,10 @@
from __future__ import unicode_literals
import sys
import os
import stat
import platform
import urllib2
from mach.decorators import (
CommandArgument,
@ -216,7 +220,6 @@ class PastebinProvider(object):
def pastebin(self, language, poster, duration, file):
import sys
import urllib
import urllib2
URL = 'http://pastebin.mozilla.org/'
@ -306,3 +309,69 @@ class ReviewboardToolsProvider(MachCommandBase):
# we fake it out.
sys.argv = ['rbt'] + args
return main()
@CommandProvider
class FormatProvider(MachCommandBase):
@Command('clang-format', category='devenv', allow_all_args=True,
description='Run clang-format on current changes')
@CommandArgument('args', nargs='...', help='Arguments to clang-format tool')
def clang_format(self, args):
if not args:
args = ['help']
fmt = "clang-format-3.5"
fmt_diff = "clang-format-diff-3.5"
# We are currently using a modified verion of clang-format hosted on people.mozilla.org.
# This is a temporary work around until we upstream the necessary changes and we can use
# a system version of clang-format. See bug 961541.
self.prompt = 1
plat = platform.system()
if plat == "Windows":
fmt += ".exe"
else:
arch = os.uname()[4]
if plat != "Linux" or arch != 'x86_64':
print("Unsupported platform " + plat + "/" + arch +
". Supported platforms are Windows/* and Linux/x86_64")
return 1
os.chdir(self.topsrcdir)
try:
if not self.locate_or_fetch(fmt):
return 1
clang_format_diff = self.locate_or_fetch(fmt_diff)
if not clang_format_diff:
return 1
except urllib2.HTTPError as e:
print("HTTP error {0}: {1}".format(e.code, e.reason))
return 1
from subprocess import Popen, PIPE
p1 = Popen(["hg", "diff", "-U0", "-r", "tip^", "--include", "glob:**.c", "--include", "glob:**.cpp",
"--include", "glob:**.h", "--exclude", "listfile:.clang-format-ignore"], stdout=PIPE)
p2 = Popen([sys.executable, clang_format_diff, "-i", "-p1", "-style=Mozilla"], stdin=p1.stdout)
return p2.communicate()[0]
def locate_or_fetch(self, root):
target = os.path.join(self._mach_context.state_dir, root)
if not os.path.exists(target):
site = "http://people.mozilla.org/~ajones/clang-format/"
if self.prompt and raw_input("Download clang-format executables from {0} (yN)? ".format(site)).lower() != 'y':
print("Download aborted.")
return 1
self.prompt = 0
u = site + root
print("Downloading {0} to {1}".format(u, target))
data = urllib2.urlopen(url=u).read()
temp = target + ".tmp"
with open(temp, "wb") as fh:
fh.write(data)
fh.close()
os.chmod(temp, os.stat(temp).st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
os.rename(temp, target)
return target

View File

@ -70,11 +70,9 @@ NS_IMETHODIMP nsColorPicker::Open(nsIColorPickerShownCallback *aColorPickerShown
title.Adopt(ToNewUTF8String(mTitle));
GtkWidget *color_chooser = gtk_color_selection_dialog_new(title);
GtkWindow *window = GTK_WINDOW(color_chooser);
gtk_window_set_modal(window, TRUE);
GtkWindow *parent_window = GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET));
if (parent_window) {
GtkWindow *window = GTK_WINDOW(color_chooser);
gtk_window_set_transient_for(window, parent_window);
gtk_window_set_destroy_with_parent(window, TRUE);
}