mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-20 17:20:54 +00:00
Merge last PGO-safe green changeset from mozilla-inbound to mozilla-central
This commit is contained in:
commit
5acdef53c1
@ -2617,7 +2617,7 @@ function UpdateUrlbarSearchSplitterState()
|
||||
}
|
||||
|
||||
function setUrlAndSearchBarWidthForConditionalForwardButton() {
|
||||
// Woraround for bug 694084: Showing/hiding the conditional forward button resizes
|
||||
// Workaround for bug 694084: Showing/hiding the conditional forward button resizes
|
||||
// the search bar when the url/search bar splitter hasn't been used.
|
||||
var urlbarContainer = document.getElementById("urlbar-container");
|
||||
var searchbarContainer = document.getElementById("search-container");
|
||||
@ -5487,7 +5487,7 @@ function updateAppButtonDisplay() {
|
||||
document.getElementById("titlebar").hidden = !displayAppButton;
|
||||
|
||||
if (displayAppButton)
|
||||
document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
|
||||
document.documentElement.setAttribute("chromemargin", "0,2,2,2");
|
||||
else
|
||||
document.documentElement.removeAttribute("chromemargin");
|
||||
|
||||
|
@ -134,7 +134,6 @@
|
||||
@BINPATH@/components/directory.xpt
|
||||
@BINPATH@/components/docshell.xpt
|
||||
@BINPATH@/components/dom.xpt
|
||||
@BINPATH@/components/dom_apps.xpt
|
||||
@BINPATH@/components/dom_base.xpt
|
||||
#ifdef MOZ_B2G_RIL
|
||||
@BINPATH@/components/dom_telephony.xpt
|
||||
@ -389,8 +388,6 @@
|
||||
#endif
|
||||
@BINPATH@/components/TelemetryPing.js
|
||||
@BINPATH@/components/TelemetryPing.manifest
|
||||
@BINPATH@/components/Webapps.js
|
||||
@BINPATH@/components/Webapps.manifest
|
||||
|
||||
; Modules
|
||||
@BINPATH@/modules/*
|
||||
|
@ -2,5 +2,6 @@
|
||||
global:
|
||||
NSModule;
|
||||
NSGetModule;
|
||||
__RLD_MAP;
|
||||
local: *;
|
||||
};
|
||||
|
@ -2,5 +2,6 @@ EXPORTED {
|
||||
global:
|
||||
NSModule;
|
||||
NSGetModule;
|
||||
__RLD_MAP;
|
||||
local: *;
|
||||
};
|
||||
|
@ -2536,7 +2536,7 @@ ia64*-hpux*)
|
||||
# Use temp file for windres (bug 213281)
|
||||
RCFLAGS='-O coff --use-temp-file'
|
||||
# mingw doesn't require kernel32, user32, and advapi32 explicitly
|
||||
LIBS="$LIBS -luuid -lgdi32 -lwinmm -lwsock32"
|
||||
LIBS="$LIBS -luuid -lgdi32 -lwinmm -lwsock32 -luserenv"
|
||||
MOZ_FIX_LINK_PATHS=
|
||||
DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib -lxpcom -lxpcom_core -lmozalloc'
|
||||
XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/lib -lxpcom -lmozalloc'
|
||||
|
@ -116,7 +116,6 @@ _TEST_FILES1 = \
|
||||
test_bug364413.xhtml \
|
||||
test_bug366946.html \
|
||||
test_bug367164.html \
|
||||
test_bug371576-1.html \
|
||||
test_bug371576-2.html \
|
||||
test_bug371576-3.html \
|
||||
test_bug371576-4.html \
|
||||
|
@ -1,32 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=371576
|
||||
-->
|
||||
<head id="head">
|
||||
<title>Test for Bug 371576</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=371576">Mozilla Bug 371576</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var result = "A";
|
||||
var scrElem= document.createElement('script');
|
||||
scrElem.setAttribute('src','data:text/javascript,result+="C";$("content").innerHTML="--";result+="D";');
|
||||
$("head").appendChild(scrElem);
|
||||
result += "B";
|
||||
|
||||
</script>
|
||||
<script>result += "E"</script>
|
||||
<script>result += "F"</script>
|
||||
<script>is(result, "ABCDEF", "Wrong order of execution");</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -52,14 +52,18 @@ EXTRA_PP_COMPONENTS = \
|
||||
ConsoleAPI.manifest \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_JS_MODULES = ConsoleAPIStorage.jsm \
|
||||
$(NULL)
|
||||
|
||||
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
|
||||
EXTRA_COMPONENTS = \
|
||||
Webapps.js \
|
||||
Webapps.manifest \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_JS_MODULES = ConsoleAPIStorage.jsm \
|
||||
Webapps.jsm \
|
||||
EXTRA_JS_MODULES += Webapps.jsm \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIEntropyCollector.idl \
|
||||
|
@ -166,7 +166,7 @@ static bool init() {
|
||||
if (gSurfaceFunctions.initialized)
|
||||
return true;
|
||||
|
||||
void* handle = dlopen("/system/lib/libsurfaceflinger_client.so", RTLD_LAZY);
|
||||
void* handle = dlopen("libsurfaceflinger_client.so", RTLD_LAZY);
|
||||
|
||||
if (!handle) {
|
||||
LOG("Failed to open libsurfaceflinger_client.so");
|
||||
@ -176,7 +176,7 @@ static bool init() {
|
||||
gSurfaceFunctions.lock = (int (*)(void*, SurfaceInfo*, void*))dlsym(handle, "_ZN7android7Surface4lockEPNS0_11SurfaceInfoEPNS_6RegionEb");
|
||||
gSurfaceFunctions.unlockAndPost = (int (*)(void*))dlsym(handle, "_ZN7android7Surface13unlockAndPostEv");
|
||||
|
||||
handle = dlopen("/system/lib/libui.so", RTLD_LAZY);
|
||||
handle = dlopen("libui.so", RTLD_LAZY);
|
||||
if (!handle) {
|
||||
LOG("Failed to open libui.so");
|
||||
return false;
|
||||
|
@ -4,7 +4,7 @@
|
||||
"use strict";
|
||||
|
||||
let libcutils = (function () {
|
||||
let library = ctypes.open("/system/lib/libcutils.so");
|
||||
let library = ctypes.open("libcutils.so");
|
||||
|
||||
return {
|
||||
property_get: library.declare("property_get", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr, ctypes.char.ptr),
|
||||
|
@ -4,7 +4,7 @@
|
||||
"use strict";
|
||||
|
||||
let libhardware_legacy = (function () {
|
||||
let library = ctypes.open("/system/lib/libhardware_legacy.so");
|
||||
let library = ctypes.open("libhardware_legacy.so");
|
||||
|
||||
return {
|
||||
// Load wifi driver, 0 on success, < 0 on failure.
|
||||
|
@ -4,7 +4,7 @@
|
||||
"use strict";
|
||||
|
||||
let libnetutils = (function () {
|
||||
let library = ctypes.open("/system/lib/libnetutils.so");
|
||||
let library = ctypes.open("libnetutils.so");
|
||||
|
||||
return {
|
||||
ifc_enable: library.declare("ifc_enable", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
|
||||
|
@ -647,6 +647,10 @@ nsEditorEventListener::HandleText(nsIDOMEvent* aTextEvent)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Transfer the event's trusted-ness to our editor
|
||||
nsCOMPtr<nsIDOMNSEvent> NSEvent = do_QueryInterface(aTextEvent);
|
||||
nsAutoEditorKeypressOperation operation(mEditor, NSEvent);
|
||||
|
||||
return mEditor->UpdateIMEComposition(composedText, textRangeList);
|
||||
}
|
||||
|
||||
|
@ -969,6 +969,7 @@ nsPlaintextEditor::UpdateIMEComposition(const nsAString& aCompositionString,
|
||||
// list are empty when listing the Chinese characters. In this case,
|
||||
// we don't need to process composition string too. See bug 271815.
|
||||
|
||||
bool notifyEditorObservers = false;
|
||||
if (!aCompositionString.IsEmpty() || (mIMETextNode && aTextRangeList)) {
|
||||
mIMETextRangeList = aTextRangeList;
|
||||
|
||||
@ -992,9 +993,12 @@ nsPlaintextEditor::UpdateIMEComposition(const nsAString& aCompositionString,
|
||||
// If still composing, we should fire input event via observer.
|
||||
// Note that if committed, we don't need to notify it since it will be
|
||||
// notified at followed compositionend event.
|
||||
if (mIsIMEComposing) {
|
||||
NotifyEditorObservers();
|
||||
}
|
||||
// NOTE: We must notify after the auto batch will be gone.
|
||||
notifyEditorObservers = mIsIMEComposing;
|
||||
}
|
||||
|
||||
if (notifyEditorObservers) {
|
||||
NotifyEditorObservers();
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -65,6 +65,7 @@ _TEST_FILES = \
|
||||
test_bug645914.html \
|
||||
test_bug681229.html \
|
||||
test_bug692520.html \
|
||||
test_bug717147.html \
|
||||
$(NULL)
|
||||
|
||||
# disables the key handling test on gtk2 because gtk2 overrides some key events
|
||||
|
99
editor/libeditor/text/tests/test_bug717147.html
Normal file
99
editor/libeditor/text/tests/test_bug717147.html
Normal file
@ -0,0 +1,99 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=717147
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 717147</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"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717147">Mozilla Bug 717147</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<iframe id="formTarget" name="formTarget"></iframe>
|
||||
<form action="data:text/html," target="formTarget">
|
||||
<input name="test" id="initValue"><input type="submit">
|
||||
</form>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 717147 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(function() {
|
||||
var formTarget = document.getElementById("formTarget");
|
||||
var initValue = document.getElementById("initValue");
|
||||
|
||||
formTarget.addEventListener("load", function() {
|
||||
var newInput = document.createElement("input");
|
||||
newInput.setAttribute("name", "test");
|
||||
document.body.appendChild(newInput);
|
||||
|
||||
setTimeout(function() {
|
||||
var popupShown = false;
|
||||
function listener() {
|
||||
popupShown = true;
|
||||
}
|
||||
SpecialPowers.addAutoCompletePopupEventListener(window, listener);
|
||||
|
||||
newInput.value = "";
|
||||
newInput.focus();
|
||||
|
||||
synthesizeComposition({ type: "compositionstart" });
|
||||
synthesizeComposition({ type: "compositionupdate", data: "f" });
|
||||
synthesizeText(
|
||||
{ "composition":
|
||||
{ "string": "f",
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
});
|
||||
|
||||
hitEventLoop(function() {
|
||||
ok(!popupShown, "Popup must not be opened during composition");
|
||||
|
||||
synthesizeText(
|
||||
{ "composition":
|
||||
{ "string": "f",
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 0, "attr": 0 }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
});
|
||||
synthesizeComposition({ type: "compositionend", data: "f" });
|
||||
|
||||
hitEventLoop(function () {
|
||||
ok(popupShown, "Popup must be opened after compositionend");
|
||||
|
||||
SpecialPowers.removeAutoCompletePopupEventListener(window, listener);
|
||||
SimpleTest.finish();
|
||||
}, 100);
|
||||
}, 100);
|
||||
}, 0);
|
||||
}, false);
|
||||
|
||||
initValue.focus();
|
||||
initValue.value = "foo";
|
||||
synthesizeKey("VK_ENTER", {});
|
||||
});
|
||||
|
||||
function hitEventLoop(func, times) {
|
||||
if (times > 0) {
|
||||
setTimeout(hitEventLoop, 0, func, times - 1);
|
||||
} else {
|
||||
setTimeout(func, 0);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -69,11 +69,11 @@
|
||||
#include "AndroidBridge.h"
|
||||
#endif
|
||||
#include <android/log.h>
|
||||
#define EGL_LIB "/system/lib/libEGL.so"
|
||||
#define GLES2_LIB "/system/lib/libGLESv2.so"
|
||||
#define EGL_LIB "libEGL.so"
|
||||
#define GLES2_LIB "libGLESv2.so"
|
||||
#else
|
||||
#define EGL_LIB "/usr/lib/libEGL.so"
|
||||
#define GLES2_LIB "/usr/lib/libGLESv2.so"
|
||||
#define EGL_LIB "libEGL.so.1"
|
||||
#define GLES2_LIB "libGLESv2.so.2"
|
||||
#endif
|
||||
|
||||
typedef void *EGLNativeDisplayType;
|
||||
|
@ -69,6 +69,7 @@
|
||||
#include "nsCompressedCharMap.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
#include "cairo.h"
|
||||
#include "gfxFontTest.h"
|
||||
@ -81,6 +82,7 @@
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using mozilla::services::GetObserverService;
|
||||
|
||||
gfxFontCache *gfxFontCache::gGlobalCache = nsnull;
|
||||
|
||||
@ -954,6 +956,39 @@ gfxFontFamily::FindFont(const nsAString& aPostscriptName)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
/*
|
||||
* gfxFontCache - global cache of gfxFont instances.
|
||||
* Expires unused fonts after a short interval;
|
||||
* notifies fonts to age their cached shaped-word records;
|
||||
* observes memory-pressure notification and tells fonts to clear their
|
||||
* shaped-word caches to free up memory.
|
||||
*/
|
||||
|
||||
// Observer for the memory-pressure notification, to trigger
|
||||
// flushing of the shaped-word caches
|
||||
class MemoryPressureObserver : public nsIObserver,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS2(MemoryPressureObserver, nsIObserver, nsISupportsWeakReference)
|
||||
|
||||
NS_IMETHODIMP
|
||||
MemoryPressureObserver::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const PRUnichar *someData)
|
||||
{
|
||||
if (!nsCRT::strcmp(aTopic, "memory-pressure")) {
|
||||
gfxFontCache *fontCache = gfxFontCache::GetCache();
|
||||
if (fontCache) {
|
||||
fontCache->FlushShapedWordCaches();
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
gfxFontCache::Init()
|
||||
@ -986,6 +1021,12 @@ gfxFontCache::gfxFontCache()
|
||||
: nsExpirationTracker<gfxFont,3>(FONT_TIMEOUT_SECONDS * 1000)
|
||||
{
|
||||
mFonts.Init();
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
||||
if (obs) {
|
||||
obs->AddObserver(new MemoryPressureObserver, "memory-pressure", false);
|
||||
}
|
||||
|
||||
mWordCacheExpirationTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if (mWordCacheExpirationTimer) {
|
||||
mWordCacheExpirationTimer->
|
||||
@ -1102,6 +1143,14 @@ gfxFontCache::WordCacheExpirationTimerCallback(nsITimer* aTimer, void* aCache)
|
||||
cache->mFonts.EnumerateEntries(AgeCachedWordsForFont, nsnull);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
PLDHashOperator
|
||||
gfxFontCache::ClearCachedWordsForFont(HashEntry* aHashEntry, void* aUserData)
|
||||
{
|
||||
aHashEntry->mFont->ClearCachedWords();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
gfxFont::RunMetrics::CombineWith(const RunMetrics& aOther, bool aOtherIsOnLeft)
|
||||
{
|
||||
|
@ -732,6 +732,10 @@ public:
|
||||
AgeAllGenerations();
|
||||
}
|
||||
|
||||
void FlushShapedWordCaches() {
|
||||
mFonts.EnumerateEntries(ClearCachedWordsForFont, nsnull);
|
||||
}
|
||||
|
||||
protected:
|
||||
void DestroyFont(gfxFont *aFont);
|
||||
|
||||
@ -767,6 +771,7 @@ protected:
|
||||
|
||||
nsTHashtable<HashEntry> mFonts;
|
||||
|
||||
static PLDHashOperator ClearCachedWordsForFont(HashEntry* aHashEntry, void*);
|
||||
static PLDHashOperator AgeCachedWordsForFont(HashEntry* aHashEntry, void*);
|
||||
static void WordCacheExpirationTimerCallback(nsITimer* aTimer, void* aCache);
|
||||
nsCOMPtr<nsITimer> mWordCacheExpirationTimer;
|
||||
@ -1405,6 +1410,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Discard all cached word records; called on memory-pressure notification.
|
||||
void ClearCachedWords() {
|
||||
if (mWordCache.IsInitialized()) {
|
||||
mWordCache.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// Call the appropriate shaper to generate glyphs for aText and store
|
||||
// them into aShapedWord.
|
||||
|
@ -319,10 +319,12 @@ endif # }
|
||||
|
||||
ifneq (86,$(findstring 86,$(OS_TEST))) # {
|
||||
ifneq (arm,$(findstring arm,$(OS_TEST))) # {
|
||||
ifneq (mips,$(findstring mips,$(OS_TEST))) # {
|
||||
# Use mutex-backed atomics
|
||||
CPPSRCS += atomicops_internals_mutex.cc
|
||||
endif # }
|
||||
endif # }
|
||||
endif # }
|
||||
|
||||
OS_CXXFLAGS += $(TK_CFLAGS)
|
||||
|
||||
|
@ -136,6 +136,8 @@ Atomic64 Release_Load(volatile const Atomic64* ptr);
|
||||
#include "base/atomicops_internals_x86_gcc.h"
|
||||
#elif defined(COMPILER_GCC) && defined(ARCH_CPU_ARM_FAMILY)
|
||||
#include "base/atomicops_internals_arm_gcc.h"
|
||||
#elif defined(COMPILER_GCC) && defined(ARCH_CPU_MIPS)
|
||||
#include "base/atomicops_internals_mips_gcc.h"
|
||||
#else
|
||||
#include "base/atomicops_internals_mutex.h"
|
||||
#endif
|
||||
|
@ -2848,6 +2848,11 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
if toplevel.talksRpc():
|
||||
self.rpcSwitch.addcase(DefaultLabel(), default)
|
||||
|
||||
# FIXME/bug 535053: only manager protocols and non-manager
|
||||
# protocols with union types need Lookup(). we'll give it to
|
||||
# all for the time being (simpler)
|
||||
if 1 or ptype.isManager():
|
||||
self.cls.addstmts(self.implementManagerIface())
|
||||
|
||||
def makeHandlerMethod(name, switch, hasReply, dispatches=0):
|
||||
params = [ Decl(Type('Message', const=1, ref=1), msgvar.name) ]
|
||||
@ -3010,11 +3015,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
_runtimeAbort("'OnConnected' called on non-toplevel actor"))
|
||||
|
||||
self.cls.addstmts([ onconnected, Whitespace.NL ])
|
||||
# FIXME/bug 535053: only manager protocols and non-manager
|
||||
# protocols with union types need Lookup(). we'll give it to
|
||||
# all for the time being (simpler)
|
||||
if 1 or ptype.isManager():
|
||||
self.cls.addstmts(self.implementManagerIface())
|
||||
|
||||
# User-facing shmem methods
|
||||
self.cls.addstmts(self.makeShmemIface())
|
||||
|
@ -333,6 +333,9 @@ endif
|
||||
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
|
||||
#############################################
|
||||
@ -361,7 +364,7 @@ CPPSRCS += checks.cc \
|
||||
# For architectures without YARR JIT, PCRE is faster than the YARR
|
||||
# interpreter (bug 684559).
|
||||
|
||||
ifeq (,$(filter arm% sparc %86 x86_64,$(TARGET_CPU)))
|
||||
ifeq (,$(filter arm% sparc %86 x86_64 mips%,$(TARGET_CPU)))
|
||||
|
||||
VPATH += $(srcdir)/yarr/pcre \
|
||||
$(NULL)
|
||||
|
1089
js/src/assembler/assembler/MIPSAssembler.h
Normal file
1089
js/src/assembler/assembler/MIPSAssembler.h
Normal file
File diff suppressed because it is too large
Load Diff
2790
js/src/assembler/assembler/MacroAssemblerMIPS.h
Normal file
2790
js/src/assembler/assembler/MacroAssemblerMIPS.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1028,7 +1028,7 @@
|
||||
|
||||
/* The JIT is enabled by default on all x86, x64-64, ARM platforms. */
|
||||
#if !defined(ENABLE_JIT) \
|
||||
&& (WTF_CPU_X86 || WTF_CPU_X86_64 || WTF_CPU_ARM || WTF_CPU_SPARC32) \
|
||||
&& (WTF_CPU_X86 || WTF_CPU_X86_64 || WTF_CPU_ARM || WTF_CPU_SPARC32 || WTF_CPU_MIPS) \
|
||||
&& (WTF_OS_DARWIN || !WTF_COMPILER_GCC || GCC_VERSION_AT_LEAST(4, 1, 0)) \
|
||||
&& !WTF_OS_WINCE
|
||||
#define ENABLE_JIT 1
|
||||
|
@ -2811,6 +2811,14 @@ sparc*-*)
|
||||
AC_DEFINE(JS_CPU_SPARC)
|
||||
AC_DEFINE(JS_NUNBOX32)
|
||||
;;
|
||||
mips*-*)
|
||||
ENABLE_METHODJIT=1
|
||||
ENABLE_MONOIC=1
|
||||
ENABLE_POLYIC=1
|
||||
ENABLE_METHODJIT_TYPED_ARRAY=1
|
||||
AC_DEFINE(JS_CPU_MIPS)
|
||||
AC_DEFINE(JS_NUNBOX32)
|
||||
;;
|
||||
esac
|
||||
|
||||
MOZ_ARG_DISABLE_BOOL(methodjit,
|
||||
|
@ -1,32 +0,0 @@
|
||||
function leak_test() {
|
||||
// Create a reference loop function->script->traceFragment->object->function
|
||||
// that GC must be able to break. To embedd object into the fragment the
|
||||
// code use prototype chain of depth 2 which caches obj.__proto__.__proto__
|
||||
// into the fragment.
|
||||
|
||||
// To make sure that we have no references to the function f after this
|
||||
// function returns due via the conservative scan of the native stack we
|
||||
// loop here multiple times overwriting the stack and registers with new garabge.
|
||||
for (var j = 0; j != 8; ++j) {
|
||||
var f = Function("a", "var s = 0; for (var i = 0; i != 100; ++i) s += a.b; return s;");
|
||||
var c = {b: 1, f: f, leakDetection: makeFinalizeObserver()};
|
||||
f({ __proto__: { __proto__: c}});
|
||||
f = c = a = null;
|
||||
gc();
|
||||
}
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
if (typeof finalizeCount != "function")
|
||||
return;
|
||||
|
||||
var base = finalizeCount();
|
||||
leak_test();
|
||||
gc();
|
||||
gc();
|
||||
var n = finalizeCount();
|
||||
assertEq(base + 4 < finalizeCount(), true, "Some finalizations must happen");
|
||||
}
|
||||
|
||||
test();
|
@ -85,6 +85,7 @@ JITSTAT(archIs64BIT)
|
||||
JITSTAT(archIsARM)
|
||||
JITSTAT(archIsSPARC)
|
||||
JITSTAT(archIsPPC)
|
||||
JITSTAT(archIsMIPS)
|
||||
|
||||
#ifdef DEFINED_MONITOR_JITSTAT
|
||||
#undef DEFINED_MONITOR_JITSTAT
|
||||
|
@ -4064,8 +4064,11 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
|
||||
pushed[0].addType(cx, Type::UnknownType());
|
||||
break;
|
||||
|
||||
case JSOP_XMLNAME:
|
||||
case JSOP_CALLXMLNAME:
|
||||
pushed[1].addType(cx, Type::UnknownType());
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case JSOP_XMLNAME:
|
||||
pushed[0].addType(cx, Type::UnknownType());
|
||||
break;
|
||||
|
||||
|
@ -92,7 +92,11 @@ JSDOUBLE_IS_NaN(jsdouble d)
|
||||
{
|
||||
jsdpun u;
|
||||
u.d = d;
|
||||
#if defined(mips) || defined(__mips__) || defined(MIPS) || defined(_MIPS_)
|
||||
return (u.u64 & ~JSDOUBLE_SIGNBIT) > JSDOUBLE_EXPMASK;
|
||||
#else
|
||||
return (u.s.hi & JSDOUBLE_HI32_NAN) == JSDOUBLE_HI32_NAN;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
@ -581,7 +581,7 @@ class OpcodeCounts
|
||||
};
|
||||
|
||||
static bool elementOp(JSOp op) {
|
||||
return accessOp(op) && !!(js_CodeSpec[op].format & JOF_ELEM);
|
||||
return accessOp(op) && (JOF_MODE(js_CodeSpec[op].format) == JOF_ELEM);
|
||||
}
|
||||
|
||||
enum PropertyCounts {
|
||||
@ -593,7 +593,7 @@ class OpcodeCounts
|
||||
};
|
||||
|
||||
static bool propertyOp(JSOp op) {
|
||||
return accessOp(op) && !!(js_CodeSpec[op].format & JOF_PROP);
|
||||
return accessOp(op) && (JOF_MODE(js_CodeSpec[op].format) == JOF_PROP);
|
||||
}
|
||||
|
||||
enum ArithCounts {
|
||||
|
@ -174,6 +174,10 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::ARMRegiste
|
||||
static const JSC::MacroAssembler::RegisterID JSReturnReg_Type = JSC::SparcRegisters::l2;
|
||||
static const JSC::MacroAssembler::RegisterID JSReturnReg_Data = JSC::SparcRegisters::l3;
|
||||
static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::SparcRegisters::l4;
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
static const JSC::MacroAssembler::RegisterID JSReturnReg_Type = JSC::MIPSRegisters::a0;
|
||||
static const JSC::MacroAssembler::RegisterID JSReturnReg_Data = JSC::MIPSRegisters::a2;
|
||||
static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::MIPSRegisters::a1;
|
||||
#endif
|
||||
|
||||
size_t distanceOf(Label l) {
|
||||
@ -283,7 +287,7 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::SparcRegist
|
||||
static const uint64_t DoubleNegMask = 0x8000000000000000ULL;
|
||||
loadDouble(&DoubleNegMask, Registers::FPConversionTemp);
|
||||
xorDouble(Registers::FPConversionTemp, fpreg);
|
||||
#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
#elif defined JS_CPU_ARM || defined JS_CPU_SPARC || defined JS_CPU_MIPS
|
||||
negDouble(fpreg, fpreg);
|
||||
#endif
|
||||
}
|
||||
@ -318,6 +322,13 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::SparcRegist
|
||||
*/
|
||||
moveWithPatch(Imm32(intptr_t(fun)), JSC::SparcRegisters::i0);
|
||||
return JS_FUNC_TO_DATA_PTR(void *, JaegerStubVeneer);
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
/*
|
||||
* For MIPS, we need to call JaegerStubVeneer by passing
|
||||
* the real target address in v0.
|
||||
*/
|
||||
moveWithPatch(Imm32(intptr_t(fun)), JSC::MIPSRegisters::v0);
|
||||
return JS_FUNC_TO_DATA_PTR(void *, JaegerStubVeneer);
|
||||
#else
|
||||
/*
|
||||
* Architectures that push the return address to an easily-determined
|
||||
@ -358,10 +369,14 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::SparcRegist
|
||||
pop(reg);
|
||||
}
|
||||
|
||||
#if defined JS_CPU_MIPS
|
||||
static const uint32_t StackAlignment = 8;
|
||||
#else
|
||||
static const uint32_t StackAlignment = 16;
|
||||
#endif
|
||||
|
||||
static inline uint32_t alignForCall(uint32_t stackBytes) {
|
||||
#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
|
||||
#if defined(JS_CPU_X86) || defined(JS_CPU_X64) || defined(JS_CPU_MIPS)
|
||||
// If StackAlignment is a power of two, % is just two shifts.
|
||||
// 16 - (x % 16) gives alignment, extra % 16 handles total == 0.
|
||||
return align(stackBytes, StackAlignment);
|
||||
|
@ -944,8 +944,14 @@ mjit::Compiler::finishThisUp(JITScript **jitp)
|
||||
JaegerSpew(JSpew_Insns, "## Fast code (masm) size = %lu, Slow code (stubcc) size = %lu.\n",
|
||||
(unsigned long) masm.size(), (unsigned long) stubcc.size());
|
||||
|
||||
/* To make inlineDoubles and oolDoubles aligned to sizeof(double) bytes,
|
||||
MIPS adds extra sizeof(double) bytes to codeSize. */
|
||||
size_t codeSize = masm.size() +
|
||||
#if defined(JS_CPU_MIPS)
|
||||
stubcc.size() + sizeof(double) +
|
||||
#else
|
||||
stubcc.size() +
|
||||
#endif
|
||||
(masm.numDoubles() * sizeof(double)) +
|
||||
(stubcc.masm.numDoubles() * sizeof(double)) +
|
||||
jumpTableOffsets.length() * sizeof(void *);
|
||||
@ -1367,7 +1373,16 @@ mjit::Compiler::finishThisUp(JITScript **jitp)
|
||||
/* Link fast and slow paths together. */
|
||||
stubcc.fixCrossJumps(result, masm.size(), masm.size() + stubcc.size());
|
||||
|
||||
#if defined(JS_CPU_MIPS)
|
||||
/* Make sure doubleOffset is aligned to sizeof(double) bytes. */
|
||||
size_t doubleOffset = (((size_t)result + masm.size() + stubcc.size() +
|
||||
sizeof(double) - 1) & (~(sizeof(double) - 1))) -
|
||||
(size_t)result;
|
||||
JS_ASSERT((((size_t)result + doubleOffset) & 7) == 0);
|
||||
#else
|
||||
size_t doubleOffset = masm.size() + stubcc.size();
|
||||
#endif
|
||||
|
||||
double *inlineDoubles = (double *) (result + doubleOffset);
|
||||
double *oolDoubles = (double*) (result + doubleOffset +
|
||||
masm.numDoubles() * sizeof(double));
|
||||
@ -3398,7 +3413,7 @@ mjit::Compiler::interruptCheckHelper()
|
||||
void *interrupt = (void*) &JS_THREAD_DATA(cx)->interruptFlags;
|
||||
#endif
|
||||
|
||||
#if defined(JS_CPU_X86) || defined(JS_CPU_ARM)
|
||||
#if defined(JS_CPU_X86) || defined(JS_CPU_ARM) || defined(JS_CPU_MIPS)
|
||||
jump = masm.branch32(Assembler::NotEqual, AbsoluteAddress(interrupt), Imm32(0));
|
||||
#else
|
||||
/* Handle processors that can't load from absolute addresses. */
|
||||
|
@ -1432,13 +1432,24 @@ mjit::Compiler::jsop_relational_double(JSOp op, BoolStub stub, jsbytecode *targe
|
||||
stubcc.leave();
|
||||
OOL_STUBCALL(stub, REJOIN_BRANCH);
|
||||
|
||||
if (!allocateLeft)
|
||||
frame.pinReg(fpLeft);
|
||||
if (!allocateRight)
|
||||
frame.pinReg(fpRight);
|
||||
|
||||
frame.syncAndKillEverything();
|
||||
|
||||
Jump j = masm.branchDouble(dblCond, fpLeft, fpRight);
|
||||
|
||||
if (allocateLeft)
|
||||
frame.freeReg(fpLeft);
|
||||
else
|
||||
frame.unpinKilledReg(fpLeft);
|
||||
|
||||
if (allocateRight)
|
||||
frame.freeReg(fpRight);
|
||||
else
|
||||
frame.unpinKilledReg(fpRight);
|
||||
|
||||
frame.popn(2);
|
||||
|
||||
|
@ -2324,6 +2324,12 @@ mjit::Compiler::jsop_stricteq(JSOp op)
|
||||
masm.or32(result1, result);
|
||||
}
|
||||
frame.freeReg(result1);
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
/* On MIPS the result 0.0/0.0 is 0x7FF7FFFF.
|
||||
We need to manually set it to 0x7FF80000. */
|
||||
static const int ShiftedCanonicalNaNType = 0x7FF80000 << 1;
|
||||
masm.setShiftedCanonicalNaN(treg, treg);
|
||||
masm.setPtr(oppositeCond, treg, Imm32(ShiftedCanonicalNaNType), result);
|
||||
#elif !defined(JS_CPU_X64)
|
||||
static const int ShiftedCanonicalNaNType = 0x7FF80000 << 1;
|
||||
masm.setPtr(oppositeCond, treg, Imm32(ShiftedCanonicalNaNType), result);
|
||||
|
@ -1282,7 +1282,7 @@ FrameState::getCallee()
|
||||
}
|
||||
|
||||
inline void
|
||||
FrameState::unpinKilledReg(RegisterID reg)
|
||||
FrameState::unpinKilledReg(AnyRegisterID reg)
|
||||
{
|
||||
regstate(reg).unpinUnsafe();
|
||||
freeRegs.putReg(reg);
|
||||
|
@ -1498,10 +1498,11 @@ FrameState::syncAndKill(Registers kill, Uses uses, Uses ignore)
|
||||
if (!fe || deadEntry(fe, ignore.nuses))
|
||||
continue;
|
||||
|
||||
JS_ASSERT(fe->isTracked() && !fe->isType(JSVAL_TYPE_DOUBLE));
|
||||
JS_ASSERT(fe->isTracked());
|
||||
|
||||
if (regstate(reg).type() == RematInfo::DATA) {
|
||||
JS_ASSERT(fe->data.reg() == reg.reg());
|
||||
JS_ASSERT_IF(reg.isFPReg(), fe->data.fpreg() == reg.fpreg());
|
||||
JS_ASSERT_IF(!reg.isFPReg(), fe->data.reg() == reg.reg());
|
||||
JS_ASSERT(fe->data.synced());
|
||||
fe->data.setMemory();
|
||||
} else {
|
||||
|
@ -806,7 +806,7 @@ class FrameState
|
||||
/*
|
||||
* Same as unpinReg(), but does not restore the FrameEntry.
|
||||
*/
|
||||
inline void unpinKilledReg(RegisterID reg);
|
||||
inline void unpinKilledReg(AnyRegisterID reg);
|
||||
|
||||
/* Pins a data or type register if one exists. */
|
||||
MaybeRegisterID maybePinData(FrameEntry *fe);
|
||||
|
@ -88,6 +88,23 @@ class Repatcher : public JSC::RepatchBuffer
|
||||
*/
|
||||
CheckIsStubCall(call.labelAtOffset(0));
|
||||
JSC::RepatchBuffer::relink(call.callAtOffset(-4), stub);
|
||||
#elif defined JS_CPU_MIPS
|
||||
/*
|
||||
* Stub calls on MIPS look like this:
|
||||
*
|
||||
* lui v0, hi(stub)
|
||||
* ori v0, v0, lo(stub)
|
||||
* lui t9, hi(JaegerStubVeneer)
|
||||
* ori t9, t9, lo(JaegerStubVeneer)
|
||||
* jalr t9
|
||||
* nop
|
||||
* call label -> xxx
|
||||
*
|
||||
* MIPS has to run stub calls through a veneer in order for THROW to
|
||||
* work properly. The address that must be patched is the load into
|
||||
* 'v0', not the load into 't9'.
|
||||
*/
|
||||
JSC::RepatchBuffer::relink(call.callAtOffset(-8), stub);
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
@ -95,7 +112,7 @@ class Repatcher : public JSC::RepatchBuffer
|
||||
|
||||
/* Patch the offset of a Value load emitted by loadValueWithAddressOffsetPatch. */
|
||||
void patchAddressOffsetForValueLoad(CodeLocationLabel label, uint32_t offset) {
|
||||
#if defined JS_CPU_X64 || defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
#if defined JS_CPU_X64 || defined JS_CPU_ARM || defined JS_CPU_SPARC || defined JS_CPU_MIPS
|
||||
repatch(label.dataLabel32AtOffset(0), offset);
|
||||
#elif defined JS_CPU_X86
|
||||
static const unsigned LOAD_TYPE_OFFSET = 6;
|
||||
@ -115,7 +132,7 @@ class Repatcher : public JSC::RepatchBuffer
|
||||
}
|
||||
|
||||
void patchAddressOffsetForValueStore(CodeLocationLabel label, uint32_t offset, bool typeConst) {
|
||||
#if defined JS_CPU_ARM || defined JS_CPU_X64 || defined JS_CPU_SPARC
|
||||
#if defined JS_CPU_ARM || defined JS_CPU_X64 || defined JS_CPU_SPARC || defined JS_CPU_MIPS
|
||||
(void) typeConst;
|
||||
repatch(label.dataLabel32AtOffset(0), offset);
|
||||
#elif defined JS_CPU_X86
|
||||
|
@ -122,6 +122,8 @@ struct Registers {
|
||||
static const RegisterID JSFrameReg = JSC::ARMRegisters::r10;
|
||||
#elif defined(JS_CPU_SPARC)
|
||||
static const RegisterID JSFrameReg = JSC::SparcRegisters::l0;
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
static const RegisterID JSFrameReg = JSC::MIPSRegisters::s0;
|
||||
#endif
|
||||
|
||||
#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
|
||||
@ -152,6 +154,12 @@ struct Registers {
|
||||
static const RegisterID ArgReg3 = JSC::SparcRegisters::o3;
|
||||
static const RegisterID ArgReg4 = JSC::SparcRegisters::o4;
|
||||
static const RegisterID ArgReg5 = JSC::SparcRegisters::o5;
|
||||
#elif JS_CPU_MIPS
|
||||
static const RegisterID ReturnReg = JSC::MIPSRegisters::v0;
|
||||
static const RegisterID ArgReg0 = JSC::MIPSRegisters::a0;
|
||||
static const RegisterID ArgReg1 = JSC::MIPSRegisters::a1;
|
||||
static const RegisterID ArgReg2 = JSC::MIPSRegisters::a2;
|
||||
static const RegisterID ArgReg3 = JSC::MIPSRegisters::a3;
|
||||
#endif
|
||||
|
||||
static const RegisterID StackPointer = JSC::MacroAssembler::stackPointerRegister;
|
||||
@ -252,6 +260,33 @@ struct Registers {
|
||||
| (1 << JSC::SparcRegisters::l6)
|
||||
| (1 << JSC::SparcRegisters::l7);
|
||||
|
||||
static const uint32_t SingleByteRegs = TempRegs | SavedRegs;
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
static const uint32_t TempRegs =
|
||||
(1 << JSC::MIPSRegisters::at)
|
||||
| (1 << JSC::MIPSRegisters::v0)
|
||||
| (1 << JSC::MIPSRegisters::v1)
|
||||
| (1 << JSC::MIPSRegisters::a0)
|
||||
| (1 << JSC::MIPSRegisters::a1)
|
||||
| (1 << JSC::MIPSRegisters::a2)
|
||||
| (1 << JSC::MIPSRegisters::a3)
|
||||
| (1 << JSC::MIPSRegisters::t5)
|
||||
| (1 << JSC::MIPSRegisters::t6)
|
||||
| (1 << JSC::MIPSRegisters::t7);
|
||||
/* t0-t4,t9 is reserved as a scratch register for the assembler.
|
||||
We don't use t8 ($24), as we limit ourselves within $0 to $23 to
|
||||
leave the bitmask for 8 FP registers. */
|
||||
|
||||
static const uint32_t SavedRegs =
|
||||
(1 << JSC::MIPSRegisters::s1)
|
||||
| (1 << JSC::MIPSRegisters::s2)
|
||||
| (1 << JSC::MIPSRegisters::s3)
|
||||
| (1 << JSC::MIPSRegisters::s4)
|
||||
| (1 << JSC::MIPSRegisters::s5)
|
||||
| (1 << JSC::MIPSRegisters::s6)
|
||||
| (1 << JSC::MIPSRegisters::s7);
|
||||
// s0 is reserved for JSFrameReg.
|
||||
|
||||
static const uint32_t SingleByteRegs = TempRegs | SavedRegs;
|
||||
#else
|
||||
# error "Unsupported platform"
|
||||
@ -287,6 +322,8 @@ struct Registers {
|
||||
return 4;
|
||||
#elif defined(JS_CPU_SPARC)
|
||||
return 6;
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
return 4;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -337,6 +374,13 @@ struct Registers {
|
||||
JSC::SparcRegisters::o4,
|
||||
JSC::SparcRegisters::o5
|
||||
};
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
static const RegisterID regs[] = {
|
||||
JSC::MIPSRegisters::a0,
|
||||
JSC::MIPSRegisters::a1,
|
||||
JSC::MIPSRegisters::a2,
|
||||
JSC::MIPSRegisters::a3,
|
||||
};
|
||||
#endif
|
||||
JS_ASSERT(numArgRegs(conv) == mozilla::ArrayLength(regs));
|
||||
if (i > mozilla::ArrayLength(regs))
|
||||
@ -386,6 +430,19 @@ struct Registers {
|
||||
| (1 << JSC::SparcRegisters::f6)
|
||||
) << TotalRegisters;
|
||||
static const FPRegisterID FPConversionTemp = JSC::SparcRegisters::f8;
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
/* TotalRegisters is 24, so TotalFPRegisters can be 8 to have a 32-bit
|
||||
bit mask.
|
||||
Note that the O32 ABI can access only even FP registers. */
|
||||
static const uint32_t TotalFPRegisters = 8;
|
||||
static const uint32_t TempFPRegs = (uint32_t)(
|
||||
(1 << JSC::MIPSRegisters::f0)
|
||||
| (1 << JSC::MIPSRegisters::f2)
|
||||
| (1 << JSC::MIPSRegisters::f4)
|
||||
| (1 << JSC::MIPSRegisters::f6)
|
||||
) << TotalRegisters;
|
||||
// f16 is reserved as a scratch register for the assembler.
|
||||
static const FPRegisterID FPConversionTemp = JSC::MIPSRegisters::f18;
|
||||
#else
|
||||
# error "Unsupported platform"
|
||||
#endif
|
||||
@ -397,6 +454,8 @@ struct Registers {
|
||||
static const RegisterID ClobberInCall = JSC::ARMRegisters::r2;
|
||||
#elif defined(JS_CPU_SPARC)
|
||||
static const RegisterID ClobberInCall = JSC::SparcRegisters::l1;
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
static const RegisterID ClobberInCall = JSC::MIPSRegisters::at;
|
||||
#endif
|
||||
|
||||
static const uint32_t AvailFPRegs = TempFPRegs;
|
||||
|
@ -253,7 +253,7 @@ JS_STATIC_ASSERT(offsetof(FrameRegs, sp) == 0);
|
||||
#if defined(__GNUC__) && !defined(_WIN64)
|
||||
|
||||
/* If this assert fails, you need to realign VMFrame to 16 bytes. */
|
||||
#ifdef JS_CPU_ARM
|
||||
#if defined(JS_CPU_ARM) || defined(JS_CPU_MIPS)
|
||||
JS_STATIC_ASSERT(sizeof(VMFrame) % 8 == 0);
|
||||
#else
|
||||
JS_STATIC_ASSERT(sizeof(VMFrame) % 16 == 0);
|
||||
@ -822,6 +822,7 @@ SYMBOL_STRING(JaegerStubVeneer) ":" "\n"
|
||||
);
|
||||
|
||||
# elif defined(JS_CPU_SPARC)
|
||||
# elif defined(JS_CPU_MIPS)
|
||||
# else
|
||||
# error "Unsupported CPU!"
|
||||
# endif
|
||||
|
@ -52,7 +52,8 @@
|
||||
#if !defined JS_CPU_X64 && \
|
||||
!defined JS_CPU_X86 && \
|
||||
!defined JS_CPU_SPARC && \
|
||||
!defined JS_CPU_ARM
|
||||
!defined JS_CPU_ARM && \
|
||||
!defined JS_CPU_MIPS
|
||||
# error "Oh no, you should define a platform so this compiles."
|
||||
#endif
|
||||
|
||||
@ -97,6 +98,13 @@ struct VMFrame
|
||||
|
||||
void *reserve_0;
|
||||
void *reserve_1;
|
||||
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
/* Reserved 16 bytes for a0-a3 space in MIPS O32 ABI */
|
||||
void *unused0;
|
||||
void *unused1;
|
||||
void *unused2;
|
||||
void *unused3;
|
||||
#endif
|
||||
|
||||
union Arguments {
|
||||
@ -204,6 +212,22 @@ struct VMFrame
|
||||
inline void** returnAddressLocation() {
|
||||
return reinterpret_cast<void**>(&this->veneerReturn);
|
||||
}
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
void *savedS0;
|
||||
void *savedS1;
|
||||
void *savedS2;
|
||||
void *savedS3;
|
||||
void *savedS4;
|
||||
void *savedS5;
|
||||
void *savedS6;
|
||||
void *savedS7;
|
||||
void *savedGP;
|
||||
void *savedRA;
|
||||
void *unused4; // For alignment.
|
||||
|
||||
inline void** returnAddressLocation() {
|
||||
return reinterpret_cast<void**>(this) - 1;
|
||||
}
|
||||
#else
|
||||
# error "The VMFrame layout isn't defined for your processor architecture!"
|
||||
#endif
|
||||
@ -226,6 +250,9 @@ struct VMFrame
|
||||
#if defined(JS_CPU_SPARC)
|
||||
static const size_t offsetOfFp = 30 * sizeof(void *) + FrameRegs::offsetOfFp;
|
||||
static const size_t offsetOfInlined = 30 * sizeof(void *) + FrameRegs::offsetOfInlined;
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
static const size_t offsetOfFp = 8 * sizeof(void *) + FrameRegs::offsetOfFp;
|
||||
static const size_t offsetOfInlined = 8 * sizeof(void *) + FrameRegs::offsetOfInlined;
|
||||
#else
|
||||
static const size_t offsetOfFp = 4 * sizeof(void *) + FrameRegs::offsetOfFp;
|
||||
static const size_t offsetOfInlined = 4 * sizeof(void *) + FrameRegs::offsetOfInlined;
|
||||
@ -237,7 +264,7 @@ struct VMFrame
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(JS_CPU_ARM) || defined(JS_CPU_SPARC)
|
||||
#if defined(JS_CPU_ARM) || defined(JS_CPU_SPARC) || defined(JS_CPU_MIPS)
|
||||
// WARNING: Do not call this function directly from C(++) code because it is not ABI-compliant.
|
||||
extern "C" void JaegerStubVeneer(void);
|
||||
#endif
|
||||
|
@ -207,6 +207,12 @@ class NunboxAssembler : public JSC::MacroAssembler
|
||||
JS_ASSERT(differenceBetween(start, load) == 0);
|
||||
(void) load;
|
||||
return start;
|
||||
#elif defined JS_CPU_MIPS
|
||||
/*
|
||||
* On MIPS there are LUI/ORI to patch.
|
||||
*/
|
||||
load64WithPatch(address, treg, dreg, TAG_OFFSET, PAYLOAD_OFFSET);
|
||||
return start;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -232,6 +238,12 @@ class NunboxAssembler : public JSC::MacroAssembler
|
||||
return start;
|
||||
#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
return store64WithAddressOffsetPatch(treg, dreg, address);
|
||||
#elif defined JS_CPU_MIPS
|
||||
/*
|
||||
* On MIPS there are LUI/ORI to patch.
|
||||
*/
|
||||
store64WithPatch(address, treg, dreg, TAG_OFFSET, PAYLOAD_OFFSET);
|
||||
return start;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -248,6 +260,12 @@ class NunboxAssembler : public JSC::MacroAssembler
|
||||
return start;
|
||||
#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
return store64WithAddressOffsetPatch(type, dreg, address);
|
||||
#elif defined JS_CPU_MIPS
|
||||
/*
|
||||
* On MIPS there are LUI/ORI to patch.
|
||||
*/
|
||||
store64WithPatch(address, type, dreg, TAG_OFFSET, PAYLOAD_OFFSET);
|
||||
return start;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -267,6 +285,12 @@ class NunboxAssembler : public JSC::MacroAssembler
|
||||
return start;
|
||||
#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
return store64WithAddressOffsetPatch(type, payload, address);
|
||||
#elif defined JS_CPU_MIPS
|
||||
/*
|
||||
* On MIPS there are LUI/ORI to patch.
|
||||
*/
|
||||
store64WithPatch(address, type, payload, TAG_OFFSET, PAYLOAD_OFFSET);
|
||||
return start;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -470,6 +494,12 @@ class NunboxAssembler : public JSC::MacroAssembler
|
||||
#elif defined JS_CPU_ARM
|
||||
// Yes, we are backwards from SPARC.
|
||||
fastStoreDouble(srcDest, dataReg, typeReg);
|
||||
#elif defined JS_CPU_MIPS
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
fastStoreDouble(srcDest, dataReg, typeReg);
|
||||
#else
|
||||
fastStoreDouble(srcDest, typeReg, dataReg);
|
||||
#endif
|
||||
#else
|
||||
JS_NOT_REACHED("implement this - push double, pop pop is easiest");
|
||||
#endif
|
||||
|
344
js/src/methodjit/TrampolineMIPS.cpp
Normal file
344
js/src/methodjit/TrampolineMIPS.cpp
Normal file
@ -0,0 +1,344 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 et tw=99:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Jaegermonkey.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Foundation.
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chao-ying Fu <fu@mips.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jstypes.h"
|
||||
|
||||
/*
|
||||
* The MIPS VMFrame is 112 bytes as follows.
|
||||
*
|
||||
* 108 [ unused4 ] For alignment.
|
||||
* 104 [ ra ]
|
||||
* 100 [ gp ] If PIC code is generated, we will save gp.
|
||||
* 96 [ s7 ]
|
||||
* 92 [ s6 ]
|
||||
* 88 [ s5 ]
|
||||
* 84 [ s4 ]
|
||||
* 80 [ s3 ]
|
||||
* 76 [ s2 ]
|
||||
* 72 [ s1 ]
|
||||
* 68 [ s0 ]
|
||||
* 64 [ stubRejoin ]
|
||||
* 60 [ entrycode ]
|
||||
* 56 [ entryfp ]
|
||||
* 52 [ stkLimit ]
|
||||
* 48 [ cx ]
|
||||
* 44 [ regs.fp_ ]
|
||||
* 40 [ regs.inlined_]
|
||||
* 36 [ regs.pc ]
|
||||
* 32 [ regs.sp ]
|
||||
* 28 [ scratch ]
|
||||
* 24 [ previous ]
|
||||
* 20 [ args.ptr2 ] [ dynamicArgc ] (union)
|
||||
* 16 [ args.ptr ] [ lazyArgsObj ] (union)
|
||||
* 12 [ unused3 ] O32 ABI, space for a3 (used in callee)
|
||||
* 8 [ unused2 ] O32 ABI, space for a2 (used in callee)
|
||||
* 4 [ unused1 ] O32 ABI, space for a1 (used in callee)
|
||||
* 0 [ unused0 ] O32 ABI, space for a0 (used in callee)
|
||||
*/
|
||||
|
||||
asm (
|
||||
".text" "\n"
|
||||
".align 2" "\n"
|
||||
".set noreorder" "\n"
|
||||
".set nomacro" "\n"
|
||||
".set nomips16" "\n"
|
||||
".globl JaegerThrowpoline" "\n"
|
||||
".ent JaegerThrowpoline" "\n"
|
||||
".type JaegerThrowpoline,@function" "\n"
|
||||
"JaegerThrowpoline:" "\n"
|
||||
#if defined(__PIC__)
|
||||
"lw $28,100($29)" "\n"
|
||||
"la $25,js_InternalThrow" "\n"
|
||||
".reloc 1f,R_MIPS_JALR,js_InternalThrow" "\n"
|
||||
"1: jalr $25" "\n"
|
||||
"move $4,$29 # set up a0" "\n"
|
||||
#else
|
||||
"jal js_InternalThrow" "\n"
|
||||
"move $4,$29 # set up a0" "\n"
|
||||
#endif
|
||||
"beq $2,$0,1f" "\n"
|
||||
"nop" "\n"
|
||||
"jr $2 # jump to a scripted handler" "\n"
|
||||
"nop" "\n"
|
||||
"1:" "\n"
|
||||
#if defined(__PIC__)
|
||||
"lw $28,100($29)" "\n"
|
||||
"la $25,PopActiveVMFrame" "\n"
|
||||
".reloc 1f,R_MIPS_JALR,PopActiveVMFrame" "\n"
|
||||
"1: jalr $25" "\n"
|
||||
"move $4,$29 # set up a0" "\n"
|
||||
#else
|
||||
"jal PopActiveVMFrame" "\n"
|
||||
"move $4,$29 # set up a0" "\n"
|
||||
#endif
|
||||
"lw $31,104($29)" "\n"
|
||||
#if defined(__PIC__)
|
||||
"lw $28,100($29)" "\n"
|
||||
#endif
|
||||
"lw $23,96($29)" "\n"
|
||||
"lw $22,92($29)" "\n"
|
||||
"lw $21,88($29)" "\n"
|
||||
"lw $20,84($29)" "\n"
|
||||
"lw $19,80($29)" "\n"
|
||||
"lw $18,76($29)" "\n"
|
||||
"lw $17,72($29)" "\n"
|
||||
"lw $16,68($29)" "\n"
|
||||
"li $2,0 # return 0 to represent an unhandled exception." "\n"
|
||||
"jr $31" "\n"
|
||||
"addiu $29,$29,112" "\n"
|
||||
".set reorder" "\n"
|
||||
".set macro" "\n"
|
||||
".end JaegerThrowpoline" "\n"
|
||||
".size JaegerThrowpoline,.-JaegerThrowpoline" "\n"
|
||||
);
|
||||
|
||||
asm (
|
||||
".text" "\n"
|
||||
".align 2" "\n"
|
||||
".set noreorder" "\n"
|
||||
".set nomacro" "\n"
|
||||
".set nomips16" "\n"
|
||||
".globl JaegerTrampoline" "\n"
|
||||
".ent JaegerTrampoline" "\n"
|
||||
".type JaegerTrampoline,@function" "\n"
|
||||
"JaegerTrampoline:" "\n"
|
||||
#if defined(__PIC__)
|
||||
"lui $28,%hi(_gp_disp)" "\n"
|
||||
"addiu $28,$28,%lo(_gp_disp)" "\n"
|
||||
"addu $28,$28,$25" "\n"
|
||||
#endif
|
||||
"addiu $29,$29,-112" "\n"
|
||||
"sw $31,104($29)" "\n"
|
||||
#if defined(__PIC__)
|
||||
"sw $28,100($29)" "\n"
|
||||
#endif
|
||||
"sw $23,96($29)" "\n"
|
||||
"sw $22,92($29)" "\n"
|
||||
"sw $21,88($29)" "\n"
|
||||
"sw $20,84($29)" "\n"
|
||||
"sw $19,80($29)" "\n"
|
||||
"sw $18,76($29)" "\n"
|
||||
"sw $17,72($29)" "\n"
|
||||
"sw $16,68($29)" "\n"
|
||||
"sw $0,64($29) # stubRejoin" "\n"
|
||||
"sw $5,60($29) # entrycode" "\n"
|
||||
"sw $5,56($29) # entryfp" "\n"
|
||||
"sw $7,52($29) # stackLimit" "\n"
|
||||
"sw $4,48($29) # cx" "\n"
|
||||
"sw $5,44($29) # regs.fp" "\n"
|
||||
"move $16,$5 # preserve fp to s0" "\n"
|
||||
"move $17,$6 # preserve code to s1" "\n"
|
||||
#if defined(__PIC__)
|
||||
"la $25,PushActiveVMFrame" "\n"
|
||||
".reloc 1f,R_MIPS_JALR,PushActiveVMFrame" "\n"
|
||||
"1: jalr $25" "\n"
|
||||
"move $4,$29 # set up a0" "\n"
|
||||
#else
|
||||
"jal PushActiveVMFrame" "\n"
|
||||
"move $4,$29 # set up a0" "\n"
|
||||
#endif
|
||||
|
||||
"move $25,$17 # move code to $25" "\n"
|
||||
"jr $25 # jump to the compiled JavaScript Function" "\n"
|
||||
"nop" "\n"
|
||||
".set reorder" "\n"
|
||||
".set macro" "\n"
|
||||
".end JaegerTrampoline" "\n"
|
||||
".size JaegerTrampoline,.-JaegerTrampoline" "\n"
|
||||
);
|
||||
|
||||
asm (
|
||||
".text" "\n"
|
||||
".align 2" "\n"
|
||||
".set noreorder" "\n"
|
||||
".set nomacro" "\n"
|
||||
".set nomips16" "\n"
|
||||
".globl JaegerTrampolineReturn" "\n"
|
||||
".ent JaegerTrampolineReturn" "\n"
|
||||
".type JaegerTrampolineReturn,@function" "\n"
|
||||
"JaegerTrampolineReturn:" "\n"
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
"sw $4,28($16) # a0: fp->rval type for LITTLE-ENDIAN" "\n"
|
||||
"sw $6,24($16) # a2: fp->rval data for LITTLE-ENDIAN" "\n"
|
||||
#else
|
||||
"sw $4,24($16) # a0: fp->rval type for BIG-ENDIAN" "\n"
|
||||
"sw $6,28($16) # a2: fp->rval data for BIG-ENDIAN" "\n"
|
||||
#endif
|
||||
#if defined(__PIC__)
|
||||
"lw $28,100($29)" "\n"
|
||||
"la $25,PopActiveVMFrame" "\n"
|
||||
".reloc 1f,R_MIPS_JALR,PopActiveVMFrame" "\n"
|
||||
"1: jalr $25" "\n"
|
||||
"move $4,$29 # set up a0" "\n"
|
||||
#else
|
||||
"jal PopActiveVMFrame" "\n"
|
||||
"move $4,$29 # set up a0" "\n"
|
||||
#endif
|
||||
"lw $31,104($29)" "\n"
|
||||
#if defined(__PIC__)
|
||||
"lw $28,100($29)" "\n"
|
||||
#endif
|
||||
"lw $23,96($29)" "\n"
|
||||
"lw $22,92($29)" "\n"
|
||||
"lw $21,88($29)" "\n"
|
||||
"lw $20,84($29)" "\n"
|
||||
"lw $19,80($29)" "\n"
|
||||
"lw $18,76($29)" "\n"
|
||||
"lw $17,72($29)" "\n"
|
||||
"lw $16,68($29)" "\n"
|
||||
"li $2,1 # return ture to indicate successful completion" "\n"
|
||||
"jr $31" "\n"
|
||||
"addiu $29,$29,112" "\n"
|
||||
".set reorder" "\n"
|
||||
".set macro" "\n"
|
||||
".end JaegerTrampolineReturn" "\n"
|
||||
".size JaegerTrampolineReturn,.-JaegerTrampolineReturn" "\n"
|
||||
);
|
||||
|
||||
asm (
|
||||
".text" "\n"
|
||||
".align 2" "\n"
|
||||
".set noreorder" "\n"
|
||||
".set nomacro" "\n"
|
||||
".set nomips16" "\n"
|
||||
".globl JaegerStubVeneer" "\n"
|
||||
".ent JaegerStubVeneer" "\n"
|
||||
".type JaegerStubVeneer,@function" "\n"
|
||||
"JaegerStubVeneer:" "\n"
|
||||
"addiu $29,$29,-24 # Need 16 (a0-a3) + 4 (align) + 4 ($31) bytes" "\n"
|
||||
"sw $31,20($29) # Store $31 to 20($29)" "\n"
|
||||
"move $25,$2 # the target address is passed from $2" "\n"
|
||||
"jalr $25" "\n"
|
||||
"nop" "\n"
|
||||
"lw $31,20($29)" "\n"
|
||||
"jr $31" "\n"
|
||||
"addiu $29,$29,24" "\n"
|
||||
".set reorder" "\n"
|
||||
".set macro" "\n"
|
||||
".end JaegerStubVeneer" "\n"
|
||||
".size JaegerStubVeneer,.-JaegerStubVeneer" "\n"
|
||||
);
|
||||
|
||||
asm (
|
||||
".text" "\n"
|
||||
".align 2" "\n"
|
||||
".set noreorder" "\n"
|
||||
".set nomacro" "\n"
|
||||
".set nomips16" "\n"
|
||||
".globl JaegerInterpolineScripted" "\n"
|
||||
".ent JaegerInterpolineScripted" "\n"
|
||||
".type JaegerInterpolineScripted,@function" "\n"
|
||||
"JaegerInterpolineScripted:" "\n"
|
||||
"lw $16,16($16) # Load f->prev_" "\n"
|
||||
"b JaegerInterpoline" "\n"
|
||||
"sw $16,44($29) # Update f->regs->fp_" "\n"
|
||||
".set reorder" "\n"
|
||||
".set macro" "\n"
|
||||
".end JaegerInterpolineScripted" "\n"
|
||||
".size JaegerInterpolineScripted,.-JaegerInterpolineScripted" "\n"
|
||||
);
|
||||
|
||||
asm (
|
||||
".text" "\n"
|
||||
".align 2" "\n"
|
||||
".set noreorder" "\n"
|
||||
".set nomacro" "\n"
|
||||
".set nomips16" "\n"
|
||||
".globl JaegerInterpoline" "\n"
|
||||
".ent JaegerInterpoline" "\n"
|
||||
".type JaegerInterpoline,@function" "\n"
|
||||
"JaegerInterpoline:" "\n"
|
||||
"move $5,$4 # returntype" "\n"
|
||||
"move $4,$6 # returnData" "\n"
|
||||
"move $6,$2 # returnReg" "\n"
|
||||
#if defined(__PIC__)
|
||||
"lw $28,100($29)" "\n"
|
||||
"la $25,js_InternalInterpret" "\n"
|
||||
".reloc 1f,R_MIPS_JALR,js_InternalInterpret" "\n"
|
||||
"1: jalr $25" "\n"
|
||||
"move $7,$29 # f" "\n"
|
||||
#else
|
||||
"jal js_InternalInterpret" "\n"
|
||||
"move $7,$29 # f" "\n"
|
||||
#endif
|
||||
"lw $16,44($29) # Load f->regs->fp_ to s0" "\n"
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
"lw $4,28($16) # a0: fp->rval type for LITTLE-ENDIAN" "\n"
|
||||
"lw $6,24($16) # a2: fp->rval data for LITTLE-ENDIAN" "\n"
|
||||
#else
|
||||
"lw $4,24($16) # a0: fp->rval type for BIG-ENDIAN" "\n"
|
||||
"lw $6,28($16) # a2: fp->rval data for BIG-ENDIAN" "\n"
|
||||
#endif
|
||||
"lw $5,28($29) # Load sctrach -> argc" "\n"
|
||||
"beq $2,$0,1f" "\n"
|
||||
"nop" "\n"
|
||||
"jr $2" "\n"
|
||||
"nop" "\n"
|
||||
"1:" "\n"
|
||||
#if defined(__PIC__)
|
||||
"lw $28,100($29)" "\n"
|
||||
"la $25,PopActiveVMFrame" "\n"
|
||||
".reloc 1f,R_MIPS_JALR,PopActiveVMFrame" "\n"
|
||||
"1: jalr $25" "\n"
|
||||
"move $4,$29 # set up a0" "\n"
|
||||
#else
|
||||
"jal PopActiveVMFrame" "\n"
|
||||
"move $4,$29 # set up a0" "\n"
|
||||
#endif
|
||||
"lw $31,104($29)" "\n"
|
||||
#if defined(__PIC__)
|
||||
"lw $28,100($29)" "\n"
|
||||
#endif
|
||||
"lw $23,96($29)" "\n"
|
||||
"lw $22,92($29)" "\n"
|
||||
"lw $21,88($29)" "\n"
|
||||
"lw $20,84($29)" "\n"
|
||||
"lw $19,80($29)" "\n"
|
||||
"lw $18,76($29)" "\n"
|
||||
"lw $17,72($29)" "\n"
|
||||
"lw $16,68($29)" "\n"
|
||||
"li $2,0 # return 0" "\n"
|
||||
"jr $31" "\n"
|
||||
"addiu $29,$29,112" "\n"
|
||||
".set reorder" "\n"
|
||||
".set macro" "\n"
|
||||
".end JaegerInterpoline" "\n"
|
||||
".size JaegerInterpoline,.-JaegerInterpoline" "\n"
|
||||
);
|
@ -196,7 +196,7 @@ const CharacterInfo js_charinfo[] = {
|
||||
{58272, 0, 2},
|
||||
};
|
||||
|
||||
const uint16_t index1[] = {
|
||||
const uint8_t index1[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 34,
|
||||
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
|
||||
@ -256,7 +256,7 @@ const uint16_t index1[] = {
|
||||
26, 26, 26, 26, 164, 165, 166, 167, 168, 169, 26, 170, 171, 172, 173, 174,
|
||||
};
|
||||
|
||||
const uint16_t index2[] = {
|
||||
const uint8_t index2[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
|
||||
|
@ -160,14 +160,14 @@ class CharacterInfo {
|
||||
}
|
||||
};
|
||||
|
||||
extern const uint16_t index1[];
|
||||
extern const uint16_t index2[];
|
||||
extern const uint8_t index1[];
|
||||
extern const uint8_t index2[];
|
||||
extern const CharacterInfo js_charinfo[];
|
||||
|
||||
inline const CharacterInfo&
|
||||
CharInfo(jschar code)
|
||||
{
|
||||
uint16_t index = index1[code >> 6];
|
||||
size_t index = index1[code >> 6];
|
||||
index = index2[(index << 6) + (code & 0x3f)];
|
||||
|
||||
return js_charinfo[index];
|
||||
|
@ -267,13 +267,13 @@ if (typeof reportCompare === "function")
|
||||
data_file.write('\n')
|
||||
|
||||
def dump(data, name, file):
|
||||
file.write('const uint16_t ' + name + '[] = {\n')
|
||||
file.write('const uint8_t ' + name + '[] = {\n')
|
||||
|
||||
line = pad = ' ' * 4
|
||||
lines = []
|
||||
for entry in data:
|
||||
assert entry < 256
|
||||
s = str(entry)
|
||||
assert len(s) <= 3
|
||||
s = s.rjust(3)
|
||||
|
||||
if len(line + s) + 5 > 99:
|
||||
|
@ -58,7 +58,9 @@
|
||||
|
||||
static int gDummyCounter;
|
||||
|
||||
static void
|
||||
// Not inlining this function avoids the compiler making optimizations
|
||||
// that end up corrupting stack traces.
|
||||
MOZ_NEVER_INLINE static void
|
||||
TouchBadMemory()
|
||||
{
|
||||
// XXX this should use the frame poisoning code
|
||||
|
@ -66,6 +66,7 @@ class ConfirmPreference extends DialogPreference {
|
||||
GeckoAppShell.getHandler().post(new Runnable(){
|
||||
public void run() {
|
||||
BrowserDB.clearHistory(mContext.getContentResolver());
|
||||
GeckoApp.mAppContext.mFavicons.clearFavicons();
|
||||
}
|
||||
});
|
||||
} else if ("clear_private_data".equalsIgnoreCase(mAction)) {
|
||||
|
@ -152,6 +152,12 @@ public class Favicons {
|
||||
|
||||
db.replace(TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
|
||||
public void clearFavicons() {
|
||||
SQLiteDatabase db = mDbHelper.getWritableDatabase();
|
||||
db.delete(TABLE_NAME, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
public Favicons(Context context) {
|
||||
@ -199,6 +205,10 @@ public class Favicons {
|
||||
return task.cancel(false);
|
||||
}
|
||||
|
||||
public void clearFavicons() {
|
||||
mDbHelper.clearFavicons();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
Log.d(LOGTAG, "Closing Favicons database");
|
||||
mDbHelper.close();
|
||||
|
@ -573,9 +573,8 @@ public class GeckoAppShell
|
||||
GeckoApp.mAppContext.getSystemService(Context.LOCATION_SERVICE);
|
||||
|
||||
if (enable) {
|
||||
Criteria crit = new Criteria();
|
||||
crit.setAccuracy(Criteria.ACCURACY_FINE);
|
||||
String provider = lm.getBestProvider(crit, true);
|
||||
Criteria criteria = new Criteria();
|
||||
String provider = lm.getBestProvider(criteria, true);
|
||||
if (provider == null)
|
||||
return;
|
||||
|
||||
|
@ -178,6 +178,9 @@ public class GeckoInputConnection
|
||||
if (content == null)
|
||||
return null;
|
||||
|
||||
if ((flags & GET_EXTRACTED_TEXT_MONITOR) != 0)
|
||||
mUpdateRequest = req;
|
||||
|
||||
ExtractedText extract = new ExtractedText();
|
||||
extract.flags = 0;
|
||||
extract.partialStartOffset = -1;
|
||||
@ -200,6 +203,14 @@ public class GeckoInputConnection
|
||||
return extract;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSelection(int start, int end) {
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_SET_SELECTION, start, end - start));
|
||||
|
||||
return super.setSelection(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||
replaceText(text, newCursorPosition, true);
|
||||
@ -337,33 +348,64 @@ public class GeckoInputConnection
|
||||
|
||||
public void notifyTextChange(InputMethodManager imm, String text,
|
||||
int start, int oldEnd, int newEnd) {
|
||||
if (mBatchMode)
|
||||
if (!mBatchMode) {
|
||||
if (!text.contentEquals(mEditable)) {
|
||||
if (DEBUG) Log.d(LOGTAG, String.format(". . . notifyTextChange: current mEditable=\"%s\"",
|
||||
mEditable.toString()));
|
||||
setEditable(text);
|
||||
}
|
||||
}
|
||||
|
||||
if (mUpdateRequest == null)
|
||||
return;
|
||||
|
||||
if (!text.contentEquals(mEditable)) {
|
||||
if (DEBUG) Log.d(LOGTAG, String.format(". . . notifyTextChange: current mEditable=\"%s\"",
|
||||
mEditable.toString()));
|
||||
setEditable(text);
|
||||
View v = GeckoApp.mAppContext.getLayerController().getView();
|
||||
|
||||
if (imm == null) {
|
||||
imm = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm == null)
|
||||
return;
|
||||
}
|
||||
|
||||
mUpdateExtract.flags = 0;
|
||||
|
||||
// We update from (0, oldEnd) to (0, newEnd) because some Android IMEs
|
||||
// assume that updates start at zero, according to jchen.
|
||||
mUpdateExtract.partialStartOffset = 0;
|
||||
mUpdateExtract.partialEndOffset = oldEnd;
|
||||
|
||||
// Faster to not query for selection
|
||||
mUpdateExtract.selectionStart = newEnd;
|
||||
mUpdateExtract.selectionEnd = newEnd;
|
||||
|
||||
mUpdateExtract.text = text.substring(0, newEnd);
|
||||
mUpdateExtract.startOffset = 0;
|
||||
|
||||
imm.updateExtractedText(v, mUpdateRequest.token, mUpdateExtract);
|
||||
}
|
||||
|
||||
public void notifySelectionChange(InputMethodManager imm,
|
||||
int start, int end) {
|
||||
if (mBatchMode)
|
||||
return;
|
||||
if (!mBatchMode) {
|
||||
final Editable content = getEditable();
|
||||
int a = Selection.getSelectionStart(content);
|
||||
int b = Selection.getSelectionEnd(content);
|
||||
if (start != a || end != b) {
|
||||
if (DEBUG) Log.d(LOGTAG, String.format(". . . notifySelectionChange: current editable selection: [%d, %d]", a, b));
|
||||
super.setSelection(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
final Editable content = getEditable();
|
||||
int a = Selection.getSelectionStart(content);
|
||||
int b = Selection.getSelectionEnd(content);
|
||||
if (start != a || end != b) {
|
||||
if (DEBUG) Log.d(LOGTAG, String.format(". . . notifySelectionChange: current editable selection: [%d, %d]", a, b));
|
||||
setSelection(start, end);
|
||||
if (imm != null && imm.isFullscreenMode()) {
|
||||
View v = GeckoApp.mAppContext.getLayerController().getView();
|
||||
imm.updateSelection(v, start, end, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
mComposing = false;
|
||||
mBatchMode = false;
|
||||
mUpdateRequest = null;
|
||||
}
|
||||
|
||||
// TextWatcher
|
||||
@ -504,12 +546,20 @@ public class GeckoInputConnection
|
||||
|
||||
// KeyListener returns true if it handled the event for us.
|
||||
if (mIMEState == IME_STATE_DISABLED ||
|
||||
keyCode == KeyEvent.KEYCODE_ENTER ||
|
||||
keyCode == KeyEvent.KEYCODE_DEL ||
|
||||
keyCode == KeyEvent.KEYCODE_TAB ||
|
||||
(event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 ||
|
||||
!mKeyListener.onKeyDown(v, mEditable, keyCode, event))
|
||||
keyCode == KeyEvent.KEYCODE_ENTER ||
|
||||
keyCode == KeyEvent.KEYCODE_DEL ||
|
||||
keyCode == KeyEvent.KEYCODE_TAB ||
|
||||
(event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 ||
|
||||
!mKeyListener.onKeyDown(v, mEditable, keyCode, event)) {
|
||||
// Make sure selection in Gecko is up-to-date
|
||||
final Editable content = getEditable();
|
||||
int a = Selection.getSelectionStart(content);
|
||||
int b = Selection.getSelectionEnd(content);
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_SET_SELECTION, a, b - a));
|
||||
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -576,11 +626,9 @@ public class GeckoInputConnection
|
||||
if (v == null)
|
||||
return;
|
||||
|
||||
if (DEBUG) Log.d(LOGTAG, "notifyIME v!= null");
|
||||
|
||||
switch (type) {
|
||||
case NOTIFY_IME_RESETINPUTSTATE:
|
||||
if (DEBUG) Log.d(LOGTAG, "notifyIME = reset");
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . notifyIME: reset");
|
||||
|
||||
// Composition event is already fired from widget.
|
||||
// So reset IME flags.
|
||||
@ -603,12 +651,12 @@ public class GeckoInputConnection
|
||||
break;
|
||||
|
||||
case NOTIFY_IME_CANCELCOMPOSITION:
|
||||
if (DEBUG) Log.d(LOGTAG, "notifyIME = cancel");
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . notifyIME: cancel");
|
||||
IMEStateUpdater.resetIME();
|
||||
break;
|
||||
|
||||
case NOTIFY_IME_FOCUSCHANGE:
|
||||
if (DEBUG) Log.d(LOGTAG, "notifyIME = focus");
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . notifyIME: focus");
|
||||
IMEStateUpdater.resetIME();
|
||||
break;
|
||||
}
|
||||
@ -747,6 +795,9 @@ public class GeckoInputConnection
|
||||
|
||||
private boolean mBatchMode;
|
||||
|
||||
ExtractedTextRequest mUpdateRequest;
|
||||
final ExtractedText mUpdateExtract = new ExtractedText();
|
||||
|
||||
int mSelectionStart, mSelectionLength;
|
||||
SynchronousQueue<String> mQueryResult;
|
||||
}
|
||||
@ -867,15 +918,15 @@ class DebugGeckoInputConnection
|
||||
@Override
|
||||
public void notifyTextChange(InputMethodManager imm, String text,
|
||||
int start, int oldEnd, int newEnd) {
|
||||
Log.d(LOGTAG, String.format("IME: notifyTextChange: text=\"%s\" s=%d ne=%d oe=%d",
|
||||
text, start, newEnd, oldEnd));
|
||||
Log.d(LOGTAG, String.format("IME: >notifyTextChange(\"%s\", start=%d, oldEnd=%d, newEnd=%d)",
|
||||
text, start, oldEnd, newEnd));
|
||||
super.notifyTextChange(imm, text, start, oldEnd, newEnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifySelectionChange(InputMethodManager imm,
|
||||
int start, int end) {
|
||||
Log.d(LOGTAG, String.format("IME: notifySelectionChange: s=%d e=%d", start, end));
|
||||
Log.d(LOGTAG, String.format("IME: >notifySelectionChange(start=%d, end=%d)", start, end));
|
||||
super.notifySelectionChange(imm, start, end);
|
||||
}
|
||||
|
||||
@ -888,7 +939,7 @@ class DebugGeckoInputConnection
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count)
|
||||
{
|
||||
Log.d(LOGTAG, String.format("IME: onTextChanged: t=\"%s\" s=%d b=%d l=%d", s, start, before, count));
|
||||
Log.d(LOGTAG, String.format("IME: onTextChanged(\"%s\" start=%d, before=%d, count=%d)", s, start, before, count));
|
||||
super.onTextChanged(s, start, before, count);
|
||||
}
|
||||
|
||||
@ -945,14 +996,14 @@ class DebugGeckoInputConnection
|
||||
|
||||
@Override
|
||||
public void notifyIME(int type, int state) {
|
||||
Log.d(LOGTAG, String.format("IME: notifyIME(%d, %d)", type, state));
|
||||
Log.d(LOGTAG, String.format("IME: >notifyIME(type=%d, state=%d)", type, state));
|
||||
super.notifyIME(type, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyIMEChange(String text, int start, int end, int newEnd) {
|
||||
Log.d(LOGTAG, String.format("IME: notifyIMEChange: t=\"%s\" s=%d ne=%d oe=%d",
|
||||
text, start, newEnd, end));
|
||||
Log.d(LOGTAG, String.format("IME: >notifyIMEChange(\"%s\", start=%d, end=%d, newEnd=%d)",
|
||||
text, start, end, newEnd));
|
||||
super.notifyIMEChange(text, start, end, newEnd);
|
||||
}
|
||||
}
|
||||
|
@ -178,15 +178,6 @@ public class LayerController {
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
/** Scrolls the viewport to the given point. You must hold the monitor while calling this. */
|
||||
public void scrollTo(PointF point) {
|
||||
mViewportMetrics.setOrigin(point);
|
||||
Log.d(LOGTAG, "scrollTo: " + mViewportMetrics);
|
||||
notifyLayerClientOfGeometryChange();
|
||||
GeckoApp.mAppContext.repositionPluginViews(false);
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
/** Scrolls the viewport by the given offset. You must hold the monitor while calling this. */
|
||||
public void scrollBy(PointF point) {
|
||||
PointF origin = mViewportMetrics.getOrigin();
|
||||
@ -199,15 +190,6 @@ public class LayerController {
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
/** Sets the current viewport. You must hold the monitor while calling this. */
|
||||
public void setViewport(RectF viewport) {
|
||||
mViewportMetrics.setViewport(viewport);
|
||||
Log.d(LOGTAG, "setViewport: " + mViewportMetrics);
|
||||
notifyLayerClientOfGeometryChange();
|
||||
GeckoApp.mAppContext.repositionPluginViews(false);
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
/** Sets the current page size. You must hold the monitor while calling this. */
|
||||
public void setPageSize(FloatSize size) {
|
||||
if (mViewportMetrics.getPageSize().fuzzyEquals(size))
|
||||
@ -230,15 +212,16 @@ public class LayerController {
|
||||
public void setViewportMetrics(ViewportMetrics viewport) {
|
||||
mViewportMetrics = new ViewportMetrics(viewport);
|
||||
Log.d(LOGTAG, "setViewportMetrics: " + mViewportMetrics);
|
||||
GeckoApp.mAppContext.repositionPluginViews(false);
|
||||
// this function may or may not be called on the UI thread,
|
||||
// but repositionPluginViews must only be called on the UI thread.
|
||||
GeckoApp.mAppContext.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
GeckoApp.mAppContext.repositionPluginViews(false);
|
||||
}
|
||||
});
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
/** Scales the viewport. You must hold the monitor while calling this. */
|
||||
public void scaleTo(float zoomFactor) {
|
||||
scaleWithFocus(zoomFactor, new PointF(0,0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales the viewport, keeping the given focus point in the same place before and after the
|
||||
* scale operation. You must hold the monitor while calling this.
|
||||
@ -254,16 +237,6 @@ public class LayerController {
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the viewport origin and scales in one operation. You must hold the monitor while
|
||||
* calling this.
|
||||
*/
|
||||
public void scaleWithOrigin(float zoomFactor, PointF origin) {
|
||||
mViewportMetrics.setOrigin(origin);
|
||||
Log.d(LOGTAG, "scaleWithOrigin: " + mViewportMetrics + "; zf=" + zoomFactor);
|
||||
scaleTo(zoomFactor);
|
||||
}
|
||||
|
||||
public boolean post(Runnable action) { return mView.post(action); }
|
||||
|
||||
public void setOnTouchListener(OnTouchListener onTouchListener) {
|
||||
|
@ -56,10 +56,10 @@
|
||||
<!ENTITY pref_clear_history_confirm "Browsing history will be deleted">
|
||||
<!ENTITY pref_clear_private_data "Clear private data">
|
||||
<!ENTITY pref_clear_private_data_confirm "Browsing settings, including passwords and cookies, will be deleted">
|
||||
<!ENTITY pref_enable_plugins "Enable plugins">
|
||||
<!ENTITY pref_enable_plugins_yes "Yes">
|
||||
<!ENTITY pref_enable_plugins_tap_to_play "Tap to play">
|
||||
<!ENTITY pref_enable_plugins_no "No">
|
||||
<!ENTITY pref_plugins "Plugins">
|
||||
<!ENTITY pref_plugins_enabled "Enabled">
|
||||
<!ENTITY pref_plugins_tap_to_play "Tap to play">
|
||||
<!ENTITY pref_plugins_disabled "Disabled">
|
||||
<!ENTITY pref_font_size "Font size">
|
||||
<!ENTITY pref_font_size_small "Small">
|
||||
<!ENTITY pref_font_size_medium "Medium">
|
||||
|
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<string-array name="pref_enable_plugins_entries">
|
||||
<item>@string/pref_enable_plugins_yes</item>
|
||||
<item>@string/pref_enable_plugins_tap_to_play</item>
|
||||
<item>@string/pref_enable_plugins_no</item>
|
||||
<string-array name="pref_plugins_entries">
|
||||
<item>@string/pref_plugins_enabled</item>
|
||||
<item>@string/pref_plugins_tap_to_play</item>
|
||||
<item>@string/pref_plugins_disabled</item>
|
||||
</string-array>
|
||||
<string-array name="pref_enable_plugins_values">
|
||||
<string-array name="pref_plugins_values">
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>0</item>
|
||||
|
@ -20,9 +20,9 @@
|
||||
android:persistent="false" />
|
||||
|
||||
<ListPreference android:key="plugin.enable"
|
||||
android:title="@string/pref_enable_plugins"
|
||||
android:entries="@array/pref_enable_plugins_entries"
|
||||
android:entryValues="@array/pref_enable_plugins_values"
|
||||
android:title="@string/pref_plugins"
|
||||
android:entries="@array/pref_plugins_entries"
|
||||
android:entryValues="@array/pref_plugins_values"
|
||||
android:persistent="false" />
|
||||
|
||||
<ListPreference android:key="font.size.inflation.minTwips"
|
||||
|
@ -62,10 +62,10 @@
|
||||
<string name="pref_clear_history_confirm">&pref_clear_history_confirm;</string>
|
||||
<string name="pref_clear_private_data">&pref_clear_private_data;</string>
|
||||
<string name="pref_clear_private_data_confirm">&pref_clear_private_data_confirm;</string>
|
||||
<string name="pref_enable_plugins">&pref_enable_plugins;</string>
|
||||
<string name="pref_enable_plugins_yes">&pref_enable_plugins_yes;</string>
|
||||
<string name="pref_enable_plugins_tap_to_play">&pref_enable_plugins_tap_to_play;</string>
|
||||
<string name="pref_enable_plugins_no">&pref_enable_plugins_no;</string>
|
||||
<string name="pref_plugins">&pref_plugins;</string>
|
||||
<string name="pref_plugins_enabled">&pref_plugins_enabled;</string>
|
||||
<string name="pref_plugins_tap_to_play">&pref_plugins_tap_to_play;</string>
|
||||
<string name="pref_plugins_disabled">&pref_plugins_disabled;</string>
|
||||
<string name="pref_font_size">&pref_font_size;</string>
|
||||
<string name="pref_font_size_small">&pref_font_size_small;</string>
|
||||
<string name="pref_font_size_medium">&pref_font_size_medium;</string>
|
||||
|
@ -665,18 +665,27 @@ public class PanZoomController
|
||||
FloatSize pageSize = viewportMetrics.getPageSize();
|
||||
RectF viewport = viewportMetrics.getViewport();
|
||||
|
||||
float focusX = viewport.width() / 2.0f;
|
||||
float focusY = viewport.height() / 2.0f;
|
||||
float minZoomFactor = 0.0f;
|
||||
if (viewport.width() > pageSize.width && pageSize.width > 0) {
|
||||
float scaleFactor = viewport.width() / pageSize.width;
|
||||
minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
|
||||
focusX = 0.0f;
|
||||
}
|
||||
if (viewport.height() > pageSize.height && pageSize.height > 0) {
|
||||
float scaleFactor = viewport.height() / pageSize.height;
|
||||
minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
|
||||
focusY = 0.0f;
|
||||
}
|
||||
|
||||
if (!FloatUtils.fuzzyEquals(minZoomFactor, 0.0f)) {
|
||||
PointF center = new PointF(viewport.width() / 2.0f, viewport.height() / 2.0f);
|
||||
// if one (or both) of the page dimensions is smaller than the viewport,
|
||||
// zoom using the top/left as the focus on that axis. this prevents the
|
||||
// scenario where, if both dimensions are smaller than the viewport, but
|
||||
// by different scale factors, we end up scrolled to the end on one axis
|
||||
// after applying the scale
|
||||
PointF center = new PointF(focusX, focusY);
|
||||
viewportMetrics.scaleTo(minZoomFactor, center);
|
||||
} else if (zoomFactor > MAX_ZOOM) {
|
||||
PointF center = new PointF(viewport.width() / 2.0f, viewport.height() / 2.0f);
|
||||
|
@ -1501,8 +1501,8 @@ Tab.prototype = {
|
||||
pageHeight = Math.max(body.scrollHeight, html.scrollHeight);
|
||||
|
||||
/* Transform the page width and height based on the zoom factor. */
|
||||
pageWidth = Math.round(pageWidth * this._viewport.zoom);
|
||||
pageHeight = Math.round(pageHeight * this._viewport.zoom);
|
||||
pageWidth *= this._viewport.zoom;
|
||||
pageHeight *= this._viewport.zoom;
|
||||
|
||||
/*
|
||||
* Avoid sending page sizes of less than screen size before we hit DOMContentLoaded, because
|
||||
@ -2029,15 +2029,19 @@ var BrowserEventHandler = {
|
||||
} else if (aTopic == "Gesture:SingleTap") {
|
||||
let element = this._highlightElement;
|
||||
if (element && !FormAssistant.handleClick(element)) {
|
||||
let data = JSON.parse(aData);
|
||||
[data.x, data.y] = ElementTouchHelper.toScreenCoords(element.ownerDocument.defaultView, data.x, data.y);
|
||||
|
||||
this._sendMouseEvent("mousemove", element, data.x, data.y);
|
||||
this._sendMouseEvent("mousedown", element, data.x, data.y);
|
||||
this._sendMouseEvent("mouseup", element, data.x, data.y);
|
||||
|
||||
if (ElementTouchHelper.isElementClickable(element))
|
||||
Haptic.performSimpleAction(Haptic.LongPress);
|
||||
try {
|
||||
let data = JSON.parse(aData);
|
||||
[data.x, data.y] = ElementTouchHelper.toScreenCoords(element.ownerDocument.defaultView, data.x, data.y);
|
||||
|
||||
this._sendMouseEvent("mousemove", element, data.x, data.y);
|
||||
this._sendMouseEvent("mousedown", element, data.x, data.y);
|
||||
this._sendMouseEvent("mouseup", element, data.x, data.y);
|
||||
|
||||
if (ElementTouchHelper.isElementClickable(element))
|
||||
Haptic.performSimpleAction(Haptic.LongPress);
|
||||
} catch(e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
}
|
||||
this._cancelTapHighlight();
|
||||
} else if (aTopic == "Gesture:DoubleTap") {
|
||||
@ -2146,10 +2150,15 @@ var BrowserEventHandler = {
|
||||
}
|
||||
}
|
||||
|
||||
[aX, aY] = ElementTouchHelper.toBrowserCoords(aElement.ownerDocument.defaultView, aX, aY);
|
||||
let cwu = aElement.ownerDocument.defaultView.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
aButton = aButton || 0;
|
||||
cwu.sendMouseEventToWindow(aName, Math.round(aX), Math.round(aY), aButton, 1, 0, true);
|
||||
let window = aElement.ownerDocument.defaultView;
|
||||
try {
|
||||
[aX, aY] = ElementTouchHelper.toBrowserCoords(window, aX, aY);
|
||||
let cwu = window.top.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
aButton = aButton || 0;
|
||||
cwu.sendMouseEventToWindow(aName, Math.round(aX), Math.round(aY), aButton, 1, 0, true);
|
||||
} catch(e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
_hasScrollableOverflow: function(elem) {
|
||||
@ -2251,24 +2260,36 @@ const kReferenceDpi = 240; // standard "pixel" size used in some preferences
|
||||
|
||||
const ElementTouchHelper = {
|
||||
toBrowserCoords: function(aWindow, aX, aY) {
|
||||
let tab = BrowserApp.selectedTab;
|
||||
if (aWindow) {
|
||||
let browser = BrowserApp.getBrowserForWindow(aWindow);
|
||||
tab = BrowserApp.getTabForBrowser(browser);
|
||||
}
|
||||
if (!aWindow)
|
||||
throw "Must provide a window";
|
||||
|
||||
let browser = BrowserApp.getBrowserForWindow(aWindow.top);
|
||||
if (!browser)
|
||||
throw "Unable to find a browser";
|
||||
|
||||
let tab = BrowserApp.getTabForBrowser(browser);
|
||||
if (!tab)
|
||||
throw "Unable to find a tab";
|
||||
|
||||
let viewport = tab.viewport;
|
||||
return [
|
||||
((aX-tab.viewportExcess.x)*viewport.zoom + viewport.offsetX),
|
||||
((aY-tab.viewportExcess.y)*viewport.zoom + viewport.offsetY)
|
||||
((aX - tab.viewportExcess.x) * viewport.zoom + viewport.offsetX),
|
||||
((aY - tab.viewportExcess.y) * viewport.zoom + viewport.offsetY)
|
||||
];
|
||||
},
|
||||
|
||||
toScreenCoords: function(aWindow, aX, aY) {
|
||||
let tab = BrowserApp.selectedTab;
|
||||
if (aWindow) {
|
||||
let browser = BrowserApp.getBrowserForWindow(aWindow);
|
||||
tab = BrowserApp.getTabForBrowser(browser);
|
||||
}
|
||||
if (!aWindow)
|
||||
throw "Must provide a window";
|
||||
|
||||
let browser = BrowserApp.getBrowserForWindow(aWindow.top);
|
||||
if (!browser)
|
||||
throw "Unable to find a browser";
|
||||
|
||||
let tab = BrowserApp.getTabForBrowser(browser);
|
||||
if (!tab)
|
||||
throw "Unable to find a tab";
|
||||
|
||||
let viewport = tab.viewport;
|
||||
return [
|
||||
(aX - viewport.offsetX)/viewport.zoom + tab.viewportExcess.x,
|
||||
@ -3637,10 +3658,16 @@ var PermissionsHelper = {
|
||||
// Keep track of permissions, so we know which ones to clear
|
||||
this._currentPermissions = permissions;
|
||||
|
||||
let host;
|
||||
try {
|
||||
host = uri.host;
|
||||
} catch(e) {
|
||||
host = uri.spec;
|
||||
}
|
||||
sendMessageToJava({
|
||||
gecko: {
|
||||
type: "Permissions:Data",
|
||||
host: uri.host,
|
||||
host: host,
|
||||
permissions: permissions
|
||||
}
|
||||
});
|
||||
|
@ -86,16 +86,16 @@ nsAboutBloat::NewChannel(nsIURI *aURI, nsIChannel **result)
|
||||
if (clear) {
|
||||
nsTraceRefcntImpl::ResetStatistics();
|
||||
|
||||
const char* msg = "Bloat statistics cleared.";
|
||||
rv = NS_NewCStringInputStream(getter_AddRefs(inStr), nsDependentCString(msg));
|
||||
rv = NS_NewCStringInputStream(getter_AddRefs(inStr),
|
||||
NS_LITERAL_CSTRING("Bloat statistics cleared."));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
else if (leaks) {
|
||||
// dump the current set of leaks.
|
||||
GC_gcollect();
|
||||
|
||||
const char* msg = "Memory leaks dumped.";
|
||||
rv = NS_NewCStringInputStream(getter_AddRefs(inStr), nsDependentCString(msg));
|
||||
rv = NS_NewCStringInputStream(getter_AddRefs(inStr),
|
||||
NS_LITERAL_CSTRING("Memory leaks dumped."));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
else {
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "nsIApplicationCacheService.h"
|
||||
#include "nsIOfflineCacheUpdate.h"
|
||||
#include "nsIRedirectChannelRegistrar.h"
|
||||
#include "prinit.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
@ -67,6 +68,9 @@ HttpChannelParent::HttpChannelParent(PBrowserParent* iframeEmbedding)
|
||||
, mStoredProgress(0)
|
||||
, mStoredProgressMax(0)
|
||||
, mHeadersToSyncToChild(nsnull)
|
||||
, mSentRedirect1Begin(false)
|
||||
, mSentRedirect1BeginFailed(false)
|
||||
, mReceivedRedirect2Verify(false)
|
||||
{
|
||||
// Ensure gHttpHandler is initialized: we need the atom table up and running.
|
||||
nsIHttpProtocolHandler* handler;
|
||||
@ -329,6 +333,11 @@ HttpChannelParent::RecvUpdateAssociatedContentSecurity(const PRInt32& high,
|
||||
return true;
|
||||
}
|
||||
|
||||
// Bug 621446 investigation, we don't want conditional PR_Aborts bellow to be
|
||||
// merged to a single address.
|
||||
#pragma warning(disable : 4068)
|
||||
#pragma GCC optimize ("O0")
|
||||
|
||||
bool
|
||||
HttpChannelParent::RecvRedirect2Verify(const nsresult& result,
|
||||
const RequestHeaderTuples& changedHeaders)
|
||||
@ -346,11 +355,30 @@ HttpChannelParent::RecvRedirect2Verify(const nsresult& result,
|
||||
}
|
||||
}
|
||||
|
||||
if (!mRedirectCallback) {
|
||||
// Bug 621446 investigation (optimization turned off above)
|
||||
if (mReceivedRedirect2Verify)
|
||||
::PR_Abort();
|
||||
if (mSentRedirect1BeginFailed)
|
||||
::PR_Abort();
|
||||
if (mSentRedirect1Begin && NS_FAILED(result))
|
||||
::PR_Abort();
|
||||
if (mSentRedirect1Begin && NS_SUCCEEDED(result))
|
||||
::PR_Abort();
|
||||
if (!mRedirectChannel)
|
||||
::PR_Abort();
|
||||
}
|
||||
|
||||
mReceivedRedirect2Verify = true;
|
||||
|
||||
mRedirectCallback->OnRedirectVerifyCallback(result);
|
||||
mRedirectCallback = nsnull;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Bug 621446 investigation
|
||||
#pragma GCC reset_options
|
||||
|
||||
bool
|
||||
HttpChannelParent::RecvDocumentChannelCleanup()
|
||||
{
|
||||
@ -568,8 +596,14 @@ HttpChannelParent::StartRedirect(PRUint32 newChannelId,
|
||||
redirectFlags,
|
||||
responseHead ? *responseHead
|
||||
: nsHttpResponseHead());
|
||||
if (!result)
|
||||
if (!result) {
|
||||
// Bug 621446 investigation
|
||||
mSentRedirect1BeginFailed = true;
|
||||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
|
||||
// Bug 621446 investigation
|
||||
mSentRedirect1Begin = true;
|
||||
|
||||
// Result is handled in RecvRedirect2Verify above
|
||||
|
||||
|
@ -138,6 +138,10 @@ private:
|
||||
|
||||
// used while visiting headers, to send them to child: else null
|
||||
RequestHeaderTuples *mHeadersToSyncToChild;
|
||||
|
||||
bool mSentRedirect1Begin : 1;
|
||||
bool mSentRedirect1BeginFailed : 1;
|
||||
bool mReceivedRedirect2Verify : 1;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
@ -529,15 +529,15 @@ SpdyStream::TransmitFrame(const char *buf,
|
||||
LOG3(("SpdyStream::TransmitFrame for regular session=%p "
|
||||
"stream=%p result %x len=%d",
|
||||
mSession, this, rv, transmittedCount));
|
||||
SpdySession::LogIO(mSession, this, "Writing from Transaction Buffer",
|
||||
buf + offset, transmittedCount);
|
||||
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK)
|
||||
mBlockedOnWrite = 1;
|
||||
|
||||
if (NS_FAILED(rv)) // this will include WOULD_BLOCK
|
||||
return rv;
|
||||
|
||||
SpdySession::LogIO(mSession, this, "Writing from Transaction Buffer",
|
||||
buf + offset, transmittedCount);
|
||||
|
||||
if (mUpstreamState == SENDING_REQUEST_BODY) {
|
||||
mTransaction->OnTransportStatus(mSocketTransport,
|
||||
nsISocketTransport::STATUS_SENDING_TO,
|
||||
|
@ -190,6 +190,11 @@ nsAutoCompleteController::StartSearch(const nsAString &aSearchString)
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteController::HandleText()
|
||||
{
|
||||
// We should do nothing during composition.
|
||||
if (mIsIMEComposing) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!mInput) {
|
||||
// Stop all searches in case they are async.
|
||||
StopSearch();
|
||||
|
@ -118,6 +118,9 @@
|
||||
testNormalFind();
|
||||
gFindBar.close();
|
||||
ok(gFindBar.hidden, "Failed to close findbar after testNormalFind");
|
||||
testNormalFindWithComposition();
|
||||
gFindBar.close();
|
||||
ok(gFindBar.hidden, "findbar should be hidden after testNormalFindWithComposition");
|
||||
testAutoCaseSensitivityUI();
|
||||
testQuickFindText();
|
||||
gFindBar.close();
|
||||
@ -226,6 +229,60 @@
|
||||
}
|
||||
}
|
||||
|
||||
function testNormalFindWithComposition() {
|
||||
document.getElementById("cmd_find").doCommand();
|
||||
|
||||
ok(!gFindBar.hidden, "testNormalFindWithComposition: findbar should be open");
|
||||
ok(document.commandDispatcher.focusedElement == gFindBar._findField.inputField,
|
||||
"testNormalFindWithComposition: find field should be focused");
|
||||
|
||||
var matchCaseCheckbox = gFindBar.getElement("find-case-sensitive");
|
||||
var clicked = false;
|
||||
if (!matchCaseCheckbox.hidden & matchCaseCheckbox.checked) {
|
||||
matchCaseCheckbox.click();
|
||||
clicked = true;
|
||||
}
|
||||
|
||||
gFindBar._findField.inputField.focus();
|
||||
|
||||
var searchStr = "text";
|
||||
|
||||
synthesizeComposition({ type: "compositionstart" });
|
||||
synthesizeComposition({ type: "compositionupdate", data: searchStr });
|
||||
synthesizeText(
|
||||
{ "composition":
|
||||
{ "string": searchStr,
|
||||
"clauses":
|
||||
[
|
||||
{ "length": searchStr.length, "attr": COMPOSITION_ATTR_RAWINPUT }
|
||||
]
|
||||
},
|
||||
"caret": { "start": searchStr.length, "length": 0 }
|
||||
});
|
||||
|
||||
ok(gBrowser.contentWindow.getSelection().toString().toLowerCase() != searchStr,
|
||||
"testNormalFindWithComposition: text shouldn't be found during composition");
|
||||
|
||||
synthesizeText(
|
||||
{ "composition":
|
||||
{ "string": searchStr,
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 0, "attr": 0 }
|
||||
]
|
||||
},
|
||||
"caret": { "start": searchStr.length, "length": 0 }
|
||||
});
|
||||
synthesizeComposition({ type: "compositionend", data: searchStr });
|
||||
|
||||
ok(gBrowser.contentWindow.getSelection().toString().toLowerCase() == searchStr,
|
||||
"testNormalFindWithComposition: text should be found after committing composition");
|
||||
|
||||
if (clicked) {
|
||||
matchCaseCheckbox.click();
|
||||
}
|
||||
}
|
||||
|
||||
function testAutoCaseSensitivityUI() {
|
||||
var matchCaseCheckbox = gFindBar.getElement("find-case-sensitive");
|
||||
var matchCaseLabel = gFindBar.getElement("match-case-status");
|
||||
|
@ -113,6 +113,14 @@
|
||||
|
||||
<handlers>
|
||||
<handler event="input"><![CDATA[
|
||||
// We should do nothing during composition. E.g., composing string
|
||||
// before converting may matches a forward word of expected word.
|
||||
// After that, even if user converts the composition string to the
|
||||
// expected word, it may find second or later searching word in the
|
||||
// document.
|
||||
if (this.findbar._isIMEComposing) {
|
||||
return;
|
||||
}
|
||||
this.findbar._find(this.value);
|
||||
]]></handler>
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
<!ENTITY props.path.label "Path:">
|
||||
<!ENTITY props.secure.label "Send For:">
|
||||
<!ENTITY props.expires.label "Expires:">
|
||||
<!ENTITY props.policy.label "Policy:">
|
||||
|
||||
<!ENTITY button.allow.label "Allow">
|
||||
<!ENTITY button.allow.accesskey "A">
|
||||
|
@ -220,8 +220,9 @@ var DownloadTaskbarProgressUpdater =
|
||||
* 1. If the active window is the download window, then we always update
|
||||
* the taskbar indicator.
|
||||
* 2. If the active window isn't the download window, then we update only if
|
||||
* the status is Normal, i.e. one or more downloads are currently
|
||||
* progressing. If we aren't, then we clear the indicator.
|
||||
* the status is normal or indeterminate. i.e. one or more downloads are
|
||||
* currently progressing or in scan mode. If we aren't, then we clear the
|
||||
* indicator.
|
||||
*/
|
||||
_updateTaskbar: function DTPU_updateTaskbar()
|
||||
{
|
||||
@ -230,9 +231,10 @@ var DownloadTaskbarProgressUpdater =
|
||||
}
|
||||
|
||||
// If the active window is not the download manager window, set the state
|
||||
// only if it is Normal
|
||||
// only if it is normal or indeterminate.
|
||||
if (this._activeWindowIsDownloadWindow ||
|
||||
(this._taskbarState == Ci.nsITaskbarProgress.STATE_NORMAL)) {
|
||||
(this._taskbarState == Ci.nsITaskbarProgress.STATE_NORMAL ||
|
||||
this._taskbarState == Ci.nsITaskbarProgress.STATE_INDETERMINATE)) {
|
||||
this._activeTaskbarProgress.setProgressState(this._taskbarState,
|
||||
this._totalTransferred,
|
||||
this._totalSize);
|
||||
|
@ -2801,6 +2801,10 @@ var gDetailView = {
|
||||
gEventManager.unregisterAddonListener(this, this._addon.id);
|
||||
gEventManager.unregisterInstallListener(this);
|
||||
this._addon = null;
|
||||
|
||||
// Flush the preferences to disk so they survive any crash
|
||||
if (this.node.getElementsByTagName("setting").length)
|
||||
Services.prefs.savePrefFile(null);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1055,7 +1055,7 @@ AndroidBridge::OpenGraphicsLibraries()
|
||||
mHasNativeWindowAccess = false;
|
||||
mHasNativeBitmapAccess = false;
|
||||
|
||||
void *handle = dlopen("/system/lib/libjnigraphics.so", RTLD_LAZY | RTLD_LOCAL);
|
||||
void *handle = dlopen("libjnigraphics.so", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (handle) {
|
||||
AndroidBitmap_getInfo = (int (*)(JNIEnv *, jobject, void *))dlsym(handle, "AndroidBitmap_getInfo");
|
||||
AndroidBitmap_lockPixels = (int (*)(JNIEnv *, jobject, void **))dlsym(handle, "AndroidBitmap_lockPixels");
|
||||
@ -1068,7 +1068,7 @@ AndroidBridge::OpenGraphicsLibraries()
|
||||
|
||||
// Try to dlopen libandroid.so for and native window access on
|
||||
// Android 2.3+ (API level 9)
|
||||
handle = dlopen("/system/lib/libandroid.so", RTLD_LAZY | RTLD_LOCAL);
|
||||
handle = dlopen("libandroid.so", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (handle) {
|
||||
ANativeWindow_fromSurface = (void* (*)(JNIEnv*, jobject))dlsym(handle, "ANativeWindow_fromSurface");
|
||||
ANativeWindow_release = (void (*)(void*))dlsym(handle, "ANativeWindow_release");
|
||||
|
@ -62,9 +62,9 @@ typedef gfxASurface::gfxImageFormat gfxImageFormat;
|
||||
#define EGL_NO_CONTEXT (EGLContext)0
|
||||
#define EGL_DEFAULT_DISPLAY (void*)0
|
||||
|
||||
#define ANDROID_LIBUI_PATH "/system/lib/libui.so"
|
||||
#define ANDROID_GLES_PATH "/system/lib/libGLESv2.so"
|
||||
#define ANDROID_EGL_PATH "/system/lib/libEGL.so"
|
||||
#define ANDROID_LIBUI_PATH "libui.so"
|
||||
#define ANDROID_GLES_PATH "libGLESv2.so"
|
||||
#define ANDROID_EGL_PATH "libEGL.so"
|
||||
|
||||
// Really I have no idea, but this should be big enough
|
||||
#define GRAPHIC_BUFFER_SIZE 1024
|
||||
|
@ -171,7 +171,7 @@ function startTests()
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
});
|
||||
checkCompositionEvents(false, false, true, false, "composing");
|
||||
checkCompositionEvents(false, false, true, true, "composing");
|
||||
var queryText = synthesizeQueryTextContent(0, 100);
|
||||
ok(queryText, "query text event result is null");
|
||||
if (!queryText) {
|
||||
|
@ -1240,6 +1240,7 @@ function runCompositionEventTest()
|
||||
|
||||
function formEventHandlerForWindow(aEvent)
|
||||
{
|
||||
ok(aEvent.isTrusted, "input events must be trusted events");
|
||||
windowEventCounts[aEvent.type]++;
|
||||
windowEventData[aEvent.type] = input.value;
|
||||
}
|
||||
|
@ -715,11 +715,11 @@ nsClipboard :: FindPlatformHTML ( IDataObject* inDataObject, UINT inIndex, void*
|
||||
return false;
|
||||
}
|
||||
|
||||
float vers = 0.0;
|
||||
char version[8] = { 0 };
|
||||
PRInt32 startOfData = 0;
|
||||
PRInt32 endOfData = 0;
|
||||
int numFound = sscanf((char*)*outData, "Version:%f\nStartHTML:%d\nEndHTML:%d",
|
||||
&vers, &startOfData, &endOfData);
|
||||
int numFound = sscanf((char*)*outData, "Version:%7s\nStartHTML:%d\nEndHTML:%d",
|
||||
version, &startOfData, &endOfData);
|
||||
|
||||
if (numFound != 3 || startOfData < -1 || endOfData < -1) {
|
||||
return false;
|
||||
|
@ -1803,8 +1803,9 @@ nsNativeThemeWin::GetWidgetPadding(nsDeviceContext* aContext,
|
||||
if (aWidgetType == NS_THEME_WINDOW_TITLEBAR ||
|
||||
aWidgetType == NS_THEME_WINDOW_TITLEBAR_MAXIMIZED) {
|
||||
aResult->SizeTo(0, 0, 0, 0);
|
||||
// Maximized windows have an offscreen offset equal to
|
||||
// the border padding. (windows quirk)
|
||||
// XXX Maximized windows have an offscreen offset equal to
|
||||
// the border padding. This should be addressed in nsWindow,
|
||||
// but currently can't be, see UpdateNonClientMargins.
|
||||
if (aWidgetType == NS_THEME_WINDOW_TITLEBAR_MAXIMIZED)
|
||||
aResult->top = GetSystemMetrics(SM_CXFRAME);
|
||||
return true;
|
||||
|
@ -341,10 +341,16 @@ static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
// General purpose user32.dll hook object
|
||||
static WindowsDllInterceptor sUser32Intercept;
|
||||
|
||||
// 2 pixel offset for eTransparencyBorderlessGlass which equals
|
||||
// the size of the default window border Windows paints.
|
||||
// 2 pixel offset for eTransparencyBorderlessGlass which equals the size of
|
||||
// the default window border Windows paints. Glass will be extended inward
|
||||
// this distance to remove the border.
|
||||
static const PRInt32 kGlassMarginAdjustment = 2;
|
||||
|
||||
// When the client area is extended out into the default window frame area,
|
||||
// this is the minimum amount of space along the edge of resizable windows
|
||||
// we will always display a resize cursor in, regardless of the underlying
|
||||
// content.
|
||||
static const PRInt32 kResizableBorderMinSize = 3;
|
||||
|
||||
// We should never really try to accelerate windows bigger than this. In some
|
||||
// cases this might lead to no D3D9 acceleration where we could have had it
|
||||
@ -2031,49 +2037,91 @@ nsWindow::UpdateNonClientMargins(PRInt32 aSizeMode, bool aReflowWindow)
|
||||
|
||||
mNonClientOffset.top = mNonClientOffset.bottom =
|
||||
mNonClientOffset.left = mNonClientOffset.right = 0;
|
||||
mCaptionHeight = mVertResizeMargin = mHorResizeMargin = 0;
|
||||
|
||||
if (aSizeMode == -1)
|
||||
aSizeMode = mSizeMode;
|
||||
|
||||
if (aSizeMode == nsSizeMode_Minimized ||
|
||||
aSizeMode == nsSizeMode_Fullscreen) {
|
||||
mCaptionHeight = mVertResizeMargin = mHorResizeMargin = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Note, for maximized windows, we need to continue to offset the client by
|
||||
// thick frame margins of a normal window, since windows expects this
|
||||
// in it's DwmDefWndProc hit testing.
|
||||
mCaptionHeight = GetSystemMetrics(SM_CYCAPTION);
|
||||
bool hasCaption = (mBorderStyle & (eBorderStyle_all |
|
||||
eBorderStyle_title |
|
||||
eBorderStyle_menu |
|
||||
eBorderStyle_default)) > 0 ? true : false;
|
||||
|
||||
if (hasCaption)
|
||||
mCaptionHeight = GetSystemMetrics(SM_CYCAPTION);
|
||||
mHorResizeMargin = GetSystemMetrics(SM_CXFRAME);
|
||||
mVertResizeMargin = GetSystemMetrics(SM_CYFRAME);
|
||||
|
||||
mCaptionHeight += mVertResizeMargin;
|
||||
|
||||
// If a margin value is 0, set the offset to the default size of the frame.
|
||||
// If a margin is -1, leave as default, and if a margin > 0, set the offset
|
||||
// so that the frame size is equal to the margin value.
|
||||
// Custom margin offset calculations for the chrome margin attribute on a
|
||||
// window. The offsets calculated here are added to the client area in the
|
||||
// WM_NCCALCSIZE event:
|
||||
// -1 - leave the default frame in place
|
||||
// 0 - remove the frame, our frame offset equals the default frame size
|
||||
// >0 - frame size equals (default frame size - margin value) with the
|
||||
// restriction that the offset <= default frame size.
|
||||
if (!mNonClientMargins.top)
|
||||
mNonClientOffset.top = mCaptionHeight;
|
||||
else if (mNonClientMargins.top > 0)
|
||||
mNonClientOffset.top = mCaptionHeight - mNonClientMargins.top;
|
||||
mNonClientOffset.top = NS_MIN(mCaptionHeight, mNonClientMargins.top);
|
||||
|
||||
if (!mNonClientMargins.left)
|
||||
mNonClientOffset.left = mHorResizeMargin;
|
||||
else if (mNonClientMargins.left > 0)
|
||||
mNonClientOffset.left = mHorResizeMargin - mNonClientMargins.left;
|
||||
mNonClientOffset.left = NS_MIN(mHorResizeMargin, mNonClientMargins.left);
|
||||
|
||||
if (!mNonClientMargins.right)
|
||||
mNonClientOffset.right = mHorResizeMargin;
|
||||
else if (mNonClientMargins.right > 0)
|
||||
mNonClientOffset.right = mHorResizeMargin - mNonClientMargins.right;
|
||||
mNonClientOffset.right = NS_MIN(mHorResizeMargin, mNonClientMargins.right);
|
||||
|
||||
if (!mNonClientMargins.bottom)
|
||||
mNonClientOffset.bottom = mVertResizeMargin;
|
||||
else if (mNonClientMargins.bottom > 0)
|
||||
mNonClientOffset.bottom = mVertResizeMargin - mNonClientMargins.bottom;
|
||||
mNonClientOffset.bottom = NS_MIN(mVertResizeMargin, mNonClientMargins.bottom);
|
||||
|
||||
// Disable chrome margins > 0 in two cases:
|
||||
// - For non-glass desktops: The window frame is painted with textures that
|
||||
// require the entire space of the default frame. We allow a full frame or
|
||||
// no frame at all.
|
||||
// - For maximized windows: Windows positions maximized windows such that the
|
||||
// outer bounds sit off screen a distance equal to the standard frame size.
|
||||
if(!nsUXThemeData::CheckForCompositor() || aSizeMode == nsSizeMode_Maximized) {
|
||||
if (mNonClientMargins.top > 0)
|
||||
mNonClientOffset.top = 0;
|
||||
if (mNonClientMargins.bottom > 0)
|
||||
mNonClientOffset.bottom = 0;
|
||||
if (mNonClientMargins.left > 0)
|
||||
mNonClientOffset.left = 0;
|
||||
if (mNonClientMargins.right > 0)
|
||||
mNonClientOffset.right = 0;
|
||||
}
|
||||
|
||||
if (aSizeMode == nsSizeMode_Maximized) {
|
||||
// For chrome margins = 0 on maximized windows, Windows places the bounds
|
||||
// off screen a distance equal to the standard frame size. Remove this
|
||||
// area from our expanded client area.
|
||||
if (!mNonClientMargins.bottom)
|
||||
mNonClientOffset.bottom = 0;
|
||||
if (!mNonClientMargins.left)
|
||||
mNonClientOffset.left = 0;
|
||||
if (!mNonClientMargins.right)
|
||||
mNonClientOffset.right = 0;
|
||||
|
||||
// This should be (mCaptionHeight - mVertResizeMargin). But if we offset
|
||||
// the client area by just SM_CYCAPTION (placing the top of the client
|
||||
// area level with the visible screen) Windows dwm def proc fails to pick
|
||||
// up mouse hover and clicks on the glass control buttons. To compensate,
|
||||
// we position the client area off screen by mVertResizeMargin, and add
|
||||
// widget padding in nsNativeThemeWin::GetWidgetPadding().
|
||||
if (!mNonClientMargins.top)
|
||||
mNonClientOffset.top = mCaptionHeight;
|
||||
|
||||
// Address an issue with auto-hide taskbars which fall behind the window.
|
||||
// Ensure a 1 pixel margin at the bottom of the monitor so that unhiding
|
||||
// the taskbar works properly.
|
||||
@ -3709,9 +3757,11 @@ void nsWindow::DispatchPendingEvents()
|
||||
--recursionBlocker;
|
||||
}
|
||||
|
||||
// Quickly check to see if there are any
|
||||
// paint events pending.
|
||||
if (::GetQueueStatus(QS_PAINT)) {
|
||||
// Quickly check to see if there are any paint events pending,
|
||||
// but only dispatch them if it has been long enough since the
|
||||
// last paint completed.
|
||||
if (::GetQueueStatus(QS_PAINT) &&
|
||||
((TimeStamp::Now() - mLastPaintEndTime).ToMilliseconds() >= 50)) {
|
||||
// Find the top level window.
|
||||
HWND topWnd = WinUtils::GetTopLevelHWND(mWnd);
|
||||
|
||||
@ -5543,6 +5593,11 @@ BOOL CALLBACK nsWindow::BroadcastMsg(HWND aTopWindow, LPARAM aMsg)
|
||||
PRInt32
|
||||
nsWindow::ClientMarginHitTestPoint(PRInt32 mx, PRInt32 my)
|
||||
{
|
||||
if (mSizeMode == nsSizeMode_Minimized ||
|
||||
mSizeMode == nsSizeMode_Fullscreen) {
|
||||
return HTCLIENT;
|
||||
}
|
||||
|
||||
// Calculations are done in screen coords
|
||||
RECT winRect;
|
||||
GetWindowRect(mWnd, &winRect);
|
||||
@ -5560,72 +5615,90 @@ nsWindow::ClientMarginHitTestPoint(PRInt32 mx, PRInt32 my)
|
||||
|
||||
PRInt32 testResult = HTCLIENT;
|
||||
|
||||
bool isResizable = (mBorderStyle & (eBorderStyle_all |
|
||||
eBorderStyle_resizeh |
|
||||
eBorderStyle_default)) > 0 ? true : false;
|
||||
if (mSizeMode == nsSizeMode_Maximized)
|
||||
isResizable = false;
|
||||
|
||||
bool top = false;
|
||||
bool bottom = false;
|
||||
bool left = false;
|
||||
bool right = false;
|
||||
|
||||
if (my >= winRect.top && my <
|
||||
(winRect.top + mVertResizeMargin + (mCaptionHeight - mNonClientOffset.top)))
|
||||
int topOffset = NS_MAX(mCaptionHeight - mNonClientOffset.top,
|
||||
kResizableBorderMinSize);
|
||||
int bottomOffset = NS_MAX(mVertResizeMargin - mNonClientOffset.bottom,
|
||||
kResizableBorderMinSize);
|
||||
int topBounds = winRect.top + topOffset;
|
||||
int bottomBounds = winRect.bottom - bottomOffset;
|
||||
|
||||
if (my >= winRect.top && my < topBounds)
|
||||
top = true;
|
||||
else if (my < winRect.bottom && my >= (winRect.bottom - mVertResizeMargin))
|
||||
else if (my <= winRect.bottom && my > bottomBounds)
|
||||
bottom = true;
|
||||
|
||||
if (mx >= winRect.left && mx < (winRect.left +
|
||||
(bottom ? (2*mHorResizeMargin) : mHorResizeMargin)))
|
||||
int leftOffset = NS_MAX(mHorResizeMargin - mNonClientOffset.left,
|
||||
kResizableBorderMinSize);
|
||||
int rightOffset = NS_MAX(mHorResizeMargin - mNonClientOffset.right,
|
||||
kResizableBorderMinSize);
|
||||
// (the 2x case here doubles the resize area for corners)
|
||||
int leftBounds = winRect.left +
|
||||
(bottom ? (2*leftOffset) : leftOffset);
|
||||
int rightBounds = winRect.right -
|
||||
(bottom ? (2*rightOffset) : rightOffset);
|
||||
|
||||
if (mx >= winRect.left && mx < leftBounds)
|
||||
left = true;
|
||||
else if (mx < winRect.right && mx >= (winRect.right -
|
||||
(bottom ? (2*mHorResizeMargin) : mHorResizeMargin)))
|
||||
else if (mx <= winRect.right && mx > rightBounds)
|
||||
right = true;
|
||||
|
||||
if (top) {
|
||||
testResult = HTTOP;
|
||||
if (left)
|
||||
testResult = HTTOPLEFT;
|
||||
else if (right)
|
||||
testResult = HTTOPRIGHT;
|
||||
} else if (bottom) {
|
||||
testResult = HTBOTTOM;
|
||||
if (left)
|
||||
testResult = HTBOTTOMLEFT;
|
||||
else if (right)
|
||||
testResult = HTBOTTOMRIGHT;
|
||||
if (isResizable) {
|
||||
if (top) {
|
||||
testResult = HTTOP;
|
||||
if (left)
|
||||
testResult = HTTOPLEFT;
|
||||
else if (right)
|
||||
testResult = HTTOPRIGHT;
|
||||
} else if (bottom) {
|
||||
testResult = HTBOTTOM;
|
||||
if (left)
|
||||
testResult = HTBOTTOMLEFT;
|
||||
else if (right)
|
||||
testResult = HTBOTTOMRIGHT;
|
||||
} else {
|
||||
if (left)
|
||||
testResult = HTLEFT;
|
||||
if (right)
|
||||
testResult = HTRIGHT;
|
||||
}
|
||||
} else {
|
||||
if (left)
|
||||
testResult = HTLEFT;
|
||||
if (right)
|
||||
testResult = HTRIGHT;
|
||||
if (top)
|
||||
testResult = HTCAPTION;
|
||||
else if (bottom || left || right)
|
||||
testResult = HTBORDER;
|
||||
}
|
||||
|
||||
bool contentOverlap = true;
|
||||
|
||||
if (mSizeMode == nsSizeMode_Maximized) {
|
||||
// There's no HTTOP in maximized state (bug 575493)
|
||||
if (testResult == HTTOP) {
|
||||
testResult = HTCAPTION;
|
||||
}
|
||||
} else {
|
||||
PRInt32 leftMargin = mNonClientMargins.left == -1 ? mHorResizeMargin : mNonClientMargins.left;
|
||||
PRInt32 rightMargin = mNonClientMargins.right == -1 ? mHorResizeMargin : mNonClientMargins.right;
|
||||
PRInt32 topMargin = mNonClientMargins.top == -1 ? mVertResizeMargin : mNonClientMargins.top;
|
||||
PRInt32 bottomMargin = mNonClientMargins.bottom == -1 ? mVertResizeMargin : mNonClientMargins.bottom;
|
||||
|
||||
contentOverlap = mx >= winRect.left + leftMargin &&
|
||||
mx <= winRect.right - rightMargin &&
|
||||
my >= winRect.top + topMargin &&
|
||||
my <= winRect.bottom - bottomMargin;
|
||||
if (mSizeMode != nsSizeMode_Maximized) {
|
||||
contentOverlap = mx >= winRect.left + leftOffset &&
|
||||
mx <= winRect.right - rightOffset &&
|
||||
my >= winRect.top + topOffset &&
|
||||
my <= winRect.bottom - bottomOffset;
|
||||
}
|
||||
|
||||
if (!sIsInMouseCapture &&
|
||||
contentOverlap &&
|
||||
(testResult == HTCLIENT ||
|
||||
testResult == HTTOP ||
|
||||
testResult == HTBORDER ||
|
||||
testResult == HTTOPLEFT ||
|
||||
testResult == HTCAPTION)) {
|
||||
LPARAM lParam = MAKELPARAM(mx, my);
|
||||
LPARAM lParamClient = lParamToClient(lParam);
|
||||
bool result = DispatchMouseEvent(NS_MOUSE_MOZHITTEST, 0, lParamClient,
|
||||
false, nsMouseEvent::eLeftButton, MOUSE_INPUT_SOURCE());
|
||||
false, nsMouseEvent::eLeftButton, MOUSE_INPUT_SOURCE());
|
||||
if (result) {
|
||||
// The mouse is over a blank area
|
||||
testResult = testResult == HTCLIENT ? HTCAPTION : testResult;
|
||||
|
@ -61,6 +61,8 @@
|
||||
#include "nsWindowDbg.h"
|
||||
#include "cairo.h"
|
||||
#include "nsITimer.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
||||
#include "gfxD2DSurface.h"
|
||||
#endif
|
||||
@ -94,6 +96,8 @@ class imgIContainer;
|
||||
|
||||
class nsWindow : public nsBaseWidget
|
||||
{
|
||||
typedef mozilla::TimeStamp TimeStamp;
|
||||
typedef mozilla::TimeDuration TimeDuration;
|
||||
typedef mozilla::widget::WindowHook WindowHook;
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
|
||||
typedef mozilla::widget::TaskbarWindowPreview TaskbarWindowPreview;
|
||||
@ -611,6 +615,10 @@ protected:
|
||||
bool mHasTaskbarIconBeenCreated;
|
||||
#endif
|
||||
|
||||
// The point in time at which the last paint completed. We use this to avoid
|
||||
// painting too rapidly in response to frequent input events.
|
||||
TimeStamp mLastPaintEndTime;
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
static BOOL sIsAccessibilityOn;
|
||||
static HINSTANCE sAccLib;
|
||||
|
@ -605,6 +605,7 @@ bool nsWindow::OnPaint(HDC aDC, PRUint32 aNestingLevel)
|
||||
}
|
||||
|
||||
mPaintDC = nsnull;
|
||||
mLastPaintEndTime = TimeStamp::Now();
|
||||
|
||||
#if defined(WIDGET_DEBUG_OUTPUT)
|
||||
if (debug_WantPaintFlashing())
|
||||
|
Loading…
x
Reference in New Issue
Block a user