mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge inbound to m-c.
This commit is contained in:
commit
f9b7785a5b
3
CLOBBER
3
CLOBBER
@ -17,5 +17,4 @@
|
||||
#
|
||||
# Modifying this file will now automatically clobber the buildbot machines \o/
|
||||
#
|
||||
Bug 866093 - Change in .gyp file for Android builds.
|
||||
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."
|
||||
Bug 852687 - changing an idl without clobbering resulted test failures
|
||||
|
@ -1108,13 +1108,47 @@ HyperTextAccessible::GetTextAfterOffset(int32_t aOffset,
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (aBoundaryType == BOUNDARY_CHAR) {
|
||||
GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset);
|
||||
return NS_OK;
|
||||
}
|
||||
int32_t offset = ConvertMagicOffset(aOffset);
|
||||
if (offset < 0)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
return GetTextHelper(eGetAfter, aBoundaryType, aOffset,
|
||||
aStartOffset, aEndOffset, aText);
|
||||
switch (aBoundaryType) {
|
||||
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
|
||||
|
@ -58,50 +58,20 @@
|
||||
"textarea", kOk, kOk, kOk);
|
||||
|
||||
// BOUNDARY_WORD_START
|
||||
testTextAfterOffset(0, BOUNDARY_WORD_START, "two ", 9, 13,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
"divbr", kTodo, kTodo, kTodo,
|
||||
"editable", kTodo, kTodo, kTodo,
|
||||
"editablebr", kTodo, kTodo, kTodo,
|
||||
"textarea", kTodo, kTodo, kTodo);
|
||||
testTextAfterOffset(0, BOUNDARY_WORD_START, "two ", 9, 13, IDs);
|
||||
testTextAfterOffset(8, BOUNDARY_WORD_START, "two ", 9, 13,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
"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,
|
||||
"div", kOk, kOk, kOk,
|
||||
"divbr", kTodo, kTodo, kTodo,
|
||||
"editable", kTodo, kTodo, kTodo,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"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
|
||||
testTextAfterOffset(0, 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(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);
|
||||
testTextAfterOffset(0, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
|
||||
testTextAfterOffset(6, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
|
||||
testTextAfterOffset(7, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
|
||||
testTextAfterOffset(8, BOUNDARY_WORD_END, " words", 12, 18, IDs);
|
||||
|
||||
// BOUNDARY_LINE_START
|
||||
testTextAfterOffset(0, BOUNDARY_LINE_START, "\n", 8, 9,
|
||||
|
@ -12,9 +12,9 @@
|
||||
src="../text.js"></script>
|
||||
<script type="application/javascript">
|
||||
if (navigator.platform.startsWith("Mac")) {
|
||||
SimpleTest.expectAssertions(0, 20);
|
||||
SimpleTest.expectAssertions(0, 14);
|
||||
} else {
|
||||
SimpleTest.expectAssertions(20);
|
||||
SimpleTest.expectAssertions(14);
|
||||
}
|
||||
|
||||
function doTest()
|
||||
@ -59,108 +59,28 @@
|
||||
testCharAfterOffset("textarea", 15, "", 16, 16);
|
||||
|
||||
// BOUNDARY_WORD_START
|
||||
testTextAfterOffset(0, BOUNDARY_WORD_START, "my ", 6, 9,
|
||||
"input", kTodo, kTodo, kTodo,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
"editable", kTodo, kTodo, kTodo,
|
||||
"textarea", kTodo, kTodo, kTodo);
|
||||
testTextAfterOffset(1, BOUNDARY_WORD_START, "my ", 6, 9,
|
||||
"input", kTodo, kTodo, kTodo,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
"editable", kTodo, kTodo, kTodo,
|
||||
"textarea", kTodo, kTodo, kTodo);
|
||||
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);
|
||||
testTextAfterOffset(0, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
|
||||
testTextAfterOffset(1, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
|
||||
testTextAfterOffset(5, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
|
||||
testTextAfterOffset(6, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
|
||||
testTextAfterOffset(7, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
|
||||
testTextAfterOffset(8, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
|
||||
testTextAfterOffset(9, BOUNDARY_WORD_START, "", 15, 15, IDs);
|
||||
testTextAfterOffset(11, BOUNDARY_WORD_START, "", 15, 15, IDs);
|
||||
testTextAfterOffset(14, BOUNDARY_WORD_START, "", 15, 15, IDs);
|
||||
testTextAfterOffset(15, BOUNDARY_WORD_START, "", 15, 15, IDs);
|
||||
|
||||
// BOUNDARY_WORD_END
|
||||
testTextAfterOffset(0, BOUNDARY_WORD_END, " my", 5, 8,
|
||||
"input", kTodo, kTodo, kTodo,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
"editable", kTodo, kTodo, kTodo,
|
||||
"textarea", kTodo, kTodo, kTodo);
|
||||
testTextAfterOffset(1, BOUNDARY_WORD_END, " my", 5, 8,
|
||||
"input", kTodo, kTodo, kTodo,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
"editable", kTodo, kTodo, kTodo,
|
||||
"textarea", kTodo, kTodo, kTodo);
|
||||
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);
|
||||
testTextAfterOffset(0, BOUNDARY_WORD_END, " my", 5, 8, IDs);
|
||||
testTextAfterOffset(1, BOUNDARY_WORD_END, " my", 5, 8, IDs);
|
||||
testTextAfterOffset(5, BOUNDARY_WORD_END, " my", 5, 8, IDs);
|
||||
testTextAfterOffset(6, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
|
||||
testTextAfterOffset(7, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
|
||||
testTextAfterOffset(8, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
|
||||
testTextAfterOffset(9, BOUNDARY_WORD_END, "", 15, 15, IDs);
|
||||
testTextAfterOffset(11, BOUNDARY_WORD_END, "", 15, 15, IDs);
|
||||
testTextAfterOffset(14, BOUNDARY_WORD_END, "", 15, 15, IDs);
|
||||
testTextAfterOffset(15, BOUNDARY_WORD_END, "", 15, 15, IDs);
|
||||
|
||||
// BOUNDARY_LINE_START
|
||||
testTextAfterOffset(0, BOUNDARY_LINE_START, "", 15, 15,
|
||||
|
@ -13,12 +13,6 @@
|
||||
<script type="application/javascript"
|
||||
src="../text.js"></script>
|
||||
<script type="application/javascript">
|
||||
if (navigator.platform.startsWith("Mac")) {
|
||||
SimpleTest.expectAssertions(0, 3);
|
||||
} else {
|
||||
SimpleTest.expectAssertions(3);
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
// __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);
|
||||
|
||||
// BOUNDARY_WORD_START
|
||||
testTextAfterOffset(0, BOUNDARY_WORD_START, "Sir ", 6, 11,
|
||||
"input", kTodo, kTodo, kTodo,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
"editable", kTodo, kTodo, kTodo,
|
||||
"textarea", kTodo, kTodo, kTodo);
|
||||
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(0, BOUNDARY_WORD_START, "Sir ", 6, 11, IDs);
|
||||
testTextAfterOffset(5, BOUNDARY_WORD_START, "Sir ", 6, 11, IDs);
|
||||
testTextAfterOffset(6, BOUNDARY_WORD_START, "Robin ", 11, 19, IDs);
|
||||
testTextAfterOffset(9, BOUNDARY_WORD_START, "Robin ", 11, 19, IDs);
|
||||
testTextAfterOffset(10, BOUNDARY_WORD_START, "Robin ", 11, 19, IDs);
|
||||
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,
|
||||
"div", kOk, kOk, kOk,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"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
|
||||
|
@ -20,7 +20,6 @@ function test() {
|
||||
// (1) Check that the scroll position is maintained at the bottom
|
||||
// when the requests overflow the vertical size of the container.
|
||||
.then(() => {
|
||||
debuggee.performRequests();
|
||||
return waitForRequestsToOverflowContainer(monitor, requestsContainer);
|
||||
}).then(() => {
|
||||
ok(scrolledToBottom(requestsContainer), "Scrolled to bottom on overflow.");
|
||||
|
@ -9,6 +9,10 @@ function test() {
|
||||
initNetMonitor(SORTING_URL).then(([aTab, aDebuggee, aMonitor]) => {
|
||||
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 { RequestsMenu } = NetMonitorView;
|
||||
|
||||
@ -172,6 +176,7 @@ function test() {
|
||||
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(a),
|
||||
"GET1", SORTING_SJS + "?index=1", {
|
||||
fuzzyUrl: true,
|
||||
status: 101,
|
||||
statusText: "Meh",
|
||||
type: "1",
|
||||
@ -181,6 +186,7 @@ function test() {
|
||||
});
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(b),
|
||||
"GET2", SORTING_SJS + "?index=2", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "Meh",
|
||||
type: "2",
|
||||
@ -190,6 +196,7 @@ function test() {
|
||||
});
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(c),
|
||||
"GET3", SORTING_SJS + "?index=3", {
|
||||
fuzzyUrl: true,
|
||||
status: 300,
|
||||
statusText: "Meh",
|
||||
type: "3",
|
||||
@ -199,6 +206,7 @@ function test() {
|
||||
});
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(d),
|
||||
"GET4", SORTING_SJS + "?index=4", {
|
||||
fuzzyUrl: true,
|
||||
status: 400,
|
||||
statusText: "Meh",
|
||||
type: "4",
|
||||
@ -208,6 +216,7 @@ function test() {
|
||||
});
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(e),
|
||||
"GET5", SORTING_SJS + "?index=5", {
|
||||
fuzzyUrl: true,
|
||||
status: 500,
|
||||
statusText: "Meh",
|
||||
type: "5",
|
||||
|
@ -9,6 +9,10 @@ function test() {
|
||||
initNetMonitor(SORTING_URL).then(([aTab, aDebuggee, aMonitor]) => {
|
||||
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 { RequestsMenu } = NetMonitorView;
|
||||
|
||||
@ -109,6 +113,7 @@ function test() {
|
||||
for (let i = 0, len = aOrder.length / 5; i < len; i++) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i]),
|
||||
"GET1", SORTING_SJS + "?index=1", {
|
||||
fuzzyUrl: true,
|
||||
status: 101,
|
||||
statusText: "Meh",
|
||||
type: "1",
|
||||
@ -120,6 +125,7 @@ function test() {
|
||||
for (let i = 0, len = aOrder.length / 5; i < len; i++) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len]),
|
||||
"GET2", SORTING_SJS + "?index=2", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "Meh",
|
||||
type: "2",
|
||||
@ -131,6 +137,7 @@ function test() {
|
||||
for (let i = 0, len = aOrder.length / 5; i < len; i++) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 2]),
|
||||
"GET3", SORTING_SJS + "?index=3", {
|
||||
fuzzyUrl: true,
|
||||
status: 300,
|
||||
statusText: "Meh",
|
||||
type: "3",
|
||||
@ -142,6 +149,7 @@ function test() {
|
||||
for (let i = 0, len = aOrder.length / 5; i < len; i++) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 3]),
|
||||
"GET4", SORTING_SJS + "?index=4", {
|
||||
fuzzyUrl: true,
|
||||
status: 400,
|
||||
statusText: "Meh",
|
||||
type: "4",
|
||||
@ -153,6 +161,7 @@ function test() {
|
||||
for (let i = 0, len = aOrder.length / 5; i < len; i++) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 4]),
|
||||
"GET5", SORTING_SJS + "?index=5", {
|
||||
fuzzyUrl: true,
|
||||
status: 500,
|
||||
statusText: "Meh",
|
||||
type: "5",
|
||||
|
@ -185,7 +185,7 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
|
||||
info("> Verifying: " + aMethod + " " + aUrl + " " + aData.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 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 hostPort = uri.hostPort;
|
||||
|
||||
is(attachment.method, aMethod,
|
||||
"The attached method is incorrect.");
|
||||
|
||||
is(attachment.url, aUrl,
|
||||
"The attached url is incorrect.");
|
||||
if (fuzzyUrl) {
|
||||
ok(attachment.method.startsWith(aMethod), "The attached method is incorrect.");
|
||||
ok(attachment.url.startsWith(aUrl), "The attached url is incorrect.");
|
||||
} else {
|
||||
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"),
|
||||
aMethod, "The displayed method is incorrect.");
|
||||
|
||||
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.");
|
||||
if (fuzzyUrl) {
|
||||
ok(target.querySelector(".requests-menu-file").getAttribute("value").startsWith(
|
||||
name + (query ? "?" + query : "")), "The displayed 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"),
|
||||
hostPort, "The displayed domain is incorrect.");
|
||||
|
@ -25,11 +25,11 @@
|
||||
// Use a count parameter to defeat caching.
|
||||
var count = 0;
|
||||
|
||||
function performRequests() {
|
||||
(function performRequests() {
|
||||
get("request_" + (count++), function() {
|
||||
setTimeout(performRequests, 0);
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
@ -12,7 +12,8 @@
|
||||
<script type="text/javascript">
|
||||
function get(aAddress, aIndex, aCallback) {
|
||||
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() {
|
||||
if (this.readyState == this.DONE) {
|
||||
|
@ -14,5 +14,5 @@ function handleRequest(request, response) {
|
||||
response.setHeader("Content-Type", "text/" + index, false);
|
||||
response.write(new Array(index * 10).join(index)); // + 0.01 KB
|
||||
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.
|
||||
}
|
||||
|
@ -573,18 +573,10 @@
|
||||
<richlistitem id="context-copy" type="copy" onclick="ContextCommands.copy();">
|
||||
<label value="&contextTextCopy.label;"/>
|
||||
</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 -->
|
||||
<richlistitem id="context-search" type="selected-text,!input-text" onclick="ContextCommands.searchText(this);">
|
||||
<label id="context-search-label" value=""/>
|
||||
</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 -->
|
||||
<richlistitem id="context-select" type="selectable" onclick="ContextCommands.select();">
|
||||
<label value="&contextTextSelect.label;"/>
|
||||
@ -593,6 +585,14 @@
|
||||
<richlistitem id="context-select-all" type="selectable" onclick="ContextCommands.selectAll();">
|
||||
<label value="&contextTextSelectAll.label;"/>
|
||||
</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 -->
|
||||
<!-- save image to user pictures library -->
|
||||
|
@ -46,7 +46,7 @@ HistoryView.prototype = {
|
||||
for (let i = 0, addedCount = 0; i < childCount && addedCount < limit; i++) {
|
||||
let node = rootNode.getChild(i);
|
||||
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 (this._toRemove && this._toRemove.indexOf(uri) !== -1)
|
||||
|
@ -7,10 +7,7 @@
|
||||
|
||||
flyoutpanel {
|
||||
height: 100%;
|
||||
border-width: 2px;
|
||||
border-color: #d7d6d6;
|
||||
background-color: #ffffff;
|
||||
-moz-border-start-style: solid;
|
||||
visibility: collapse;
|
||||
position: fixed;
|
||||
transition: transform @metro_animation_duration@ @metro_animation_easing@;
|
||||
@ -41,6 +38,9 @@ flyoutpanel[visible] {
|
||||
}
|
||||
|
||||
.flyoutpanel-header {
|
||||
border-width: 1px;
|
||||
-moz-border-start-style: solid;
|
||||
border-color: #1b1b1b;
|
||||
background-color: #002147;
|
||||
height: 80px;
|
||||
width: 100%;
|
||||
@ -60,6 +60,9 @@ flyoutpanel[visible] {
|
||||
}
|
||||
|
||||
.flyoutpanel-contents {
|
||||
border-width: 1px;
|
||||
-moz-border-start-style: solid;
|
||||
border-color: #c2c2c2;
|
||||
padding: 40px;
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -699,21 +699,8 @@ arrowbox {
|
||||
|
||||
.meta {
|
||||
background-color: @panel_light_color@;
|
||||
background-image: radial-gradient(circle farthest-corner at left bottom,
|
||||
rgba(255, 127, 0, 0.2) 0%,
|
||||
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-image: url("chrome://browser/skin/images/firefox-watermark.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
padding: @metro_spacing_normal@ @metro_spacing_xxnormal@;
|
||||
overflow: auto;
|
||||
|
@ -89,7 +89,7 @@ class RemoteAutomation(Automation):
|
||||
def checkForJavaException(self, logcat):
|
||||
found_exception = False
|
||||
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
|
||||
# concatenate the remainder to form a concise summary of the exception.
|
||||
#
|
||||
|
19
configure.in
19
configure.in
@ -486,24 +486,7 @@ case "$target" in
|
||||
AC_MSG_ERROR([The major versions of \$CC and \$CXX do not match.])
|
||||
fi
|
||||
|
||||
if test "$_CC_MAJOR_VERSION" = "14"; 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
|
||||
if test "$_CC_MAJOR_VERSION" = "16"; then
|
||||
_CC_SUITE=10
|
||||
_MSVS_VERSION=2010
|
||||
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
|
||||
|
@ -1440,7 +1440,8 @@ void
|
||||
nsContentSink::DidBuildModelImpl(bool aTerminated)
|
||||
{
|
||||
if (mDocument) {
|
||||
MOZ_ASSERT(mDocument->GetReadyStateEnum() ==
|
||||
MOZ_ASSERT(aTerminated ||
|
||||
mDocument->GetReadyStateEnum() ==
|
||||
nsIDocument::READYSTATE_LOADING, "Bad readyState");
|
||||
mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
|
||||
}
|
||||
|
@ -93,9 +93,7 @@ NS_IMPL_FORWARD_EVENT_HANDLER(nsDOMFileReader, error, FileIOObject)
|
||||
void
|
||||
nsDOMFileReader::RootResultArrayBuffer()
|
||||
{
|
||||
nsContentUtils::PreserveWrapper(
|
||||
static_cast<EventTarget*>(
|
||||
static_cast<nsDOMEventTargetHelper*>(this)), this);
|
||||
NS_HOLD_JS_OBJECTS(this, nsDOMFileReader);
|
||||
}
|
||||
|
||||
//nsDOMFileReader constructors/initializers
|
||||
@ -113,7 +111,8 @@ nsDOMFileReader::nsDOMFileReader()
|
||||
nsDOMFileReader::~nsDOMFileReader()
|
||||
{
|
||||
FreeFileData();
|
||||
|
||||
mResultArrayBuffer = nullptr;
|
||||
NS_DROP_JS_OBJECTS(this, nsDOMFileReader);
|
||||
nsLayoutStatics::Release();
|
||||
}
|
||||
|
||||
|
@ -324,15 +324,17 @@ nsXMLHttpRequest::~nsXMLHttpRequest()
|
||||
NS_ABORT_IF_FALSE(!(mState & XML_HTTP_REQUEST_SYNCLOOPING), "we rather crash than hang");
|
||||
mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
|
||||
|
||||
mResultJSON = JSVAL_VOID;
|
||||
mResultArrayBuffer = nullptr;
|
||||
NS_DROP_JS_OBJECTS(this, nsXMLHttpRequest);
|
||||
|
||||
nsLayoutStatics::Release();
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLHttpRequest::RootJSResultObjects()
|
||||
{
|
||||
nsContentUtils::PreserveWrapper(
|
||||
static_cast<EventTarget*>(
|
||||
static_cast<nsDOMEventTargetHelper*>(this)), this);
|
||||
NS_HOLD_JS_OBJECTS(this, nsXMLHttpRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2645,7 +2647,8 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
||||
mLoadLengthComputable = false;
|
||||
mLoadTotal = 0;
|
||||
if ((aVariant || !aBody.IsNull()) && httpChannel &&
|
||||
!method.EqualsLiteral("GET")) {
|
||||
!method.LowerCaseEqualsLiteral("get") &&
|
||||
!method.LowerCaseEqualsLiteral("head")) {
|
||||
|
||||
nsAutoCString charset;
|
||||
nsAutoCString defaultContentType;
|
||||
|
@ -1 +1,3 @@
|
||||
conformance/more/conformance/quickCheckAPI-B2.html
|
||||
conformance/more/conformance/quickCheckAPI-B3.html
|
||||
conformance/more/functions/bufferSubDataBadArgs.html
|
||||
|
@ -5028,8 +5028,6 @@ HTMLInputElement::GetStep() const
|
||||
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();
|
||||
}
|
||||
|
||||
@ -5220,15 +5218,6 @@ HTMLInputElement::HasStepMismatch() const
|
||||
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.
|
||||
return NS_floorModulo(value - GetStepBase(), step) != 0;
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ MOCHITEST_FILES = \
|
||||
submit_invalid_file.sjs \
|
||||
test_input_file_picker.html \
|
||||
test_input_event.html \
|
||||
test_input_number_rounding.html \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
116
content/html/content/test/forms/test_input_number_rounding.html
Normal file
116
content/html/content/test/forms/test_input_number_rounding.html
Normal file
@ -0,0 +1,116 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=783607
|
||||
-->
|
||||
<head>
|
||||
<title>Test rounding behaviour for <input type='number'></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>
|
@ -406,6 +406,13 @@ for (var test of data) {
|
||||
input.value = 2;
|
||||
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.
|
||||
input = getFreshElement(test.type);
|
||||
input.step = '2';
|
||||
|
@ -97,7 +97,10 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
|
||||
JNIEnv *env;
|
||||
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);
|
||||
#endif
|
||||
@ -230,7 +233,10 @@ MediaEngineWebRTC::EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSourc
|
||||
JNIEnv *env;
|
||||
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);
|
||||
#endif
|
||||
|
@ -4597,8 +4597,10 @@ nsDocShell::Stop(uint32_t aStopFlags)
|
||||
|
||||
if (nsIWebNavigation::STOP_CONTENT & aStopFlags) {
|
||||
// Stop the document loading
|
||||
if (mContentViewer)
|
||||
mContentViewer->Stop();
|
||||
if (mContentViewer) {
|
||||
nsCOMPtr<nsIContentViewer> cv = mContentViewer;
|
||||
cv->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
if (nsIWebNavigation::STOP_NETWORK & aStopFlags) {
|
||||
@ -10525,6 +10527,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
|
||||
shContainer->GetChildAt(i, getter_AddRefs(child));
|
||||
shContainer->RemoveChild(child);
|
||||
} // for
|
||||
entry->AbandonBFCacheEntry();
|
||||
} // shContainer
|
||||
}
|
||||
|
||||
|
@ -3088,6 +3088,8 @@ nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior,
|
||||
case nsIDOMWindowUtils::SELECT_WORDNOSPACE:
|
||||
amount = eSelectWordNoSpace;
|
||||
break;
|
||||
default:
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
|
@ -7425,9 +7425,10 @@ nsGlobalWindow::NotifyDOMWindowThawed(nsGlobalWindow* aWindow) {
|
||||
JSObject*
|
||||
nsGlobalWindow::GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey)
|
||||
{
|
||||
JSObject* handler = nullptr;
|
||||
AutoSafeJSContext cx;
|
||||
JS::Rooted<JSObject*> handler(cx);
|
||||
if (mCachedXBLPrototypeHandlers.IsInitialized()) {
|
||||
mCachedXBLPrototypeHandlers.Get(aKey, &handler);
|
||||
mCachedXBLPrototypeHandlers.Get(aKey, handler.address());
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ class CGNativePropertyHooks(CGThing):
|
||||
prototypeID += "_ID_Count"
|
||||
parent = self.descriptor.interface.parent
|
||||
parentHooks = ("&" + toBindingNamespace(parent.identifier.name) + "::sNativePropertyHooks"
|
||||
if parent else 'NULL')
|
||||
if parent else 'nullptr')
|
||||
|
||||
return CGWrapper(CGIndenter(CGList([CGGeneric(resolveOwnProperty),
|
||||
CGGeneric(enumerateOwnProperties),
|
||||
@ -183,10 +183,10 @@ DOMJSClass Class = {
|
||||
%s,
|
||||
JS_ConvertStub,
|
||||
%s, /* finalize */
|
||||
NULL, /* checkAccess */
|
||||
nullptr, /* checkAccess */
|
||||
%s, /* call */
|
||||
NULL, /* hasInstance */
|
||||
NULL, /* construct */
|
||||
nullptr, /* hasInstance */
|
||||
nullptr, /* construct */
|
||||
%s, /* trace */
|
||||
JSCLASS_NO_INTERNAL_MEMBERS
|
||||
},
|
||||
@ -1393,7 +1393,7 @@ class PropertyDefiner:
|
||||
# And the actual spec
|
||||
specs.append(specTemplate % getDataTuple(member))
|
||||
specs.append(specTerminator)
|
||||
prefableSpecs.append(" { false, NULL }");
|
||||
prefableSpecs.append(" { false, nullptr }");
|
||||
|
||||
specType = "const " + specType
|
||||
arrays = (("static %s %s_specs[] = {\n" +
|
||||
@ -1847,7 +1847,7 @@ if (!unforgeableHolder) {
|
||||
domClass,
|
||||
properties,
|
||||
chromeProperties,
|
||||
'"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "NULL"))
|
||||
'"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "nullptr"))
|
||||
if UseHolderForUnforgeable(self.descriptor):
|
||||
assert needInterfacePrototypeObject
|
||||
setUnforgeableHolder = CGGeneric(
|
||||
@ -2009,7 +2009,7 @@ def CreateBindingJSObject(descriptor, properties, parent):
|
||||
create = """ obj = NewProxyObject(aCx, DOMProxyHandler::getInstance(),
|
||||
JS::PrivateValue(aObject), proto, %s);
|
||||
if (!obj) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
"""
|
||||
@ -2021,7 +2021,7 @@ def CreateBindingJSObject(descriptor, properties, parent):
|
||||
else:
|
||||
create = """ obj = JS_NewObject(aCx, &Class.mBase, proto, %s);
|
||||
if (!obj) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject));
|
||||
@ -2148,7 +2148,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
|
||||
GetRealParentObject(aObject,
|
||||
WrapNativeParent(aCx, aScope, aObject->GetParentObject())));
|
||||
if (!parent) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 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::Handle<JSObject*> proto = GetProtoObject(aCx, global);
|
||||
if (!proto) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
%s
|
||||
@ -2213,7 +2213,7 @@ class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
|
||||
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, aScope));
|
||||
JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
|
||||
if (!proto) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
%s
|
||||
@ -3011,7 +3011,7 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
templateBody += "${declName} = tmp;"
|
||||
|
||||
templateBody = wrapObjectTemplate(templateBody, type,
|
||||
"${declName} = NULL",
|
||||
"${declName} = nullptr",
|
||||
failureCode)
|
||||
|
||||
declType = CGGeneric(declType)
|
||||
@ -3066,7 +3066,7 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
elif not isOptional:
|
||||
template += "${declName} = ${holderName}.addr();"
|
||||
template = wrapObjectTemplate(template, type,
|
||||
"%s = NULL" % nullableTarget,
|
||||
"%s = nullptr" % nullableTarget,
|
||||
failureCode)
|
||||
|
||||
if holderType is not None:
|
||||
@ -5403,7 +5403,7 @@ MOZ_END_ENUM_CLASS(%s)
|
||||
strings = """
|
||||
const EnumEntry %s[%d] = {
|
||||
%s,
|
||||
{ NULL, 0 }
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
""" % (ENUM_ENTRY_VARIABLE_NAME, self.nEnumStrings(),
|
||||
",\n ".join(['{"' + val + '", ' + str(len(val)) + '}' for val in self.enum.values()]))
|
||||
@ -6650,7 +6650,7 @@ if (!isXray && (expando = GetExpandoObject(proxy))) {
|
||||
}
|
||||
}
|
||||
""" + namedGet + """
|
||||
desc->obj = NULL;
|
||||
desc->obj = nullptr;
|
||||
return true;"""
|
||||
|
||||
class CGDOMJSProxyHandler_defineProperty(ClassMethod):
|
||||
|
@ -1325,25 +1325,20 @@ nsDOMDeviceStorage::SetRootDirectoryForType(const nsAString& aStorageType,
|
||||
JS::Value
|
||||
InterfaceToJsval(nsPIDOMWindow* aWindow, nsISupports* aObject, const nsIID* aIID)
|
||||
{
|
||||
AutoJSContext cx;
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
|
||||
if (!sgo) {
|
||||
return JSVAL_NULL;
|
||||
}
|
||||
|
||||
nsIScriptContext *scriptContext = sgo->GetScriptContext();
|
||||
if (!scriptContext) {
|
||||
return JSVAL_NULL;
|
||||
}
|
||||
JS::RootedObject scopeObj(cx, sgo->GetGlobalJSObject());
|
||||
NS_ENSURE_TRUE(scopeObj, JSVAL_NULL);
|
||||
JSAutoCompartment ac(cx, scopeObj);
|
||||
|
||||
AutoPushJSContext cx(scriptContext->GetNativeContext());
|
||||
if (!cx) {
|
||||
return JSVAL_NULL;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> someJsVal(cx);
|
||||
JS::Rooted<JSObject*> global(cx, JS_GetGlobalObject(cx));
|
||||
nsresult rv = nsContentUtils::WrapNative(cx,
|
||||
global,
|
||||
scopeObj,
|
||||
aObject,
|
||||
aIID,
|
||||
someJsVal.address());
|
||||
|
@ -142,7 +142,7 @@ NPObjWrapper_Construct(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
|
||||
static JSBool
|
||||
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 =
|
||||
{
|
||||
@ -960,7 +960,7 @@ JSObjWrapperHashMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *entry,
|
||||
|
||||
// static
|
||||
NPObject *
|
||||
nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj)
|
||||
nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JS::Handle<JSObject*> obj)
|
||||
{
|
||||
if (!npp) {
|
||||
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
|
||||
// substantial with it.
|
||||
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))) {
|
||||
if (JS_GetClass(obj) == &sNPObjectJSWrapperClass) {
|
||||
if (wrapResult && !JS_WrapObject(cx, &obj)) {
|
||||
if (wrapResult && !JS_WrapObject(cx, obj.address())) {
|
||||
return NULL;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
if (!::JS_GetPrototype(cx, obj, &obj)) {
|
||||
if (!::JS_GetPrototype(cx, obj, obj.address())) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -1336,7 +1337,7 @@ NPObjWrapper_GetProperty(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMut
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
NPObject *npobj = GetNPObject(cx, obj);
|
||||
@ -1465,7 +1466,7 @@ CallNPMethodInternal(JSContext *cx, JSObject *obj, unsigned argc,
|
||||
static JSBool
|
||||
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)
|
||||
return JS_FALSE;
|
||||
|
||||
@ -1666,14 +1667,16 @@ NPObjWrapper_Finalize(JSFreeOp *fop, JSObject *obj)
|
||||
static JSBool
|
||||
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);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1960,7 +1963,7 @@ LookupNPP(NPObject *npobj)
|
||||
|
||||
JSBool
|
||||
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);
|
||||
|
||||
|
@ -37,7 +37,8 @@ class nsJSObjWrapper : public NPObject,
|
||||
public nsJSObjWrapperKey
|
||||
{
|
||||
public:
|
||||
static NPObject *GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj);
|
||||
static NPObject *GetNewOrUsed(NPP npp, JSContext *cx,
|
||||
JS::Handle<JSObject*> obj);
|
||||
|
||||
protected:
|
||||
nsJSObjWrapper(NPP npp);
|
||||
|
@ -1211,7 +1211,8 @@ _getwindowobject(NPP npp)
|
||||
// Using ::JS_GetGlobalObject(cx) is ok here since the window we
|
||||
// want to return here is the outer window, *not* the inner (since
|
||||
// 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
|
||||
|
@ -154,7 +154,7 @@ ConnectWorkerToRIL::RunTask(JSContext *aCx)
|
||||
// communication.
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
|
||||
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",
|
||||
INT_TO_JSVAL(mClientId), nullptr, nullptr, 0)) {
|
||||
@ -260,7 +260,7 @@ ConnectWorkerToNetd::RunTask(JSContext *aCx)
|
||||
// communication.
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
|
||||
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",
|
||||
DoNetdCommand, 1, 0);
|
||||
}
|
||||
@ -299,7 +299,7 @@ private:
|
||||
bool
|
||||
NetdReceiver::DispatchNetdEvent::RunTask(JSContext *aCx)
|
||||
{
|
||||
JSObject *obj = JS_GetGlobalObject(aCx);
|
||||
JSObject *obj = JS_GetGlobalForScopeChain(aCx);
|
||||
|
||||
JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize);
|
||||
if (!array) {
|
||||
|
@ -41,7 +41,7 @@ class nsIURI;
|
||||
class nsPIDOMWindow;
|
||||
class nsITimer;
|
||||
class nsIXPCScriptNotify;
|
||||
namespace JS { class RuntimeStats; }
|
||||
namespace JS { struct RuntimeStats; }
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
|
@ -123,8 +123,10 @@ function execTests() {
|
||||
}
|
||||
|
||||
doCommand("cmd_scrollBottom");
|
||||
yield;
|
||||
testScrollCommand("cmd_scrollBottom", root.scrollHeight - 100);
|
||||
doCommand("cmd_scrollTop");
|
||||
yield;
|
||||
testScrollCommand("cmd_scrollTop", 0);
|
||||
|
||||
doCommand("cmd_scrollPageDown");
|
||||
|
@ -589,7 +589,6 @@ nsHTMLCSSUtils::GetComputedStyle(dom::Element* aElement)
|
||||
NS_ENSURE_TRUE(doc, nullptr);
|
||||
|
||||
nsIPresShell* presShell = doc->GetShell();
|
||||
NS_ASSERTION(presShell, "Trying to compute style without PresShell");
|
||||
NS_ENSURE_TRUE(presShell, nullptr);
|
||||
|
||||
nsRefPtr<nsComputedDOMStyle> style =
|
||||
|
@ -924,6 +924,11 @@ public:
|
||||
CreateSkiaDrawTargetForFBO(unsigned int aFBOID, GrContext *aContext, const IntSize &aSize, SurfaceFormat aFormat);
|
||||
#endif
|
||||
|
||||
#if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
|
||||
static TemporaryRef<GlyphRenderingOptions>
|
||||
CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
static TemporaryRef<DrawTarget> CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
|
||||
static TemporaryRef<DrawTarget>
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "DrawTargetSkia.h"
|
||||
#include "SourceSurfaceSkia.h"
|
||||
#include "ScaledFontBase.h"
|
||||
#include "ScaledFontCairo.h"
|
||||
#include "skia/SkDevice.h"
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
@ -445,7 +446,7 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
|
||||
const GlyphBuffer &aBuffer,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions,
|
||||
const GlyphRenderingOptions*)
|
||||
const GlyphRenderingOptions *aRenderingOptions)
|
||||
{
|
||||
if (aFont->GetType() != FONT_MAC &&
|
||||
aFont->GetType() != FONT_SKIA &&
|
||||
@ -461,7 +462,30 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
|
||||
paint.mPaint.setTypeface(skiaFont->GetSkTypeface());
|
||||
paint.mPaint.setTextSize(SkFloatToScalar(skiaFont->mSize));
|
||||
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<SkPoint> offsets;
|
||||
indices.resize(aBuffer.mNumGlyphs);
|
||||
|
@ -7,14 +7,15 @@
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
#include "DrawTargetCairo.h"
|
||||
#include "ScaledFontBase.h"
|
||||
#include "ScaledFontCairo.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_SKIA
|
||||
#include "DrawTargetSkia.h"
|
||||
#include "ScaledFontBase.h"
|
||||
#ifdef MOZ_ENABLE_FREETYPE
|
||||
#include "ScaledFontFreetype.h"
|
||||
#define USE_SKIA_FREETYPE
|
||||
#include "ScaledFontCairo.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -297,20 +298,10 @@ Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSiz
|
||||
return new ScaledFontMac(static_cast<CGFontRef>(aNativeFont.mFont), aSize);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SKIA
|
||||
#ifdef MOZ_ENABLE_FREETYPE
|
||||
case NATIVE_FONT_SKIA_FONT_FACE:
|
||||
{
|
||||
return new ScaledFontFreetype(static_cast<FontOptions*>(aNativeFont.mFont), aSize);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifdef USE_CAIRO
|
||||
#if defined(USE_CAIRO) || defined(USE_SKIA_FREETYPE)
|
||||
case NATIVE_FONT_CAIRO_FONT_FACE:
|
||||
{
|
||||
ScaledFontBase* fontBase = new ScaledFontBase(aSize);
|
||||
fontBase->SetCairoScaledFont(static_cast<cairo_scaled_font_t*>(aNativeFont.mFont));
|
||||
return fontBase;
|
||||
return new ScaledFontCairo(static_cast<cairo_scaled_font_t*>(aNativeFont.mFont), aSize);
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
@ -459,6 +450,19 @@ Factory::CreateSkiaDrawTargetForFBO(unsigned int aFBOID, GrContext *aGrContext,
|
||||
}
|
||||
#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>
|
||||
Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize)
|
||||
{
|
||||
|
@ -28,6 +28,7 @@ CPPSRCS = \
|
||||
Blur.cpp \
|
||||
Scale.cpp \
|
||||
ScaledFontBase.cpp \
|
||||
ScaledFontCairo.cpp \
|
||||
DrawTargetDual.cpp \
|
||||
ImageScaling.cpp \
|
||||
SourceSurfaceRawData.cpp \
|
||||
@ -73,10 +74,8 @@ CPPSRCS += \
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gtk2 gonk qt))
|
||||
CPPSRCS += \
|
||||
ScaledFontFreetype.cpp \
|
||||
$(NULL)
|
||||
DEFINES += -DMOZ_ENABLE_FREETYPE
|
||||
OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
|
||||
endif
|
||||
|
||||
DEFINES += -DSK_A32_SHIFT=24 -DSK_R32_SHIFT=16 -DSK_G32_SHIFT=8 -DSK_B32_SHIFT=0
|
||||
|
@ -28,7 +28,7 @@ ScaledFontBase::~ScaledFontBase()
|
||||
#ifdef USE_SKIA
|
||||
SkSafeUnref(mTypeface);
|
||||
#endif
|
||||
#ifdef USE_CAIRO
|
||||
#ifdef USE_CAIRO_SCALED_FONT
|
||||
cairo_scaled_font_destroy(mScaledFont);
|
||||
#endif
|
||||
}
|
||||
@ -39,7 +39,7 @@ ScaledFontBase::ScaledFontBase(Float aSize)
|
||||
#ifdef USE_SKIA
|
||||
mTypeface = nullptr;
|
||||
#endif
|
||||
#ifdef USE_CAIRO
|
||||
#ifdef USE_CAIRO_SCALED_FONT
|
||||
mScaledFont = nullptr;
|
||||
#endif
|
||||
}
|
||||
@ -106,7 +106,7 @@ ScaledFontBase::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBu
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
#ifdef USE_CAIRO_SCALED_FONT
|
||||
void
|
||||
ScaledFontBase::SetCairoScaledFont(cairo_scaled_font_t* font)
|
||||
{
|
||||
|
@ -8,10 +8,15 @@
|
||||
|
||||
#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
|
||||
#include "skia/SkTypeface.h"
|
||||
#endif
|
||||
#ifdef USE_CAIRO
|
||||
#ifdef USE_CAIRO_SCALED_FONT
|
||||
#include "cairo.h"
|
||||
#endif
|
||||
|
||||
@ -39,7 +44,7 @@ public:
|
||||
// Not true, but required to instantiate a ScaledFontBase.
|
||||
virtual FontType GetType() const { return FONT_SKIA; }
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
#ifdef USE_CAIRO_SCALED_FONT
|
||||
cairo_scaled_font_t* GetCairoScaledFont() { return mScaledFont; }
|
||||
void SetCairoScaledFont(cairo_scaled_font_t* font);
|
||||
#endif
|
||||
@ -49,7 +54,7 @@ protected:
|
||||
#ifdef USE_SKIA
|
||||
SkTypeface* mTypeface;
|
||||
#endif
|
||||
#ifdef USE_CAIRO
|
||||
#ifdef USE_CAIRO_SCALED_FONT
|
||||
cairo_scaled_font_t* mScaledFont;
|
||||
#endif
|
||||
Float mSize;
|
||||
|
59
gfx/2d/ScaledFontCairo.cpp
Normal file
59
gfx/2d/ScaledFontCairo.cpp
Normal 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
50
gfx/2d/ScaledFontCairo.h
Normal 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_ */
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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_ */
|
@ -88,6 +88,14 @@ enum FontStyle
|
||||
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,
|
||||
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 };
|
||||
|
@ -295,7 +295,7 @@ struct hb_set_t
|
||||
{
|
||||
for (unsigned int i = 0; i < 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))
|
||||
return i * BITS + j;
|
||||
return SENTINEL;
|
||||
|
@ -68,7 +68,7 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
}
|
||||
|
||||
void
|
||||
CanvasClient2D::Updated()
|
||||
CanvasClientWebGL::Updated()
|
||||
{
|
||||
mForwarder->UpdateTextureNoSwap(this, 1, mTextureClient->GetDescriptor());
|
||||
}
|
||||
|
@ -65,8 +65,6 @@ public:
|
||||
}
|
||||
|
||||
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
|
||||
@ -83,6 +81,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer);
|
||||
virtual void Updated() MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -299,14 +299,15 @@ CPPSRCS += \
|
||||
SkFontHost_mac_coretext.cpp \
|
||||
SkStream_mac.cpp \
|
||||
SkTime_Unix.cpp \
|
||||
SkThread_pthread.cpp \
|
||||
$(NULL)
|
||||
DEFINES += -DSK_USE_POSIX_THREADS=1
|
||||
endif
|
||||
|
||||
ifeq (android,$(MOZ_WIDGET_TOOLKIT))
|
||||
CPPSRCS += \
|
||||
SkDebug_android.cpp \
|
||||
SkFontHost_android_old.cpp \
|
||||
SkFontHost_FreeType.cpp \
|
||||
SkFontHost_cairo.cpp \
|
||||
SkFontHost_FreeType_common.cpp \
|
||||
SkFontHost_tables.cpp \
|
||||
SkMMapStream.cpp \
|
||||
@ -314,27 +315,33 @@ CPPSRCS += \
|
||||
SkThread_pthread.cpp \
|
||||
$(NULL)
|
||||
|
||||
OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
|
||||
DEFINES += -DSK_USE_POSIX_THREADS=1
|
||||
EXPORTS_skia += \
|
||||
include/ports/SkTypeface_cairo.h \
|
||||
$(NULL)
|
||||
|
||||
OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(CAIRO_FT_CFLAGS)
|
||||
else
|
||||
CPPSRCS += \
|
||||
SkDebug_stdio.cpp \
|
||||
SkThread_none.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
|
||||
CPPSRCS += \
|
||||
SkFontHost_FreeType.cpp \
|
||||
SkFontHost_cairo.cpp \
|
||||
SkFontHost_FreeType_common.cpp \
|
||||
SkFontHost_linux.cpp \
|
||||
SkFontHost_tables.cpp \
|
||||
SkTime_Unix.cpp \
|
||||
SkMMapStream.cpp \
|
||||
SkOSFile.cpp \
|
||||
$(NULL)
|
||||
|
||||
OS_CXXFLAGS += $(MOZ_PANGO_CFLAGS)
|
||||
EXPORTS_skia += \
|
||||
include/ports/SkTypeface_cairo.h \
|
||||
$(NULL)
|
||||
|
||||
OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(CAIRO_FT_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq (qt,$(MOZ_WIDGET_TOOLKIT))
|
||||
@ -357,6 +364,9 @@ endif
|
||||
|
||||
ifeq (Linux,$(OS_TARGET))
|
||||
DEFINES += -DSK_USE_POSIX_THREADS=1
|
||||
CPPSRCS += \
|
||||
SkThread_pthread.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq (windows,$(MOZ_WIDGET_TOOLKIT))
|
||||
@ -365,6 +375,7 @@ CPPSRCS += \
|
||||
SkFontHost_tables.cpp \
|
||||
SkFontHost_sandbox_none.cpp \
|
||||
SkTime_win.cpp \
|
||||
SkThread_win.cpp \
|
||||
$(NULL)
|
||||
DEFINES += -DSKIA_IMPLEMENTATION=1 -DGR_IMPLEMENTATION=1
|
||||
endif
|
||||
|
11
gfx/skia/include/ports/SkTypeface_cairo.h
Normal file
11
gfx/skia/include/ports/SkTypeface_cairo.h
Normal 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
|
||||
|
382
gfx/skia/src/ports/SkFontHost_cairo.cpp
Normal file
382
gfx/skia/src/ports/SkFontHost_cairo.cpp
Normal 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
|
@ -322,16 +322,13 @@ TemporaryRef<ScaledFont>
|
||||
gfxAndroidPlatform::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont)
|
||||
{
|
||||
NativeFont nativeFont;
|
||||
if (aTarget->GetType() == BACKEND_CAIRO) {
|
||||
if (aTarget->GetType() == BACKEND_CAIRO || aTarget->GetType() == BACKEND_SKIA) {
|
||||
nativeFont.mType = NATIVE_FONT_CAIRO_FONT_FACE;
|
||||
nativeFont.mFont = NULL;
|
||||
return Factory::CreateScaledFontWithCairo(nativeFont, aFont->GetAdjustedSize(), aFont->GetCairoScaledFont());
|
||||
nativeFont.mFont = 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;
|
||||
nativeFont.mFont = static_cast<gfxFT2FontBase*>(aFont)->GetFontOptions();
|
||||
return Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "prinit.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
||||
// rounding and truncation functions for a Freetype floating point number
|
||||
// (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);
|
||||
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
|
||||
|
||||
|
@ -68,6 +68,10 @@ public: // new functions
|
||||
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
|
||||
#ifdef USE_SKIA
|
||||
virtual mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions> GetGlyphRenderingOptions();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual bool ShapeText(gfxContext *aContext,
|
||||
const PRUnichar *aText,
|
||||
|
@ -777,6 +777,10 @@ public:
|
||||
return mPangoFont;
|
||||
}
|
||||
|
||||
#ifdef USE_SKIA
|
||||
virtual mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions> GetGlyphRenderingOptions();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual bool ShapeText(gfxContext *aContext,
|
||||
const PRUnichar *aText,
|
||||
@ -3231,3 +3235,36 @@ ApplyGdkScreenFontOptions(FcPattern *aPattern)
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
|
@ -758,13 +758,13 @@ TemporaryRef<ScaledFont>
|
||||
gfxPlatformGtk::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont)
|
||||
{
|
||||
NativeFont nativeFont;
|
||||
if (aTarget->GetType() == BACKEND_CAIRO) {
|
||||
|
||||
if (aTarget->GetType() == BACKEND_CAIRO || aTarget->GetType() == BACKEND_SKIA) {
|
||||
nativeFont.mType = NATIVE_FONT_CAIRO_FONT_FACE;
|
||||
nativeFont.mFont = NULL;
|
||||
return Factory::CreateScaledFontWithCairo(nativeFont, aFont->GetAdjustedSize(), aFont->GetCairoScaledFont());
|
||||
nativeFont.mFont = 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;
|
||||
nativeFont.mFont = static_cast<gfxFT2FontBase*>(aFont)->GetFontOptions();
|
||||
return Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ private:
|
||||
bool
|
||||
DispatchRILEvent::RunTask(JSContext *aCx)
|
||||
{
|
||||
JSObject *obj = JS_GetGlobalObject(aCx);
|
||||
JSObject *obj = JS_GetGlobalForScopeChain(aCx);
|
||||
|
||||
JSObject *array = JS_NewUint8Array(aCx, mMessage->mSize);
|
||||
if (!array) {
|
||||
|
@ -28,7 +28,7 @@ namespace {
|
||||
|
||||
class AutoResolveFlag
|
||||
{
|
||||
JSObject* mObj;
|
||||
Rooted<JSObject*> mObj;
|
||||
unsigned mOldFlags;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
||||
@ -46,9 +46,9 @@ namespace {
|
||||
|
||||
public:
|
||||
|
||||
AutoResolveFlag(JSObject* obj
|
||||
AutoResolveFlag(JSContext *cx, JSObject* obj
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mObj(obj)
|
||||
: mObj(cx, obj)
|
||||
, mOldFlags(SetFlags(obj, GetFlags(obj) | CPOW_FLAG_RESOLVING))
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
@ -101,7 +101,7 @@ ObjectWrapperParent::CheckOperation(JSContext* cx,
|
||||
switch (status->type()) {
|
||||
case OperationStatus::TJSVariant:
|
||||
{
|
||||
JS::RootedValue thrown(cx);
|
||||
Rooted<Value> thrown(cx);
|
||||
if (jsval_from_JSVariant(cx, status->get_JSVariant(), thrown.address()))
|
||||
JS_SetPendingException(cx, thrown);
|
||||
*status = JS_FALSE;
|
||||
@ -181,7 +181,7 @@ ObjectWrapperParent::GetJSObject(JSContext* cx) const
|
||||
static ObjectWrapperParent*
|
||||
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) {
|
||||
if (!js::GetObjectProto(cx, obj, &proto) || !proto)
|
||||
return NULL;
|
||||
@ -285,7 +285,7 @@ ObjectWrapperParent::boolean_from_JSVariant(JSContext* cx, const JSVariant& from
|
||||
*to = false;
|
||||
return true;
|
||||
case JSVariant::TPObjectWrapperParent: {
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
Rooted<Value> v(cx);
|
||||
if (!jsval_from_PObjectWrapperParent(cx, from.get_PObjectWrapperParent(), v.address()))
|
||||
return false;
|
||||
*to = JS::ToBoolean(v);
|
||||
@ -332,7 +332,7 @@ JSObject_to_PObjectWrapperParent(JSContext* cx, JSObject* from, PObjectWrapperPa
|
||||
ObjectWrapperParent::
|
||||
JSObject_from_PObjectWrapperParent(JSContext* cx,
|
||||
const PObjectWrapperParent* from,
|
||||
JS::MutableHandleObject to)
|
||||
MutableHandleObject to)
|
||||
{
|
||||
const ObjectWrapperParent* owp =
|
||||
static_cast<const ObjectWrapperParent*>(from);
|
||||
@ -348,7 +348,7 @@ jsval_from_PObjectWrapperParent(JSContext* cx,
|
||||
const PObjectWrapperParent* from,
|
||||
jsval* to)
|
||||
{
|
||||
JS::RootedObject obj(cx);
|
||||
Rooted<JSObject*> obj(cx);
|
||||
if (!JSObject_from_PObjectWrapperParent(cx, from, &obj))
|
||||
return false;
|
||||
*to = OBJECT_TO_JSVAL(obj);
|
||||
@ -530,7 +530,7 @@ ObjectWrapperParent::NewEnumerateNext(JSContext* cx, jsval* statep, jsid* idp)
|
||||
jsid_from_nsString(cx, out_id, idp))
|
||||
{
|
||||
JSObject* obj = GetJSObject(cx);
|
||||
JS::Rooted<AutoResolveFlag> arf(cx, obj);
|
||||
AutoResolveFlag arf(cx, obj);
|
||||
return JS_DefinePropertyById(cx, obj, *idp, JSVAL_VOID, NULL, NULL,
|
||||
JSPROP_ENUMERATE);
|
||||
}
|
||||
@ -578,7 +578,7 @@ ObjectWrapperParent::CPOW_NewEnumerate(JSContext *cx, JSHandleObject obj,
|
||||
|
||||
/*static*/ JSBool
|
||||
ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id,
|
||||
unsigned flags, JS::MutableHandleObject objp)
|
||||
unsigned flags, MutableHandleObject objp)
|
||||
{
|
||||
CPOW_LOG(("Calling CPOW_NewResolve (%s)...",
|
||||
JSVAL_TO_CSTR(cx, id)));
|
||||
@ -604,8 +604,8 @@ ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSHandleObject obj, JSHandle
|
||||
return JS_FALSE;
|
||||
|
||||
if (objp) {
|
||||
JS::Rooted<AutoResolveFlag> arf(cx, objp.get());
|
||||
JS::RootedObject obj2(cx, objp);
|
||||
AutoResolveFlag arf(cx, objp.get());
|
||||
Rooted<JSObject*> obj2(cx, objp);
|
||||
JS_DefinePropertyById(cx, obj2, id, JSVAL_VOID, NULL, NULL,
|
||||
JSPROP_ENUMERATE);
|
||||
}
|
||||
@ -647,7 +647,7 @@ ObjectWrapperParent::CPOW_Call(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
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)
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -184,30 +184,6 @@ CPPSRCS += TraceLogging.cpp
|
||||
|
||||
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
|
||||
ifdef ENABLE_ION
|
||||
VPATH += $(srcdir)/ion
|
||||
@ -336,17 +312,6 @@ CPPSRCS += Lowering-arm.cpp \
|
||||
endif #ENABLE_ION
|
||||
endif
|
||||
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
|
||||
@ -366,10 +331,6 @@ CPPSRCS += ExecutableAllocator.cpp \
|
||||
YarrCanonicalizeUCS2.cpp \
|
||||
$(NONE)
|
||||
|
||||
ifdef ENABLE_METHODJIT_SPEW
|
||||
CPPSRCS += Logging.cpp
|
||||
endif
|
||||
|
||||
ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
|
||||
CPPSRCS += ExecutableAllocatorPosix.cpp \
|
||||
OSAllocatorPosix.cpp \
|
||||
@ -386,9 +347,8 @@ CPPSRCS += ExecutableAllocatorOS2.cpp \
|
||||
$(NONE)
|
||||
endif
|
||||
|
||||
ifneq (,$(ENABLE_METHODJIT)$(ENABLE_ION)$(ENABLE_YARR_JIT))
|
||||
ifneq (,$(ENABLE_ION)$(ENABLE_YARR_JIT))
|
||||
VPATH += $(srcdir)/assembler/assembler \
|
||||
$(srcdir)/methodjit \
|
||||
$(NONE)
|
||||
|
||||
CPPSRCS += ARMAssembler.cpp \
|
||||
@ -1000,34 +960,12 @@ selfhosted.out.h: $(selfhosted_out_h_deps)
|
||||
# the code in js/src/assembler.
|
||||
CXXFLAGS += -DUSE_SYSTEM_MALLOC=1 -DENABLE_ASSEMBLER=1
|
||||
|
||||
ifneq (,$(ENABLE_YARR_JIT)$(ENABLE_METHODJIT))
|
||||
ifneq (,$(ENABLE_YARR_JIT))
|
||||
CXXFLAGS += -DENABLE_JIT=1
|
||||
endif
|
||||
|
||||
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
|
||||
###############################################
|
||||
|
@ -45,7 +45,6 @@
|
||||
|
||||
#include "ion/IonSpewer.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "methodjit/Logging.h"
|
||||
|
||||
#define PRETTY_PRINT_OFFSET(os) (((os)<0)?"-":""), (((os)<0)?-(os):(os))
|
||||
|
||||
@ -286,8 +285,7 @@ namespace JSC {
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
#endif
|
||||
{
|
||||
if (printer ||
|
||||
js::IsJaegerSpewChannelActive(js::JSpew_Insns)
|
||||
if (printer
|
||||
#ifdef JS_ION
|
||||
|| js::ion::IonSpewEnabled(js::ion::IonSpew_Codegen)
|
||||
#endif
|
||||
@ -306,14 +304,8 @@ namespace JSC {
|
||||
if (printer)
|
||||
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
|
||||
else
|
||||
js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
|
||||
js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -324,12 +316,8 @@ namespace JSC {
|
||||
__attribute__ ((format (printf, 1, 2)))
|
||||
#endif
|
||||
{
|
||||
if (js::IsJaegerSpewChannelActive(js::JSpew_Insns)
|
||||
#ifdef JS_ION
|
||||
|| js::ion::IonSpewEnabled(js::ion::IonSpew_Codegen)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (js::ion::IonSpewEnabled(js::ion::IonSpew_Codegen)) {
|
||||
char buf[200];
|
||||
|
||||
va_list va;
|
||||
@ -337,15 +325,10 @@ namespace JSC {
|
||||
int i = vsnprintf(buf, sizeof(buf), fmt, va);
|
||||
va_end(va);
|
||||
|
||||
if (i > -1) {
|
||||
if (js::IsJaegerSpewChannelActive(js::JSpew_Insns))
|
||||
js::JaegerSpew(js::JSpew_Insns, " %s\n", buf);
|
||||
#ifdef JS_ION
|
||||
else
|
||||
js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
|
||||
#endif
|
||||
}
|
||||
if (i > -1)
|
||||
js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include "assembler/wtf/SegmentedVector.h"
|
||||
#include "assembler/wtf/Assertions.h"
|
||||
|
||||
#include "methodjit/Logging.h"
|
||||
#include "jsnum.h"
|
||||
#define ASSEMBLER_HAS_CONSTANT_POOL 1
|
||||
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "builtin/TestingFunctions.h"
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "vm/ForkJoin.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))
|
||||
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
|
||||
value = BooleanValue(true);
|
||||
#else
|
||||
@ -816,45 +807,6 @@ DumpHeapComplete(JSContext *cx, unsigned argc, jsval *vp)
|
||||
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
|
||||
Terminate(JSContext *cx, unsigned arg, jsval *vp)
|
||||
{
|
||||
@ -1056,10 +1008,6 @@ static JSFunctionSpecWithHelp TestingFunctions[] = {
|
||||
"dumpHeapComplete([filename])",
|
||||
" 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,
|
||||
"terminate()",
|
||||
" Terminate JavaScript execution, as if we had run out of\n"
|
||||
|
@ -484,22 +484,7 @@ case "$target" in
|
||||
AC_MSG_ERROR([The major versions of \$CC and \$CXX do not match.])
|
||||
fi
|
||||
|
||||
if test "$_CC_MAJOR_VERSION" = "14"; 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
|
||||
if test "$_CC_MAJOR_VERSION" = "16"; then
|
||||
_CC_SUITE=10
|
||||
AC_DEFINE(_CRT_SECURE_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],
|
||||
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,
|
||||
[ --disable-yarr-jit Disable YARR JIT support],
|
||||
ENABLE_YARR_JIT= )
|
||||
|
@ -63,6 +63,7 @@ var ignoreCallees = {
|
||||
"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::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)
|
||||
@ -133,7 +134,8 @@ function isRootedTypeName(name)
|
||||
{
|
||||
if (name == "mozilla::ErrorResult" ||
|
||||
name == "js::frontend::TokenStream" ||
|
||||
name == "js::frontend::TokenStream::Position")
|
||||
name == "js::frontend::TokenStream::Position" ||
|
||||
name == "ModuleCompiler")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -436,7 +436,7 @@ class StrictModeGetter {
|
||||
//
|
||||
// The methods seek() and tell() allow to rescan from a previous visited
|
||||
// location of the buffer.
|
||||
class TokenStream
|
||||
class MOZ_STACK_CLASS TokenStream
|
||||
{
|
||||
/* Unicode separators that are treated as line terminators, in addition to \n, \r */
|
||||
enum {
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include "gc/Marking.h"
|
||||
#include "gc/Nursery-inl.h"
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "vm/Shape.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
@ -769,12 +769,6 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
|
||||
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);
|
||||
|
||||
#ifdef JS_ION
|
||||
|
@ -66,13 +66,6 @@ Zone::init(JSContext *cx)
|
||||
void
|
||||
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
|
||||
if (updateIon == UpdateIon && needs != ionUsingBarriers_) {
|
||||
ion::ToggleBarriers(this, needs);
|
||||
@ -156,41 +149,27 @@ Zone::sweep(FreeOp *fop, bool releaseTypes)
|
||||
void
|
||||
Zone::discardJitCode(FreeOp *fop, bool discardConstraints)
|
||||
{
|
||||
#ifdef JS_METHODJIT
|
||||
/*
|
||||
* 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);
|
||||
|
||||
#ifdef JS_ION
|
||||
if (isPreservingCode()) {
|
||||
PurgeJITCaches(this);
|
||||
} else {
|
||||
# ifdef JS_ION
|
||||
|
||||
# ifdef DEBUG
|
||||
# ifdef DEBUG
|
||||
/* Assert no baseline scripts are marked as active. */
|
||||
for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
JS_ASSERT_IF(script->hasBaselineScript(), !script->baselineScript()->active());
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Mark baseline scripts on the stack as active. */
|
||||
ion::MarkActiveBaselineScripts(this);
|
||||
|
||||
/* Only mark OSI points if code is being discarded. */
|
||||
ion::InvalidateAll(fop, this);
|
||||
# endif
|
||||
|
||||
for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
|
||||
mjit::ReleaseScriptCode(fop, script);
|
||||
# ifdef JS_ION
|
||||
ion::FinishInvalidation(fop, script);
|
||||
|
||||
/*
|
||||
@ -198,7 +177,6 @@ Zone::discardJitCode(FreeOp *fop, bool discardConstraints)
|
||||
* this also resets the active flag.
|
||||
*/
|
||||
ion::FinishDiscardBaselineScript(fop, script);
|
||||
# endif
|
||||
|
||||
/*
|
||||
* 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()) {
|
||||
#ifdef JS_ION
|
||||
/* Free optimized baseline stubs. */
|
||||
if (comp->ionCompartment())
|
||||
comp->ionCompartment()->optimizedStubSpace()->free();
|
||||
#endif
|
||||
|
||||
comp->types.sweepCompilerOutputs(fop, discardConstraints);
|
||||
}
|
||||
}
|
||||
#endif /* JS_METHODJIT */
|
||||
#endif
|
||||
}
|
||||
|
@ -894,7 +894,16 @@ typedef Vector<MBasicBlock*,16> CaseVector;
|
||||
// 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
|
||||
// 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:
|
||||
class Func
|
||||
|
@ -900,7 +900,8 @@ HandleSignal(int signum, siginfo_t *info, void *ctx)
|
||||
# endif
|
||||
}
|
||||
|
||||
static struct sigaction sPrevHandler;
|
||||
static struct sigaction sPrevSegvHandler;
|
||||
static struct sigaction sPrevBusHandler;
|
||||
|
||||
static void
|
||||
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
|
||||
// doing this is that we remove ourselves from the crash stack which
|
||||
// simplifies crash reports. Note: the order of these tests matter.
|
||||
if (sPrevHandler.sa_flags & SA_SIGINFO) {
|
||||
sPrevHandler.sa_sigaction(signum, info, context);
|
||||
struct sigaction* prevHandler = NULL;
|
||||
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
|
||||
} else if (sPrevHandler.sa_handler == SIG_DFL || sPrevHandler.sa_handler == SIG_IGN) {
|
||||
sigaction(signum, &sPrevHandler, NULL);
|
||||
} else if (prevHandler->sa_handler == SIG_DFL || prevHandler->sa_handler == SIG_IGN) {
|
||||
sigaction(signum, prevHandler, NULL);
|
||||
} else {
|
||||
sPrevHandler.sa_handler(signum);
|
||||
prevHandler->sa_handler(signum);
|
||||
exit(signum); // backstop
|
||||
}
|
||||
}
|
||||
@ -950,9 +959,9 @@ EnsureAsmJSSignalHandlersInstalled(JSRuntime *rt)
|
||||
sigAction.sa_sigaction = &AsmJSFaultHandler;
|
||||
sigemptyset(&sigAction.sa_mask);
|
||||
sigAction.sa_flags = SA_SIGINFO;
|
||||
if (sigaction(SIGSEGV, &sigAction, &sPrevHandler))
|
||||
if (sigaction(SIGSEGV, &sigAction, &sPrevSegvHandler))
|
||||
return false;
|
||||
if (sigaction(SIGBUS, &sigAction, &sPrevHandler))
|
||||
if (sigaction(SIGBUS, &sigAction, &sPrevBusHandler))
|
||||
return false;
|
||||
# endif
|
||||
|
||||
@ -994,3 +1003,14 @@ js::TriggerOperationCallbackForAsmJSCode(JSRuntime *rt)
|
||||
# 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
|
||||
|
@ -572,11 +572,6 @@ ion::CachedShapeGuardFailure()
|
||||
|
||||
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");
|
||||
|
||||
return Invalidate(cx, script);
|
||||
|
@ -190,23 +190,6 @@ BaselineCompiler::compile()
|
||||
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
|
||||
BaselineCompiler::emitPrologue()
|
||||
{
|
||||
@ -539,7 +522,6 @@ BaselineCompiler::emitBody()
|
||||
uint32_t emittedOps = 0;
|
||||
|
||||
while (true) {
|
||||
SPEW_OPCODE();
|
||||
JSOp op = JSOp(*pc);
|
||||
IonSpew(IonSpew_BaselineOp, "Compiling op @ %d: %s",
|
||||
int(pc - script->code), js_CodeName[op]);
|
||||
|
@ -7178,8 +7178,23 @@ ICCallScriptedCompiler::generateStubCode(MacroAssembler &masm)
|
||||
Label skipThisReplace;
|
||||
masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
|
||||
|
||||
Register scratchReg = JSReturnOperand.scratchReg();
|
||||
|
||||
// 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
|
||||
masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
|
||||
masm.breakpoint();
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "vm/Stack-inl.h"
|
||||
#include "ion/IonFrames-inl.h"
|
||||
#include "ion/CompilerRoot.h"
|
||||
#include "methodjit/Retcon.h"
|
||||
#include "ExecutionModeInlines.h"
|
||||
|
||||
#if JS_TRACE_LOGGING
|
||||
@ -1294,10 +1293,7 @@ AttachFinishedCompilations(JSContext *cx)
|
||||
success = codegen->link();
|
||||
}
|
||||
|
||||
if (success) {
|
||||
if (script->hasIonScript())
|
||||
mjit::DisableScriptCodeForIon(script, script->ionScript()->osrPc());
|
||||
} else {
|
||||
if (!success) {
|
||||
// Silently ignore OOM during code generation, we're at an
|
||||
// operation callback and can't propagate failures.
|
||||
cx->clearPendingException();
|
||||
@ -1590,8 +1586,8 @@ Compile(JSContext *cx, HandleScript script, AbstractFramePtr fp, jsbytecode *osr
|
||||
}
|
||||
|
||||
if (executionMode == SequentialExecution) {
|
||||
if (cx->methodJitEnabled || IsBaselineEnabled(cx)) {
|
||||
// If JM is enabled we use getUseCount instead of incUseCount to avoid
|
||||
if (IsBaselineEnabled(cx)) {
|
||||
// If Baseline is enabled we use getUseCount instead of incUseCount to avoid
|
||||
// bumping the use count twice.
|
||||
if (script->getUseCount() < js_IonOptions.usesBeforeCompile)
|
||||
return Method_Skipped;
|
||||
@ -2297,8 +2293,6 @@ ion::Invalidate(types::TypeCompartment &types, FreeOp *fop,
|
||||
for (size_t i = 0; i < invalid.length(); i++) {
|
||||
const types::CompilerOutput &co = *invalid[i].compilerOutput(types);
|
||||
switch (co.kind()) {
|
||||
case types::CompilerOutput::MethodJIT:
|
||||
break;
|
||||
case types::CompilerOutput::Ion:
|
||||
case types::CompilerOutput::ParallelIon:
|
||||
JS_ASSERT(co.isValid());
|
||||
@ -2328,8 +2322,6 @@ ion::Invalidate(types::TypeCompartment &types, FreeOp *fop,
|
||||
types::CompilerOutput &co = *invalid[i].compilerOutput(types);
|
||||
ExecutionMode executionMode = SequentialExecution;
|
||||
switch (co.kind()) {
|
||||
case types::CompilerOutput::MethodJIT:
|
||||
continue;
|
||||
case types::CompilerOutput::Ion:
|
||||
break;
|
||||
case types::CompilerOutput::ParallelIon:
|
||||
|
@ -7480,13 +7480,8 @@ IonBuilder::getPropTryInlineAccess(bool *emitted, HandlePropertyName name, Handl
|
||||
return true;
|
||||
|
||||
Vector<Shape *> shapes(cx);
|
||||
if (Shape *objShape = mjit::GetPICSingleShape(cx, script(), pc, info().constructing())) {
|
||||
if (!shapes.append(objShape))
|
||||
return false;
|
||||
} else {
|
||||
if (!inspector->maybeShapesForPropertyOp(pc, shapes))
|
||||
return false;
|
||||
}
|
||||
if (!inspector->maybeShapesForPropertyOp(pc, shapes))
|
||||
return false;
|
||||
|
||||
if (shapes.empty() || !CanInlinePropertyOpShapes(shapes))
|
||||
return true;
|
||||
@ -7682,13 +7677,8 @@ IonBuilder::jsop_setprop(HandlePropertyName name)
|
||||
}
|
||||
|
||||
Vector<Shape *> shapes(cx);
|
||||
if (Shape *objShape = mjit::GetPICSingleShape(cx, script(), pc, info().constructing())) {
|
||||
if (!shapes.append(objShape))
|
||||
return false;
|
||||
} else {
|
||||
if (!inspector->maybeShapesForPropertyOp(pc, shapes))
|
||||
return false;
|
||||
}
|
||||
if (!inspector->maybeShapesForPropertyOp(pc, shapes))
|
||||
return false;
|
||||
|
||||
if (!shapes.empty() && CanInlinePropertyOpShapes(shapes)) {
|
||||
if (shapes.length() == 1) {
|
||||
|
@ -2386,7 +2386,8 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
|
||||
if (!cache.attachArgumentsElement(cx, ion, obj))
|
||||
return false;
|
||||
attachedStub = true;
|
||||
} else if (obj->isNative() && cache.monitoredResult()) {
|
||||
}
|
||||
if (!attachedStub && obj->isNative() && cache.monitoredResult()) {
|
||||
uint32_t dummy;
|
||||
if (idval.isString() && JSID_IS_ATOM(id) && !JSID_TO_ATOM(id)->isIndex(&dummy)) {
|
||||
RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName());
|
||||
@ -2394,11 +2395,13 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
|
||||
return false;
|
||||
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))
|
||||
return false;
|
||||
attachedStub = true;
|
||||
} else if (obj->isTypedArray()) {
|
||||
}
|
||||
if (!attachedStub && obj->isTypedArray()) {
|
||||
if ((idval.isInt32()) ||
|
||||
(idval.isString() && GetIndexFromString(idval.toString()) != UINT32_MAX))
|
||||
{
|
||||
|
@ -426,8 +426,6 @@ LIRGenerator::visitApplyArgs(MApplyArgs *apply)
|
||||
{
|
||||
JS_ASSERT(apply->getFunction()->type() == MIRType_Object);
|
||||
|
||||
JSFunction *target = apply->getSingleTarget();
|
||||
|
||||
// Assert if we cannot build a rectifier frame.
|
||||
JS_ASSERT(CallTempReg0 != ArgumentsRectifierReg);
|
||||
JS_ASSERT(CallTempReg1 != ArgumentsRectifierReg);
|
||||
@ -447,7 +445,7 @@ LIRGenerator::visitApplyArgs(MApplyArgs *apply)
|
||||
return false;
|
||||
|
||||
// Bailout is only needed in the case of possible non-JSFunction callee.
|
||||
if (!target && !assignSnapshot(lir))
|
||||
if (!apply->getSingleTarget() && !assignSnapshot(lir))
|
||||
return false;
|
||||
|
||||
if (!defineReturn(lir, apply))
|
||||
|
@ -120,8 +120,7 @@ MacroAssemblerX64::callWithABIPre(uint32_t *stackAdjust)
|
||||
#ifdef DEBUG
|
||||
{
|
||||
Label good;
|
||||
movl(rsp, rax);
|
||||
testq(rax, Imm32(StackAlignment - 1));
|
||||
testq(rsp, Imm32(StackAlignment - 1));
|
||||
j(Equal, &good);
|
||||
breakpoint();
|
||||
bind(&good);
|
||||
|
@ -149,8 +149,7 @@ MacroAssemblerX86::callWithABIPre(uint32_t *stackAdjust)
|
||||
{
|
||||
// Check call alignment.
|
||||
Label good;
|
||||
movl(esp, eax);
|
||||
testl(eax, Imm32(StackAlignment - 1));
|
||||
testl(esp, Imm32(StackAlignment - 1));
|
||||
j(Equal, &good);
|
||||
breakpoint();
|
||||
bind(&good);
|
||||
|
@ -142,21 +142,13 @@ def main(argv):
|
||||
if options.tbpl:
|
||||
# Running all bits would take forever. Instead, we test a few interesting combinations.
|
||||
flags = [
|
||||
['--no-baseline', '--no-jm'],
|
||||
['--ion-eager'], # implies --baseline-eager
|
||||
['--no-baseline'],
|
||||
['--no-baseline', '--ion-eager'],
|
||||
['--baseline-eager'],
|
||||
['--baseline-eager', '--no-ti', '--no-fpu'],
|
||||
# Below, equivalents the old shell flags: ,m,am,amd,n,mn,amn,amdn,mdn
|
||||
['--no-baseline', '--no-ion', '--no-jm', '--no-ti'],
|
||||
['--no-baseline', '--no-ion', '--no-ti'],
|
||||
['--no-baseline', '--no-ion', '--no-ti', '--always-mjit', '--debugjit'],
|
||||
['--no-baseline', '--no-ion', '--no-jm'],
|
||||
['--no-baseline'],
|
||||
['--no-baseline', '--ion-eager'],
|
||||
['--no-baseline', '--no-ion'],
|
||||
['--no-baseline', '--no-ion', '--always-mjit'],
|
||||
['--no-baseline', '--no-ion', '--always-mjit', '--debugjit'],
|
||||
['--no-baseline', '--no-ion', '--debugjit']
|
||||
['--no-baseline', '--no-ion', '--no-ti'],
|
||||
]
|
||||
for test in test_list:
|
||||
for variant in flags:
|
||||
|
@ -5,7 +5,6 @@ function tryItOut(code) {
|
||||
f = eval("(function(){" + code + "})")
|
||||
for (e in f()) {}
|
||||
}
|
||||
mjitChunkLimit(25)
|
||||
tryItOut("\
|
||||
for each(x in[0,0,0,0,0,0,0]) {\
|
||||
function f(b) {\
|
||||
|
@ -10,5 +10,5 @@ function g(code) {
|
||||
evalcx("(function(){return" + code + "})()")
|
||||
} catch (e) {}
|
||||
}
|
||||
g("mjitChunkLimit(8)")
|
||||
g("")
|
||||
g(" function(x,[]){NaN.x::c}()")
|
||||
|
@ -3,7 +3,6 @@
|
||||
// Binary: cache/js-dbg-32-92fe907ddac8-linux
|
||||
// Flags: -m -n
|
||||
//
|
||||
mjitChunkLimit(31)
|
||||
o = {}
|
||||
o.valueOf = function() {
|
||||
for (var p in undefined) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
var lfcode = new Array();
|
||||
lfcode.push("3");
|
||||
lfcode.push("\
|
||||
evaluate(\"mjitChunkLimit(5)\");\
|
||||
evaluate(\"\");\
|
||||
function slice(a, b) {\
|
||||
return slice(index, ++(ArrayBuffer));\
|
||||
}\
|
||||
|
@ -8,6 +8,5 @@ Object.defineProperty(this, "t2", {
|
||||
}
|
||||
})
|
||||
h2 = {}
|
||||
mjitChunkLimit(8)
|
||||
h2.a = function() {}
|
||||
Object(t2)
|
||||
|
@ -7,8 +7,6 @@ function test(m) {
|
||||
arr[1] = m;
|
||||
}
|
||||
|
||||
mjitChunkLimit(10);
|
||||
|
||||
arr = new Float64Array(2);
|
||||
|
||||
// run function a lot to trigger methodjit compile
|
||||
|
@ -1,4 +1,3 @@
|
||||
mjitChunkLimit(42);
|
||||
Function("\
|
||||
switch (/x/) {\
|
||||
case 8:\
|
||||
|
@ -1,4 +1,3 @@
|
||||
mjitChunkLimit(10);
|
||||
function e() {
|
||||
try {
|
||||
var t = undefined;
|
||||
|
@ -1,5 +1,3 @@
|
||||
|
||||
evaluate("mjitChunkLimit(5)");
|
||||
expected = 100;
|
||||
function slice(a, b) {
|
||||
return expected--;
|
||||
|
@ -596,25 +596,6 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
|
||||
*/
|
||||
if (!script_->analyzedArgsUsage())
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef JS_METHODJIT_SPEW
|
||||
#ifdef DEBUG
|
||||
void
|
||||
LifetimeVariable::print() const
|
||||
{
|
||||
@ -1106,21 +1087,6 @@ ScriptAnalysis::ensureVariable(LifetimeVariable &var, unsigned until)
|
||||
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
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
@ -1841,13 +1807,9 @@ ScriptAnalysis::needsArgsObj(JSContext *cx, SeenVector &seen, SSAUseChain *use)
|
||||
if (op == JSOP_POP || op == JSOP_POPN)
|
||||
return false;
|
||||
|
||||
/* SplatApplyArgs can read fp->canonicalActualArg(i) directly. */
|
||||
if (op == JSOP_FUNAPPLY && GET_ARGC(pc) == 2 && use->u.which == 0) {
|
||||
#ifdef JS_METHODJIT
|
||||
JS_ASSERT(mjit::IsLowerableFunCallOrApply(pc));
|
||||
#endif
|
||||
/* 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)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* arguments[i] can read fp->canonicalActualArg(i) directly. */
|
||||
if (op == JSOP_GETELEM && use->u.which == 1)
|
||||
|
@ -25,9 +25,6 @@
|
||||
|
||||
class JSScript;
|
||||
|
||||
/* Forward declaration of downstream register allocations computed for join points. */
|
||||
namespace js { namespace mjit { struct RegisterAllocation; } }
|
||||
|
||||
namespace js {
|
||||
namespace analyze {
|
||||
|
||||
@ -125,11 +122,6 @@ class Bytecode
|
||||
/* If this is a JSOP_LOOPHEAD or JSOP_LOOPENTRY, information about the loop. */
|
||||
LoopAnalysis *loop;
|
||||
|
||||
/* --------- Lifetime analysis --------- */
|
||||
|
||||
/* Any allocation computed downstream for this bytecode. */
|
||||
mjit::RegisterAllocation *allocation;
|
||||
|
||||
/* --------- SSA analysis --------- */
|
||||
|
||||
/* Generated location of each value popped by this bytecode. */
|
||||
@ -513,7 +505,7 @@ struct LifetimeVariable
|
||||
return offset;
|
||||
}
|
||||
|
||||
#ifdef JS_METHODJIT_SPEW
|
||||
#ifdef DEBUG
|
||||
void print() const;
|
||||
#endif
|
||||
};
|
||||
@ -995,14 +987,6 @@ class ScriptAnalysis
|
||||
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) {
|
||||
JS_ASSERT(offset < script_->length);
|
||||
return getCode(offset).loop;
|
||||
@ -1051,8 +1035,6 @@ class ScriptAnalysis
|
||||
void printSSA(JSContext *cx);
|
||||
void printTypes(JSContext *cx);
|
||||
|
||||
void clearAllocations();
|
||||
|
||||
private:
|
||||
void setOOM(JSContext *cx) {
|
||||
if (!outOfMemory)
|
||||
|
@ -131,10 +131,7 @@ ThrowHook(JSContext *cx, JSScript *, jsbytecode *, jsval *rval, void *closure)
|
||||
|
||||
BEGIN_TEST(testDebugger_throwHook)
|
||||
{
|
||||
uint32_t newopts =
|
||||
JS_GetOptions(cx) | JSOPTION_METHODJIT | JSOPTION_METHODJIT_ALWAYS;
|
||||
uint32_t oldopts = JS_SetOptions(cx, newopts);
|
||||
|
||||
CHECK(JS_SetDebugMode(cx, true));
|
||||
CHECK(JS_SetThrowHook(rt, ThrowHook, NULL));
|
||||
EXEC("function foo() { throw 3 };\n"
|
||||
"for (var i = 0; i < 10; ++i) { \n"
|
||||
@ -145,7 +142,6 @@ BEGIN_TEST(testDebugger_throwHook)
|
||||
"}\n");
|
||||
CHECK(called);
|
||||
CHECK(JS_SetThrowHook(rt, NULL, NULL));
|
||||
JS_SetOptions(cx, oldopts);
|
||||
return true;
|
||||
}
|
||||
END_TEST(testDebugger_throwHook)
|
||||
|
@ -87,10 +87,9 @@
|
||||
|
||||
#if ENABLE_YARR_JIT
|
||||
#include "assembler/jit/ExecutableAllocator.h"
|
||||
#include "methodjit/Logging.h"
|
||||
#endif
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
#ifdef JS_ION
|
||||
#include "ion/Ion.h"
|
||||
#endif
|
||||
|
||||
@ -692,7 +691,7 @@ static const JSSecurityCallbacks NullSecurityCallbacks = { };
|
||||
static bool
|
||||
JitSupportsFloatingPoint()
|
||||
{
|
||||
#if defined(JS_METHODJIT) || defined(JS_ION)
|
||||
#if defined(JS_ION)
|
||||
if (!JSC::MacroAssembler().supportsFloatingPoint())
|
||||
return false;
|
||||
|
||||
@ -739,9 +738,6 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
|
||||
freeLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
|
||||
execAlloc_(NULL),
|
||||
bumpAlloc_(NULL),
|
||||
#ifdef JS_METHODJIT
|
||||
jaegerRuntime_(NULL),
|
||||
#endif
|
||||
ionRuntime_(NULL),
|
||||
selfHostingGlobal_(NULL),
|
||||
nativeStackBase(0),
|
||||
@ -927,10 +923,6 @@ JSRuntime::init(uint32_t maxbytes)
|
||||
|
||||
js::TlsPerThreadData.set(&mainThread);
|
||||
|
||||
#ifdef JS_METHODJIT_SPEW
|
||||
JMCheckLogging();
|
||||
#endif
|
||||
|
||||
if (!js_InitGC(this, maxbytes))
|
||||
return false;
|
||||
|
||||
@ -1050,13 +1042,10 @@ JSRuntime::~JSRuntime()
|
||||
|
||||
js_delete(bumpAlloc_);
|
||||
js_delete(mathCache_);
|
||||
#ifdef JS_METHODJIT
|
||||
js_delete(jaegerRuntime_);
|
||||
#endif
|
||||
#ifdef JS_ION
|
||||
js_delete(ionRuntime_);
|
||||
#endif
|
||||
js_delete(execAlloc_); /* Delete after jaegerRuntime_. */
|
||||
js_delete(execAlloc_); /* Delete after ionRuntime_. */
|
||||
|
||||
if (ionPcScriptCache)
|
||||
js_delete(ionPcScriptCache);
|
||||
@ -1166,7 +1155,7 @@ JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads)
|
||||
if (!rt)
|
||||
return NULL;
|
||||
|
||||
#if defined(JS_METHODJIT) && defined(JS_ION)
|
||||
#if defined(JS_ION)
|
||||
if (!ion::InitializeIon())
|
||||
return NULL;
|
||||
#endif
|
||||
@ -2242,6 +2231,14 @@ JS_GetFunctionPrototype(JSContext *cx, JSObject *forObj)
|
||||
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_GetGlobalForObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
|
@ -2159,6 +2159,13 @@ JS_GetFunctionPrototype(JSContext *cx, JSObject *forObj);
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
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 *)
|
||||
JS_GetGlobalForObject(JSContext *cx, JSObject *obj);
|
||||
|
||||
|
@ -24,8 +24,6 @@
|
||||
#include "jstypes.h"
|
||||
#include "jsutil.h"
|
||||
#include "ds/Sort.h"
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "methodjit/StubCalls-inl.h"
|
||||
#include "vm/ArgumentsObject.h"
|
||||
#include "vm/ForkJoin.h"
|
||||
#include "vm/NumericConversions.h"
|
||||
@ -2006,15 +2004,6 @@ js::ArrayShiftMoveElements(JSObject *obj)
|
||||
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 */
|
||||
JSBool
|
||||
js::array_shift(JSContext *cx, unsigned argc, Value *vp)
|
||||
@ -2437,7 +2426,7 @@ array_splice(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
#ifdef JS_ION
|
||||
bool
|
||||
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(initlen1, obj2->getDenseElements(), initlen2);
|
||||
|
||||
result->setArrayLengthInt32(len);
|
||||
return true;
|
||||
}
|
||||
|
||||
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 */
|
||||
#endif /* JS_ION */
|
||||
|
||||
/*
|
||||
* Python-esque sequence operations.
|
||||
@ -2992,18 +2969,6 @@ js::NewDenseUnallocatedArray(JSContext *cx, uint32_t length, JSObject *proto /*
|
||||
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 *
|
||||
js::NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t elementOffset,
|
||||
JSObject *proto /* = NULL */)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user