Merge inbound to m-c.

This commit is contained in:
Ryan VanderMeulen 2013-05-15 21:14:58 -04:00
commit f9b7785a5b
386 changed files with 3768 additions and 44999 deletions

View File

@ -17,5 +17,4 @@
# #
# Modifying this file will now automatically clobber the buildbot machines \o/ # Modifying this file will now automatically clobber the buildbot machines \o/
# #
Bug 866093 - Change in .gyp file for Android builds. Bug 852687 - changing an idl without clobbering resulted test failures
Bug 861039 - Nuking and rebuilding gfx/angle without clobber caused: "No rule to make target `../../../../gfx/angle/src/compiler/ArrayBoundsClamper.cpp', needed by `ArrayBoundsClamper.o'. Stop."

View File

@ -1108,13 +1108,47 @@ HyperTextAccessible::GetTextAfterOffset(int32_t aOffset,
if (IsDefunct()) if (IsDefunct())
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
if (aBoundaryType == BOUNDARY_CHAR) { int32_t offset = ConvertMagicOffset(aOffset);
GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset); if (offset < 0)
return NS_OK; return NS_ERROR_INVALID_ARG;
}
return GetTextHelper(eGetAfter, aBoundaryType, aOffset, switch (aBoundaryType) {
aStartOffset, aEndOffset, aText); case BOUNDARY_CHAR:
GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset);
return NS_OK;
case BOUNDARY_WORD_START:
// Move word forward twice to find start and end offsets.
*aStartOffset = FindWordBoundary(offset, eDirNext, eStartWord);
*aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eStartWord);
return GetText(*aStartOffset, *aEndOffset, aText);
case BOUNDARY_WORD_END:
// If the offset is a word end (except 0 offset) then move forward to find
// end offset (start offset is the given offset). Otherwise move forward
// twice to find both start and end offsets.
if (offset == 0) {
*aStartOffset = FindWordBoundary(offset, eDirNext, eEndWord);
*aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eEndWord);
} else {
*aEndOffset = FindWordBoundary(offset, eDirNext, eEndWord);
*aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eEndWord);
if (*aStartOffset != offset) {
*aStartOffset = *aEndOffset;
*aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eEndWord);
}
}
return GetText(*aStartOffset, *aEndOffset, aText);
case BOUNDARY_LINE_START:
case BOUNDARY_LINE_END:
case BOUNDARY_ATTRIBUTE_RANGE:
return GetTextHelper(eGetAfter, aBoundaryType, aOffset,
aStartOffset, aEndOffset, aText);
default:
return NS_ERROR_INVALID_ARG;
}
} }
// nsIPersistentProperties // nsIPersistentProperties

View File

