Merge inbound to m-c.

This commit is contained in:
Ryan VanderMeulen 2012-09-15 09:39:57 -04:00
commit ca60a72df2
24 changed files with 680 additions and 140 deletions

View File

@ -452,13 +452,13 @@ pref("app.update.staging.enabled", true);
pref("app.update.service.enabled", true);
// The URL hosting the update manifest.
pref("app.update.url", "http://update.boot2gecko.org/m2.5/updates.xml");
pref("app.update.url", "http://update.boot2gecko.org/nightly/update.xml");
// Interval at which update manifest is fetched. In units of seconds.
pref("app.update.interval", 3600); // 1 hour
pref("app.update.interval", 86400); // 1 day
// First interval to elapse before checking for update. In units of
// milliseconds. Capped at 10 seconds.
pref("app.update.timerFirstInterval", 30000);
pref("app.update.timerMinimumDelay", 30); // seconds
pref("app.update.timerFirstInterval", 3600000); // 1 hour
pref("app.update.timerMinimumDelay", 3600); // 1 hour in seconds
// Don't throttle background updates.
pref("app.update.download.backgroundInterval", 0);

View File

@ -2394,6 +2394,9 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
mMayStartLayout = false;
mHaveInputEncoding = true;
nsCOMPtr<nsIContentSecurityPolicy> csp;
nsresult rv = InitCSP(aChannel, getter_AddRefs(csp));
NS_ENSURE_SUCCESS(rv, rv);
if (aReset) {
Reset(aChannel, aLoadGroup);
@ -2423,29 +2426,39 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
NS_ENSURE_SUCCESS(rv, rv);
}
nsresult rv = InitCSP();
NS_ENSURE_SUCCESS(rv, rv);
if (csp) {
// Copy into principal
nsIPrincipal* principal = GetPrincipal();
principal->SetCsp(csp);
#ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("Inserted CSP into principal %p", principal));
#endif
}
return NS_OK;
}
nsresult
nsDocument::InitCSP()
nsDocument::InitCSP(nsIChannel* aChannel, nsIContentSecurityPolicy **aCSP)
{
*aCSP = nullptr;
if (CSPService::sCSPEnabled) {
nsAutoString cspHeaderValue;
nsAutoString cspROHeaderValue;
this->GetHeaderData(nsGkAtoms::headerCSP, cspHeaderValue);
this->GetHeaderData(nsGkAtoms::headerCSPReportOnly, cspROHeaderValue);
bool system = false;
nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager();
if (NS_SUCCEEDED(ssm->IsSystemPrincipal(NodePrincipal(), &system)) && system) {
// only makes sense to register new CSP if this document is not priviliged
nsAutoCString tCspHeaderValue, tCspROHeaderValue;
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
if (!httpChannel) {
// no CSP for non http channels
return NS_OK;
}
httpChannel->GetResponseHeader(
NS_LITERAL_CSTRING("x-content-security-policy"),
tCspHeaderValue);
httpChannel->GetResponseHeader(
NS_LITERAL_CSTRING("x-content-security-policy-report-only"),
tCspROHeaderValue);
NS_ConvertASCIItoUTF16 cspHeaderValue(tCspHeaderValue);
NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue);
if (cspHeaderValue.IsEmpty() && cspROHeaderValue.IsEmpty()) {
// no CSP header present, stop processing
@ -2457,8 +2470,8 @@ nsDocument::InitCSP()
#endif
nsresult rv;
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
mCSP = do_CreateInstance("@mozilla.org/contentsecuritypolicy;1", &rv);
nsCOMPtr<nsIContentSecurityPolicy> csp;
csp = do_CreateInstance("@mozilla.org/contentsecuritypolicy;1", &rv);
if (NS_FAILED(rv)) {
#ifdef PR_LOGGING
@ -2468,12 +2481,11 @@ nsDocument::InitCSP()
}
// Store the request context for violation reports
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
mCSP->ScanRequestData(httpChannel);
csp->ScanRequestData(httpChannel);
// Start parsing the policy
nsCOMPtr<nsIURI> chanURI;
mChannel->GetURI(getter_AddRefs(chanURI));
aChannel->GetURI(getter_AddRefs(chanURI));
#ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("CSP Loaded"));
@ -2484,7 +2496,7 @@ nsDocument::InitCSP()
// toss a warning into the error console, proceeding with enforcing the
// regular-strength CSP.
if (cspHeaderValue.IsEmpty()) {
mCSP->SetReportOnlyMode(true);
csp->SetReportOnlyMode(true);
// Need to tokenize the header value since multiple headers could be
// concatenated into one comma-separated list of policies.
@ -2492,7 +2504,7 @@ nsDocument::InitCSP()
nsCharSeparatedTokenizer tokenizer(cspROHeaderValue, ',');
while (tokenizer.hasMoreTokens()) {
const nsSubstring& policy = tokenizer.nextToken();
mCSP->RefinePolicy(policy, chanURI);
csp->RefinePolicy(policy, chanURI);
#ifdef PR_LOGGING
{
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
@ -2511,7 +2523,7 @@ nsDocument::InitCSP()
nsCharSeparatedTokenizer tokenizer(cspHeaderValue, ',');
while (tokenizer.hasMoreTokens()) {
const nsSubstring& policy = tokenizer.nextToken();
mCSP->RefinePolicy(policy, chanURI);
csp->RefinePolicy(policy, chanURI);
#ifdef PR_LOGGING
{
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
@ -2528,7 +2540,7 @@ nsDocument::InitCSP()
bool safeAncestry = false;
// PermitsAncestry sends violation reports when necessary
rv = mCSP->PermitsAncestry(docShell, &safeAncestry);
rv = csp->PermitsAncestry(docShell, &safeAncestry);
NS_ENSURE_SUCCESS(rv, rv);
if (!safeAncestry) {
@ -2537,24 +2549,10 @@ nsDocument::InitCSP()
("CSP doesn't like frame's ancestry, not loading."));
#endif
// stop! ERROR page!
mChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
}
}
//Copy into principal
nsIPrincipal* principal = GetPrincipal();
if (principal) {
principal->SetCsp(mCSP);
#ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("Inserted CSP into principal %p", principal));
}
else {
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("Couldn't copy CSP into absent principal %p", principal));
#endif
}
csp.forget(aCSP);
}
#ifdef PR_LOGGING
else { //CSP was not enabled!
@ -6791,8 +6789,6 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
"content-disposition",
"refresh",
"x-dns-prefetch-control",
"x-content-security-policy",
"x-content-security-policy-report-only",
"x-frame-options",
// add more http headers if you need
// XXXbz don't add content-location support without reading bug

View File

@ -1274,7 +1274,7 @@ private:
void DoUnblockOnload();
nsresult CheckFrameOptions();
nsresult InitCSP();
nsresult InitCSP(nsIChannel* aChannel, nsIContentSecurityPolicy **aCSP);
// Sets aElement to be the pending pointer lock element. Once this document's
// node principal's URI is granted the "fullscreen" permission, the pointer

View File

@ -440,7 +440,10 @@ AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
return DBUS_HANDLER_RESULT_HANDLED;
}
} else {
#ifdef DEBUG
LOG("agent handler %s: Unhandled event. Ignore.", __FUNCTION__);
#endif
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
if (!errorStr.IsEmpty()) {
@ -669,8 +672,18 @@ GetProperty(DBusMessageIter aIter, Properties* aPropertyTypes,
dbus_message_iter_recurse(&aIter, &prop_val);
type = aPropertyTypes[*aPropIndex].type;
NS_ASSERTION(dbus_message_iter_get_arg_type(&prop_val) == type,
"Iterator not type we expect!");
if(dbus_message_iter_get_arg_type(&prop_val) != type) {
NS_WARNING("Iterator not type we expect!");
nsAutoCString str;
str += "Property Name: ;";
str += NS_ConvertUTF16toUTF8(propertyName);
str += " Property Type Expected: ;";
str += type;
str += " Property Type Received: ";
str += dbus_message_iter_get_arg_type(&prop_val);
NS_WARNING(str.get());
return false;
}
BluetoothValue propertyValue;
switch (type) {
@ -982,6 +995,7 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
signalStr += " Signal not handled!";
NS_WARNING(signalStr.get());
#endif
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
if (!errorStr.IsEmpty()) {
@ -1077,8 +1091,6 @@ BluetoothDBusService::StopInternal()
return NS_OK;
}
RemoveReservedServicesInternal(sDefaultAdapterPath, sServiceHandles);
DBusError err;
dbus_error_init(&err);
for (uint32_t i = 0; i < ArrayLength(sBluetoothDBusSignals); ++i) {
@ -1167,7 +1179,6 @@ public:
path));
RegisterAgent(path);
AddReservedServices(path);
DispatchBluetoothReply(mRunnable, v, replyError);

View File

@ -292,6 +292,13 @@ child:
*/
HandleDoubleTap(nsIntPoint point);
/**
* Requests handling of a single tap. |point| is in CSS pixels, relative to
* the scroll offset. This message is expected to send a "mousedown" and
* "mouseup" series of events at this point.
*/
HandleSingleTap(nsIntPoint point);
/**
* Sending an activate message moves focus to the child.
*/

View File

@ -888,6 +888,19 @@ TabChild::RecvHandleDoubleTap(const nsIntPoint& aPoint)
return true;
}
bool
TabChild::RecvHandleSingleTap(const nsIntPoint& aPoint)
{
if (!mCx || !mTabChildGlobal) {
return true;
}
RecvMouseEvent(NS_LITERAL_STRING("mousedown"), aPoint.x, aPoint.y, 0, 1, 0, false);
RecvMouseEvent(NS_LITERAL_STRING("mouseup"), aPoint.x, aPoint.y, 0, 1, 0, false);
return true;
}
bool
TabChild::RecvActivate()
{
@ -936,61 +949,67 @@ TabChild::RecvMouseWheelEvent(const WheelEvent& event)
return true;
}
void
TabChild::DispatchSynthesizedMouseEvent(const nsTouchEvent& aEvent)
{
// Synthesize a phony mouse event.
uint32_t msg;
switch (aEvent.message) {
case NS_TOUCH_START:
msg = NS_MOUSE_BUTTON_DOWN;
break;
case NS_TOUCH_MOVE:
msg = NS_MOUSE_MOVE;
break;
case NS_TOUCH_END:
case NS_TOUCH_CANCEL:
msg = NS_MOUSE_BUTTON_UP;
break;
default:
MOZ_NOT_REACHED("Unknown touch event message");
}
nsIntPoint refPoint(0, 0);
if (aEvent.touches.Length()) {
refPoint = aEvent.touches[0]->mRefPoint;
}
nsMouseEvent event(true, msg, NULL,
nsMouseEvent::eReal, nsMouseEvent::eNormal);
event.refPoint = refPoint;
event.time = aEvent.time;
event.button = nsMouseEvent::eLeftButton;
if (msg != NS_MOUSE_MOVE) {
event.clickCount = 1;
}
DispatchWidgetEvent(event);
}
bool
TabChild::RecvRealTouchEvent(const nsTouchEvent& aEvent)
{
nsTouchEvent localEvent(aEvent);
nsEventStatus status = DispatchWidgetEvent(localEvent);
nsTouchEvent localEvent(aEvent);
nsEventStatus status = DispatchWidgetEvent(localEvent);
if (IsAsyncPanZoomEnabled()) {
nsCOMPtr<nsPIDOMWindow> outerWindow = do_GetInterface(mWebNav);
nsCOMPtr<nsPIDOMWindow> innerWindow = outerWindow->GetCurrentInnerWindow();
if (innerWindow && innerWindow->HasTouchEventListeners()) {
SendContentReceivedTouch(nsIPresShell::gPreventMouseEvents);
}
} else if (status != nsEventStatus_eConsumeNoDefault) {
DispatchSynthesizedMouseEvent(aEvent);
}
if (status == nsEventStatus_eConsumeNoDefault) {
return true;
}
// Synthesize a phony mouse event.
uint32_t msg;
switch (aEvent.message) {
case NS_TOUCH_START:
msg = NS_MOUSE_BUTTON_DOWN;
break;
case NS_TOUCH_MOVE:
msg = NS_MOUSE_MOVE;
break;
case NS_TOUCH_END:
case NS_TOUCH_CANCEL:
msg = NS_MOUSE_BUTTON_UP;
break;
default:
MOZ_NOT_REACHED("Unknown touch event message");
}
nsIntPoint refPoint(0, 0);
if (aEvent.touches.Length()) {
refPoint = aEvent.touches[0]->mRefPoint;
}
nsMouseEvent event(true, msg, NULL,
nsMouseEvent::eReal, nsMouseEvent::eNormal);
event.refPoint = refPoint;
event.time = aEvent.time;
event.button = nsMouseEvent::eLeftButton;
if (msg != NS_MOUSE_MOVE) {
event.clickCount = 1;
}
DispatchWidgetEvent(event);
return true;
return true;
}
bool
TabChild::RecvRealTouchMoveEvent(const nsTouchEvent& aEvent)
{
return RecvRealTouchEvent(aEvent);
return RecvRealTouchEvent(aEvent);
}
bool

View File

@ -183,6 +183,7 @@ public:
virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size);
virtual bool RecvUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
virtual bool RecvHandleDoubleTap(const nsIntPoint& aPoint);
virtual bool RecvHandleSingleTap(const nsIntPoint& aPoint);
virtual bool RecvActivate();
virtual bool RecvDeactivate();
virtual bool RecvMouseEvent(const nsString& aType,
@ -323,6 +324,9 @@ private:
void DispatchMessageManagerMessage(const nsAString& aMessageName,
const nsACString& aJSONData);
// Sends a simulated mouse event from a touch event for compatibility.
void DispatchSynthesizedMouseEvent(const nsTouchEvent& aEvent);
nsresult
BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
nsIURI* aURI,

View File

@ -252,6 +252,11 @@ void TabParent::HandleDoubleTap(const nsIntPoint& aPoint)
unused << SendHandleDoubleTap(aPoint);
}
void TabParent::HandleSingleTap(const nsIntPoint& aPoint)
{
unused << SendHandleSingleTap(aPoint);
}
void
TabParent::Activate()
{

View File

@ -152,6 +152,7 @@ public:
void UpdateDimensions(const nsRect& rect, const nsIntSize& size);
void UpdateFrame(const layers::FrameMetrics& aFrameMetrics);
void HandleDoubleTap(const nsIntPoint& aPoint);
void HandleSingleTap(const nsIntPoint& aPoint);
void Activate();
void Deactivate();

View File

@ -28,6 +28,10 @@ In this order:
see bug 680840. Probably not useful anymore now that we're on the new
preprocessor, but it doesn't hurt to keep it around a bit longer.
angle-faceforward-emu.patch
See bug 771406. Adds emulation for faceforward(float,float,float),
which is needed to prevent crashing on Mac+Intel.
In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
Therefore, changes made to the Makefile.in files should not be stored in the local .patch files.

View File

@ -0,0 +1,314 @@
From: Jeff Gilbert <jgilbert@mozilla.com>
Bug 771406 - Add emulation for GLSL faceforward() to ANGLE - r=bjacob
diff --git a/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp b/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp
--- a/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp
+++ b/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp
@@ -26,16 +26,22 @@ const char* kFunctionEmulationVertexSour
"#error no emulation for distance(vec3, vec3)",
"#error no emulation for distance(vec4, vec4)",
"#define webgl_dot_emu(x, y) ((x) * (y))",
"#error no emulation for dot(vec2, vec2)",
"#error no emulation for dot(vec3, vec3)",
"#error no emulation for dot(vec4, vec4)",
+ // |faceforward(N, I, Nref)| is |dot(NRef, I) < 0 ? N : -N|
+ "#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))",
+ "#error no emulation for faceforward(vec2, vec2, vec2)",
+ "#error no emulation for faceforward(vec3, vec3, vec3)",
+ "#error no emulation for faceforward(vec4, vec4, vec4)",
+
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
"#error no emulation for length(vec2)",
"#error no emulation for length(vec3)",
"#error no emulation for length(vec4)",
"#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))",
"#error no emulation for normalize(vec2)",
"#error no emulation for normalize(vec3)",
@@ -58,16 +64,22 @@ const char* kFunctionEmulationFragmentSo
"#error no emulation for distance(vec3, vec3)",
"#error no emulation for distance(vec4, vec4)",
"#define webgl_dot_emu(x, y) ((x) * (y))",
"#error no emulation for dot(vec2, vec2)",
"#error no emulation for dot(vec3, vec3)",
"#error no emulation for dot(vec4, vec4)",
+ // |faceforward(N, I, Nref)| is |dot(NRef, I) < 0 ? N : -N|
+ "#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))",
+ "#error no emulation for faceforward(vec2, vec2, vec2)",
+ "#error no emulation for faceforward(vec3, vec3, vec3)",
+ "#error no emulation for faceforward(vec4, vec4, vec4)",
+
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
"#error no emulation for length(vec2)",
"#error no emulation for length(vec3)",
"#error no emulation for length(vec4)",
"#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))",
"#error no emulation for normalize(vec2)",
"#error no emulation for normalize(vec3)",
@@ -89,16 +101,20 @@ const bool kFunctionEmulationVertexMask[
true, // TFunctionDistance1_1
false, // TFunctionDistance2_2
false, // TFunctionDistance3_3
false, // TFunctionDistance4_4
true, // TFunctionDot1_1
false, // TFunctionDot2_2
false, // TFunctionDot3_3
false, // TFunctionDot4_4
+ true, // TFunctionFaceForward1_1_1
+ false, // TFunctionFaceForward2_2_2
+ false, // TFunctionFaceForward3_3_3
+ false, // TFunctionFaceForward4_4_4
true, // TFunctionLength1
false, // TFunctionLength2
false, // TFunctionLength3
false, // TFunctionLength4
true, // TFunctionNormalize1
false, // TFunctionNormalize2
false, // TFunctionNormalize3
false, // TFunctionNormalize4
@@ -115,16 +131,20 @@ const bool kFunctionEmulationVertexMask[
false, // TFunctionDistance1_1
false, // TFunctionDistance2_2
false, // TFunctionDistance3_3
false, // TFunctionDistance4_4
false, // TFunctionDot1_1
false, // TFunctionDot2_2
false, // TFunctionDot3_3
false, // TFunctionDot4_4
+ false, // TFunctionFaceForward1_1_1
+ false, // TFunctionFaceForward2_2_2
+ false, // TFunctionFaceForward3_3_3
+ false, // TFunctionFaceForward4_4_4
false, // TFunctionLength1
false, // TFunctionLength2
false, // TFunctionLength3
false, // TFunctionLength4
false, // TFunctionNormalize1
false, // TFunctionNormalize2
false, // TFunctionNormalize3
false, // TFunctionNormalize4
@@ -146,16 +166,20 @@ const bool kFunctionEmulationFragmentMas
true, // TFunctionDistance1_1
false, // TFunctionDistance2_2
false, // TFunctionDistance3_3
false, // TFunctionDistance4_4
true, // TFunctionDot1_1
false, // TFunctionDot2_2
false, // TFunctionDot3_3
false, // TFunctionDot4_4
+ true, // TFunctionFaceForward1_1_1
+ false, // TFunctionFaceForward2_2_2
+ false, // TFunctionFaceForward3_3_3
+ false, // TFunctionFaceForward4_4_4
true, // TFunctionLength1
false, // TFunctionLength2
false, // TFunctionLength3
false, // TFunctionLength4
true, // TFunctionNormalize1
false, // TFunctionNormalize2
false, // TFunctionNormalize3
false, // TFunctionNormalize4
@@ -172,16 +196,20 @@ const bool kFunctionEmulationFragmentMas
false, // TFunctionDistance1_1
false, // TFunctionDistance2_2
false, // TFunctionDistance3_3
false, // TFunctionDistance4_4
false, // TFunctionDot1_1
false, // TFunctionDot2_2
false, // TFunctionDot3_3
false, // TFunctionDot4_4
+ false, // TFunctionFaceForward1_1_1
+ false, // TFunctionFaceForward2_2_2
+ false, // TFunctionFaceForward3_3_3
+ false, // TFunctionFaceForward4_4_4
false, // TFunctionLength1
false, // TFunctionLength2
false, // TFunctionLength3
false, // TFunctionLength4
false, // TFunctionNormalize1
false, // TFunctionNormalize2
false, // TFunctionNormalize3
false, // TFunctionNormalize4
@@ -239,25 +267,37 @@ public:
case EOpReflect:
case EOpRefract:
case EOpMul:
break;
default:
return true;
};
const TIntermSequence& sequence = node->getSequence();
- // Right now we only handle built-in functions with two parameters.
- if (sequence.size() != 2)
+ bool needToEmulate = false;
+
+ if (sequence.size() == 2) {
+ TIntermTyped* param1 = sequence[0]->getAsTyped();
+ TIntermTyped* param2 = sequence[1]->getAsTyped();
+ if (!param1 || !param2)
+ return true;
+ needToEmulate = mEmulator.SetFunctionCalled(
+ node->getOp(), param1->getType(), param2->getType());
+ } else if (sequence.size() == 3) {
+ TIntermTyped* param1 = sequence[0]->getAsTyped();
+ TIntermTyped* param2 = sequence[1]->getAsTyped();
+ TIntermTyped* param3 = sequence[2]->getAsTyped();
+ if (!param1 || !param2 || !param3)
+ return true;
+ needToEmulate = mEmulator.SetFunctionCalled(
+ node->getOp(), param1->getType(), param2->getType(), param3->getType());
+ } else {
return true;
- TIntermTyped* param1 = sequence[0]->getAsTyped();
- TIntermTyped* param2 = sequence[1]->getAsTyped();
- if (!param1 || !param2)
- return true;
- bool needToEmulate = mEmulator.SetFunctionCalled(
- node->getOp(), param1->getType(), param2->getType());
+ }
+
if (needToEmulate)
node->setUseEmulatedFunction();
}
return true;
}
private:
BuiltInFunctionEmulator& mEmulator;
@@ -286,16 +326,23 @@ bool BuiltInFunctionEmulator::SetFunctio
bool BuiltInFunctionEmulator::SetFunctionCalled(
TOperator op, const TType& param1, const TType& param2)
{
TBuiltInFunction function = IdentifyFunction(op, param1, param2);
return SetFunctionCalled(function);
}
bool BuiltInFunctionEmulator::SetFunctionCalled(
+ TOperator op, const TType& param1, const TType& param2, const TType& param3)
+{
+ TBuiltInFunction function = IdentifyFunction(op, param1, param2, param3);
+ return SetFunctionCalled(function);
+}
+
+bool BuiltInFunctionEmulator::SetFunctionCalled(
BuiltInFunctionEmulator::TBuiltInFunction function) {
if (function == TFunctionUnknown || mFunctionMask[function] == false)
return false;
for (size_t i = 0; i < mFunctions.size(); ++i) {
if (mFunctions[i] == function)
return true;
}
mFunctions.push_back(function);
@@ -377,16 +424,44 @@ BuiltInFunctionEmulator::IdentifyFunctio
}
if (function == TFunctionUnknown)
return TFunctionUnknown;
if (param1.isVector())
function += param1.getNominalSize() - 1;
return static_cast<TBuiltInFunction>(function);
}
+BuiltInFunctionEmulator::TBuiltInFunction
+BuiltInFunctionEmulator::IdentifyFunction(
+ TOperator op, const TType& param1, const TType& param2, const TType& param3)
+{
+ // Check that all params have the same type, length,
+ // and that they're not too large.
+ if (param1.isVector() != param2.isVector() ||
+ param2.isVector() != param3.isVector() ||
+ param1.getNominalSize() != param2.getNominalSize() ||
+ param2.getNominalSize() != param3.getNominalSize() ||
+ param1.getNominalSize() > 4)
+ return TFunctionUnknown;
+
+ unsigned int function = TFunctionUnknown;
+ switch (op) {
+ case EOpFaceForward:
+ function = TFunctionFaceForward1_1_1;
+ break;
+ default:
+ break;
+ }
+ if (function == TFunctionUnknown)
+ return TFunctionUnknown;
+ if (param1.isVector())
+ function += param1.getNominalSize() - 1;
+ return static_cast<TBuiltInFunction>(function);
+}
+
void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
TIntermNode* root)
{
ASSERT(root);
BuiltInFunctionEmulationMarker marker(*this);
root->traverse(&marker);
}
diff --git a/gfx/angle/src/compiler/BuiltInFunctionEmulator.h b/gfx/angle/src/compiler/BuiltInFunctionEmulator.h
--- a/gfx/angle/src/compiler/BuiltInFunctionEmulator.h
+++ b/gfx/angle/src/compiler/BuiltInFunctionEmulator.h
@@ -23,16 +23,18 @@ public:
// Records that a function is called by the shader and might needs to be
// emulated. If the function's group is not in mFunctionGroupFilter, this
// becomes an no-op.
// Returns true if the function call needs to be replaced with an emulated
// one.
bool SetFunctionCalled(TOperator op, const TType& param);
bool SetFunctionCalled(
TOperator op, const TType& param1, const TType& param2);
+ bool SetFunctionCalled(
+ TOperator op, const TType& param1, const TType& param2, const TType& param3);
// Output function emulation definition. This should be before any other
// shader source.
void OutputEmulatedFunctionDefinition(TInfoSinkBase& out, bool withPrecision) const;
void MarkBuiltInFunctionsForEmulation(TIntermNode* root);
void Cleanup();
@@ -55,16 +57,21 @@ private:
TFunctionDistance3_3, // vec3 distance(vec3, vec3);
TFunctionDistance4_4, // vec4 distance(vec4, vec4);
TFunctionDot1_1, // float dot(float, float);
TFunctionDot2_2, // vec2 dot(vec2, vec2);
TFunctionDot3_3, // vec3 dot(vec3, vec3);
TFunctionDot4_4, // vec4 dot(vec4, vec4);
+ TFunctionFaceForward1_1_1, // float faceforward(float, float, float);
+ TFunctionFaceForward2_2_2, // vec2 faceforward(vec2, vec2, vec2);
+ TFunctionFaceForward3_3_3, // vec3 faceforward(vec3, vec3, vec3);
+ TFunctionFaceForward4_4_4, // vec4 faceforward(vec4, vec4, vec4);
+
TFunctionLength1, // float length(float);
TFunctionLength2, // float length(vec2);
TFunctionLength3, // float length(vec3);
TFunctionLength4, // float length(vec4);
TFunctionNormalize1, // float normalize(float);
TFunctionNormalize2, // vec2 normalize(vec2);
TFunctionNormalize3, // vec3 normalize(vec3);
@@ -76,16 +83,18 @@ private:
TFunctionReflect4_4, // vec4 reflect(vec4, vec4);
TFunctionUnknown
};
TBuiltInFunction IdentifyFunction(TOperator op, const TType& param);
TBuiltInFunction IdentifyFunction(
TOperator op, const TType& param1, const TType& param2);
+ TBuiltInFunction IdentifyFunction(
+ TOperator op, const TType& param1, const TType& param2, const TType& param3);
bool SetFunctionCalled(TBuiltInFunction function);
std::vector<TBuiltInFunction> mFunctions;
const bool* mFunctionMask; // a boolean flag for each function.
const char** mFunctionSource;
};

