mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge m-c to b2g-inbound
This commit is contained in:
commit
9803d43fac
@ -165,7 +165,7 @@ HTMLListBulletAccessible::Name(nsString &aName)
|
||||
// Native anonymous content, ARIA can't be used. Get list bullet text.
|
||||
nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
|
||||
if (blockFrame) {
|
||||
blockFrame->GetBulletText(aName);
|
||||
blockFrame->GetSpokenBulletText(aName);
|
||||
}
|
||||
|
||||
return eNameOK;
|
||||
@ -190,7 +190,7 @@ HTMLListBulletAccessible::AppendTextTo(nsAString& aText, uint32_t aStartOffset,
|
||||
nsAutoString bulletText;
|
||||
nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
|
||||
if (blockFrame)
|
||||
blockFrame->GetBulletText(bulletText);
|
||||
blockFrame->GetSpokenBulletText(bulletText);
|
||||
|
||||
aText.Append(Substring(bulletText, aStartOffset, aLength));
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ const kEmbedChar = String.fromCharCode(0xfffc);
|
||||
const kDiscBulletChar = String.fromCharCode(0x2022);
|
||||
const kDiscBulletText = kDiscBulletChar + " ";
|
||||
const kCircleBulletText = String.fromCharCode(0x25e6) + " ";
|
||||
const kSquareBulletText = String.fromCharCode(0x25aa) + " ";
|
||||
const kSquareBulletText = String.fromCharCode(0x25fe) + " ";
|
||||
|
||||
const MAX_TRIM_LENGTH = 100;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Test accessible name for the given accessible identifier.
|
||||
*/
|
||||
function testName(aAccOrElmOrID, aName, aMsg)
|
||||
function testName(aAccOrElmOrID, aName, aMsg, aTodo)
|
||||
{
|
||||
var msg = aMsg ? aMsg : "";
|
||||
|
||||
@ -9,9 +9,10 @@ function testName(aAccOrElmOrID, aName, aMsg)
|
||||
if (!acc)
|
||||
return;
|
||||
|
||||
var func = aTodo ? todo_is : is;
|
||||
var txtID = prettyName(aAccOrElmOrID);
|
||||
try {
|
||||
is(acc.name, aName, msg + "Wrong name of the accessible for " + txtID);
|
||||
func(acc.name, aName, msg + "Wrong name of the accessible for " + txtID);
|
||||
} catch (e) {
|
||||
ok(false, msg + "Can't get name of the accessible for " + txtID);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ support-files =
|
||||
markuprules.xml
|
||||
|
||||
[test_browserui.xul]
|
||||
[test_counterstyle.html]
|
||||
[test_general.html]
|
||||
[test_general.xul]
|
||||
[test_link.html]
|
||||
|
153
accessible/tests/mochitest/name/test_counterstyle.html
Normal file
153
accessible/tests/mochitest/name/test_counterstyle.html
Normal file
@ -0,0 +1,153 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>nsIAccessible::name calculation for @counter-style</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../name.js"></script>
|
||||
|
||||
<style id="counterstyles" type="text/css">
|
||||
@counter-style system-alphabetic {
|
||||
system: alphabetic;
|
||||
symbols: x y z;
|
||||
}
|
||||
@counter-style system-cyclic {
|
||||
system: cyclic;
|
||||
symbols: x y z;
|
||||
}
|
||||
@counter-style system-numeric {
|
||||
system: numeric;
|
||||
symbols: x y z;
|
||||
}
|
||||
@counter-style speak-as-bullets {
|
||||
system: extends decimal;
|
||||
speak-as: bullets;
|
||||
}
|
||||
@counter-style speak-as-numbers {
|
||||
system: extends system-alphabetic;
|
||||
speak-as: numbers;
|
||||
}
|
||||
@counter-style speak-as-words {
|
||||
system: additive;
|
||||
additive-symbols: 20 "twenty ", 9 "nine", 7 "seven", 1 "one";
|
||||
speak-as: words;
|
||||
}
|
||||
@counter-style speak-as-spell-out {
|
||||
system: extends system-alphabetic;
|
||||
speak-as: spell-out;
|
||||
}
|
||||
@counter-style speak-as-other {
|
||||
system: extends decimal;
|
||||
speak-as: speak-as-words;
|
||||
}
|
||||
@counter-style speak-as-loop {
|
||||
system: extends upper-latin;
|
||||
speak-as: speak-as-loop0;
|
||||
}
|
||||
@counter-style speak-as-loop0 {
|
||||
system: extends disc;
|
||||
speak-as: speak-as-loop1;
|
||||
}
|
||||
@counter-style speak-as-loop1 {
|
||||
system: extends decimal;
|
||||
speak-as: speak-as-loop0;
|
||||
}
|
||||
@counter-style speak-as-extended0 {
|
||||
system: extends decimal;
|
||||
speak-as: speak-as-extended1;
|
||||
}
|
||||
@counter-style speak-as-extended1 {
|
||||
system: extends speak-as-extended0;
|
||||
speak-as: disc;
|
||||
}
|
||||
@counter-style speak-as-extended2 {
|
||||
system: extends decimal;
|
||||
speak-as: speak-as-extended3;
|
||||
}
|
||||
@counter-style speak-as-extended3 {
|
||||
system: extends speak-as-extended2;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
function doTest()
|
||||
{
|
||||
function testRule(aRule, aNames, aTodo)
|
||||
{
|
||||
testName(aRule + "-1", aNames[0], null, aTodo);
|
||||
testName(aRule + "-7", aNames[1], null, aTodo);
|
||||
testName(aRule + "-29", aNames[2], null, aTodo);
|
||||
}
|
||||
|
||||
var spellOutNames = ["X. 1", "Y X. 7", "Y Z Y. 29"];
|
||||
var bulletsNames = [kDiscBulletText + "1",
|
||||
kDiscBulletText + "7",
|
||||
kDiscBulletText + "29"];
|
||||
var numbersNames = ["1. 1", "7. 7", "29. 29"];
|
||||
var wordsNames = ["one. 1", "seven. 7", "twenty nine. 29"];
|
||||
|
||||
testRule("system-alphabetic", spellOutNames, true); // bug 1024178
|
||||
testRule("system-cyclic", bulletsNames);
|
||||
testRule("system-numeric", numbersNames);
|
||||
|
||||
testRule("speak-as-bullets", bulletsNames);
|
||||
testRule("speak-as-numbers", numbersNames);
|
||||
testRule("speak-as-words", wordsNames);
|
||||
testRule("speak-as-spell-out", spellOutNames, true); // bug 1024178
|
||||
testRule("speak-as-other", wordsNames);
|
||||
|
||||
testRule("speak-as-loop", bulletsNames);
|
||||
testRule("speak-as-loop0", bulletsNames);
|
||||
testRule("speak-as-loop1", numbersNames);
|
||||
|
||||
testRule("speak-as-extended0", bulletsNames);
|
||||
testRule("speak-as-extended1", bulletsNames);
|
||||
testRule("speak-as-extended2", numbersNames);
|
||||
testRule("speak-as-extended3", numbersNames);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=966166"
|
||||
title="Bug 966166 - Implement @counter-style rule">
|
||||
Bug 966166
|
||||
</a>
|
||||
|
||||
<ol id="list"></ol>
|
||||
|
||||
<script type="application/javascript">
|
||||
var list = getNode("list");
|
||||
var rules = getNode("counterstyles").sheet.cssRules;
|
||||
var values = [1, 7, 29];
|
||||
for (var i = 0; i < rules.length; i++) {
|
||||
var rule = rules[i];
|
||||
for (var j = 0; j < values.length; j++) {
|
||||
var item = document.createElement("li");
|
||||
item.id = rule.name + '-' + values[j];
|
||||
item.value = values[j];
|
||||
item.textContent = values[j];
|
||||
item.setAttribute("style", "list-style-type: " + rule.name);
|
||||
list.appendChild(item);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -84,11 +84,11 @@ if test -n "$ENABLE_INTL_API"; then
|
||||
case "$OS_TARGET" in
|
||||
WINNT)
|
||||
ICU_LIB_NAMES="icuin icuuc icudt"
|
||||
MOZ_ICU_DBG_SUFFIX=
|
||||
if test -n "$MOZ_DEBUG" -a -z "$MOZ_NO_DEBUG_RTL"; then
|
||||
MOZ_ICU_DBG_SUFFIX=d
|
||||
fi
|
||||
if test -n "$MOZ_SHARED_ICU"; then
|
||||
MOZ_ICU_DBG_SUFFIX=
|
||||
if test -n "$MOZ_DEBUG" -a -z "$MOZ_NO_DEBUG_RTL"; then
|
||||
MOZ_ICU_DBG_SUFFIX=d
|
||||
fi
|
||||
MOZ_ICU_LIBS='$(foreach lib,$(ICU_LIB_NAMES),$(DEPTH)/intl/icu/target/lib/$(LIB_PREFIX)$(lib)$(MOZ_ICU_DBG_SUFFIX).$(LIB_SUFFIX))'
|
||||
fi
|
||||
;;
|
||||
@ -108,7 +108,7 @@ if test -n "$ENABLE_INTL_API"; then
|
||||
AC_MSG_ERROR([ECMAScript Internationalization API is not yet supported on this platform])
|
||||
esac
|
||||
if test -z "$MOZ_SHARED_ICU"; then
|
||||
MOZ_ICU_LIBS='$(call EXPAND_LIBNAME_PATH,$(ICU_LIB_NAMES),$(DEPTH)/intl/icu/target/lib)'
|
||||
MOZ_ICU_LIBS='$(call EXPAND_LIBNAME_PATH,$(addsuffix $(MOZ_ICU_DBG_SUFFIX),$(ICU_LIB_NAMES)),$(DEPTH)/intl/icu/target/lib)'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
@ -43,7 +43,7 @@ gyp_vars = {
|
||||
# (for vp8) chromium sets to 0 also
|
||||
'use_temporal_layers': 0,
|
||||
# Creates AEC internal sample dump files in current directory
|
||||
# 'aec_debug_dump': 1,
|
||||
'aec_debug_dump': 1,
|
||||
|
||||
# codec enable/disables:
|
||||
'include_g711': 1,
|
||||
|
@ -614,12 +614,12 @@ nsChromeRegistryChrome::kTableOps = {
|
||||
nsChromeRegistryChrome::ProviderEntry*
|
||||
nsChromeRegistryChrome::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType)
|
||||
{
|
||||
int32_t i = mArray.Length();
|
||||
size_t i = mArray.Length();
|
||||
if (!i)
|
||||
return nullptr;
|
||||
|
||||
ProviderEntry* found = nullptr; // Only set if we find a partial-match locale
|
||||
ProviderEntry* entry;
|
||||
ProviderEntry* entry = nullptr;
|
||||
|
||||
while (i--) {
|
||||
entry = &mArray[i];
|
||||
|
28
configure.in
28
configure.in
@ -1302,6 +1302,9 @@ dnl ========================================================
|
||||
dnl GNU specific defaults
|
||||
dnl ========================================================
|
||||
if test "$GNU_CC"; then
|
||||
MMX_FLAGS="-mmmx"
|
||||
SSE_FLAGS="-msse"
|
||||
SSE2_FLAGS="-msse2"
|
||||
# Per bug 719659 comment 2, some of the headers on ancient build machines
|
||||
# may require gnu89 inline semantics. But otherwise, we use C99.
|
||||
# But on OS X we just use C99 plus GNU extensions, in order to fix
|
||||
@ -1915,10 +1918,6 @@ case "$target" in
|
||||
fi
|
||||
TARGET_NSPR_MDCPUCFG='\"md/_darwin.cfg\"'
|
||||
|
||||
MMX_FLAGS="-mmmx"
|
||||
SSE_FLAGS="-msse"
|
||||
SSE2_FLAGS="-msse2"
|
||||
|
||||
if test "x$lto_is_enabled" = "xyes"; then
|
||||
echo "Skipping -dead_strip because lto is enabled."
|
||||
dnl DTrace and -dead_strip don't interact well. See bug 403132.
|
||||
@ -2010,10 +2009,6 @@ ia64*-hpux*)
|
||||
fi
|
||||
TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
|
||||
|
||||
MMX_FLAGS="-mmmx"
|
||||
SSE_FLAGS="-msse"
|
||||
SSE2_FLAGS="-msse2"
|
||||
|
||||
MOZ_GFX_OPTIMIZE_MOBILE=1
|
||||
MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions"
|
||||
;;
|
||||
@ -2035,10 +2030,6 @@ ia64*-hpux*)
|
||||
MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks $MOZ_OPTIMIZE_SIZE_TWEAK"
|
||||
fi
|
||||
|
||||
MMX_FLAGS="-mmmx"
|
||||
SSE_FLAGS="-msse"
|
||||
SSE2_FLAGS="-msse2"
|
||||
|
||||
TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
|
||||
|
||||
MOZ_MEMORY=1
|
||||
@ -2084,10 +2075,6 @@ ia64*-hpux*)
|
||||
DLL_PREFIX=
|
||||
IMPORT_LIB_SUFFIX=dll.a
|
||||
|
||||
MMX_FLAGS="-mmmx"
|
||||
SSE_FLAGS="-msse"
|
||||
SSE2_FLAGS="-msse2"
|
||||
|
||||
# We use mix of both POSIX and Win32 printf format across the tree, so format
|
||||
# warnings are useless on mingw.
|
||||
MOZ_C_SUPPORTS_WARNING(-Wno-, format, ac_c_has_wno_format)
|
||||
@ -2297,9 +2284,6 @@ ia64*-hpux*)
|
||||
fi
|
||||
MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,$(notdir $@) -o $@'
|
||||
MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,$(notdir $@)) -o $@'
|
||||
MMX_FLAGS="-mmmx"
|
||||
SSE_FLAGS="-msse"
|
||||
SSE2_FLAGS="-msse2"
|
||||
;;
|
||||
|
||||
*-openbsd*)
|
||||
@ -2315,9 +2299,6 @@ ia64*-hpux*)
|
||||
if test "$LIBRUNPATH"; then
|
||||
DSO_LDOPTS="-R$LIBRUNPATH $DSO_LDOPTS"
|
||||
fi
|
||||
MMX_FLAGS="-mmmx"
|
||||
SSE_FLAGS="-msse"
|
||||
SSE2_FLAGS="-msse2"
|
||||
;;
|
||||
|
||||
*-solaris*)
|
||||
@ -2399,9 +2380,6 @@ ia64*-hpux*)
|
||||
if test "$OS_RELEASE" = "5.3"; then
|
||||
AC_DEFINE(MUST_UNDEF_HAVE_BOOLEAN_AFTER_INCLUDES)
|
||||
fi
|
||||
MMX_FLAGS="-mmmx"
|
||||
SSE_FLAGS="-msse"
|
||||
SSE2_FLAGS="-msse2"
|
||||
fi
|
||||
if test "$OS_RELEASE" = "5.5.1"; then
|
||||
AC_DEFINE(NEED_USLEEP_PROTOTYPE)
|
||||
|
@ -20,6 +20,7 @@ class SourceSurface;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
class SVGMatrix;
|
||||
|
||||
class CanvasPattern MOZ_FINAL : public nsWrapperCache
|
||||
{
|
||||
@ -43,6 +44,7 @@ public:
|
||||
: mContext(aContext)
|
||||
, mSurface(aSurface)
|
||||
, mPrincipal(principalForSecurityCheck)
|
||||
, mTransform()
|
||||
, mForceWriteOnly(forceWriteOnly)
|
||||
, mCORSUsed(CORSUsed)
|
||||
, mRepeat(aRepeat)
|
||||
@ -60,9 +62,13 @@ public:
|
||||
return mContext;
|
||||
}
|
||||
|
||||
// WebIDL
|
||||
void SetTransform(SVGMatrix& matrix);
|
||||
|
||||
nsRefPtr<CanvasRenderingContext2D> mContext;
|
||||
RefPtr<gfx::SourceSurface> mSurface;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
mozilla::gfx::Matrix mTransform;
|
||||
const bool mForceWriteOnly;
|
||||
const bool mCORSUsed;
|
||||
const RepeatMode mRepeat;
|
||||
|
@ -93,6 +93,7 @@
|
||||
#include "mozilla/dom/HTMLVideoElement.h"
|
||||
#include "mozilla/dom/TextMetrics.h"
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
#include "mozilla/dom/SVGMatrix.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "GLContext.h"
|
||||
#include "GLContextProvider.h"
|
||||
@ -262,7 +263,8 @@ public:
|
||||
mode = ExtendMode::REPEAT;
|
||||
}
|
||||
mPattern = new (mSurfacePattern.addr())
|
||||
SurfacePattern(state.patternStyles[aStyle]->mSurface, mode);
|
||||
SurfacePattern(state.patternStyles[aStyle]->mSurface, mode,
|
||||
state.patternStyles[aStyle]->mTransform);
|
||||
}
|
||||
|
||||
return *mPattern;
|
||||
@ -382,6 +384,12 @@ private:
|
||||
mgfx::Rect mTempRect;
|
||||
};
|
||||
|
||||
void
|
||||
CanvasPattern::SetTransform(SVGMatrix& aMatrix)
|
||||
{
|
||||
mTransform = ToMatrix(aMatrix.GetMatrix());
|
||||
}
|
||||
|
||||
void
|
||||
CanvasGradient::AddColorStop(float offset, const nsAString& colorstr, ErrorResult& rv)
|
||||
{
|
||||
|
@ -1206,12 +1206,8 @@ WebGLContext::ValidateTexInputData(GLenum type, int jsArrayType, WebGLTexImageFu
|
||||
validInput = (jsArrayType == -1 || jsArrayType == js::ArrayBufferView::TYPE_UINT8);
|
||||
break;
|
||||
|
||||
// TODO: WebGL spec doesn't allow half floats to specified as UInt16.
|
||||
case LOCAL_GL_HALF_FLOAT:
|
||||
case LOCAL_GL_HALF_FLOAT_OES:
|
||||
validInput = (jsArrayType == -1);
|
||||
break;
|
||||
|
||||
case LOCAL_GL_UNSIGNED_SHORT:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
|
@ -214,5 +214,6 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk')
|
||||
[test_toDataURL_parameters.html]
|
||||
[test_windingRuleUndefined.html]
|
||||
[test_2d.fillText.gradient.html]
|
||||
[test_2d_composite_canvaspattern_setTransform.html]
|
||||
[test_createPattern_broken.html]
|
||||
[test_setlinedash.html]
|
||||
|
@ -0,0 +1,77 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title>Canvas Tests</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<body>
|
||||
<script>
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
const Cc = SpecialPowers.Cc;
|
||||
const Cr = SpecialPowers.Cr;
|
||||
SpecialPowers.setBoolPref("canvas.path.enabled", true);
|
||||
|
||||
function isPixel(ctx, x,y, r,g,b,a, d) {
|
||||
var pos = x + "," + y;
|
||||
var colour = r + "," + g + "," + b + "," + a;
|
||||
var pixel = ctx.getImageData(x, y, 1, 1);
|
||||
var pr = pixel.data[0],
|
||||
pg = pixel.data[1],
|
||||
pb = pixel.data[2],
|
||||
pa = pixel.data[3];
|
||||
ok(r-d <= pr && pr <= r+d &&
|
||||
g-d <= pg && pg <= g+d &&
|
||||
b-d <= pb && pb <= b+d &&
|
||||
a-d <= pa && pa <= a+d,
|
||||
"pixel "+pos+" of "+ctx.canvas.id+" is "+pr+","+pg+","+pb+","+pa+"; expected "+colour+" +/- "+d);
|
||||
}
|
||||
</script>
|
||||
|
||||
<p>Canvas test: 2d.composite.canvaspattern.setTransform</p>
|
||||
<canvas id="ctx" width="100" height="50"><p class="fallback">FAIL
|
||||
(fallback content)</p></canvas>
|
||||
<svg id="svg1"></svg>
|
||||
<img src="image_rgrg-256x256.png" id="rgrg-256x256.png" width="32"
|
||||
height="32" class="resource">
|
||||
|
||||
<script>
|
||||
|
||||
function test_2d_canvaspattern_setTransform() {
|
||||
|
||||
var canvas = document.getElementById('ctx');
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.clearRect(0,0,canvas.width,canvas.height);
|
||||
var img = document.getElementById("rgrg-256x256.png");
|
||||
var pat = ctx.createPattern(img,"repeat");
|
||||
|
||||
var svg = document.getElementById("svg1");
|
||||
var mtx = svg1.createSVGMatrix();
|
||||
pat.setTransform(mtx.rotate(-45).scale(0.1));
|
||||
ctx.fillStyle = pat;
|
||||
ctx.fillRect(0, 0, 100, 50);
|
||||
|
||||
// If the pattern doesn't get transformed, or only gets rotated or
|
||||
// scaled, but not both, this will not be green and will fail.
|
||||
isPixel(ctx, 90,14, 0,255,0,255, 0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
||||
function runTests() {
|
||||
try {
|
||||
test_2d_canvaspattern_setTransform();
|
||||
} catch(e) {
|
||||
throw e;
|
||||
ok(false, "unexpected exception thrown in: test_2d_canvaspattern_setTransform");
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addLoadEvent(runTests);
|
||||
|
||||
// Don't leak the world via the Path2D reference to its window.
|
||||
document.all;
|
||||
window.p = new Path2D();
|
||||
|
||||
</script>
|
||||
|
@ -2574,9 +2574,8 @@ bool
|
||||
nsGenericHTMLFormElement::IsLabelable() const
|
||||
{
|
||||
// TODO: keygen should be in that list, see bug 101019.
|
||||
// TODO: NS_FORM_INPUT_HIDDEN should be removed, see bug 597650.
|
||||
uint32_t type = GetType();
|
||||
return type & NS_FORM_INPUT_ELEMENT ||
|
||||
return (type & NS_FORM_INPUT_ELEMENT && type != NS_FORM_INPUT_HIDDEN) ||
|
||||
type & NS_FORM_BUTTON_ELEMENT ||
|
||||
// type == NS_FORM_KEYGEN ||
|
||||
type == NS_FORM_OUTPUT ||
|
||||
|
@ -56,6 +56,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
|
||||
[test_input_untrusted_key_events.html]
|
||||
[test_input_url.html]
|
||||
[test_label_control_attribute.html]
|
||||
[test_label_input_controls.html]
|
||||
[test_max_attribute.html]
|
||||
skip-if = e10s
|
||||
[test_maxlength_attribute.html]
|
||||
|
@ -0,0 +1,84 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=597650
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 597650</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=597650">Mozilla Bug 597650</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<label id="l">
|
||||
<input id="h"></input>
|
||||
<input type="text" id="i"></input>
|
||||
</label>
|
||||
<label id="lh" for="h"></label>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
/** Test for Bug 597650 **/
|
||||
label = document.getElementById("l");
|
||||
labelForH = document.getElementById("lh");
|
||||
inputI = document.getElementById("i");
|
||||
inputH = document.getElementById("h");
|
||||
|
||||
var labelableTypes = ["text", "search", "tel", "url", "email", "password",
|
||||
"datetime", "date", "month", "week", "time",
|
||||
"number", "range", "color", "checkbox", "radio",
|
||||
"file", "submit", "image", "reset", "button"];
|
||||
var nonLabelableTypes = ["hidden"];
|
||||
|
||||
for (var i in labelableTypes) {
|
||||
test(labelableTypes[i], true);
|
||||
}
|
||||
|
||||
for (var i in nonLabelableTypes) {
|
||||
test(nonLabelableTypes[i], false);
|
||||
}
|
||||
|
||||
function test(type, isLabelable) {
|
||||
inputH.type = type;
|
||||
if (isLabelable) {
|
||||
testControl(label, inputH, type, true);
|
||||
testControl(labelForH, inputH, type, true);
|
||||
} else {
|
||||
testControl(label, inputI, type, false);
|
||||
testControl(labelForH, undefined, type, false);
|
||||
|
||||
inputH.type = "text";
|
||||
testControl(label, inputH, "text", true);
|
||||
testControl(labelForH, inputH, "text", true);
|
||||
|
||||
inputH.type = type;
|
||||
testControl(label, inputI, type, false);
|
||||
testControl(labelForH, undefined, type, false);
|
||||
|
||||
label.removeChild(inputH);
|
||||
testControl(label, inputI, "text", true);
|
||||
|
||||
var element = document.createElement('input');
|
||||
element.type = type;
|
||||
label.insertBefore(element, inputI);
|
||||
testControl(label, inputI, "text", true);
|
||||
}
|
||||
}
|
||||
|
||||
function testControl(label, control, type, labelable) {
|
||||
if (labelable) {
|
||||
is(label.control, control, "Input controls of type " + type
|
||||
+ " should be labeled");
|
||||
} else {
|
||||
is(label.control, control, "Input controls of type " + type
|
||||
+ " should be ignored by <label>");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -188,7 +188,7 @@ public:
|
||||
AudioChunk& c = *ci;
|
||||
// If this chunk is null, don't bother resampling, just alter its duration
|
||||
if (c.IsNull()) {
|
||||
c.mDuration *= aOutRate / aInRate;
|
||||
c.mDuration = (c.mDuration * aOutRate) / aInRate;
|
||||
mDuration += c.mDuration;
|
||||
continue;
|
||||
}
|
||||
|
@ -81,6 +81,10 @@ TextTrackCue::TextTrackCue(nsPIDOMWindow* aOwnerWindow,
|
||||
}
|
||||
}
|
||||
|
||||
TextTrackCue::~TextTrackCue()
|
||||
{
|
||||
}
|
||||
|
||||
/** Save a reference to our creating document so we don't have to
|
||||
* keep getting it from our window.
|
||||
*/
|
||||
|
@ -51,6 +51,8 @@ public:
|
||||
const nsAString& aText, HTMLTrackElement* aTrackElement,
|
||||
ErrorResult& aRv);
|
||||
|
||||
~TextTrackCue();
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
TextTrack* GetTrack() const
|
||||
|
@ -18,7 +18,7 @@
|
||||
// 'mCurrentFrameTime <= clock_time || mPlaybackRate <= 0',
|
||||
// file MediaDecoderStateMachine.cpp, line 2379
|
||||
// This test is currently disabled on Android debug for wildly-varying numbers of the above.
|
||||
SimpleTest.expectAssertions(5, 9);
|
||||
SimpleTest.expectAssertions(3, 9);
|
||||
if (navigator.platform.startsWith("Win")) {
|
||||
SimpleTest.expectAssertions(4, 5);
|
||||
}
|
||||
|
@ -161,6 +161,7 @@ SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded()
|
||||
EnsureOnDemandBuiltInUASheet(sheet);
|
||||
}
|
||||
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::FormsSheet());
|
||||
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::CounterStylesSheet());
|
||||
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::HTMLSheet());
|
||||
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::UASheet());
|
||||
}
|
||||
|
@ -237,6 +237,11 @@ AutoJSAPIWithErrorsReportedToWindow::AutoJSAPIWithErrorsReportedToWindow(nsIScri
|
||||
{
|
||||
}
|
||||
|
||||
AutoJSAPIWithErrorsReportedToWindow::AutoJSAPIWithErrorsReportedToWindow(nsIGlobalObject* aGlobalObject)
|
||||
: AutoJSAPI(FindJSContext(aGlobalObject), /* aIsMainThread = */ true)
|
||||
{
|
||||
}
|
||||
|
||||
AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
|
||||
bool aIsMainThread,
|
||||
JSContext* aCx)
|
||||
|
@ -158,6 +158,8 @@ private:
|
||||
class AutoJSAPIWithErrorsReportedToWindow : public AutoJSAPI {
|
||||
public:
|
||||
AutoJSAPIWithErrorsReportedToWindow(nsIScriptContext* aScx);
|
||||
// Equivalent to AutoJSAPI if aGlobal is not a Window.
|
||||
AutoJSAPIWithErrorsReportedToWindow(nsIGlobalObject* aGlobalObject);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -98,6 +98,7 @@
|
||||
#include "nsIDOMCSSSupportsRule.h"
|
||||
#include "nsIDOMMozCSSKeyframeRule.h"
|
||||
#include "nsIDOMMozCSSKeyframesRule.h"
|
||||
#include "nsIDOMCSSCounterStyleRule.h"
|
||||
#include "nsIDOMCSSPageRule.h"
|
||||
#include "nsIDOMCSSStyleRule.h"
|
||||
#include "nsIDOMXULCommandDispatcher.h"
|
||||
@ -411,6 +412,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
NS_DEFINE_CLASSINFO_DATA(MozCSSKeyframesRule, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(CSSCounterStyleRule, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(CSSPageRule, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
@ -1036,6 +1040,10 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozCSSKeyframesRule)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(CSSCounterStyleRule, nsIDOMCSSCounterStyleRule)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSCounterStyleRule)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(CSSPageRule, nsIDOMCSSPageRule)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSPageRule)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
@ -76,6 +76,9 @@ DOMCI_CLASS(ChromeMessageSender)
|
||||
DOMCI_CLASS(MozCSSKeyframeRule)
|
||||
DOMCI_CLASS(MozCSSKeyframesRule)
|
||||
|
||||
// @counter-style in CSS
|
||||
DOMCI_CLASS(CSSCounterStyleRule)
|
||||
|
||||
DOMCI_CLASS(CSSPageRule)
|
||||
|
||||
DOMCI_CLASS(CSSFontFeatureValuesRule)
|
||||
|
@ -29,6 +29,10 @@ DataStore::DataStore(nsPIDOMWindow* aWindow)
|
||||
{
|
||||
}
|
||||
|
||||
DataStore::~DataStore()
|
||||
{
|
||||
}
|
||||
|
||||
already_AddRefed<DataStore>
|
||||
DataStore::Constructor(GlobalObject& aGlobal, ErrorResult& aRv)
|
||||
{
|
||||
|
@ -27,6 +27,7 @@ public:
|
||||
DOMEventTargetHelper)
|
||||
|
||||
explicit DataStore(nsPIDOMWindow* aWindow);
|
||||
~DataStore();
|
||||
|
||||
// WebIDL (internal functions)
|
||||
|
||||
@ -89,4 +90,4 @@ private:
|
||||
} //namespace dom
|
||||
} //namespace mozilla
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@ XPIDL_SOURCES += [
|
||||
'nsIDOMCounter.idl',
|
||||
'nsIDOMCSSCharsetRule.idl',
|
||||
'nsIDOMCSSConditionRule.idl',
|
||||
'nsIDOMCSSCounterStyleRule.idl',
|
||||
'nsIDOMCSSFontFaceRule.idl',
|
||||
'nsIDOMCSSFontFeatureValuesRule.idl',
|
||||
'nsIDOMCSSGroupingRule.idl',
|
||||
|
23
dom/interfaces/css/nsIDOMCSSCounterStyleRule.idl
Normal file
23
dom/interfaces/css/nsIDOMCSSCounterStyleRule.idl
Normal file
@ -0,0 +1,23 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsIDOMCSSRule.idl"
|
||||
|
||||
[scriptable, uuid(5f9f2068-743b-42e3-becb-10ffa994d1e3)]
|
||||
interface nsIDOMCSSCounterStyleRule : nsIDOMCSSRule
|
||||
{
|
||||
attribute DOMString name;
|
||||
attribute DOMString system;
|
||||
attribute DOMString symbols;
|
||||
attribute DOMString additiveSymbols;
|
||||
attribute DOMString negative;
|
||||
attribute DOMString prefix;
|
||||
attribute DOMString suffix;
|
||||
attribute DOMString range;
|
||||
attribute DOMString pad;
|
||||
attribute DOMString speakAs;
|
||||
attribute DOMString fallback;
|
||||
};
|
@ -31,6 +31,7 @@ interface nsIDOMCSSRule : nsISupports
|
||||
const unsigned short MOZ_KEYFRAMES_RULE = 7;
|
||||
const unsigned short MOZ_KEYFRAME_RULE = 8;
|
||||
const unsigned short NAMESPACE_RULE = 10;
|
||||
const unsigned short COUNTER_STYLE_RULE = 11;
|
||||
const unsigned short SUPPORTS_RULE = 12;
|
||||
const unsigned short FONT_FEATURE_VALUES_RULE = 14;
|
||||
|
||||
|
@ -44,6 +44,14 @@ PESelectorListExtraEOF=',' or '{'
|
||||
PESelectorListExtra=Expected ',' or '{' but found '%1$S'.
|
||||
PESelectorGroupNoSelector=Selector expected.
|
||||
PESelectorGroupExtraCombinator=Dangling combinator.
|
||||
PECounterStyleNotIdent=Expected identifier for name of @counter-style rule.
|
||||
PECounterStyleBadName=Name of @counter-style rule can't be '%1$S'.
|
||||
PECounterStyleBadBlockStart=Expected '{' to begin @counter-style rule but found '%1$S'.
|
||||
PECounterStyleEOF=closing '}' of @counter-style block
|
||||
PECounterDescExpected=Expected counter descriptor but found '%1$S'.
|
||||
PEUnknownCounterDesc=Unknown descriptor '%1$S' in @counter-style rule.
|
||||
PECounterExtendsNotIdent=Expected identifier for extends system but found '%1$S'.
|
||||
PECounterASWeight=Each weight in the additive-symbols descriptor must be smaller than the previous weight.
|
||||
PEClassSelEOF=class name
|
||||
PEClassSelNotIdent=Expected identifier for class selector but found '%1$S'.
|
||||
PETypeSelEOF=element type
|
||||
|
@ -5,6 +5,19 @@
|
||||
"use strict";
|
||||
|
||||
|
||||
const iceStateTransitions = {
|
||||
"new": ["checking", "closed"], //Note: 'failed' might need to added here
|
||||
// even though it is not in the standard
|
||||
"checking": ["new", "connected", "failed", "closed"], //Note: do we need to
|
||||
// allow 'completed' in
|
||||
// here as well?
|
||||
"connected": ["new", "completed", "disconnected", "closed"],
|
||||
"completed": ["new", "disconnected", "closed"],
|
||||
"disconnected": ["new", "connected", "completed", "failed", "closed"],
|
||||
"failed": ["new", "disconnected", "closed"],
|
||||
"closed": []
|
||||
}
|
||||
|
||||
/**
|
||||
* This class mimics a state machine and handles a list of commands by
|
||||
* executing them synchronously.
|
||||
@ -1708,6 +1721,28 @@ PeerConnectionWrapper.prototype = {
|
||||
return (this.isIceChecking() || this.isIceNew());
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a callback for the ICE connection state change and
|
||||
* appends the new state to an array for logging it later.
|
||||
*/
|
||||
logIceConnectionState: function PCW_logIceConnectionState() {
|
||||
var self = this;
|
||||
|
||||
function logIceConState () {
|
||||
var newstate = self._pc.iceConnectionState;
|
||||
var oldstate = self.iceConnectionLog[self.iceConnectionLog.length - 1]
|
||||
if (Object.keys(iceStateTransitions).indexOf(oldstate) != -1) {
|
||||
ok(iceStateTransitions[oldstate].indexOf(newstate) != -1, "Legal ICE state transition from " + oldstate + " to " + newstate);
|
||||
} else {
|
||||
ok(false, "Old ICE state " + oldstate + " missing in ICE transition array");
|
||||
}
|
||||
self.iceConnectionLog.push(self._pc.iceConnectionState);
|
||||
}
|
||||
|
||||
self.iceConnectionLog = [self._pc.iceConnectionState];
|
||||
self.ice_connection_callbacks.logIceStatus = logIceConState;
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a callback for the ICE connection state change and
|
||||
* reports success (=connected) or failure via the callbacks.
|
||||
|
@ -19,6 +19,13 @@ function dumpSdp(test) {
|
||||
dump("ERROR: SDP answer: " + test._remote_answer.sdp.replace(/[\r]/g, ''));
|
||||
}
|
||||
|
||||
if (typeof test.pcLocal.iceConnectionLog !== 'undefined') {
|
||||
dump("pcLocal ICE connection state log: " + test.pcLocal.iceConnectionLog + "\n");
|
||||
}
|
||||
if (typeof test.pcRemote.iceConnectionLog !== 'undefined') {
|
||||
dump("pcRemote ICE connection state log: " + test.pcRemote.iceConnectionLog + "\n");
|
||||
}
|
||||
|
||||
if ((typeof test.pcLocal.setRemoteDescDate !== 'undefined') &&
|
||||
(typeof test.pcRemote.setLocalDescDate !== 'undefined')) {
|
||||
var delta = deltaSeconds(test.pcLocal.setRemoteDescDate, test.pcRemote.setLocalDescDate);
|
||||
@ -69,6 +76,20 @@ var commandsPeerConnection = [
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SETUP_ICE_LOGGER',
|
||||
function (test) {
|
||||
test.pcLocal.logIceConnectionState();
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SETUP_ICE_LOGGER',
|
||||
function (test) {
|
||||
test.pcRemote.logIceConnectionState();
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CREATE_OFFER',
|
||||
function (test) {
|
||||
@ -178,6 +199,7 @@ var commandsPeerConnection = [
|
||||
var myPc = myTest.pcLocal;
|
||||
|
||||
function onIceConnectedSuccess () {
|
||||
info("pcLocal ICE connection state log: " + test.pcLocal.iceConnectionLog);
|
||||
ok(true, "pc_local: ICE switched to 'connected' state");
|
||||
myTest.next();
|
||||
};
|
||||
@ -188,6 +210,7 @@ var commandsPeerConnection = [
|
||||
};
|
||||
|
||||
if (myPc.isIceConnected()) {
|
||||
info("pcLocal ICE connection state log: " + test.pcLocal.iceConnectionLog);
|
||||
ok(true, "pc_local: ICE is in connected state");
|
||||
myTest.next();
|
||||
} else if (myPc.isIceConnectionPending()) {
|
||||
@ -206,6 +229,7 @@ var commandsPeerConnection = [
|
||||
var myPc = myTest.pcRemote;
|
||||
|
||||
function onIceConnectedSuccess () {
|
||||
info("pcRemote ICE connection state log: " + test.pcRemote.iceConnectionLog);
|
||||
ok(true, "pc_remote: ICE switched to 'connected' state");
|
||||
myTest.next();
|
||||
};
|
||||
@ -216,6 +240,7 @@ var commandsPeerConnection = [
|
||||
};
|
||||
|
||||
if (myPc.isIceConnected()) {
|
||||
info("pcRemote ICE connection state log: " + test.pcRemote.iceConnectionLog);
|
||||
ok(true, "pc_remote: ICE is in connected state");
|
||||
myTest.next();
|
||||
} else if (myPc.isIceConnectionPending()) {
|
||||
@ -300,6 +325,13 @@ var commandsDataChannel = [
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SETUP_ICE_LOGGER',
|
||||
function (test) {
|
||||
test.pcLocal.logIceConnectionState();
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_GUM',
|
||||
function (test) {
|
||||
@ -316,6 +348,13 @@ var commandsDataChannel = [
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SETUP_ICE_LOGGER',
|
||||
function (test) {
|
||||
test.pcRemote.logIceConnectionState();
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CREATE_DATA_CHANNEL',
|
||||
function (test) {
|
||||
@ -428,6 +467,7 @@ var commandsDataChannel = [
|
||||
var myPc = myTest.pcLocal;
|
||||
|
||||
function onIceConnectedSuccess () {
|
||||
info("pcLocal ICE connection state log: " + test.pcLocal.iceConnectionLog);
|
||||
ok(true, "pc_local: ICE switched to 'connected' state");
|
||||
myTest.next();
|
||||
};
|
||||
@ -438,6 +478,7 @@ var commandsDataChannel = [
|
||||
};
|
||||
|
||||
if (myPc.isIceConnected()) {
|
||||
info("pcLocal ICE connection state log: " + test.pcLocal.iceConnectionLog);
|
||||
ok(true, "pc_local: ICE is in connected state");
|
||||
myTest.next();
|
||||
} else if (myPc.isIceConnectionPending()) {
|
||||
@ -456,6 +497,7 @@ var commandsDataChannel = [
|
||||
var myPc = myTest.pcRemote;
|
||||
|
||||
function onIceConnectedSuccess () {
|
||||
info("pcRemote ICE connection state log: " + test.pcRemote.iceConnectionLog);
|
||||
ok(true, "pc_remote: ICE switched to 'connected' state");
|
||||
myTest.next();
|
||||
};
|
||||
@ -466,6 +508,7 @@ var commandsDataChannel = [
|
||||
};
|
||||
|
||||
if (myPc.isIceConnected()) {
|
||||
info("pcRemote ICE connection state log: " + test.pcRemote.iceConnectionLog);
|
||||
ok(true, "pc_remote: ICE is in connected state");
|
||||
myTest.next();
|
||||
} else if (myPc.isIceConnectionPending()) {
|
||||
|
@ -224,6 +224,8 @@ var interfaceNamesInGlobalScope =
|
||||
"CSSCharsetRule",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"CSSConditionRule",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"CSSCounterStyleRule",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"CSSFontFaceRule",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -286,7 +286,11 @@ interface CanvasGradient {
|
||||
|
||||
interface CanvasPattern {
|
||||
// opaque object
|
||||
// void setTransform(SVGMatrix transform);
|
||||
// [Throws, LenientFloat] - could not do this overload because of bug 1020975
|
||||
// void setTransform(double a, double b, double c, double d, double e, double f);
|
||||
|
||||
// No throw necessary here - SVGMatrix is always good.
|
||||
void setTransform(SVGMatrix matrix);
|
||||
};
|
||||
|
||||
interface TextMetrics {
|
||||
|
@ -29,6 +29,9 @@ interface WebrtcGlobalInformation {
|
||||
// - Subsequently setting a zero debug level writes that log to disk.
|
||||
|
||||
static attribute long debugLevel;
|
||||
|
||||
// WebRTC AEC debugging enable
|
||||
static attribute boolean aecDebug;
|
||||
};
|
||||
|
||||
|
||||
|
@ -3127,26 +3127,10 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
|
||||
|
||||
size_t actionsIndex = windowActions.LastIndexOf(WindowAction(window));
|
||||
|
||||
// Get the context for this window so that we can report errors correctly.
|
||||
JSContext* cx;
|
||||
rv = NS_OK;
|
||||
|
||||
if (actionsIndex == windowActions.NoIndex) {
|
||||
nsIScriptContext* scx = sharedWorker->GetContextForEventHandlers(&rv);
|
||||
cx = (NS_SUCCEEDED(rv) && scx) ?
|
||||
scx->GetNativeContext() :
|
||||
nsContentUtils::GetSafeJSContext();
|
||||
} else {
|
||||
cx = windowActions[actionsIndex].mJSContext;
|
||||
}
|
||||
|
||||
AutoCxPusher autoPush(cx);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
Throw(cx, rv);
|
||||
JS_ReportPendingException(cx);
|
||||
continue;
|
||||
}
|
||||
nsIGlobalObject* global = sharedWorker->GetParentObject();
|
||||
AutoJSAPIWithErrorsReportedToWindow jsapi(global);
|
||||
JSContext* cx = jsapi.cx();
|
||||
JSAutoCompartment ac(cx, global->GetGlobalJSObject());
|
||||
|
||||
RootedDictionary<ErrorEventInit> errorInit(aCx);
|
||||
errorInit.mBubbles = false;
|
||||
@ -3168,7 +3152,7 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
|
||||
errorEvent->SetTrusted(true);
|
||||
|
||||
bool defaultActionEnabled;
|
||||
rv = sharedWorker->DispatchEvent(errorEvent, &defaultActionEnabled);
|
||||
nsresult rv = sharedWorker->DispatchEvent(errorEvent, &defaultActionEnabled);
|
||||
if (NS_FAILED(rv)) {
|
||||
Throw(cx, rv);
|
||||
JS_ReportPendingException(cx);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
57219
|
||||
57220
|
||||
0/nm
|
||||
0th/pt
|
||||
1/n1
|
||||
@ -10811,6 +10811,7 @@ Mozart/M
|
||||
Mozelle/M
|
||||
Mozes/M
|
||||
Mozilla/M
|
||||
Mozillian/SM
|
||||
Mr/SM
|
||||
Ms/S
|
||||
Msgr
|
||||
|
@ -69,13 +69,20 @@ SourceSurfaceD2D::InitFromData(unsigned char *aData,
|
||||
}
|
||||
|
||||
D2D1_BITMAP_PROPERTIES props = D2D1::BitmapProperties(D2DPixelFormat(aFormat));
|
||||
hr = aRT->CreateBitmap(D2DIntSize(aSize), aData, aStride, props, byRef(mBitmap));
|
||||
hr = aRT->CreateBitmap(D2DIntSize(aSize), props, byRef(mBitmap));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
gfxWarning() << "Failed to create D2D Bitmap for data. Code: " << hr;
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = mBitmap->CopyFromMemory(nullptr, aData, aStride);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
gfxWarning() << "Failed to copy data to D2D bitmap. Code: " << hr;
|
||||
return false;
|
||||
}
|
||||
|
||||
DrawTargetD2D::mVRAMUsageSS += GetByteSize();
|
||||
mDevice = Factory::GetDirect3D10Device();
|
||||
|
||||
|
@ -771,31 +771,38 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
return (ReadParam(aMsg, aIter, &aResult->mScrollableRect) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mViewport) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mScrollOffset) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mDisplayPort) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mDisplayPortMargins) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mUseDisplayPortMargins) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mCriticalDisplayPort) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mCompositionBounds) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mRootCompositionSize) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mScrollId) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mResolution) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mCumulativeResolution) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mZoom) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mDevPixelsPerCSSPixel) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mMayHaveTouchListeners) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mMayHaveTouchCaret) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mPresShellId) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mIsRoot) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mHasScrollgrab) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mUpdateScrollOffset) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mScrollGeneration) &&
|
||||
aMsg->ReadBytes(aIter,
|
||||
reinterpret_cast<const char**>(&aResult->mContentDescription),
|
||||
sizeof(aResult->mContentDescription)) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mTransformScale));
|
||||
const char* contentDescription;
|
||||
if (!(ReadParam(aMsg, aIter, &aResult->mScrollableRect) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mViewport) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mScrollOffset) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mDisplayPort) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mDisplayPortMargins) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mUseDisplayPortMargins) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mCriticalDisplayPort) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mCompositionBounds) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mRootCompositionSize) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mScrollId) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mResolution) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mCumulativeResolution) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mZoom) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mDevPixelsPerCSSPixel) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mMayHaveTouchListeners) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mMayHaveTouchCaret) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mPresShellId) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mIsRoot) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mHasScrollgrab) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mUpdateScrollOffset) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mScrollGeneration) &&
|
||||
aMsg->ReadBytes(aIter, &contentDescription,
|
||||
sizeof(aResult->mContentDescription)) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mTransformScale))) {
|
||||
return false;
|
||||
}
|
||||
// ReadBytes() doesn't actually copy the string, it only points
|
||||
// a pointer to the string in its internal buffer.
|
||||
strncpy(aResult->mContentDescription, contentDescription,
|
||||
sizeof(aResult->mContentDescription));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -287,7 +287,7 @@ void
|
||||
SharedBufferManagerChild::DeallocGrallocBuffer(const mozilla::layers::MaybeMagicGrallocBufferHandle& aBuffer)
|
||||
{
|
||||
#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
|
||||
NS_ASSERTION(aBuffer.type() != mozilla::layers::MaybeMagicGrallocBufferHandle::TMagicGrallocBufferHandle, "We shouldn't trying to do IPC with real buffer");
|
||||
NS_ASSERTION(aBuffer.type() != mozilla::layers::MaybeMagicGrallocBufferHandle::TMagicGrallocBufferHandle, "We shouldn't try to do IPC with real buffer");
|
||||
if (aBuffer.type() != mozilla::layers::MaybeMagicGrallocBufferHandle::TGrallocBufferRef) {
|
||||
return;
|
||||
}
|
||||
@ -305,7 +305,7 @@ void
|
||||
SharedBufferManagerChild::DeallocGrallocBufferNow(const mozilla::layers::MaybeMagicGrallocBufferHandle& aBuffer)
|
||||
{
|
||||
#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
|
||||
NS_ASSERTION(aBuffer.type() != mozilla::layers::MaybeMagicGrallocBufferHandle::TMagicGrallocBufferHandle, "We shouldn't trying to do IPC with real buffer");
|
||||
NS_ASSERTION(aBuffer.type() != mozilla::layers::MaybeMagicGrallocBufferHandle::TMagicGrallocBufferHandle, "We shouldn't try to do IPC with real buffer");
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mBufferMutex);
|
||||
@ -325,7 +325,7 @@ bool SharedBufferManagerChild::RecvDropGrallocBuffer(const mozilla::layers::Mayb
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mBufferMutex);
|
||||
NS_ASSERTION(mBuffers.count(bufferKey) != 0, "Not my buffer");
|
||||
NS_ASSERTION(mBuffers.count(bufferKey) != 0, "No such buffer");
|
||||
mBuffers.erase(bufferKey);
|
||||
}
|
||||
#endif
|
||||
|
@ -197,7 +197,7 @@ bool SharedBufferManagerParent::RecvDropGrallocBuffer(const mozilla::layers::May
|
||||
sp<GraphicBuffer> buf = GetGraphicBuffer(bufferKey);
|
||||
MOZ_ASSERT(buf.get());
|
||||
MutexAutoLock lock(mBuffersMutex);
|
||||
NS_ASSERTION(mBuffers.count(bufferKey) == 1, "How can you drop others buffer");
|
||||
NS_ASSERTION(mBuffers.count(bufferKey) == 1, "No such buffer");
|
||||
mBuffers.erase(bufferKey);
|
||||
|
||||
if(!buf.get()) {
|
||||
@ -252,7 +252,7 @@ void SharedBufferManagerParent::DropGrallocBufferImpl(mozilla::layers::SurfaceDe
|
||||
key = handle.get_MagicGrallocBufferHandle().mRef.mKey;
|
||||
|
||||
NS_ASSERTION(key != -1, "Invalid buffer key");
|
||||
NS_ASSERTION(mBuffers.count(key) == 1, "How can you drop others buffer");
|
||||
NS_ASSERTION(mBuffers.count(key) == 1, "No such buffer");
|
||||
mBuffers.erase(key);
|
||||
SendDropGrallocBuffer(handle);
|
||||
#endif
|
||||
@ -275,8 +275,13 @@ android::sp<android::GraphicBuffer>
|
||||
SharedBufferManagerParent::GetGraphicBuffer(int key)
|
||||
{
|
||||
MutexAutoLock lock(mBuffersMutex);
|
||||
NS_ASSERTION(mBuffers.count(key) == 1, "No such buffer, or the buffer is belongs to other session");
|
||||
return mBuffers[key];
|
||||
if (mBuffers.count(key) == 1) {
|
||||
return mBuffers[key];
|
||||
}
|
||||
else {
|
||||
// The buffer can be dropped, or invalid
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
android::sp<android::GraphicBuffer>
|
||||
|
@ -98,7 +98,7 @@ gfxPattern::AddColorStop(gfxFloat offset, const gfxRGBA& c)
|
||||
}
|
||||
|
||||
void
|
||||
gfxPattern::SetColorStops(mozilla::RefPtr<GradientStops> aStops)
|
||||
gfxPattern::SetColorStops(GradientStops* aStops)
|
||||
{
|
||||
mStops = aStops;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
|
||||
cairo_pattern_t *CairoPattern();
|
||||
void AddColorStop(gfxFloat offset, const gfxRGBA& c);
|
||||
void SetColorStops(mozilla::RefPtr<mozilla::gfx::GradientStops> aStops);
|
||||
void SetColorStops(mozilla::gfx::GradientStops* aStops);
|
||||
|
||||
// This should only be called on a cairo pattern that we want to use with
|
||||
// Azure. We will read back the color stops from cairo and try to look
|
||||
|
@ -534,19 +534,19 @@ gfxPlatform::~gfxPlatform()
|
||||
|
||||
cairo_user_data_key_t kDrawTarget;
|
||||
|
||||
RefPtr<DrawTarget>
|
||||
TemporaryRef<DrawTarget>
|
||||
gfxPlatform::CreateDrawTargetForSurface(gfxASurface *aSurface, const IntSize& aSize)
|
||||
{
|
||||
SurfaceFormat format = Optimal2DFormatForContent(aSurface->GetContentType());
|
||||
RefPtr<DrawTarget> drawTarget = Factory::CreateDrawTargetForCairoSurface(aSurface->CairoSurface(), aSize, &format);
|
||||
aSurface->SetData(&kDrawTarget, drawTarget, nullptr);
|
||||
return drawTarget;
|
||||
return drawTarget.forget();
|
||||
}
|
||||
|
||||
// This is a temporary function used by ContentClient to build a DrawTarget
|
||||
// around the gfxASurface. This should eventually be replaced by plumbing
|
||||
// the DrawTarget through directly
|
||||
RefPtr<DrawTarget>
|
||||
TemporaryRef<DrawTarget>
|
||||
gfxPlatform::CreateDrawTargetForUpdateSurface(gfxASurface *aSurface, const IntSize& aSize)
|
||||
{
|
||||
#ifdef XP_MACOSX
|
||||
@ -643,7 +643,7 @@ CopySurface(gfxASurface* aSurface)
|
||||
return data;
|
||||
}
|
||||
|
||||
/* static */ RefPtr<SourceSurface>
|
||||
/* static */ TemporaryRef<SourceSurface>
|
||||
gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurface)
|
||||
{
|
||||
if (!aSurface->CairoSurface() || aSurface->CairoStatus()) {
|
||||
@ -709,7 +709,7 @@ gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurfa
|
||||
if (srcBuffer) {
|
||||
// It's cheap enough to make a new one so we won't keep it around and
|
||||
// keeping it creates a cycle.
|
||||
return srcBuffer;
|
||||
return srcBuffer.forget();
|
||||
}
|
||||
}
|
||||
|
||||
@ -734,7 +734,7 @@ gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurfa
|
||||
// Our wrapping surface will hold a reference to its image surface. We cause
|
||||
// a reference cycle if we add it to the cache. And caching it is pretty
|
||||
// pointless since we'll just wrap it again next use.
|
||||
return srcBuffer;
|
||||
return srcBuffer.forget();
|
||||
}
|
||||
}
|
||||
|
||||
@ -744,10 +744,10 @@ gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurfa
|
||||
srcSurfUD->mSrcSurface = srcBuffer;
|
||||
aSurface->SetData(&kSourceSurface, srcSurfUD, SourceBufferDestroy);
|
||||
|
||||
return srcBuffer;
|
||||
return srcBuffer.forget();
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface>
|
||||
TemporaryRef<DataSourceSurface>
|
||||
gfxPlatform::GetWrappedDataSourceSurface(gfxASurface* aSurface)
|
||||
{
|
||||
nsRefPtr<gfxImageSurface> image = aSurface->GetAsImageSurface();
|
||||
@ -770,7 +770,7 @@ gfxPlatform::GetWrappedDataSourceSurface(gfxASurface* aSurface)
|
||||
srcSurfUD->mSurface = aSurface;
|
||||
result->AddUserData(&kThebesSurface, srcSurfUD, SourceSurfaceDestroyed);
|
||||
|
||||
return result;
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
TemporaryRef<ScaledFont>
|
||||
@ -927,7 +927,7 @@ gfxPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
|
||||
return surf.forget();
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget>
|
||||
TemporaryRef<DrawTarget>
|
||||
gfxPlatform::CreateDrawTargetForBackend(BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat)
|
||||
{
|
||||
// There is a bunch of knowledge in the gfxPlatform heirarchy about how to
|
||||
@ -951,27 +951,27 @@ gfxPlatform::CreateDrawTargetForBackend(BackendType aBackend, const IntSize& aSi
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget>
|
||||
TemporaryRef<DrawTarget>
|
||||
gfxPlatform::CreateOffscreenCanvasDrawTarget(const IntSize& aSize, SurfaceFormat aFormat)
|
||||
{
|
||||
NS_ASSERTION(mPreferredCanvasBackend != BackendType::NONE, "No backend.");
|
||||
RefPtr<DrawTarget> target = CreateDrawTargetForBackend(mPreferredCanvasBackend, aSize, aFormat);
|
||||
if (target ||
|
||||
mFallbackCanvasBackend == BackendType::NONE) {
|
||||
return target;
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
return CreateDrawTargetForBackend(mFallbackCanvasBackend, aSize, aFormat);
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget>
|
||||
TemporaryRef<DrawTarget>
|
||||
gfxPlatform::CreateOffscreenContentDrawTarget(const IntSize& aSize, SurfaceFormat aFormat)
|
||||
{
|
||||
NS_ASSERTION(mPreferredCanvasBackend != BackendType::NONE, "No backend.");
|
||||
return CreateDrawTargetForBackend(mContentBackend, aSize, aFormat);
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget>
|
||||
TemporaryRef<DrawTarget>
|
||||
gfxPlatform::CreateDrawTargetForData(unsigned char* aData, const IntSize& aSize, int32_t aStride, SurfaceFormat aFormat)
|
||||
{
|
||||
NS_ASSERTION(mContentBackend != BackendType::NONE, "No backend.");
|
||||
|
@ -155,7 +155,10 @@ GetBackendName(mozilla::gfx::BackendType aBackend)
|
||||
|
||||
class gfxPlatform {
|
||||
public:
|
||||
typedef mozilla::gfx::DataSourceSurface DataSourceSurface;
|
||||
typedef mozilla::gfx::DrawTarget DrawTarget;
|
||||
typedef mozilla::gfx::IntSize IntSize;
|
||||
typedef mozilla::gfx::SourceSurface SourceSurface;
|
||||
|
||||
/**
|
||||
* Return a pointer to the current active platform.
|
||||
@ -187,10 +190,10 @@ public:
|
||||
* support the DrawTarget we get back.
|
||||
* See SupportsAzureContentForDrawTarget.
|
||||
*/
|
||||
virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
|
||||
virtual mozilla::TemporaryRef<DrawTarget>
|
||||
CreateDrawTargetForSurface(gfxASurface *aSurface, const mozilla::gfx::IntSize& aSize);
|
||||
|
||||
virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
|
||||
virtual mozilla::TemporaryRef<DrawTarget>
|
||||
CreateDrawTargetForUpdateSurface(gfxASurface *aSurface, const mozilla::gfx::IntSize& aSize);
|
||||
|
||||
/*
|
||||
@ -205,12 +208,12 @@ public:
|
||||
* PluginInstanceChild (where we can't call gfxPlatform::GetPlatform()
|
||||
* because the prefs service can only be accessed from the main process).
|
||||
*/
|
||||
static mozilla::RefPtr<mozilla::gfx::SourceSurface>
|
||||
static mozilla::TemporaryRef<SourceSurface>
|
||||
GetSourceSurfaceForSurface(mozilla::gfx::DrawTarget *aTarget, gfxASurface *aSurface);
|
||||
|
||||
static void ClearSourceSurfaceForSurface(gfxASurface *aSurface);
|
||||
|
||||
static mozilla::RefPtr<mozilla::gfx::DataSourceSurface>
|
||||
static mozilla::TemporaryRef<DataSourceSurface>
|
||||
GetWrappedDataSourceSurface(gfxASurface *aSurface);
|
||||
|
||||
virtual mozilla::TemporaryRef<mozilla::gfx::ScaledFont>
|
||||
@ -219,13 +222,13 @@ public:
|
||||
virtual already_AddRefed<gfxASurface>
|
||||
GetThebesSurfaceForDrawTarget(mozilla::gfx::DrawTarget *aTarget);
|
||||
|
||||
mozilla::RefPtr<mozilla::gfx::DrawTarget>
|
||||
mozilla::TemporaryRef<DrawTarget>
|
||||
CreateOffscreenContentDrawTarget(const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat);
|
||||
|
||||
mozilla::RefPtr<mozilla::gfx::DrawTarget>
|
||||
mozilla::TemporaryRef<DrawTarget>
|
||||
CreateOffscreenCanvasDrawTarget(const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat);
|
||||
|
||||
virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
|
||||
virtual mozilla::TemporaryRef<DrawTarget>
|
||||
CreateDrawTargetForData(unsigned char* aData, const mozilla::gfx::IntSize& aSize,
|
||||
int32_t aStride, mozilla::gfx::SurfaceFormat aFormat);
|
||||
|
||||
@ -557,7 +560,7 @@ protected:
|
||||
* Helper method, creates a draw target for a specific Azure backend.
|
||||
* Used by CreateOffscreenDrawTarget.
|
||||
*/
|
||||
mozilla::RefPtr<mozilla::gfx::DrawTarget>
|
||||
mozilla::TemporaryRef<DrawTarget>
|
||||
CreateDrawTargetForBackend(mozilla::gfx::BackendType aBackend,
|
||||
const mozilla::gfx::IntSize& aSize,
|
||||
mozilla::gfx::SurfaceFormat aFormat);
|
||||
|
@ -965,7 +965,7 @@ gfxUtils::CopyAsDataURL(DrawTarget* aDT)
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
gfxUtils::WriteAsPNG(RefPtr<gfx::SourceSurface> aSourceSurface, const char* aFile)
|
||||
gfxUtils::WriteAsPNG(gfx::SourceSurface* aSourceSurface, const char* aFile)
|
||||
{
|
||||
RefPtr<gfx::DataSourceSurface> dataSurface = aSourceSurface->GetDataSurface();
|
||||
RefPtr<gfx::DrawTarget> dt
|
||||
@ -978,7 +978,7 @@ gfxUtils::WriteAsPNG(RefPtr<gfx::SourceSurface> aSourceSurface, const char* aFil
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
gfxUtils::DumpAsDataURL(RefPtr<gfx::SourceSurface> aSourceSurface)
|
||||
gfxUtils::DumpAsDataURL(gfx::SourceSurface* aSourceSurface)
|
||||
{
|
||||
RefPtr<gfx::DataSourceSurface> dataSurface = aSourceSurface->GetDataSurface();
|
||||
RefPtr<gfx::DrawTarget> dt
|
||||
@ -991,7 +991,7 @@ gfxUtils::DumpAsDataURL(RefPtr<gfx::SourceSurface> aSourceSurface)
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
gfxUtils::CopyAsDataURL(RefPtr<gfx::SourceSurface> aSourceSurface)
|
||||
gfxUtils::CopyAsDataURL(gfx::SourceSurface* aSourceSurface)
|
||||
{
|
||||
RefPtr<gfx::DataSourceSurface> dataSurface = aSourceSurface->GetDataSurface();
|
||||
RefPtr<gfx::DrawTarget> dt
|
||||
|
@ -240,19 +240,19 @@ public:
|
||||
* Writes a binary PNG file.
|
||||
* Expensive. Creates a DataSourceSurface, then a DrawTarget, then passes to DrawTarget overloads
|
||||
*/
|
||||
static void WriteAsPNG(mozilla::RefPtr<mozilla::gfx::SourceSurface> aSourceSurface, const char* aFile);
|
||||
static void WriteAsPNG(mozilla::gfx::SourceSurface* aSourceSurface, const char* aFile);
|
||||
|
||||
/**
|
||||
* Write as a PNG encoded Data URL to stdout.
|
||||
* Expensive. Creates a DataSourceSurface, then a DrawTarget, then passes to DrawTarget overloads
|
||||
*/
|
||||
static void DumpAsDataURL(mozilla::RefPtr<mozilla::gfx::SourceSurface> aSourceSurface);
|
||||
static void DumpAsDataURL(mozilla::gfx::SourceSurface* aSourceSurface);
|
||||
|
||||
/**
|
||||
* Copy a PNG encoded Data URL to the clipboard.
|
||||
* Expensive. Creates a DataSourceSurface, then a DrawTarget, then passes to DrawTarget overloads
|
||||
*/
|
||||
static void CopyAsDataURL(mozilla::RefPtr<mozilla::gfx::SourceSurface> aSourceSurface);
|
||||
static void CopyAsDataURL(mozilla::gfx::SourceSurface* aSourceSurface);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -34,7 +34,7 @@ ifdef ENABLE_INTL_API
|
||||
else # !MOZ_SHARED_ICU
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
ICU_LIB_RENAME = $(foreach libname,$(ICU_LIB_NAMES),\
|
||||
cp -p $(DEPTH)/intl/icu/target/lib/s$(libname)$(MOZ_ICU_DBG_SUFFIX).lib $(DEPTH)/intl/icu/target/lib/$(libname).lib;)
|
||||
cp -p $(DEPTH)/intl/icu/target/lib/s$(libname)$(MOZ_ICU_DBG_SUFFIX).lib $(DEPTH)/intl/icu/target/lib/$(libname)$(MOZ_ICU_DBG_SUFFIX).lib;)
|
||||
endif
|
||||
endif # MOZ_SHARED_ICU
|
||||
endif # !MOZ_NATIVE_ICU
|
||||
|
@ -864,7 +864,12 @@ function ArrayScanPar(func, mode) {
|
||||
if (length === 0)
|
||||
ThrowError(JSMSG_EMPTY_ARRAY_REDUCE);
|
||||
|
||||
// We need two buffers because phase2() will read an intermediate result and
|
||||
// write a final result; that is safe against bailout-and-restart only if
|
||||
// the intermediate and final buffers are distinct. (Bug 1023755)
|
||||
// Obviously paying for a second buffer is undesirable.
|
||||
var buffer = NewDenseArray(length);
|
||||
var buffer2 = NewDenseArray(length);
|
||||
|
||||
parallel: for (;;) { // see ArrayMapPar() to explain why for(;;) etc
|
||||
if (ShouldForceSequential())
|
||||
@ -889,11 +894,12 @@ function ArrayScanPar(func, mode) {
|
||||
|
||||
// Complete each slice using intermediates array (see comment on phase2()).
|
||||
//
|
||||
// We start from slice 1 instead of 0 since there is no work to be done
|
||||
// for slice 0.
|
||||
if (numSlices > 1)
|
||||
ForkJoin(phase2, 1, numSlices, ForkJoinMode(mode), buffer);
|
||||
return buffer;
|
||||
// Slice 0 must be handled specially - it's just a copy - since we don't
|
||||
// have an identity value for the operation.
|
||||
for ( var k=0, limit=finalElement(0) ; k <= limit ; k++ )
|
||||
buffer2[k] = buffer[k];
|
||||
ForkJoin(phase2, 1, numSlices, ForkJoinMode(mode), buffer2);
|
||||
return buffer2;
|
||||
}
|
||||
|
||||
// Sequential fallback:
|
||||
@ -986,7 +992,7 @@ function ArrayScanPar(func, mode) {
|
||||
var indexEnd = SLICE_END_INDEX(sliceShift, indexPos, length);
|
||||
var intermediate = intermediates[sliceId - 1];
|
||||
for (; indexPos < indexEnd; indexPos++)
|
||||
UnsafePutElements(buffer, indexPos, func(intermediate, buffer[indexPos]));
|
||||
UnsafePutElements(buffer2, indexPos, func(intermediate, buffer[indexPos]));
|
||||
}
|
||||
return sliceId;
|
||||
}
|
||||
|
@ -2791,6 +2791,8 @@ MOZ_ARG_DISABLE_BOOL(threadsafe,
|
||||
if test -n "$JS_THREADSAFE"; then
|
||||
AC_DEFINE(JS_THREADSAFE)
|
||||
fi
|
||||
JS_THREADSAFE_CONFIGURED=$JS_THREADSAFE
|
||||
AC_SUBST(JS_THREADSAFE_CONFIGURED)
|
||||
|
||||
if test "$_USE_SYSTEM_NSPR" || (test "$NSPR_CFLAGS" -o "$NSPR_LIBS"); then
|
||||
_HAS_NSPR=1
|
||||
|
@ -41,7 +41,7 @@ of the additional attack surface.
|
||||
## Debugger Instances and Shadow Objects
|
||||
|
||||
`Debugger` reflects every aspect of the debuggee's state as a JavaScript
|
||||
value—not just actual JavaScript values like objects and primitives,
|
||||
value---not just actual JavaScript values like objects and primitives,
|
||||
but also stack frames, environments, scripts, and compilation units, which
|
||||
are not normally accessible as objects in their own right.
|
||||
|
||||
@ -57,7 +57,7 @@ Debugger API (which all follow some [general conventions][conventions]):
|
||||
invoking getters, setters, proxy traps, and so on.
|
||||
|
||||
- A [`Debugger.Script`][script] represents a block of JavaScript
|
||||
code—either a function body or a top-level script. Given a
|
||||
code---either a function body or a top-level script. Given a
|
||||
`Debugger.Script`, one can set breakpoints, translate between source
|
||||
positions and bytecode offsets (a deviation from the "source level"
|
||||
design principle), and find other static characteristics of the code.
|
||||
@ -154,7 +154,7 @@ You can try out `Debugger` yourself in Firefox's Scratchpad.
|
||||
![The Debugger callback displaying an alert][img-example-alert]
|
||||
|
||||
7) Press "Run" in the Scratchpad again. Now, clicking on the "Click me!"
|
||||
text causes *two* alerts to show—one for each `Debugger`
|
||||
text causes *two* alerts to show---one for each `Debugger`
|
||||
instance.
|
||||
|
||||
Multiple `Debugger` instances can observe the same debuggee. Re-running
|
||||
@ -163,7 +163,7 @@ You can try out `Debugger` yourself in Firefox's Scratchpad.
|
||||
`debugger;` statement handler with the new instance. When you clicked
|
||||
on the `div` element, both of them ran. This shows how any number of
|
||||
`Debugger`-based tools can observe a single web page
|
||||
simultaneously—although, since the order in which their handlers
|
||||
simultaneously---although, since the order in which their handlers
|
||||
run is not specified, such tools should probably only observe, and not
|
||||
influence, the debuggee's behavior.
|
||||
|
||||
@ -185,6 +185,6 @@ While the `Debugger` core API deals only with concepts common to any
|
||||
JavaScript implementation, it also includes some Gecko-specific features:
|
||||
|
||||
- [Global tracking][global] supports debugging all the code running in a
|
||||
Gecko instance at once—the 'chrome debugging' model.
|
||||
Gecko instance at once---the 'chrome debugging' model.
|
||||
- [Object wrapper][wrapper] functions help manipulate object references
|
||||
that cross privilege boundaries.
|
||||
|
@ -83,7 +83,11 @@ markdown() {
|
||||
local output_file=$outputdir/${INPUT_FILE/md/html}
|
||||
|
||||
mkdir -p $(dirname "$output_file")
|
||||
pandoc $standalone_arg -f markdown "$file" <("$lib/make-bibliography.sh" $mdn_arg "$config" "$URL") -t html -o "$output_file"
|
||||
pandoc $standalone_arg \
|
||||
-f markdown --smart -t html \
|
||||
"$file" \
|
||||
<("$lib/make-bibliography.sh" $mdn_arg "$config" "$URL") \
|
||||
-o "$output_file"
|
||||
|
||||
"$lib/make-watermark.sh" "$output_file" "$hg_relative_sourcedir/$INPUT_FILE" >> "$output_file"
|
||||
}
|
||||
|
@ -394,7 +394,7 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext *cx)
|
||||
masm.movePtr(ImmPtr(runtime), temp1);
|
||||
|
||||
// Save registers before calling C function
|
||||
RegisterSet volatileRegs = RegisterSet::Volatile();
|
||||
GeneralRegisterSet volatileRegs = GeneralRegisterSet::Volatile();
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
volatileRegs.add(Register::FromCode(Registers::lr));
|
||||
#elif defined(JS_CODEGEN_MIPS)
|
||||
@ -733,7 +733,7 @@ NativeRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(int start_reg, Label
|
||||
JS_ASSERT(mode_ == JSCHAR);
|
||||
|
||||
// Note: temp1 needs to be saved/restored if it is volatile, as it is used after the call.
|
||||
RegisterSet volatileRegs = RegisterSet::Volatile();
|
||||
GeneralRegisterSet volatileRegs = GeneralRegisterSet::Volatile();
|
||||
volatileRegs.takeUnchecked(temp0);
|
||||
volatileRegs.takeUnchecked(temp2);
|
||||
masm.PushRegsInMask(volatileRegs);
|
||||
|
@ -31,6 +31,25 @@ function rbitnot_object(i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
var uceFault_bitand_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_bitand_number'));
|
||||
function rbitand_number(i) {
|
||||
var x = 1 & i;
|
||||
if (uceFault_bitand_number(i) || uceFault_bitand_number(i))
|
||||
assertEq(x, 1 /* = 1 & 99 */);
|
||||
return i;
|
||||
}
|
||||
|
||||
var uceFault_bitand_object = eval(uneval(uceFault).replace('uceFault', 'uceFault_bitand_object'));
|
||||
function rbitand_object(i) {
|
||||
var t = i;
|
||||
var o = { valueOf: function () { return t; } };
|
||||
var x = o & i; /* computed with t == i, not 1000 */
|
||||
t = 1000;
|
||||
if (uceFault_bitand_object(i) || uceFault_bitand_object(i))
|
||||
assertEq(x, 99);
|
||||
return i;
|
||||
}
|
||||
|
||||
var uceFault_bitor_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_bitor_number'));
|
||||
function rbitor_number(i) {
|
||||
var x = i | -100; /* -100 == ~99 */
|
||||
@ -280,6 +299,8 @@ function rconcat_number(i) {
|
||||
for (i = 0; i < 100; i++) {
|
||||
rbitnot_number(i);
|
||||
rbitnot_object(i);
|
||||
rbitand_number(i);
|
||||
rbitand_object(i);
|
||||
rbitor_number(i);
|
||||
rbitor_object(i);
|
||||
rbitxor_number(i);
|
||||
|
@ -192,6 +192,7 @@ IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
|
||||
: JitFrameIterator(activations),
|
||||
machine_(frame.machineState())
|
||||
{
|
||||
kind_ = Kind_BailoutIterator;
|
||||
returnAddressToFp_ = frame.returnAddressToFp();
|
||||
topIonScript_ = frame.ionScript();
|
||||
const OsiIndex *osiIndex = frame.osiIndex();
|
||||
|
@ -125,11 +125,14 @@ class IonBailoutIterator : public JitFrameIterator
|
||||
IonBailoutIterator(const JitActivationIterator &activations, const JitFrameIterator &frame);
|
||||
|
||||
SnapshotOffset snapshotOffset() const {
|
||||
JS_ASSERT(topIonScript_);
|
||||
return snapshotOffset_;
|
||||
if (topIonScript_)
|
||||
return snapshotOffset_;
|
||||
return osiIndex()->snapshotOffset();
|
||||
}
|
||||
const MachineState &machineState() const {
|
||||
return machine_;
|
||||
const MachineState machineState() const {
|
||||
if (topIonScript_)
|
||||
return machine_;
|
||||
return JitFrameIterator::machineState();
|
||||
}
|
||||
size_t topFrameSize() const {
|
||||
JS_ASSERT(topIonScript_);
|
||||
@ -141,6 +144,14 @@ class IonBailoutIterator : public JitFrameIterator
|
||||
return JitFrameIterator::ionScript();
|
||||
}
|
||||
|
||||
IonBailoutIterator &operator++() {
|
||||
JitFrameIterator::operator++();
|
||||
// Clear topIonScript_ now that we've advanced past it, so that
|
||||
// snapshotOffset() and machineState() reflect the current script.
|
||||
topIonScript_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
|
@ -1672,13 +1672,45 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo *bailoutInfo)
|
||||
(unsigned) bailoutKind);
|
||||
|
||||
switch (bailoutKind) {
|
||||
case Bailout_Normal:
|
||||
// Normal bailouts.
|
||||
case Bailout_Inevitable:
|
||||
case Bailout_DuringVMCall:
|
||||
case Bailout_NonJSFunctionCallee:
|
||||
case Bailout_DynamicNameNotFound:
|
||||
case Bailout_StringArgumentsEval:
|
||||
case Bailout_Overflow:
|
||||
case Bailout_Round:
|
||||
case Bailout_NonPrimitiveInput:
|
||||
case Bailout_PrecisionLoss:
|
||||
case Bailout_TypeBarrierO:
|
||||
case Bailout_TypeBarrierV:
|
||||
case Bailout_MonitorTypes:
|
||||
case Bailout_Hole:
|
||||
case Bailout_NegativeIndex:
|
||||
case Bailout_ObjectIdentityOrTypeGuard:
|
||||
case Bailout_NonInt32Input:
|
||||
case Bailout_NonNumericInput:
|
||||
case Bailout_NonBooleanInput:
|
||||
case Bailout_NonObjectInput:
|
||||
case Bailout_NonStringInput:
|
||||
case Bailout_GuardThreadExclusive:
|
||||
case Bailout_InitialState:
|
||||
// Do nothing.
|
||||
break;
|
||||
|
||||
// Invalid assumption based on baseline code.
|
||||
case Bailout_OverflowInvalidate:
|
||||
case Bailout_NonStringInputInvalidate:
|
||||
case Bailout_DoubleOutput:
|
||||
if (!HandleBaselineInfoBailout(cx, outerScript, innerScript))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case Bailout_ArgumentCheck:
|
||||
// Do nothing, bailout will resume before the argument monitor ICs.
|
||||
break;
|
||||
case Bailout_BoundsCheck:
|
||||
case Bailout_Neutered:
|
||||
if (!HandleBoundsCheckFailure(cx, outerScript, innerScript))
|
||||
return false;
|
||||
break;
|
||||
@ -1686,10 +1718,6 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo *bailoutInfo)
|
||||
if (!HandleShapeGuardFailure(cx, outerScript, innerScript))
|
||||
return false;
|
||||
break;
|
||||
case Bailout_BaselineInfo:
|
||||
if (!HandleBaselineInfoBailout(cx, outerScript, innerScript))
|
||||
return false;
|
||||
break;
|
||||
case Bailout_IonExceptionDebugMode:
|
||||
// Return false to resume in HandleException with reconstructed
|
||||
// baseline frame.
|
||||
|
@ -9899,7 +9899,8 @@ IonBuilder::jsop_iternext()
|
||||
return false;
|
||||
|
||||
if (!nonStringIteration_ && !inspector->hasSeenNonStringIterNext(pc)) {
|
||||
ins = MUnbox::New(alloc(), ins, MIRType_String, MUnbox::Fallible, Bailout_BaselineInfo);
|
||||
ins = MUnbox::New(alloc(), ins, MIRType_String, MUnbox::Fallible,
|
||||
Bailout_NonStringInputInvalidate);
|
||||
current->add(ins);
|
||||
current->rewriteAtDepth(-1, ins);
|
||||
}
|
||||
|
@ -83,20 +83,23 @@ JitFrameIterator::JitFrameIterator(ThreadSafeContext *cx)
|
||||
type_(JitFrame_Exit),
|
||||
returnAddressToFp_(nullptr),
|
||||
frameSize_(0),
|
||||
mode_(cx->isForkJoinContext() ? ParallelExecution : SequentialExecution),
|
||||
kind_(Kind_FrameIterator),
|
||||
cachedSafepointIndex_(nullptr),
|
||||
activation_(nullptr),
|
||||
mode_(cx->isForkJoinContext() ? ParallelExecution : SequentialExecution)
|
||||
activation_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
JitFrameIterator::JitFrameIterator(const ActivationIterator &activations)
|
||||
: current_(activations.jitTop()),
|
||||
type_(JitFrame_Exit),
|
||||
returnAddressToFp_(nullptr),
|
||||
frameSize_(0),
|
||||
cachedSafepointIndex_(nullptr),
|
||||
activation_(activations->asJit()),
|
||||
mode_(activation_->cx()->isForkJoinContext() ? ParallelExecution : SequentialExecution)
|
||||
: current_(activations.jitTop()),
|
||||
type_(JitFrame_Exit),
|
||||
returnAddressToFp_(nullptr),
|
||||
frameSize_(0),
|
||||
mode_(activations->asJit()->cx()->isForkJoinContext() ? ParallelExecution
|
||||
: SequentialExecution),
|
||||
kind_(Kind_FrameIterator),
|
||||
cachedSafepointIndex_(nullptr),
|
||||
activation_(activations->asJit())
|
||||
{
|
||||
}
|
||||
|
||||
@ -105,10 +108,25 @@ JitFrameIterator::JitFrameIterator(IonJSFrameLayout *fp, ExecutionMode mode)
|
||||
type_(JitFrame_IonJS),
|
||||
returnAddressToFp_(fp->returnAddress()),
|
||||
frameSize_(fp->prevFrameLocalSize()),
|
||||
mode_(mode)
|
||||
mode_(mode),
|
||||
kind_(Kind_FrameIterator)
|
||||
{
|
||||
}
|
||||
|
||||
IonBailoutIterator *
|
||||
JitFrameIterator::asBailoutIterator()
|
||||
{
|
||||
MOZ_ASSERT(isBailoutIterator());
|
||||
return static_cast<IonBailoutIterator *>(this);
|
||||
}
|
||||
|
||||
const IonBailoutIterator *
|
||||
JitFrameIterator::asBailoutIterator() const
|
||||
{
|
||||
MOZ_ASSERT(isBailoutIterator());
|
||||
return static_cast<const IonBailoutIterator *>(this);
|
||||
}
|
||||
|
||||
bool
|
||||
JitFrameIterator::checkInvalidation() const
|
||||
{
|
||||
@ -1698,7 +1716,14 @@ JitFrameIterator::ionScriptFromCalleeToken() const
|
||||
switch (GetCalleeTokenTag(calleeToken())) {
|
||||
case CalleeToken_Function:
|
||||
case CalleeToken_Script:
|
||||
return mode_ == ParallelExecution ? script()->parallelIonScript() : script()->ionScript();
|
||||
switch (mode_) {
|
||||
case SequentialExecution:
|
||||
return script()->ionScript();
|
||||
case ParallelExecution:
|
||||
return script()->parallelIonScript();
|
||||
default:
|
||||
MOZ_ASSUME_UNREACHABLE("No such execution mode");
|
||||
}
|
||||
default:
|
||||
MOZ_ASSUME_UNREACHABLE("unknown callee token type");
|
||||
}
|
||||
@ -1754,7 +1779,11 @@ InlineFrameIterator::InlineFrameIterator(ThreadSafeContext *cx, const InlineFram
|
||||
script_(cx)
|
||||
{
|
||||
if (frame_) {
|
||||
start_ = SnapshotIterator(*frame_);
|
||||
if (frame_->isBailoutIterator())
|
||||
start_ = SnapshotIterator(*frame_->asBailoutIterator());
|
||||
else
|
||||
start_ = SnapshotIterator(*frame_);
|
||||
|
||||
// findNextFrame will iterate to the next frame and init. everything.
|
||||
// Therefore to settle on the same frame, we report one frame less readed.
|
||||
framesRead_ = iter->framesRead_ - 1;
|
||||
|
@ -35,9 +35,96 @@ static const SnapshotOffset INVALID_SNAPSHOT_OFFSET = uint32_t(-1);
|
||||
// the bits reserved for bailout kinds in Bailouts.h
|
||||
enum BailoutKind
|
||||
{
|
||||
// A normal bailout triggered from type, shape, and assorted overflow
|
||||
// guards in the compiler.
|
||||
Bailout_Normal,
|
||||
// Normal bailouts, that don't need to be handled specially when restarting
|
||||
// in baseline.
|
||||
|
||||
// An inevitable bailout (MBail instruction or type barrier that always bails)
|
||||
Bailout_Inevitable,
|
||||
|
||||
// Bailing out during a VM call. Many possible causes that are hard
|
||||
// to distinguish statically at snapshot construction time.
|
||||
// We just lump them together.
|
||||
Bailout_DuringVMCall,
|
||||
|
||||
// Call to a non-JSFunction (problem for |apply|)
|
||||
Bailout_NonJSFunctionCallee,
|
||||
|
||||
// Dynamic scope chain lookup produced |undefined|
|
||||
Bailout_DynamicNameNotFound,
|
||||
|
||||
// Input string contains 'arguments' or 'eval'
|
||||
Bailout_StringArgumentsEval,
|
||||
|
||||
// Bailout on overflow, but don't immediately invalidate.
|
||||
// Used for abs, sub and LoadTypedArrayElement (when loading a uint32 that
|
||||
// doesn't fit in an int32).
|
||||
Bailout_Overflow,
|
||||
|
||||
// floor, ceiling and round bail if input is NaN, if output would be -0 or
|
||||
// doesn't fit in int32 range
|
||||
Bailout_Round,
|
||||
|
||||
// Non-primitive value used as input for ToDouble, ToInt32, ToString, etc.
|
||||
// For ToInt32, can also mean that input can't be converted without precision
|
||||
// loss (e.g. 5.5).
|
||||
Bailout_NonPrimitiveInput,
|
||||
|
||||
// For ToInt32, would lose precision when converting (e.g. 5.5).
|
||||
Bailout_PrecisionLoss,
|
||||
|
||||
// We tripped a type barrier (object was not in the expected TypeSet)
|
||||
Bailout_TypeBarrierO,
|
||||
// We tripped a type barrier (value was not in the expected TypeSet)
|
||||
Bailout_TypeBarrierV,
|
||||
// We tripped a type monitor (wrote an unexpected type in a property)
|
||||
Bailout_MonitorTypes,
|
||||
|
||||
// We hit a hole in an array.
|
||||
Bailout_Hole,
|
||||
|
||||
// Array access with negative index
|
||||
Bailout_NegativeIndex,
|
||||
|
||||
// Pretty specific case:
|
||||
// - need a type barrier on a property write
|
||||
// - all but one of the observed types have property types that reflect the value
|
||||
// - we need to guard that we're not given an object of that one other type
|
||||
// also used for the unused GuardClass instruction
|
||||
Bailout_ObjectIdentityOrTypeGuard,
|
||||
|
||||
// Unbox expects a given type, bails out if it doesn't get it.
|
||||
Bailout_NonInt32Input,
|
||||
Bailout_NonNumericInput, // unboxing a double works with int32 too
|
||||
Bailout_NonBooleanInput,
|
||||
Bailout_NonObjectInput,
|
||||
Bailout_NonStringInput,
|
||||
|
||||
Bailout_GuardThreadExclusive,
|
||||
|
||||
// For the initial snapshot when entering a function.
|
||||
Bailout_InitialState,
|
||||
|
||||
// END Normal bailouts
|
||||
|
||||
|
||||
// Bailouts caused by invalid assumptions based on Baseline code.
|
||||
// Causes immediate invalidation.
|
||||
|
||||
// Like Bailout_Overflow, but causes immediate invalidation.
|
||||
Bailout_OverflowInvalidate,
|
||||
|
||||
// Like NonStringInput, but should cause immediate invalidation.
|
||||
// Used for jsop_iternext.
|
||||
Bailout_NonStringInputInvalidate,
|
||||
|
||||
// Used for integer division, multiplication and modulo.
|
||||
// If there's a remainder, bails to return a double.
|
||||
// Can also signal overflow or result of -0.
|
||||
// Can also signal division by 0 (returns inf, a double).
|
||||
Bailout_DoubleOutput,
|
||||
|
||||
// END Invalid assumptions bailouts
|
||||
|
||||
|
||||
// A bailout at the very start of a function indicates that there may be
|
||||
// a type mismatch in the arguments that necessitates a reflow.
|
||||
@ -45,13 +132,14 @@ enum BailoutKind
|
||||
|
||||
// A bailout triggered by a bounds-check failure.
|
||||
Bailout_BoundsCheck,
|
||||
// A bailout triggered by a neutered typed object.
|
||||
Bailout_Neutered,
|
||||
|
||||
// A shape guard based on TI information failed.
|
||||
// (We saw an object whose shape does not match that / any of those observed
|
||||
// by the baseline IC.)
|
||||
Bailout_ShapeGuard,
|
||||
|
||||
// A bailout caused by invalid assumptions based on Baseline code.
|
||||
Bailout_BaselineInfo,
|
||||
|
||||
// A bailout to baseline from Ion on exception to handle Debugger hooks.
|
||||
Bailout_IonExceptionDebugMode,
|
||||
};
|
||||
@ -60,16 +148,69 @@ inline const char *
|
||||
BailoutKindString(BailoutKind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case Bailout_Normal:
|
||||
return "Bailout_Normal";
|
||||
// Normal bailouts.
|
||||
case Bailout_Inevitable:
|
||||
return "Bailout_Inevitable";
|
||||
case Bailout_DuringVMCall:
|
||||
return "Bailout_DuringVMCall";
|
||||
case Bailout_NonJSFunctionCallee:
|
||||
return "Bailout_NonJSFunctionCallee";
|
||||
case Bailout_DynamicNameNotFound:
|
||||
return "Bailout_DynamicNameNotFound";
|
||||
case Bailout_StringArgumentsEval:
|
||||
return "Bailout_StringArgumentsEval";
|
||||
case Bailout_Overflow:
|
||||
return "Bailout_Overflow";
|
||||
case Bailout_Round:
|
||||
return "Bailout_Round";
|
||||
case Bailout_NonPrimitiveInput:
|
||||
return "Bailout_NonPrimitiveInput";
|
||||
case Bailout_PrecisionLoss:
|
||||
return "Bailout_PrecisionLoss";
|
||||
case Bailout_TypeBarrierO:
|
||||
return "Bailout_TypeBarrierO";
|
||||
case Bailout_TypeBarrierV:
|
||||
return "Bailout_TypeBarrierV";
|
||||
case Bailout_MonitorTypes:
|
||||
return "Bailout_MonitorTypes";
|
||||
case Bailout_Hole:
|
||||
return "Bailout_Hole";
|
||||
case Bailout_NegativeIndex:
|
||||
return "Bailout_NegativeIndex";
|
||||
case Bailout_ObjectIdentityOrTypeGuard:
|
||||
return "Bailout_ObjectIdentityOrTypeGuard";
|
||||
case Bailout_NonInt32Input:
|
||||
return "Bailout_NonInt32Input";
|
||||
case Bailout_NonNumericInput:
|
||||
return "Bailout_NonNumericInput";
|
||||
case Bailout_NonBooleanInput:
|
||||
return "Bailout_NonBooleanInput";
|
||||
case Bailout_NonObjectInput:
|
||||
return "Bailout_NonObjectInput";
|
||||
case Bailout_NonStringInput:
|
||||
return "Bailout_NonStringInput";
|
||||
case Bailout_GuardThreadExclusive:
|
||||
return "Bailout_GuardThreadExclusive";
|
||||
case Bailout_InitialState:
|
||||
return "Bailout_InitialState";
|
||||
|
||||
// Bailouts caused by invalid assumptions.
|
||||
case Bailout_OverflowInvalidate:
|
||||
return "Bailout_OverflowInvalidate";
|
||||
case Bailout_NonStringInputInvalidate:
|
||||
return "Bailout_NonStringInputInvalidate";
|
||||
case Bailout_DoubleOutput:
|
||||
return "Bailout_DoubleOutput";
|
||||
|
||||
// Other bailouts.
|
||||
case Bailout_ArgumentCheck:
|
||||
return "Bailout_ArgumentCheck";
|
||||
case Bailout_BoundsCheck:
|
||||
return "Bailout_BoundsCheck";
|
||||
case Bailout_Neutered:
|
||||
return "Bailout_Neutered";
|
||||
case Bailout_ShapeGuard:
|
||||
return "Bailout_ShapeGuard";
|
||||
case Bailout_BaselineInfo:
|
||||
return "Bailout_BaselineInfo";
|
||||
case Bailout_IonExceptionDebugMode:
|
||||
return "Bailout_IonExceptionDebugMode";
|
||||
default:
|
||||
|
@ -76,6 +76,7 @@ enum ReadFrameArgsBehavior {
|
||||
class IonCommonFrameLayout;
|
||||
class IonJSFrameLayout;
|
||||
class IonExitFrameLayout;
|
||||
class IonBailoutIterator;
|
||||
|
||||
class BaselineFrame;
|
||||
|
||||
@ -88,11 +89,15 @@ class JitFrameIterator
|
||||
FrameType type_;
|
||||
uint8_t *returnAddressToFp_;
|
||||
size_t frameSize_;
|
||||
ExecutionMode mode_;
|
||||
enum Kind {
|
||||
Kind_FrameIterator,
|
||||
Kind_BailoutIterator
|
||||
} kind_;
|
||||
|
||||
private:
|
||||
mutable const SafepointIndex *cachedSafepointIndex_;
|
||||
const JitActivation *activation_;
|
||||
ExecutionMode mode_;
|
||||
|
||||
void dumpBaseline() const;
|
||||
|
||||
@ -102,15 +107,22 @@ class JitFrameIterator
|
||||
type_(JitFrame_Exit),
|
||||
returnAddressToFp_(nullptr),
|
||||
frameSize_(0),
|
||||
mode_(mode),
|
||||
kind_(Kind_FrameIterator),
|
||||
cachedSafepointIndex_(nullptr),
|
||||
activation_(nullptr),
|
||||
mode_(mode)
|
||||
activation_(nullptr)
|
||||
{ }
|
||||
|
||||
explicit JitFrameIterator(ThreadSafeContext *cx);
|
||||
explicit JitFrameIterator(const ActivationIterator &activations);
|
||||
explicit JitFrameIterator(IonJSFrameLayout *fp, ExecutionMode mode);
|
||||
|
||||
bool isBailoutIterator() const {
|
||||
return kind_ == Kind_BailoutIterator;
|
||||
}
|
||||
IonBailoutIterator *asBailoutIterator();
|
||||
const IonBailoutIterator *asBailoutIterator() const;
|
||||
|
||||
// Current frame information.
|
||||
FrameType type() const {
|
||||
return type_;
|
||||
@ -247,7 +259,6 @@ class JitFrameIterator
|
||||
};
|
||||
|
||||
class IonJSFrameLayout;
|
||||
class IonBailoutIterator;
|
||||
|
||||
class RResumePoint;
|
||||
|
||||
|
@ -1570,7 +1570,7 @@ class LIRGraph
|
||||
}
|
||||
void setEntrySnapshot(LSnapshot *snapshot) {
|
||||
JS_ASSERT(!entrySnapshot_);
|
||||
JS_ASSERT(snapshot->bailoutKind() == Bailout_Normal);
|
||||
JS_ASSERT(snapshot->bailoutKind() == Bailout_InitialState);
|
||||
snapshot->setBailoutKind(Bailout_ArgumentCheck);
|
||||
entrySnapshot_ = snapshot;
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ LIRGenerator::visitApplyArgs(MApplyArgs *apply)
|
||||
return false;
|
||||
|
||||
// Bailout is only needed in the case of possible non-JSFunction callee.
|
||||
if (!apply->getSingleTarget() && !assignSnapshot(lir))
|
||||
if (!apply->getSingleTarget() && !assignSnapshot(lir, Bailout_NonJSFunctionCallee))
|
||||
return false;
|
||||
|
||||
if (!defineReturn(lir, apply))
|
||||
@ -508,7 +508,7 @@ bool
|
||||
LIRGenerator::visitBail(MBail *bail)
|
||||
{
|
||||
LBail *lir = new(alloc()) LBail();
|
||||
return assignSnapshot(lir) && add(lir, bail);
|
||||
return assignSnapshot(lir, bail->bailoutKind()) && add(lir, bail);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -551,7 +551,7 @@ LIRGenerator::visitGetDynamicName(MGetDynamicName *ins)
|
||||
tempFixed(CallTempReg3),
|
||||
tempFixed(CallTempReg4));
|
||||
|
||||
return assignSnapshot(lir) && defineReturn(lir, ins);
|
||||
return assignSnapshot(lir, Bailout_DynamicNameNotFound) && defineReturn(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -576,7 +576,9 @@ LIRGenerator::visitFilterArgumentsOrEval(MFilterArgumentsOrEval *ins)
|
||||
}
|
||||
}
|
||||
|
||||
return assignSnapshot(lir) && add(lir, ins) && assignSafepoint(lir, ins);
|
||||
return assignSnapshot(lir, Bailout_StringArgumentsEval)
|
||||
&& add(lir, ins)
|
||||
&& assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1126,7 +1128,7 @@ LIRGenerator::lowerShiftOp(JSOp op, MShiftInstruction *ins)
|
||||
|
||||
LShiftI *lir = new(alloc()) LShiftI(op);
|
||||
if (op == JSOP_URSH) {
|
||||
if (ins->toUrsh()->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (ins->toUrsh()->fallible() && !assignSnapshot(lir, Bailout_OverflowInvalidate))
|
||||
return false;
|
||||
}
|
||||
return lowerForShift(lir, ins, lhs, rhs);
|
||||
@ -1173,13 +1175,13 @@ LIRGenerator::visitFloor(MFloor *ins)
|
||||
|
||||
if (type == MIRType_Double) {
|
||||
LFloor *lir = new(alloc()) LFloor(useRegister(ins->num()));
|
||||
if (!assignSnapshot(lir))
|
||||
if (!assignSnapshot(lir, Bailout_Round))
|
||||
return false;
|
||||
return define(lir, ins);
|
||||
}
|
||||
|
||||
LFloorF *lir = new(alloc()) LFloorF(useRegister(ins->num()));
|
||||
if (!assignSnapshot(lir))
|
||||
if (!assignSnapshot(lir, Bailout_Round))
|
||||
return false;
|
||||
return define(lir, ins);
|
||||
}
|
||||
@ -1192,13 +1194,13 @@ LIRGenerator::visitCeil(MCeil *ins)
|
||||
|
||||
if (type == MIRType_Double) {
|
||||
LCeil *lir = new(alloc()) LCeil(useRegister(ins->num()));
|
||||
if (!assignSnapshot(lir))
|
||||
if (!assignSnapshot(lir, Bailout_Round))
|
||||
return false;
|
||||
return define(lir, ins);
|
||||
}
|
||||
|
||||
LCeilF *lir = new(alloc()) LCeilF(useRegister(ins->num()));
|
||||
if (!assignSnapshot(lir))
|
||||
if (!assignSnapshot(lir, Bailout_Round))
|
||||
return false;
|
||||
return define(lir, ins);
|
||||
}
|
||||
@ -1211,13 +1213,13 @@ LIRGenerator::visitRound(MRound *ins)
|
||||
|
||||
if (type == MIRType_Double) {
|
||||
LRound *lir = new (alloc()) LRound(useRegister(ins->num()), tempDouble());
|
||||
if (!assignSnapshot(lir))
|
||||
if (!assignSnapshot(lir, Bailout_Round))
|
||||
return false;
|
||||
return define(lir, ins);
|
||||
}
|
||||
|
||||
LRoundF *lir = new (alloc()) LRoundF(useRegister(ins->num()), tempDouble());
|
||||
if (!assignSnapshot(lir))
|
||||
if (!assignSnapshot(lir, Bailout_Round))
|
||||
return false;
|
||||
return define(lir, ins);
|
||||
}
|
||||
@ -1248,7 +1250,7 @@ LIRGenerator::visitAbs(MAbs *ins)
|
||||
if (num->type() == MIRType_Int32) {
|
||||
LAbsI *lir = new(alloc()) LAbsI(useRegisterAtStart(num));
|
||||
// needed to handle abs(INT32_MIN)
|
||||
if (ins->fallible() && !assignSnapshot(lir))
|
||||
if (ins->fallible() && !assignSnapshot(lir, Bailout_Overflow))
|
||||
return false;
|
||||
return defineReuseInput(lir, ins, 0);
|
||||
}
|
||||
@ -1393,7 +1395,7 @@ LIRGenerator::visitAdd(MAdd *ins)
|
||||
ReorderCommutative(&lhs, &rhs);
|
||||
LAddI *lir = new(alloc()) LAddI;
|
||||
|
||||
if (ins->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (ins->fallible() && !assignSnapshot(lir, Bailout_OverflowInvalidate))
|
||||
return false;
|
||||
|
||||
if (!lowerForALU(lir, ins, lhs, rhs))
|
||||
@ -1430,7 +1432,7 @@ LIRGenerator::visitSub(MSub *ins)
|
||||
JS_ASSERT(lhs->type() == MIRType_Int32);
|
||||
|
||||
LSubI *lir = new(alloc()) LSubI;
|
||||
if (ins->fallible() && !assignSnapshot(lir))
|
||||
if (ins->fallible() && !assignSnapshot(lir, Bailout_Overflow))
|
||||
return false;
|
||||
|
||||
if (!lowerForALU(lir, ins, lhs, rhs))
|
||||
@ -1638,7 +1640,7 @@ LIRGenerator::visitStart(MStart *start)
|
||||
{
|
||||
// Create a snapshot that captures the initial state of the function.
|
||||
LStart *lir = new(alloc()) LStart;
|
||||
if (!assignSnapshot(lir))
|
||||
if (!assignSnapshot(lir, Bailout_InitialState))
|
||||
return false;
|
||||
|
||||
if (start->startType() == MStart::StartType_Default)
|
||||
@ -1705,7 +1707,7 @@ LIRGenerator::visitToDouble(MToDouble *convert)
|
||||
LValueToDouble *lir = new(alloc()) LValueToDouble();
|
||||
if (!useBox(lir, LValueToDouble::Input, opd))
|
||||
return false;
|
||||
return assignSnapshot(lir) && define(lir, convert);
|
||||
return assignSnapshot(lir, Bailout_NonPrimitiveInput) && define(lir, convert);
|
||||
}
|
||||
|
||||
case MIRType_Null:
|
||||
@ -1754,7 +1756,7 @@ LIRGenerator::visitToFloat32(MToFloat32 *convert)
|
||||
LValueToFloat32 *lir = new(alloc()) LValueToFloat32();
|
||||
if (!useBox(lir, LValueToFloat32::Input, opd))
|
||||
return false;
|
||||
return assignSnapshot(lir) && define(lir, convert);
|
||||
return assignSnapshot(lir, Bailout_NonPrimitiveInput) && define(lir, convert);
|
||||
}
|
||||
|
||||
case MIRType_Null:
|
||||
@ -1800,10 +1802,13 @@ LIRGenerator::visitToInt32(MToInt32 *convert)
|
||||
switch (opd->type()) {
|
||||
case MIRType_Value:
|
||||
{
|
||||
LValueToInt32 *lir = new(alloc()) LValueToInt32(tempDouble(), temp(), LValueToInt32::NORMAL);
|
||||
LValueToInt32 *lir =
|
||||
new(alloc()) LValueToInt32(tempDouble(), temp(), LValueToInt32::NORMAL);
|
||||
if (!useBox(lir, LValueToInt32::Input, opd))
|
||||
return false;
|
||||
return assignSnapshot(lir) && define(lir, convert) && assignSafepoint(lir, convert);
|
||||
return assignSnapshot(lir, Bailout_NonPrimitiveInput)
|
||||
&& define(lir, convert)
|
||||
&& assignSafepoint(lir, convert);
|
||||
}
|
||||
|
||||
case MIRType_Null:
|
||||
@ -1816,13 +1821,13 @@ LIRGenerator::visitToInt32(MToInt32 *convert)
|
||||
case MIRType_Float32:
|
||||
{
|
||||
LFloat32ToInt32 *lir = new(alloc()) LFloat32ToInt32(useRegister(opd));
|
||||
return assignSnapshot(lir) && define(lir, convert);
|
||||
return assignSnapshot(lir, Bailout_PrecisionLoss) && define(lir, convert);
|
||||
}
|
||||
|
||||
case MIRType_Double:
|
||||
{
|
||||
LDoubleToInt32 *lir = new(alloc()) LDoubleToInt32(useRegister(opd));
|
||||
return assignSnapshot(lir) && define(lir, convert);
|
||||
return assignSnapshot(lir, Bailout_PrecisionLoss) && define(lir, convert);
|
||||
}
|
||||
|
||||
case MIRType_String:
|
||||
@ -1845,10 +1850,13 @@ LIRGenerator::visitTruncateToInt32(MTruncateToInt32 *truncate)
|
||||
switch (opd->type()) {
|
||||
case MIRType_Value:
|
||||
{
|
||||
LValueToInt32 *lir = new(alloc()) LValueToInt32(tempDouble(), temp(), LValueToInt32::TRUNCATE);
|
||||
LValueToInt32 *lir = new(alloc()) LValueToInt32(tempDouble(), temp(),
|
||||
LValueToInt32::TRUNCATE);
|
||||
if (!useBox(lir, LValueToInt32::Input, opd))
|
||||
return false;
|
||||
return assignSnapshot(lir) && define(lir, truncate) && assignSafepoint(lir, truncate);
|
||||
return assignSnapshot(lir, Bailout_NonPrimitiveInput)
|
||||
&& define(lir, truncate)
|
||||
&& assignSafepoint(lir, truncate);
|
||||
}
|
||||
|
||||
case MIRType_Null:
|
||||
@ -1918,7 +1926,7 @@ LIRGenerator::visitToString(MToString *ins)
|
||||
LValueToString *lir = new(alloc()) LValueToString(tempToUnbox());
|
||||
if (!useBox(lir, LValueToString::Input, opd))
|
||||
return false;
|
||||
if (ins->fallible() && !assignSnapshot(lir))
|
||||
if (ins->fallible() && !assignSnapshot(lir, Bailout_NonPrimitiveInput))
|
||||
return false;
|
||||
if (!define(lir, ins))
|
||||
return false;
|
||||
@ -2272,7 +2280,7 @@ LIRGenerator::visitTypeBarrier(MTypeBarrier *ins)
|
||||
// (Emit LBail for visibility).
|
||||
if (ins->alwaysBails()) {
|
||||
LBail *bail = new(alloc()) LBail();
|
||||
if (!assignSnapshot(bail))
|
||||
if (!assignSnapshot(bail, Bailout_Inevitable))
|
||||
return false;
|
||||
return redefine(ins, ins->input()) && add(bail, ins);
|
||||
}
|
||||
@ -2283,7 +2291,7 @@ LIRGenerator::visitTypeBarrier(MTypeBarrier *ins)
|
||||
LTypeBarrierV *barrier = new(alloc()) LTypeBarrierV(tmp);
|
||||
if (!useBox(barrier, LTypeBarrierV::Input, ins->input()))
|
||||
return false;
|
||||
if (!assignSnapshot(barrier))
|
||||
if (!assignSnapshot(barrier, Bailout_TypeBarrierV))
|
||||
return false;
|
||||
return redefine(ins, ins->input()) && add(barrier, ins);
|
||||
}
|
||||
@ -2294,7 +2302,7 @@ LIRGenerator::visitTypeBarrier(MTypeBarrier *ins)
|
||||
{
|
||||
LDefinition tmp = needTemp ? temp() : LDefinition::BogusTemp();
|
||||
LTypeBarrierO *barrier = new(alloc()) LTypeBarrierO(useRegister(ins->getOperand(0)), tmp);
|
||||
if (!assignSnapshot(barrier))
|
||||
if (!assignSnapshot(barrier, Bailout_TypeBarrierO))
|
||||
return false;
|
||||
return redefine(ins, ins->getOperand(0)) && add(barrier, ins);
|
||||
}
|
||||
@ -2316,7 +2324,7 @@ LIRGenerator::visitMonitorTypes(MMonitorTypes *ins)
|
||||
LMonitorTypes *lir = new(alloc()) LMonitorTypes(tmp);
|
||||
if (!useBox(lir, LMonitorTypes::Input, ins->input()))
|
||||
return false;
|
||||
return assignSnapshot(lir, Bailout_Normal) && add(lir, ins);
|
||||
return assignSnapshot(lir, Bailout_MonitorTypes) && add(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2488,7 +2496,7 @@ LIRGenerator::visitNeuterCheck(MNeuterCheck *ins)
|
||||
{
|
||||
LNeuterCheck *chk = new(alloc()) LNeuterCheck(useRegister(ins->object()),
|
||||
temp());
|
||||
if (!assignSnapshot(chk, Bailout_BoundsCheck))
|
||||
if (!assignSnapshot(chk, Bailout_Neutered))
|
||||
return false;
|
||||
return redefine(ins, ins->input()) && add(chk, ins);
|
||||
}
|
||||
@ -2551,7 +2559,7 @@ LIRGenerator::visitLoadElement(MLoadElement *ins)
|
||||
{
|
||||
LLoadElementV *lir = new(alloc()) LLoadElementV(useRegister(ins->elements()),
|
||||
useRegisterOrConstant(ins->index()));
|
||||
if (ins->fallible() && !assignSnapshot(lir))
|
||||
if (ins->fallible() && !assignSnapshot(lir, Bailout_Hole))
|
||||
return false;
|
||||
return defineBox(lir, ins);
|
||||
}
|
||||
@ -2563,7 +2571,7 @@ LIRGenerator::visitLoadElement(MLoadElement *ins)
|
||||
{
|
||||
LLoadElementT *lir = new(alloc()) LLoadElementT(useRegister(ins->elements()),
|
||||
useRegisterOrConstant(ins->index()));
|
||||
if (ins->fallible() && !assignSnapshot(lir))
|
||||
if (ins->fallible() && !assignSnapshot(lir, Bailout_Hole))
|
||||
return false;
|
||||
return define(lir, ins);
|
||||
}
|
||||
@ -2581,7 +2589,7 @@ LIRGenerator::visitLoadElementHole(MLoadElementHole *ins)
|
||||
LLoadElementHole *lir = new(alloc()) LLoadElementHole(useRegister(ins->elements()),
|
||||
useRegisterOrConstant(ins->index()),
|
||||
useRegister(ins->initLength()));
|
||||
if (ins->needsNegativeIntCheck() && !assignSnapshot(lir))
|
||||
if (ins->needsNegativeIntCheck() && !assignSnapshot(lir, Bailout_NegativeIndex))
|
||||
return false;
|
||||
return defineBox(lir, ins);
|
||||
}
|
||||
@ -2599,7 +2607,7 @@ LIRGenerator::visitStoreElement(MStoreElement *ins)
|
||||
case MIRType_Value:
|
||||
{
|
||||
LInstruction *lir = new(alloc()) LStoreElementV(elements, index);
|
||||
if (ins->fallible() && !assignSnapshot(lir))
|
||||
if (ins->fallible() && !assignSnapshot(lir, Bailout_Hole))
|
||||
return false;
|
||||
if (!useBox(lir, LStoreElementV::Value, ins->value()))
|
||||
return false;
|
||||
@ -2610,7 +2618,7 @@ LIRGenerator::visitStoreElement(MStoreElement *ins)
|
||||
{
|
||||
const LAllocation value = useRegisterOrNonDoubleConstant(ins->value());
|
||||
LInstruction *lir = new(alloc()) LStoreElementT(elements, index, value);
|
||||
if (ins->fallible() && !assignSnapshot(lir))
|
||||
if (ins->fallible() && !assignSnapshot(lir, Bailout_Hole))
|
||||
return false;
|
||||
return add(lir, ins);
|
||||
}
|
||||
@ -2743,7 +2751,7 @@ LIRGenerator::visitLoadTypedArrayElement(MLoadTypedArrayElement *ins)
|
||||
tempDef = temp();
|
||||
|
||||
LLoadTypedArrayElement *lir = new(alloc()) LLoadTypedArrayElement(elements, index, tempDef);
|
||||
if (ins->fallible() && !assignSnapshot(lir))
|
||||
if (ins->fallible() && !assignSnapshot(lir, Bailout_Overflow))
|
||||
return false;
|
||||
return define(lir, ins);
|
||||
}
|
||||
@ -2768,7 +2776,9 @@ LIRGenerator::visitClampToUint8(MClampToUint8 *ins)
|
||||
LClampVToUint8 *lir = new(alloc()) LClampVToUint8(tempDouble());
|
||||
if (!useBox(lir, LClampVToUint8::Input, in))
|
||||
return false;
|
||||
return assignSnapshot(lir) && define(lir, ins) && assignSafepoint(lir, ins);
|
||||
return assignSnapshot(lir, Bailout_NonPrimitiveInput)
|
||||
&& define(lir, ins)
|
||||
&& assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
default:
|
||||
@ -2788,7 +2798,7 @@ LIRGenerator::visitLoadTypedArrayElementHole(MLoadTypedArrayElementHole *ins)
|
||||
const LAllocation index = useRegisterOrConstant(ins->index());
|
||||
|
||||
LLoadTypedArrayElementHole *lir = new(alloc()) LLoadTypedArrayElementHole(object, index);
|
||||
if (ins->fallible() && !assignSnapshot(lir))
|
||||
if (ins->fallible() && !assignSnapshot(lir, Bailout_Overflow))
|
||||
return false;
|
||||
return defineBox(lir, ins) && assignSafepoint(lir, ins);
|
||||
}
|
||||
@ -2799,7 +2809,8 @@ LIRGenerator::visitLoadTypedArrayElementStatic(MLoadTypedArrayElementStatic *ins
|
||||
LLoadTypedArrayElementStatic *lir =
|
||||
new(alloc()) LLoadTypedArrayElementStatic(useRegisterAtStart(ins->ptr()));
|
||||
|
||||
if (ins->fallible() && !assignSnapshot(lir))
|
||||
// In case of out of bounds, may bail out, or may jump to ool code.
|
||||
if (ins->fallible() && !assignSnapshot(lir, Bailout_BoundsCheck))
|
||||
return false;
|
||||
return define(lir, ins);
|
||||
}
|
||||
@ -3010,7 +3021,9 @@ bool
|
||||
LIRGenerator::visitGuardObjectIdentity(MGuardObjectIdentity *ins)
|
||||
{
|
||||
LGuardObjectIdentity *guard = new(alloc()) LGuardObjectIdentity(useRegister(ins->obj()));
|
||||
return assignSnapshot(guard) && add(guard, ins) && redefine(ins, ins->obj());
|
||||
return assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard)
|
||||
&& add(guard, ins)
|
||||
&& redefine(ins, ins->obj());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -3018,7 +3031,7 @@ LIRGenerator::visitGuardClass(MGuardClass *ins)
|
||||
{
|
||||
LDefinition t = temp();
|
||||
LGuardClass *guard = new(alloc()) LGuardClass(useRegister(ins->obj()), t);
|
||||
return assignSnapshot(guard) && add(guard, ins);
|
||||
return assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard) && add(guard, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -2279,22 +2279,34 @@ class MApplyArgs
|
||||
class MBail : public MNullaryInstruction
|
||||
{
|
||||
protected:
|
||||
MBail()
|
||||
MBail(BailoutKind kind)
|
||||
{
|
||||
bailoutKind_ = kind;
|
||||
setGuard();
|
||||
}
|
||||
|
||||
private:
|
||||
BailoutKind bailoutKind_;
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(Bail)
|
||||
|
||||
static MBail *
|
||||
New(TempAllocator &alloc, BailoutKind kind) {
|
||||
return new(alloc) MBail(kind);
|
||||
}
|
||||
static MBail *
|
||||
New(TempAllocator &alloc) {
|
||||
return new(alloc) MBail();
|
||||
return new(alloc) MBail(Bailout_Inevitable);
|
||||
}
|
||||
|
||||
AliasSet getAliasSet() const {
|
||||
return AliasSet::None();
|
||||
}
|
||||
|
||||
BailoutKind bailoutKind() const {
|
||||
return bailoutKind_;
|
||||
}
|
||||
};
|
||||
|
||||
class MAssertFloat32 : public MUnaryInstruction
|
||||
@ -2693,7 +2705,30 @@ class MUnbox : public MUnaryInstruction, public BoxInputsPolicy
|
||||
INSTRUCTION_HEADER(Unbox)
|
||||
static MUnbox *New(TempAllocator &alloc, MDefinition *ins, MIRType type, Mode mode)
|
||||
{
|
||||
return new(alloc) MUnbox(ins, type, mode, Bailout_Normal);
|
||||
// Unless we were given a specific BailoutKind, pick a default based on
|
||||
// the type we expect.
|
||||
BailoutKind kind;
|
||||
switch(type){
|
||||
case MIRType_Boolean:
|
||||
kind = Bailout_NonBooleanInput;
|
||||
break;
|
||||
case MIRType_Int32:
|
||||
kind = Bailout_NonInt32Input;
|
||||
break;
|
||||
case MIRType_Double:
|
||||
kind = Bailout_NonNumericInput; // Int32s are fine too
|
||||
break;
|
||||
case MIRType_String:
|
||||
kind = Bailout_NonStringInput;
|
||||
break;
|
||||
case MIRType_Object:
|
||||
kind = Bailout_NonObjectInput;
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSUME_UNREACHABLE("Given MIRType cannot be unboxed.");
|
||||
}
|
||||
|
||||
return new(alloc) MUnbox(ins, type, mode, kind);
|
||||
}
|
||||
|
||||
static MUnbox *New(TempAllocator &alloc, MDefinition *ins, MIRType type, Mode mode,
|
||||
@ -3617,6 +3652,11 @@ class MBitAnd : public MBinaryBitwiseInstruction
|
||||
return getOperand(0); // x & x => x;
|
||||
}
|
||||
void computeRange(TempAllocator &alloc);
|
||||
|
||||
bool writeRecoverData(CompactBufferWriter &writer) const;
|
||||
bool canRecoverOnBailout() const {
|
||||
return specialization_ != MIRType_None;
|
||||
}
|
||||
};
|
||||
|
||||
class MBitOr : public MBinaryBitwiseInstruction
|
||||
@ -9439,7 +9479,7 @@ class MGuardThreadExclusive
|
||||
return getOperand(1);
|
||||
}
|
||||
BailoutKind bailoutKind() const {
|
||||
return Bailout_Normal;
|
||||
return Bailout_GuardThreadExclusive;
|
||||
}
|
||||
bool congruentTo(const MDefinition *ins) const {
|
||||
return congruentIfOperandsEqual(ins);
|
||||
|
@ -163,6 +163,33 @@ RBitNot::recover(JSContext *cx, SnapshotIterator &iter) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MBitAnd::writeRecoverData(CompactBufferWriter &writer) const
|
||||
{
|
||||
MOZ_ASSERT(canRecoverOnBailout());
|
||||
writer.writeUnsigned(uint32_t(RInstruction::Recover_BitAnd));
|
||||
return true;
|
||||
}
|
||||
|
||||
RBitAnd::RBitAnd(CompactBufferReader &reader)
|
||||
{ }
|
||||
|
||||
bool
|
||||
RBitAnd::recover(JSContext *cx, SnapshotIterator &iter) const
|
||||
{
|
||||
RootedValue lhs(cx, iter.read());
|
||||
RootedValue rhs(cx, iter.read());
|
||||
int32_t result;
|
||||
MOZ_ASSERT(!lhs.isObject() && !rhs.isObject());
|
||||
|
||||
if (!js::BitAnd(cx, lhs, rhs, &result))
|
||||
return false;
|
||||
|
||||
RootedValue rootedResult(cx, js::Int32Value(result));
|
||||
iter.storeInstructionResult(rootedResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MBitOr::writeRecoverData(CompactBufferWriter &writer) const
|
||||
{
|
||||
|
@ -19,6 +19,7 @@ namespace jit {
|
||||
#define RECOVER_OPCODE_LIST(_) \
|
||||
_(ResumePoint) \
|
||||
_(BitNot) \
|
||||
_(BitAnd) \
|
||||
_(BitOr) \
|
||||
_(BitXor) \
|
||||
_(Lsh) \
|
||||
@ -111,6 +112,18 @@ class RBitNot MOZ_FINAL : public RInstruction
|
||||
bool recover(JSContext *cx, SnapshotIterator &iter) const;
|
||||
};
|
||||
|
||||
class RBitAnd MOZ_FINAL : public RInstruction
|
||||
{
|
||||
public:
|
||||
RINSTRUCTION_HEADER_(BitAnd)
|
||||
|
||||
virtual uint32_t numOperands() const {
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool recover(JSContext *cx, SnapshotIterator &iter) const;
|
||||
};
|
||||
|
||||
class RBitOr MOZ_FINAL : public RInstruction
|
||||
{
|
||||
public:
|
||||
|
@ -482,7 +482,7 @@ SnapshotReader::SnapshotReader(const uint8_t *snapshots, uint32_t offset,
|
||||
|
||||
// Details of snapshot header packing.
|
||||
static const uint32_t SNAPSHOT_BAILOUTKIND_SHIFT = 0;
|
||||
static const uint32_t SNAPSHOT_BAILOUTKIND_BITS = 3;
|
||||
static const uint32_t SNAPSHOT_BAILOUTKIND_BITS = 5;
|
||||
static const uint32_t SNAPSHOT_BAILOUTKIND_MASK = COMPUTE_MASK_(SNAPSHOT_BAILOUTKIND);
|
||||
|
||||
static const uint32_t SNAPSHOT_ROFFSET_SHIFT = COMPUTE_SHIFT_AFTER_(SNAPSHOT_BAILOUTKIND);
|
||||
|
@ -1861,7 +1861,7 @@ Assembler::as_b(Label *l, Condition c, bool isPatchable)
|
||||
// This will currently throw an assertion if we couldn't actually
|
||||
// encode the offset of the branch.
|
||||
if (!BOffImm::isInRange(old)) {
|
||||
m_buffer.bail();
|
||||
m_buffer.fail_bail();
|
||||
return ret;
|
||||
}
|
||||
ret = as_b(BOffImm(old), c, isPatchable);
|
||||
@ -1923,7 +1923,7 @@ Assembler::as_bl(Label *l, Condition c)
|
||||
// encode the offset of the branch.
|
||||
old = l->offset();
|
||||
if (!BOffImm::isInRange(old)) {
|
||||
m_buffer.bail();
|
||||
m_buffer.fail_bail();
|
||||
return ret;
|
||||
}
|
||||
ret = as_bl(BOffImm(old), c);
|
||||
|
@ -984,7 +984,8 @@ class BOffImm
|
||||
: data ((offset - 8) >> 2 & 0x00ffffff)
|
||||
{
|
||||
JS_ASSERT((offset & 0x3) == 0);
|
||||
JS_ASSERT(isInRange(offset));
|
||||
if (!isInRange(offset))
|
||||
CrashAtUnhandlableOOM("BOffImm");
|
||||
}
|
||||
static bool isInRange(int offset)
|
||||
{
|
||||
|
@ -76,10 +76,15 @@ IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
|
||||
uint8_t *sp = bailout->parentStackPointer();
|
||||
uint8_t *fp = sp + bailout->frameSize();
|
||||
|
||||
kind_ = Kind_BailoutIterator;
|
||||
current_ = fp;
|
||||
type_ = JitFrame_IonJS;
|
||||
topFrameSize_ = current_ - sp;
|
||||
topIonScript_ = script()->ionScript();
|
||||
switch (mode_) {
|
||||
case SequentialExecution: topIonScript_ = script()->ionScript(); break;
|
||||
case ParallelExecution: topIonScript_ = script()->parallelIonScript(); break;
|
||||
default: MOZ_ASSUME_UNREACHABLE("No such execution mode");
|
||||
}
|
||||
|
||||
if (bailout->frameClass() == FrameSizeClass::None()) {
|
||||
snapshotOffset_ = bailout->snapshotOffset();
|
||||
@ -108,6 +113,7 @@ IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
|
||||
: JitFrameIterator(activations),
|
||||
machine_(bailout->machine())
|
||||
{
|
||||
kind_ = Kind_BailoutIterator;
|
||||
returnAddressToFp_ = bailout->osiPointReturnAddress();
|
||||
topIonScript_ = bailout->ionScript();
|
||||
const OsiIndex *osiIndex = topIonScript_->getOsiIndex(returnAddressToFp_);
|
||||
|
@ -431,8 +431,6 @@ class LUMod : public LBinaryMath<0>
|
||||
}
|
||||
};
|
||||
|
||||
// This class performs a simple x86 'div', yielding either a quotient or remainder depending on
|
||||
// whether this instruction is defined to output eax (quotient) or edx (remainder).
|
||||
class LSoftUDivOrMod : public LBinaryMath<3>
|
||||
{
|
||||
public:
|
||||
|
@ -277,7 +277,7 @@ LIRGeneratorARM::lowerDivI(MDiv *div)
|
||||
int32_t shift = FloorLog2(rhs);
|
||||
if (rhs > 0 && 1 << shift == rhs) {
|
||||
LDivPowTwoI *lir = new(alloc()) LDivPowTwoI(useRegisterAtStart(div->lhs()), shift);
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, div);
|
||||
}
|
||||
@ -285,14 +285,14 @@ LIRGeneratorARM::lowerDivI(MDiv *div)
|
||||
|
||||
if (hasIDIV()) {
|
||||
LDivI *lir = new(alloc()) LDivI(useRegister(div->lhs()), useRegister(div->rhs()), temp());
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, div);
|
||||
}
|
||||
|
||||
LSoftDivI *lir = new(alloc()) LSoftDivI(useFixedAtStart(div->lhs(), r0), useFixedAtStart(div->rhs(), r1),
|
||||
tempFixed(r1), tempFixed(r2), tempFixed(r3));
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineFixed(lir, div, LAllocation(AnyRegister(r0)));
|
||||
}
|
||||
@ -301,7 +301,7 @@ bool
|
||||
LIRGeneratorARM::lowerMulI(MMul *mul, MDefinition *lhs, MDefinition *rhs)
|
||||
{
|
||||
LMulI *lir = new(alloc()) LMulI;
|
||||
if (mul->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mul->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return lowerForALU(lir, mul, lhs, rhs);
|
||||
}
|
||||
@ -317,12 +317,12 @@ LIRGeneratorARM::lowerModI(MMod *mod)
|
||||
int32_t shift = FloorLog2(rhs);
|
||||
if (rhs > 0 && 1 << shift == rhs) {
|
||||
LModPowTwoI *lir = new(alloc()) LModPowTwoI(useRegister(mod->lhs()), shift);
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, mod);
|
||||
} else if (shift < 31 && (1 << (shift+1)) - 1 == rhs) {
|
||||
LModMaskI *lir = new(alloc()) LModMaskI(useRegister(mod->lhs()), temp(LDefinition::GENERAL), shift+1);
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, mod);
|
||||
}
|
||||
@ -330,7 +330,7 @@ LIRGeneratorARM::lowerModI(MMod *mod)
|
||||
|
||||
if (hasIDIV()) {
|
||||
LModI *lir = new(alloc()) LModI(useRegister(mod->lhs()), useRegister(mod->rhs()), temp());
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, mod);
|
||||
}
|
||||
@ -338,7 +338,7 @@ LIRGeneratorARM::lowerModI(MMod *mod)
|
||||
LSoftModI *lir = new(alloc()) LSoftModI(useFixedAtStart(mod->lhs(), r0), useFixedAtStart(mod->rhs(), r1),
|
||||
tempFixed(r0), tempFixed(r2), tempFixed(r3),
|
||||
temp(LDefinition::GENERAL));
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineFixed(lir, mod, LAllocation(AnyRegister(r1)));
|
||||
}
|
||||
@ -386,7 +386,7 @@ LIRGeneratorARM::visitGuardObjectType(MGuardObjectType *ins)
|
||||
|
||||
LDefinition tempObj = temp(LDefinition::OBJECT);
|
||||
LGuardObjectType *guard = new(alloc()) LGuardObjectType(useRegister(ins->obj()), tempObj);
|
||||
if (!assignSnapshot(guard))
|
||||
if (!assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard))
|
||||
return false;
|
||||
if (!add(guard, ins))
|
||||
return false;
|
||||
@ -429,13 +429,13 @@ LIRGeneratorARM::lowerUDiv(MDiv *div)
|
||||
LUDiv *lir = new(alloc()) LUDiv;
|
||||
lir->setOperand(0, useRegister(lhs));
|
||||
lir->setOperand(1, useRegister(rhs));
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, div);
|
||||
} else {
|
||||
LSoftUDivOrMod *lir = new(alloc()) LSoftUDivOrMod(useFixedAtStart(lhs, r0), useFixedAtStart(rhs, r1),
|
||||
tempFixed(r1), tempFixed(r2), tempFixed(r3));
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineFixed(lir, div, LAllocation(AnyRegister(r0)));
|
||||
}
|
||||
@ -451,13 +451,13 @@ LIRGeneratorARM::lowerUMod(MMod *mod)
|
||||
LUMod *lir = new(alloc()) LUMod;
|
||||
lir->setOperand(0, useRegister(lhs));
|
||||
lir->setOperand(1, useRegister(rhs));
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, mod);
|
||||
} else {
|
||||
LSoftUDivOrMod *lir = new(alloc()) LSoftUDivOrMod(useFixedAtStart(lhs, r0), useFixedAtStart(rhs, r1),
|
||||
tempFixed(r0), tempFixed(r2), tempFixed(r3));
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineFixed(lir, mod, LAllocation(AnyRegister(r1)));
|
||||
}
|
||||
|
@ -20,10 +20,15 @@ IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
|
||||
uint8_t *sp = bailout->parentStackPointer();
|
||||
uint8_t *fp = sp + bailout->frameSize();
|
||||
|
||||
kind_ = Kind_BailoutIterator;
|
||||
current_ = fp;
|
||||
type_ = JitFrame_IonJS;
|
||||
topFrameSize_ = current_ - sp;
|
||||
topIonScript_ = script()->ionScript();
|
||||
switch (mode_) {
|
||||
case SequentialExecution: topIonScript_ = script()->ionScript(); break;
|
||||
case ParallelExecution: topIonScript_ = script()->parallelIonScript(); break;
|
||||
default: MOZ_ASSUME_UNREACHABLE("No such execution mode");
|
||||
}
|
||||
|
||||
if (bailout->frameClass() == FrameSizeClass::None()) {
|
||||
snapshotOffset_ = bailout->snapshotOffset();
|
||||
@ -52,6 +57,7 @@ IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
|
||||
: JitFrameIterator(activations),
|
||||
machine_(bailout->machine())
|
||||
{
|
||||
kind_ = Kind_BailoutIterator;
|
||||
returnAddressToFp_ = bailout->osiPointReturnAddress();
|
||||
topIonScript_ = bailout->ionScript();
|
||||
const OsiIndex *osiIndex = topIonScript_->getOsiIndex(returnAddressToFp_);
|
||||
|
@ -284,14 +284,14 @@ LIRGeneratorMIPS::lowerDivI(MDiv *div)
|
||||
int32_t shift = FloorLog2(rhs);
|
||||
if (rhs > 0 && 1 << shift == rhs) {
|
||||
LDivPowTwoI *lir = new(alloc()) LDivPowTwoI(useRegister(div->lhs()), shift, temp());
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, div);
|
||||
}
|
||||
}
|
||||
|
||||
LDivI *lir = new(alloc()) LDivI(useRegister(div->lhs()), useRegister(div->rhs()), temp());
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, div);
|
||||
}
|
||||
@ -300,7 +300,7 @@ bool
|
||||
LIRGeneratorMIPS::lowerMulI(MMul *mul, MDefinition *lhs, MDefinition *rhs)
|
||||
{
|
||||
LMulI *lir = new(alloc()) LMulI;
|
||||
if (mul->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mul->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
|
||||
return lowerForALU(lir, mul, lhs, rhs);
|
||||
@ -317,13 +317,13 @@ LIRGeneratorMIPS::lowerModI(MMod *mod)
|
||||
int32_t shift = FloorLog2(rhs);
|
||||
if (rhs > 0 && 1 << shift == rhs) {
|
||||
LModPowTwoI *lir = new(alloc()) LModPowTwoI(useRegister(mod->lhs()), shift);
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, mod);
|
||||
} else if (shift < 31 && (1 << (shift + 1)) - 1 == rhs) {
|
||||
LModMaskI *lir = new(alloc()) LModMaskI(useRegister(mod->lhs()),
|
||||
temp(LDefinition::GENERAL), shift + 1);
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, mod);
|
||||
}
|
||||
@ -331,7 +331,7 @@ LIRGeneratorMIPS::lowerModI(MMod *mod)
|
||||
LModI *lir = new(alloc()) LModI(useRegister(mod->lhs()), useRegister(mod->rhs()),
|
||||
temp(LDefinition::GENERAL));
|
||||
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, mod);
|
||||
}
|
||||
@ -379,7 +379,7 @@ LIRGeneratorMIPS::visitGuardObjectType(MGuardObjectType *ins)
|
||||
|
||||
LDefinition tempObj = temp(LDefinition::OBJECT);
|
||||
LGuardObjectType *guard = new(alloc()) LGuardObjectType(useRegister(ins->obj()), tempObj);
|
||||
if (!assignSnapshot(guard))
|
||||
if (!assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard))
|
||||
return false;
|
||||
if (!add(guard, ins))
|
||||
return false;
|
||||
@ -421,7 +421,7 @@ LIRGeneratorMIPS::lowerUDiv(MDiv *div)
|
||||
LUDiv *lir = new(alloc()) LUDiv;
|
||||
lir->setOperand(0, useRegister(lhs));
|
||||
lir->setOperand(1, useRegister(rhs));
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
|
||||
return define(lir, div);
|
||||
@ -436,7 +436,7 @@ LIRGeneratorMIPS::lowerUMod(MMod *mod)
|
||||
LUMod *lir = new(alloc()) LUMod;
|
||||
lir->setOperand(0, useRegister(lhs));
|
||||
lir->setOperand(1, useRegister(rhs));
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
|
||||
return define(lir, mod);
|
||||
|
@ -214,7 +214,7 @@ LIRGeneratorShared::assignSnapshot(LInstruction *ins, BailoutKind kind)
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGeneratorShared::assignSafepoint(LInstruction *ins, MInstruction *mir)
|
||||
LIRGeneratorShared::assignSafepoint(LInstruction *ins, MInstruction *mir, BailoutKind kind)
|
||||
{
|
||||
JS_ASSERT(!osiPoint_);
|
||||
JS_ASSERT(!ins->safepoint());
|
||||
@ -222,7 +222,7 @@ LIRGeneratorShared::assignSafepoint(LInstruction *ins, MInstruction *mir)
|
||||
ins->initSafepoint(alloc());
|
||||
|
||||
MResumePoint *mrp = mir->resumePoint() ? mir->resumePoint() : lastResumePoint_;
|
||||
LSnapshot *postSnapshot = buildSnapshot(ins, mrp, Bailout_Normal);
|
||||
LSnapshot *postSnapshot = buildSnapshot(ins, mrp, kind);
|
||||
if (!postSnapshot)
|
||||
return false;
|
||||
|
||||
|
@ -171,12 +171,13 @@ class LIRGeneratorShared : public MInstructionVisitorWithDefaults
|
||||
// effects (if any), it may check pre-conditions and bailout if they do not
|
||||
// hold. This function informs the register allocator that it will need to
|
||||
// capture appropriate state.
|
||||
bool assignSnapshot(LInstruction *ins, BailoutKind kind = Bailout_Normal);
|
||||
bool assignSnapshot(LInstruction *ins, BailoutKind kind);
|
||||
|
||||
// Marks this instruction as needing to call into either the VM or GC. This
|
||||
// function may build a snapshot that captures the result of its own
|
||||
// instruction, and as such, should generally be called after define*().
|
||||
bool assignSafepoint(LInstruction *ins, MInstruction *mir);
|
||||
bool assignSafepoint(LInstruction *ins, MInstruction *mir,
|
||||
BailoutKind kind = Bailout_DuringVMCall);
|
||||
|
||||
public:
|
||||
bool visitConstant(MConstant *ins);
|
||||
|
@ -50,7 +50,7 @@ LIRGeneratorX86Shared::visitGuardObjectType(MGuardObjectType *ins)
|
||||
JS_ASSERT(ins->obj()->type() == MIRType_Object);
|
||||
|
||||
LGuardObjectType *guard = new(alloc()) LGuardObjectType(useRegisterAtStart(ins->obj()));
|
||||
if (!assignSnapshot(guard))
|
||||
if (!assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard))
|
||||
return false;
|
||||
if (!add(guard, ins))
|
||||
return false;
|
||||
@ -122,7 +122,7 @@ LIRGeneratorX86Shared::lowerMulI(MMul *mul, MDefinition *lhs, MDefinition *rhs)
|
||||
// Note: lhs is used twice, so that we can restore the original value for the
|
||||
// negative zero check.
|
||||
LMulI *lir = new(alloc()) LMulI(useRegisterAtStart(lhs), useOrConstant(rhs), use(lhs));
|
||||
if (mul->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mul->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineReuseInput(lir, mul, 0);
|
||||
}
|
||||
@ -152,13 +152,13 @@ LIRGeneratorX86Shared::lowerDivI(MDiv *div)
|
||||
// lhs copy register is needed.
|
||||
lir = new(alloc()) LDivPowTwoI(lhs, useRegister(div->lhs()), shift, rhs < 0);
|
||||
}
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineReuseInput(lir, div, 0);
|
||||
} else if (rhs != 0) {
|
||||
LDivOrModConstantI *lir;
|
||||
lir = new(alloc()) LDivOrModConstantI(useRegister(div->lhs()), rhs, tempFixed(eax));
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineFixed(lir, div, LAllocation(AnyRegister(edx)));
|
||||
}
|
||||
@ -166,7 +166,7 @@ LIRGeneratorX86Shared::lowerDivI(MDiv *div)
|
||||
|
||||
LDivI *lir = new(alloc()) LDivI(useRegister(div->lhs()), useRegister(div->rhs()),
|
||||
tempFixed(edx));
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineFixed(lir, div, LAllocation(AnyRegister(eax)));
|
||||
}
|
||||
@ -182,13 +182,13 @@ LIRGeneratorX86Shared::lowerModI(MMod *mod)
|
||||
int32_t shift = FloorLog2(Abs(rhs));
|
||||
if (rhs != 0 && uint32_t(1) << shift == Abs(rhs)) {
|
||||
LModPowTwoI *lir = new(alloc()) LModPowTwoI(useRegisterAtStart(mod->lhs()), shift);
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineReuseInput(lir, mod, 0);
|
||||
} else if (rhs != 0) {
|
||||
LDivOrModConstantI *lir;
|
||||
lir = new(alloc()) LDivOrModConstantI(useRegister(mod->lhs()), rhs, tempFixed(edx));
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineFixed(lir, mod, LAllocation(AnyRegister(eax)));
|
||||
}
|
||||
@ -197,7 +197,7 @@ LIRGeneratorX86Shared::lowerModI(MMod *mod)
|
||||
LModI *lir = new(alloc()) LModI(useRegister(mod->lhs()),
|
||||
useRegister(mod->rhs()),
|
||||
tempFixed(eax));
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineFixed(lir, mod, LAllocation(AnyRegister(edx)));
|
||||
}
|
||||
@ -221,7 +221,7 @@ LIRGeneratorX86Shared::lowerUDiv(MDiv *div)
|
||||
LUDivOrMod *lir = new(alloc()) LUDivOrMod(useRegister(div->lhs()),
|
||||
useRegister(div->rhs()),
|
||||
tempFixed(edx));
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineFixed(lir, div, LAllocation(AnyRegister(eax)));
|
||||
}
|
||||
@ -232,7 +232,7 @@ LIRGeneratorX86Shared::lowerUMod(MMod *mod)
|
||||
LUDivOrMod *lir = new(alloc()) LUDivOrMod(useRegister(mod->lhs()),
|
||||
useRegister(mod->rhs()),
|
||||
tempFixed(eax));
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return defineFixed(lir, mod, LAllocation(AnyRegister(edx)));
|
||||
}
|
||||
|
@ -53,10 +53,15 @@ IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
|
||||
uint8_t *sp = bailout->parentStackPointer();
|
||||
uint8_t *fp = sp + bailout->frameSize();
|
||||
|
||||
kind_ = Kind_BailoutIterator;
|
||||
current_ = fp;
|
||||
type_ = JitFrame_IonJS;
|
||||
topFrameSize_ = current_ - sp;
|
||||
topIonScript_ = script()->ionScript();
|
||||
switch (mode_) {
|
||||
case SequentialExecution: topIonScript_ = script()->ionScript(); break;
|
||||
case ParallelExecution: topIonScript_ = script()->parallelIonScript(); break;
|
||||
default: MOZ_ASSUME_UNREACHABLE("No such execution mode");
|
||||
}
|
||||
snapshotOffset_ = bailout->snapshotOffset();
|
||||
}
|
||||
|
||||
@ -65,6 +70,7 @@ IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
|
||||
: JitFrameIterator(activations),
|
||||
machine_(bailout->machine())
|
||||
{
|
||||
kind_ = Kind_BailoutIterator;
|
||||
returnAddressToFp_ = bailout->osiPointReturnAddress();
|
||||
topIonScript_ = bailout->ionScript();
|
||||
const OsiIndex *osiIndex = topIonScript_->getOsiIndex(returnAddressToFp_);
|
||||
|
@ -73,10 +73,15 @@ IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
|
||||
uint8_t *sp = bailout->parentStackPointer();
|
||||
uint8_t *fp = sp + bailout->frameSize();
|
||||
|
||||
kind_ = Kind_BailoutIterator;
|
||||
current_ = fp;
|
||||
type_ = JitFrame_IonJS;
|
||||
topFrameSize_ = current_ - sp;
|
||||
topIonScript_ = script()->ionScript();
|
||||
switch (mode_) {
|
||||
case SequentialExecution: topIonScript_ = script()->ionScript(); break;
|
||||
case ParallelExecution: topIonScript_ = script()->parallelIonScript(); break;
|
||||
default: MOZ_ASSUME_UNREACHABLE("No such execution mode");
|
||||
}
|
||||
|
||||
if (bailout->frameClass() == FrameSizeClass::None()) {
|
||||
snapshotOffset_ = bailout->snapshotOffset();
|
||||
@ -105,6 +110,7 @@ IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
|
||||
: JitFrameIterator(activations),
|
||||
machine_(bailout->machine())
|
||||
{
|
||||
kind_ = Kind_BailoutIterator;
|
||||
returnAddressToFp_ = bailout->osiPointReturnAddress();
|
||||
topIonScript_ = bailout->ionScript();
|
||||
const OsiIndex *osiIndex = topIonScript_->getOsiIndex(returnAddressToFp_);
|
||||
|
@ -458,9 +458,8 @@ if CONFIG['NIGHTLY_BUILD']:
|
||||
DEFINES['ENABLE_PARALLEL_JS'] = True
|
||||
DEFINES['ENABLE_BINARYDATA'] = True
|
||||
DEFINES['ENABLE_SHARED_ARRAY_BUFFER'] = True
|
||||
if CONFIG['ENABLE_ION']:
|
||||
if CONFIG['JSGC_GENERATIONAL_CONFIGURED']:
|
||||
DEFINES['JSGC_FJGENERATIONAL'] = True
|
||||
if CONFIG['ENABLE_ION'] and CONFIG['JSGC_GENERATIONAL_CONFIGURED'] and CONFIG['JS_THREADSAFE_CONFIGURED']:
|
||||
DEFINES['JSGC_FJGENERATIONAL'] = True
|
||||
|
||||
DEFINES['EXPORT_JS_API'] = True
|
||||
|
||||
|
@ -16,8 +16,9 @@
|
||||
#include "RestyleTracker.h"
|
||||
#include "nsPresContext.h"
|
||||
|
||||
class nsRefreshDriver;
|
||||
class nsIFrame;
|
||||
class nsRefreshDriver;
|
||||
class nsStyleChangeList;
|
||||
struct TreeMatchContext;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -1674,7 +1674,8 @@ nsCSSFrameConstructor::CreateGeneratedContent(nsFrameConstructorState& aState,
|
||||
return nullptr;
|
||||
|
||||
nsCounterUseNode* node =
|
||||
new nsCounterUseNode(counters, aContentIndex,
|
||||
new nsCounterUseNode(mPresShell->GetPresContext(),
|
||||
counters, aContentIndex,
|
||||
type == eStyleContentType_Counters);
|
||||
|
||||
nsGenConInitializer* initializer =
|
||||
@ -8008,6 +8009,14 @@ nsCSSFrameConstructor::RecalcQuotesAndCounters()
|
||||
NS_ASSERTION(!mCountersDirty, "Counter updates will be lost");
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSFrameConstructor::NotifyCounterStylesAreDirty()
|
||||
{
|
||||
NS_PRECONDITION(mUpdateCount != 0, "Should be in an update");
|
||||
mCounterManager.SetAllCounterStylesDirty();
|
||||
CountersDirty();
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSFrameConstructor::WillDestroyFrameTree()
|
||||
{
|
||||
|
@ -220,6 +220,9 @@ public:
|
||||
void EndUpdate();
|
||||
void RecalcQuotesAndCounters();
|
||||
|
||||
// Called when any counter style is changed.
|
||||
void NotifyCounterStylesAreDirty();
|
||||
|
||||
// Gets called when the presshell is destroying itself and also
|
||||
// when we tear down our frame tree to reconstruct it
|
||||
void WillDestroyFrameTree();
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "mozilla/Likely.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
bool
|
||||
nsCounterUseNode::InitTextFrame(nsGenConList* aList,
|
||||
nsIFrame* aPseudoFrame, nsIFrame* aTextFrame)
|
||||
@ -40,6 +42,17 @@ nsCounterUseNode::InitTextFrame(nsGenConList* aList,
|
||||
return false;
|
||||
}
|
||||
|
||||
CounterStyle*
|
||||
nsCounterUseNode::GetCounterStyle()
|
||||
{
|
||||
if (!mCounterStyle) {
|
||||
const nsCSSValue& style = mCounterFunction->Item(mAllCounters ? 2 : 1);
|
||||
mCounterStyle = mPresContext->CounterStyleManager()->
|
||||
BuildCounterStyle(nsDependentString(style.GetStringBufferValue()));
|
||||
}
|
||||
return mCounterStyle;
|
||||
}
|
||||
|
||||
// assign the correct |mValueAfter| value to a node that has been inserted
|
||||
// Should be called immediately after calling |Insert|.
|
||||
void nsCounterUseNode::Calc(nsCounterList *aList)
|
||||
@ -77,17 +90,17 @@ nsCounterUseNode::GetText(nsString& aResult)
|
||||
for (nsCounterNode *n = mScopeStart; n->mScopePrev; n = n->mScopeStart)
|
||||
stack.AppendElement(n->mScopePrev);
|
||||
|
||||
const nsCSSValue& styleItem = mCounterStyle->Item(mAllCounters ? 2 : 1);
|
||||
int32_t style = styleItem.GetIntValue();
|
||||
const char16_t* separator;
|
||||
if (mAllCounters)
|
||||
separator = mCounterStyle->Item(1).GetStringBufferValue();
|
||||
separator = mCounterFunction->Item(1).GetStringBufferValue();
|
||||
|
||||
CounterStyle* style = GetCounterStyle();
|
||||
for (uint32_t i = stack.Length() - 1;; --i) {
|
||||
nsCounterNode *n = stack[i];
|
||||
nsAutoString text;
|
||||
bool isTextRTL;
|
||||
nsBulletFrame::AppendCounterText(
|
||||
style, n->mValueAfter, aResult, isTextRTL);
|
||||
style->GetCounterText(n->mValueAfter, text, isTextRTL);
|
||||
aResult.Append(text);
|
||||
if (i == 0)
|
||||
break;
|
||||
NS_ASSERTION(mAllCounters, "yikes, separator is uninitialized");
|
||||
@ -267,6 +280,34 @@ nsCounterManager::RecalcAll()
|
||||
mNames.EnumerateRead(RecalcDirtyLists, nullptr);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
SetCounterStylesDirty(const nsAString& aKey,
|
||||
nsCounterList* aList,
|
||||
void* aClosure)
|
||||
{
|
||||
nsCounterNode* first = aList->First();
|
||||
if (first) {
|
||||
bool changed = false;
|
||||
nsCounterNode* node = first;
|
||||
do {
|
||||
if (node->mType == nsCounterNode::USE) {
|
||||
node->UseNode()->SetCounterStyleDirty();
|
||||
changed = true;
|
||||
}
|
||||
} while ((node = aList->Next(node)) != first);
|
||||
if (changed) {
|
||||
aList->SetDirty();
|
||||
}
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsCounterManager::SetAllCounterStylesDirty()
|
||||
{
|
||||
mNames.EnumerateRead(SetCounterStylesDirty, nullptr);
|
||||
}
|
||||
|
||||
struct DestroyNodesData {
|
||||
DestroyNodesData(nsIFrame *aFrame)
|
||||
: mFrame(aFrame)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "CounterStyleManager.h"
|
||||
|
||||
class nsCounterList;
|
||||
struct nsCounterUseNode;
|
||||
@ -79,16 +80,22 @@ struct nsCounterUseNode : public nsCounterNode {
|
||||
// The same structure passed through the style system: an array
|
||||
// containing the values in the counter() or counters() in the order
|
||||
// given in the CSS spec.
|
||||
nsRefPtr<nsCSSValue::Array> mCounterStyle;
|
||||
nsRefPtr<nsCSSValue::Array> mCounterFunction;
|
||||
|
||||
nsPresContext* mPresContext;
|
||||
nsRefPtr<mozilla::CounterStyle> mCounterStyle;
|
||||
|
||||
// false for counter(), true for counters()
|
||||
bool mAllCounters;
|
||||
|
||||
// args go directly to member variables here and of nsGenConNode
|
||||
nsCounterUseNode(nsCSSValue::Array* aCounterStyle,
|
||||
nsCounterUseNode(nsPresContext* aPresContext,
|
||||
nsCSSValue::Array* aCounterFunction,
|
||||
uint32_t aContentIndex, bool aAllCounters)
|
||||
: nsCounterNode(aContentIndex, USE)
|
||||
, mCounterStyle(aCounterStyle)
|
||||
, mCounterFunction(aCounterFunction)
|
||||
, mPresContext(aPresContext)
|
||||
, mCounterStyle(nullptr)
|
||||
, mAllCounters(aAllCounters)
|
||||
{
|
||||
NS_ASSERTION(aContentIndex <= INT32_MAX, "out of range");
|
||||
@ -97,6 +104,12 @@ struct nsCounterUseNode : public nsCounterNode {
|
||||
virtual bool InitTextFrame(nsGenConList* aList,
|
||||
nsIFrame* aPseudoFrame, nsIFrame* aTextFrame) MOZ_OVERRIDE;
|
||||
|
||||
mozilla::CounterStyle* GetCounterStyle();
|
||||
void SetCounterStyleDirty()
|
||||
{
|
||||
mCounterStyle = nullptr;
|
||||
}
|
||||
|
||||
// assign the correct |mValueAfter| value to a node that has been inserted
|
||||
// Should be called immediately after calling |Insert|.
|
||||
void Calc(nsCounterList* aList);
|
||||
@ -219,6 +232,9 @@ public:
|
||||
// Clean up data in any dirty counter lists.
|
||||
void RecalcAll();
|
||||
|
||||
// Set all counter styles dirty
|
||||
void SetAllCounterStylesDirty();
|
||||
|
||||
// Destroy nodes for the frame in any lists, and return whether any
|
||||
// nodes were destroyed.
|
||||
bool DestroyNodesFor(nsIFrame *aFrame);
|
||||
|
@ -2332,6 +2332,11 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument,
|
||||
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
|
||||
}
|
||||
|
||||
sheet = nsLayoutStylesheetCache::CounterStylesSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
|
||||
}
|
||||
|
||||
sheet = nsLayoutStylesheetCache::HTMLSheet();
|
||||
if (sheet) {
|
||||
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
|
||||
|
@ -19,11 +19,15 @@
|
||||
#ifndef _nsFrameManager_h_
|
||||
#define _nsFrameManager_h_
|
||||
|
||||
#include "nsIFrame.h"
|
||||
#include "nsFrameManagerBase.h"
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsFrameList.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsStyleContext.h"
|
||||
|
||||
class nsContainerFrame;
|
||||
class nsPlaceholderFrame;
|
||||
|
||||
namespace mozilla {
|
||||
/**
|
||||
@ -75,7 +79,7 @@ struct UndisplayedNode {
|
||||
|
||||
class nsFrameManager : public nsFrameManagerBase
|
||||
{
|
||||
typedef nsIFrame::ChildListID ChildListID;
|
||||
typedef mozilla::layout::FrameChildListID ChildListID;
|
||||
|
||||
public:
|
||||
nsFrameManager(nsIPresShell *aPresShell, nsStyleSet* aStyleSet) {
|
||||
|
@ -19,24 +19,24 @@
|
||||
#ifndef _nsFrameManagerBase_h_
|
||||
#define _nsFrameManagerBase_h_
|
||||
|
||||
#include "nsDebug.h"
|
||||
#include "pldhash.h"
|
||||
|
||||
class nsIFrame;
|
||||
class nsIPresShell;
|
||||
class nsStyleSet;
|
||||
class nsIContent;
|
||||
class nsPlaceholderFrame;
|
||||
class nsIFrame;
|
||||
class nsStyleContext;
|
||||
class nsIAtom;
|
||||
class nsStyleChangeList;
|
||||
class nsILayoutHistoryState;
|
||||
|
||||
class nsFrameManagerBase
|
||||
{
|
||||
public:
|
||||
nsFrameManagerBase()
|
||||
: mPresShell(nullptr)
|
||||
, mStyleSet(nullptr)
|
||||
, mRootFrame(nullptr)
|
||||
, mUndisplayedMap(nullptr)
|
||||
, mIsDestroyingFrames(false)
|
||||
{
|
||||
memset(this, '\0', sizeof(nsFrameManagerBase));
|
||||
mPlaceholderMap.ops = nullptr;
|
||||
}
|
||||
|
||||
bool IsDestroyingFrames() { return mIsDestroyingFrames; }
|
||||
|
@ -530,6 +530,8 @@ public:
|
||||
|
||||
virtual void CancelAllPendingReflows() = 0;
|
||||
|
||||
virtual void NotifyCounterStylesAreDirty() = 0;
|
||||
|
||||
/**
|
||||
* Recreates the frames for a node
|
||||
*/
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "nsObjectFrame.h"
|
||||
#include "nsTransitionManager.h"
|
||||
#include "nsAnimationManager.h"
|
||||
#include "CounterStyleManager.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIMessageManager.h"
|
||||
@ -239,6 +240,8 @@ nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType)
|
||||
mUserFontSet = nullptr;
|
||||
mUserFontSetDirty = true;
|
||||
|
||||
mCounterStylesDirty = true;
|
||||
|
||||
// if text perf logging enabled, init stats struct
|
||||
PRLogModuleInfo *log = gfxPlatform::GetLog(eGfxLog_textperf);
|
||||
if (log && log->level >= PR_LOG_WARNING) {
|
||||
@ -964,9 +967,12 @@ nsPresContext::Init(nsDeviceContext* aDeviceContext)
|
||||
|
||||
mAnimationManager = new nsAnimationManager(this);
|
||||
|
||||
// FIXME: Why is mozilla:: needed?
|
||||
// Since there are methods in nsPresContext have the same name as the
|
||||
// classes, it is necessary to prefix them with the namespace here.
|
||||
mRestyleManager = new mozilla::RestyleManager(this);
|
||||
|
||||
mCounterStyleManager = new mozilla::CounterStyleManager(this);
|
||||
|
||||
if (mDocument->GetDisplayDocument()) {
|
||||
NS_ASSERTION(mDocument->GetDisplayDocument()->GetShell() &&
|
||||
mDocument->GetDisplayDocument()->GetShell()->GetPresContext(),
|
||||
@ -1142,6 +1148,10 @@ nsPresContext::SetShell(nsIPresShell* aShell)
|
||||
mRestyleManager->Disconnect();
|
||||
mRestyleManager = nullptr;
|
||||
}
|
||||
if (mCounterStyleManager) {
|
||||
mCounterStyleManager->Disconnect();
|
||||
mCounterStyleManager = nullptr;
|
||||
}
|
||||
|
||||
if (IsRoot()) {
|
||||
// Have to cancel our plugin geometry timer, because the
|
||||
@ -1867,6 +1877,7 @@ nsPresContext::RebuildAllStyleData(nsChangeHint aExtraHint)
|
||||
mUsesRootEMUnits = false;
|
||||
mUsesViewportUnits = false;
|
||||
RebuildUserFontSet();
|
||||
RebuildCounterStyles();
|
||||
|
||||
RestyleManager()->RebuildAllStyleData(aExtraHint);
|
||||
}
|
||||
@ -2201,6 +2212,46 @@ nsPresContext::UserFontSetUpdated()
|
||||
PostRebuildAllStyleDataEvent(NS_STYLE_HINT_REFLOW);
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::FlushCounterStyles()
|
||||
{
|
||||
if (!mShell) {
|
||||
return; // we've been torn down
|
||||
}
|
||||
if (mCounterStyleManager->IsInitial()) {
|
||||
// Still in its initial state, no need to clean.
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCounterStylesDirty) {
|
||||
bool changed = mCounterStyleManager->NotifyRuleChanged();
|
||||
if (changed) {
|
||||
PresShell()->NotifyCounterStylesAreDirty();
|
||||
PostRebuildAllStyleDataEvent(NS_STYLE_HINT_REFLOW);
|
||||
}
|
||||
mCounterStylesDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::RebuildCounterStyles()
|
||||
{
|
||||
if (mCounterStyleManager->IsInitial()) {
|
||||
// Still in its initial state, no need to reset.
|
||||
return;
|
||||
}
|
||||
|
||||
mCounterStylesDirty = true;
|
||||
mDocument->SetNeedStyleFlush();
|
||||
if (!mPostedFlushCounterStyles) {
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
NS_NewRunnableMethod(this, &nsPresContext::HandleRebuildCounterStyles);
|
||||
if (NS_SUCCEEDED(NS_DispatchToCurrentThread(ev))) {
|
||||
mPostedFlushCounterStyles = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::EnsureSafeToHandOutCSSRules()
|
||||
{
|
||||
|
@ -69,6 +69,7 @@ class nsDeviceContext;
|
||||
namespace mozilla {
|
||||
class EventStateManager;
|
||||
class RestyleManager;
|
||||
class CounterStyleManager;
|
||||
namespace dom {
|
||||
class MediaQueryList;
|
||||
}
|
||||
@ -242,13 +243,17 @@ public:
|
||||
nsRefreshDriver* RefreshDriver() { return mRefreshDriver; }
|
||||
|
||||
mozilla::RestyleManager* RestyleManager() { return mRestyleManager; }
|
||||
|
||||
mozilla::CounterStyleManager* CounterStyleManager() {
|
||||
return mCounterStyleManager;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Rebuilds all style data by throwing out the old rule tree and
|
||||
* building a new one, and additionally applying aExtraHint (which
|
||||
* must not contain nsChangeHint_ReconstructFrame) to the root frame.
|
||||
* Also rebuild the user font set.
|
||||
* Also rebuild the user font set and counter style manager.
|
||||
*/
|
||||
void RebuildAllStyleData(nsChangeHint aExtraHint);
|
||||
/**
|
||||
@ -869,6 +874,9 @@ public:
|
||||
// user font set is changed and fonts become unavailable).
|
||||
void UserFontSetUpdated();
|
||||
|
||||
void FlushCounterStyles();
|
||||
void RebuildCounterStyles(); // asynchronously
|
||||
|
||||
// Ensure that it is safe to hand out CSS rules outside the layout
|
||||
// engine by ensuring that all CSS style sheets have unique inners
|
||||
// and, if necessary, synchronously rebuilding all style data.
|
||||
@ -1158,6 +1166,11 @@ protected:
|
||||
FlushUserFontSet();
|
||||
}
|
||||
|
||||
void HandleRebuildCounterStyles() {
|
||||
mPostedFlushCounterStyles = false;
|
||||
FlushCounterStyles();
|
||||
}
|
||||
|
||||
bool HavePendingInputEvent();
|
||||
|
||||
// Can't be inline because we can't include nsStyleSet.h.
|
||||
@ -1182,6 +1195,7 @@ protected:
|
||||
nsRefPtr<nsTransitionManager> mTransitionManager;
|
||||
nsRefPtr<nsAnimationManager> mAnimationManager;
|
||||
nsRefPtr<mozilla::RestyleManager> mRestyleManager;
|
||||
nsRefPtr<mozilla::CounterStyleManager> mCounterStyleManager;
|
||||
nsIAtom* mMedium; // initialized by subclass ctors;
|
||||
// weak pointer to static atom
|
||||
nsCOMPtr<nsIAtom> mMediaEmulated;
|
||||
@ -1322,6 +1336,11 @@ protected:
|
||||
// Do we currently have an event posted to call FlushUserFontSet?
|
||||
unsigned mPostedFlushUserFontSet : 1;
|
||||
|
||||
// Is the current mCounterStyleManager valid?
|
||||
unsigned mCounterStylesDirty : 1;
|
||||
// Do we currently have an event posted to call FlushCounterStyles?
|
||||
unsigned mPostedFlushCounterStyles: 1;
|
||||
|
||||
// resize reflow is suppressed when the only change has been to zoom
|
||||
// the document rather than to change the document's dimensions
|
||||
unsigned mSupressResizeReflow : 1;
|
||||
|
@ -4171,6 +4171,8 @@ PresShell::FlushPendingNotifications(mozilla::ChangesToFlush aFlush)
|
||||
// reflow).
|
||||
mPresContext->FlushUserFontSet();
|
||||
|
||||
mPresContext->FlushCounterStyles();
|
||||
|
||||
// Flush any requested SMIL samples.
|
||||
if (mDocument->HasAnimationController()) {
|
||||
mDocument->GetAnimationController()->FlushResampleRequests();
|
||||
@ -4517,6 +4519,15 @@ PresShell::ContentRemoved(nsIDocument *aDocument,
|
||||
VERIFY_STYLE_TREE;
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::NotifyCounterStylesAreDirty()
|
||||
{
|
||||
nsAutoCauseReflowNotifier reflowNotifier(this);
|
||||
mFrameConstructor->BeginUpdate();
|
||||
mFrameConstructor->NotifyCounterStylesAreDirty();
|
||||
mFrameConstructor->EndUpdate();
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresShell::ReconstructFrames(void)
|
||||
{
|
||||
@ -4563,6 +4574,7 @@ nsIPresShell::ReconstructStyleDataInternal()
|
||||
|
||||
if (mPresContext) {
|
||||
mPresContext->RebuildUserFontSet();
|
||||
mPresContext->RebuildCounterStyles();
|
||||
}
|
||||
|
||||
Element* root = mDocument->GetRootElement();
|
||||
@ -8556,6 +8568,8 @@ PresShell::WillDoReflow()
|
||||
|
||||
mPresContext->FlushUserFontSet();
|
||||
|
||||
mPresContext->FlushCounterStyles();
|
||||
|
||||
mFrameConstructor->BeginUpdate();
|
||||
|
||||
mLastReflowStart = GetPerformanceNow();
|
||||
|
@ -159,6 +159,7 @@ public:
|
||||
virtual already_AddRefed<nsIContent> GetEventTargetContent(
|
||||
mozilla::WidgetEvent* aEvent) MOZ_OVERRIDE;
|
||||
|
||||
virtual void NotifyCounterStylesAreDirty();
|
||||
|
||||
virtual nsresult ReconstructFrames(void) MOZ_OVERRIDE;
|
||||
virtual void Freeze() MOZ_OVERRIDE;
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "CacheObserver.h"
|
||||
#include "DisplayItemClip.h"
|
||||
#include "ActiveLayerTracker.h"
|
||||
#include "CounterStyleManager.h"
|
||||
|
||||
#include "AudioChannelService.h"
|
||||
#include "mozilla/dom/DataStoreService.h"
|
||||
@ -293,6 +294,8 @@ nsLayoutStatics::Initialize()
|
||||
|
||||
CacheObserver::Init();
|
||||
|
||||
CounterStyleManager::InitializeBuiltinCounterStyles();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "nsRenderingContext.h"
|
||||
#include "TextOverflow.h"
|
||||
#include "nsIFrameInlines.h"
|
||||
#include "CounterStyleManager.h"
|
||||
|
||||
#include "nsBidiPresUtils.h"
|
||||
|
||||
@ -6486,17 +6487,10 @@ nsBlockFrame::SetInitialChildList(ChildListID aListID,
|
||||
!GetPrevInFlow()) {
|
||||
// Resolve style for the bullet frame
|
||||
const nsStyleList* styleList = StyleList();
|
||||
nsCSSPseudoElements::Type pseudoType;
|
||||
switch (styleList->mListStyleType) {
|
||||
case NS_STYLE_LIST_STYLE_DISC:
|
||||
case NS_STYLE_LIST_STYLE_CIRCLE:
|
||||
case NS_STYLE_LIST_STYLE_SQUARE:
|
||||
pseudoType = nsCSSPseudoElements::ePseudo_mozListBullet;
|
||||
break;
|
||||
default:
|
||||
pseudoType = nsCSSPseudoElements::ePseudo_mozListNumber;
|
||||
break;
|
||||
}
|
||||
CounterStyle* style = styleList->GetCounterStyle();
|
||||
nsCSSPseudoElements::Type pseudoType = style->IsBullet() ?
|
||||
nsCSSPseudoElements::ePseudo_mozListBullet :
|
||||
nsCSSPseudoElements::ePseudo_mozListNumber;
|
||||
|
||||
nsIPresShell *shell = presContext->PresShell();
|
||||
|
||||
@ -6535,35 +6529,23 @@ nsBlockFrame::BulletIsEmpty() const
|
||||
NS_STYLE_DISPLAY_LIST_ITEM && HasOutsideBullet(),
|
||||
"should only care when we have an outside bullet");
|
||||
const nsStyleList* list = StyleList();
|
||||
return list->mListStyleType == NS_STYLE_LIST_STYLE_NONE &&
|
||||
return list->GetCounterStyle()->IsNone() &&
|
||||
!list->GetListStyleImage();
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockFrame::GetBulletText(nsAString& aText) const
|
||||
nsBlockFrame::GetSpokenBulletText(nsAString& aText) const
|
||||
{
|
||||
aText.Truncate();
|
||||
|
||||
const nsStyleList* myList = StyleList();
|
||||
if (myList->GetListStyleImage() ||
|
||||
myList->mListStyleType == NS_STYLE_LIST_STYLE_DISC) {
|
||||
if (myList->GetListStyleImage()) {
|
||||
aText.Assign(kDiscCharacter);
|
||||
aText.Append(' ');
|
||||
}
|
||||
else if (myList->mListStyleType == NS_STYLE_LIST_STYLE_CIRCLE) {
|
||||
aText.Assign(kCircleCharacter);
|
||||
aText.Append(' ');
|
||||
}
|
||||
else if (myList->mListStyleType == NS_STYLE_LIST_STYLE_SQUARE) {
|
||||
aText.Assign(kSquareCharacter);
|
||||
aText.Append(' ');
|
||||
}
|
||||
else if (myList->mListStyleType != NS_STYLE_LIST_STYLE_NONE) {
|
||||
} else {
|
||||
nsBulletFrame* bullet = GetBullet();
|
||||
if (bullet) {
|
||||
nsAutoString text;
|
||||
bullet->GetListItemText(*myList, text);
|
||||
aText = text;
|
||||
bullet->GetSpokenText(aText);
|
||||
} else {
|
||||
aText.Truncate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ public:
|
||||
/**
|
||||
* Return the bullet text equivalent.
|
||||
*/
|
||||
void GetBulletText(nsAString& aText) const;
|
||||
void GetSpokenBulletText(nsAString& aText) const;
|
||||
|
||||
/**
|
||||
* Return true if there's a bullet.
|
||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user