@ -58,50 +58,20 @@
"textarea", kOk, kOk, kOk); "textarea", kOk, kOk, kOk);
// BOUNDARY_WORD_START // BOUNDARY_WORD_START
testTextAfterOffset(0, BOUNDARY_WORD_START, "two ", 9, 13, testTextAfterOffset(0, BOUNDARY_WORD_START, "two ", 9, 13, IDs);
"div", kTodo, kTodo, kTodo,
"divbr", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"editablebr", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(8, BOUNDARY_WORD_START, "two ", 9, 13, testTextAfterOffset(8, BOUNDARY_WORD_START, "two ", 9, 13,
"div", kTodo, kTodo, kTodo, "div", kOk, kOk, kOk,
"divbr", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kTodo,
"editablebr", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(9, BOUNDARY_WORD_START, "words\n", 13, 19,
"div", kTodo, kTodo, kTodo,
"divbr", kTodo, kTodo, kTodo, "divbr", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo, "editable", kOk, kOk, kOk,
"editablebr", kTodo, kTodo, kTodo, "editablebr", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo); "textarea", kOk, kOk, kOk);
testTextAfterOffset(9, BOUNDARY_WORD_START, "words\n", 13, 19, IDs);
// BOUNDARY_WORD_END // BOUNDARY_WORD_END
testTextAfterOffset(0, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, testTextAfterOffset(0, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
"div", kTodo, kTodo, kTodo, testTextAfterOffset(6, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
"divbr", kTodo, kTodo, kTodo, testTextAfterOffset(7, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
"editable", kTodo, kTodo, kTodo, testTextAfterOffset(8, BOUNDARY_WORD_END, " words", 12, 18, IDs);
"editablebr", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(6, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
"div", kTodo, kTodo, kTodo,
"divbr", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"editablebr", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(7, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
"div", kOk, kOk, kOk,
"divbr", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"editablebr", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAfterOffset(8, BOUNDARY_WORD_END, " words", 12, 18,
"div", kTodo, kTodo, kTodo,
"divbr", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"editablebr", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
// BOUNDARY_LINE_START // BOUNDARY_LINE_START
testTextAfterOffset(0, BOUNDARY_LINE_START, "\n", 8, 9, testTextAfterOffset(0, BOUNDARY_LINE_START, "\n", 8, 9,

View File

@ -12,9 +12,9 @@
src="../text.js"></script> src="../text.js"></script>
<script type="application/javascript"> <script type="application/javascript">
if (navigator.platform.startsWith("Mac")) { if (navigator.platform.startsWith("Mac")) {
SimpleTest.expectAssertions(0, 20); SimpleTest.expectAssertions(0, 14);
} else { } else {
SimpleTest.expectAssertions(20); SimpleTest.expectAssertions(14);
} }
function doTest() function doTest()
@ -59,108 +59,28 @@
testCharAfterOffset("textarea", 15, "", 16, 16); testCharAfterOffset("textarea", 15, "", 16, 16);
// BOUNDARY_WORD_START // BOUNDARY_WORD_START
testTextAfterOffset(0, BOUNDARY_WORD_START, "my ", 6, 9, testTextAfterOffset(0, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
"input", kTodo, kTodo, kTodo, testTextAfterOffset(1, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
"div", kTodo, kTodo, kTodo, testTextAfterOffset(5, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
"editable", kTodo, kTodo, kTodo, testTextAfterOffset(6, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
"textarea", kTodo, kTodo, kTodo); testTextAfterOffset(7, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
testTextAfterOffset(1, BOUNDARY_WORD_START, "my ", 6, 9, testTextAfterOffset(8, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
"input", kTodo, kTodo, kTodo, testTextAfterOffset(9, BOUNDARY_WORD_START, "", 15, 15, IDs);
"div", kTodo, kTodo, kTodo, testTextAfterOffset(11, BOUNDARY_WORD_START, "", 15, 15, IDs);
"editable", kTodo, kTodo, kTodo, testTextAfterOffset(14, BOUNDARY_WORD_START, "", 15, 15, IDs);
"textarea", kTodo, kTodo, kTodo); testTextAfterOffset(15, BOUNDARY_WORD_START, "", 15, 15, IDs);
testTextAfterOffset(5, BOUNDARY_WORD_START, "my ", 6, 9,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(6, BOUNDARY_WORD_START, "friend", 9, 15,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(7, BOUNDARY_WORD_START, "friend", 9, 15,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(8, BOUNDARY_WORD_START, "friend", 9, 15,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(9, BOUNDARY_WORD_START, "", 15, 15,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(11, BOUNDARY_WORD_START, "", 15, 15,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(14, BOUNDARY_WORD_START, "", 15, 15,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(15, BOUNDARY_WORD_START, "", 15, 15,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
// BOUNDARY_WORD_END // BOUNDARY_WORD_END
testTextAfterOffset(0, BOUNDARY_WORD_END, " my", 5, 8, testTextAfterOffset(0, BOUNDARY_WORD_END, " my", 5, 8, IDs);
"input", kTodo, kTodo, kTodo, testTextAfterOffset(1, BOUNDARY_WORD_END, " my", 5, 8, IDs);
"div", kTodo, kTodo, kTodo, testTextAfterOffset(5, BOUNDARY_WORD_END, " my", 5, 8, IDs);
"editable", kTodo, kTodo, kTodo, testTextAfterOffset(6, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
"textarea", kTodo, kTodo, kTodo); testTextAfterOffset(7, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
testTextAfterOffset(1, BOUNDARY_WORD_END, " my", 5, 8, testTextAfterOffset(8, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
"input", kTodo, kTodo, kTodo, testTextAfterOffset(9, BOUNDARY_WORD_END, "", 15, 15, IDs);
"div", kTodo, kTodo, kTodo, testTextAfterOffset(11, BOUNDARY_WORD_END, "", 15, 15, IDs);
"editable", kTodo, kTodo, kTodo, testTextAfterOffset(14, BOUNDARY_WORD_END, "", 15, 15, IDs);
"textarea", kTodo, kTodo, kTodo); testTextAfterOffset(15, BOUNDARY_WORD_END, "", 15, 15, IDs);
testTextAfterOffset(5, BOUNDARY_WORD_END, " my", 5, 8,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAfterOffset(6, BOUNDARY_WORD_END, " friend", 8, 15,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(7, BOUNDARY_WORD_END, " friend", 8, 15,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(8, BOUNDARY_WORD_END, " friend", 8, 15,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAfterOffset(9, BOUNDARY_WORD_END, "", 15, 15,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(11, BOUNDARY_WORD_END, "", 15, 15,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(14, BOUNDARY_WORD_END, "", 15, 15,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(15, BOUNDARY_WORD_END, "", 15, 15,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
// BOUNDARY_LINE_START // BOUNDARY_LINE_START
testTextAfterOffset(0, BOUNDARY_LINE_START, "", 15, 15, testTextAfterOffset(0, BOUNDARY_LINE_START, "", 15, 15,

View File

@ -13,12 +13,6 @@
<script type="application/javascript" <script type="application/javascript"
src="../text.js"></script> src="../text.js"></script>
<script type="application/javascript"> <script type="application/javascript">
if (navigator.platform.startsWith("Mac")) {
SimpleTest.expectAssertions(0, 3);
} else {
SimpleTest.expectAssertions(3);
}
function doTest() function doTest()
{ {
// __B__r__a__v__e__ __S__i__r__ __ __R__o__b__i__n__ __ __ __r__a__n // __B__r__a__v__e__ __S__i__r__ __ __R__o__b__i__n__ __ __ __r__a__n
@ -60,128 +54,68 @@
testCharAfterOffset(IDs, 18, "r", 19, 20); testCharAfterOffset(IDs, 18, "r", 19, 20);
// BOUNDARY_WORD_START // BOUNDARY_WORD_START
testTextAfterOffset(0, BOUNDARY_WORD_START, "Sir ", 6, 11, testTextAfterOffset(0, BOUNDARY_WORD_START, "Sir ", 6, 11, IDs);
"input", kTodo, kTodo, kTodo, testTextAfterOffset(5, BOUNDARY_WORD_START, "Sir ", 6, 11, IDs);
"div", kTodo, kTodo, kTodo, testTextAfterOffset(6, BOUNDARY_WORD_START, "Robin ", 11, 19, IDs);
"editable", kTodo, kTodo, kTodo, testTextAfterOffset(9, BOUNDARY_WORD_START, "Robin ", 11, 19, IDs);
"textarea", kTodo, kTodo, kTodo); testTextAfterOffset(10, BOUNDARY_WORD_START, "Robin ", 11, 19, IDs);
testTextAfterOffset(5, BOUNDARY_WORD_START, "Sir ", 6, 11,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(6, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(9, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(10, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(11, BOUNDARY_WORD_START, "ran", 19, 22, testTextAfterOffset(11, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(16, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(18, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(19, BOUNDARY_WORD_START, "", 22, 22,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kTodo);
// BOUNDARY_WORD_END
testTextAfterOffset(0, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(4, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(5, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAfterOffset(6, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(8, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(9, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAfterOffset(10, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(11, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(15, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(16, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAfterOffset(17, BOUNDARY_WORD_END, "", 22, 22,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(18, BOUNDARY_WORD_END, "", 22, 22,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(19, BOUNDARY_WORD_END, "", 22, 22,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(21, BOUNDARY_WORD_END, "", 22, 22,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(22, BOUNDARY_WORD_END, "", 22, 22,
"input", kOk, kOk, kOk, "input", kOk, kOk, kOk,
"div", kOk, kOk, kOk, "div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk, "editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo); "textarea", kTodo, kOk, kTodo);
testTextAfterOffset(16, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(18, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(19, BOUNDARY_WORD_START, "", 22, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kTodo, kTodo);
// BOUNDARY_WORD_END
testTextAfterOffset(0, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
testTextAfterOffset(4, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
testTextAfterOffset(5, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
testTextAfterOffset(6, BOUNDARY_WORD_END, " Robin", 9, 16, IDs);
testTextAfterOffset(8, BOUNDARY_WORD_END, " Robin", 9, 16, IDs);
testTextAfterOffset(9, BOUNDARY_WORD_END, " Robin", 9, 16, IDs);
testTextAfterOffset(10, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
testTextAfterOffset(11, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
testTextAfterOffset(15, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
testTextAfterOffset(16, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
testTextAfterOffset(17, BOUNDARY_WORD_END, "", 22, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(18, BOUNDARY_WORD_END, "", 22, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(19, BOUNDARY_WORD_END, "", 22, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(21, BOUNDARY_WORD_END, "", 22, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(22, BOUNDARY_WORD_END, "", 22, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kTodo, kTodo);
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// getTextBeforeOffset // getTextBeforeOffset

View File

@ -20,7 +20,6 @@ function test() {
// (1) Check that the scroll position is maintained at the bottom // (1) Check that the scroll position is maintained at the bottom
// when the requests overflow the vertical size of the container. // when the requests overflow the vertical size of the container.
.then(() => { .then(() => {
debuggee.performRequests();
return waitForRequestsToOverflowContainer(monitor, requestsContainer); return waitForRequestsToOverflowContainer(monitor, requestsContainer);
}).then(() => { }).then(() => {
ok(scrolledToBottom(requestsContainer), "Scrolled to bottom on overflow."); ok(scrolledToBottom(requestsContainer), "Scrolled to bottom on overflow.");

View File

@ -9,6 +9,10 @@ function test() {
initNetMonitor(SORTING_URL).then(([aTab, aDebuggee, aMonitor]) => { initNetMonitor(SORTING_URL).then(([aTab, aDebuggee, aMonitor]) => {
info("Starting test... "); info("Starting test... ");
// It seems that this test may be slow on debug builds. This could be because
// of the heavy dom manipulation associated with sorting.
requestLongerTimeout(2);
let { $, L10N, NetMonitorView } = aMonitor.panelWin; let { $, L10N, NetMonitorView } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView; let { RequestsMenu } = NetMonitorView;
@ -172,6 +176,7 @@ function test() {
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(a), verifyRequestItemTarget(RequestsMenu.getItemAtIndex(a),
"GET1", SORTING_SJS + "?index=1", { "GET1", SORTING_SJS + "?index=1", {
fuzzyUrl: true,
status: 101, status: 101,
statusText: "Meh", statusText: "Meh",
type: "1", type: "1",
@ -181,6 +186,7 @@ function test() {
}); });
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(b), verifyRequestItemTarget(RequestsMenu.getItemAtIndex(b),
"GET2", SORTING_SJS + "?index=2", { "GET2", SORTING_SJS + "?index=2", {
fuzzyUrl: true,
status: 200, status: 200,
statusText: "Meh", statusText: "Meh",
type: "2", type: "2",
@ -190,6 +196,7 @@ function test() {
}); });
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(c), verifyRequestItemTarget(RequestsMenu.getItemAtIndex(c),
"GET3", SORTING_SJS + "?index=3", { "GET3", SORTING_SJS + "?index=3", {
fuzzyUrl: true,
status: 300, status: 300,
statusText: "Meh", statusText: "Meh",
type: "3", type: "3",
@ -199,6 +206,7 @@ function test() {
}); });
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(d), verifyRequestItemTarget(RequestsMenu.getItemAtIndex(d),
"GET4", SORTING_SJS + "?index=4", { "GET4", SORTING_SJS + "?index=4", {
fuzzyUrl: true,
status: 400, status: 400,
statusText: "Meh", statusText: "Meh",
type: "4", type: "4",
@ -208,6 +216,7 @@ function test() {
}); });
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(e), verifyRequestItemTarget(RequestsMenu.getItemAtIndex(e),
"GET5", SORTING_SJS + "?index=5", { "GET5", SORTING_SJS + "?index=5", {
fuzzyUrl: true,
status: 500, status: 500,
statusText: "Meh", statusText: "Meh",
type: "5", type: "5",

View File

@ -9,6 +9,10 @@ function test() {
initNetMonitor(SORTING_URL).then(([aTab, aDebuggee, aMonitor]) => { initNetMonitor(SORTING_URL).then(([aTab, aDebuggee, aMonitor]) => {
info("Starting test... "); info("Starting test... ");
// It seems that this test may be slow on debug builds. This could be because
// of the heavy dom manipulation associated with sorting.
requestLongerTimeout(2);
let { $, L10N, NetMonitorView } = aMonitor.panelWin; let { $, L10N, NetMonitorView } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView; let { RequestsMenu } = NetMonitorView;
@ -109,6 +113,7 @@ function test() {
for (let i = 0, len = aOrder.length / 5; i < len; i++) { for (let i = 0, len = aOrder.length / 5; i < len; i++) {
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i]), verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i]),
"GET1", SORTING_SJS + "?index=1", { "GET1", SORTING_SJS + "?index=1", {
fuzzyUrl: true,
status: 101, status: 101,
statusText: "Meh", statusText: "Meh",
type: "1", type: "1",
@ -120,6 +125,7 @@ function test() {
for (let i = 0, len = aOrder.length / 5; i < len; i++) { for (let i = 0, len = aOrder.length / 5; i < len; i++) {
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len]), verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len]),
"GET2", SORTING_SJS + "?index=2", { "GET2", SORTING_SJS + "?index=2", {
fuzzyUrl: true,
status: 200, status: 200,
statusText: "Meh", statusText: "Meh",
type: "2", type: "2",
@ -131,6 +137,7 @@ function test() {
for (let i = 0, len = aOrder.length / 5; i < len; i++) { for (let i = 0, len = aOrder.length / 5; i < len; i++) {
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 2]), verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 2]),
"GET3", SORTING_SJS + "?index=3", { "GET3", SORTING_SJS + "?index=3", {
fuzzyUrl: true,
status: 300, status: 300,
statusText: "Meh", statusText: "Meh",
type: "3", type: "3",
@ -142,6 +149,7 @@ function test() {
for (let i = 0, len = aOrder.length / 5; i < len; i++) { for (let i = 0, len = aOrder.length / 5; i < len; i++) {
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 3]), verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 3]),
"GET4", SORTING_SJS + "?index=4", { "GET4", SORTING_SJS + "?index=4", {
fuzzyUrl: true,
status: 400, status: 400,
statusText: "Meh", statusText: "Meh",
type: "4", type: "4",
@ -153,6 +161,7 @@ function test() {
for (let i = 0, len = aOrder.length / 5; i < len; i++) { for (let i = 0, len = aOrder.length / 5; i < len; i++) {
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 4]), verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 4]),
"GET5", SORTING_SJS + "?index=5", { "GET5", SORTING_SJS + "?index=5", {
fuzzyUrl: true,
status: 500, status: 500,
statusText: "Meh", statusText: "Meh",
type: "5", type: "5",

View File

@ -185,7 +185,7 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
info("> Verifying: " + aMethod + " " + aUrl + " " + aData.toSource()); info("> Verifying: " + aMethod + " " + aUrl + " " + aData.toSource());
info("> Request: " + aRequestItem.attachment.toSource()); info("> Request: " + aRequestItem.attachment.toSource());
let { status, statusText, type, fullMimeType, size, time } = aData; let { fuzzyUrl, status, statusText, type, fullMimeType, size, time } = aData;
let { attachment, target } = aRequestItem let { attachment, target } = aRequestItem
let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL); let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
@ -193,19 +193,28 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
let query = uri.query; let query = uri.query;
let hostPort = uri.hostPort; let hostPort = uri.hostPort;
is(attachment.method, aMethod, if (fuzzyUrl) {
"The attached method is incorrect."); ok(attachment.method.startsWith(aMethod), "The attached method is incorrect.");
ok(attachment.url.startsWith(aUrl), "The attached url is incorrect.");
is(attachment.url, aUrl, } else {
"The attached url is incorrect."); is(attachment.method, aMethod, "The attached method is incorrect.");
is(attachment.url, aUrl, "The attached url is incorrect.");
}
is(target.querySelector(".requests-menu-method").getAttribute("value"), is(target.querySelector(".requests-menu-method").getAttribute("value"),
aMethod, "The displayed method is incorrect."); aMethod, "The displayed method is incorrect.");
is(target.querySelector(".requests-menu-file").getAttribute("value"), if (fuzzyUrl) {
name + (query ? "?" + query : ""), "The displayed file is incorrect."); ok(target.querySelector(".requests-menu-file").getAttribute("value").startsWith(
is(target.querySelector(".requests-menu-file").getAttribute("tooltiptext"), name + (query ? "?" + query : "")), "The displayed file is incorrect.");
name + (query ? "?" + query : ""), "The tooltip file is incorrect."); ok(target.querySelector(".requests-menu-file").getAttribute("tooltiptext").startsWith(
name + (query ? "?" + query : "")), "The tooltip file is incorrect.");
} else {
is(target.querySelector(".requests-menu-file").getAttribute("value"),
name + (query ? "?" + query : ""), "The displayed file is incorrect.");
is(target.querySelector(".requests-menu-file").getAttribute("tooltiptext"),
name + (query ? "?" + query : ""), "The tooltip file is incorrect.");
}
is(target.querySelector(".requests-menu-domain").getAttribute("value"), is(target.querySelector(".requests-menu-domain").getAttribute("value"),
hostPort, "The displayed domain is incorrect."); hostPort, "The displayed domain is incorrect.");

View File

@ -25,11 +25,11 @@
// Use a count parameter to defeat caching. // Use a count parameter to defeat caching.
var count = 0; var count = 0;
function performRequests() { (function performRequests() {
get("request_" + (count++), function() { get("request_" + (count++), function() {
setTimeout(performRequests, 0); setTimeout(performRequests, 0);
}); });
} })();
</script> </script>
</body> </body>

View File

@ -12,7 +12,8 @@
<script type="text/javascript"> <script type="text/javascript">
function get(aAddress, aIndex, aCallback) { function get(aAddress, aIndex, aCallback) {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open("GET" + aIndex, aAddress + "?index=" + aIndex, true); // Use a random parameter to defeat caching.
xhr.open("GET" + aIndex, aAddress + "?index=" + aIndex + "&" + Math.random(), true);
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (this.readyState == this.DONE) { if (this.readyState == this.DONE) {

View File

@ -14,5 +14,5 @@ function handleRequest(request, response) {
response.setHeader("Content-Type", "text/" + index, false); response.setHeader("Content-Type", "text/" + index, false);
response.write(new Array(index * 10).join(index)); // + 0.01 KB response.write(new Array(index * 10).join(index)); // + 0.01 KB
response.finish(); response.finish();
}, 50, Ci.nsITimer.TYPE_ONE_SHOT); // Make sure this request takes a few ms. }, 10, Ci.nsITimer.TYPE_ONE_SHOT); // Make sure this request takes a few ms.
} }

View File

@ -573,18 +573,10 @@
<richlistitem id="context-copy" type="copy" onclick="ContextCommands.copy();"> <richlistitem id="context-copy" type="copy" onclick="ContextCommands.copy();">
<label value="&contextTextCopy.label;"/> <label value="&contextTextCopy.label;"/>
</richlistitem> </richlistitem>
<!-- only displayed if there is text on the clipboard -->
<richlistitem id="context-paste" type="paste" onclick="ContextCommands.paste();">
<label value="&contextTextPaste.label;"/>
</richlistitem>
<!-- Search Bing for "(text..)", displayed on selected content text only --> <!-- Search Bing for "(text..)", displayed on selected content text only -->
<richlistitem id="context-search" type="selected-text,!input-text" onclick="ContextCommands.searchText(this);"> <richlistitem id="context-search" type="selected-text,!input-text" onclick="ContextCommands.searchText(this);">
<label id="context-search-label" value=""/> <label id="context-search-label" value=""/>
</richlistitem> </richlistitem>
<!-- only display if there is text on the clipboard and the target is the urlbar -->
<richlistitem id="context-paste-n-go" type="paste-url" onclick="ContextCommands.pasteAndGo();">
<label value="&contextTextPasteAndGo.label;"/>
</richlistitem>
<!-- only displayed in inputs with text that do not have selection --> <!-- only displayed in inputs with text that do not have selection -->
<richlistitem id="context-select" type="selectable" onclick="ContextCommands.select();"> <richlistitem id="context-select" type="selectable" onclick="ContextCommands.select();">
<label value="&contextTextSelect.label;"/> <label value="&contextTextSelect.label;"/>
@ -593,6 +585,14 @@
<richlistitem id="context-select-all" type="selectable" onclick="ContextCommands.selectAll();"> <richlistitem id="context-select-all" type="selectable" onclick="ContextCommands.selectAll();">
<label value="&contextTextSelectAll.label;"/> <label value="&contextTextSelectAll.label;"/>
</richlistitem> </richlistitem>
<!-- only displayed if there is text on the clipboard -->
<richlistitem id="context-paste" type="paste" onclick="ContextCommands.paste();">
<label value="&contextTextPaste.label;"/>
</richlistitem>
<!-- only display if there is text on the clipboard and the target is the urlbar -->
<richlistitem id="context-paste-n-go" type="paste-url" onclick="ContextCommands.pasteAndGo();">
<label value="&contextTextPasteAndGo.label;"/>
</richlistitem>
<!-- Image related --> <!-- Image related -->
<!-- save image to user pictures library --> <!-- save image to user pictures library -->

View File

@ -46,7 +46,7 @@ HistoryView.prototype = {
for (let i = 0, addedCount = 0; i < childCount && addedCount < limit; i++) { for (let i = 0, addedCount = 0; i < childCount && addedCount < limit; i++) {
let node = rootNode.getChild(i); let node = rootNode.getChild(i);
let uri = node.uri; let uri = node.uri;
let title = node.title || uri; let title = (node.title && node.title.length) ? node.title : uri;
// If item is marked for deletion, skip it. // If item is marked for deletion, skip it.
if (this._toRemove && this._toRemove.indexOf(uri) !== -1) if (this._toRemove && this._toRemove.indexOf(uri) !== -1)

View File

@ -7,10 +7,7 @@
flyoutpanel { flyoutpanel {
height: 100%; height: 100%;
border-width: 2px;
border-color: #d7d6d6;
background-color: #ffffff; background-color: #ffffff;
-moz-border-start-style: solid;
visibility: collapse; visibility: collapse;
position: fixed; position: fixed;
transition: transform @metro_animation_duration@ @metro_animation_easing@; transition: transform @metro_animation_duration@ @metro_animation_easing@;
@ -41,6 +38,9 @@ flyoutpanel[visible] {
} }
.flyoutpanel-header { .flyoutpanel-header {
border-width: 1px;
-moz-border-start-style: solid;
border-color: #1b1b1b;
background-color: #002147; background-color: #002147;
height: 80px; height: 80px;
width: 100%; width: 100%;
@ -60,6 +60,9 @@ flyoutpanel[visible] {
} }
.flyoutpanel-contents { .flyoutpanel-contents {
border-width: 1px;
-moz-border-start-style: solid;
border-color: #c2c2c2;
padding: 40px; padding: 40px;
width: 100%; width: 100%;
} }

View File

@ -699,21 +699,8 @@ arrowbox {
.meta { .meta {
background-color: @panel_light_color@; background-color: @panel_light_color@;
background-image: radial-gradient(circle farthest-corner at left bottom, background-image: url("chrome://browser/skin/images/firefox-watermark.png");
rgba(255, 127, 0, 0.2) 0%, background-repeat: no-repeat;
rgba(255, 212, 0, 0) 30%),
radial-gradient(circle farthest-corner at 40% 100%,
rgba(0, 120, 255, 0.15) 0%,
rgba(0, 186, 255, 0) 20%),
radial-gradient(circle farthest-corner at 60% 100%,
rgba(0, 120, 255, 0.125) 0%,
rgba(0, 186, 255, 0) 20%),
radial-gradient(circle farthest-corner at right bottom,
rgba(185, 17, 255, 0.1) 0%,
rgba(255, 84, 253, 0) 30%),
url("chrome://browser/skin/images/firefox-watermark.png"),
@panel_light_background@;
background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, repeat;
background-position: center center; background-position: center center;
padding: @metro_spacing_normal@ @metro_spacing_xxnormal@; padding: @metro_spacing_normal@ @metro_spacing_xxnormal@;
overflow: auto; overflow: auto;

View File

@ -89,7 +89,7 @@ class RemoteAutomation(Automation):
def checkForJavaException(self, logcat): def checkForJavaException(self, logcat):
found_exception = False found_exception = False
for i, line in enumerate(logcat): for i, line in enumerate(logcat):
if "REPORTING UNCAUGHT EXCEPTION" in line: if "REPORTING UNCAUGHT EXCEPTION" in line or "FATAL EXCEPTION" in line:
# Strip away the date, time, logcat tag and pid from the next two lines and # Strip away the date, time, logcat tag and pid from the next two lines and
# concatenate the remainder to form a concise summary of the exception. # concatenate the remainder to form a concise summary of the exception.
# #

View File

@ -486,24 +486,7 @@ case "$target" in
AC_MSG_ERROR([The major versions of \$CC and \$CXX do not match.]) AC_MSG_ERROR([The major versions of \$CC and \$CXX do not match.])
fi fi
if test "$_CC_MAJOR_VERSION" = "14"; then if test "$_CC_MAJOR_VERSION" = "16"; then
dnl Require VC8SP1 or newer.
dnl VC8 is 14.00.50727.42, VC8SP1 is 14.00.50727.762.
if test "$_CC_RELEASE" -lt 50727 -o \
\( "$_CC_RELEASE" -eq 50727 -a "$_CC_BUILD" -lt 762 \); then
AC_MSG_ERROR([This version ($CC_VERSION) of the MSVC compiler is unsupported. You probably need to install Service Pack 1 of Visual Studio 2005. See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
fi
_CC_SUITE=8
_MSVS_VERSION=2005
AC_DEFINE(_CRT_SECURE_NO_DEPRECATE)
AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE)
elif test "$_CC_MAJOR_VERSION" = "15"; then
_CC_SUITE=9
_MSVS_VERSION=2008
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
elif test "$_CC_MAJOR_VERSION" = "16"; then
_CC_SUITE=10 _CC_SUITE=10
_MSVS_VERSION=2010 _MSVS_VERSION=2010
AC_DEFINE(_CRT_SECURE_NO_WARNINGS) AC_DEFINE(_CRT_SECURE_NO_WARNINGS)

View File

@ -1440,7 +1440,8 @@ void
nsContentSink::DidBuildModelImpl(bool aTerminated) nsContentSink::DidBuildModelImpl(bool aTerminated)
{ {
if (mDocument) { if (mDocument) {
MOZ_ASSERT(mDocument->GetReadyStateEnum() == MOZ_ASSERT(aTerminated ||
mDocument->GetReadyStateEnum() ==
nsIDocument::READYSTATE_LOADING, "Bad readyState"); nsIDocument::READYSTATE_LOADING, "Bad readyState");
mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE); mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
} }

View File

@ -93,9 +93,7 @@ NS_IMPL_FORWARD_EVENT_HANDLER(nsDOMFileReader, error, FileIOObject)
void void
nsDOMFileReader::RootResultArrayBuffer() nsDOMFileReader::RootResultArrayBuffer()
{ {
nsContentUtils::PreserveWrapper( NS_HOLD_JS_OBJECTS(this, nsDOMFileReader);
static_cast<EventTarget*>(
static_cast<nsDOMEventTargetHelper*>(this)), this);
} }
//nsDOMFileReader constructors/initializers //nsDOMFileReader constructors/initializers
@ -113,7 +111,8 @@ nsDOMFileReader::nsDOMFileReader()
nsDOMFileReader::~nsDOMFileReader() nsDOMFileReader::~nsDOMFileReader()
{ {
FreeFileData(); FreeFileData();
mResultArrayBuffer = nullptr;
NS_DROP_JS_OBJECTS(this, nsDOMFileReader);
nsLayoutStatics::Release(); nsLayoutStatics::Release();
} }

View File

@ -324,15 +324,17 @@ nsXMLHttpRequest::~nsXMLHttpRequest()
NS_ABORT_IF_FALSE(!(mState & XML_HTTP_REQUEST_SYNCLOOPING), "we rather crash than hang"); NS_ABORT_IF_FALSE(!(mState & XML_HTTP_REQUEST_SYNCLOOPING), "we rather crash than hang");
mState &= ~XML_HTTP_REQUEST_SYNCLOOPING; mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
mResultJSON = JSVAL_VOID;
mResultArrayBuffer = nullptr;
NS_DROP_JS_OBJECTS(this, nsXMLHttpRequest);
nsLayoutStatics::Release(); nsLayoutStatics::Release();
} }
void void
nsXMLHttpRequest::RootJSResultObjects() nsXMLHttpRequest::RootJSResultObjects()
{ {
nsContentUtils::PreserveWrapper( NS_HOLD_JS_OBJECTS(this, nsXMLHttpRequest);
static_cast<EventTarget*>(
static_cast<nsDOMEventTargetHelper*>(this)), this);
} }
/** /**
@ -2645,7 +2647,8 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
mLoadLengthComputable = false; mLoadLengthComputable = false;
mLoadTotal = 0; mLoadTotal = 0;
if ((aVariant || !aBody.IsNull()) && httpChannel && if ((aVariant || !aBody.IsNull()) && httpChannel &&
!method.EqualsLiteral("GET")) { !method.LowerCaseEqualsLiteral("get") &&
!method.LowerCaseEqualsLiteral("head")) {
nsAutoCString charset; nsAutoCString charset;
nsAutoCString defaultContentType; nsAutoCString defaultContentType;

View File

@ -1 +1,3 @@
conformance/more/conformance/quickCheckAPI-B2.html
conformance/more/conformance/quickCheckAPI-B3.html
conformance/more/functions/bufferSubDataBadArgs.html conformance/more/functions/bufferSubDataBadArgs.html

View File

@ -5028,8 +5028,6 @@ HTMLInputElement::GetStep() const
step = GetDefaultStep(); step = GetDefaultStep();
} }
// TODO: This multiplication can lead to inexact results, we should use a
// type that supports a better precision than double. Bug 783607.
return step * GetStepScaleFactor(); return step * GetStepScaleFactor();
} }
@ -5220,15 +5218,6 @@ HTMLInputElement::HasStepMismatch() const
return false; return false;
} }
if (mType == NS_FORM_INPUT_DATE) {
// The multiplication by the stepScaleFactor for date can easily lead
// to precision loss, since in most use cases this value should be
// an integer (millisecond precision), we can get rid of the precision
// loss by rounding step. This will however lead to erroneous results
// when step was intented to have a precision superior to a millisecond.
step = step.round();
}
// Value has to be an integral multiple of step. // Value has to be an integral multiple of step.
return NS_floorModulo(value - GetStepBase(), step) != 0; return NS_floorModulo(value - GetStepBase(), step) != 0;
} }

View File

@ -60,6 +60,7 @@ MOCHITEST_FILES = \
submit_invalid_file.sjs \ submit_invalid_file.sjs \
test_input_file_picker.html \ test_input_file_picker.html \
test_input_event.html \ test_input_event.html \
test_input_number_rounding.html \
$(NULL) $(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,116 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=783607
-->
<head>
<title>Test rounding behaviour for &lt;input type='number'&gt;</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<meta charset="UTF-8">
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=783607">Mozilla Bug 783607</a>
<p id="display"></p>
<div id="content">
<input id=number type=number value=0 step=0.01 max=1>
</div>
<pre id="test">
<script type="application/javascript">
/**
* Test for Bug 783607.
* This test checks that when <input type=number> has fractional step values,
* the values that a content author will see in their script will not have
* ugly rounding errors.
**/
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
test();
SimpleTest.finish();
});
/**
* We can _NOT_ generate these values by looping and simply incrementing a
* variable by 0.01 and stringifying it, since we'll end up with strings like
* "0.060000000000000005" due to the inability of binary floating point numbers
* to accurately represent decimal values.
*/
var stepVals = [
"0", "0.01", "0.02", "0.03", "0.04", "0.05", "0.06", "0.07", "0.08", "0.09",
"0.1", "0.11", "0.12", "0.13", "0.14", "0.15", "0.16", "0.17", "0.18", "0.19",
"0.2", "0.21", "0.22", "0.23", "0.24", "0.25", "0.26", "0.27", "0.28", "0.29",
"0.3", "0.31", "0.32", "0.33", "0.34", "0.35", "0.36", "0.37", "0.38", "0.39",
"0.4", "0.41", "0.42", "0.43", "0.44", "0.45", "0.46", "0.47", "0.48", "0.49",
"0.5", "0.51", "0.52", "0.53", "0.54", "0.55", "0.56", "0.57", "0.58", "0.59",
"0.6", "0.61", "0.62", "0.63", "0.64", "0.65", "0.66", "0.67", "0.68", "0.69",
"0.7", "0.71", "0.72", "0.73", "0.74", "0.75", "0.76", "0.77", "0.78", "0.79",
"0.8", "0.81", "0.82", "0.83", "0.84", "0.85", "0.86", "0.87", "0.88", "0.89",
"0.9", "0.91", "0.92", "0.93", "0.94", "0.95", "0.96", "0.97", "0.98", "0.99",
"1"
];
var pgUpDnVals = [
"0", "0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1"
];
function test() {
var elem = document.getElementById("number");
elem.focus();
/**
* TODO:
* When <input type='number'> widget will have a widge we should test PAGE_UP,
* PAGE_DOWN, UP and DOWN keys. For the moment, there is no widget so those
* keys do not have any effect.
* The tests using those keys as marked as todo_is() hoping that at least part
* of them will fail when the widget will be implemented.
*/
for (var i = 1; i < pgUpDnVals.length; ++i) {
synthesizeKey("VK_PAGE_UP", {});
todo_is(elem.value, pgUpDnVals[i], "Test VK_PAGE_UP");
is(elem.validity.valid, true, "Check element is valid for value " + pgUpDnVals[i]);
}
for (var i = pgUpDnVals.length - 2; i >= 0; --i) {
synthesizeKey("VK_PAGE_DOWN", {});
// TODO: this condition is there because the todo_is() below would pass otherwise.
if (stepVals[i] == 0) { continue; }
todo_is(elem.value, pgUpDnVals[i], "Test VK_PAGE_DOWN");
is(elem.validity.valid, true, "Check element is valid for value " + pgUpDnVals[i]);
}
for (var i = 1; i < stepVals.length; ++i) {
synthesizeKey("VK_UP", {});
todo_is(elem.value, stepVals[i], "Test VK_UP");
is(elem.validity.valid, true, "Check element is valid for value " + stepVals[i]);
}
for (var i = stepVals.length - 2; i >= 0; --i) {
synthesizeKey("VK_DOWN", {});
// TODO: this condition is there because the todo_is() below would pass otherwise.
if (stepVals[i] == 0) { continue; }
todo_is(elem.value, stepVals[i], "Test VK_DOWN");
is(elem.validity.valid, true, "Check element is valid for value " + stepVals[i]);
}
for (var i = 1; i < stepVals.length; ++i) {
elem.stepUp();
is(elem.value, stepVals[i], "Test stepUp()");
is(elem.validity.valid, true, "Check element is valid for value " + stepVals[i]);
}
for (var i = stepVals.length - 2; i >= 0; --i) {
elem.stepDown();
is(elem.value, stepVals[i], "Test stepDown()");
is(elem.validity.valid, true, "Check element is valid for value " + stepVals[i]);
}
}
</script>
</pre>
</body>
</html>

View File

@ -406,6 +406,13 @@ for (var test of data) {
input.value = 2; input.value = 2;
checkValidity(input, false, apply, {low: 1, high: 3}); checkValidity(input, false, apply, {low: 1, high: 3});
// Rounding issues.
input = getFreshElement(test.type);
input.min = 0.1;
input.step = 0.2;
input.value = 0.3;
checkValidity(input, true, apply);
// Check that when the higher value is higher than max, we don't show it. // Check that when the higher value is higher than max, we don't show it.
input = getFreshElement(test.type); input = getFreshElement(test.type);
input.step = '2'; input.step = '2';

View File

@ -97,7 +97,10 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
JNIEnv *env; JNIEnv *env;
jint res = jvm->AttachCurrentThread(&env, NULL); jint res = jvm->AttachCurrentThread(&env, NULL);
webrtc::VideoEngine::SetAndroidObjects(jvm, (void*)context); if (webrtc::VideoEngine::SetAndroidObjects(jvm, (void*)context) != 0) {
LOG(("VieCapture:SetAndroidObjects Failed"));
return;
}
env->DeleteGlobalRef(context); env->DeleteGlobalRef(context);
#endif #endif
@ -230,7 +233,10 @@ MediaEngineWebRTC::EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSourc
JNIEnv *env; JNIEnv *env;
jvm->AttachCurrentThread(&env, NULL); jvm->AttachCurrentThread(&env, NULL);
webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context); if (webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context) != 0) {
LOG(("VoiceEngine:SetAndroidObjects Failed"));
return;
}
env->DeleteGlobalRef(context); env->DeleteGlobalRef(context);
#endif #endif

View File

@ -4597,8 +4597,10 @@ nsDocShell::Stop(uint32_t aStopFlags)
if (nsIWebNavigation::STOP_CONTENT & aStopFlags) { if (nsIWebNavigation::STOP_CONTENT & aStopFlags) {
// Stop the document loading // Stop the document loading
if (mContentViewer) if (mContentViewer) {
mContentViewer->Stop(); nsCOMPtr<nsIContentViewer> cv = mContentViewer;
cv->Stop();
}
} }
if (nsIWebNavigation::STOP_NETWORK & aStopFlags) { if (nsIWebNavigation::STOP_NETWORK & aStopFlags) {
@ -10525,6 +10527,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
shContainer->GetChildAt(i, getter_AddRefs(child)); shContainer->GetChildAt(i, getter_AddRefs(child));
shContainer->RemoveChild(child); shContainer->RemoveChild(child);
} // for } // for
entry->AbandonBFCacheEntry();
} // shContainer } // shContainer
} }

View File

@ -3088,6 +3088,8 @@ nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior,
case nsIDOMWindowUtils::SELECT_WORDNOSPACE: case nsIDOMWindowUtils::SELECT_WORDNOSPACE:
amount = eSelectWordNoSpace; amount = eSelectWordNoSpace;
break; break;
default:
return NS_ERROR_INVALID_ARG;
} }
nsIPresShell* presShell = GetPresShell(); nsIPresShell* presShell = GetPresShell();

View File

@ -7425,9 +7425,10 @@ nsGlobalWindow::NotifyDOMWindowThawed(nsGlobalWindow* aWindow) {
JSObject* JSObject*
nsGlobalWindow::GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey) nsGlobalWindow::GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey)
{ {
JSObject* handler = nullptr; AutoSafeJSContext cx;
JS::Rooted<JSObject*> handler(cx);
if (mCachedXBLPrototypeHandlers.IsInitialized()) { if (mCachedXBLPrototypeHandlers.IsInitialized()) {
mCachedXBLPrototypeHandlers.Get(aKey, &handler); mCachedXBLPrototypeHandlers.Get(aKey, handler.address());
} }
return handler; return handler;
} }

View File

@ -108,7 +108,7 @@ class CGNativePropertyHooks(CGThing):
prototypeID += "_ID_Count" prototypeID += "_ID_Count"
parent = self.descriptor.interface.parent parent = self.descriptor.interface.parent
parentHooks = ("&" + toBindingNamespace(parent.identifier.name) + "::sNativePropertyHooks" parentHooks = ("&" + toBindingNamespace(parent.identifier.name) + "::sNativePropertyHooks"
if parent else 'NULL') if parent else 'nullptr')
return CGWrapper(CGIndenter(CGList([CGGeneric(resolveOwnProperty), return CGWrapper(CGIndenter(CGList([CGGeneric(resolveOwnProperty),
CGGeneric(enumerateOwnProperties), CGGeneric(enumerateOwnProperties),
@ -183,10 +183,10 @@ DOMJSClass Class = {
%s, %s,
JS_ConvertStub, JS_ConvertStub,
%s, /* finalize */ %s, /* finalize */
NULL, /* checkAccess */ nullptr, /* checkAccess */
%s, /* call */ %s, /* call */
NULL, /* hasInstance */ nullptr, /* hasInstance */
NULL, /* construct */ nullptr, /* construct */
%s, /* trace */ %s, /* trace */
JSCLASS_NO_INTERNAL_MEMBERS JSCLASS_NO_INTERNAL_MEMBERS
}, },
@ -1393,7 +1393,7 @@ class PropertyDefiner:
# And the actual spec # And the actual spec
specs.append(specTemplate % getDataTuple(member)) specs.append(specTemplate % getDataTuple(member))
specs.append(specTerminator) specs.append(specTerminator)
prefableSpecs.append(" { false, NULL }"); prefableSpecs.append(" { false, nullptr }");
specType = "const " + specType specType = "const " + specType
arrays = (("static %s %s_specs[] = {\n" + arrays = (("static %s %s_specs[] = {\n" +
@ -1847,7 +1847,7 @@ if (!unforgeableHolder) {
domClass, domClass,
properties, properties,
chromeProperties, chromeProperties,
'"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "NULL")) '"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "nullptr"))
if UseHolderForUnforgeable(self.descriptor): if UseHolderForUnforgeable(self.descriptor):
assert needInterfacePrototypeObject assert needInterfacePrototypeObject
setUnforgeableHolder = CGGeneric( setUnforgeableHolder = CGGeneric(
@ -2009,7 +2009,7 @@ def CreateBindingJSObject(descriptor, properties, parent):
create = """ obj = NewProxyObject(aCx, DOMProxyHandler::getInstance(), create = """ obj = NewProxyObject(aCx, DOMProxyHandler::getInstance(),
JS::PrivateValue(aObject), proto, %s); JS::PrivateValue(aObject), proto, %s);
if (!obj) { if (!obj) {
return NULL; return nullptr;
} }
""" """
@ -2021,7 +2021,7 @@ def CreateBindingJSObject(descriptor, properties, parent):
else: else:
create = """ obj = JS_NewObject(aCx, &Class.mBase, proto, %s); create = """ obj = JS_NewObject(aCx, &Class.mBase, proto, %s);
if (!obj) { if (!obj) {
return NULL; return nullptr;
} }
js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject)); js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject));
@ -2148,7 +2148,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
GetRealParentObject(aObject, GetRealParentObject(aObject,
WrapNativeParent(aCx, aScope, aObject->GetParentObject()))); WrapNativeParent(aCx, aScope, aObject->GetParentObject())));
if (!parent) { if (!parent) {
return NULL; return nullptr;
} }
// That might have ended up wrapping us already, due to the wonders // That might have ended up wrapping us already, due to the wonders
@ -2165,7 +2165,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, parent)); JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, parent));
JS::Handle<JSObject*> proto = GetProtoObject(aCx, global); JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
if (!proto) { if (!proto) {
return NULL; return nullptr;
} }
%s %s
@ -2213,7 +2213,7 @@ class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, aScope)); JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, aScope));
JS::Handle<JSObject*> proto = GetProtoObject(aCx, global); JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
if (!proto) { if (!proto) {
return NULL; return nullptr;
} }
%s %s
@ -3011,7 +3011,7 @@ for (uint32_t i = 0; i < length; ++i) {
templateBody += "${declName} = tmp;" templateBody += "${declName} = tmp;"
templateBody = wrapObjectTemplate(templateBody, type, templateBody = wrapObjectTemplate(templateBody, type,
"${declName} = NULL", "${declName} = nullptr",
failureCode) failureCode)
declType = CGGeneric(declType) declType = CGGeneric(declType)
@ -3066,7 +3066,7 @@ for (uint32_t i = 0; i < length; ++i) {
elif not isOptional: elif not isOptional:
template += "${declName} = ${holderName}.addr();" template += "${declName} = ${holderName}.addr();"
template = wrapObjectTemplate(template, type, template = wrapObjectTemplate(template, type,
"%s = NULL" % nullableTarget, "%s = nullptr" % nullableTarget,
failureCode) failureCode)
if holderType is not None: if holderType is not None:
@ -5403,7 +5403,7 @@ MOZ_END_ENUM_CLASS(%s)
strings = """ strings = """
const EnumEntry %s[%d] = { const EnumEntry %s[%d] = {
%s, %s,
{ NULL, 0 } { nullptr, 0 }
}; };
""" % (ENUM_ENTRY_VARIABLE_NAME, self.nEnumStrings(), """ % (ENUM_ENTRY_VARIABLE_NAME, self.nEnumStrings(),
",\n ".join(['{"' + val + '", ' + str(len(val)) + '}' for val in self.enum.values()])) ",\n ".join(['{"' + val + '", ' + str(len(val)) + '}' for val in self.enum.values()]))
@ -6650,7 +6650,7 @@ if (!isXray && (expando = GetExpandoObject(proxy))) {
} }
} }
""" + namedGet + """ """ + namedGet + """
desc->obj = NULL; desc->obj = nullptr;
return true;""" return true;"""
class CGDOMJSProxyHandler_defineProperty(ClassMethod): class CGDOMJSProxyHandler_defineProperty(ClassMethod):

View File

@ -1325,25 +1325,20 @@ nsDOMDeviceStorage::SetRootDirectoryForType(const nsAString& aStorageType,
JS::Value JS::Value
InterfaceToJsval(nsPIDOMWindow* aWindow, nsISupports* aObject, const nsIID* aIID) InterfaceToJsval(nsPIDOMWindow* aWindow, nsISupports* aObject, const nsIID* aIID)
{ {
AutoJSContext cx;
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow); nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
if (!sgo) { if (!sgo) {
return JSVAL_NULL; return JSVAL_NULL;
} }
nsIScriptContext *scriptContext = sgo->GetScriptContext(); JS::RootedObject scopeObj(cx, sgo->GetGlobalJSObject());
if (!scriptContext) { NS_ENSURE_TRUE(scopeObj, JSVAL_NULL);
return JSVAL_NULL; JSAutoCompartment ac(cx, scopeObj);
}
AutoPushJSContext cx(scriptContext->GetNativeContext());
if (!cx) {
return JSVAL_NULL;
}
JS::Rooted<JS::Value> someJsVal(cx); JS::Rooted<JS::Value> someJsVal(cx);
JS::Rooted<JSObject*> global(cx, JS_GetGlobalObject(cx));
nsresult rv = nsContentUtils::WrapNative(cx, nsresult rv = nsContentUtils::WrapNative(cx,
global, scopeObj,
aObject, aObject,
aIID, aIID,
someJsVal.address()); someJsVal.address());

View File

@ -142,7 +142,7 @@ NPObjWrapper_Construct(JSContext *cx, unsigned argc, JS::Value *vp);
static JSBool static JSBool
CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject *npobj, CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject *npobj,
jsid id, NPVariant* getPropertyResult, JS::Value *vp); JS::Handle<jsid> id, NPVariant* getPropertyResult, JS::Value *vp);
JSClass sNPObjectJSWrapperClass = JSClass sNPObjectJSWrapperClass =
{ {
@ -960,7 +960,7 @@ JSObjWrapperHashMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *entry,
// static // static
NPObject * NPObject *
nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj) nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JS::Handle<JSObject*> obj)
{ {
if (!npp) { if (!npp) {
NS_ERROR("Null NPP passed to nsJSObjWrapper::GetNewOrUsed()!"); NS_ERROR("Null NPP passed to nsJSObjWrapper::GetNewOrUsed()!");
@ -1084,16 +1084,17 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj)
// compartment for callers that plan to hold onto the result or do anything // compartment for callers that plan to hold onto the result or do anything
// substantial with it. // substantial with it.
static JSObject * static JSObject *
GetNPObjectWrapper(JSContext *cx, JSObject *obj, bool wrapResult = true) GetNPObjectWrapper(JSContext *cx, JSObject *aObj, bool wrapResult = true)
{ {
JS::Rooted<JSObject*> obj(cx, aObj);
while (obj && (obj = js::CheckedUnwrap(obj))) { while (obj && (obj = js::CheckedUnwrap(obj))) {
if (JS_GetClass(obj) == &sNPObjectJSWrapperClass) { if (JS_GetClass(obj) == &sNPObjectJSWrapperClass) {
if (wrapResult && !JS_WrapObject(cx, &obj)) { if (wrapResult && !JS_WrapObject(cx, obj.address())) {
return NULL; return NULL;
} }
return obj; return obj;
} }
if (!::JS_GetPrototype(cx, obj, &obj)) { if (!::JS_GetPrototype(cx, obj, obj.address())) {
return NULL; return NULL;
} }
} }
@ -1336,7 +1337,7 @@ NPObjWrapper_GetProperty(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMut
} }
static JSBool static JSBool
CallNPMethodInternal(JSContext *cx, JSObject *obj, unsigned argc, CallNPMethodInternal(JSContext *cx, JS::Handle<JSObject*> obj, unsigned argc,
JS::Value *argv, JS::Value *rval, bool ctorCall) JS::Value *argv, JS::Value *rval, bool ctorCall)
{ {
NPObject *npobj = GetNPObject(cx, obj); NPObject *npobj = GetNPObject(cx, obj);
@ -1465,7 +1466,7 @@ CallNPMethodInternal(JSContext *cx, JSObject *obj, unsigned argc,
static JSBool static JSBool
CallNPMethod(JSContext *cx, unsigned argc, JS::Value *vp) CallNPMethod(JSContext *cx, unsigned argc, JS::Value *vp)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp); JS::Rooted<JSObject*> obj(cx, JS_THIS_OBJECT(cx, vp));
if (!obj) if (!obj)
return JS_FALSE; return JS_FALSE;
@ -1666,14 +1667,16 @@ NPObjWrapper_Finalize(JSFreeOp *fop, JSObject *obj)
static JSBool static JSBool
NPObjWrapper_Call(JSContext *cx, unsigned argc, JS::Value *vp) NPObjWrapper_Call(JSContext *cx, unsigned argc, JS::Value *vp)
{ {
return CallNPMethodInternal(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), argc, JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
return CallNPMethodInternal(cx, obj, argc,
JS_ARGV(cx, vp), vp, false); JS_ARGV(cx, vp), vp, false);
} }
static JSBool static JSBool
NPObjWrapper_Construct(JSContext *cx, unsigned argc, JS::Value *vp) NPObjWrapper_Construct(JSContext *cx, unsigned argc, JS::Value *vp)
{ {
return CallNPMethodInternal(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), argc, JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
return CallNPMethodInternal(cx, obj, argc,
JS_ARGV(cx, vp), vp, true); JS_ARGV(cx, vp), vp, true);
} }
@ -1960,7 +1963,7 @@ LookupNPP(NPObject *npobj)
JSBool JSBool
CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj, CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
jsid id, NPVariant* getPropertyResult, JS::Value *vp) JS::Handle<jsid> id, NPVariant* getPropertyResult, JS::Value *vp)
{ {
NS_ENSURE_TRUE(vp, JS_FALSE); NS_ENSURE_TRUE(vp, JS_FALSE);

View File

@ -37,7 +37,8 @@ class nsJSObjWrapper : public NPObject,
public nsJSObjWrapperKey public nsJSObjWrapperKey
{ {
public: public:
static NPObject *GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj); static NPObject *GetNewOrUsed(NPP npp, JSContext *cx,
JS::Handle<JSObject*> obj);
protected: protected:
nsJSObjWrapper(NPP npp); nsJSObjWrapper(NPP npp);

View File

@ -1211,7 +1211,8 @@ _getwindowobject(NPP npp)
// Using ::JS_GetGlobalObject(cx) is ok here since the window we // Using ::JS_GetGlobalObject(cx) is ok here since the window we
// want to return here is the outer window, *not* the inner (since // want to return here is the outer window, *not* the inner (since
// we don't know what the plugin will do with it). // we don't know what the plugin will do with it).
return nsJSObjWrapper::GetNewOrUsed(npp, cx, ::JS_GetGlobalObject(cx)); JS::Rooted<JSObject*> global(cx, ::JS_GetGlobalObject(cx));
return nsJSObjWrapper::GetNewOrUsed(npp, cx, global);
} }
NPObject* NP_CALLBACK NPObject* NP_CALLBACK

View File

@ -154,7 +154,7 @@ ConnectWorkerToRIL::RunTask(JSContext *aCx)
// communication. // communication.
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread"); NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?"); NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
JSObject *workerGlobal = JS_GetGlobalObject(aCx); JSObject *workerGlobal = JS_GetGlobalForScopeChain(aCx);
if (!JS_DefineProperty(aCx, workerGlobal, "CLIENT_ID", if (!JS_DefineProperty(aCx, workerGlobal, "CLIENT_ID",
INT_TO_JSVAL(mClientId), nullptr, nullptr, 0)) { INT_TO_JSVAL(mClientId), nullptr, nullptr, 0)) {
@ -260,7 +260,7 @@ ConnectWorkerToNetd::RunTask(JSContext *aCx)
// communication. // communication.
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread"); NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?"); NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
JSObject *workerGlobal = JS_GetGlobalObject(aCx); JSObject *workerGlobal = JS_GetGlobalForScopeChain(aCx);
return !!JS_DefineFunction(aCx, workerGlobal, "postNetdCommand", return !!JS_DefineFunction(aCx, workerGlobal, "postNetdCommand",
DoNetdCommand, 1, 0); DoNetdCommand, 1, 0);
} }
@ -299,7 +299,7 @@ private:
bool bool
NetdReceiver::DispatchNetdEvent::RunTask(JSContext *aCx) NetdReceiver::DispatchNetdEvent::RunTask(JSContext *aCx)
{ {
JSObject *obj = JS_GetGlobalObject(aCx); JSObject *obj = JS_GetGlobalForScopeChain(aCx);
JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize); JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize);
if (!array) { if (!array) {

View File

@ -41,7 +41,7 @@ class nsIURI;
class nsPIDOMWindow; class nsPIDOMWindow;
class nsITimer; class nsITimer;
class nsIXPCScriptNotify; class nsIXPCScriptNotify;
namespace JS { class RuntimeStats; } namespace JS { struct RuntimeStats; }
BEGIN_WORKERS_NAMESPACE BEGIN_WORKERS_NAMESPACE

View File

@ -123,8 +123,10 @@ function execTests() {
} }
doCommand("cmd_scrollBottom"); doCommand("cmd_scrollBottom");
yield;
testScrollCommand("cmd_scrollBottom", root.scrollHeight - 100); testScrollCommand("cmd_scrollBottom", root.scrollHeight - 100);
doCommand("cmd_scrollTop"); doCommand("cmd_scrollTop");
yield;
testScrollCommand("cmd_scrollTop", 0); testScrollCommand("cmd_scrollTop", 0);
doCommand("cmd_scrollPageDown"); doCommand("cmd_scrollPageDown");

View File

@ -589,7 +589,6 @@ nsHTMLCSSUtils::GetComputedStyle(dom::Element* aElement)
NS_ENSURE_TRUE(doc, nullptr); NS_ENSURE_TRUE(doc, nullptr);
nsIPresShell* presShell = doc->GetShell(); nsIPresShell* presShell = doc->GetShell();
NS_ASSERTION(presShell, "Trying to compute style without PresShell");
NS_ENSURE_TRUE(presShell, nullptr); NS_ENSURE_TRUE(presShell, nullptr);
nsRefPtr<nsComputedDOMStyle> style = nsRefPtr<nsComputedDOMStyle> style =

View File

@ -924,6 +924,11 @@ public:
CreateSkiaDrawTargetForFBO(unsigned int aFBOID, GrContext *aContext, const IntSize &aSize, SurfaceFormat aFormat); CreateSkiaDrawTargetForFBO(unsigned int aFBOID, GrContext *aContext, const IntSize &aSize, SurfaceFormat aFormat);
#endif #endif
#if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
static TemporaryRef<GlyphRenderingOptions>
CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting);
#endif
#ifdef WIN32 #ifdef WIN32
static TemporaryRef<DrawTarget> CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat); static TemporaryRef<DrawTarget> CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
static TemporaryRef<DrawTarget> static TemporaryRef<DrawTarget>

View File

@ -6,6 +6,7 @@
#include "DrawTargetSkia.h" #include "DrawTargetSkia.h"
#include "SourceSurfaceSkia.h" #include "SourceSurfaceSkia.h"
#include "ScaledFontBase.h" #include "ScaledFontBase.h"
#include "ScaledFontCairo.h"
#include "skia/SkDevice.h" #include "skia/SkDevice.h"
#ifdef USE_SKIA_GPU #ifdef USE_SKIA_GPU
@ -445,7 +446,7 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
const GlyphBuffer &aBuffer, const GlyphBuffer &aBuffer,
const Pattern &aPattern, const Pattern &aPattern,
const DrawOptions &aOptions, const DrawOptions &aOptions,
const GlyphRenderingOptions*) const GlyphRenderingOptions *aRenderingOptions)
{ {
if (aFont->GetType() != FONT_MAC && if (aFont->GetType() != FONT_MAC &&
aFont->GetType() != FONT_SKIA && aFont->GetType() != FONT_SKIA &&
@ -461,7 +462,30 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
paint.mPaint.setTypeface(skiaFont->GetSkTypeface()); paint.mPaint.setTypeface(skiaFont->GetSkTypeface());
paint.mPaint.setTextSize(SkFloatToScalar(skiaFont->mSize)); paint.mPaint.setTextSize(SkFloatToScalar(skiaFont->mSize));
paint.mPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); paint.mPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
if (aRenderingOptions && aRenderingOptions->GetType() == FONT_CAIRO) {
switch (static_cast<const GlyphRenderingOptionsCairo*>(aRenderingOptions)->GetHinting()) {
case FONT_HINTING_NONE:
paint.mPaint.setHinting(SkPaint::kNo_Hinting);
break;
case FONT_HINTING_LIGHT:
paint.mPaint.setHinting(SkPaint::kSlight_Hinting);
break;
case FONT_HINTING_NORMAL:
paint.mPaint.setHinting(SkPaint::kNormal_Hinting);
break;
case FONT_HINTING_FULL:
paint.mPaint.setHinting(SkPaint::kFull_Hinting);
break;
}
if (static_cast<const GlyphRenderingOptionsCairo*>(aRenderingOptions)->GetAutoHinting()) {
paint.mPaint.setAutohinted(true);
}
} else {
paint.mPaint.setHinting(SkPaint::kNormal_Hinting);
}
std::vector<uint16_t> indices; std::vector<uint16_t> indices;
std::vector<SkPoint> offsets; std::vector<SkPoint> offsets;
indices.resize(aBuffer.mNumGlyphs); indices.resize(aBuffer.mNumGlyphs);

View File

@ -7,14 +7,15 @@
#ifdef USE_CAIRO #ifdef USE_CAIRO
#include "DrawTargetCairo.h" #include "DrawTargetCairo.h"
#include "ScaledFontBase.h" #include "ScaledFontCairo.h"
#endif #endif
#ifdef USE_SKIA #ifdef USE_SKIA
#include "DrawTargetSkia.h" #include "DrawTargetSkia.h"
#include "ScaledFontBase.h" #include "ScaledFontBase.h"
#ifdef MOZ_ENABLE_FREETYPE #ifdef MOZ_ENABLE_FREETYPE
#include "ScaledFontFreetype.h" #define USE_SKIA_FREETYPE
#include "ScaledFontCairo.h"
#endif #endif
#endif #endif
@ -297,20 +298,10 @@ Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSiz
return new ScaledFontMac(static_cast<CGFontRef>(aNativeFont.mFont), aSize); return new ScaledFontMac(static_cast<CGFontRef>(aNativeFont.mFont), aSize);
} }
#endif #endif
#ifdef USE_SKIA #if defined(USE_CAIRO) || defined(USE_SKIA_FREETYPE)
#ifdef MOZ_ENABLE_FREETYPE
case NATIVE_FONT_SKIA_FONT_FACE:
{
return new ScaledFontFreetype(static_cast<FontOptions*>(aNativeFont.mFont), aSize);
}
#endif
#endif
#ifdef USE_CAIRO
case NATIVE_FONT_CAIRO_FONT_FACE: case NATIVE_FONT_CAIRO_FONT_FACE:
{ {
ScaledFontBase* fontBase = new ScaledFontBase(aSize); return new ScaledFontCairo(static_cast<cairo_scaled_font_t*>(aNativeFont.mFont), aSize);
fontBase->SetCairoScaledFont(static_cast<cairo_scaled_font_t*>(aNativeFont.mFont));
return fontBase;
} }
#endif #endif
default: default:
@ -459,6 +450,19 @@ Factory::CreateSkiaDrawTargetForFBO(unsigned int aFBOID, GrContext *aGrContext,
} }
#endif // USE_SKIA_GPU #endif // USE_SKIA_GPU
#ifdef USE_SKIA_FREETYPE
TemporaryRef<GlyphRenderingOptions>
Factory::CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting)
{
RefPtr<GlyphRenderingOptionsCairo> options =
new GlyphRenderingOptionsCairo();
options->SetHinting(aHinting);
options->SetAutoHinting(aAutoHinting);
return options;
}
#endif
TemporaryRef<DrawTarget> TemporaryRef<DrawTarget>
Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize) Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize)
{ {

View File

@ -28,6 +28,7 @@ CPPSRCS = \
Blur.cpp \ Blur.cpp \
Scale.cpp \ Scale.cpp \
ScaledFontBase.cpp \ ScaledFontBase.cpp \
ScaledFontCairo.cpp \
DrawTargetDual.cpp \ DrawTargetDual.cpp \
ImageScaling.cpp \ ImageScaling.cpp \
SourceSurfaceRawData.cpp \ SourceSurfaceRawData.cpp \
@ -73,10 +74,8 @@ CPPSRCS += \
endif endif
ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gtk2 gonk qt)) ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gtk2 gonk qt))
CPPSRCS += \
ScaledFontFreetype.cpp \
$(NULL)
DEFINES += -DMOZ_ENABLE_FREETYPE DEFINES += -DMOZ_ENABLE_FREETYPE
OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
endif endif
DEFINES += -DSK_A32_SHIFT=24 -DSK_R32_SHIFT=16 -DSK_G32_SHIFT=8 -DSK_B32_SHIFT=0 DEFINES += -DSK_A32_SHIFT=24 -DSK_R32_SHIFT=16 -DSK_G32_SHIFT=8 -DSK_B32_SHIFT=0

View File

@ -28,7 +28,7 @@ ScaledFontBase::~ScaledFontBase()
#ifdef USE_SKIA #ifdef USE_SKIA
SkSafeUnref(mTypeface); SkSafeUnref(mTypeface);
#endif #endif
#ifdef USE_CAIRO #ifdef USE_CAIRO_SCALED_FONT
cairo_scaled_font_destroy(mScaledFont); cairo_scaled_font_destroy(mScaledFont);
#endif #endif
} }
@ -39,7 +39,7 @@ ScaledFontBase::ScaledFontBase(Float aSize)
#ifdef USE_SKIA #ifdef USE_SKIA
mTypeface = nullptr; mTypeface = nullptr;
#endif #endif
#ifdef USE_CAIRO #ifdef USE_CAIRO_SCALED_FONT
mScaledFont = nullptr; mScaledFont = nullptr;
#endif #endif
} }
@ -106,7 +106,7 @@ ScaledFontBase::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBu
return; return;
} }
#ifdef USE_CAIRO #ifdef USE_CAIRO_SCALED_FONT
void void
ScaledFontBase::SetCairoScaledFont(cairo_scaled_font_t* font) ScaledFontBase::SetCairoScaledFont(cairo_scaled_font_t* font)
{ {

View File

@ -8,10 +8,15 @@
#include "2D.h" #include "2D.h"
// Skia uses cairo_scaled_font_t as the internal font type in ScaledFont
#if defined(USE_SKIA) || defined(USE_CAIRO)
#define USE_CAIRO_SCALED_FONT
#endif
#ifdef USE_SKIA #ifdef USE_SKIA
#include "skia/SkTypeface.h" #include "skia/SkTypeface.h"
#endif #endif
#ifdef USE_CAIRO #ifdef USE_CAIRO_SCALED_FONT
#include "cairo.h" #include "cairo.h"
#endif #endif
@ -39,7 +44,7 @@ public:
// Not true, but required to instantiate a ScaledFontBase. // Not true, but required to instantiate a ScaledFontBase.
virtual FontType GetType() const { return FONT_SKIA; } virtual FontType GetType() const { return FONT_SKIA; }
#ifdef USE_CAIRO #ifdef USE_CAIRO_SCALED_FONT
cairo_scaled_font_t* GetCairoScaledFont() { return mScaledFont; } cairo_scaled_font_t* GetCairoScaledFont() { return mScaledFont; }
void SetCairoScaledFont(cairo_scaled_font_t* font); void SetCairoScaledFont(cairo_scaled_font_t* font);
#endif #endif
@ -49,7 +54,7 @@ protected:
#ifdef USE_SKIA #ifdef USE_SKIA
SkTypeface* mTypeface; SkTypeface* mTypeface;
#endif #endif
#ifdef USE_CAIRO #ifdef USE_CAIRO_SCALED_FONT
cairo_scaled_font_t* mScaledFont; cairo_scaled_font_t* mScaledFont;
#endif #endif
Float mSize; Float mSize;

View File

@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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 "ScaledFontCairo.h"
#include "Logging.h"
#include "gfxFont.h"
#ifdef MOZ_ENABLE_FREETYPE
#include <ft2build.h>
#include FT_FREETYPE_H
#include "cairo-ft.h"
#endif
#if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
#include "skia/SkTypeface.h"
#include "skia/SkTypeface_cairo.h"
#endif
#include <string>
typedef struct FT_FaceRec_* FT_Face;
using namespace std;
namespace mozilla {
namespace gfx {
// On Linux and Android our "platform" font is a cairo_scaled_font_t and we use
// an SkFontHost implementation that allows Skia to render using this.
// This is mainly because FT_Face is not good for sharing between libraries, which
// is a requirement when we consider runtime switchable backends and so on
ScaledFontCairo::ScaledFontCairo(cairo_scaled_font_t* aScaledFont, Float aSize)
: ScaledFontBase(aSize)
{
mScaledFont = aScaledFont;
#if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
cairo_font_face_t* fontFace = cairo_scaled_font_get_font_face(aScaledFont);
FT_Face face = cairo_ft_scaled_font_lock_face(aScaledFont);
int style = SkTypeface::kNormal;
if (face->style_flags & FT_STYLE_FLAG_ITALIC)
style |= SkTypeface::kItalic;
if (face->style_flags & FT_STYLE_FLAG_BOLD)
style |= SkTypeface::kBold;
bool isFixedWidth = face->face_flags & FT_FACE_FLAG_FIXED_WIDTH;
cairo_ft_scaled_font_unlock_face(aScaledFont);
mTypeface = SkCreateTypefaceFromCairoFont(fontFace, (SkTypeface::Style)style, isFixedWidth);
#endif
}
}
}

50
gfx/2d/ScaledFontCairo.h Normal file
View File

@ -0,0 +1,50 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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/. */
#ifndef MOZILLA_GFX_SCALEDFONTCAIRO_H_
#define MOZILLA_GFX_SCALEDFONTCAIRO_H_
#include "ScaledFontBase.h"
#include "cairo.h"
namespace mozilla {
namespace gfx {
class ScaledFontCairo : public ScaledFontBase
{
public:
ScaledFontCairo(cairo_scaled_font_t* aScaledFont, Float aSize);
};
// We need to be able to tell Skia whether or not to use
// hinting when rendering text, so that the glyphs it renders
// are the same as what layout is expecting. At the moment, only
// Skia uses this class when rendering with FreeType, as gfxFT2Font
// is the only gfxFont that honours gfxPlatform::FontHintingEnabled().
class GlyphRenderingOptionsCairo : public GlyphRenderingOptions
{
public:
GlyphRenderingOptionsCairo()
: mHinting(FONT_HINTING_NORMAL)
, mAutoHinting(false)
{
}
void SetHinting(FontHinting aHinting) { mHinting = aHinting; }
void SetAutoHinting(bool aAutoHinting) { mAutoHinting = aAutoHinting; }
FontHinting GetHinting() const { return mHinting; }
bool GetAutoHinting() const { return mAutoHinting; }
virtual FontType GetType() const { return FONT_CAIRO; }
private:
FontHinting mHinting;
bool mAutoHinting;
};
}
}
#endif /* MOZILLA_GFX_SCALEDFONTCAIRO_H_ */

View File

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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 "ScaledFontFreetype.h"
#include "Logging.h"
#include "gfxFont.h"
#ifdef USE_SKIA
#include "skia/SkTypeface.h"
#endif
#include <string>
using namespace std;
namespace mozilla {
namespace gfx {
#ifdef USE_SKIA
static SkTypeface::Style
fontStyleToSkia(FontStyle aStyle)
{
switch (aStyle) {
case FONT_STYLE_NORMAL:
return SkTypeface::kNormal;
case FONT_STYLE_ITALIC:
return SkTypeface::kItalic;
case FONT_STYLE_BOLD:
return SkTypeface::kBold;
case FONT_STYLE_BOLD_ITALIC:
return SkTypeface::kBoldItalic;
}
gfxWarning() << "Unknown font style";
return SkTypeface::kNormal;
}
#endif
// Ideally we want to use FT_Face here but as there is currently no way to get
// an SkTypeface from an FT_Face we do this.
ScaledFontFreetype::ScaledFontFreetype(FontOptions* aFont, Float aSize)
: ScaledFontBase(aSize)
{
#ifdef USE_SKIA
mTypeface = SkTypeface::CreateFromName(aFont->mName.c_str(), fontStyleToSkia(aFont->mStyle));
#endif
}
}
}

View File

@ -1,24 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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/. */
#ifndef MOZILLA_GFX_SCALEDFONTFREETYPE_H_
#define MOZILLA_GFX_SCALEDFONTFREETYPE_H_
#include "ScaledFontBase.h"
namespace mozilla {
namespace gfx {
class ScaledFontFreetype : public ScaledFontBase
{
public:
ScaledFontFreetype(FontOptions* aFont, Float aSize);
};
}
}
#endif /* MOZILLA_GFX_SCALEDFONTFREETYPE_H_ */

View File

@ -88,6 +88,14 @@ enum FontStyle
FONT_STYLE_BOLD_ITALIC FONT_STYLE_BOLD_ITALIC
}; };
enum FontHinting
{
FONT_HINTING_NONE,
FONT_HINTING_LIGHT,
FONT_HINTING_NORMAL,
FONT_HINTING_FULL
};
enum CompositionOp { OP_OVER, OP_ADD, OP_ATOP, OP_OUT, OP_IN, OP_SOURCE, OP_DEST_IN, OP_DEST_OUT, OP_DEST_OVER, OP_DEST_ATOP, OP_XOR, enum CompositionOp { OP_OVER, OP_ADD, OP_ATOP, OP_OUT, OP_IN, OP_SOURCE, OP_DEST_IN, OP_DEST_OUT, OP_DEST_OVER, OP_DEST_ATOP, OP_XOR,
OP_MULTIPLY, OP_SCREEN, OP_OVERLAY, OP_DARKEN, OP_LIGHTEN, OP_COLOR_DODGE, OP_COLOR_BURN, OP_HARD_LIGHT, OP_SOFT_LIGHT, OP_DIFFERENCE, OP_EXCLUSION, OP_HUE, OP_SATURATION, OP_COLOR, OP_LUMINOSITY, OP_COUNT }; OP_MULTIPLY, OP_SCREEN, OP_OVERLAY, OP_DARKEN, OP_LIGHTEN, OP_COLOR_DODGE, OP_COLOR_BURN, OP_HARD_LIGHT, OP_SOFT_LIGHT, OP_DIFFERENCE, OP_EXCLUSION, OP_HUE, OP_SATURATION, OP_COLOR, OP_LUMINOSITY, OP_COUNT };
enum ExtendMode { EXTEND_CLAMP, EXTEND_REPEAT, EXTEND_REFLECT }; enum ExtendMode { EXTEND_CLAMP, EXTEND_REPEAT, EXTEND_REFLECT };

View File

@ -295,7 +295,7 @@ struct hb_set_t
{ {
for (unsigned int i = 0; i < ELTS; i++) for (unsigned int i = 0; i < ELTS; i++)
if (elts[i]) if (elts[i])
for (unsigned int j = 0; i < BITS; j++) for (unsigned int j = 0; j < BITS; j++)
if (elts[i] & (1 << j)) if (elts[i] & (1 << j))
return i * BITS + j; return i * BITS + j;
return SENTINEL; return SENTINEL;

View File

@ -68,7 +68,7 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
} }
void void
CanvasClient2D::Updated() CanvasClientWebGL::Updated()
{ {
mForwarder->UpdateTextureNoSwap(this, 1, mTextureClient->GetDescriptor()); mForwarder->UpdateTextureNoSwap(this, 1, mTextureClient->GetDescriptor());
} }

View File

@ -65,8 +65,6 @@ public:
} }
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer); virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer);
virtual void Updated() MOZ_OVERRIDE;
}; };
// Used for GL canvases where we don't need to do any readback, i.e., with a // Used for GL canvases where we don't need to do any readback, i.e., with a
@ -83,6 +81,7 @@ public:
} }
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer); virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer);
virtual void Updated() MOZ_OVERRIDE;
}; };
} }

View File

@ -299,14 +299,15 @@ CPPSRCS += \
SkFontHost_mac_coretext.cpp \ SkFontHost_mac_coretext.cpp \
SkStream_mac.cpp \ SkStream_mac.cpp \
SkTime_Unix.cpp \ SkTime_Unix.cpp \
SkThread_pthread.cpp \
$(NULL) $(NULL)
DEFINES += -DSK_USE_POSIX_THREADS=1
endif endif
ifeq (android,$(MOZ_WIDGET_TOOLKIT)) ifeq (android,$(MOZ_WIDGET_TOOLKIT))
CPPSRCS += \ CPPSRCS += \
SkDebug_android.cpp \ SkDebug_android.cpp \
SkFontHost_android_old.cpp \ SkFontHost_cairo.cpp \
SkFontHost_FreeType.cpp \
SkFontHost_FreeType_common.cpp \ SkFontHost_FreeType_common.cpp \
SkFontHost_tables.cpp \ SkFontHost_tables.cpp \
SkMMapStream.cpp \ SkMMapStream.cpp \
@ -314,27 +315,33 @@ CPPSRCS += \
SkThread_pthread.cpp \ SkThread_pthread.cpp \
$(NULL) $(NULL)
OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
DEFINES += -DSK_USE_POSIX_THREADS=1 DEFINES += -DSK_USE_POSIX_THREADS=1
EXPORTS_skia += \
include/ports/SkTypeface_cairo.h \
$(NULL)
OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(CAIRO_FT_CFLAGS)
else else
CPPSRCS += \ CPPSRCS += \
SkDebug_stdio.cpp \ SkDebug_stdio.cpp \
SkThread_none.cpp \
$(NULL) $(NULL)
endif endif
ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT)) ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
CPPSRCS += \ CPPSRCS += \
SkFontHost_FreeType.cpp \ SkFontHost_cairo.cpp \
SkFontHost_FreeType_common.cpp \ SkFontHost_FreeType_common.cpp \
SkFontHost_linux.cpp \
SkFontHost_tables.cpp \ SkFontHost_tables.cpp \
SkTime_Unix.cpp \ SkTime_Unix.cpp \
SkMMapStream.cpp \ SkMMapStream.cpp \
SkOSFile.cpp \ SkOSFile.cpp \
$(NULL) $(NULL)
OS_CXXFLAGS += $(MOZ_PANGO_CFLAGS) EXPORTS_skia += \
include/ports/SkTypeface_cairo.h \
$(NULL)
OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(CAIRO_FT_CFLAGS)
endif endif
ifeq (qt,$(MOZ_WIDGET_TOOLKIT)) ifeq (qt,$(MOZ_WIDGET_TOOLKIT))
@ -357,6 +364,9 @@ endif
ifeq (Linux,$(OS_TARGET)) ifeq (Linux,$(OS_TARGET))
DEFINES += -DSK_USE_POSIX_THREADS=1 DEFINES += -DSK_USE_POSIX_THREADS=1
CPPSRCS += \
SkThread_pthread.cpp \
$(NULL)
endif endif
ifeq (windows,$(MOZ_WIDGET_TOOLKIT)) ifeq (windows,$(MOZ_WIDGET_TOOLKIT))
@ -365,6 +375,7 @@ CPPSRCS += \
SkFontHost_tables.cpp \ SkFontHost_tables.cpp \
SkFontHost_sandbox_none.cpp \ SkFontHost_sandbox_none.cpp \
SkTime_win.cpp \ SkTime_win.cpp \
SkThread_win.cpp \
$(NULL) $(NULL)
DEFINES += -DSKIA_IMPLEMENTATION=1 -DGR_IMPLEMENTATION=1 DEFINES += -DSKIA_IMPLEMENTATION=1 -DGR_IMPLEMENTATION=1
endif endif

View File

@ -0,0 +1,11 @@
#ifndef SkTypeface_cairo_DEFINED
#define SkTypeface_cairo_DEFINED
#include <cairo.h>
#include "SkTypeface.h"
SK_API extern SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth);
#endif

View File

@ -0,0 +1,382 @@
/*
* Copyright 2012 Mozilla Foundation
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "cairo.h"
#include "cairo-ft.h"
#include "SkFontHost_FreeType_common.h"
#include "SkAdvancedTypefaceMetrics.h"
#include "SkFontHost.h"
#include "SkPath.h"
#include "SkScalerContext.h"
#include "SkTypefaceCache.h"
#include <ft2build.h>
#include FT_FREETYPE_H
static cairo_user_data_key_t kSkTypefaceKey;
class SkScalerContext_CairoFT : public SkScalerContext_FreeType_Base {
public:
SkScalerContext_CairoFT(const SkDescriptor* desc);
virtual ~SkScalerContext_CairoFT();
protected:
virtual unsigned generateGlyphCount() SK_OVERRIDE;
virtual uint16_t generateCharToGlyph(SkUnichar uniChar) SK_OVERRIDE;
virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE;
virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
virtual void generateImage(const SkGlyph& glyph, SkMaskGamma::PreBlend* maskPreBlend) SK_OVERRIDE;
virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
SkPaint::FontMetrics* my) SK_OVERRIDE;
virtual SkUnichar generateGlyphToChar(uint16_t glyph) SK_OVERRIDE;
private:
cairo_scaled_font_t* fScaledFont;
uint32_t fLoadGlyphFlags;
};
class CairoLockedFTFace {
public:
CairoLockedFTFace(cairo_scaled_font_t* scaledFont)
: fScaledFont(scaledFont)
, fFace(cairo_ft_scaled_font_lock_face(scaledFont))
{}
~CairoLockedFTFace()
{
cairo_ft_scaled_font_unlock_face(fScaledFont);
}
FT_Face getFace()
{
return fFace;
}
private:
cairo_scaled_font_t* fScaledFont;
FT_Face fFace;
};
class SkCairoFTTypeface : public SkTypeface {
public:
static SkTypeface* CreateTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth) {
SkASSERT(fontFace != NULL);
SkASSERT(cairo_font_face_get_type(fontFace) == CAIRO_FONT_TYPE_FT);
SkFontID newId = SkTypefaceCache::NewFontID();
return SkNEW_ARGS(SkCairoFTTypeface, (fontFace, style, newId, isFixedWidth));
}
cairo_font_face_t* getFontFace() {
return fFontFace;
}
private:
SkCairoFTTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, SkFontID id, bool isFixedWidth)
: SkTypeface(style, id, isFixedWidth)
, fFontFace(fontFace)
{
cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, this, NULL);
cairo_font_face_reference(fFontFace);
}
~SkCairoFTTypeface()
{
cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, NULL, NULL);
cairo_font_face_destroy(fFontFace);
}
cairo_font_face_t* fFontFace;
};
SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth)
{
SkTypeface* typeface = reinterpret_cast<SkTypeface*>(cairo_font_face_get_user_data(fontFace, &kSkTypefaceKey));
if (typeface) {
typeface->ref();
} else {
typeface = SkCairoFTTypeface::CreateTypeface(fontFace, style, isFixedWidth);
SkTypefaceCache::Add(typeface, style);
}
return typeface;
}
SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
const char famillyName[],
SkTypeface::Style style)
{
SkDEBUGFAIL("SkFontHost::FindTypeface unimplemented");
return NULL;
}
SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream*)
{
SkDEBUGFAIL("SkFontHost::CreateTypeface unimplemented");
return NULL;
}
SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*)
{
SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented");
return NULL;
}
// static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
uint32_t fontID,
SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
const uint32_t* glyphIDs,
uint32_t glyphIDsCount)
{
return NULL;
}
void SkFontHost::FilterRec(SkScalerContext::Rec* rec) {
}
///////////////////////////////////////////////////////////////////////////////
SkStream* SkFontHost::OpenStream(uint32_t uniqueID)
{
SkDEBUGFAIL("SkFontHost::OpenStream unimplemented");
return NULL;
}
size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
int32_t* index) {
SkDebugf("SkFontHost::GetFileName unimplemented\n");
return 0;
}
///////////////////////////////////////////////////////////////////////////////
void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream)
{
SkDEBUGFAIL("SkFontHost::Serialize unimplemented");
}
SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
SkDEBUGFAIL("SkFontHost::Deserialize unimplemented");
return NULL;
}
static bool isLCD(const SkScalerContext::Rec& rec) {
switch (rec.fMaskFormat) {
case SkMask::kLCD16_Format:
case SkMask::kLCD32_Format:
return true;
default:
return false;
}
}
///////////////////////////////////////////////////////////////////////////////
SkScalerContext_CairoFT::SkScalerContext_CairoFT(const SkDescriptor* desc)
: SkScalerContext_FreeType_Base(desc)
{
SkCairoFTTypeface* typeface = static_cast<SkCairoFTTypeface*>(SkTypefaceCache::FindByID(fRec.fFontID));
SkMatrix matrix;
fRec.getSingleMatrix(&matrix);
cairo_font_face_t* fontFace = typeface->getFontFace();
cairo_matrix_t fontMatrix, ctMatrix;
cairo_matrix_init(&fontMatrix, matrix.getScaleX(), matrix.getSkewY(), matrix.getSkewX(), matrix.getScaleY(), 0.0, 0.0);
cairo_matrix_init_scale(&ctMatrix, 1.0, 1.0);
// We need to ensure that the font options match for hinting, as generateMetrics()
// uses the fScaledFont which uses these font options
cairo_font_options_t *fontOptions = cairo_font_options_create();
FT_Int32 loadFlags = FT_LOAD_DEFAULT;
if (SkMask::kBW_Format == fRec.fMaskFormat) {
// See http://code.google.com/p/chromium/issues/detail?id=43252#c24
loadFlags = FT_LOAD_TARGET_MONO;
if (fRec.getHinting() == SkPaint::kNo_Hinting) {
cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
loadFlags = FT_LOAD_NO_HINTING;
}
} else {
switch (fRec.getHinting()) {
case SkPaint::kNo_Hinting:
loadFlags = FT_LOAD_NO_HINTING;
cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
break;
case SkPaint::kSlight_Hinting:
loadFlags = FT_LOAD_TARGET_LIGHT; // This implies FORCE_AUTOHINT
cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_SLIGHT);
break;
case SkPaint::kNormal_Hinting:
cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_MEDIUM);
if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) {
loadFlags = FT_LOAD_FORCE_AUTOHINT;
}
break;
case SkPaint::kFull_Hinting:
cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_FULL);
if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) {
loadFlags = FT_LOAD_FORCE_AUTOHINT;
}
if (isLCD(fRec)) {
if (SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag)) {
loadFlags = FT_LOAD_TARGET_LCD_V;
} else {
loadFlags = FT_LOAD_TARGET_LCD;
}
}
break;
default:
SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting());
break;
}
}
fScaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctMatrix, fontOptions);
if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) {
loadFlags |= FT_LOAD_NO_BITMAP;
}
// Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct
// advances, as fontconfig and cairo do.
// See http://code.google.com/p/skia/issues/detail?id=222.
loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
fLoadGlyphFlags = loadFlags;
}
SkScalerContext_CairoFT::~SkScalerContext_CairoFT()
{
cairo_scaled_font_destroy(fScaledFont);
}
SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc)
{
return SkNEW_ARGS(SkScalerContext_CairoFT, (desc));
}
SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID)
{
return 0;
}
#ifdef SK_BUILD_FOR_ANDROID
uint32_t SkFontHost::GetUnitsPerEm(SkFontID fontID) {
return 0;
}
#endif
unsigned SkScalerContext_CairoFT::generateGlyphCount()
{
CairoLockedFTFace faceLock(fScaledFont);
return faceLock.getFace()->num_glyphs;
}
uint16_t SkScalerContext_CairoFT::generateCharToGlyph(SkUnichar uniChar)
{
CairoLockedFTFace faceLock(fScaledFont);
return SkToU16(FT_Get_Char_Index(faceLock.getFace(), uniChar));
}
void SkScalerContext_CairoFT::generateAdvance(SkGlyph* glyph)
{
generateMetrics(glyph);
}
void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
{
SkASSERT(fScaledFont != NULL);
cairo_text_extents_t extents;
cairo_glyph_t cairoGlyph = { glyph->getGlyphID(fBaseGlyphCount), 0.0, 0.0 };
cairo_scaled_font_glyph_extents(fScaledFont, &cairoGlyph, 1, &extents);
glyph->fAdvanceX = SkDoubleToFixed(extents.x_advance);
glyph->fAdvanceY = SkDoubleToFixed(extents.y_advance);
glyph->fWidth = SkToU16(SkScalarCeil(extents.width));
glyph->fHeight = SkToU16(SkScalarCeil(extents.height));
glyph->fLeft = SkToS16(SkScalarCeil(extents.x_bearing));
glyph->fTop = SkToS16(SkScalarCeil(extents.y_bearing));
glyph->fLsbDelta = 0;
glyph->fRsbDelta = 0;
}
void SkScalerContext_CairoFT::generateImage(const SkGlyph& glyph, SkMaskGamma::PreBlend* maskPreBlend)
{
SkASSERT(fScaledFont != NULL);
CairoLockedFTFace faceLock(fScaledFont);
FT_Face face = faceLock.getFace();
FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFlags);
if (err != 0) {
memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
return;
}
generateGlyphImage(face, glyph, maskPreBlend);
}
void SkScalerContext_CairoFT::generatePath(const SkGlyph& glyph, SkPath* path)
{
SkASSERT(fScaledFont != NULL);
CairoLockedFTFace faceLock(fScaledFont);
FT_Face face = faceLock.getFace();
SkASSERT(&glyph && path);
uint32_t flags = fLoadGlyphFlags;
flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline)
FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), flags);
if (err != 0) {
path->reset();
return;
}
generateGlyphPath(face, glyph, path);
}
void SkScalerContext_CairoFT::generateFontMetrics(SkPaint::FontMetrics* mx,
SkPaint::FontMetrics* my)
{
}
SkUnichar SkScalerContext_CairoFT::generateGlyphToChar(uint16_t glyph)
{
SkASSERT(fScaledFont != NULL);
CairoLockedFTFace faceLock(fScaledFont);
FT_Face face = faceLock.getFace();
FT_UInt glyphIndex;
SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex);
while (glyphIndex != 0) {
if (glyphIndex == glyph) {
return charCode;
}
charCode = FT_Get_Next_Char(face, charCode, &glyphIndex);
}
return 0;
}
#ifdef SK_BUILD_FOR_ANDROID
SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID,
SkFontID origFontID) {
return NULL;
}
#endif

View File

@ -322,16 +322,13 @@ TemporaryRef<ScaledFont>
gfxAndroidPlatform::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont) gfxAndroidPlatform::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont)
{ {
NativeFont nativeFont; NativeFont nativeFont;
if (aTarget->GetType() == BACKEND_CAIRO) { if (aTarget->GetType() == BACKEND_CAIRO || aTarget->GetType() == BACKEND_SKIA) {
nativeFont.mType = NATIVE_FONT_CAIRO_FONT_FACE; nativeFont.mType = NATIVE_FONT_CAIRO_FONT_FACE;
nativeFont.mFont = NULL; nativeFont.mFont = aFont->GetCairoScaledFont();
return Factory::CreateScaledFontWithCairo(nativeFont, aFont->GetAdjustedSize(), aFont->GetCairoScaledFont()); return Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
} }
NS_ASSERTION(aFont->GetType() == gfxFont::FONT_TYPE_FT2, "Expecting Freetype font"); return nullptr;
nativeFont.mType = NATIVE_FONT_SKIA_FONT_FACE;
nativeFont.mFont = static_cast<gfxFT2FontBase*>(aFont)->GetFontOptions();
return Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
} }
bool bool

View File

@ -36,6 +36,7 @@
#include "prinit.h" #include "prinit.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/gfx/2D.h"
// rounding and truncation functions for a Freetype floating point number // rounding and truncation functions for a Freetype floating point number
// (FT26Dot6) stored in a 32bit integer with high 26 bits for the integer // (FT26Dot6) stored in a 32bit integer with high 26 bits for the integer
@ -659,3 +660,21 @@ gfxFT2Font::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
aSizes->mFontInstances += aMallocSizeOf(this); aSizes->mFontInstances += aMallocSizeOf(this);
SizeOfExcludingThis(aMallocSizeOf, aSizes); SizeOfExcludingThis(aMallocSizeOf, aSizes);
} }
#ifdef USE_SKIA
mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions>
gfxFT2Font::GetGlyphRenderingOptions()
{
mozilla::gfx::FontHinting hinting;
if (gfxPlatform::GetPlatform()->FontHintingEnabled()) {
hinting = mozilla::gfx::FONT_HINTING_NORMAL;
} else {
hinting = mozilla::gfx::FONT_HINTING_NONE;
}
// We don't want to force the use of the autohinter over the font's built in hints
return mozilla::gfx::Factory::CreateCairoGlyphRenderingOptions(hinting, false);
}
#endif

View File

@ -68,6 +68,10 @@ public: // new functions
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf, virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontCacheSizes* aSizes) const; FontCacheSizes* aSizes) const;
#ifdef USE_SKIA
virtual mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions> GetGlyphRenderingOptions();
#endif
protected: protected:
virtual bool ShapeText(gfxContext *aContext, virtual bool ShapeText(gfxContext *aContext,
const PRUnichar *aText, const PRUnichar *aText,

View File

@ -777,6 +777,10 @@ public:
return mPangoFont; return mPangoFont;
} }
#ifdef USE_SKIA
virtual mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions> GetGlyphRenderingOptions();
#endif
protected: protected:
virtual bool ShapeText(gfxContext *aContext, virtual bool ShapeText(gfxContext *aContext,
const PRUnichar *aText, const PRUnichar *aText,
@ -3231,3 +3235,36 @@ ApplyGdkScreenFontOptions(FcPattern *aPattern)
} }
#endif // MOZ_WIDGET_GTK2 #endif // MOZ_WIDGET_GTK2
#ifdef USE_SKIA
mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions>
gfxFcFont::GetGlyphRenderingOptions()
{
cairo_scaled_font_t *scaled_font = CairoScaledFont();
cairo_font_options_t *options = cairo_font_options_create();
cairo_scaled_font_get_font_options(scaled_font, options);
cairo_hint_style_t hint_style = cairo_font_options_get_hint_style(options);
cairo_font_options_destroy(options);
mozilla::gfx::FontHinting hinting;
switch (hint_style) {
case CAIRO_HINT_STYLE_NONE:
hinting = mozilla::gfx::FONT_HINTING_NONE;
break;
case CAIRO_HINT_STYLE_SLIGHT:
hinting = mozilla::gfx::FONT_HINTING_LIGHT;
break;
case CAIRO_HINT_STYLE_FULL:
hinting = mozilla::gfx::FONT_HINTING_FULL;
break;
default:
hinting = mozilla::gfx::FONT_HINTING_NORMAL;
break;
}
// We don't want to force the use of the autohinter over the font's built in hints
return mozilla::gfx::Factory::CreateCairoGlyphRenderingOptions(hinting, false);
}
#endif

View File

@ -758,13 +758,13 @@ TemporaryRef<ScaledFont>
gfxPlatformGtk::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont) gfxPlatformGtk::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont)
{ {
NativeFont nativeFont; NativeFont nativeFont;
if (aTarget->GetType() == BACKEND_CAIRO) {
if (aTarget->GetType() == BACKEND_CAIRO || aTarget->GetType() == BACKEND_SKIA) {
nativeFont.mType = NATIVE_FONT_CAIRO_FONT_FACE; nativeFont.mType = NATIVE_FONT_CAIRO_FONT_FACE;
nativeFont.mFont = NULL; nativeFont.mFont = aFont->GetCairoScaledFont();
return Factory::CreateScaledFontWithCairo(nativeFont, aFont->GetAdjustedSize(), aFont->GetCairoScaledFont()); return Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
} }
NS_ASSERTION(aFont->GetType() == gfxFont::FONT_TYPE_FT2, "Expecting Freetype font");
nativeFont.mType = NATIVE_FONT_SKIA_FONT_FACE; return NULL;
nativeFont.mFont = static_cast<gfxFT2FontBase*>(aFont)->GetFontOptions();
return Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
} }

View File

@ -48,7 +48,7 @@ private:
bool bool
DispatchRILEvent::RunTask(JSContext *aCx) DispatchRILEvent::RunTask(JSContext *aCx)
{ {
JSObject *obj = JS_GetGlobalObject(aCx); JSObject *obj = JS_GetGlobalForScopeChain(aCx);
JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize); JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize);
if (!array) { if (!array) {

View File

@ -28,7 +28,7 @@ namespace {
class AutoResolveFlag class AutoResolveFlag
{ {
JSObject* mObj; Rooted<JSObject*> mObj;
unsigned mOldFlags; unsigned mOldFlags;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
@ -46,9 +46,9 @@ namespace {
public: public:
AutoResolveFlag(JSObject* obj AutoResolveFlag(JSContext *cx, JSObject* obj
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mObj(obj) : mObj(cx, obj)
, mOldFlags(SetFlags(obj, GetFlags(obj) | CPOW_FLAG_RESOLVING)) , mOldFlags(SetFlags(obj, GetFlags(obj) | CPOW_FLAG_RESOLVING))
{ {
MOZ_GUARD_OBJECT_NOTIFIER_INIT; MOZ_GUARD_OBJECT_NOTIFIER_INIT;
@ -101,7 +101,7 @@ ObjectWrapperParent::CheckOperation(JSContext* cx,
switch (status->type()) { switch (status->type()) {
case OperationStatus::TJSVariant: case OperationStatus::TJSVariant:
{ {
JS::RootedValue thrown(cx); Rooted<Value> thrown(cx);
if (jsval_from_JSVariant(cx, status->get_JSVariant(), thrown.address())) if (jsval_from_JSVariant(cx, status->get_JSVariant(), thrown.address()))
JS_SetPendingException(cx, thrown); JS_SetPendingException(cx, thrown);
*status = JS_FALSE; *status = JS_FALSE;
@ -181,7 +181,7 @@ ObjectWrapperParent::GetJSObject(JSContext* cx) const
static ObjectWrapperParent* static ObjectWrapperParent*
Unwrap(JSContext* cx, JSObject* objArg) Unwrap(JSContext* cx, JSObject* objArg)
{ {
RootedObject obj(cx, objArg), proto(cx); Rooted<JSObject*> obj(cx, objArg), proto(cx);
while (js::GetObjectClass(obj) != &ObjectWrapperParent::sCPOW_JSClass) { while (js::GetObjectClass(obj) != &ObjectWrapperParent::sCPOW_JSClass) {
if (!js::GetObjectProto(cx, obj, &proto) || !proto) if (!js::GetObjectProto(cx, obj, &proto) || !proto)
return NULL; return NULL;
@ -285,7 +285,7 @@ ObjectWrapperParent::boolean_from_JSVariant(JSContext* cx, const JSVariant& from
*to = false; *to = false;
return true; return true;
case JSVariant::TPObjectWrapperParent: { case JSVariant::TPObjectWrapperParent: {
JS::Rooted<JS::Value> v(cx); Rooted<Value> v(cx);
if (!jsval_from_PObjectWrapperParent(cx, from.get_PObjectWrapperParent(), v.address())) if (!jsval_from_PObjectWrapperParent(cx, from.get_PObjectWrapperParent(), v.address()))
return false; return false;
*to = JS::ToBoolean(v); *to = JS::ToBoolean(v);
@ -332,7 +332,7 @@ JSObject_to_PObjectWrapperParent(JSContext* cx, JSObject* from, PObjectWrapperPa
ObjectWrapperParent:: ObjectWrapperParent::
JSObject_from_PObjectWrapperParent(JSContext* cx, JSObject_from_PObjectWrapperParent(JSContext* cx,
const PObjectWrapperParent* from, const PObjectWrapperParent* from,
JS::MutableHandleObject to) MutableHandleObject to)
{ {
const ObjectWrapperParent* owp = const ObjectWrapperParent* owp =
static_cast<const ObjectWrapperParent*>(from); static_cast<const ObjectWrapperParent*>(from);
@ -348,7 +348,7 @@ jsval_from_PObjectWrapperParent(JSContext* cx,
const PObjectWrapperParent* from, const PObjectWrapperParent* from,
jsval* to) jsval* to)
{ {
JS::RootedObject obj(cx); Rooted<JSObject*> obj(cx);
if (!JSObject_from_PObjectWrapperParent(cx, from, &obj)) if (!JSObject_from_PObjectWrapperParent(cx, from, &obj))
return false; return false;
*to = OBJECT_TO_JSVAL(obj); *to = OBJECT_TO_JSVAL(obj);
@ -530,7 +530,7 @@ ObjectWrapperParent::NewEnumerateNext(JSContext* cx, jsval* statep, jsid* idp)
jsid_from_nsString(cx, out_id, idp)) jsid_from_nsString(cx, out_id, idp))
{ {
JSObject* obj = GetJSObject(cx); JSObject* obj = GetJSObject(cx);
JS::Rooted<AutoResolveFlag> arf(cx, obj); AutoResolveFlag arf(cx, obj);
return JS_DefinePropertyById(cx, obj, *idp, JSVAL_VOID, NULL, NULL, return JS_DefinePropertyById(cx, obj, *idp, JSVAL_VOID, NULL, NULL,
JSPROP_ENUMERATE); JSPROP_ENUMERATE);
} }
@ -578,7 +578,7 @@ ObjectWrapperParent::CPOW_NewEnumerate(JSContext *cx, JSHandleObject obj,
/*static*/ JSBool /*static*/ JSBool
ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id,
unsigned flags, JS::MutableHandleObject objp) unsigned flags, MutableHandleObject objp)
{ {
CPOW_LOG(("Calling CPOW_NewResolve (%s)...", CPOW_LOG(("Calling CPOW_NewResolve (%s)...",
JSVAL_TO_CSTR(cx, id))); JSVAL_TO_CSTR(cx, id)));
@ -604,8 +604,8 @@ ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSHandleObject obj, JSHandle
return JS_FALSE; return JS_FALSE;
if (objp) { if (objp) {
JS::Rooted<AutoResolveFlag> arf(cx, objp.get()); AutoResolveFlag arf(cx, objp.get());
JS::RootedObject obj2(cx, objp); Rooted<JSObject*> obj2(cx, objp);
JS_DefinePropertyById(cx, obj2, id, JSVAL_VOID, NULL, NULL, JS_DefinePropertyById(cx, obj2, id, JSVAL_VOID, NULL, NULL,
JSPROP_ENUMERATE); JSPROP_ENUMERATE);
} }
@ -647,7 +647,7 @@ ObjectWrapperParent::CPOW_Call(JSContext* cx, unsigned argc, jsval* vp)
{ {
CPOW_LOG(("Calling CPOW_Call...")); CPOW_LOG(("Calling CPOW_Call..."));
JS::RootedObject thisobj(cx, JS_THIS_OBJECT(cx, vp)); Rooted<JSObject*> thisobj(cx, JS_THIS_OBJECT(cx, vp));
if (!thisobj) if (!thisobj)
return JS_FALSE; return JS_FALSE;

View File

@ -184,30 +184,6 @@ CPPSRCS += TraceLogging.cpp
endif endif
ifdef ENABLE_METHODJIT
###############################################
# BEGIN include sources for the method JIT
#
VPATH += $(srcdir)/methodjit
CPPSRCS += MethodJIT.cpp \
StubCalls.cpp \
Compiler.cpp \
FrameState.cpp \
FastArithmetic.cpp \
FastBuiltins.cpp \
FastOps.cpp \
LoopState.cpp \
StubCompiler.cpp \
MonoIC.cpp \
PolyIC.cpp \
ImmutableSync.cpp \
InvokeHelpers.cpp \
Retcon.cpp \
TrampolineCompiler.cpp \
$(NULL)
# Ion # Ion
ifdef ENABLE_ION ifdef ENABLE_ION
VPATH += $(srcdir)/ion VPATH += $(srcdir)/ion
@ -336,17 +312,6 @@ CPPSRCS += Lowering-arm.cpp \
endif #ENABLE_ION endif #ENABLE_ION
endif endif
endif #ENABLE_ION endif #ENABLE_ION
ifeq (sparc, $(findstring sparc,$(TARGET_CPU)))
ASFILES += TrampolineSparc.s
endif
ifeq (mips, $(findstring mips,$(TARGET_CPU)))
CPPSRCS += TrampolineMIPS.cpp
endif
#
# END enclude sources for the method JIT
#############################################
endif
############################################### ###############################################
# BEGIN include sources for the Nitro assembler # BEGIN include sources for the Nitro assembler
@ -366,10 +331,6 @@ CPPSRCS += ExecutableAllocator.cpp \
YarrCanonicalizeUCS2.cpp \ YarrCanonicalizeUCS2.cpp \
$(NONE) $(NONE)
ifdef ENABLE_METHODJIT_SPEW
CPPSRCS += Logging.cpp
endif
ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH))) ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
CPPSRCS += ExecutableAllocatorPosix.cpp \ CPPSRCS += ExecutableAllocatorPosix.cpp \
OSAllocatorPosix.cpp \ OSAllocatorPosix.cpp \
@ -386,9 +347,8 @@ CPPSRCS += ExecutableAllocatorOS2.cpp \
$(NONE) $(NONE)
endif endif
ifneq (,$(ENABLE_METHODJIT)$(ENABLE_ION)$(ENABLE_YARR_JIT)) ifneq (,$(ENABLE_ION)$(ENABLE_YARR_JIT))
VPATH += $(srcdir)/assembler/assembler \ VPATH += $(srcdir)/assembler/assembler \
$(srcdir)/methodjit \
$(NONE) $(NONE)
CPPSRCS += ARMAssembler.cpp \ CPPSRCS += ARMAssembler.cpp \
@ -1000,34 +960,12 @@ selfhosted.out.h: $(selfhosted_out_h_deps)
# the code in js/src/assembler. # the code in js/src/assembler.
CXXFLAGS += -DUSE_SYSTEM_MALLOC=1 -DENABLE_ASSEMBLER=1 CXXFLAGS += -DUSE_SYSTEM_MALLOC=1 -DENABLE_ASSEMBLER=1
ifneq (,$(ENABLE_YARR_JIT)$(ENABLE_METHODJIT)) ifneq (,$(ENABLE_YARR_JIT))
CXXFLAGS += -DENABLE_JIT=1 CXXFLAGS += -DENABLE_JIT=1
endif endif
INCLUDES += -I$(srcdir)/assembler -I$(srcdir)/yarr INCLUDES += -I$(srcdir)/assembler -I$(srcdir)/yarr
ifdef ENABLE_METHODJIT
# Build a standalone test program that exercises the assembler
# sources a bit.
TESTMAIN_OBJS = \
Assertions.$(OBJ_SUFFIX) \
ExecutableAllocator.$(OBJ_SUFFIX) \
ARMAssembler.$(OBJ_SUFFIX) \
MacroAssemblerARM.$(OBJ_SUFFIX) \
TestMain.$(OBJ_SUFFIX) \
jsutil.$(OBJ_SUFFIX) \
jslog2.$(OBJ_SUFFIX)
ifeq ($(OS_ARCH),WINNT)
TESTMAIN_OBJS += ExecutableAllocatorWin.$(OBJ_SUFFIX)
else
TESTMAIN_OBJS += ExecutableAllocatorPosix.$(OBJ_SUFFIX)
endif
TestMain$(HOST_BIN_SUFFIX): $(TESTMAIN_OBJS)
$(CXX) -o TestMain$(HOST_BIN_SUFFIX) $(TESTMAIN_OBJS)
endif
# #
# END kludges for the Nitro assembler # END kludges for the Nitro assembler
############################################### ###############################################

View File

@ -45,7 +45,6 @@
#include "ion/IonSpewer.h" #include "ion/IonSpewer.h"
#include "js/RootingAPI.h" #include "js/RootingAPI.h"
#include "methodjit/Logging.h"
#define PRETTY_PRINT_OFFSET(os) (((os)<0)?"-":""), (((os)<0)?-(os):(os)) #define PRETTY_PRINT_OFFSET(os) (((os)<0)?"-":""), (((os)<0)?-(os):(os))
@ -286,8 +285,7 @@ namespace JSC {
__attribute__ ((format (printf, 2, 3))) __attribute__ ((format (printf, 2, 3)))
#endif #endif
{ {
if (printer || if (printer
js::IsJaegerSpewChannelActive(js::JSpew_Insns)
#ifdef JS_ION #ifdef JS_ION
|| js::ion::IonSpewEnabled(js::ion::IonSpew_Codegen) || js::ion::IonSpewEnabled(js::ion::IonSpew_Codegen)
#endif #endif
@ -306,14 +304,8 @@ namespace JSC {
if (printer) if (printer)
printer->printf("%s\n", buf); printer->printf("%s\n", buf);
// The assembler doesn't know which compiler it is for, so if
// both JM and Ion spew are on, just print via one channel
// (Use JM to pick up isOOLPath).
if (js::IsJaegerSpewChannelActive(js::JSpew_Insns))
js::JaegerSpew(js::JSpew_Insns, "%s %s\n", isOOLPath ? ">" : " ", buf);
#ifdef JS_ION #ifdef JS_ION
else js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
#endif #endif
} }
} }
@ -324,12 +316,8 @@ namespace JSC {
__attribute__ ((format (printf, 1, 2))) __attribute__ ((format (printf, 1, 2)))
#endif #endif
{ {
if (js::IsJaegerSpewChannelActive(js::JSpew_Insns)
#ifdef JS_ION #ifdef JS_ION
|| js::ion::IonSpewEnabled(js::ion::IonSpew_Codegen) if (js::ion::IonSpewEnabled(js::ion::IonSpew_Codegen)) {
#endif
)
{
char buf[200]; char buf[200];
va_list va; va_list va;
@ -337,15 +325,10 @@ namespace JSC {
int i = vsnprintf(buf, sizeof(buf), fmt, va); int i = vsnprintf(buf, sizeof(buf), fmt, va);
va_end(va); va_end(va);
if (i > -1) { if (i > -1)
if (js::IsJaegerSpewChannelActive(js::JSpew_Insns)) js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
js::JaegerSpew(js::JSpew_Insns, " %s\n", buf);
#ifdef JS_ION
else
js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
#endif
}
} }
#endif
} }
}; };

View File

@ -39,7 +39,6 @@
#include "assembler/wtf/SegmentedVector.h" #include "assembler/wtf/SegmentedVector.h"
#include "assembler/wtf/Assertions.h" #include "assembler/wtf/Assertions.h"
#include "methodjit/Logging.h"
#include "jsnum.h" #include "jsnum.h"
#define ASSEMBLER_HAS_CONSTANT_POOL 1 #define ASSEMBLER_HAS_CONSTANT_POOL 1

View File

@ -16,7 +16,6 @@
#include "jswrapper.h" #include "jswrapper.h"
#include "builtin/TestingFunctions.h" #include "builtin/TestingFunctions.h"
#include "methodjit/MethodJIT.h"
#include "vm/ForkJoin.h" #include "vm/ForkJoin.h"
#include "vm/Stack-inl.h" #include "vm/Stack-inl.h"
@ -170,14 +169,6 @@ GetBuildConfiguration(JSContext *cx, unsigned argc, jsval *vp)
if (!JS_SetProperty(cx, info, "oom-backtraces", &value)) if (!JS_SetProperty(cx, info, "oom-backtraces", &value))
return false; return false;
#ifdef JS_METHODJIT
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "methodjit", &value))
return false;
#ifdef ENABLE_PARALLEL_JS #ifdef ENABLE_PARALLEL_JS
value = BooleanValue(true); value = BooleanValue(true);
#else #else
@ -816,45 +807,6 @@ DumpHeapComplete(JSContext *cx, unsigned argc, jsval *vp)
return true; return true;
} }
JSBool
MJitChunkLimit(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (argc != 1) {
RootedObject callee(cx, &args.callee());
ReportUsageError(cx, callee, "Wrong number of arguments");
return JS_FALSE;
}
if (cx->runtime->alwaysPreserveCode) {
JS_ReportError(cx, "Can't change chunk limit after gcPreserveCode()");
return JS_FALSE;
}
for (CompartmentsIter c(cx->runtime); !c.done(); c.next()) {
if (c->lastAnimationTime != 0) {
JS_ReportError(cx, "Can't change chunk limit if code may be preserved");
return JS_FALSE;
}
}
double t;
if (!JS_ValueToNumber(cx, args[0], &t))
return JS_FALSE;
#ifdef JS_METHODJIT
mjit::SetChunkLimit((uint32_t) t);
#endif
// Clear out analysis information which might refer to code compiled with
// the previous chunk limit.
JS_GC(cx->runtime);
vp->setUndefined();
return true;
}
static JSBool static JSBool
Terminate(JSContext *cx, unsigned arg, jsval *vp) Terminate(JSContext *cx, unsigned arg, jsval *vp)
{ {
@ -1056,10 +1008,6 @@ static JSFunctionSpecWithHelp TestingFunctions[] = {
"dumpHeapComplete([filename])", "dumpHeapComplete([filename])",
" Dump reachable and unreachable objects to a file."), " Dump reachable and unreachable objects to a file."),
JS_FN_HELP("mjitChunkLimit", MJitChunkLimit, 1, 0,
"mjitChunkLimit(N)",
" Specify limit on compiled chunk size during mjit compilation."),
JS_FN_HELP("terminate", Terminate, 0, 0, JS_FN_HELP("terminate", Terminate, 0, 0,
"terminate()", "terminate()",
" Terminate JavaScript execution, as if we had run out of\n" " Terminate JavaScript execution, as if we had run out of\n"

View File

@ -484,22 +484,7 @@ case "$target" in
AC_MSG_ERROR([The major versions of \$CC and \$CXX do not match.]) AC_MSG_ERROR([The major versions of \$CC and \$CXX do not match.])
fi fi
if test "$_CC_MAJOR_VERSION" = "14"; then if test "$_CC_MAJOR_VERSION" = "16"; then
dnl Require VC8SP1 or newer.
dnl VC8 is 14.00.50727.42, VC8SP1 is 14.00.50727.762.
if test "$_CC_RELEASE" -lt 50727 -o \
\( "$_CC_RELEASE" -eq 50727 -a "$_CC_BUILD" -lt 762 \); then
AC_MSG_ERROR([This version ($CC_VERSION) of the MSVC compiler is unsupported. You probably need to install Service Pack 1 of Visual Studio 2005. See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
fi
_CC_SUITE=8
AC_DEFINE(_CRT_SECURE_NO_DEPRECATE)
AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE)
elif test "$_CC_MAJOR_VERSION" = "15"; then
_CC_SUITE=9
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
elif test "$_CC_MAJOR_VERSION" = "16"; then
_CC_SUITE=10 _CC_SUITE=10
AC_DEFINE(_CRT_SECURE_NO_WARNINGS) AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS) AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
@ -2168,23 +2153,6 @@ MOZ_ARG_DISABLE_BOOL(ion,
[ --disable-ion Disable use of the IonMonkey JIT], [ --disable-ion Disable use of the IonMonkey JIT],
ENABLE_ION= ) ENABLE_ION= )
MOZ_ARG_DISABLE_BOOL(methodjit,
[ --disable-methodjit Disable method JIT support],
ENABLE_METHODJIT= )
MOZ_ARG_DISABLE_BOOL(monoic,
[ --disable-monoic Disable use of MICs by JIT compiler],
ENABLE_MONOIC= )
MOZ_ARG_DISABLE_BOOL(polyic,
[ --disable-polyic Disable use of PICs by JIT compiler],
ENABLE_POLYIC= )
MOZ_ARG_ENABLE_BOOL(methodjit-spew,
[ --enable-methodjit-spew Enable method JIT spew support],
ENABLE_METHODJIT_SPEW=1,
ENABLE_METHODJIT_SPEW= )
MOZ_ARG_DISABLE_BOOL(yarr-jit, MOZ_ARG_DISABLE_BOOL(yarr-jit,
[ --disable-yarr-jit Disable YARR JIT support], [ --disable-yarr-jit Disable YARR JIT support],
ENABLE_YARR_JIT= ) ENABLE_YARR_JIT= )

View File

@ -63,6 +63,7 @@ var ignoreCallees = {
"js::ion::MDefinition.opName" : true, // macro generated virtuals just return a constant "js::ion::MDefinition.opName" : true, // macro generated virtuals just return a constant
"js::ion::LInstruction.getDef" : true, // virtual but no implementation can GC "js::ion::LInstruction.getDef" : true, // virtual but no implementation can GC
"js::ion::IonCache.kind" : true, // macro generated virtuals just return a constant "js::ion::IonCache.kind" : true, // macro generated virtuals just return a constant
"icu_50::UObject.__deleting_dtor" : true, // destructors in ICU code can't cause GC
}; };
function fieldCallCannotGC(csu, fullfield) function fieldCallCannotGC(csu, fullfield)
@ -133,7 +134,8 @@ function isRootedTypeName(name)
{ {
if (name == "mozilla::ErrorResult" || if (name == "mozilla::ErrorResult" ||
name == "js::frontend::TokenStream" || name == "js::frontend::TokenStream" ||
name == "js::frontend::TokenStream::Position") name == "js::frontend::TokenStream::Position" ||
name == "ModuleCompiler")
{ {
return true; return true;
} }

View File

@ -436,7 +436,7 @@ class StrictModeGetter {
// //
// The methods seek() and tell() allow to rescan from a previous visited // The methods seek() and tell() allow to rescan from a previous visited
// location of the buffer. // location of the buffer.
class TokenStream class MOZ_STACK_CLASS TokenStream
{ {
/* Unicode separators that are treated as line terminators, in addition to \n, \r */ /* Unicode separators that are treated as line terminators, in addition to \n, \r */
enum { enum {

View File

@ -11,7 +11,6 @@
#include "gc/Marking.h" #include "gc/Marking.h"
#include "gc/Nursery-inl.h" #include "gc/Nursery-inl.h"
#include "methodjit/MethodJIT.h"
#include "vm/Shape.h" #include "vm/Shape.h"
#include "jsobjinlines.h" #include "jsobjinlines.h"

View File

@ -769,12 +769,6 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
c->debugScopes->mark(trc); c->debugScopes->mark(trc);
} }
#ifdef JS_METHODJIT
/* We need to expand inline frames before stack scanning. */
for (ZonesIter zone(rt); !zone.done(); zone.next())
mjit::ExpandInlineFrames(zone);
#endif
rt->stackSpace.mark(trc); rt->stackSpace.mark(trc);
#ifdef JS_ION #ifdef JS_ION

View File

@ -66,13 +66,6 @@ Zone::init(JSContext *cx)
void void
Zone::setNeedsBarrier(bool needs, ShouldUpdateIon updateIon) Zone::setNeedsBarrier(bool needs, ShouldUpdateIon updateIon)
{ {
#ifdef JS_METHODJIT
/* ClearAllFrames calls compileBarriers() and needs the old value. */
bool old = compileBarriers();
if (compileBarriers(needs) != old)
mjit::ClearAllFrames(this);
#endif
#ifdef JS_ION #ifdef JS_ION
if (updateIon == UpdateIon && needs != ionUsingBarriers_) { if (updateIon == UpdateIon && needs != ionUsingBarriers_) {
ion::ToggleBarriers(this, needs); ion::ToggleBarriers(this, needs);
@ -156,41 +149,27 @@ Zone::sweep(FreeOp *fop, bool releaseTypes)
void void
Zone::discardJitCode(FreeOp *fop, bool discardConstraints) Zone::discardJitCode(FreeOp *fop, bool discardConstraints)
{ {
#ifdef JS_METHODJIT #ifdef JS_ION
/*
* Kick all frames on the stack into the interpreter, and release all JIT
* code in the compartment unless code is being preserved, in which case
* purge all caches in the JIT scripts. Even if we are not releasing all
* JIT code, we still need to release code for scripts which are in the
* middle of a native or getter stub call, as these stubs will have been
* redirected to the interpoline.
*/
mjit::ClearAllFrames(this);
if (isPreservingCode()) { if (isPreservingCode()) {
PurgeJITCaches(this); PurgeJITCaches(this);
} else { } else {
# ifdef JS_ION
# ifdef DEBUG # ifdef DEBUG
/* Assert no baseline scripts are marked as active. */ /* Assert no baseline scripts are marked as active. */
for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) { for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>(); JSScript *script = i.get<JSScript>();
JS_ASSERT_IF(script->hasBaselineScript(), !script->baselineScript()->active()); JS_ASSERT_IF(script->hasBaselineScript(), !script->baselineScript()->active());
} }
# endif # endif
/* Mark baseline scripts on the stack as active. */ /* Mark baseline scripts on the stack as active. */
ion::MarkActiveBaselineScripts(this); ion::MarkActiveBaselineScripts(this);
/* Only mark OSI points if code is being discarded. */ /* Only mark OSI points if code is being discarded. */
ion::InvalidateAll(fop, this); ion::InvalidateAll(fop, this);
# endif
for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) { for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>(); JSScript *script = i.get<JSScript>();
mjit::ReleaseScriptCode(fop, script);
# ifdef JS_ION
ion::FinishInvalidation(fop, script); ion::FinishInvalidation(fop, script);
/* /*
@ -198,7 +177,6 @@ Zone::discardJitCode(FreeOp *fop, bool discardConstraints)
* this also resets the active flag. * this also resets the active flag.
*/ */
ion::FinishDiscardBaselineScript(fop, script); ion::FinishDiscardBaselineScript(fop, script);
# endif
/* /*
* Use counts for scripts are reset on GC. After discarding code we * Use counts for scripts are reset on GC. After discarding code we
@ -209,14 +187,12 @@ Zone::discardJitCode(FreeOp *fop, bool discardConstraints)
} }
for (CompartmentsInZoneIter comp(this); !comp.done(); comp.next()) { for (CompartmentsInZoneIter comp(this); !comp.done(); comp.next()) {
#ifdef JS_ION
/* Free optimized baseline stubs. */ /* Free optimized baseline stubs. */
if (comp->ionCompartment()) if (comp->ionCompartment())
comp->ionCompartment()->optimizedStubSpace()->free(); comp->ionCompartment()->optimizedStubSpace()->free();
#endif
comp->types.sweepCompilerOutputs(fop, discardConstraints); comp->types.sweepCompilerOutputs(fop, discardConstraints);
} }
} }
#endif /* JS_METHODJIT */ #endif
} }

View File

@ -894,7 +894,16 @@ typedef Vector<MBasicBlock*,16> CaseVector;
// to add a new exit or reuse an existing one. The key is an ExitDescriptor // to add a new exit or reuse an existing one. The key is an ExitDescriptor
// (which holds the exit pairing) and the value is an index into the // (which holds the exit pairing) and the value is an index into the
// Vector<Exit> stored in the AsmJSModule. // Vector<Exit> stored in the AsmJSModule.
class ModuleCompiler //
// Rooting note: ModuleCompiler is a stack class that contains unrooted
// PropertyName (JSAtom) pointers. This is safe because it cannot be
// constructed without a TokenStream reference. TokenStream is itself a stack
// class that cannot be constructed without an AutoKeepAtoms being live on the
// stack, which prevents collection of atoms.
//
// ModuleCompiler is marked as rooted in the rooting analysis. Don't add
// non-JSAtom pointers, or this will break!
class MOZ_STACK_CLASS ModuleCompiler
{ {
public: public:
class Func class Func

View File

@ -900,7 +900,8 @@ HandleSignal(int signum, siginfo_t *info, void *ctx)
# endif # endif
} }
static struct sigaction sPrevHandler; static struct sigaction sPrevSegvHandler;
static struct sigaction sPrevBusHandler;
static void static void
AsmJSFaultHandler(int signum, siginfo_t *info, void *context) AsmJSFaultHandler(int signum, siginfo_t *info, void *context)
@ -915,13 +916,21 @@ AsmJSFaultHandler(int signum, siginfo_t *info, void *context)
// be re-executed which will crash in the normal way. The advantage to // be re-executed which will crash in the normal way. The advantage to
// doing this is that we remove ourselves from the crash stack which // doing this is that we remove ourselves from the crash stack which
// simplifies crash reports. Note: the order of these tests matter. // simplifies crash reports. Note: the order of these tests matter.
if (sPrevHandler.sa_flags & SA_SIGINFO) { struct sigaction* prevHandler = NULL;
sPrevHandler.sa_sigaction(signum, info, context); if (signum == SIGSEGV)
prevHandler = &sPrevSegvHandler;
else {
JS_ASSERT(signum == SIGBUS);
prevHandler = &sPrevBusHandler;
}
if (prevHandler->sa_flags & SA_SIGINFO) {
prevHandler->sa_sigaction(signum, info, context);
exit(signum); // backstop exit(signum); // backstop
} else if (sPrevHandler.sa_handler == SIG_DFL || sPrevHandler.sa_handler == SIG_IGN) { } else if (prevHandler->sa_handler == SIG_DFL || prevHandler->sa_handler == SIG_IGN) {
sigaction(signum, &sPrevHandler, NULL); sigaction(signum, prevHandler, NULL);
} else { } else {
sPrevHandler.sa_handler(signum); prevHandler->sa_handler(signum);
exit(signum); // backstop exit(signum); // backstop
} }
} }
@ -950,9 +959,9 @@ EnsureAsmJSSignalHandlersInstalled(JSRuntime *rt)
sigAction.sa_sigaction = &AsmJSFaultHandler; sigAction.sa_sigaction = &AsmJSFaultHandler;
sigemptyset(&sigAction.sa_mask); sigemptyset(&sigAction.sa_mask);
sigAction.sa_flags = SA_SIGINFO; sigAction.sa_flags = SA_SIGINFO;
if (sigaction(SIGSEGV, &sigAction, &sPrevHandler)) if (sigaction(SIGSEGV, &sigAction, &sPrevSegvHandler))
return false; return false;
if (sigaction(SIGBUS, &sigAction, &sPrevHandler)) if (sigaction(SIGBUS, &sigAction, &sPrevBusHandler))
return false; return false;
# endif # endif
@ -994,3 +1003,14 @@ js::TriggerOperationCallbackForAsmJSCode(JSRuntime *rt)
# endif # endif
#endif #endif
} }
#ifdef MOZ_ASAN
// When running with asm.js under AddressSanitizer, we need to explicitely
// tell AddressSanitizer to allow custom signal handlers because it will
// otherwise trigger ASan's SIGSEGV handler for the internal SIGSEGVs that
// asm.js would otherwise handle.
extern "C" MOZ_ASAN_BLACKLIST
const char* __asan_default_options() {
return "allow_user_segv_handler=1";
}
#endif

View File

@ -572,11 +572,6 @@ ion::CachedShapeGuardFailure()
script->failedShapeGuard = true; script->failedShapeGuard = true;
// Purge JM caches in the script and all inlined script, to avoid baking in
// the same shape guard next time.
for (size_t i = 0; i < script->ionScript()->scriptEntries(); i++)
mjit::PurgeCaches(script->ionScript()->getScript(i));
IonSpew(IonSpew_Invalidate, "Invalidating due to shape guard failure"); IonSpew(IonSpew_Invalidate, "Invalidating due to shape guard failure");
return Invalidate(cx, script); return Invalidate(cx, script);

View File

@ -190,23 +190,6 @@ BaselineCompiler::compile()
return Method_Compiled; return Method_Compiled;
} }
#ifdef DEBUG
#define SPEW_OPCODE() \
JS_BEGIN_MACRO \
if (IsJaegerSpewChannelActive(JSpew_JSOps)) { \
Sprinter sprinter(cx); \
sprinter.init(); \
RootedScript script_(cx, script); \
js_Disassemble1(cx, script_, pc, pc - script_->code, \
JS_TRUE, &sprinter); \
JaegerSpew(JSpew_JSOps, " %2u %s", \
(unsigned)frame.stackDepth(), sprinter.string()); \
} \
JS_END_MACRO;
#else
#define SPEW_OPCODE()
#endif /* DEBUG */
bool bool
BaselineCompiler::emitPrologue() BaselineCompiler::emitPrologue()
{ {
@ -539,7 +522,6 @@ BaselineCompiler::emitBody()
uint32_t emittedOps = 0; uint32_t emittedOps = 0;
while (true) { while (true) {
SPEW_OPCODE();
JSOp op = JSOp(*pc); JSOp op = JSOp(*pc);
IonSpew(IonSpew_BaselineOp, "Compiling op @ %d: %s", IonSpew(IonSpew_BaselineOp, "Compiling op @ %d: %s",
int(pc - script->code), js_CodeName[op]); int(pc - script->code), js_CodeName[op]);

View File

@ -7178,8 +7178,23 @@ ICCallScriptedCompiler::generateStubCode(MacroAssembler &masm)
Label skipThisReplace; Label skipThisReplace;
masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace); masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
Register scratchReg = JSReturnOperand.scratchReg();
// Current stack: [ ARGVALS..., ThisVal, ActualArgc, Callee, Descriptor ] // Current stack: [ ARGVALS..., ThisVal, ActualArgc, Callee, Descriptor ]
masm.loadValue(Address(BaselineStackReg, 3*sizeof(size_t)), JSReturnOperand); // However, we can't use this ThisVal, because it hasn't been traced. We need to use
// The ThisVal higher up the stack:
// Current stack: [ ThisVal, ARGVALS..., ...STUB FRAME...,
// ARGVALS..., ThisVal, ActualArgc, Callee, Descriptor ]
masm.loadPtr(Address(BaselineStackReg, 2*sizeof(size_t)), scratchReg);
// scratchReg now contains actualArgCount. Double it to account for skipping past two
// pushed copies of argument values. Additionally, we need to add:
// STUB_FRAME_SIZE + sizeof(ThisVal) + sizeof(size_t) + sizeof(void *) + sizoef(size_t)
// for: stub frame, this value, actual argc, callee, and descriptor
masm.lshiftPtr(Imm32(1), scratchReg);
BaseIndex reloadThisSlot(BaselineStackReg, scratchReg, TimesEight,
STUB_FRAME_SIZE + sizeof(Value) + 3*sizeof(size_t));
masm.loadValue(reloadThisSlot, JSReturnOperand);
#ifdef DEBUG #ifdef DEBUG
masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace); masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
masm.breakpoint(); masm.breakpoint();

View File

@ -45,7 +45,6 @@
#include "vm/Stack-inl.h" #include "vm/Stack-inl.h"
#include "ion/IonFrames-inl.h" #include "ion/IonFrames-inl.h"
#include "ion/CompilerRoot.h" #include "ion/CompilerRoot.h"
#include "methodjit/Retcon.h"
#include "ExecutionModeInlines.h" #include "ExecutionModeInlines.h"
#if JS_TRACE_LOGGING #if JS_TRACE_LOGGING
@ -1294,10 +1293,7 @@ AttachFinishedCompilations(JSContext *cx)
success = codegen->link(); success = codegen->link();
} }
if (success) { if (!success) {
if (script->hasIonScript())
mjit::DisableScriptCodeForIon(script, script->ionScript()->osrPc());
} else {
// Silently ignore OOM during code generation, we're at an // Silently ignore OOM during code generation, we're at an
// operation callback and can't propagate failures. // operation callback and can't propagate failures.
cx->clearPendingException(); cx->clearPendingException();
@ -1590,8 +1586,8 @@ Compile(JSContext *cx, HandleScript script, AbstractFramePtr fp, jsbytecode *osr
} }
if (executionMode == SequentialExecution) { if (executionMode == SequentialExecution) {
if (cx->methodJitEnabled || IsBaselineEnabled(cx)) { if (IsBaselineEnabled(cx)) {
// If JM is enabled we use getUseCount instead of incUseCount to avoid // If Baseline is enabled we use getUseCount instead of incUseCount to avoid
// bumping the use count twice. // bumping the use count twice.
if (script->getUseCount() < js_IonOptions.usesBeforeCompile) if (script->getUseCount() < js_IonOptions.usesBeforeCompile)
return Method_Skipped; return Method_Skipped;
@ -2297,8 +2293,6 @@ ion::Invalidate(types::TypeCompartment &types, FreeOp *fop,
for (size_t i = 0; i < invalid.length(); i++) { for (size_t i = 0; i < invalid.length(); i++) {
const types::CompilerOutput &co = *invalid[i].compilerOutput(types); const types::CompilerOutput &co = *invalid[i].compilerOutput(types);
switch (co.kind()) { switch (co.kind()) {
case types::CompilerOutput::MethodJIT:
break;
case types::CompilerOutput::Ion: case types::CompilerOutput::Ion:
case types::CompilerOutput::ParallelIon: case types::CompilerOutput::ParallelIon:
JS_ASSERT(co.isValid()); JS_ASSERT(co.isValid());
@ -2328,8 +2322,6 @@ ion::Invalidate(types::TypeCompartment &types, FreeOp *fop,
types::CompilerOutput &co = *invalid[i].compilerOutput(types); types::CompilerOutput &co = *invalid[i].compilerOutput(types);
ExecutionMode executionMode = SequentialExecution; ExecutionMode executionMode = SequentialExecution;
switch (co.kind()) { switch (co.kind()) {
case types::CompilerOutput::MethodJIT:
continue;
case types::CompilerOutput::Ion: case types::CompilerOutput::Ion:
break; break;
case types::CompilerOutput::ParallelIon: case types::CompilerOutput::ParallelIon:

View File

@ -7480,13 +7480,8 @@ IonBuilder::getPropTryInlineAccess(bool *emitted, HandlePropertyName name, Handl
return true; return true;
Vector<Shape *> shapes(cx); Vector<Shape *> shapes(cx);
if (Shape *objShape = mjit::GetPICSingleShape(cx, script(), pc, info().constructing())) { if (!inspector->maybeShapesForPropertyOp(pc, shapes))
if (!shapes.append(objShape)) return false;
return false;
} else {
if (!inspector->maybeShapesForPropertyOp(pc, shapes))
return false;
}
if (shapes.empty() || !CanInlinePropertyOpShapes(shapes)) if (shapes.empty() || !CanInlinePropertyOpShapes(shapes))
return true; return true;
@ -7682,13 +7677,8 @@ IonBuilder::jsop_setprop(HandlePropertyName name)
} }
Vector<Shape *> shapes(cx); Vector<Shape *> shapes(cx);
if (Shape *objShape = mjit::GetPICSingleShape(cx, script(), pc, info().constructing())) { if (!inspector->maybeShapesForPropertyOp(pc, shapes))
if (!shapes.append(objShape)) return false;
return false;
} else {
if (!inspector->maybeShapesForPropertyOp(pc, shapes))
return false;
}
if (!shapes.empty() && CanInlinePropertyOpShapes(shapes)) { if (!shapes.empty() && CanInlinePropertyOpShapes(shapes)) {
if (shapes.length() == 1) { if (shapes.length() == 1) {

View File

@ -2386,7 +2386,8 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
if (!cache.attachArgumentsElement(cx, ion, obj)) if (!cache.attachArgumentsElement(cx, ion, obj))
return false; return false;
attachedStub = true; attachedStub = true;
} else if (obj->isNative() && cache.monitoredResult()) { }
if (!attachedStub && obj->isNative() && cache.monitoredResult()) {
uint32_t dummy; uint32_t dummy;
if (idval.isString() && JSID_IS_ATOM(id) && !JSID_TO_ATOM(id)->isIndex(&dummy)) { if (idval.isString() && JSID_IS_ATOM(id) && !JSID_TO_ATOM(id)->isIndex(&dummy)) {
RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName()); RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName());
@ -2394,11 +2395,13 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
return false; return false;
attachedStub = true; attachedStub = true;
} }
} else if (!cache.hasDenseStub() && obj->isNative() && idval.isInt32()) { }
if (!attachedStub && !cache.hasDenseStub() && obj->isNative() && idval.isInt32()) {
if (!cache.attachDenseElement(cx, ion, obj, idval)) if (!cache.attachDenseElement(cx, ion, obj, idval))
return false; return false;
attachedStub = true; attachedStub = true;
} else if (obj->isTypedArray()) { }
if (!attachedStub && obj->isTypedArray()) {
if ((idval.isInt32()) || if ((idval.isInt32()) ||
(idval.isString() && GetIndexFromString(idval.toString()) != UINT32_MAX)) (idval.isString() && GetIndexFromString(idval.toString()) != UINT32_MAX))
{ {

View File

@ -426,8 +426,6 @@ LIRGenerator::visitApplyArgs(MApplyArgs *apply)
{ {
JS_ASSERT(apply->getFunction()->type() == MIRType_Object); JS_ASSERT(apply->getFunction()->type() == MIRType_Object);
JSFunction *target = apply->getSingleTarget();
// Assert if we cannot build a rectifier frame. // Assert if we cannot build a rectifier frame.
JS_ASSERT(CallTempReg0 != ArgumentsRectifierReg); JS_ASSERT(CallTempReg0 != ArgumentsRectifierReg);
JS_ASSERT(CallTempReg1 != ArgumentsRectifierReg); JS_ASSERT(CallTempReg1 != ArgumentsRectifierReg);
@ -447,7 +445,7 @@ LIRGenerator::visitApplyArgs(MApplyArgs *apply)
return false; return false;
// Bailout is only needed in the case of possible non-JSFunction callee. // Bailout is only needed in the case of possible non-JSFunction callee.
if (!target && !assignSnapshot(lir)) if (!apply->getSingleTarget() && !assignSnapshot(lir))
return false; return false;
if (!defineReturn(lir, apply)) if (!defineReturn(lir, apply))

View File

@ -120,8 +120,7 @@ MacroAssemblerX64::callWithABIPre(uint32_t *stackAdjust)
#ifdef DEBUG #ifdef DEBUG
{ {
Label good; Label good;
movl(rsp, rax); testq(rsp, Imm32(StackAlignment - 1));
testq(rax, Imm32(StackAlignment - 1));
j(Equal, &good); j(Equal, &good);
breakpoint(); breakpoint();
bind(&good); bind(&good);

View File

@ -149,8 +149,7 @@ MacroAssemblerX86::callWithABIPre(uint32_t *stackAdjust)
{ {
// Check call alignment. // Check call alignment.
Label good; Label good;
movl(esp, eax); testl(esp, Imm32(StackAlignment - 1));
testl(eax, Imm32(StackAlignment - 1));
j(Equal, &good); j(Equal, &good);
breakpoint(); breakpoint();
bind(&good); bind(&good);

View File

@ -142,21 +142,13 @@ def main(argv):
if options.tbpl: if options.tbpl:
# Running all bits would take forever. Instead, we test a few interesting combinations. # Running all bits would take forever. Instead, we test a few interesting combinations.
flags = [ flags = [
['--no-baseline', '--no-jm'],
['--ion-eager'], # implies --baseline-eager ['--ion-eager'], # implies --baseline-eager
['--no-baseline'],
['--no-baseline', '--ion-eager'],
['--baseline-eager'], ['--baseline-eager'],
['--baseline-eager', '--no-ti', '--no-fpu'], ['--baseline-eager', '--no-ti', '--no-fpu'],
# Below, equivalents the old shell flags: ,m,am,amd,n,mn,amn,amdn,mdn ['--no-baseline'],
['--no-baseline', '--no-ion', '--no-jm', '--no-ti'], ['--no-baseline', '--ion-eager'],
['--no-baseline', '--no-ion', '--no-ti'],
['--no-baseline', '--no-ion', '--no-ti', '--always-mjit', '--debugjit'],
['--no-baseline', '--no-ion', '--no-jm'],
['--no-baseline', '--no-ion'], ['--no-baseline', '--no-ion'],
['--no-baseline', '--no-ion', '--always-mjit'], ['--no-baseline', '--no-ion', '--no-ti'],
['--no-baseline', '--no-ion', '--always-mjit', '--debugjit'],
['--no-baseline', '--no-ion', '--debugjit']
] ]
for test in test_list: for test in test_list:
for variant in flags: for variant in flags:

View File

@ -5,7 +5,6 @@ function tryItOut(code) {
f = eval("(function(){" + code + "})") f = eval("(function(){" + code + "})")
for (e in f()) {} for (e in f()) {}
} }
mjitChunkLimit(25)
tryItOut("\ tryItOut("\
for each(x in[0,0,0,0,0,0,0]) {\ for each(x in[0,0,0,0,0,0,0]) {\
function f(b) {\ function f(b) {\

View File

@ -10,5 +10,5 @@ function g(code) {
evalcx("(function(){return" + code + "})()") evalcx("(function(){return" + code + "})()")
} catch (e) {} } catch (e) {}
} }
g("mjitChunkLimit(8)") g("")
g(" function(x,[]){NaN.x::c}()") g(" function(x,[]){NaN.x::c}()")

View File

@ -3,7 +3,6 @@
// Binary: cache/js-dbg-32-92fe907ddac8-linux // Binary: cache/js-dbg-32-92fe907ddac8-linux
// Flags: -m -n // Flags: -m -n
// //
mjitChunkLimit(31)
o = {} o = {}
o.valueOf = function() { o.valueOf = function() {
for (var p in undefined) { for (var p in undefined) {

View File

@ -5,7 +5,7 @@
var lfcode = new Array(); var lfcode = new Array();
lfcode.push("3"); lfcode.push("3");
lfcode.push("\ lfcode.push("\
evaluate(\"mjitChunkLimit(5)\");\ evaluate(\"\");\
function slice(a, b) {\ function slice(a, b) {\
return slice(index, ++(ArrayBuffer));\ return slice(index, ++(ArrayBuffer));\
}\ }\

View File

@ -8,6 +8,5 @@ Object.defineProperty(this, "t2", {
} }
}) })
h2 = {} h2 = {}
mjitChunkLimit(8)
h2.a = function() {} h2.a = function() {}
Object(t2) Object(t2)

View File

@ -7,8 +7,6 @@ function test(m) {
arr[1] = m; arr[1] = m;
} }
mjitChunkLimit(10);
arr = new Float64Array(2); arr = new Float64Array(2);
// run function a lot to trigger methodjit compile // run function a lot to trigger methodjit compile

View File

@ -1,4 +1,3 @@
mjitChunkLimit(42);
Function("\ Function("\
switch (/x/) {\ switch (/x/) {\
case 8:\ case 8:\

View File

@ -1,4 +1,3 @@
mjitChunkLimit(10);
function e() { function e() {
try { try {
var t = undefined; var t = undefined;

View File

@ -1,5 +1,3 @@
evaluate("mjitChunkLimit(5)");
expected = 100; expected = 100;
function slice(a, b) { function slice(a, b) {
return expected--; return expected--;

View File

@ -596,25 +596,6 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
*/ */
if (!script_->analyzedArgsUsage()) if (!script_->analyzedArgsUsage())
analyzeSSA(cx); analyzeSSA(cx);
/*
* If the script has JIT information (we are reanalyzing the script after
* a purge), add safepoints for the targets of any cross chunk edges in
* the script. These safepoints are normally added when the JITScript is
* constructed, but will have been lost during the purge.
*/
#ifdef JS_METHODJIT
mjit::JITScript *jit = NULL;
for (int constructing = 0; constructing <= 1 && !jit; constructing++) {
for (int barriers = 0; barriers <= 1 && !jit; barriers++)
jit = script_->getJIT((bool) constructing, (bool) barriers);
}
if (jit) {
mjit::CrossChunkEdge *edges = jit->edges();
for (size_t i = 0; i < jit->nedges; i++)
getCode(edges[i].target).safePoint = true;
}
#endif
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
@ -890,7 +871,7 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
ranLifetimes_ = true; ranLifetimes_ = true;
} }
#ifdef JS_METHODJIT_SPEW #ifdef DEBUG
void void
LifetimeVariable::print() const LifetimeVariable::print() const
{ {
@ -1106,21 +1087,6 @@ ScriptAnalysis::ensureVariable(LifetimeVariable &var, unsigned until)
var.ensured = true; var.ensured = true;
} }
void
ScriptAnalysis::clearAllocations()
{
/*
* Clear out storage used for register allocations in a compilation once
* that compilation has finished. Register allocations are only used for
* a single compilation.
*/
for (unsigned i = 0; i < script_->length; i++) {
Bytecode *code = maybeCode(i);
if (code)
code->allocation = NULL;
}
}
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
// SSA Analysis // SSA Analysis
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
@ -1841,13 +1807,9 @@ ScriptAnalysis::needsArgsObj(JSContext *cx, SeenVector &seen, SSAUseChain *use)
if (op == JSOP_POP || op == JSOP_POPN) if (op == JSOP_POP || op == JSOP_POPN)
return false; return false;
/* SplatApplyArgs can read fp->canonicalActualArg(i) directly. */ /* We can read the frame's arguments directly for f.apply(x, arguments). */
if (op == JSOP_FUNAPPLY && GET_ARGC(pc) == 2 && use->u.which == 0) { if (op == JSOP_FUNAPPLY && GET_ARGC(pc) == 2 && use->u.which == 0)
#ifdef JS_METHODJIT
JS_ASSERT(mjit::IsLowerableFunCallOrApply(pc));
#endif
return false; return false;
}
/* arguments[i] can read fp->canonicalActualArg(i) directly. */ /* arguments[i] can read fp->canonicalActualArg(i) directly. */
if (op == JSOP_GETELEM && use->u.which == 1) if (op == JSOP_GETELEM && use->u.which == 1)

View File

@ -25,9 +25,6 @@
class JSScript; class JSScript;
/* Forward declaration of downstream register allocations computed for join points. */
namespace js { namespace mjit { struct RegisterAllocation; } }
namespace js { namespace js {
namespace analyze { namespace analyze {
@ -125,11 +122,6 @@ class Bytecode
/* If this is a JSOP_LOOPHEAD or JSOP_LOOPENTRY, information about the loop. */ /* If this is a JSOP_LOOPHEAD or JSOP_LOOPENTRY, information about the loop. */
LoopAnalysis *loop; LoopAnalysis *loop;
/* --------- Lifetime analysis --------- */
/* Any allocation computed downstream for this bytecode. */
mjit::RegisterAllocation *allocation;
/* --------- SSA analysis --------- */ /* --------- SSA analysis --------- */
/* Generated location of each value popped by this bytecode. */ /* Generated location of each value popped by this bytecode. */
@ -513,7 +505,7 @@ struct LifetimeVariable
return offset; return offset;
} }
#ifdef JS_METHODJIT_SPEW #ifdef DEBUG
void print() const; void print() const;
#endif #endif
}; };
@ -995,14 +987,6 @@ class ScriptAnalysis
return v.phiNode()->uses; return v.phiNode()->uses;
} }
mjit::RegisterAllocation *&getAllocation(uint32_t offset) {
JS_ASSERT(offset < script_->length);
return getCode(offset).allocation;
}
mjit::RegisterAllocation *&getAllocation(const jsbytecode *pc) {
return getAllocation(pc - script_->code);
}
LoopAnalysis *getLoop(uint32_t offset) { LoopAnalysis *getLoop(uint32_t offset) {
JS_ASSERT(offset < script_->length); JS_ASSERT(offset < script_->length);
return getCode(offset).loop; return getCode(offset).loop;
@ -1051,8 +1035,6 @@ class ScriptAnalysis
void printSSA(JSContext *cx); void printSSA(JSContext *cx);
void printTypes(JSContext *cx); void printTypes(JSContext *cx);
void clearAllocations();
private: private:
void setOOM(JSContext *cx) { void setOOM(JSContext *cx) {
if (!outOfMemory) if (!outOfMemory)

View File

@ -131,10 +131,7 @@ ThrowHook(JSContext *cx, JSScript *, jsbytecode *, jsval *rval, void *closure)
BEGIN_TEST(testDebugger_throwHook) BEGIN_TEST(testDebugger_throwHook)
{ {
uint32_t newopts = CHECK(JS_SetDebugMode(cx, true));
JS_GetOptions(cx) | JSOPTION_METHODJIT | JSOPTION_METHODJIT_ALWAYS;
uint32_t oldopts = JS_SetOptions(cx, newopts);
CHECK(JS_SetThrowHook(rt, ThrowHook, NULL)); CHECK(JS_SetThrowHook(rt, ThrowHook, NULL));
EXEC("function foo() { throw 3 };\n" EXEC("function foo() { throw 3 };\n"
"for (var i = 0; i < 10; ++i) { \n" "for (var i = 0; i < 10; ++i) { \n"
@ -145,7 +142,6 @@ BEGIN_TEST(testDebugger_throwHook)
"}\n"); "}\n");
CHECK(called); CHECK(called);
CHECK(JS_SetThrowHook(rt, NULL, NULL)); CHECK(JS_SetThrowHook(rt, NULL, NULL));
JS_SetOptions(cx, oldopts);
return true; return true;
} }
END_TEST(testDebugger_throwHook) END_TEST(testDebugger_throwHook)

View File

@ -87,10 +87,9 @@
#if ENABLE_YARR_JIT #if ENABLE_YARR_JIT
#include "assembler/jit/ExecutableAllocator.h" #include "assembler/jit/ExecutableAllocator.h"
#include "methodjit/Logging.h"
#endif #endif
#ifdef JS_METHODJIT #ifdef JS_ION
#include "ion/Ion.h" #include "ion/Ion.h"
#endif #endif
@ -692,7 +691,7 @@ static const JSSecurityCallbacks NullSecurityCallbacks = { };
static bool static bool
JitSupportsFloatingPoint() JitSupportsFloatingPoint()
{ {
#if defined(JS_METHODJIT) || defined(JS_ION) #if defined(JS_ION)
if (!JSC::MacroAssembler().supportsFloatingPoint()) if (!JSC::MacroAssembler().supportsFloatingPoint())
return false; return false;
@ -739,9 +738,6 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
freeLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), freeLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
execAlloc_(NULL), execAlloc_(NULL),
bumpAlloc_(NULL), bumpAlloc_(NULL),
#ifdef JS_METHODJIT
jaegerRuntime_(NULL),
#endif
ionRuntime_(NULL), ionRuntime_(NULL),
selfHostingGlobal_(NULL), selfHostingGlobal_(NULL),
nativeStackBase(0), nativeStackBase(0),
@ -927,10 +923,6 @@ JSRuntime::init(uint32_t maxbytes)
js::TlsPerThreadData.set(&mainThread); js::TlsPerThreadData.set(&mainThread);
#ifdef JS_METHODJIT_SPEW
JMCheckLogging();
#endif
if (!js_InitGC(this, maxbytes)) if (!js_InitGC(this, maxbytes))
return false; return false;
@ -1050,13 +1042,10 @@ JSRuntime::~JSRuntime()
js_delete(bumpAlloc_); js_delete(bumpAlloc_);
js_delete(mathCache_); js_delete(mathCache_);
#ifdef JS_METHODJIT
js_delete(jaegerRuntime_);
#endif
#ifdef JS_ION #ifdef JS_ION
js_delete(ionRuntime_); js_delete(ionRuntime_);
#endif #endif
js_delete(execAlloc_); /* Delete after jaegerRuntime_. */ js_delete(execAlloc_); /* Delete after ionRuntime_. */
if (ionPcScriptCache) if (ionPcScriptCache)
js_delete(ionPcScriptCache); js_delete(ionPcScriptCache);
@ -1166,7 +1155,7 @@ JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads)
if (!rt) if (!rt)
return NULL; return NULL;
#if defined(JS_METHODJIT) && defined(JS_ION) #if defined(JS_ION)
if (!ion::InitializeIon()) if (!ion::InitializeIon())
return NULL; return NULL;
#endif #endif
@ -2242,6 +2231,14 @@ JS_GetFunctionPrototype(JSContext *cx, JSObject *forObj)
return forObj->global().getOrCreateFunctionPrototype(cx); return forObj->global().getOrCreateFunctionPrototype(cx);
} }
JS_PUBLIC_API(JSObject *)
JS_GetArrayPrototype(JSContext *cx, JSObject *forObj)
{
CHECK_REQUEST(cx);
assertSameCompartment(cx, forObj);
return forObj->global().getOrCreateArrayPrototype(cx);
}
JS_PUBLIC_API(JSObject *) JS_PUBLIC_API(JSObject *)
JS_GetGlobalForObject(JSContext *cx, JSObject *obj) JS_GetGlobalForObject(JSContext *cx, JSObject *obj)
{ {

View File

@ -2159,6 +2159,13 @@ JS_GetFunctionPrototype(JSContext *cx, JSObject *forObj);
extern JS_PUBLIC_API(JSObject *) extern JS_PUBLIC_API(JSObject *)
JS_GetObjectPrototype(JSContext *cx, JSObject *forObj); JS_GetObjectPrototype(JSContext *cx, JSObject *forObj);
/*
* Returns the original value of |Array.prototype| from the global object in
* which |forObj| was created.
*/
extern JS_PUBLIC_API(JSObject *)
JS_GetArrayPrototype(JSContext *cx, JSObject *forObj);
extern JS_PUBLIC_API(JSObject *) extern JS_PUBLIC_API(JSObject *)
JS_GetGlobalForObject(JSContext *cx, JSObject *obj); JS_GetGlobalForObject(JSContext *cx, JSObject *obj);

View File

@ -24,8 +24,6 @@
#include "jstypes.h" #include "jstypes.h"
#include "jsutil.h" #include "jsutil.h"
#include "ds/Sort.h" #include "ds/Sort.h"
#include "methodjit/MethodJIT.h"
#include "methodjit/StubCalls-inl.h"
#include "vm/ArgumentsObject.h" #include "vm/ArgumentsObject.h"
#include "vm/ForkJoin.h" #include "vm/ForkJoin.h"
#include "vm/NumericConversions.h" #include "vm/NumericConversions.h"
@ -2006,15 +2004,6 @@ js::ArrayShiftMoveElements(JSObject *obj)
obj->moveDenseElementsUnbarriered(0, 1, initlen); obj->moveDenseElementsUnbarriered(0, 1, initlen);
} }
#ifdef JS_METHODJIT
void JS_FASTCALL
mjit::stubs::ArrayShift(VMFrame &f)
{
JSObject *obj = &f.regs.sp[-1].toObject();
ArrayShiftMoveElements(obj);
}
#endif /* JS_METHODJIT */
/* ES5 15.4.4.9 */ /* ES5 15.4.4.9 */
JSBool JSBool
js::array_shift(JSContext *cx, unsigned argc, Value *vp) js::array_shift(JSContext *cx, unsigned argc, Value *vp)
@ -2437,7 +2426,7 @@ array_splice(JSContext *cx, unsigned argc, Value *vp)
return true; return true;
} }
#ifdef JS_METHODJIT #ifdef JS_ION
bool bool
js::array_concat_dense(JSContext *cx, HandleObject obj1, HandleObject obj2, HandleObject result) js::array_concat_dense(JSContext *cx, HandleObject obj1, HandleObject obj2, HandleObject result)
{ {
@ -2460,22 +2449,10 @@ js::array_concat_dense(JSContext *cx, HandleObject obj1, HandleObject obj2, Hand
result->initDenseElements(0, obj1->getDenseElements(), initlen1); result->initDenseElements(0, obj1->getDenseElements(), initlen1);
result->initDenseElements(initlen1, obj2->getDenseElements(), initlen2); result->initDenseElements(initlen1, obj2->getDenseElements(), initlen2);
result->setArrayLengthInt32(len); result->setArrayLengthInt32(len);
return true; return true;
} }
#endif /* JS_ION */
void JS_FASTCALL
mjit::stubs::ArrayConcatTwoArrays(VMFrame &f)
{
RootedObject result(f.cx, &f.regs.sp[-3].toObject());
RootedObject obj1(f.cx, &f.regs.sp[-2].toObject());
RootedObject obj2(f.cx, &f.regs.sp[-1].toObject());
if (!array_concat_dense(f.cx, obj1, obj2, result))
THROW();
}
#endif /* JS_METHODJIT */
/* /*
* Python-esque sequence operations. * Python-esque sequence operations.
@ -2992,18 +2969,6 @@ js::NewDenseUnallocatedArray(JSContext *cx, uint32_t length, JSObject *proto /*
return NewArray<false>(cx, length, proto, newKind); return NewArray<false>(cx, length, proto, newKind);
} }
#ifdef JS_METHODJIT
JSObject * JS_FASTCALL
mjit::stubs::NewDenseUnallocatedArray(VMFrame &f, uint32_t length)
{
JSObject *obj = NewArray<false>(f.cx, length, (JSObject *)f.scratch);
if (!obj)
THROWV(NULL);
return obj;
}
#endif
JSObject * JSObject *
js::NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t elementOffset, js::NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t elementOffset,
JSObject *proto /* = NULL */) JSObject *proto /* = NULL */)

Some files were not shown because too many files have changed in this diff Show More