merge m-c to b2g-inbound

This commit is contained in:
Wes Kocher 2014-06-12 17:48:18 -07:00
commit 9803d43fac
242 changed files with 9052 additions and 3284 deletions

View File

@ -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));
}

View File

@ -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;

View File

@ -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);
}

View File

@ -6,6 +6,7 @@ support-files =
markuprules.xml
[test_browserui.xul]
[test_counterstyle.html]
[test_general.html]
[test_general.xul]
[test_link.html]

View 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>

View File

@ -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

View File

@ -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,

View File

@ -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];

View File

@ -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)

View File

@ -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;

View File

@ -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)
{

View File

@ -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:

View File

@ -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]

View File

@ -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>

View File

@ -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 ||

View File

@ -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]

View File

@ -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>

View File

@ -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;
}

View File

@ -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.
*/

View File

@ -51,6 +51,8 @@ public:
const nsAString& aText, HTMLTrackElement* aTrackElement,
ErrorResult& aRv);
~TextTrackCue();
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
TextTrack* GetTrack() const

View File

@ -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);
}

View File

@ -161,6 +161,7 @@ SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded()
EnsureOnDemandBuiltInUASheet(sheet);
}
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::FormsSheet());
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::CounterStylesSheet());
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::HTMLSheet());
EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::UASheet());
}

View File

@ -237,6 +237,11 @@ AutoJSAPIWithErrorsReportedToWindow::AutoJSAPIWithErrorsReportedToWindow(nsIScri
{
}
AutoJSAPIWithErrorsReportedToWindow::AutoJSAPIWithErrorsReportedToWindow(nsIGlobalObject* aGlobalObject)
: AutoJSAPI(FindJSContext(aGlobalObject), /* aIsMainThread = */ true)
{
}
AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
bool aIsMainThread,
JSContext* aCx)

View File

@ -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);
};
/*

View File

@ -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

View File

@ -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)

View File

@ -29,6 +29,10 @@ DataStore::DataStore(nsPIDOMWindow* aWindow)
{
}
DataStore::~DataStore()
{
}
already_AddRefed<DataStore>
DataStore::Constructor(GlobalObject& aGlobal, ErrorResult& aRv)
{

View File

@ -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

View File

@ -8,6 +8,7 @@ XPIDL_SOURCES += [
'nsIDOMCounter.idl',
'nsIDOMCSSCharsetRule.idl',
'nsIDOMCSSConditionRule.idl',
'nsIDOMCSSCounterStyleRule.idl',
'nsIDOMCSSFontFaceRule.idl',
'nsIDOMCSSFontFeatureValuesRule.idl',
'nsIDOMCSSGroupingRule.idl',

View 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;
};

View File

@ -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;

View File

@ -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

View File

@ -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.

View File

@ -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()) {

View File

@ -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!

View File

@ -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 {

View File

@ -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;
};

View File

@ -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);

View File

@ -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

View File

@ -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();

View File

@ -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;
}
};

View File

@ -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

View File

@ -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>

View File

@ -98,7 +98,7 @@ gfxPattern::AddColorStop(gfxFloat offset, const gfxRGBA& c)
}
void
gfxPattern::SetColorStops(mozilla::RefPtr<GradientStops> aStops)
gfxPattern::SetColorStops(GradientStops* aStops)
{
mStops = aStops;
}

View File

@ -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

View File

@ -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.");

View File

@ -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);

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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&mdash;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&mdash;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&mdash;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&mdash;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&mdash;the 'chrome debugging' model.
Gecko instance at once---the 'chrome debugging' model.
- [Object wrapper][wrapper] functions help manipulate object references
that cross privilege boundaries.

View File

@ -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"
}

View 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);

View File

@ -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);

View File

@ -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();

View File

@ -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;
};

View File

@ -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.

View File

@ -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);
}

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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
{

View File

@ -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:

View File

@ -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);

View File

@ -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);

View File

@ -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)
{

View File

@ -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_);

View File

@ -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:

View File

@ -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)));
}

View File

@ -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_);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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)));
}

View File

@ -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_);

View File

@ -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_);

View File

@ -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

View File

@ -16,8 +16,9 @@
#include "RestyleTracker.h"
#include "nsPresContext.h"
class nsRefreshDriver;
class nsIFrame;
class nsRefreshDriver;
class nsStyleChangeList;
struct TreeMatchContext;
namespace mozilla {

View File

@ -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()
{

View File

@ -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();

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -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; }

View File

@ -530,6 +530,8 @@ public:
virtual void CancelAllPendingReflows() = 0;
virtual void NotifyCounterStylesAreDirty() = 0;
/**
* Recreates the frames for a node
*/

View File

@ -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()
{

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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;
}

View File

@ -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();
}
}
}

View File

@ -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