View File

@ -31,6 +31,12 @@ const char* kFunctionEmulationVertexSource[] = {
"#error no emulation for dot(vec3, vec3)",
"#error no emulation for dot(vec4, vec4)",
// |faceforward(N, I, Nref)| is |dot(NRef, I) < 0 ? N : -N|
"#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))",
"#error no emulation for faceforward(vec2, vec2, vec2)",
"#error no emulation for faceforward(vec3, vec3, vec3)",
"#error no emulation for faceforward(vec4, vec4, vec4)",
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
"#error no emulation for length(vec2)",
"#error no emulation for length(vec3)",
@ -63,6 +69,12 @@ const char* kFunctionEmulationFragmentSource[] = {
"#error no emulation for dot(vec3, vec3)",
"#error no emulation for dot(vec4, vec4)",
// |faceforward(N, I, Nref)| is |dot(NRef, I) < 0 ? N : -N|
"#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))",
"#error no emulation for faceforward(vec2, vec2, vec2)",
"#error no emulation for faceforward(vec3, vec3, vec3)",
"#error no emulation for faceforward(vec4, vec4, vec4)",
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
"#error no emulation for length(vec2)",
"#error no emulation for length(vec3)",
@ -94,6 +106,10 @@ const bool kFunctionEmulationVertexMask[] = {
false, // TFunctionDot2_2
false, // TFunctionDot3_3
false, // TFunctionDot4_4
true, // TFunctionFaceForward1_1_1
false, // TFunctionFaceForward2_2_2
false, // TFunctionFaceForward3_3_3
false, // TFunctionFaceForward4_4_4
true, // TFunctionLength1
false, // TFunctionLength2
false, // TFunctionLength3
@ -120,6 +136,10 @@ const bool kFunctionEmulationVertexMask[] = {
false, // TFunctionDot2_2
false, // TFunctionDot3_3
false, // TFunctionDot4_4
false, // TFunctionFaceForward1_1_1
false, // TFunctionFaceForward2_2_2
false, // TFunctionFaceForward3_3_3
false, // TFunctionFaceForward4_4_4
false, // TFunctionLength1
false, // TFunctionLength2
false, // TFunctionLength3
@ -151,6 +171,10 @@ const bool kFunctionEmulationFragmentMask[] = {
false, // TFunctionDot2_2
false, // TFunctionDot3_3
false, // TFunctionDot4_4
true, // TFunctionFaceForward1_1_1
false, // TFunctionFaceForward2_2_2
false, // TFunctionFaceForward3_3_3
false, // TFunctionFaceForward4_4_4
true, // TFunctionLength1
false, // TFunctionLength2
false, // TFunctionLength3
@ -177,6 +201,10 @@ const bool kFunctionEmulationFragmentMask[] = {
false, // TFunctionDot2_2
false, // TFunctionDot3_3
false, // TFunctionDot4_4
false, // TFunctionFaceForward1_1_1
false, // TFunctionFaceForward2_2_2
false, // TFunctionFaceForward3_3_3
false, // TFunctionFaceForward4_4_4
false, // TFunctionLength1
false, // TFunctionLength2
false, // TFunctionLength3
@ -244,15 +272,27 @@ public:
return true;
};
const TIntermSequence& sequence = node->getSequence();
// Right now we only handle built-in functions with two parameters.
if (sequence.size() != 2)
bool needToEmulate = false;
if (sequence.size() == 2) {
TIntermTyped* param1 = sequence[0]->getAsTyped();
TIntermTyped* param2 = sequence[1]->getAsTyped();
if (!param1 || !param2)
return true;
needToEmulate = mEmulator.SetFunctionCalled(
node->getOp(), param1->getType(), param2->getType());
} else if (sequence.size() == 3) {
TIntermTyped* param1 = sequence[0]->getAsTyped();
TIntermTyped* param2 = sequence[1]->getAsTyped();
TIntermTyped* param3 = sequence[2]->getAsTyped();
if (!param1 || !param2 || !param3)
return true;
needToEmulate = mEmulator.SetFunctionCalled(
node->getOp(), param1->getType(), param2->getType(), param3->getType());
} else {
return true;
TIntermTyped* param1 = sequence[0]->getAsTyped();
TIntermTyped* param2 = sequence[1]->getAsTyped();
if (!param1 || !param2)
return true;
bool needToEmulate = mEmulator.SetFunctionCalled(
node->getOp(), param1->getType(), param2->getType());
}
if (needToEmulate)
node->setUseEmulatedFunction();
}
@ -290,6 +330,13 @@ bool BuiltInFunctionEmulator::SetFunctionCalled(
return SetFunctionCalled(function);
}
bool BuiltInFunctionEmulator::SetFunctionCalled(
TOperator op, const TType& param1, const TType& param2, const TType& param3)
{
TBuiltInFunction function = IdentifyFunction(op, param1, param2, param3);
return SetFunctionCalled(function);
}
bool BuiltInFunctionEmulator::SetFunctionCalled(
BuiltInFunctionEmulator::TBuiltInFunction function) {
if (function == TFunctionUnknown || mFunctionMask[function] == false)
@ -382,6 +429,34 @@ BuiltInFunctionEmulator::IdentifyFunction(
return static_cast<TBuiltInFunction>(function);
}
BuiltInFunctionEmulator::TBuiltInFunction
BuiltInFunctionEmulator::IdentifyFunction(
TOperator op, const TType& param1, const TType& param2, const TType& param3)
{
// Check that all params have the same type, length,
// and that they're not too large.
if (param1.isVector() != param2.isVector() ||
param2.isVector() != param3.isVector() ||
param1.getNominalSize() != param2.getNominalSize() ||
param2.getNominalSize() != param3.getNominalSize() ||
param1.getNominalSize() > 4)
return TFunctionUnknown;
unsigned int function = TFunctionUnknown;
switch (op) {
case EOpFaceForward:
function = TFunctionFaceForward1_1_1;
break;
default:
break;
}
if (function == TFunctionUnknown)
return TFunctionUnknown;
if (param1.isVector())
function += param1.getNominalSize() - 1;
return static_cast<TBuiltInFunction>(function);
}
void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
TIntermNode* root)
{

View File

@ -28,6 +28,8 @@ public:
bool SetFunctionCalled(TOperator op, const TType& param);
bool SetFunctionCalled(
TOperator op, const TType& param1, const TType& param2);
bool SetFunctionCalled(
TOperator op, const TType& param1, const TType& param2, const TType& param3);
// Output function emulation definition. This should be before any other
// shader source.
@ -60,6 +62,11 @@ private:
TFunctionDot3_3, // vec3 dot(vec3, vec3);
TFunctionDot4_4, // vec4 dot(vec4, vec4);
TFunctionFaceForward1_1_1, // float faceforward(float, float, float);
TFunctionFaceForward2_2_2, // vec2 faceforward(vec2, vec2, vec2);
TFunctionFaceForward3_3_3, // vec3 faceforward(vec3, vec3, vec3);
TFunctionFaceForward4_4_4, // vec4 faceforward(vec4, vec4, vec4);
TFunctionLength1, // float length(float);
TFunctionLength2, // float length(vec2);
TFunctionLength3, // float length(vec3);
@ -81,6 +88,8 @@ private:
TBuiltInFunction IdentifyFunction(TOperator op, const TType& param);
TBuiltInFunction IdentifyFunction(
TOperator op, const TType& param1, const TType& param2);
TBuiltInFunction IdentifyFunction(
TOperator op, const TType& param1, const TType& param2, const TType& param3);
bool SetFunctionCalled(TBuiltInFunction function);

View File

@ -524,7 +524,15 @@ nsEventStatus AsyncPanZoomController::OnLongPress(const TapGestureInput& aEvent)
}
nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEvent) {
// XXX: Implement this.
if (mGeckoContentController) {
MonitorAutoLock monitor(mMonitor);
gfx::Point point = WidgetSpaceToCompensatedViewportSpace(
gfx::Point(aEvent.mPoint.x, aEvent.mPoint.y),
mFrameMetrics.mResolution.width);
mGeckoContentController->HandleSingleTap(nsIntPoint(NS_lround(point.x), NS_lround(point.y)));
return nsEventStatus_eConsumeNoDefault;
}
return nsEventStatus_eIgnore;
}
@ -989,6 +997,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
// we get a larger displayport. This is very bad because we're wasting a
// paint and not initializating the displayport correctly.
RequestContentRepaint();
mState = NOTHING;
} else if (!mFrameMetrics.mCSSContentRect.IsEqualEdges(aViewportFrame.mCSSContentRect)) {
mFrameMetrics.mCSSContentRect = aViewportFrame.mCSSContentRect;
SetPageRect(mFrameMetrics.mCSSContentRect);

View File

@ -31,6 +31,13 @@ public:
*/
virtual void HandleDoubleTap(const nsIntPoint& aPoint) = 0;
/**
* Requests handling a single tap. |aPoint| is in CSS pixels, relative to the
* current scroll offset. This should simulate and send to content a mouse
* button down, then mouse button up at |aPoint|.
*/
virtual void HandleSingleTap(const nsIntPoint& aPoint) = 0;
GeckoContentController() {}
virtual ~GeckoContentController() {}
};

View File

@ -3273,11 +3273,80 @@ ShouldPreserveJITCode(JSCompartment *c, int64_t currentTime)
return false;
}
#ifdef DEBUG
struct CompartmentCheckTracer : public JSTracer
{
Cell *src;
JSGCTraceKind srcKind;
JSCompartment *compartment;
};
static bool
InCrossCompartmentMap(JSObject *src, Cell *dst, JSGCTraceKind dstKind)
{
JSCompartment *srccomp = src->compartment();
if (dstKind == JSTRACE_OBJECT) {
Value key = ObjectValue(*static_cast<JSObject *>(dst));
WrapperMap::Ptr p = srccomp->crossCompartmentWrappers.lookup(key);
if (*p->value.unsafeGet() == ObjectValue(*src))
return true;
}
/*
* If the cross-compartment edge is caused by the debugger, then we don't
* know the right hashtable key, so we have to iterate.
*/
for (WrapperMap::Enum e(srccomp->crossCompartmentWrappers); !e.empty(); e.popFront()) {
if (e.front().key.wrapped == dst && ToMarkable(e.front().value) == src)
return true;
}
return false;
}
static void
CheckCompartmentCallback(JSTracer *trcArg, void **thingp, JSGCTraceKind kind)
{
CompartmentCheckTracer *trc = static_cast<CompartmentCheckTracer *>(trcArg);
Cell *thing = (Cell *)*thingp;
JS_ASSERT(thing->compartment() == trc->compartment ||
thing->compartment() == trc->runtime->atomsCompartment ||
(trc->srcKind == JSTRACE_OBJECT &&
InCrossCompartmentMap((JSObject *)trc->src, thing, kind)));
}
static void
CheckForCompartmentMismatches(JSRuntime *rt)
{
if (rt->gcDisableStrictProxyCheckingCount)
return;
CompartmentCheckTracer trc;
JS_TracerInit(&trc, rt, CheckCompartmentCallback);
for (CompartmentsIter c(rt); !c.done(); c.next()) {
trc.compartment = c;
for (size_t thingKind = 0; thingKind < FINALIZE_LAST; thingKind++) {
for (CellIterUnderGC i(c, AllocKind(thingKind)); !i.done(); i.next()) {
trc.src = i.getCell();
trc.srcKind = MapAllocToTraceKind(AllocKind(thingKind));
JS_TraceChildren(&trc, trc.src, trc.srcKind);
}
}
}
}
#endif
static void
BeginMarkPhase(JSRuntime *rt)
{
int64_t currentTime = PRMJ_Now();
#ifdef DEBUG
CheckForCompartmentMismatches(rt);
#endif
rt->gcIsFull = true;
DebugOnly<bool> any = false;
for (CompartmentsIter c(rt); !c.done(); c.next()) {

View File

@ -2063,6 +2063,9 @@ TypeCompartment::newTypeObject(JSContext *cx, JSScript *script,
JSProtoKey key, JSObject *proto_, bool unknown,
bool isDOM)
{
JS_ASSERT_IF(script, cx->compartment == script->compartment());
JS_ASSERT_IF(proto_, cx->compartment == proto_->compartment());
RootedObject proto(cx, proto_);
TypeObject *object = gc::NewGCThing<TypeObject>(cx, gc::FINALIZE_TYPE_OBJECT, sizeof(TypeObject));
if (!object)
@ -5579,6 +5582,8 @@ JSObject::shouldSplicePrototype(JSContext *cx)
bool
JSObject::splicePrototype(JSContext *cx, JSObject *proto_)
{
JS_ASSERT(cx->compartment == compartment());
RootedObject proto(cx, proto_);
RootedObject self(cx, this);
@ -5639,6 +5644,7 @@ TypeObject *
JSObject::makeLazyType(JSContext *cx)
{
JS_ASSERT(hasLazyType());
JS_ASSERT(cx->compartment == compartment());
RootedObject self(cx, this);
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(getClass());
@ -5749,6 +5755,8 @@ JSObject::setNewTypeUnknown(JSContext *cx)
TypeObject *
JSObject::getNewType(JSContext *cx, JSFunction *fun_, bool isDOM)
{
JS_ASSERT(cx->compartment == compartment());
TypeObjectSet &table = cx->compartment->newTypeObjects;
if (!table.initialized() && !table.init())
@ -5837,6 +5845,9 @@ JSObject::getNewType(JSContext *cx, JSFunction *fun_, bool isDOM)
TypeObject *
JSCompartment::getLazyType(JSContext *cx, JSObject *proto_)
{
JS_ASSERT(cx->compartment == this);
JS_ASSERT_IF(proto_, cx->compartment == proto_->compartment());
RootedObject proto(cx, proto_);
MaybeCheckStackRoots(cx);

View File

@ -2660,6 +2660,9 @@ bool
JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *a, JSObject *b,
TradeGutsReserved &reserved)
{
JS_ASSERT(a->compartment() == b->compartment());
AutoCompartment ac(cx, a);
/*
* When performing multiple swaps between objects which may have different
* numbers of fixed slots, we reserve all space ahead of time so that the
@ -2898,53 +2901,19 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
b->type_ = tmp;
}
/*
* Use this method with extreme caution. It trades the guts of two objects and updates
* scope ownership. This operation is not thread-safe, just as fast array to slow array
* transitions are inherently not thread-safe. Don't perform a swap operation on objects
* shared across threads or, or bad things will happen. You have been warned.
*/
/* Use this method with extreme caution. It trades the guts of two objects. */
bool
JSObject::swap(JSContext *cx, JSObject *other)
{
// Ensure swap doesn't cause a finalizer to not be run.
JS_ASSERT(IsBackgroundFinalized(getAllocKind()) ==
IsBackgroundFinalized(other->getAllocKind()));
JS_ASSERT(compartment() == other->compartment());
if (this->compartment() == other->compartment()) {
TradeGutsReserved reserved(cx);
if (!ReserveForTradeGuts(cx, this, other, reserved))
return false;
TradeGuts(cx, this, other, reserved);
return true;
}
JSObject *thisClone;
JSObject *otherClone;
{
AutoCompartment ac(cx, other);
thisClone = JS_CloneObject(cx, this, other->getProto(), other->getParent());
if (!thisClone || !JS_CopyPropertiesFrom(cx, thisClone, this))
return false;
}
{
AutoCompartment ac(cx, this);
otherClone = JS_CloneObject(cx, other, other->getProto(), other->getParent());
if (!otherClone || !JS_CopyPropertiesFrom(cx, otherClone, other))
return false;
}
TradeGutsReserved reservedThis(cx);
TradeGutsReserved reservedOther(cx);
if (!ReserveForTradeGuts(cx, this, otherClone, reservedThis) ||
!ReserveForTradeGuts(cx, other, thisClone, reservedOther)) {
TradeGutsReserved reserved(cx);
if (!ReserveForTradeGuts(cx, this, other, reserved))
return false;
}
TradeGuts(cx, this, otherClone, reservedThis);
TradeGuts(cx, other, thisClone, reservedOther);
TradeGuts(cx, this, other, reserved);
return true;
}

View File

@ -663,6 +663,7 @@ JSObject::setSingletonType(JSContext *cx, js::HandleObject obj)
inline js::types::TypeObject *
JSObject::getType(JSContext *cx)
{
JS_ASSERT(cx->compartment == compartment());
if (hasLazyType())
return makeLazyType(cx);
return type_;
@ -672,6 +673,7 @@ JSObject::getType(JSContext *cx)
JSObject::clearType(JSContext *cx, js::HandleObject obj)
{
JS_ASSERT(!obj->hasSingletonType());
JS_ASSERT(cx->compartment == obj->compartment());
js::types::TypeObject *type = cx->compartment->getEmptyType(cx);
if (!type)
@ -692,6 +694,7 @@ JSObject::setType(js::types::TypeObject *newType)
JS_ASSERT_IF(hasSpecialEquality(),
newType->hasAnyFlags(js::types::OBJECT_FLAG_SPECIAL_EQUALITY));
JS_ASSERT(!hasSingletonType());
JS_ASSERT(compartment() == newType->compartment());
type_ = newType;
}
@ -824,6 +827,7 @@ JSObject::create(JSContext *cx, js::gc::AllocKind kind,
JS_ASSERT(shape && type);
JS_ASSERT(!!dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan()) == !!slots);
JS_ASSERT(js::gc::GetGCKindSlots(kind, shape->getObjectClass()) == shape->numFixedSlots());
JS_ASSERT(cx->compartment == type->compartment());
JSObject *obj = js_NewGCObject(cx, kind);
if (!obj)
@ -852,6 +856,7 @@ JSObject::createDenseArray(JSContext *cx, js::gc::AllocKind kind,
{
JS_ASSERT(shape && type);
JS_ASSERT(shape->getObjectClass() == &js::ArrayClass);
JS_ASSERT(cx->compartment == type->compartment());
/*
* Dense arrays are non-native, and never have properties to store.

View File

@ -3059,6 +3059,7 @@ js::NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv_,
JS_ASSERT_IF(proto, cx->compartment == proto->compartment());
JS_ASSERT_IF(parent, cx->compartment == parent->compartment());
JS_ASSERT_IF(construct, cx->compartment == construct->compartment());
JS_ASSERT_IF(call && cx->compartment != call->compartment(), priv.get() == ObjectValue(*call));
bool fun = call || construct;
Class *clasp;
if (fun)

View File

@ -928,6 +928,7 @@ JSObject::rollbackProperties(JSContext *cx, uint32_t slotSpan)
Shape *
JSObject::replaceWithNewEquivalentShape(JSContext *cx, Shape *oldShape, Shape *newShape)
{
JS_ASSERT(cx->compartment == oldShape->compartment());
JS_ASSERT_IF(oldShape != lastProperty(),
inDictionaryMode() &&
nativeLookupNoAllocation(oldShape->propidRef()) == oldShape);
@ -1202,6 +1203,9 @@ InitialShapeEntry::match(const InitialShapeEntry &key, const Lookup &lookup)
EmptyShape::getInitialShape(JSContext *cx, Class *clasp, JSObject *proto, JSObject *parent,
AllocKind kind, uint32_t objectFlags)
{
JS_ASSERT_IF(proto, cx->compartment == proto->compartment());
JS_ASSERT_IF(parent, cx->compartment == parent->compartment());
InitialShapeSet &table = cx->compartment->initialShapes;
if (!table.initialized() && !table.init())

View File

@ -531,6 +531,8 @@ ContextStack::currentScript(jsbytecode **ppc) const
if (fp->beginsIonActivation()) {
JSScript *script = NULL;
ion::GetPcScript(cx_, &script, ppc);
if (script->compartment() != cx_->compartment)
return NULL;
return script;
}
#endif

View File

@ -511,6 +511,23 @@ public:
}
}
virtual void HandleSingleTap(const nsIntPoint& aPoint) MOZ_OVERRIDE
{
if (MessageLoop::current() != mUILoop) {
// We have to send this message from the "UI thread" (main
// thread).
mUILoop->PostTask(
FROM_HERE,
NewRunnableMethod(this, &RemoteContentController::HandleSingleTap,
aPoint));
return;
}
if (mRenderFrame) {
TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
browser->HandleSingleTap(aPoint);
}
}
void ClearRenderFrame() { mRenderFrame = nullptr; }
private:

View File

@ -4,7 +4,7 @@ package @ANDROID_PACKAGE_NAME@.tests;
import @ANDROID_PACKAGE_NAME@.*;
abstract class PixelTest extends BaseTest {
private static final long PAINT_CLEAR_DELAY = 1000; // milliseconds
private static final long PAINT_CLEAR_DELAY = 3000; // milliseconds
protected final PaintedSurface loadAndGetPainted(String url) {
Actions.RepeatedEventExpecter paintExpecter = mActions.expectPaint();