author | Marco Bonardo <mbonardo@mozilla.com> |
Fri, 19 Aug 2011 11:39:42 +0200 | |
changeset 75528 | 1881f9b5f8b50fa29a6b4f9885948e9ce632d22b |
parent 75480 | 6181ba4693f9face8f50d367f3de5593b500742d (current diff) |
parent 75527 | 54a15fc04437f437a88253f971e343b03f591b0a (diff) |
child 75531 | d963476cbf67a6a4e10223806842fa8af28ff03d |
push id | 21031 |
push user | mak77@bonardo.net |
push date | Fri, 19 Aug 2011 09:40:40 +0000 |
treeherder | mozilla-central@1881f9b5f8b5 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 9.0a1 |
first release with | nightly linux32
1881f9b5f8b5
/
9.0a1
/
20110819030749
/
files
nightly linux64
1881f9b5f8b5
/
9.0a1
/
20110819030749
/
files
nightly mac
1881f9b5f8b5
/
9.0a1
/
20110819030749
/
files
nightly win32
1881f9b5f8b5
/
9.0a1
/
20110819030749
/
files
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
9.0a1
/
20110819030749
/
pushlog to previous
nightly linux64
9.0a1
/
20110819030749
/
pushlog to previous
nightly mac
9.0a1
/
20110819030749
/
pushlog to previous
nightly win32
9.0a1
/
20110819030749
/
pushlog to previous
|
content/base/src/nsGkAtomList.h | file | annotate | diff | comparison | revisions | |
docshell/base/nsIGlobalHistory3.idl | file | annotate | diff | comparison | revisions | |
js/src/jit-test/tests/bug666448.js | file | annotate | diff | comparison | revisions | |
modules/libreg/src/mmapio.c | file | annotate | diff | comparison | revisions | |
modules/libreg/src/mmapio.h | file | annotate | diff | comparison | revisions |
--- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -876,17 +876,17 @@ pref("browser.privatebrowsing.autostart" // Whether we should skip prompting before starting the private browsing mode pref("browser.privatebrowsing.dont_prompt_on_enter", false); // Don't try to alter this pref, it'll be reset the next time you use the // bookmarking dialog pref("browser.bookmarks.editDialog.firstEditField", "namePicker"); // base url for the wifi geolocation network provider -pref("geo.wifi.uri", "https://www.google.com/loc/json"); +pref("geo.wifi.uri", "https://maps.googleapis.com/maps/api/browserlocation/json"); pref("geo.wifi.protocol", 0); // Whether to use a panel that looks like an OS X sheet for customization #ifdef XP_MACOSX pref("toolbar.customization.usesheet", true); #else pref("toolbar.customization.usesheet", false); #endif
--- a/build/mobile/sutagent/android/watcher/WatcherService.java +++ b/build/mobile/sutagent/android/watcher/WatcherService.java @@ -102,17 +102,16 @@ public class WatcherService extends Serv private Method mStartForeground; private Method mStopForeground; private Object[] mSetForegroundArgs = new Object[1]; private Object[] mStartForegroundArgs = new Object[2]; private Object[] mStopForegroundArgs = new Object[1]; private IWatcherService.Stub stub = new IWatcherService.Stub() { - @Override public int UpdateApplication(String sAppName, String sFileName, String sOutFile, int bReboot) throws RemoteException { return UpdtApp(sAppName, sFileName, sOutFile, bReboot); } }; @Override public IBinder onBind(Intent arg0) { @@ -869,17 +868,16 @@ public class WatcherService extends Serv runner = new Thread(this); msPkgName = sPkgName; msPkgFileName = sPkgFileName; msOutFile = sOutFile; mbReboot = bReboot; runner.start(); } - @Override public void run() { bInstalling = true; UpdtApp(msPkgName, msPkgFileName, msOutFile, mbReboot); bInstalling = false; } } private class MyTime extends TimerTask
--- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -1732,17 +1732,18 @@ nsScriptSecurityManager::CheckFunctionAc nsIPrincipal* subject = GetFunctionObjectPrincipal(aCx, (JSObject *)aFunObj, nsnull, &rv); // If subject is null, get a principal from the function object's scope. if (NS_SUCCEEDED(rv) && !subject) { #ifdef DEBUG { - JSFunction *fun = GET_FUNCTION_PRIVATE(cx, (JSObject *)aFunObj); + JS_ASSERT(JS_ObjectIsFunction(aCx, (JSObject *)aFunObj)); + JSFunction *fun = (JSFunction *)JS_GetPrivate(aCx, (JSObject *)aFunObj); JSScript *script = JS_GetFunctionScript(aCx, fun); NS_ASSERTION(!script, "Null principal for non-native function!"); } #endif subject = doGetObjectPrincipal((JSObject*)aFunObj); } @@ -2213,17 +2214,17 @@ nsScriptSecurityManager::GetFunctionObje { // Protect against pseudo-functions (like SJOWs). nsIPrincipal *result = doGetObjectPrincipal(obj); if (!result) *rv = NS_ERROR_FAILURE; return result; } - JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj); + JSFunction *fun = (JSFunction *)JS_GetPrivate(cx, obj); JSScript *script = JS_GetFunctionScript(cx, fun); if (!script) { // A native function: skip it in order to find its scripted caller. return nsnull; } @@ -2279,17 +2280,17 @@ nsScriptSecurityManager::GetFramePrincip return GetScriptPrincipal(cx, script, rv); } nsIPrincipal* result = GetFunctionObjectPrincipal(cx, obj, fp, rv); #ifdef DEBUG if (NS_SUCCEEDED(*rv) && !result) { - JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj); + JSFunction *fun = (JSFunction *)JS_GetPrivate(cx, obj); JSScript *script = JS_GetFunctionScript(cx, fun); NS_ASSERTION(!script, "Null principal for non-native function!"); } #endif return result; }
--- a/config/autoconf.mk.in +++ b/config/autoconf.mk.in @@ -218,17 +218,16 @@ MOZ_POST_DSO_LIB_COMMAND = @MOZ_POST_DSO MOZ_POST_PROGRAM_COMMAND = @MOZ_POST_PROGRAM_COMMAND@ MOZ_BUILD_ROOT = @MOZ_BUILD_ROOT@ MOZ_XUL = @MOZ_XUL@ MOZ_RDF = @MOZ_RDF@ NECKO_PROTOCOLS = @NECKO_PROTOCOLS@ -NECKO_DISK_CACHE = @NECKO_DISK_CACHE@ NECKO_COOKIES = @NECKO_COOKIES@ NECKO_WIFI = @NECKO_WIFI@ MOZ_AUTH_EXTENSION = @MOZ_AUTH_EXTENSION@ MOZ_NATIVE_HUNSPELL = @SYSTEM_HUNSPELL@ MOZ_HUNSPELL_LIBS = @MOZ_HUNSPELL_LIBS@ MOZ_HUNSPELL_CFLAGS = @MOZ_HUNSPELL_CFLAGS@
--- a/configure.in +++ b/configure.in @@ -2102,16 +2102,18 @@ case "$target" in DSO_LDOPTS='' STRIP="$STRIP -x -S" _PLATFORM_DEFAULT_TOOLKIT='cairo-cocoa' TARGET_NSPR_MDCPUCFG='\"md/_darwin.cfg\"' # The ExceptionHandling framework is needed for Objective-C exception # logging code in nsObjCExceptions.h. Currently we only use that in debug # builds. MOZ_DEBUG_LDFLAGS="$MOZ_DEBUG_LDFLAGS -framework ExceptionHandling" + # Debug builds should always have frame pointers + MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer" if test "x$lto_is_enabled" = "xyes"; then echo "Skipping -dead_strip because lto is enabled." dnl DTrace and -dead_strip don't interact well. See bug 403132. dnl =================================================================== elif test "x$enable_dtrace" = "xyes"; then echo "Skipping -dead_strip because DTrace is enabled. See bug 403132." else @@ -2248,16 +2250,18 @@ ia64*-hpux*) MOZ_GFX_OPTIMIZE_MOBILE=1 # If we're building with --enable-profiling, we need a frame pointer. if test -z "$MOZ_PROFILING"; then MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions -fomit-frame-pointer" else MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions -fno-omit-frame-pointer" fi + # Debug builds should always have frame pointers + MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer" ;; *-*linux*) # Note: both GNU_CC and INTEL_CC are set when using Intel's C compiler. # Similarly for GNU_CXX and INTEL_CXX. if test "$INTEL_CC" -o "$INTEL_CXX"; then # -Os has been broken on Intel's C/C++ compilers for quite a # while; Intel recommends against using it. @@ -2273,17 +2277,18 @@ ia64*-hpux*) # If we're building with --enable-profiling, we need a frame pointer. if test -z "$MOZ_PROFILING"; then MOZ_FRAMEPTR_FLAGS="-fomit-frame-pointer" else MOZ_FRAMEPTR_FLAGS="-fno-omit-frame-pointer" fi MOZ_PGO_OPTIMIZE_FLAGS="-O3 $MOZ_FRAMEPTR_FLAGS" MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks $MOZ_OPTIMIZE_SIZE_TWEAK $MOZ_FRAMEPTR_FLAGS" - MOZ_DEBUG_FLAGS="-g" + # Debug builds should always have frame pointers + MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer" fi TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"' MOZ_MEMORY=1 case "${target_cpu}" in alpha*) @@ -2366,17 +2371,18 @@ ia64*-hpux*) _DEFINES_CXXFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT' CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)" CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)" CXXFLAGS="$CXXFLAGS -wd4800" # disable warning "forcing value to bool" # make 'foo == bar;' error out CFLAGS="$CFLAGS -we4553" CXXFLAGS="$CXXFLAGS -we4553" LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib" - MOZ_DEBUG_FLAGS='-Zi' + # Debug builds should always have frame pointers + MOZ_DEBUG_FLAGS='-Zi -Oy-' MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV' WARNINGS_AS_ERRORS='-WX' # If we're building with --enable-profiling, we need -Oy-, which forces a frame pointer. if test -z "$MOZ_PROFILING"; then MOZ_OPTIMIZE_FLAGS='-O1' else MOZ_OPTIMIZE_FLAGS='-O1 -Oy-' fi @@ -3583,63 +3589,16 @@ then CFLAGS="$CFLAGS -mt" CXXFLAGS="$CXXFLAGS -mt" fi ;; esac LDFLAGS="${_PTHREAD_LDFLAGS} ${LDFLAGS}" fi -dnl ======================================================== -dnl See if mmap sees writes -dnl For cross compiling, just define it as no, which is a safe default -dnl ======================================================== -AC_MSG_CHECKING(whether mmap() sees write()s) - -changequote(,) -mmap_test_prog=' - #include <stdlib.h> - #include <unistd.h> - #include <sys/mman.h> - #include <sys/types.h> - #include <sys/stat.h> - #include <fcntl.h> - - char fname[] = "conftest.file"; - char zbuff[1024]; /* Fractional page is probably worst case */ - - int main() { - char *map; - int fd; - int i; - unlink(fname); - fd = open(fname, O_RDWR | O_CREAT, 0660); - if(fd<0) return 1; - unlink(fname); - write(fd, zbuff, sizeof(zbuff)); - lseek(fd, 0, SEEK_SET); - map = (char*)mmap(0, sizeof(zbuff), PROT_READ, MAP_SHARED, fd, 0); - if(map==(char*)-1) return 2; - for(i=0; fname[i]; i++) { - int rc = write(fd, &fname[i], 1); - if(map[i]!=fname[i]) return 4; - } - return 0; - } -' -changequote([,]) - -AC_TRY_RUN($mmap_test_prog , result="yes", result="no", result="yes") - -AC_MSG_RESULT("$result") - -if test "$result" = "no"; then - AC_DEFINE(MMAP_MISSES_WRITES) -fi - dnl Checks for library functions. dnl ======================================================== AC_PROG_GCC_TRADITIONAL AC_FUNC_MEMCMP AC_CHECK_FUNCS(random strerror lchown fchmod snprintf statvfs memmove rint stat64 lstat64 truncate64 statvfs64 setbuf isatty) AC_CHECK_FUNCS(flockfile getpagesize) AC_CHECK_FUNCS(localtime_r strtok_r) @@ -4773,17 +4732,16 @@ MOZ_XTF=1 MOZ_XUL=1 MOZ_ZIPWRITER=1 NS_PRINTING=1 MOZ_PDF_PRINTING= MOZ_DISABLE_DOMCRYPTO= NSS_DISABLE_DBM= NECKO_WIFI=1 NECKO_COOKIES=1 -NECKO_DISK_CACHE=1 NECKO_PROTOCOLS_DEFAULT="about data file ftp http res viewsource websocket wyciwyg" USE_ARM_KUSER= BUILD_CTYPES=1 MOZ_USE_NATIVE_POPUP_WINDOWS= case "${target}" in *android*|*darwin*) @@ -5189,30 +5147,31 @@ incorrect]) MOZ_ENABLE_QTNETWORK=) if test "$MOZ_ENABLE_QTNETWORK"; then MOZ_ENABLE_QTNETWORK=1 AC_DEFINE(MOZ_ENABLE_QTNETWORK) fi MOZ_ENABLE_QTMOBILITY= - PKG_CHECK_MODULES(_QTMOBILITY, QtSensors QtFeedback, + PKG_CHECK_MODULES(_QTMOBILITY, QtSensors QtFeedback QtLocation, MOZ_ENABLE_QTMOBILITY=1, MOZ_ENABLE_QTMOBILITY=) if test "$MOZ_ENABLE_QTMOBILITY"; then MOZ_ENABLE_QTMOBILITY=1 MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $_QTMOBILITY_CFLAGS" MOZ_QT_LIBS="$MOZ_QT_LIBS $_QTMOBILITY_LIBS" else - AC_CHECK_LIB(QtSensors QtFeedback, main, [ + AC_CHECK_LIB(QtSensors QtFeedback QtLocation, main, [ MOZ_ENABLE_QTMOBILITY=1 MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtMobility" MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtSensors" MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtFeedback" - MOZ_QT_LIBS="$MOZ_QT_LIBS -lQtSensors -lQtFeedback" + MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtLocation" + MOZ_QT_LIBS="$MOZ_QT_LIBS -lQtSensors -lQtFeedback -lQtLocation" ]) fi if test "$MOZ_ENABLE_QTMOBILITY"; then AC_DEFINE(MOZ_ENABLE_QTMOBILITY) fi fi AC_SUBST(GTK_CONFIG) @@ -8760,29 +8719,16 @@ done], dnl Remove dupes NECKO_PROTOCOLS=`${PERL} ${srcdir}/build/unix/uniq.pl ${NECKO_PROTOCOLS}` AC_SUBST(NECKO_PROTOCOLS) for p in $NECKO_PROTOCOLS; do AC_DEFINE_UNQUOTED(NECKO_PROTOCOL_$p) done dnl -dnl option to disable necko's disk cache -dnl -MOZ_ARG_DISABLE_BOOL(necko-disk-cache, -[ --disable-necko-disk-cache - Disable necko disk cache], - NECKO_DISK_CACHE=, - NECKO_DISK_CACHE=1) -AC_SUBST(NECKO_DISK_CACHE) -if test "$NECKO_DISK_CACHE"; then - AC_DEFINE(NECKO_DISK_CACHE) -fi - -dnl dnl option to disable necko's wifi scanner dnl MOZ_ARG_DISABLE_BOOL(necko-wifi, [ --disable-necko-wifi Disable necko wifi scanner], NECKO_WIFI=, NECKO_WIFI=1) if test "$OS_ARCH" = "OS2"; then
--- a/content/base/src/Makefile.in +++ b/content/base/src/Makefile.in @@ -90,16 +90,17 @@ CPPSRCS = \ nsContentUtils.cpp \ nsCopySupport.cpp \ nsCrossSiteListenerProxy.cpp \ nsCSPService.cpp \ nsDataDocumentContentPolicy.cpp \ nsDOMAttribute.cpp \ nsDOMAttributeMap.cpp \ nsDOMBlobBuilder.cpp \ + nsDOMCaretPosition.cpp \ nsDOMDocumentType.cpp \ nsDOMEventTargetWrapperCache.cpp \ nsDOMFile.cpp \ nsDOMFileReader.cpp \ nsDOMLists.cpp \ nsDOMParser.cpp \ nsDOMSerializer.cpp \ nsDOMTokenList.cpp \
new file mode 100644 --- /dev/null +++ b/content/base/src/nsDOMCaretPosition.cpp @@ -0,0 +1,77 @@ +/* ***** 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.org. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brad Lassey <blassey@mozilla.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 "nsDOMCaretPosition.h" +#include "nsDOMClassInfoID.h" +#include "nsIDOMClassInfo.h" + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMCaretPosition) + NS_INTERFACE_MAP_ENTRY(nsIDOMCaretPosition) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMCaretPosition) + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CaretPosition) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTION_1(nsDOMCaretPosition, mNode) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCaretPosition) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMCaretPosition) + +DOMCI_DATA(CaretPosition, nsDOMCaretPosition) + + +nsDOMCaretPosition::nsDOMCaretPosition(nsIDOMNode* aNode, PRUint32 aOffset) + : mNode(aNode), mOffset(aOffset) +{ +} + +nsDOMCaretPosition::~nsDOMCaretPosition() +{ +} + +NS_IMETHODIMP nsDOMCaretPosition::GetOffsetNode(nsIDOMNode** aOffsetNode) +{ + nsCOMPtr<nsIDOMNode> node = mNode; + node.forget(aOffsetNode); + return NS_OK; +} + +NS_IMETHODIMP nsDOMCaretPosition::GetOffset(PRUint32* aOffset) +{ + *aOffset = mOffset; + return NS_OK; +} +
new file mode 100644 --- /dev/null +++ b/content/base/src/nsDOMCaretPosition.h @@ -0,0 +1,59 @@ +/* ***** 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.org. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brad Lassey <blassey@mozilla.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 ***** */ + +#ifndef nsDOMCaretPosition_h +#define nsDOMCaretPosition_h + +#include "nsIDOMCaretPosition.h" +#include "nsCycleCollectionParticipant.h" +#include "nsCOMPtr.h" + +class nsDOMCaretPosition : public nsIDOMCaretPosition +{ +public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMCaretPosition) + NS_DECL_NSIDOMCARETPOSITION + + nsDOMCaretPosition(nsIDOMNode* aNode, PRUint32 aOffset); + +protected: + virtual ~nsDOMCaretPosition(); + PRUint32 mOffset; + nsCOMPtr<nsIDOMNode> mNode; +}; +#endif
--- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -197,19 +197,23 @@ #include "nsHTMLCSSStyleSheet.h" #include "mozilla/dom/Link.h" #include "nsIHTMLDocument.h" #include "nsXULAppAPI.h" #include "nsDOMTouchEvent.h" #include "mozilla/Preferences.h" +#include "nsFrame.h" #include "imgILoader.h" +#include "nsDOMCaretPosition.h" +#include "nsIDOMHTMLTextAreaElement.h" + using namespace mozilla; using namespace mozilla::dom; typedef nsTArray<Link*> LinkArray; #ifdef PR_LOGGING static PRLogModuleInfo* gDocumentLeakPRLog; @@ -8389,16 +8393,68 @@ nsDocument::CreateTouchList(nsIVariant* nsMemory::Free(rawArray); } } *aRetVal = retval.forget().get(); return NS_OK; } +NS_IMETHODIMP +nsDocument::CaretPositionFromPoint(float aX, float aY, nsIDOMCaretPosition** aCaretPos) +{ + NS_ENSURE_ARG_POINTER(aCaretPos); + *aCaretPos = nsnull; + + nscoord x = nsPresContext::CSSPixelsToAppUnits(aX); + nscoord y = nsPresContext::CSSPixelsToAppUnits(aY); + nsPoint pt(x, y); + + nsIPresShell *ps = GetShell(); + if (!ps) { + return NS_OK; + } + + nsIFrame *rootFrame = ps->GetRootFrame(); + + // XUL docs, unlike HTML, have no frame tree until everything's done loading + if (!rootFrame) { + return NS_OK; // return null to premature XUL callers as a reminder to wait + } + + nsIFrame *ptFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, pt, PR_TRUE, + PR_FALSE); + if (!ptFrame) { + return NS_OK; + } + + nsFrame::ContentOffsets offsets = ptFrame->GetContentOffsetsFromPoint(pt); + nsCOMPtr<nsIDOMNode> node = do_QueryInterface(offsets.content); + nsIContent* ptContent = offsets.content; + PRInt32 offset = offsets.offset; + if (ptContent && ptContent->IsInNativeAnonymousSubtree()) { + nsIContent* nonanon = ptContent->FindFirstNonNativeAnonymous(); + nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(nonanon); + nsCOMPtr<nsIDOMHTMLTextAreaElement> textArea = do_QueryInterface(nonanon); + PRBool isText; + if (textArea || (input && + NS_SUCCEEDED(input->MozIsTextField(PR_FALSE, &isText)) && + isText)) { + node = do_QueryInterface(nonanon); + } else { + node = nsnull; + offset = 0; + } + } + + *aCaretPos = new nsDOMCaretPosition(node, offset); + NS_ADDREF(*aCaretPos); + return NS_OK; +} + PRInt64 nsIDocument::SizeOf() const { PRInt64 size = sizeof(*this); for (nsIContent* node = GetFirstChild(); node; node = node->GetNextNode(this)) { size += node->SizeOf();
--- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -1054,18 +1054,19 @@ nsINode::AddEventListener(const nsAStrin if (!aWantsUntrusted && (aOptionalArgc < 2 && !nsContentUtils::IsChromeDoc(GetOwnerDoc()))) { aWantsUntrusted = PR_TRUE; } nsEventListenerManager* listener_manager = GetListenerManager(PR_TRUE); NS_ENSURE_STATE(listener_manager); - return listener_manager->AddEventListener(aType, aListener, aUseCapture, - aWantsUntrusted); + listener_manager->AddEventListener(aType, aListener, aUseCapture, + aWantsUntrusted); + return NS_OK; } NS_IMETHODIMP nsINode::RemoveEventListener(const nsAString& aType, nsIDOMEventListener* aListener, PRBool aUseCapture) { nsEventListenerManager* elm = GetListenerManager(PR_FALSE);
--- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -1869,16 +1869,17 @@ GK_ATOM(scrollbar_start_backward, "scrol GK_ATOM(scrollbar_start_forward, "scrollbar-start-forward") GK_ATOM(scrollbar_end_backward, "scrollbar-end-backward") GK_ATOM(scrollbar_end_forward, "scrollbar-end-forward") GK_ATOM(scrollbar_thumb_proportional, "scrollbar-thumb-proportional") GK_ATOM(images_in_menus, "images-in-menus") GK_ATOM(images_in_buttons, "images-in-buttons") GK_ATOM(windows_default_theme, "windows-default-theme") GK_ATOM(mac_graphite_theme, "mac-graphite-theme") +GK_ATOM(mac_lion_theme, "mac-lion-theme") GK_ATOM(windows_compositor, "windows-compositor") GK_ATOM(touch_enabled, "touch-enabled") GK_ATOM(maemo_classic, "maemo-classic") GK_ATOM(menubar_drag, "menubar-drag") // windows theme selector metrics GK_ATOM(windows_classic, "windows-classic") GK_ATOM(windows_theme_aero, "windows-theme-aero") @@ -1894,16 +1895,17 @@ GK_ATOM(_moz_scrollbar_start_backward, " GK_ATOM(_moz_scrollbar_start_forward, "-moz-scrollbar-start-forward") GK_ATOM(_moz_scrollbar_end_backward, "-moz-scrollbar-end-backward") GK_ATOM(_moz_scrollbar_end_forward, "-moz-scrollbar-end-forward") GK_ATOM(_moz_scrollbar_thumb_proportional, "-moz-scrollbar-thumb-proportional") GK_ATOM(_moz_images_in_menus, "-moz-images-in-menus") GK_ATOM(_moz_images_in_buttons, "-moz-images-in-buttons") GK_ATOM(_moz_windows_default_theme, "-moz-windows-default-theme") GK_ATOM(_moz_mac_graphite_theme, "-moz-mac-graphite-theme") +GK_ATOM(_moz_mac_lion_theme, "-moz-mac-lion-theme") GK_ATOM(_moz_windows_compositor, "-moz-windows-compositor") GK_ATOM(_moz_windows_classic, "-moz-windows-classic") GK_ATOM(_moz_windows_theme, "-moz-windows-theme") GK_ATOM(_moz_touch_enabled, "-moz-touch-enabled") GK_ATOM(_moz_maemo_classic, "-moz-maemo-classic") GK_ATOM(_moz_menubar_drag, "-moz-menubar-drag") GK_ATOM(_moz_device_pixel_ratio, "-moz-device-pixel-ratio") GK_ATOM(_moz_device_orientation, "-moz-device-orientation")
--- a/content/base/test/Makefile.in +++ b/content/base/test/Makefile.in @@ -498,16 +498,17 @@ include $(topsrcdir)/config/rules.mk invalid_accesscontrol.resource^headers^ \ somedatas.resource \ somedatas.resource^headers^ \ delayedServerEvents.sjs \ test_bug664916.html \ test_bug666604.html \ test_bug675121.html \ file_bug675121.sjs \ + test_bug654352.html \ $(NULL) _CHROME_FILES = \ test_bug357450.js \ $(NULL) # This test fails on the Mac for some reason ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
new file mode 100644 --- /dev/null +++ b/content/base/test/test_bug654352.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=654352 +--> +<head> + <title>Test for Bug 654352</title> + <script type="application/javascript" src="/MochiKit/packed.js"></script> + <script type="application/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=654352">Mozilla Bug 654352</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 654352 **/ +SimpleTest.waitForExplicitFinish(); +function afterLoad() { + var testpre = document.getElementById("testpre"); + var rect1 = testpre.getBoundingClientRect(); + dump(rect1 + "\n"); + var caret1 = document.caretPositionFromPoint(rect1.right - 5, rect1.top + 10); + ok(caret1.offsetNode == testpre.firstChild, "node in CaretPosition not correct (" + caret1.offsetNode + " == " + testpre.firstChild + ")") + ok(caret1.offset == 9, "offset in CaretPosition not correct (" + caret1.offset + "== 9)") + + var testinput = document.getElementById("testinput"); + var rect2 = testinput.getBoundingClientRect(); + dump(rect2.top +", " + rect2.left + "\n"); + var caret2 = document.caretPositionFromPoint( rect2.right - 5, rect2.top + 10); + ok(caret2.offsetNode == testinput, "node in CaretPosition not correct (" + caret2.offsetNode + " == " + testinput + ")") + ok(caret2.offset == 9, "offset in CaretPosition not correct (" + caret2.offset + "== 9)") + SimpleTest.finish(); +}; +addLoadEvent(afterLoad); +</script> +</pre> +<span id="testdiv"> + <pre id="testpre">test text</pre> +</span> +<br> +<br> +</div> + <input id="testinput" type="text" value="test text"></input> +</div> +</body> +</html>
--- a/content/base/test/test_copypaste.html +++ b/content/base/test/test_copypaste.html @@ -48,18 +48,18 @@ function testCopyPaste () { var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"] .getService(Components.interfaces.nsIClipboard); var textarea = document.getElementById('input'); function copySelectionToClipboard() { documentViewer.copySelection(); - is(clipboard.hasDataMatchingFlavors(["text/unicode"], 1,1), true); - is(clipboard.hasDataMatchingFlavors(["text/html"], 1,1), true); + ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1,1), "check text/unicode"); + ok(clipboard.hasDataMatchingFlavors(["text/html"], 1,1), "check text/html"); } function copyToClipboard(node) { textarea.blur(); clipboard.emptyClipboard(1); var sel = window.getSelection(); sel.removeAllRanges(); var r = document.createRange(); r.selectNode(node);
--- a/content/events/src/nsDOMEventTargetHelper.cpp +++ b/content/events/src/nsDOMEventTargetHelper.cpp @@ -121,17 +121,18 @@ nsDOMEventTargetHelper::AddEventListener NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDocument> doc = nsContentUtils::GetDocumentFromScriptContext(context); aWantsUntrusted = doc && !nsContentUtils::IsChromeDoc(doc); } nsEventListenerManager* elm = GetListenerManager(PR_TRUE); NS_ENSURE_STATE(elm); - return elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted); + elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted); + return NS_OK; } NS_IMETHODIMP nsDOMEventTargetHelper::DispatchEvent(nsIDOMEvent* aEvent, PRBool* aRetVal) { nsEventStatus status = nsEventStatus_eIgnore; nsresult rv = nsEventDispatcher::DispatchDOMEvent(this, nsnull, aEvent, nsnull, &status);
--- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -204,34 +204,37 @@ nsEventListenerManager::GetInnerWindowFo if (window) { NS_ASSERTION(window->IsInnerWindow(), "Target should not be an outer window"); return window; } return nsnull; } -nsresult +void nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener, PRUint32 aType, nsIAtom* aTypeAtom, PRInt32 aFlags) { - NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE); - NS_ENSURE_TRUE(aType, NS_ERROR_FAILURE); + NS_ABORT_IF_FALSE(aType && aTypeAtom, "Missing type"); + + if (!aListener) { + return; + } nsRefPtr<nsIDOMEventListener> kungFuDeathGrip = aListener; nsListenerStruct* ls; PRUint32 count = mListeners.Length(); for (PRUint32 i = 0; i < count; i++) { ls = &mListeners.ElementAt(i); if (ls->mListener == aListener && ls->mFlags == aFlags && EVENT_TYPE_EQUALS(ls, aType, aTypeAtom)) { - return NS_OK; + return; } } mNoListenerForEvent = NS_EVENT_TYPE_NULL; mNoListenerForEventAtom = nsnull; ls = mListeners.AppendElement(); ls->mListener = aListener; @@ -286,18 +289,16 @@ nsEventListenerManager::AddEventListener aTypeAtom == nsGkAtoms::ontouchenter || aTypeAtom == nsGkAtoms::ontouchleave || aTypeAtom == nsGkAtoms::ontouchcancel)) { mMayHaveTouchEventListener = PR_TRUE; nsPIDOMWindow* window = GetInnerWindowForTarget(); if (window) window->SetHasTouchEventListeners(); } - - return NS_OK; } void nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener, PRUint32 aType, nsIAtom* aUserType, PRInt32 aFlags) { @@ -329,24 +330,24 @@ ListenerCanHandle(nsListenerStruct* aLs, // This is slightly different from EVENT_TYPE_EQUALS in that it returns // true even when aEvent->message == NS_USER_DEFINED_EVENT and // aLs=>mEventType != NS_USER_DEFINED_EVENT as long as the atoms are the same return aEvent->message == NS_USER_DEFINED_EVENT ? (aLs->mTypeAtom == aEvent->userType) : (aLs->mEventType == aEvent->message); } -nsresult +void nsEventListenerManager::AddEventListenerByType(nsIDOMEventListener *aListener, const nsAString& aType, PRInt32 aFlags) { nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aType); PRUint32 type = nsContentUtils::GetEventId(atom); - return AddEventListener(aListener, type, atom, aFlags); + AddEventListener(aListener, type, atom, aFlags); } void nsEventListenerManager::RemoveEventListenerByType(nsIDOMEventListener *aListener, const nsAString& aType, PRInt32 aFlags) { nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aType); @@ -938,18 +939,17 @@ nsEventListenerManager::HandleEventInter void nsEventListenerManager::Disconnect() { mTarget = nsnull; RemoveAllListeners(); } -// nsIDOMEventTarget interface -nsresult +void nsEventListenerManager::AddEventListener(const nsAString& aType, nsIDOMEventListener* aListener, PRBool aUseCapture, PRBool aWantsUntrusted) { PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE; if (aWantsUntrusted) {
--- a/content/events/src/nsEventListenerManager.h +++ b/content/events/src/nsEventListenerManager.h @@ -79,31 +79,31 @@ class nsEventListenerManager public: nsEventListenerManager(nsISupports* aTarget); virtual ~nsEventListenerManager(); NS_INLINE_DECL_REFCOUNTING(nsEventListenerManager) NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsEventListenerManager) - nsresult AddEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, - PRBool aUseCapture, - PRBool aWantsUntrusted); + void AddEventListener(const nsAString& aType, + nsIDOMEventListener* aListener, + PRBool aUseCapture, + PRBool aWantsUntrusted); void RemoveEventListener(const nsAString& aType, nsIDOMEventListener* aListener, PRBool aUseCapture); /** * Sets events listeners of all types. * @param an event listener */ - nsresult AddEventListenerByType(nsIDOMEventListener *aListener, - const nsAString& type, - PRInt32 aFlags); + void AddEventListenerByType(nsIDOMEventListener *aListener, + const nsAString& type, + PRInt32 aFlags); void RemoveEventListenerByType(nsIDOMEventListener *aListener, const nsAString& type, PRInt32 aFlags); nsresult AddScriptEventListener(nsIAtom *aName, const nsAString& aFunc, PRUint32 aLanguage, PRBool aDeferCompilation, PRBool aPermitUntrustedEvents); @@ -205,20 +205,20 @@ protected: nsListenerStruct *aListenerStruct, nsISupports* aCurrentTarget, PRBool aNeedsCxPush); nsListenerStruct* FindJSEventListener(PRUint32 aEventType, nsIAtom* aTypeAtom); nsresult SetJSEventListener(nsIScriptContext *aContext, void *aScopeGlobal, nsIAtom* aName, PRBool aIsString, PRBool aPermitUntrustedEvents); - nsresult AddEventListener(nsIDOMEventListener *aListener, - PRUint32 aType, - nsIAtom* aTypeAtom, - PRInt32 aFlags); + void AddEventListener(nsIDOMEventListener *aListener, + PRUint32 aType, + nsIAtom* aTypeAtom, + PRInt32 aFlags); void RemoveEventListener(nsIDOMEventListener *aListener, PRUint32 aType, nsIAtom* aUserType, PRInt32 aFlags); void RemoveAllListeners(); const EventTypeData* GetTypeDataForIID(const nsIID& aIID); const EventTypeData* GetTypeDataForEventName(nsIAtom* aName); nsPIDOMWindow* GetInnerWindowForTarget();
--- a/content/events/src/nsEventListenerService.cpp +++ b/content/events/src/nsEventListenerService.cpp @@ -275,17 +275,18 @@ nsEventListenerService::AddSystemEventLi nsEventListenerManager* manager = aTarget->GetListenerManager(PR_TRUE); NS_ENSURE_STATE(manager); PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE | NS_EVENT_FLAG_SYSTEM_EVENT : NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_SYSTEM_EVENT; - return manager->AddEventListenerByType(aListener, aType, flags); + manager->AddEventListenerByType(aListener, aType, flags); + return NS_OK; } NS_IMETHODIMP nsEventListenerService::RemoveSystemEventListener(nsIDOMEventTarget *aTarget, const nsAString& aType, nsIDOMEventListener* aListener, PRBool aUseCapture) {
--- a/content/events/test/Makefile.in +++ b/content/events/test/Makefile.in @@ -102,16 +102,18 @@ include $(topsrcdir)/config/rules.mk test_bug648573.html \ test_bug615597.html \ test_bug656379-1.html \ test_bug656379-2.html \ test_bug656954.html \ test_bug662678.html \ test_bug667919-1.html \ test_bug667919-2.html \ + test_bug667612.html \ + empty.js \ $(NULL) #bug 585630 ifneq (mobile,$(MOZ_BUILD_APP)) _TEST_FILES += \ test_dragstart.html \ $(NULL) endif
new file mode 100644 --- /dev/null +++ b/content/events/test/test_bug667612.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=667612 +--> +<head> + <title>Test for Bug 667612</title> + <script type="text/javascript" src="/MochiKit/packed.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=667612">Mozilla Bug 667612</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +xhr = new XMLHttpRequest; +w = new Worker("empty.js"); +window.addEventListener("load", null, false); +document.addEventListener("load", null, false); +document.body.addEventListener("load", null, false); +xhr.addEventListener("load", null, false); +w.addEventListener("load", null, false); +window.addEventListener("load", undefined, false); +document.addEventListener("load", undefined, false); +document.body.addEventListener("load", undefined, false); +xhr.addEventListener("load", undefined, false); +w.addEventListener("load", undefined, false); + +ok(true, "didn't throw"); + +</script> +</pre> +</body> +</html>
--- a/content/media/test/test_delay_load.html +++ b/content/media/test/test_delay_load.html @@ -91,24 +91,26 @@ document.body.appendChild(v); // Load outside of doc. v = createVideo(test.name, test.type, "3"); v.load(); // Load and move to another document. netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); v = createVideo(test.name, test.type, "4"); +v.onloadstart = function(e) { + // Opening a new window to do this is a bit annoying, but if we use an iframe here, + // delaying of the iframe's load event might interfere with the firing of our load event + // in some confusing way. So it's simpler just to open another window. + var w = window.open("", "testWindow", "width=400,height=400"); + w.document.body.appendChild(v); + testWindows.push(w); +}; v.load(); // load started while in this document, this doc's load will block until - // the video's finished loading (in the other document). -// Opening a new window to do this is a bit annoying, but if we use an iframe here, -// delaying of the iframe's load event might interfere with the firing of our load event -// in some confusing way. So it's simpler just to open another window. -var w = window.open("", "testWindow", "width=400,height=400"); -w.document.body.appendChild(v); -testWindows.push(w); + // the video's finished loading (in the other document). if (gRegisteredElements.length > 0) { SimpleTest.waitForExplicitFinish(); } else { todo(false, "No types supported"); } </script>
--- a/docshell/base/Makefile.in +++ b/docshell/base/Makefile.in @@ -61,17 +61,16 @@ XPIDLSRCS = \ nsCDefaultURIFixup.idl \ nsIDocShell.idl \ nsIDocShellLoadInfo.idl \ nsIDocShellTreeItem.idl \ nsIDocShellTreeNode.idl \ nsIDocShellTreeOwner.idl \ nsIDocShellHistory.idl \ nsIGlobalHistory2.idl \ - nsIGlobalHistory3.idl \ nsIMarkupDocumentViewer.idl \ nsIScrollable.idl \ nsITextScroll.idl \ nsIWebNavigation.idl \ nsIWebNavigationInfo.idl \ nsIContentViewer.idl \ nsIContentViewerEdit.idl \ nsIContentViewerFile.idl \
--- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -192,17 +192,16 @@ #include "nsIJARChannel.h" #include "prlog.h" #include "prmem.h" #include "nsISelectionDisplay.h" #include "nsIGlobalHistory2.h" -#include "nsIGlobalHistory3.h" #ifdef DEBUG_DOCSHELL_FOCUS #include "nsEventStateManager.h" #endif #include "nsIFrame.h" // for embedding
deleted file mode 100644 --- a/docshell/base/nsIGlobalHistory3.idl +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** 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 the Mozilla gecko engine. - * - * The Initial Developer of the Original Code is - * Google Inc. - * Portions created by the Initial Developer are Copyright (C) 2006 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brett Wilson <brettw@gmail.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 "nsISupports.idl" -#include "nsIGlobalHistory2.idl" -interface nsIChannel; - -%{C++ - -// This is NOT part of the interface! It could change. -#define NS_GECKO_FLAG_NEEDS_VERTICAL_SCROLLBAR (1 << 0) - -%} - -/** - * Provides information about global history to gecko, extending GlobalHistory2 - */ -[scriptable, uuid(24306852-c60e-49c3-a455-90f6747118ba)] -interface nsIGlobalHistory3 : nsIGlobalHistory2 -{ - /** - * Notifies the history system that the page loading via aOldChannel - * redirected to aNewChannel. Implementations should generally add the URI for - * aOldChannel to history for link coloring, but are advised not to expose it - * in the history user interface. This function is preferred if - * nsIGlobalHistory3 is available. Otherwise, nsIGlobalHistory2.addURI should - * be called with redirect=true. - * - * This function is preferred to nsIGlobalHistory2.addURI because it provides - * more information (including the redirect destination, channels involved, - * and redirect flags) to the history implementation. - * - * For implementors of nsIGlobalHistory3: The history implementation is - * responsible for sending NS_LINK_VISITED_EVENT_TOPIC to observers for - * redirect pages. This notification must be sent for history consumers for - * all non-redirect pages. - * - * @param aToplevel whether the URI is loaded in a top-level window. If - * false, the load is in a subframe. - * - * The other params to this function are the same as those for - * nsIChannelEventSink::OnChannelRedirect. - * - * Note: Implementors who wish to implement this interface but rely on - * nsIGlobalHistory2.addURI for redirect processing may throw - * NS_ERROR_NOT_IMPLEMENTED from this method. If they do so, then callers - * must call nsIGlobalHistory2.addURI upon getting the - * NS_ERROR_NOT_IMPLEMENTED result. - */ - void addDocumentRedirect(in nsIChannel aOldChannel, - in nsIChannel aNewChannel, - in PRInt32 aFlags, - in boolean aTopLevel); - - /** - * Get the Gecko flags for this URI. These flags are used by Gecko as hints - * to optimize page loading. Not all histories have them; this need not be - * supported (just return NS_ERROR_NOT_IMPLEMENTED. These flags are opaque - * and should not be interpreted by the history engine. - */ - unsigned long getURIGeckoFlags(in nsIURI aURI); - - /** - * Set the Gecko flags for this URI. May fail if the history entry - * doesn't have any flags or if there is no entry for the URI. - */ - void setURIGeckoFlags(in nsIURI aURI, in unsigned long aFlags); -};
--- a/docshell/test/chrome/docshell_helpers.js +++ b/docshell/test/chrome/docshell_helpers.js @@ -318,18 +318,30 @@ function finish() { // enableBFCache(), then restore it now. if (typeof(gOrigMaxTotalViewers) != "undefined") { SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers", gOrigMaxTotalViewers); } // Close the test window and signal the framework that the test is done. let opener = window.opener; + let SimpleTest = opener.wrappedJSObject.SimpleTest; + + // Wait for the window to be closed before finishing the test + let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci.nsIWindowWatcher); + ww.registerNotification(function(subject, topic, data) { + if (topic == "domwindowclosed") { + ww.unregisterNotification(arguments.callee); + SimpleTest.waitForFocus(function() { + SimpleTest.finish(); + }, opener); + } + }); + window.close(); - opener.wrappedJSObject.SimpleTest.finish(); } /** * Helper function which waits until another function returns true, or until a * timeout occurs, and then notifies a callback. * * Parameters: *
--- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -90,16 +90,17 @@ #include "nsIDOMEventListener.h" #include "nsIDOMPopStateEvent.h" #include "nsIDOMHashChangeEvent.h" #include "nsContentUtils.h" #include "nsDOMWindowUtils.h" #include "nsIDOMGlobalPropertyInitializer.h" #include "mozilla/Preferences.h" #include "nsLocation.h" +#include "nsIDOMCaretPosition.h" // Window scriptable helper includes #include "nsIDocShell.h" #include "nsIDocShellTreeItem.h" #include "nsIDocShellTreeNode.h" #include "nsIScriptExternalNameSet.h" #include "nsJSUtils.h" #include "nsIInterfaceRequestor.h" @@ -660,16 +661,19 @@ static nsDOMClassInfoData sClassInfoData NS_DEFINE_CLASSINFO_DATA(Window, nsWindowSH, DEFAULT_SCRIPTABLE_FLAGS | WINDOW_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(Location, nsLocationSH, (DOM_DEFAULT_SCRIPTABLE_FLAGS & ~nsIXPCScriptable::ALLOW_PROP_MODS_TO_PROTOTYPE)) + NS_DEFINE_CLASSINFO_DATA(CaretPosition, nsDOMGenericSH, + DOM_DEFAULT_SCRIPTABLE_FLAGS) + NS_DEFINE_CLASSINFO_DATA(Navigator, nsNavigatorSH, DOM_DEFAULT_SCRIPTABLE_FLAGS | nsIXPCScriptable::WANT_PRECREATE) NS_DEFINE_CLASSINFO_DATA(Plugin, nsPluginSH, ARRAY_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(PluginArray, nsPluginArraySH, ARRAY_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(MimeType, nsDOMGenericSH, @@ -2275,16 +2279,20 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_MAP_BEGIN(WindowUtils, nsIDOMWindowUtils) DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowUtils) DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_BEGIN(Location, nsIDOMLocation) DOM_CLASSINFO_MAP_ENTRY(nsIDOMLocation) DOM_CLASSINFO_MAP_END + DOM_CLASSINFO_MAP_BEGIN(CaretPosition, nsIDOMCaretPosition) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMCaretPosition) + DOM_CLASSINFO_MAP_END + if (nsNavigator::HasDesktopNotificationSupport()) { DOM_CLASSINFO_MAP_BEGIN(Navigator, nsIDOMNavigator) DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigator) DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorGeolocation) DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorDesktopNotification) DOM_CLASSINFO_MAP_ENTRY(nsIDOMClientInformation) DOM_CLASSINFO_MAP_END } else {
--- a/dom/base/nsDOMClassInfoClasses.h +++ b/dom/base/nsDOMClassInfoClasses.h @@ -33,16 +33,17 @@ * 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 ***** */ DOMCI_CLASS(Window) DOMCI_CLASS(Location) +DOMCI_CLASS(CaretPosition) DOMCI_CLASS(Navigator) DOMCI_CLASS(Plugin) DOMCI_CLASS(PluginArray) DOMCI_CLASS(MimeType) DOMCI_CLASS(MimeTypeArray) DOMCI_CLASS(BarProp) DOMCI_CLASS(History) DOMCI_CLASS(PerformanceTiming)
--- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -1032,26 +1032,27 @@ nsGlobalWindow::~nsGlobalWindow() mDocument = nsnull; // Forces Release mDoc = nsnull; NS_ASSERTION(!mArguments, "mArguments wasn't cleaned up properly!"); CleanUp(PR_TRUE); - NS_ASSERTION(!mHasDeviceMotion, "Window still registered with device motion."); - #ifdef DEBUG nsCycleCollector_DEBUG_wasFreed(static_cast<nsIScriptGlobalObject*>(this)); #endif if (mURLProperty) { mURLProperty->ClearWindowReference(); } + DisableDeviceMotionUpdates(); + mHasDeviceMotion = PR_FALSE; + nsLayoutStatics::Release(); } // static void nsGlobalWindow::ShutDown() { NS_IF_RELEASE(sGlobalStorageList); @@ -1160,19 +1161,16 @@ nsGlobalWindow::CleanUp(PRBool aIgnoreMo mParentTarget = nsnull; nsGlobalWindow *inner = GetCurrentInnerWindowInternal(); if (inner) { inner->CleanUp(aIgnoreModalDialog); } - DisableDeviceMotionUpdates(); - mHasDeviceMotion = PR_FALSE; - if (mCleanMessageManager) { NS_ABORT_IF_FALSE(mIsChrome, "only chrome should have msg manager cleaned"); nsGlobalChromeWindow *asChrome = static_cast<nsGlobalChromeWindow*>(this); if (asChrome->mMessageManager) { static_cast<nsFrameMessageManager*>( asChrome->mMessageManager.get())->Disconnect(); } } @@ -7371,18 +7369,18 @@ nsGlobalWindow::AddEventListener(const n if (!aWantsUntrusted && (aOptionalArgc < 2 && !nsContentUtils::IsChromeDoc(mDoc))) { aWantsUntrusted = PR_TRUE; } nsEventListenerManager* manager = GetListenerManager(PR_TRUE); NS_ENSURE_STATE(manager); - return manager->AddEventListener(aType, aListener, aUseCapture, - aWantsUntrusted); + manager->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted); + return NS_OK; } nsEventListenerManager* nsGlobalWindow::GetListenerManager(PRBool aCreateIfNotFound) { FORWARD_TO_INNER_CREATE(GetListenerManager, (aCreateIfNotFound), nsnull); if (!mListenerManager && aCreateIfNotFound) {
--- a/dom/base/nsWindowRoot.cpp +++ b/dom/base/nsWindowRoot.cpp @@ -141,17 +141,18 @@ nsWindowRoot::AddEventListener(const nsA { NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1, "Won't check if this is chrome, you want to set " "aWantsUntrusted to PR_FALSE or make the aWantsUntrusted " "explicit by making optional_argc non-zero."); nsEventListenerManager* elm = GetListenerManager(PR_TRUE); NS_ENSURE_STATE(elm); - return elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted); + elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted); + return NS_OK; } nsEventListenerManager* nsWindowRoot::GetListenerManager(PRBool aCreateIfNotFound) { if (!mListenerManager && aCreateIfNotFound) { mListenerManager = new nsEventListenerManager(static_cast<nsIDOMEventTarget*>(this));
--- a/dom/interfaces/core/Makefile.in +++ b/dom/interfaces/core/Makefile.in @@ -43,16 +43,17 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk MODULE = dom XPIDL_MODULE = dom_core GRE_MODULE = 1 SDK_XPIDLSRCS = \ nsIDOMAttr.idl \ + nsIDOMCaretPosition.idl \ nsIDOMCDATASection.idl \ nsIDOMCharacterData.idl \ nsIDOMComment.idl \ nsIDOMDOMException.idl \ nsIDOMDOMImplementation.idl \ nsIDOMDocument.idl \ nsIDOMDocumentFragment.idl \ nsIDOMDocumentType.idl \
new file mode 100644 --- /dev/null +++ b/dom/interfaces/core/nsIDOMCaretPosition.idl @@ -0,0 +1,44 @@ +/* ***** 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.org. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brad Lassey <blassey@mozilla.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 "nsIDOMNode.idl" + +[scriptable, uuid(cf5ad6cf-6f49-4ca7-9b50-590d7bb27a13)] +interface nsIDOMCaretPosition : nsISupports { + readonly attribute nsIDOMNode offsetNode; + readonly attribute unsigned long offset; +};
--- a/dom/interfaces/core/nsIDOMDocument.idl +++ b/dom/interfaces/core/nsIDOMDocument.idl @@ -43,31 +43,32 @@ * ***** END LICENSE BLOCK ***** */ #include "nsIDOMNode.idl" interface nsIDOMNodeIterator; interface nsIDOMNodeFilter; interface nsIDOMTreeWalker; interface nsIDOMLocation; +interface nsIDOMCaretPosition; /** * The nsIDOMDocument interface represents the entire HTML or XML document. * Conceptually, it is the root of the document tree, and provides the * primary access to the document's data. * Since elements, text nodes, comments, processing instructions, etc. * cannot exist outside the context of a Document, the nsIDOMDocument * interface also contains the factory methods needed to create these * objects. * * For more information on this interface please see * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html */ -[scriptable, uuid(10034b87-384e-4e19-902c-c4edafb899be)] +[scriptable, uuid(d19897dc-948a-42e7-8ac6-d8a0bd141b85)] interface nsIDOMDocument : nsIDOMNode { readonly attribute nsIDOMDocumentType doctype; readonly attribute nsIDOMDOMImplementation implementation; readonly attribute nsIDOMElement documentElement; nsIDOMElement createElement(in DOMString tagName) raises(DOMException); nsIDOMDocumentFragment createDocumentFragment(); @@ -363,9 +364,11 @@ interface nsIDOMDocument : nsIDOMNode * @param aImageElement a DOM element to be used as the source image of * |-moz-element(#aImageElementId)|. If this is null, the function will * unregister the image element ID |aImageElementId|. * * @see <https://developer.mozilla.org/en/DOM/document.mozSetImageElement> */ void mozSetImageElement(in DOMString aImageElementId, in nsIDOMElement aImageElement); + + nsIDOMCaretPosition caretPositionFromPoint(in float x, in float y); };
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -300,16 +300,17 @@ nsPluginInstanceOwner::nsPluginInstanceO mInCGPaintLevel = 0; mSentInitialTopLevelWindowEvent = PR_FALSE; mColorProfile = nsnull; mPluginPortChanged = PR_FALSE; #endif mContentFocused = PR_FALSE; mWidgetVisible = PR_TRUE; mPluginWindowVisible = PR_FALSE; + mPluginDocumentActiveState = PR_TRUE; mNumCachedAttrs = 0; mNumCachedParams = 0; mCachedAttrParamNames = nsnull; mCachedAttrParamValues = nsnull; mDestroyWidget = PR_FALSE; #ifdef XP_MACOSX #ifndef NP_NO_QUICKDRAW @@ -3236,17 +3237,17 @@ void nsPluginInstanceOwner::UpdateWindow nsIntPoint origin = mObjectFrame->GetWindowOriginInPixels(windowless); mPluginWindow->x = origin.x; mPluginWindow->y = origin.y; mPluginWindow->clipRect.left = 0; mPluginWindow->clipRect.top = 0; - if (mPluginWindowVisible) { + if (mPluginWindowVisible && mPluginDocumentActiveState) { mPluginWindow->clipRect.right = mPluginWindow->width; mPluginWindow->clipRect.bottom = mPluginWindow->height; } else { mPluginWindow->clipRect.right = 0; mPluginWindow->clipRect.bottom = 0; } if (!aSetWindow) @@ -3264,16 +3265,22 @@ void nsPluginInstanceOwner::UpdateWindow void nsPluginInstanceOwner::UpdateWindowVisibility(PRBool aVisible) { mPluginWindowVisible = aVisible; UpdateWindowPositionAndClipRect(PR_TRUE); } +void +nsPluginInstanceOwner::UpdateDocumentActiveState(PRBool aIsActive) +{ + mPluginDocumentActiveState = aIsActive; + UpdateWindowPositionAndClipRect(PR_TRUE); +} #endif // XP_MACOSX void nsPluginInstanceOwner::CallSetWindow() { if (!mInstance) return;
--- a/dom/plugins/base/nsPluginInstanceOwner.h +++ b/dom/plugins/base/nsPluginInstanceOwner.h @@ -197,16 +197,17 @@ public: // FixUpPluginWindow() (i.e. we need to know when FixUpPluginWindow() has // been called from nsObjectFrame::PaintPlugin() when we're using the // CoreGraphics drawing model). void BeginCGPaint(); void EndCGPaint(); #else // XP_MACOSX void UpdateWindowPositionAndClipRect(PRBool aSetWindow); void UpdateWindowVisibility(PRBool aVisible); + void UpdateDocumentActiveState(PRBool aIsActive); #endif // XP_MACOSX void CallSetWindow(); void SetOwner(nsObjectFrame *aOwner) { mObjectFrame = aOwner; } nsObjectFrame* GetOwner() { @@ -338,16 +339,17 @@ private: #ifdef XP_MACOSX PRPackedBool mPluginPortChanged; #endif #ifdef MOZ_X11 // Used with windowless plugins only, initialized in CreateWidget(). PRPackedBool mFlash10Quirks; #endif PRPackedBool mPluginWindowVisible; + PRPackedBool mPluginDocumentActiveState; // If true, destroy the widget on destruction. Used when plugin stop // is being delayed to a safer point in time. PRPackedBool mDestroyWidget; PRUint16 mNumCachedAttrs; PRUint16 mNumCachedParams; char **mCachedAttrParamNames; char **mCachedAttrParamValues;
--- a/dom/src/geolocation/Makefile.in +++ b/dom/src/geolocation/Makefile.in @@ -63,16 +63,21 @@ LOCAL_INCLUDES = \ EXPORTS = nsGeoPosition.h ifdef MOZ_MAEMO_LIBLOCATION LOCAL_INCLUDES += $(MOZ_PLATFORM_MAEMO_CFLAGS) \ -I$(topsrcdir)/dom/system/unix \ $(NULL) endif +ifdef MOZ_ENABLE_QTMOBILITY +LOCAL_INCLUDES += $(MOZ_QT_CFLAGS) \ + -I$(topsrcdir)/dom/system/unix \ + $(NULL) +endif ifeq ($(MOZ_WIDGET_TOOLKIT),android) LOCAL_INCLUDES += -I$(topsrcdir)/dom/system/android \ $(NULL) endif EXPORTS += nsGeoPositionIPCSerialiser.h
--- a/dom/src/geolocation/nsGeolocation.cpp +++ b/dom/src/geolocation/nsGeolocation.cpp @@ -75,16 +75,20 @@ #include "mozilla/Preferences.h" #include <math.h> #ifdef MOZ_MAEMO_LIBLOCATION #include "MaemoLocationProvider.h" #endif +#ifdef MOZ_ENABLE_QTMOBILITY +#include "QTMLocationProvider.h" +#endif + #ifdef ANDROID #include "AndroidLocationProvider.h" #endif #include "nsIDOMDocument.h" #include "nsIDocument.h" // Some limit to the number of get or watch geolocation requests @@ -573,16 +577,22 @@ nsresult nsGeolocationService::Init() // we should move these providers outside of this file! dft #ifdef MOZ_MAEMO_LIBLOCATION provider = new MaemoLocationProvider(); if (provider) mProviders.AppendObject(provider); #endif +#ifdef MOZ_ENABLE_QTMOBILITY + provider = new QTMLocationProvider(); + if (provider) + mProviders.AppendObject(provider); +#endif + #ifdef ANDROID provider = new AndroidLocationProvider(); if (provider) mProviders.AppendObject(provider); #endif return NS_OK; }
--- a/dom/system/NetworkGeolocationProvider.js +++ b/dom/system/NetworkGeolocationProvider.js @@ -1,427 +1,311 @@ +/* ***** 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 Network Location Provider for GLS. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Doug Turner <dougt@dougt.org> + * + * 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 ***** */ + + +// Do not use this API without permission from Google. +// See http://www.google.com/support/enterprise/bin/request.py?contact_type=gme&utm_campaign=en-us-ptr-mz +// for more information. + Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); +Components.utils.import("resource://gre/modules/Services.jsm"); const Ci = Components.interfaces; const Cc = Components.classes; -var gLoggingEnabled = false; -var gTestingEnabled = false; - -function nowInSeconds() -{ - return Date.now() / 1000; -} +let gLoggingEnabled = false; +let gTestingEnabled = false; function LOG(aMsg) { if (gLoggingEnabled) { aMsg = "*** WIFI GEO: " + aMsg + "\n"; Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(aMsg); dump(aMsg); } } -function WifiGeoAddressObject(streetNumber, street, premises, city, county, region, country, countryCode, postalCode) { - - this.streetNumber = streetNumber; - this.street = street; - this.premises = premises; - this.city = city; - this.county = county; - this.region = region; - this.country = country; - this.countryCode = countryCode; - this.postalCode = postalCode; +function WifiGeoCoordsObject(lat, lon, acc, alt, altacc) { + this.latitude = lat; + this.longitude = lon; + this.accuracy = acc; + this.altitude = alt; + this.altitudeAccuracy = altacc; } -WifiGeoAddressObject.prototype = { - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGeoPositionAddress]), - - classInfo: XPCOMUtils.generateCI({interfaces: [Ci.nsIDOMGeoPositionAddress], - flags: Ci.nsIClassInfo.DOM_OBJECT}) -}; - -function WifiGeoCoordsObject(lat, lon, acc, alt, altacc) { - this.latitude = lat; - this.longitude = lon; - this.accuracy = acc; - this.altitude = alt; - this.altitudeAccuracy = altacc; -}; - WifiGeoCoordsObject.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGeoPositionCoords]), - - classInfo: XPCOMUtils.generateCI({interfaces: [Ci.nsIDOMGeoPositionCoords], - flags: Ci.nsIClassInfo.DOM_OBJECT, - classDescription: "wifi geo position coords object"}), + QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGeoPositionCoords]), - latitude: 0, - longitude: 0, - accuracy: 0, - altitude: 0, - altitudeAccuracy: 0, - + classInfo: XPCOMUtils.generateCI({interfaces: [Ci.nsIDOMGeoPositionCoords], + flags: Ci.nsIClassInfo.DOM_OBJECT, + classDescription: "wifi geo position coords object"}), }; -function WifiGeoPositionObject(location) { - - this.coords = new WifiGeoCoordsObject(location.latitude, - location.longitude, - location.accuracy || 12450, // .5 * circumference of earth. - location.altitude || 0, - location.altitude_accuracy || 0); - - if (location.address) { - let address = location.address; - this.address = new WifiGeoAddressObject(address.street_number || null, - address.street || null, - address.premises || null, - address.city || null, - address.county || null, - address.region || null, - address.country || null, - address.country_code || null, - address.postal_code || null); - } - else - this.address = null; - - this.timestamp = Date.now(); -}; +function WifiGeoPositionObject(lat, lng, acc) { + this.coords = new WifiGeoCoordsObject(lat, lng, acc, 0, 0); + this.address = null; + this.timestamp = Date.now(); +} WifiGeoPositionObject.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGeoPosition]), + QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGeoPosition]), - // Class Info is required to be able to pass objects back into the DOM. - classInfo: XPCOMUtils.generateCI({interfaces: [Ci.nsIDOMGeoPosition], - flags: Ci.nsIClassInfo.DOM_OBJECT, - classDescription: "wifi geo location position object"}), - - coords: null, - timestamp: 0, + // Class Info is required to be able to pass objects back into the DOM. + classInfo: XPCOMUtils.generateCI({interfaces: [Ci.nsIDOMGeoPosition], + flags: Ci.nsIClassInfo.DOM_OBJECT, + classDescription: "wifi geo location position object"}), }; -function HELD() {}; - // For information about the HELD format, see: - // http://tools.ietf.org/html/draft-thomson-geopriv-held-measurements-05 -HELD.encode = function(requestObject) { - // XML Header - var requestString = "<locationRequest xmlns=\"urn:ietf:params:xml:ns:geopriv:held\">"; - // Measurements - if (requestObject.wifi_towers && requestObject.wifi_towers.length > 0) { - requestString += "<measurements xmlns=\"urn:ietf:params:xml:ns:geopriv:lm\">"; - requestString += "<wifi xmlns=\"urn:ietf:params:xml:ns:geopriv:lm:wifi\">"; - for (var i=0; i < requestObject.wifi_towers.length; ++i) { - requestString += "<neighbourWap>"; - requestString += "<bssid>" + requestObject.wifi_towers[i].mac_address + "</bssid>"; - requestString += "<ssid>" + requestObject.wifi_towers[i].ssid + "</ssid>"; - requestString += "<rssi>" + requestObject.wifi_towers[i].signal_strength + "</rssi>"; - requestString += "</neighbourWap>"; - } - // XML Footer - requestString += "</wifi></measurements>"; +function WifiGeoPositionProvider() { + try { + gLoggingEnabled = Services.prefs.getBoolPref("geo.wifi.logging.enabled"); + } catch (e) {} + + try { + gTestingEnabled = Services.prefs.getBoolPref("geo.wifi.testing"); + } catch (e) {} + + wifiService = null; + timer = null; + hasSeenWiFi = false; + started = false; +} + +WifiGeoPositionProvider.prototype = { + classID: Components.ID("{77DA64D3-7458-4920-9491-86CC9914F904}"), + QueryInterface: XPCOMUtils.generateQI([Ci.nsIGeolocationProvider, + Ci.nsIWifiListener, + Ci.nsITimerCallback]), + startup: function() { + if (this.started) + return; + this.started = true; + this.hasSeenWiFi = false; + + LOG("startup called. testing mode is" + gTestingEnabled); + + // if we don't see anything in 5 seconds, kick of one IP geo lookup. + // if we are testing, just hammer this callback so that we are more or less + // always sending data. It doesn't matter if we have an access point or not. + this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + if (!gTestingEnabled) + this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT); + else + this.timer.initWithCallback(this, 200, this.timer.TYPE_REPEATING_SLACK); + }, + + watch: function(c) { + LOG("watch called"); + if (!this.wifiService) { + this.wifiService = Cc["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor); + this.wifiService.startWatching(this); } - requestString += "</locationRequest>"; - return requestString; -}; + }, -// Decode a HELD response into a Gears-style object -HELD.decode = function(responseXML) { - // Find a Circle object in PIDF-LO and decode - function nsResolver(prefix) { - var ns = { - 'held': 'urn:ietf:params:xml:ns:geopriv:held', - 'pres': 'urn:ietf:params:xml:ns:pidf', - 'gp': 'urn:ietf:params:xml:ns:pidf:geopriv10', - 'gml': 'http://www.opengis.net/gml', - 'gs': 'http://www.opengis.net/pidflo/1.0', - }; - return ns[prefix] || null; + shutdown: function() { + LOG("shutdown called"); + if(this.wifiService) { + this.wifiService.stopWatching(this); + this.wifiService = null; + } + if (this.timer != null) { + this.timer.cancel(); + this.timer = null; } - var xpathEval = Components.classes["@mozilla.org/dom/xpath-evaluator;1"].createInstance(Ci.nsIDOMXPathEvaluator); + // Although we aren't using cookies, we should err on the side of not + // saving any access tokens if the user asked us not to save cookies or + // has changed the lifetimePolicy. The access token in these cases is + // used and valid for the life of this object (eg. between startup and + // shutdown). + if (Services.prefs.getIntPref("network.cookie.lifetimePolicy") != 0) + Services.prefs.deleteBranch("geo.wifi.access_token."); + this.started = false; + }, - // Grab values out of XML via XPath - var pos = xpathEval.evaluate( - '/held:locationResponse/pres:presence/pres:tuple/pres:status/gp:geopriv/gp:location-info/gs:Circle/gml:pos', - responseXML, - nsResolver, - Ci.nsIDOMXPathResult.STRING_TYPE, - null); + getAccessTokenForURL: function(url) + { + // check to see if we have an access token: + let accessToken = ""; + try { + let accessTokenPrefName = "geo.wifi.access_token." + url; + accessToken = Services.prefs.getCharPref(accessTokenPrefName); + + // check to see if it has expired + let accessTokenDate = Services.prefs.getIntPref(accessTokenPrefName + ".time"); + + let accessTokenInterval = 1209600; // seconds in 2 weeks + try { + accessTokenInterval = Services.prefs.getIntPref("geo.wifi.access_token.recycle_interval"); + } catch (e) {} + + if ((Date.now() / 1000) - accessTokenDate > accessTokenInterval) + accessToken = ""; + } + catch (e) { + accessToken = ""; + } + return accessToken; + }, - var rad = xpathEval.evaluate( - '/held:locationResponse/pres:presence/pres:tuple/pres:status/gp:geopriv/gp:location-info/gs:Circle/gs:radius', - responseXML, - nsResolver, - Ci.nsIDOMXPathResult.NUMBER_TYPE, - null ); + onChange: function(accessPoints) { + LOG("onChange called"); + this.hasSeenWiFi = true; + + let providerUrlBase = Services.prefs.getCharPref("geo.wifi.uri"); + let providerUrl; + + let query = providerUrlBase.indexOf("?"); + if (query == -1) + providerUrl = providerUrlBase + "?" + else + providerUrl = providerUrlBase + "&"; + providerUrl = providerUrl + "browser=firefox&sensor=true"; + + + let accessToken = this.getAccessTokenForURL(providerUrlBase); + if (accessToken !== "") + providerUrl = providerUrl + "&access_token="+access_token; - var uom = xpathEval.evaluate( - '/held:locationResponse/pres:presence/pres:tuple/pres:status/gp:geopriv/gp:location-info/gs:Circle/gs:radius/@uom', - responseXML, - nsResolver, - Ci.nsIDOMXPathResult.STRING_TYPE, - null); + function sort(a, b) { + return b.signal - a.signal; + }; + + function encode(ap) { + // make sure that the ssid doesn't contain any | chars. + ap.ssid = ap.ssid.replace("|", "\\|"); + // gls service parses the | as fields + return "&wifi=mac:"+ap.mac+"|ssid:"+ap.ssid+"|ss:"+ap.signal; + }; - // Bail if we don't have a valid result (all values && uom==meters) - if ((pos.stringValue == null) || - (rad.numberValue == null) || - (uom.stringValue == null) || - (uom.stringValue != "urn:ogc:def:uom:EPSG::9001")) { - return null; + if (accessPoints) { + accessPoints.sort(sort).map(encode).join(""); + // max length is 2k. make sure we are under that + let x = providerUrl.length - 2000; + if (x >= 0) { + // we need to trim + let doomed = providerUrl.lastIndexOf("&", 2000); + LOG("Doomed:"+doomed); + providerUrl = providerUrl.substring(0, doomed); + } } - // Split the pos value into lat/long - var coords = pos.stringValue.split(/[ \t\n]+/); - - // Fill out the object to return: - var obj = { - location: { - latitude: parseFloat(coords[0]), - longitude: parseFloat(coords[1]), - accuracy: rad.numberValue - } - }; - return obj; -} + providerUrl = encodeURI(providerUrl); + LOG("************************************* Sending request:\n" + providerUrl + "\n"); -function WifiGeoPositionProvider() { - this.prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch).QueryInterface(Ci.nsIPrefService); - try { - gLoggingEnabled = this.prefService.getBoolPref("geo.wifi.logging.enabled"); - } catch (e) {} - - try { - gTestingEnabled = this.prefService.getBoolPref("geo.wifi.testing"); - } catch (e) {} - -}; - -WifiGeoPositionProvider.prototype = { - classID: Components.ID("{77DA64D3-7458-4920-9491-86CC9914F904}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIGeolocationProvider, - Ci.nsIWifiListener, - Ci.nsITimerCallback]), + // send our request to a wifi geolocation network provider: + let xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"] + .createInstance(Ci.nsIXMLHttpRequest); - prefService: null, - wifi_service: null, - timer: null, - hasSeenWiFi: false, - started: false, - - startup: function() { - if (this.started == true) - return; - - this.started = true; + // This is a background load + xhr.mozBackgroundRequest = true; + xhr.open("GET", providerUrl, false); + xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS; + xhr.onerror = function(req) { + LOG("onerror: " + req); + }; + xhr.onload = function (req) { + LOG("service returned: " + req.target.responseText); + response = JSON.parse(req.target.responseText); + /* + { + "status": "OK", + "accuracy": 150.0, + "location": { + "lat": -33.85702, + "lng": 151.21494 + }, + "access_token": "quijibo" + } + */ - LOG("startup called. testing mode is" + gTestingEnabled); - // if we don't see anything in 5 seconds, kick of one IP geo lookup. - // if we are testing, just hammer this callback so that we are more or less - // always sending data. It doesn't matter if we have an access point or not. - this.hasSeenWiFi = false; - this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - if (gTestingEnabled == false) - this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT); - else - this.timer.initWithCallback(this, 200, this.timer.TYPE_REPEATING_SLACK); - }, + if (response.status != "OK") + return; - watch: function(c) { - LOG("watch called"); - if (!this.wifi_service) { - this.wifi_service = Cc["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor); - this.wifi_service.startWatching(this); - } - }, + if (response.location) { + let newLocation = new WifiGeoPositionObject(response.location.lat, + response.location.lng, + response.accuracy); - shutdown: function() { - LOG("shutdown called"); - if(this.wifi_service) - this.wifi_service.stopWatching(this); - this.wifi_service = null; - - if (this.timer != null) { - this.timer.cancel(); - this.timer = null; + let update = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate); + update.update(newLocation); } - // Although we aren't using cookies, we should err on the side of not - // saving any access tokens if the user asked us not to save cookies or - // has changed the lifetimePolicy. The access token in these cases is - // used and valid for the life of this object (eg. between startup and - // shutdown).e - let prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); - if (prefBranch.getIntPref("network.cookie.lifetimePolicy") != 0) - prefBranch.deleteBranch("geo.wifi.access_token."); - - this.started = false; - }, - - getAccessTokenForURL: function(url) - { - // check to see if we have an access token: - var accessToken = ""; - - try { - var accessTokenPrefName = "geo.wifi.access_token." + url; - accessToken = this.prefService.getCharPref(accessTokenPrefName); - - // check to see if it has expired - var accessTokenDate = this.prefService.getIntPref(accessTokenPrefName + ".time"); - - var accessTokenInterval = 1209600; /* seconds in 2 weeks */ - try { - accessTokenInterval = this.prefService.getIntPref("geo.wifi.access_token.recycle_interval"); - } catch (e) {} - - if (nowInSeconds() - accessTokenDate > accessTokenInterval) - accessToken = ""; - } - catch (e) { - accessToken = ""; - } - return accessToken; - }, - - onChange: function(accessPoints) { - - LOG("onChange called"); - this.hasSeenWiFi = true; - - // send our request to a wifi geolocation network provider: - var xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"] - .createInstance(Ci.nsIXMLHttpRequest); - - // This is a background load - xhr.mozBackgroundRequest = true; - - var provider_url = this.prefService.getCharPref("geo.wifi.uri"); - var provider_protocol = 0; - try { - provider_protocol = this.prefService.getIntPref("geo.wifi.protocol"); - } catch (e) {} - - LOG("provider url = " + provider_url); - - xhr.open("POST", provider_url, false); - - // set something so that we can strip cookies - xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS; - - xhr.onerror = function(req) { - LOG("onerror: " + req); - }; - - xhr.onload = function (req) { - - LOG("xhr onload..."); + // Check to see if we have a new access token + let newAccessToken = response.access_token; + if (newAccessToken !== undefined) + { + let accessToken = ""; + let accessTokenPrefName = "geo.wifi.access_token." + providerUrlBase; + try { accessToken = Services.prefs.getCharPref(accessTokenPrefName); } catch (e) {} - try { - // if we get a bad response, we will throw and never report a location - var response; - switch (provider_protocol) { - case 1: - LOG("service returned: " + req.target.responseXML); - response = HELD.decode(req.target.responseXML); - break; - case 0: - default: - LOG("service returned: " + req.target.responseText); - response = JSON.parse(req.target.responseText); - } - } catch (e) { - LOG("Parse failed"); - return; - } - - // response looks something like: - // {"location":{"latitude":51.5090332,"longitude":-0.1212726,"accuracy":150.0},"access_token":"2:jVhRZJ-j6PiRchH_:RGMrR0W1BiwdZs12"} - - // Check to see if we have a new access token - var newAccessToken = response.access_token; - if (newAccessToken != undefined) - { - var prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); - var accessToken = ""; - var accessTokenPrefName = "geo.wifi.access_token." + req.target.channel.URI.spec; - try { accessToken = prefService.getCharPref(accessTokenPrefName); } catch (e) {} - - if (accessToken != newAccessToken) { - // no match, lets cache - LOG("New Access Token: " + newAccessToken + "\n" + accessTokenPrefName); - - try { - prefService.setIntPref(accessTokenPrefName + ".time", nowInSeconds()); - prefService.setCharPref(accessTokenPrefName, newAccessToken); - } catch (x) { - // XXX temporary hack for bug 575346 to allow geolocation to function - } - } - } - - if (response.location) { - var newLocation = new WifiGeoPositionObject(response.location); - - var update = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate); - update.update(newLocation); - } - }; + if (accessToken != newAccessToken) { + // no match, lets cache + LOG("New Access Token: " + newAccessToken + "\n" + accessTokenPrefName); + try { + Services.prefs.setIntPref(accessTokenPrefName + ".time", nowInSeconds()); + Services.prefs.setCharPref(accessTokenPrefName, newAccessToken); + } catch (x) { + // XXX temporary hack for bug 575346 to allow geolocation to function + } + } + } + }; - var accessToken = this.getAccessTokenForURL(provider_url); - - var request = { - version: "1.1.0", - request_address: true, - }; - - if (accessToken != "") - request.access_token = accessToken; + LOG("************************************* ------>>>> sending."); + xhr.send(null); + }, - if (accessPoints != null) { - function filterBlankSSIDs(ap) ap.ssid != "" - function deconstruct(ap) ({ - mac_address: ap.mac, - ssid: ap.ssid, - signal_strength: ap.signal - }) - request.wifi_towers = accessPoints.filter(filterBlankSSIDs).map(deconstruct); - } + onError: function (code) { + LOG("wifi error: " + code); + }, - var requestString; - switch (provider_protocol) { - case 1: - requestString = HELD.encode(request); - break; - case 0: - default: - requestString = JSON.stringify(request); - } - LOG("client sending: " + requestString); - - try { - xhr.send(requestString); - } catch (e) {} - }, - - onError: function (code) { - LOG("wifi error: " + code); - }, - - notify: function (timer) { - if (!gTestingEnabled) { - if (this.hasSeenWiFi == false) - this.onChange(null); - this.timer = null; - return; - } - // if we are testing, we need to hammer this. + notify: function (timer) { + if (gTestingEnabled) { + // if we are testing, timer is repeating + this.onChange(null); + } + else { + if (!this.hasSeenWiFi) this.onChange(null); - }, - + this.timer = null; + } + }, }; -var NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiGeoPositionProvider]); +let NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiGeoPositionProvider]);
--- a/dom/system/unix/Makefile.in +++ b/dom/system/unix/Makefile.in @@ -45,16 +45,18 @@ MODULE = dom LIBRARY_NAME = domsystemunix_s # we don't want the shared lib, but we want to force the creation of a static lib. LIBXUL_LIBRARY = 1 FORCE_STATIC_LIB = 1 EXPORT_LIBRARY = 1 include $(topsrcdir)/config/config.mk +include $(topsrcdir)/ipc/chromium/chromium-config.mk + CPPSRCS = \ nsDeviceMotionSystem.cpp \ $(NULL) ifdef MOZ_MAEMO_LIBLOCATION CPPSRCS += MaemoLocationProvider.cpp LOCAL_INCLUDES += $(MOZ_PLATFORM_MAEMO_CFLAGS) \ @@ -62,14 +64,19 @@ ifdef MOZ_MAEMO_LIBLOCATION $(NULL) endif ifdef MOZ_PLATFORM_MAEMO CPPSRCS += nsHapticFeedback.cpp LOCAL_INCLUDES += $(MOZ_DBUS_CFLAGS) \ $(NULL) ifdef MOZ_ENABLE_QTMOBILITY +MOCSRCS += moc_QTMLocationProvider.cpp +CPPSRCS += $(MOCSRCS) \ + QTMLocationProvider.cpp \ + $(NULL) LOCAL_INCLUDES += $(MOZ_QT_CFLAGS) \ + -I$(topsrcdir)/dom/src/geolocation \ $(NULL) endif endif include $(topsrcdir)/config/rules.mk
new file mode 100644 --- /dev/null +++ b/dom/system/unix/QTMLocationProvider.cpp @@ -0,0 +1,118 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * ***** 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 Qt code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Oleg Romashin <romaxa@gmail.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 "QTMLocationProvider.h" +#include "nsGeoPosition.h" +#include <QFeedbackEffect> +using namespace QtMobility; + +using namespace mozilla; + +NS_IMPL_ISUPPORTS1(QTMLocationProvider, nsIGeolocationProvider) + +QTMLocationProvider::QTMLocationProvider() +{ + mLocation = QGeoPositionInfoSource::createDefaultSource(this); + if (mLocation) + connect(mLocation, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo))); +} + +QTMLocationProvider::~QTMLocationProvider() +{ + delete mLocation; +} + +void +QTMLocationProvider::positionUpdated(const QGeoPositionInfo &geoPosition) +{ + if (!geoPosition.isValid()) { + NS_WARNING("Invalida geoposition received"); + return; + } + + QGeoCoordinate coord = geoPosition.coordinate(); + double latitude = coord.latitude(); + double longitude = coord.longitude(); + double altitude = coord.altitude(); + double accuracy = geoPosition.attribute(QGeoPositionInfo::HorizontalAccuracy); + double altitudeAccuracy = geoPosition.attribute(QGeoPositionInfo::VerticalAccuracy); + double heading = geoPosition.attribute(QGeoPositionInfo::Direction); + + bool providesSpeed = geoPosition.hasAttribute(QGeoPositionInfo::GroundSpeed); + double speed = geoPosition.attribute(QGeoPositionInfo::GroundSpeed); + + nsRefPtr<nsGeoPosition> p = + new nsGeoPosition(latitude, longitude, + altitude, accuracy, + altitudeAccuracy, heading, + speed, geoPosition.timestamp().toTime_t()); + if (mCallback) { + mCallback->Update(p); + } +} + +NS_IMETHODIMP +QTMLocationProvider::Startup() +{ + if (!mLocation) + return NS_ERROR_NOT_IMPLEMENTED; + + mLocation->startUpdates(); + + return NS_OK; +} + +NS_IMETHODIMP +QTMLocationProvider::Watch(nsIGeolocationUpdate* aCallback) +{ + mCallback = aCallback; + + return NS_OK; +} + +NS_IMETHODIMP +QTMLocationProvider::Shutdown() +{ + if (!mLocation) + return NS_ERROR_NOT_IMPLEMENTED; + + mLocation->stopUpdates(); + mCallback = nsnull; + + return NS_OK; +} +
new file mode 100644 --- /dev/null +++ b/dom/system/unix/QTMLocationProvider.h @@ -0,0 +1,69 @@ +/* ***** 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 Qt code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Oleg Romashin <romaxa@gmail.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 ***** */ + +#ifndef QTMLocationProvider_h +#define QTMLocationProvider_h + +#include <QGeoPositionInfoSource> +#include "nsGeolocation.h" +#include "nsIGeolocationProvider.h" +#include "nsCOMPtr.h" + +using namespace QtMobility; + +class QTMLocationProvider : public QObject, + public nsIGeolocationProvider +{ + Q_OBJECT + +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIGEOLOCATIONPROVIDER + + QTMLocationProvider(); + +public Q_SLOTS: + // QGeoPositionInfoSource + void positionUpdated(const QGeoPositionInfo&); + +private: + ~QTMLocationProvider(); + + QtMobility::QGeoPositionInfoSource* mLocation; + nsCOMPtr<nsIGeolocationUpdate> mCallback; +}; + +#endif /* QTMLocationProvider_h */
--- a/dom/tests/mochitest/geolocation/geolocation_common.js +++ b/dom/tests/mochitest/geolocation/geolocation_common.js @@ -72,20 +72,20 @@ function check_geolocation(location) { // eventually, coords may be optional (eg, when civic addresses are supported) ok("coords" in location, "Check to see if this location has a coords"); var coords = location.coords; ok("latitude" in coords, "Check to see if there is a latitude"); ok("longitude" in coords, "Check to see if there is a longitude"); - ok("altitude" in coords, "Check to see if there is a altitude"); ok("accuracy" in coords, "Check to see if there is a accuracy"); - ok("altitudeAccuracy" in coords, "Check to see if there is a alt accuracy"); - + + // optional ok("altitude" in coords, "Check to see if there is a altitude"); + // optional ok("altitudeAccuracy" in coords, "Check to see if there is a alt accuracy"); // optional ok("heading" in coords, "Check to see if there is a heading"); // optional ok("speed" in coords, "Check to see if there is a speed"); ok (location.coords.latitude == 37.41857, "lat matches known value"); ok (location.coords.longitude == -122.08769, "lon matches known value"); - ok(location.coords.altitude == 42, "alt matches known value"); - ok(location.coords.altitudeAccuracy == 42, "alt acc matches known value"); + // optional ok(location.coords.altitude == 42, "alt matches known value"); + // optional ok(location.coords.altitudeAccuracy == 42, "alt acc matches known value"); }
--- a/dom/tests/mochitest/geolocation/network_geolocation.sjs +++ b/dom/tests/mochitest/geolocation/network_geolocation.sjs @@ -14,45 +14,26 @@ function parseQueryString(str) params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]); } return params; } function getPosition(action) { - // this isn't the w3c data structure, it is the network location provider structure. - - var address = { - street_number: "street_number", - street: "street", - premises: "premises", - city: "city", - county: "county", - region: "region", - country: "country", - country_code: "country_code", - postal_code: "postal_code", - }; - - - var coords = { - latitude: 37.41857, - longitude: -122.08769, - - altitude: 42, + var response = { + status: "OK", + location: { + lat: 37.41857, + lng: -122.08769, + }, accuracy: (action == "worse-accuracy") ? 100 : 42, - altitude_accuracy: 42, }; - var geoposition = { - location: coords, - }; - - return JSON.stringify(geoposition); + return JSON.stringify(response); } function handleRequest(request, response) { var params = parseQueryString(request.queryString); if (params.action == "stop-responding") { return;
--- a/editor/composer/src/nsComposerCommands.cpp +++ b/editor/composer/src/nsComposerCommands.cpp @@ -426,17 +426,18 @@ NS_IMETHODIMP nsRemoveListCommand::IsCommandEnabled(const char * aCommandName, nsISupports *refCon, PRBool *outCmdEnabled) { nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon); if (editor) { PRBool isEditable = PR_FALSE; - NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable)); + nsresult rv = editor->GetIsSelectionEditable(&isEditable); + NS_ENSURE_SUCCESS(rv, rv); if (isEditable) { // It is enabled if we are in any list type PRBool bMixed; PRUnichar *tagStr; nsresult rv = GetListState(editor, &bMixed, &tagStr); NS_ENSURE_SUCCESS(rv, rv); @@ -538,17 +539,18 @@ nsOutdentCommand::IsCommandEnabled(const nsISupports *refCon, PRBool *outCmdEnabled) { nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon); nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(refCon); if (editor && htmlEditor) { PRBool canIndent, isEditable = PR_FALSE; - NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable)); + nsresult rv = editor->GetIsSelectionEditable(&isEditable); + NS_ENSURE_SUCCESS(rv, rv); if (isEditable) return htmlEditor->GetIndentState(&canIndent, outCmdEnabled); } *outCmdEnabled = PR_FALSE; return NS_OK; } @@ -1046,17 +1048,18 @@ nsAbsolutePositioningCommand::IsCommandE nsISupports *aCommandRefCon, PRBool *outCmdEnabled) { nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon); nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(aCommandRefCon); if (htmlEditor) { PRBool isEditable = PR_FALSE; - NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable)); + nsresult rv = editor->GetIsSelectionEditable(&isEditable); + NS_ENSURE_SUCCESS(rv, rv); if (isEditable) return htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled); } *outCmdEnabled = PR_FALSE; return NS_OK; }
--- a/editor/libeditor/base/nsEditorCommands.cpp +++ b/editor/libeditor/base/nsEditorCommands.cpp @@ -66,17 +66,18 @@ nsUndoCommand::IsCommandEnabled(const ch nsISupports *aCommandRefCon, PRBool *outCmdEnabled) { NS_ENSURE_ARG_POINTER(outCmdEnabled); nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon); if (editor) { PRBool isEnabled, isEditable = PR_FALSE; - NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable)); + nsresult rv = editor->GetIsSelectionEditable(&isEditable); + NS_ENSURE_SUCCESS(rv, rv); if (isEditable) return editor->CanUndo(&isEnabled, outCmdEnabled); } *outCmdEnabled = PR_FALSE; return NS_OK; } @@ -114,17 +115,18 @@ nsRedoCommand::IsCommandEnabled(const ch nsISupports *aCommandRefCon, PRBool *outCmdEnabled) { NS_ENSURE_ARG_POINTER(outCmdEnabled); nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon); if (editor) { PRBool isEnabled, isEditable = PR_FALSE; - NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable)); + nsresult rv = editor->GetIsSelectionEditable(&isEditable); + NS_ENSURE_SUCCESS(rv, rv); if (isEditable) return editor->CanRedo(&isEnabled, outCmdEnabled); } *outCmdEnabled = PR_FALSE; return NS_OK; } @@ -210,17 +212,18 @@ nsCutCommand::IsCommandEnabled(const cha nsISupports *aCommandRefCon, PRBool *outCmdEnabled) { NS_ENSURE_ARG_POINTER(outCmdEnabled); nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon); if (editor) { PRBool isEditable = PR_FALSE; - NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable)); + nsresult rv = editor->GetIsSelectionEditable(&isEditable); + NS_ENSURE_SUCCESS(rv, rv); if (isEditable) return editor->CanCut(outCmdEnabled); } *outCmdEnabled = PR_FALSE; return NS_OK; } @@ -314,17 +317,18 @@ nsCopyCommand::IsCommandEnabled(const ch nsISupports *aCommandRefCon, PRBool *outCmdEnabled) { NS_ENSURE_ARG_POINTER(outCmdEnabled); nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon); if (editor) { PRBool isEditable = PR_FALSE; - NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable)); + nsresult rv = editor->GetIsSelectionEditable(&isEditable); + NS_ENSURE_SUCCESS(rv, rv); if (isEditable) return editor->CanCopy(outCmdEnabled); } *outCmdEnabled = PR_FALSE; return NS_OK; } @@ -417,17 +421,18 @@ nsPasteCommand::IsCommandEnabled(const c nsISupports *aCommandRefCon, PRBool *outCmdEnabled) { NS_ENSURE_ARG_POINTER(outCmdEnabled); nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon); if (editor) { PRBool isEditable = PR_FALSE; - NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable)); + nsresult rv = editor->GetIsSelectionEditable(&isEditable); + NS_ENSURE_SUCCESS(rv, rv); if (isEditable) return editor->CanPaste(nsIClipboard::kGlobalClipboard, outCmdEnabled); } *outCmdEnabled = PR_FALSE; return NS_OK; } @@ -464,17 +469,18 @@ nsPasteTransferableCommand::IsCommandEna nsISupports *aCommandRefCon, PRBool *outCmdEnabled) { NS_ENSURE_ARG_POINTER(outCmdEnabled); nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon); if (editor) { PRBool isEditable = PR_FALSE; - NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable)); + nsresult rv = editor->GetIsSelectionEditable(&isEditable); + NS_ENSURE_SUCCESS(rv, rv); if (isEditable) return editor->CanPasteTransferable(nsnull, outCmdEnabled); } *outCmdEnabled = PR_FALSE; return NS_OK; } @@ -575,17 +581,18 @@ nsDeleteCommand::IsCommandEnabled(const NS_ENSURE_ARG_POINTER(outCmdEnabled); nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon); *outCmdEnabled = PR_FALSE; // we can delete when we can cut NS_ENSURE_TRUE(editor, NS_OK); PRBool isEditable = PR_FALSE; - NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable)); + nsresult rv = editor->GetIsSelectionEditable(&isEditable); + NS_ENSURE_SUCCESS(rv, rv); if (!isEditable) return NS_OK; else if (!nsCRT::strcmp(aCommandName,"cmd_delete")) return editor->CanCut(outCmdEnabled); else if (!nsCRT::strcmp(aCommandName,"cmd_deleteCharBackward")) *outCmdEnabled = PR_TRUE; else if (!nsCRT::strcmp(aCommandName,"cmd_deleteCharForward"))
--- a/editor/libeditor/base/nsEditorEventListener.cpp +++ b/editor/libeditor/base/nsEditorEventListener.cpp @@ -121,88 +121,72 @@ nsEditorEventListener::Connect(nsEditor* nsresult nsEditorEventListener::InstallToEditor() { NS_PRECONDITION(mEditor, "The caller must set mEditor"); nsCOMPtr<nsIDOMEventTarget> piTarget = mEditor->GetDOMEventTarget(); NS_ENSURE_TRUE(piTarget, NS_ERROR_FAILURE); - nsresult rv; - // register the event listeners with the listener manager nsEventListenerManager* elmP = piTarget->GetListenerManager(PR_TRUE); NS_ENSURE_STATE(elmP); - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("keypress"), - NS_EVENT_FLAG_BUBBLE | - NS_PRIV_EVENT_UNTRUSTED_PERMITTED | - NS_EVENT_FLAG_SYSTEM_EVENT); - NS_ENSURE_SUCCESS(rv, rv); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("keypress"), + NS_EVENT_FLAG_BUBBLE | + NS_PRIV_EVENT_UNTRUSTED_PERMITTED | + NS_EVENT_FLAG_SYSTEM_EVENT); // See bug 455215, we cannot use the standard dragstart event yet - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("draggesture"), - NS_EVENT_FLAG_BUBBLE | - NS_EVENT_FLAG_SYSTEM_EVENT); - NS_ENSURE_SUCCESS(rv, rv); - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("dragenter"), - NS_EVENT_FLAG_BUBBLE | - NS_EVENT_FLAG_SYSTEM_EVENT); - NS_ENSURE_SUCCESS(rv, rv); - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("dragover"), - NS_EVENT_FLAG_BUBBLE | - NS_EVENT_FLAG_SYSTEM_EVENT); - NS_ENSURE_SUCCESS(rv, rv); - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("dragexit"), - NS_EVENT_FLAG_BUBBLE | - NS_EVENT_FLAG_SYSTEM_EVENT); - NS_ENSURE_SUCCESS(rv, rv); - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("drop"), - NS_EVENT_FLAG_BUBBLE | - NS_EVENT_FLAG_SYSTEM_EVENT); - NS_ENSURE_SUCCESS(rv, rv); - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("mousedown"), - NS_EVENT_FLAG_CAPTURE); - NS_ENSURE_SUCCESS(rv, rv); - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("mouseup"), - NS_EVENT_FLAG_CAPTURE); - NS_ENSURE_SUCCESS(rv, rv); - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("click"), - NS_EVENT_FLAG_CAPTURE); - NS_ENSURE_SUCCESS(rv, rv); - // Focus event doesn't bubble so adding the listener to capturing phase. - // Make sure this works after bug 235441 gets fixed. - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("blur"), - NS_EVENT_FLAG_CAPTURE); - NS_ENSURE_SUCCESS(rv, rv); - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("focus"), - NS_EVENT_FLAG_CAPTURE); - NS_ENSURE_SUCCESS(rv, rv); - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("text"), - NS_EVENT_FLAG_BUBBLE); - NS_ENSURE_SUCCESS(rv, rv); - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("compositionstart"), - NS_EVENT_FLAG_BUBBLE); - NS_ENSURE_SUCCESS(rv, rv); - rv = elmP->AddEventListenerByType(this, - NS_LITERAL_STRING("compositionend"), - NS_EVENT_FLAG_BUBBLE); - NS_ENSURE_SUCCESS(rv, rv); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("draggesture"), + NS_EVENT_FLAG_BUBBLE | + NS_EVENT_FLAG_SYSTEM_EVENT); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("dragenter"), + NS_EVENT_FLAG_BUBBLE | + NS_EVENT_FLAG_SYSTEM_EVENT); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("dragover"), + NS_EVENT_FLAG_BUBBLE | + NS_EVENT_FLAG_SYSTEM_EVENT); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("dragexit"), + NS_EVENT_FLAG_BUBBLE | + NS_EVENT_FLAG_SYSTEM_EVENT); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("drop"), + NS_EVENT_FLAG_BUBBLE | + NS_EVENT_FLAG_SYSTEM_EVENT); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("mousedown"), + NS_EVENT_FLAG_CAPTURE); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("mouseup"), + NS_EVENT_FLAG_CAPTURE); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("click"), + NS_EVENT_FLAG_CAPTURE); +// Focus event doesn't bubble so adding the listener to capturing phase. +// Make sure this works after bug 235441 gets fixed. + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("blur"), + NS_EVENT_FLAG_CAPTURE); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("focus"), + NS_EVENT_FLAG_CAPTURE); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("text"), + NS_EVENT_FLAG_BUBBLE); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("compositionstart"), + NS_EVENT_FLAG_BUBBLE); + elmP->AddEventListenerByType(this, + NS_LITERAL_STRING("compositionend"), + NS_EVENT_FLAG_BUBBLE); return NS_OK; } void nsEditorEventListener::Disconnect() { if (!mEditor) {
--- a/embedding/android/GeckoApp.java +++ b/embedding/android/GeckoApp.java @@ -61,16 +61,18 @@ import android.util.*; import android.net.*; import android.database.*; import android.provider.*; import android.telephony.*; abstract public class GeckoApp extends Activity { + private static final String LOG_FILE_NAME = "GeckoApp"; + public static final String ACTION_ALERT_CLICK = "org.mozilla.gecko.ACTION_ALERT_CLICK"; public static final String ACTION_ALERT_CLEAR = "org.mozilla.gecko.ACTION_ALERT_CLEAR"; public static final String ACTION_WEBAPP = "org.mozilla.gecko.WEBAPP"; public static final String ACTION_DEBUG = "org.mozilla.gecko.DEBUG"; public static final String ACTION_BOOKMARK = "org.mozilla.gecko.BOOKMARK"; public static FrameLayout mainLayout; public static GeckoSurfaceView surfaceView; @@ -146,23 +148,23 @@ abstract public class GeckoApp } catch (InterruptedException ie) {} surfaceView.mSplashStatusMsg = getResources().getString(R.string.splash_screen_loading); surfaceView.drawSplashScreen(); // unpack files in the components directory try { unpackComponents(); } catch (FileNotFoundException fnfe) { - Log.e("GeckoApp", "error unpacking components", fnfe); + Log.e(LOG_FILE_NAME, "error unpacking components", fnfe); Looper.prepare(); showErrorDialog(getString(R.string.error_loading_file)); Looper.loop(); return; } catch (IOException ie) { - Log.e("GeckoApp", "error unpacking components", ie); + Log.e(LOG_FILE_NAME, "error unpacking components", ie); String msg = ie.getMessage(); Looper.prepare(); if (msg != null && msg.equalsIgnoreCase("No space left on device")) showErrorDialog(getString(R.string.no_space_to_start_error)); else showErrorDialog(getString(R.string.error_loading_file)); Looper.loop(); return; @@ -170,17 +172,17 @@ abstract public class GeckoApp // and then fire us up try { String env = i.getStringExtra("env0"); GeckoAppShell.runGecko(getApplication().getPackageResourcePath(), i.getStringExtra("args"), i.getDataString()); } catch (Exception e) { - Log.e("GeckoApp", "top level exception", e); + Log.e(LOG_FILE_NAME, "top level exception", e); StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); GeckoAppShell.reportJavaCrash(sw.toString()); } } }.start(); return true; } @@ -194,33 +196,33 @@ abstract public class GeckoApp if (!sTryCatchAttached) { sTryCatchAttached = true; mMainHandler.post(new Runnable() { public void run() { try { Looper.loop(); } catch (Exception e) { - Log.e("GeckoApp", "top level exception", e); + Log.e(LOG_FILE_NAME, "top level exception", e); StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); GeckoAppShell.reportJavaCrash(sw.toString()); } // resetting this is kinda pointless, but oh well sTryCatchAttached = false; } }); } SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE); String localeCode = settings.getString(getPackageName() + ".locale", ""); if (localeCode != null && localeCode.length() > 0) GeckoAppShell.setSelectedLocale(localeCode); - Log.i("GeckoApp", "create"); + Log.i(LOG_FILE_NAME, "create"); super.onCreate(savedInstanceState); if (sGREDir == null) sGREDir = new File(this.getApplicationInfo().dataDir); getWindow().setFlags(mFullscreen ? WindowManager.LayoutParams.FLAG_FULLSCREEN : 0, WindowManager.LayoutParams.FLAG_FULLSCREEN); @@ -314,40 +316,40 @@ abstract public class GeckoApp }); mainLayout.addView(launchButton, 300, 200); return; } if (checkLaunchState(LaunchState.WaitButton) || launch(intent)) return; if (Intent.ACTION_MAIN.equals(action)) { - Log.i("GeckoApp", "Intent : ACTION_MAIN"); + Log.i(LOG_FILE_NAME, "Intent : ACTION_MAIN"); GeckoAppShell.sendEventToGecko(new GeckoEvent("")); } else if (Intent.ACTION_VIEW.equals(action)) { String uri = intent.getDataString(); GeckoAppShell.sendEventToGecko(new GeckoEvent(uri)); - Log.i("GeckoApp","onNewIntent: "+uri); + Log.i(LOG_FILE_NAME,"onNewIntent: "+uri); } else if (ACTION_WEBAPP.equals(action)) { String uri = intent.getStringExtra("args"); GeckoAppShell.sendEventToGecko(new GeckoEvent(uri)); - Log.i("GeckoApp","Intent : WEBAPP - " + uri); + Log.i(LOG_FILE_NAME,"Intent : WEBAPP - " + uri); } else if (ACTION_BOOKMARK.equals(action)) { String args = intent.getStringExtra("args"); GeckoAppShell.sendEventToGecko(new GeckoEvent(args)); - Log.i("GeckoApp","Intent : BOOKMARK - " + args); + Log.i(LOG_FILE_NAME,"Intent : BOOKMARK - " + args); } } @Override public void onPause() { - Log.i("GeckoApp", "pause"); + Log.i(LOG_FILE_NAME, "pause"); GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_PAUSING)); // The user is navigating away from this activity, but nothing // has come to the foreground yet; for Gecko, we may want to // stop repainting, for example. // Whatever we do here should be fast, because we're blocking // the next activity from showing up until we finish. @@ -359,17 +361,17 @@ abstract public class GeckoApp TelephonyManager tm = (TelephonyManager) GeckoApp.mAppContext.getSystemService(Context.TELEPHONY_SERVICE); tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); } @Override public void onResume() { - Log.i("GeckoApp", "resume"); + Log.i(LOG_FILE_NAME, "resume"); if (checkLaunchState(LaunchState.GeckoRunning)) GeckoAppShell.onResume(); // After an onPause, the activity is back in the foreground. // Undo whatever we did in onPause. super.onResume(); // Just in case. Normally we start in onNewIntent if (checkLaunchState(LaunchState.PreLaunch) || @@ -384,17 +386,17 @@ abstract public class GeckoApp // Notify if network state changed since we paused GeckoAppShell.onNetworkStateChange(true); } @Override public void onStop() { - Log.i("GeckoApp", "stop"); + Log.i(LOG_FILE_NAME, "stop"); // We're about to be stopped, potentially in preparation for // being destroyed. We're killable after this point -- as I // understand it, in extreme cases the process can be terminated // without going through onDestroy. // // We might also get an onRestart after this; not sure what // that would mean for Gecko if we were to kill it here. // Instead, what we should do here is save prefs, session, @@ -405,52 +407,52 @@ abstract public class GeckoApp GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_STOPPING)); super.onStop(); GeckoAppShell.putChildInBackground(); } @Override public void onRestart() { - Log.i("GeckoApp", "restart"); + Log.i(LOG_FILE_NAME, "restart"); GeckoAppShell.putChildInForeground(); super.onRestart(); } @Override public void onStart() { - Log.i("GeckoApp", "start"); + Log.i(LOG_FILE_NAME, "start"); super.onStart(); } @Override public void onDestroy() { - Log.i("GeckoApp", "destroy"); + Log.i(LOG_FILE_NAME, "destroy"); // Tell Gecko to shutting down; we'll end up calling System.exit() // in onXreExit. if (isFinishing()) GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_SHUTDOWN)); super.onDestroy(); } @Override public void onConfigurationChanged(android.content.res.Configuration newConfig) { - Log.i("GeckoApp", "configuration changed"); + Log.i(LOG_FILE_NAME, "configuration changed"); // nothing, just ignore super.onConfigurationChanged(newConfig); } @Override public void onLowMemory() { - Log.e("GeckoApp", "low memory"); + Log.e(LOG_FILE_NAME, "low memory"); if (checkLaunchState(LaunchState.GeckoRunning)) GeckoAppShell.onLowMemory(); super.onLowMemory(); } abstract public String getPackageName(); abstract public String getContentProcessName(); @@ -465,17 +467,17 @@ abstract public class GeckoApp zip = new ZipFile(getApplication().getPackageResourcePath()); byte[] buf = new byte[8192]; try { if (unpackFile(zip, buf, null, "removed-files")) removeFiles(); } catch (Exception ex) { // This file may not be there, so just log any errors and move on - Log.w("GeckoApp", "error removing files", ex); + Log.w(LOG_FILE_NAME, "error removing files", ex); } unpackFile(zip, buf, null, "application.ini"); unpackFile(zip, buf, null, getContentProcessName()); try { unpackFile(zip, buf, null, "update.locale"); } catch (Exception e) {/* this is non-fatal */} // copy any .xpi file into an extensions/ directory @@ -580,33 +582,33 @@ abstract public class GeckoApp try { String action = "org.mozilla.gecko.restart"; Intent intent = new Intent(action); intent.setClassName(getPackageName(), getPackageName() + ".Restarter"); addEnvToIntent(intent); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); - Log.i("GeckoAppJava", intent.toString()); + Log.i(LOG_FILE_NAME, intent.toString()); GeckoAppShell.killAnyZombies(); startActivity(intent); } catch (Exception e) { - Log.i("GeckoAppJava", "error doing restart", e); + Log.i(LOG_FILE_NAME, "error doing restart", e); } finish(); // Give the restart process time to start before we die GeckoAppShell.waitForAnotherGeckoProc(); } public void handleNotification(String action, String alertName, String alertCookie) { GeckoAppShell.handleNotification(action, alertName, alertCookie); } private void checkAndLaunchUpdate() { - Log.i("GeckoAppJava", "Checking for an update"); + Log.i(LOG_FILE_NAME, "Checking for an update"); int statusCode = 8; // UNEXPECTED_ERROR File baseUpdateDir = null; if (Build.VERSION.SDK_INT >= 8) baseUpdateDir = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); else baseUpdateDir = new File(Environment.getExternalStorageDirectory().getPath(), "download"); @@ -616,81 +618,85 @@ abstract public class GeckoApp File statusFile = new File(updateDir, "update.status"); if (!statusFile.exists() || !readUpdateStatus(statusFile).equals("pending")) return; if (!updateFile.exists()) return; - Log.i("GeckoAppJava", "Update is available!"); + Log.i(LOG_FILE_NAME, "Update is available!"); // Launch APK File updateFileToRun = new File(updateDir, getPackageName() + "-update.apk"); try { if (updateFile.renameTo(updateFileToRun)) { String amCmd = "/system/bin/am start -a android.intent.action.VIEW " + "-n com.android.packageinstaller/.PackageInstallerActivity -d file://" + updateFileToRun.getPath(); - Log.i("GeckoAppJava", amCmd); + Log.i(LOG_FILE_NAME, amCmd); Runtime.getRuntime().exec(amCmd); statusCode = 0; // OK } else { - Log.i("GeckoAppJava", "Cannot rename the update file!"); + Log.i(LOG_FILE_NAME, "Cannot rename the update file!"); statusCode = 7; // WRITE_ERROR } } catch (Exception e) { - Log.i("GeckoAppJava", "error launching installer to update", e); + Log.i(LOG_FILE_NAME, "error launching installer to update", e); } // Update the status file String status = statusCode == 0 ? "succeeded\n" : "failed: "+ statusCode + "\n"; OutputStream outStream; try { byte[] buf = status.getBytes("UTF-8"); outStream = new FileOutputStream(statusFile); outStream.write(buf, 0, buf.length); outStream.close(); } catch (Exception e) { - Log.i("GeckoAppJava", "error writing status file", e); + Log.i(LOG_FILE_NAME, "error writing status file", e); } if (statusCode == 0) System.exit(0); } private String readUpdateStatus(File statusFile) { String status = ""; try { BufferedReader reader = new BufferedReader(new FileReader(statusFile)); status = reader.readLine(); reader.close(); } catch (Exception e) { - Log.i("GeckoAppJava", "error reading update status", e); + Log.i(LOG_FILE_NAME, "error reading update status", e); } return status; } static final int FILE_PICKER_REQUEST = 1; private SynchronousQueue<String> mFilePickerResult = new SynchronousQueue(); public String showFilePicker(String aMimeType) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType(aMimeType); GeckoApp.this. startActivityForResult( Intent.createChooser(intent, getString(R.string.choose_file)), FILE_PICKER_REQUEST); String filePickerResult = ""; + try { - filePickerResult = mFilePickerResult.take(); + while (null == (filePickerResult = mFilePickerResult.poll(1, TimeUnit.MILLISECONDS))) { + Log.i("GeckoApp", "processing events from showFilePicker "); + GeckoAppShell.processNextNativeEvent(); + } } catch (InterruptedException e) { - Log.i("GeckoApp", "showing file picker ", e); + Log.i(LOG_FILE_NAME, "showing file picker ", e); } return filePickerResult; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { @@ -733,18 +739,18 @@ abstract public class GeckoApp int len = is.read(buf); while (len != -1) { fos.write(buf, 0, len); len = is.read(buf); } fos.close(); filePickerResult = file.getAbsolutePath(); }catch (Exception e) { - Log.e("GeckoApp", "showing file picker", e); + Log.e(LOG_FILE_NAME, "showing file picker", e); } } try { mFilePickerResult.put(filePickerResult); } catch (InterruptedException e) { - Log.i("GeckoApp", "error returning file picker result", e); + Log.i(LOG_FILE_NAME, "error returning file picker result", e); } } }
--- a/embedding/android/GeckoAppShell.java +++ b/embedding/android/GeckoAppShell.java @@ -69,16 +69,18 @@ import android.net.Uri; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.graphics.drawable.*; import android.graphics.Bitmap; public class GeckoAppShell { + private static final String LOG_FILE_NAME = "GeckoAppShell"; + // static members only private GeckoAppShell() { } static private LinkedList<GeckoEvent> gPendingEvents = new LinkedList<GeckoEvent>(); static private boolean gRestartScheduled = false; @@ -112,16 +114,18 @@ public class GeckoAppShell public static native void onResume(); public static native void onLowMemory(); public static native void callObserver(String observerKey, String topic, String data); public static native void removeObserver(String observerKey); public static native void loadLibs(String apkName, boolean shouldExtract); public static native void onChangeNetworkLinkStatus(String status, String type); public static native void reportJavaCrash(String stack); + public static native void processNextNativeEvent(); + // A looper thread, accessed by GeckoAppShell.getHandler private static class LooperThread extends Thread { public SynchronousQueue<Handler> mHandlerQueue = new SynchronousQueue<Handler>(); public void run() { Looper.prepare(); try { @@ -185,35 +189,35 @@ public class GeckoAppShell try { if (sFreeSpace == -1) { File cacheDir = getCacheDir(); if (cacheDir != null) { StatFs cacheStats = new StatFs(cacheDir.getPath()); sFreeSpace = cacheStats.getFreeBlocks() * cacheStats.getBlockSize(); } else { - Log.i("GeckoAppShell", "Unable to get cache dir"); + Log.i(LOG_FILE_NAME, "Unable to get cache dir"); } } } catch (Exception e) { - Log.e("GeckoAppShell", "exception while stating cache dir: ", e); + Log.e(LOG_FILE_NAME, "exception while stating cache dir: ", e); } return sFreeSpace; } static boolean moveFile(File inFile, File outFile) { - Log.i("GeckoAppShell", "moving " + inFile + " to " + outFile); + Log.i(LOG_FILE_NAME, "moving " + inFile + " to " + outFile); if (outFile.isDirectory()) outFile = new File(outFile, inFile.getName()); try { if (inFile.renameTo(outFile)) return true; } catch (SecurityException se) { - Log.w("GeckoAppShell", "error trying to rename file", se); + Log.w(LOG_FILE_NAME, "error trying to rename file", se); } try { long lastModified = inFile.lastModified(); outFile.createNewFile(); // so copy it instead FileChannel inChannel = new FileInputStream(inFile).getChannel(); FileChannel outChannel = new FileOutputStream(outFile).getChannel(); long size = inChannel.size(); @@ -222,34 +226,34 @@ public class GeckoAppShell outChannel.close(); outFile.setLastModified(lastModified); if (transferred == size) inFile.delete(); else return false; } catch (Exception e) { - Log.e("GeckoAppShell", "exception while moving file: ", e); + Log.e(LOG_FILE_NAME, "exception while moving file: ", e); try { outFile.delete(); } catch (SecurityException se) { - Log.w("GeckoAppShell", "error trying to delete file", se); + Log.w(LOG_FILE_NAME, "error trying to delete file", se); } return false; } return true; } static boolean moveDir(File from, File to) { try { to.mkdirs(); if (from.renameTo(to)) return true; } catch (SecurityException se) { - Log.w("GeckoAppShell", "error trying to rename file", se); + Log.w(LOG_FILE_NAME, "error trying to rename file", se); } File[] files = from.listFiles(); boolean retVal = true; if (files == null) return false; try { Iterator fileIterator = Arrays.asList(files).iterator(); while (fileIterator.hasNext()) { @@ -257,17 +261,17 @@ public class GeckoAppShell File dest = new File(to, file.getName()); if (file.isDirectory()) retVal = moveDir(file, dest) ? retVal : false; else retVal = moveFile(file, dest) ? retVal : false; } from.delete(); } catch(Exception e) { - Log.e("GeckoAppShell", "error trying to move file", e); + Log.e(LOG_FILE_NAME, "error trying to move file", e); } return retVal; } // java-side stuff public static void loadGeckoLibs(String apkName) { // The package data lib directory isn't placed in ld.so's // search path, so we have to manually load libraries that @@ -305,21 +309,21 @@ public class GeckoAppShell File intProf = new File(intHome, "mozilla"); if (intHome != null && intProf != null && intProf.exists()) moveDir(intProf, profileDir); } GeckoAppShell.putenv("HOME=" + homeDir); GeckoAppShell.putenv("GRE_HOME=" + GeckoApp.sGREDir.getPath()); Intent i = geckoApp.getIntent(); String env = i.getStringExtra("env0"); - Log.i("GeckoApp", "env0: "+ env); + Log.i(LOG_FILE_NAME, "env0: "+ env); for (int c = 1; env != null; c++) { GeckoAppShell.putenv(env); env = i.getStringExtra("env" + c); - Log.i("GeckoApp", "env"+ c +": "+ env); + Log.i(LOG_FILE_NAME, "env"+ c +": "+ env); } File f = geckoApp.getDir("tmp", Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE ); if (!f.exists()) f.mkdirs(); @@ -341,17 +345,17 @@ public class GeckoAppShell updatesDir = GeckoApp.mAppContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); } else { updatesDir = downloadDir = new File(Environment.getExternalStorageDirectory().getPath(), "download"); } GeckoAppShell.putenv("DOWNLOADS_DIRECTORY=" + downloadDir.getPath()); GeckoAppShell.putenv("UPDATES_DIRECTORY=" + updatesDir.getPath()); } catch (Exception e) { - Log.i("GeckoApp", "No download directory has been found: " + e); + Log.i(LOG_FILE_NAME, "No download directory has been found: " + e); } putLocaleEnv(); if (freeSpace + kLibFreeSpaceBuffer < kFreeSpaceThreshold) { // remove any previously extracted libs since we're apparently low File[] files = cacheFile.listFiles(); if (files != null) { @@ -1102,17 +1106,17 @@ public class GeckoAppShell type = "4g"; typeCode = 7; } } } // If the network state has changed, notify Gecko if (notifyChanged && (state != sNetworkState || typeCode != sNetworkTypeCode)) { - Log.i("GeckoAppShell", "Network state changed: (" + state + ", " + type + ") "); + Log.i(LOG_FILE_NAME, "Network state changed: (" + state + ", " + type + ") "); sNetworkState = state; sNetworkType = type; sNetworkTypeCode = typeCode; if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) onChangeNetworkLinkStatus(sNetworkState, sNetworkType); } } @@ -1186,17 +1190,17 @@ public class GeckoAppShell public boolean callback(int pid) { if (pid != android.os.Process.myPid()) { try { FileOutputStream fos = new FileOutputStream( new File("/dev/cpuctl/" + backgroundGroup +"/tasks")); fos.write(new Integer(pid).toString().getBytes()); fos.close(); } catch(Exception e) { - Log.e("GeckoAppShell", "error putting child in the background", e); + Log.e(LOG_FILE_NAME, "error putting child in the background", e); } } return true; } }; EnumerateGeckoProcesses(visitor); } catch (Exception e) { Log.e("GeckoInputStream", "error reading cgroup", e); @@ -1207,17 +1211,17 @@ public class GeckoAppShell GeckoProcessesVisitor visitor = new GeckoProcessesVisitor() { public boolean callback(int pid) { if (pid != android.os.Process.myPid()) { try { FileOutputStream fos = new FileOutputStream(new File("/dev/cpuctl/tasks")); fos.write(new Integer(pid).toString().getBytes()); fos.close(); } catch(Exception e) { - Log.e("GeckoAppShell", "error putting child in the foreground", e); + Log.e(LOG_FILE_NAME, "error putting child in the foreground", e); } } return true; } }; EnumerateGeckoProcesses(visitor); } @@ -1295,17 +1299,17 @@ public class GeckoAppShell boolean keepGoing = visiter.callback(pid); if (keepGoing == false) break; } } in.close(); } catch (Exception e) { - Log.i("GeckoAppShell", "finding procs throws ", e); + Log.i(LOG_FILE_NAME, "finding procs throws ", e); } } public static void waitForAnotherGeckoProc(){ int countdown = 40; while (!checkForGeckoProcs() && --countdown > 0) { try { Thread.currentThread().sleep(100); @@ -1338,17 +1342,17 @@ public class GeckoAppShell bitmap = Bitmap.createScaledBitmap(bitmap, iconSize, iconSize, true); ByteBuffer buf = ByteBuffer.allocate(iconSize * iconSize * 4); bitmap.copyPixelsToBuffer(buf); return buf.array(); } catch (Exception e) { - Log.i("GeckoAppShell", "getIconForExtension error: ", e); + Log.i(LOG_FILE_NAME, "getIconForExtension error: ", e); return null; } } private static Drawable getDrawableForExtension(PackageManager pm, String aExt) { Intent intent = new Intent(Intent.ACTION_VIEW); MimeTypeMap mtm = MimeTypeMap.getSingleton(); String mimeType = mtm.getMimeTypeFromExtension(aExt);
--- a/embedding/android/GeckoSurfaceView.java +++ b/embedding/android/GeckoSurfaceView.java @@ -66,16 +66,18 @@ import android.util.*; * similar to GLSurfaceView. However, since we * already have a thread for Gecko, we don't really want * a separate renderer thread that GLSurfaceView provides. */ class GeckoSurfaceView extends SurfaceView implements SurfaceHolder.Callback, SensorEventListener, LocationListener { + private static final String LOG_FILE_NAME = "GeckoSurfaceView"; + public GeckoSurfaceView(Context context) { super(context); getHolder().addCallback(this); inputConnection = new GeckoInputConnection(this); setFocusable(true); setFocusableInTouchMode(true); @@ -102,17 +104,17 @@ class GeckoSurfaceView void drawSplashScreen() { this.drawSplashScreen(getHolder(), mWidth, mHeight); } void drawSplashScreen(SurfaceHolder holder, int width, int height) { Canvas c = holder.lockCanvas(); if (c == null) { - Log.i("GeckoSurfaceView", "canvas is null"); + Log.i(LOG_FILE_NAME, "canvas is null"); return; } Resources res = getResources(); c.drawColor(res.getColor(R.color.splash_background)); Drawable drawable = res.getDrawable(R.drawable.splash); int w = drawable.getIntrinsicWidth(); int h = drawable.getIntrinsicHeight(); int x = (width - w)/2; @@ -168,17 +170,17 @@ class GeckoSurfaceView public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (mShowingSplashScreen) drawSplashScreen(holder, width, height); mSurfaceLock.lock(); try { if (mInDrawing) { - Log.w("GeckoAppJava", "surfaceChanged while mInDrawing is true!"); + Log.w(LOG_FILE_NAME, "surfaceChanged while mInDrawing is true!"); } boolean invalidSize; if (width == 0 || height == 0) { mSoftwareBitmap = null; mSoftwareBuffer = null; mSoftwareBufferCopy = null; @@ -193,17 +195,17 @@ class GeckoSurfaceView GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning); mSyncDraw = doSyncDraw; mFormat = format; mWidth = width; mHeight = height; mSurfaceValid = true; - Log.i("GeckoAppJava", "surfaceChanged: fmt: " + format + " dim: " + width + " " + height); + Log.i(LOG_FILE_NAME, "surfaceChanged: fmt: " + format + " dim: " + width + " " + height); DisplayMetrics metrics = new DisplayMetrics(); GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); GeckoEvent e = new GeckoEvent(GeckoEvent.SIZE_CHANGED, width, height, metrics.widthPixels, metrics.heightPixels); GeckoAppShell.sendEventToGecko(e); @@ -220,38 +222,38 @@ class GeckoSurfaceView } finally { mSurfaceLock.unlock(); } Object syncDrawObject = null; try { syncDrawObject = mSyncDraws.take(); } catch (InterruptedException ie) { - Log.e("GeckoAppJava", "Threw exception while getting sync draw bitmap/buffer: ", ie); + Log.e(LOG_FILE_NAME, "Threw exception while getting sync draw bitmap/buffer: ", ie); } if (syncDrawObject != null) { if (syncDrawObject instanceof Bitmap) draw(holder, (Bitmap)syncDrawObject); else draw(holder, (ByteBuffer)syncDrawObject); } else { Log.e("GeckoSurfaceViewJava", "Synchronised draw object is null"); } } public void surfaceCreated(SurfaceHolder holder) { - Log.i("GeckoAppJava", "surface created"); + Log.i(LOG_FILE_NAME, "surface created"); GeckoEvent e = new GeckoEvent(GeckoEvent.SURFACE_CREATED); GeckoAppShell.sendEventToGecko(e); if (mShowingSplashScreen) drawSplashScreen(); } public void surfaceDestroyed(SurfaceHolder holder) { - Log.i("GeckoAppJava", "surface destroyed"); + Log.i(LOG_FILE_NAME, "surface destroyed"); mSurfaceValid = false; mSoftwareBuffer = null; mSoftwareBufferCopy = null; mSoftwareBitmap = null; GeckoEvent e = new GeckoEvent(GeckoEvent.SURFACE_DESTROYED); GeckoAppShell.sendEventToGecko(e); } @@ -289,17 +291,17 @@ class GeckoSurfaceView */ public static final int DRAW_ERROR = 0; public static final int DRAW_GLES_2 = 1; public static final int DRAW_2D = 2; public int beginDrawing() { if (mInDrawing) { - Log.e("GeckoAppJava", "Recursive beginDrawing call!"); + Log.e(LOG_FILE_NAME, "Recursive beginDrawing call!"); return DRAW_ERROR; } /* Grab the lock, which we'll hold while we're drawing. * It gets released in endDrawing(), and is also used in surfaceChanged * to make sure that we don't change our surface details while * we're in the middle of drawing (and especially in the middle of * executing beginDrawing/endDrawing). @@ -307,42 +309,42 @@ class GeckoSurfaceView * We might not need to hold this lock in between * beginDrawing/endDrawing, and might just be able to make * surfaceChanged, beginDrawing, and endDrawing synchronized, * but this way is safer for now. */ mSurfaceLock.lock(); if (!mSurfaceValid) { - Log.e("GeckoAppJava", "Surface not valid"); + Log.e(LOG_FILE_NAME, "Surface not valid"); mSurfaceLock.unlock(); return DRAW_ERROR; } mInDrawing = true; mDrawMode = DRAW_GLES_2; return DRAW_GLES_2; } public void endDrawing() { if (!mInDrawing) { - Log.e("GeckoAppJava", "endDrawing without beginDrawing!"); + Log.e(LOG_FILE_NAME, "endDrawing without beginDrawing!"); return; } try { if (!mSurfaceValid) { - Log.e("GeckoAppJava", "endDrawing with false mSurfaceValid"); + Log.e(LOG_FILE_NAME, "endDrawing with false mSurfaceValid"); return; } } finally { mInDrawing = false; if (!mSurfaceLock.isHeldByCurrentThread()) - Log.e("GeckoAppJava", "endDrawing while mSurfaceLock not held by current thread!"); + Log.e(LOG_FILE_NAME, "endDrawing while mSurfaceLock not held by current thread!"); mSurfaceLock.unlock(); } } /* How this works: * Whenever we want to draw, we want to be sure that we do not lock * the canvas unless we're sure we can draw. Locking the canvas clears @@ -363,17 +365,17 @@ class GeckoSurfaceView try { if (mSyncDraw) { if (bitmap != mSoftwareBitmap || width != mWidth || height != mHeight) return; mSyncDraw = false; try { mSyncDraws.put(bitmap); } catch (InterruptedException ie) { - Log.e("GeckoAppJava", "Threw exception while getting sync draws queue: ", ie); + Log.e(LOG_FILE_NAME, "Threw exception while getting sync draws queue: ", ie); } return; } } finally { mSurfaceLock.unlock(); } draw(getHolder(), bitmap); @@ -384,17 +386,17 @@ class GeckoSurfaceView try { if (mSyncDraw) { if (buffer != mSoftwareBuffer || stride != (mWidth * 2)) return; mSyncDraw = false; try { mSyncDraws.put(buffer); } catch (InterruptedException ie) { - Log.e("GeckoAppJava", "Threw exception while getting sync bitmaps queue: ", ie); + Log.e(LOG_FILE_NAME, "Threw exception while getting sync bitmaps queue: ", ie); } return; } } finally { mSurfaceLock.unlock(); } draw(getHolder(), buffer); @@ -487,17 +489,17 @@ class GeckoSurfaceView List<Address> addresses = mGeocoder.getFromLocation(location[0].getLatitude(), location[0].getLongitude(), 1); // grab the first address. in the future, // may want to expose multiple, or filter // for best. mLastGeoAddress = addresses.get(0); GeckoAppShell.sendEventToGecko(new GeckoEvent(location[0], mLastGeoAddress)); } catch (Exception e) { - Log.w("GeckoSurfaceView", "GeocoderTask "+e); + Log.w(LOG_FILE_NAME, "GeocoderTask "+e); } return null; } } // geolocation public void onLocationChanged(Location location) {
--- a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp +++ b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp @@ -882,25 +882,23 @@ nsDocShellTreeOwner::AddChromeListeners( } } // register dragover and drop event listeners with the listener manager nsCOMPtr<nsIDOMEventTarget> target; GetDOMEventTarget(mWebBrowser, getter_AddRefs(target)); nsEventListenerManager* elmP = target->GetListenerManager(PR_TRUE); - if (elmP) - { - rv = elmP->AddEventListenerByType(this, NS_LITERAL_STRING("dragover"), - NS_EVENT_FLAG_BUBBLE | - NS_EVENT_FLAG_SYSTEM_EVENT); - NS_ENSURE_SUCCESS(rv, rv); - rv = elmP->AddEventListenerByType(this, NS_LITERAL_STRING("drop"), - NS_EVENT_FLAG_BUBBLE | - NS_EVENT_FLAG_SYSTEM_EVENT); + if (elmP) { + elmP->AddEventListenerByType(this, NS_LITERAL_STRING("dragover"), + NS_EVENT_FLAG_BUBBLE | + NS_EVENT_FLAG_SYSTEM_EVENT); + elmP->AddEventListenerByType(this, NS_LITERAL_STRING("drop"), + NS_EVENT_FLAG_BUBBLE | + NS_EVENT_FLAG_SYSTEM_EVENT); } return rv; } // AddChromeListeners NS_IMETHODIMP
--- a/gfx/src/nsRenderingContext.h +++ b/gfx/src/nsRenderingContext.h @@ -65,17 +65,17 @@ public: NS_INLINE_DECL_REFCOUNTING(nsRenderingContext) void Init(nsDeviceContext* aContext, gfxASurface* aThebesSurface); void Init(nsDeviceContext* aContext, gfxContext* aThebesContext); // These accessors will never return null. gfxContext *ThebesContext() { return mThebes; } nsDeviceContext *DeviceContext() { return mDeviceContext; } - PRUint32 AppUnitsPerDevPixel() { return mP2A; } + PRUint32 AppUnitsPerDevPixel() { return NSToIntRound(mP2A); } // Graphics state void PushState(void); void PopState(void); void IntersectClip(const nsRect& aRect); void SetClip(const nsIntRegion& aRegion); void SetLineStyle(nsLineStyle aLineStyle);
--- a/js/src/configure.in +++ b/js/src/configure.in @@ -2007,16 +2007,18 @@ case "$target" in _PLATFORM_DEFAULT_TOOLKIT='cairo-cocoa' TARGET_NSPR_MDCPUCFG='\"md/_darwin.cfg\"' LDFLAGS="$LDFLAGS -framework Cocoa -lobjc" LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS) $(LIBXUL_DIST)/bin/XUL' # The ExceptionHandling framework is needed for Objective-C exception # logging code in nsObjCExceptions.h. Currently we only use that in debug # builds. MOZ_DEBUG_LDFLAGS="$MOZ_DEBUG_LDFLAGS -framework ExceptionHandling" + # Debug builds should always have frame pointers + MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer" if test "x$lto_is_enabled" = "xyes"; then echo "Skipping -dead_strip because lto is enabled." dnl DTrace and -dead_strip don't interact well. See bug 403132. dnl =================================================================== elif test "x$enable_dtrace" = "xyes"; then echo "Skipping -dead_strip because DTrace is enabled. See bug 403132." else @@ -2155,16 +2157,18 @@ ia64*-hpux*) # If we're building with --enable-profiling, we need a frame pointer. if test -z "$MOZ_PROFILING"; then MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions -fomit-frame-pointer" else MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions -fno-omit-frame-pointer" fi # The Maemo builders don't know about this flag MOZ_ARM_VFP_FLAGS="-mfpu=vfp" + # Debug builds should always have frame pointers + MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer" ;; *-*linux*) # Note: both GNU_CC and INTEL_CC are set when using Intel's C compiler. # Similarly for GNU_CXX and INTEL_CXX. if test "$INTEL_CC" -o "$INTEL_CXX"; then # -Os has been broken on Intel's C/C++ compilers for quite a # while; Intel recommends against using it. @@ -2180,17 +2184,18 @@ ia64*-hpux*) # If we're building with --enable-profiling, we need a frame pointer. if test -z "$MOZ_PROFILING"; then MOZ_FRAMEPTR_FLAGS="-fomit-frame-pointer" else MOZ_FRAMEPTR_FLAGS="-fno-omit-frame-pointer" fi MOZ_PGO_OPTIMIZE_FLAGS="-O3 $MOZ_FRAMEPTR_FLAGS" MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks $MOZ_OPTIMIZE_SIZE_TWEAK $MOZ_FRAMEPTR_FLAGS" - MOZ_DEBUG_FLAGS="-g" + # Debug builds should always have frame pointers + MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer" fi TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"' case "${target_cpu}" in alpha*) CFLAGS="$CFLAGS -mieee" CXXFLAGS="$CXXFLAGS -mieee" @@ -2296,17 +2301,18 @@ ia64*-hpux*) CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)" CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)" # MSVC warnings C4244 and C4800 are ubiquitous, useless, and annoying. CXXFLAGS="$CXXFLAGS -wd4244 -wd4800" # make 'foo == bar;' error out CFLAGS="$CFLAGS -we4553" CXXFLAGS="$CXXFLAGS -we4553" LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib" - MOZ_DEBUG_FLAGS='-Zi' + # Debug builds should always have frame pointers + MOZ_DEBUG_FLAGS='-Zi -Oy-' MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV' WARNINGS_AS_ERRORS='-WX' # If we're building with --enable-profiling, we need -Oy-, which forces a frame pointer. if test -z "$MOZ_PROFILING"; then MOZ_OPTIMIZE_FLAGS='-O1' else MOZ_OPTIMIZE_FLAGS='-O1 -Oy-' fi @@ -3489,63 +3495,16 @@ then CFLAGS="$CFLAGS -mt" CXXFLAGS="$CXXFLAGS -mt" fi ;; esac LDFLAGS="${_PTHREAD_LDFLAGS} ${LDFLAGS}" fi -dnl ======================================================== -dnl See if mmap sees writes -dnl For cross compiling, just define it as no, which is a safe default -dnl ======================================================== -AC_MSG_CHECKING(whether mmap() sees write()s) - -changequote(,) -mmap_test_prog=' - #include <stdlib.h> - #include <unistd.h> - #include <sys/mman.h> - #include <sys/types.h> - #include <sys/stat.h> - #include <fcntl.h> - - char fname[] = "conftest.file"; - char zbuff[1024]; /* Fractional page is probably worst case */ - - int main() { - char *map; - int fd; - int i; - unlink(fname); - fd = open(fname, O_RDWR | O_CREAT, 0660); - if(fd<0) return 1; - unlink(fname); - write(fd, zbuff, sizeof(zbuff)); - lseek(fd, 0, SEEK_SET); - map = (char*)mmap(0, sizeof(zbuff), PROT_READ, MAP_SHARED, fd, 0); - if(map==(char*)-1) return 2; - for(i=0; fname[i]; i++) { - int rc = write(fd, &fname[i], 1); - if(map[i]!=fname[i]) return 4; - } - return 0; - } -' -changequote([,]) - -AC_TRY_RUN($mmap_test_prog , result="yes", result="no", result="yes") - -AC_MSG_RESULT("$result") - -if test "$result" = "no"; then - AC_DEFINE(MMAP_MISSES_WRITES) -fi - dnl Checks for library functions. dnl ======================================================== AC_PROG_GCC_TRADITIONAL AC_FUNC_MEMCMP AC_CHECK_FUNCS([fchmod flockfile getc_unlocked _getc_nolock getpagesize \ lchown localtime_r lstat64 memmove random rint sbrk snprintf \ stat64 statvfs statvfs64 strerror strtok_r truncate64])
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug677367.js @@ -0,0 +1,5 @@ +// |jit-test| debug + +function f() {} +trap(f, 0, 'eval("2+2")'); +f();
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/basic/testErrorInFinalizerCalledWhileUnwinding.js @@ -0,0 +1,32 @@ +var finalizerRun = false; +var caught = false; + +function foo(arr) { + finalizerRun = true; + return not_defined; +} + +function gen() { + try { + yield 1; + } finally { + foo(); + } +} + +function test() { + var i_have_locals; + for (i in gen()) { + "this won't work"(); + } +} + +try { + test(); +} catch(e) { + caught = true; + assertEq(''+e, "ReferenceError: not_defined is not defined"); +} + +assertEq(finalizerRun, true); +assertEq(caught, true);
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/basic/testEvalFromTrap.js @@ -0,0 +1,4 @@ +// |jit-test| debug +function f() {} +trap(f, 0, 'eval("2+2")'); +f();
--- a/js/src/jit-test/tests/basic/testStackIter.js +++ b/js/src/jit-test/tests/basic/testStackIter.js @@ -123,16 +123,22 @@ var obj = { valueOf:(function valueOf() var obj = { valueOf:(function valueOf() { assertStackIs([valueOf, "bound(valueOf)", "bound(valueOf)", "bound(valueOf)", Math.sin, Array.prototype.sort, "global-code"]); }).bind().bind().bind() }; [obj, obj].sort(Math.sin); /***********/ +var proxy = Proxy.createFunction({}, function f() { assertStackIs([f, "global-code"]) }); +proxy(); +new proxy(); + +/***********/ + for (var i = 0; i < 10; ++i) { /* No loss for scripts. */ (function f() { assertStackIs([f, Function.prototype.apply, 'global-code']); }).apply(null, {}); (function f() { assertStackIs([f, Function.prototype.call, 'global-code']); }).call(null);
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/debug/Object-deleteProperty-error-01.js @@ -0,0 +1,16 @@ +// Don't crash when a scripted proxy handler throws Error.prototype. + +var g = newGlobal('new-compartment'); +var dbg = Debugger(g); +dbg.onDebuggerStatement = function (frame) { + try { + frame.arguments[0].deleteProperty("x"); + } catch (exc) { + return; + } + throw new Error("deleteProperty should throw"); +}; + +g.eval("function h(x) { debugger; }"); +g.eval("h(Proxy.create({delete: function () { throw Error.prototype; }}));"); +
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/debug/onDebuggerStatement-04.js @@ -0,0 +1,10 @@ +var g = newGlobal('new-compartment'); +var dbg = new Debugger(g); +dbg.onDebuggerStatement = function (frame) { + var code = "assertEq(c, 'ok');\n"; + assertEq(frame.evalWithBindings("eval(s)", {s: code, a: 1234}).return, undefined); +}; +g.eval("function first() { return second(); }"); +g.eval("function second() { return eval('third()'); }"); +g.eval("function third() { debugger; }"); +g.evaluate("first();");
--- a/js/src/jsapi-tests/testLookup.cpp +++ b/js/src/jsapi-tests/testLookup.cpp @@ -21,17 +21,17 @@ BEGIN_TEST(testLookup_bug522590) // This lookup must not return an internal function object. jsvalRoot r(cx); CHECK(JS_LookupProperty(cx, xobj, "f", r.addr())); CHECK(JSVAL_IS_OBJECT(r)); JSObject *funobj = JSVAL_TO_OBJECT(r); CHECK(funobj->isFunction()); CHECK(!js::IsInternalFunctionObject(funobj)); - CHECK(GET_FUNCTION_PRIVATE(cx, funobj) != (JSFunction *) funobj); + CHECK(funobj->getFunctionPrivate() != (JSFunction *) funobj); return true; } END_TEST(testLookup_bug522590) JSBool document_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp) {
--- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -338,17 +338,17 @@ JS_ConvertArgumentsVA(JSContext *cx, uin *sp = OBJECT_TO_JSVAL(obj); *va_arg(ap, JSObject **) = obj; break; case 'f': obj = js_ValueToFunctionObject(cx, Valueify(sp), 0); if (!obj) return JS_FALSE; *sp = OBJECT_TO_JSVAL(obj); - *va_arg(ap, JSFunction **) = GET_FUNCTION_PRIVATE(cx, obj); + *va_arg(ap, JSFunction **) = obj->getFunctionPrivate(); break; case 'v': *va_arg(ap, jsval *) = *sp; break; case '*': break; default: format--; @@ -2265,20 +2265,20 @@ JS_PrintTraceThingInfo(char *buf, size_t bufsize--; switch (kind) { case JSTRACE_OBJECT: { JSObject *obj = (JSObject *)thing; Class *clasp = obj->getClass(); if (clasp == &js_FunctionClass) { - JSFunction *fun = GET_FUNCTION_PRIVATE(trc->context, obj); + JSFunction *fun = obj->getFunctionPrivate(); if (!fun) { JS_snprintf(buf, bufsize, "<newborn>"); - } else if (FUN_OBJECT(fun) != obj) { + } else if (fun != obj) { JS_snprintf(buf, bufsize, "%p", fun); } else { if (fun->atom) PutEscapedString(buf, bufsize, fun->atom, 0); } } else if (clasp->flags & JSCLASS_HAS_PRIVATE) { JS_snprintf(buf, bufsize, "%p", obj->getPrivate()); } else { @@ -4203,18 +4203,18 @@ JS_CloneFunctionObject(JSContext *cx, JS * We cannot clone this object, so fail (we used to return funobj, bad * idea, but we changed incompatibly to teach any abusers a lesson!). */ Value v = ObjectValue(*funobj); js_ReportIsNotFunction(cx, &v, 0); return NULL; } - JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj); - if (!FUN_FLAT_CLOSURE(fun)) + JSFunction *fun = funobj->getFunctionPrivate(); + if (!fun->isFlatClosure()) return CloneFunctionObject(cx, fun, parent); /* * A flat closure carries its own environment, so why clone it? In case * someone wants to mutate its fixed slots or add ad-hoc properties. API * compatibility suggests we not return funobj and let callers mutate the * returned object at will. * @@ -4249,17 +4249,17 @@ JS_CloneFunctionObject(JSContext *cx, JS } return clone; } JS_PUBLIC_API(JSObject *) JS_GetFunctionObject(JSFunction *fun) { - return FUN_OBJECT(fun); + return fun; } JS_PUBLIC_API(JSString *) JS_GetFunctionId(JSFunction *fun) { return fun->atom; } @@ -4352,17 +4352,17 @@ JS_DefineFunctions(JSContext *cx, JSObje if (!fun) return JS_FALSE; /* * As jsapi.h notes, fs must point to storage that lives as long * as fun->object lives. */ Value priv = PrivateValue(fs); - if (!js_SetReservedSlot(cx, FUN_OBJECT(fun), 0, priv)) + if (!js_SetReservedSlot(cx, fun, 0, priv)) return JS_FALSE; } fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs, flags); if (!fun) return JS_FALSE; } return JS_TRUE; @@ -4707,68 +4707,66 @@ CompileUCFunctionForPrincipalsCommon(JSC CHECK_REQUEST(cx); assertSameCompartment(cx, obj, principals); if (!name) { funAtom = NULL; } else { funAtom = js_Atomize(cx, name, strlen(name)); if (!funAtom) { fun = NULL; - goto out2; + goto out; } } fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, obj, funAtom); if (!fun) - goto out2; + goto out; { EmptyShape *emptyCallShape = EmptyShape::getEmptyCallShape(cx); - if (!emptyCallShape) { + if (!emptyCallShape) fun = NULL; - goto out2; - } AutoShapeRooter shapeRoot(cx, emptyCallShape); - AutoObjectRooter tvr(cx, FUN_OBJECT(fun)); - MUST_FLOW_THROUGH("out"); + AutoObjectRooter tvr(cx, fun); Bindings bindings(cx, emptyCallShape); AutoBindingsRooter root(cx, bindings); for (i = 0; i < nargs; i++) { argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i])); if (!argAtom) { fun = NULL; - goto out2; + goto out; } uint16 dummy; if (!bindings.addArgument(cx, argAtom, &dummy)) { fun = NULL; - goto out2; + goto out; } } if (!Compiler::compileFunctionBody(cx, fun, principals, &bindings, chars, length, filename, lineno, version)) { fun = NULL; - goto out2; + goto out; } if (obj && funAtom && !obj->defineProperty(cx, ATOM_TO_JSID(funAtom), ObjectValue(*fun), NULL, NULL, JSPROP_ENUMERATE)) { fun = NULL; } } - out2: + out: LAST_FRAME_CHECKS(cx, fun); return fun; } + JS_PUBLIC_API(JSFunction *) JS_CompileUCFunctionForPrincipalsVersion(JSContext *cx, JSObject *obj, JSPrincipals *principals, const char *name, uintN nargs, const char **argnames, const jschar *chars, size_t length, const char *filename, uintN lineno, JSVersion version) { @@ -4887,17 +4885,17 @@ JS_DecompileFunctionBody(JSContext *cx, JS_PUBLIC_API(JSBool) JS_ExecuteScript(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval) { JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment); CHECK_REQUEST(cx); assertSameCompartment(cx, obj, scriptObj); - JSBool ok = ExternalExecute(cx, scriptObj->getScript(), *obj, Valueify(rval)); + JSBool ok = Execute(cx, scriptObj->getScript(), *obj, Valueify(rval)); LAST_FRAME_CHECKS(cx, ok); return ok; } JS_PUBLIC_API(JSBool) JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval, JSVersion version) { @@ -4921,17 +4919,17 @@ EvaluateUCScriptForPrincipalsCommon(JSCo : TCF_COMPILE_N_GO, chars, length, filename, lineno, compileVersion); if (!script) { LAST_FRAME_CHECKS(cx, script); return false; } JS_ASSERT(script->getVersion() == compileVersion); - bool ok = ExternalExecute(cx, script, *obj, Valueify(rval)); + bool ok = Execute(cx, script, *obj, Valueify(rval)); LAST_FRAME_CHECKS(cx, ok); js_DestroyScript(cx, script, 5); return ok; } JS_PUBLIC_API(JSBool) JS_EvaluateUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj, @@ -5001,18 +4999,18 @@ JS_EvaluateScript(JSContext *cx, JSObjec JS_PUBLIC_API(JSBool) JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc, jsval *argv, jsval *rval) { JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment); CHECK_REQUEST(cx); assertSameCompartment(cx, obj, fun, JSValueArray(argv, argc)); - JSBool ok = ExternalInvoke(cx, ObjectOrNullValue(obj), ObjectValue(*fun), argc, - Valueify(argv), Valueify(rval)); + JSBool ok = Invoke(cx, ObjectOrNullValue(obj), ObjectValue(*fun), argc, Valueify(argv), + Valueify(rval)); LAST_FRAME_CHECKS(cx, ok); return ok; } JS_PUBLIC_API(JSBool) JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc, jsval *argv, jsval *rval) { @@ -5020,62 +5018,61 @@ JS_CallFunctionName(JSContext *cx, JSObj CHECK_REQUEST(cx); assertSameCompartment(cx, obj, JSValueArray(argv, argc)); AutoValueRooter tvr(cx); JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSBool ok = atom && js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, tvr.addr()) && - ExternalInvoke(cx, ObjectOrNullValue(obj), tvr.value(), argc, Valueify(argv), - Valueify(rval)); + Invoke(cx, ObjectOrNullValue(obj), tvr.value(), argc, Valueify(argv), Valueify(rval)); LAST_FRAME_CHECKS(cx, ok); return ok; } JS_PUBLIC_API(JSBool) JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc, jsval *argv, jsval *rval) { JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment); CHECK_REQUEST(cx); assertSameCompartment(cx, obj, fval, JSValueArray(argv, argc)); - JSBool ok = ExternalInvoke(cx, ObjectOrNullValue(obj), Valueify(fval), argc, Valueify(argv), - Valueify(rval)); + JSBool ok = Invoke(cx, ObjectOrNullValue(obj), Valueify(fval), argc, Valueify(argv), + Valueify(rval)); LAST_FRAME_CHECKS(cx, ok); return ok; } namespace JS { JS_PUBLIC_API(bool) Call(JSContext *cx, jsval thisv, jsval fval, uintN argc, jsval *argv, jsval *rval) { JSBool ok; CHECK_REQUEST(cx); assertSameCompartment(cx, thisv, fval, JSValueArray(argv, argc)); - ok = ExternalInvoke(cx, Valueify(thisv), Valueify(fval), argc, Valueify(argv), Valueify(rval)); + ok = Invoke(cx, Valueify(thisv), Valueify(fval), argc, Valueify(argv), Valueify(rval)); LAST_FRAME_CHECKS(cx, ok); return ok; } } // namespace JS JS_PUBLIC_API(JSObject *) JS_New(JSContext *cx, JSObject *ctor, uintN argc, jsval *argv) { CHECK_REQUEST(cx); assertSameCompartment(cx, ctor, JSValueArray(argv, argc)); // This is not a simple variation of JS_CallFunctionValue because JSOP_NEW // is not a simple variation of JSOP_CALL. We have to determine what class // of object to create, create it, and clamp the return value to an object, - // among other details. js_InvokeConstructor does the hard work. + // among other details. InvokeConstructor does the hard work. InvokeArgsGuard args; if (!cx->stack.pushInvokeArgs(cx, argc, &args)) return NULL; args.calleev().setObject(*ctor); args.thisv().setNull(); memcpy(args.argv(), argv, argc * sizeof(jsval));
--- a/js/src/jsbuiltins.cpp +++ b/js/src/jsbuiltins.cpp @@ -305,17 +305,17 @@ JS_DEFINE_CALLINFO_2(extern, STRING, js_ JSObject* FASTCALL js_NewNullClosure(JSContext* cx, JSObject* funobj, JSObject* proto, JSObject* parent) { JS_ASSERT(funobj->isFunction()); JS_ASSERT(proto->isFunction()); JS_ASSERT(JS_ON_TRACE(cx)); JSFunction *fun = (JSFunction*) funobj; - JS_ASSERT(GET_FUNCTION_PRIVATE(cx, funobj) == fun); + JS_ASSERT(funobj->getFunctionPrivate() == fun); JSObject* closure = js_NewGCObject(cx, gc::FINALIZE_OBJECT2); if (!closure) return NULL; if (!closure->initSharingEmptyShape(cx, &js_FunctionClass, proto, parent, fun, gc::FINALIZE_OBJECT2)) { return NULL;
--- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -1078,17 +1078,17 @@ js_ReportMissingArg(JSContext *cx, const { char argbuf[11]; char *bytes; JSAtom *atom; JS_snprintf(argbuf, sizeof argbuf, "%u", arg); bytes = NULL; if (IsFunctionObject(v)) { - atom = GET_FUNCTION_PRIVATE(cx, &v.toObject())->atom; + atom = v.toObject().getFunctionPrivate()->atom; bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, atom); if (!bytes) return; } JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MISSING_FUN_ARG, argbuf, bytes ? bytes : "");
--- a/js/src/jscntxtinlines.h +++ b/js/src/jscntxtinlines.h @@ -344,17 +344,17 @@ CallJSPropertyOpSetter(JSContext *cx, js return op(cx, obj, id, strict, vp); } inline bool CallSetter(JSContext *cx, JSObject *obj, jsid id, js::StrictPropertyOp op, uintN attrs, uintN shortid, JSBool strict, js::Value *vp) { if (attrs & JSPROP_SETTER) - return ExternalGetOrSet(cx, obj, id, CastAsObjectJsval(op), JSACC_WRITE, 1, vp, vp); + return InvokeGetterOrSetter(cx, obj, CastAsObjectJsval(op), 1, vp, vp); if (attrs & JSPROP_GETTER) return js_ReportGetterOnlyAssignment(cx); if (attrs & JSPROP_SHORTID) id = INT_TO_JSID(shortid); return CallJSPropertyOpSetter(cx, op, obj, id, strict, vp); }
--- a/js/src/jsdbgapi.cpp +++ b/js/src/jsdbgapi.cpp @@ -543,17 +543,17 @@ extern JS_PUBLIC_API(void) JS_ReleaseFunctionLocalNameArray(JSContext *cx, void *mark) { JS_ARENA_RELEASE(&cx->tempPool, mark); } JS_PUBLIC_API(JSScript *) JS_GetFunctionScript(JSContext *cx, JSFunction *fun) { - return FUN_SCRIPT(fun); + return fun->maybeScript(); } JS_PUBLIC_API(JSNative) JS_GetFunctionNative(JSContext *cx, JSFunction *fun) { return Jsvalify(fun->maybeNative()); } @@ -1090,18 +1090,18 @@ GetAtomTotalSize(JSContext *cx, JSAtom * } JS_PUBLIC_API(size_t) JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun) { size_t nbytes; nbytes = sizeof *fun; - nbytes += JS_GetObjectTotalSize(cx, FUN_OBJECT(fun)); - if (FUN_INTERPRETED(fun)) + nbytes += JS_GetObjectTotalSize(cx, fun); + if (fun->isInterpreted()) nbytes += JS_GetScriptTotalSize(cx, fun->script()); if (fun->atom) nbytes += GetAtomTotalSize(cx, fun->atom); return nbytes; } #include "jsemit.h"
--- a/js/src/jsemit.cpp +++ b/js/src/jsemit.cpp @@ -4810,32 +4810,32 @@ js_EmitTree(JSContext *cx, JSCodeGenerat if (pn->pn_arity == PN_NULLARY) { if (js_Emit1(cx, cg, JSOP_GETFUNNS) < 0) return JS_FALSE; break; } #endif fun = pn->pn_funbox->function(); - JS_ASSERT(FUN_INTERPRETED(fun)); + JS_ASSERT(fun->isInterpreted()); if (fun->script()) { /* * This second pass is needed to emit JSOP_NOP with a source note * for the already-emitted function definition prolog opcode. See * comments in the TOK_LC case. */ JS_ASSERT(pn->pn_op == JSOP_NOP); JS_ASSERT(cg->inFunction()); if (!EmitFunctionDefNop(cx, cg, pn->pn_index)) return JS_FALSE; break; } JS_ASSERT_IF(pn->pn_funbox->tcflags & TCF_FUN_HEAVYWEIGHT, - FUN_KIND(fun) == JSFUN_INTERPRETED); + fun->kind() == JSFUN_INTERPRETED); /* Generate code for the function's body. */ void *cg2mark = JS_ARENA_MARK(cg->codePool); void *cg2space; JS_ARENA_ALLOCATE_TYPE(cg2space, JSCodeGenerator, cg->codePool); if (!cg2space) { js_ReportOutOfMemory(cx); return JS_FALSE; @@ -4908,17 +4908,17 @@ js_EmitTree(JSContext *cx, JSCodeGenerat * definitions can be scheduled before generating the rest of code. */ if (!cg->inFunction()) { JS_ASSERT(!cg->topStmt); if (!BindGlobal(cx, cg, pn, fun->atom)) return false; if (pn->pn_cookie.isFree()) { CG_SWITCH_TO_PROLOG(cg); - op = FUN_FLAT_CLOSURE(fun) ? JSOP_DEFFUN_FC : JSOP_DEFFUN; + op = fun->isFlatClosure() ? JSOP_DEFFUN_FC : JSOP_DEFFUN; EMIT_INDEX_OP(op, index); /* Make blockChain determination quicker. */ if (EmitBlockChain(cx, cg) < 0) return JS_FALSE; CG_SWITCH_TO_MAIN(cg); }
--- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -523,49 +523,49 @@ js_ErrorFromException(JSContext *cx, jsv return NULL; priv = GetExnPrivate(obj); if (!priv) return NULL; return priv->errorReport; } static JSString * -ValueToShortSource(JSContext *cx, jsval v) +ValueToShortSource(JSContext *cx, const Value &v) { JSString *str; /* Avoid toSource bloat and fallibility for object types. */ - if (JSVAL_IS_PRIMITIVE(v)) - return js_ValueToSource(cx, Valueify(v)); + if (!v.isObject()) + return js_ValueToSource(cx, v); - AutoCompartment ac(cx, JSVAL_TO_OBJECT(v)); + JSObject *obj = &v.toObject(); + AutoCompartment ac(cx, obj); if (!ac.enter()) return NULL; - if (VALUE_IS_FUNCTION(cx, v)) { + if (obj->isFunction()) { /* * XXX Avoid function decompilation bloat for now. */ - str = JS_GetFunctionId(JS_ValueToFunction(cx, v)); - if (!str && !(str = js_ValueToSource(cx, Valueify(v)))) { + str = JS_GetFunctionId(obj->getFunctionPrivate()); + if (!str && !(str = js_ValueToSource(cx, v))) { /* * Continue to soldier on if the function couldn't be * converted into a string. */ JS_ClearPendingException(cx); str = JS_NewStringCopyZ(cx, "[unknown function]"); } } else { /* * XXX Avoid toString on objects, it takes too long and uses too much * memory, for too many classes (see Mozilla bug 166743). */ char buf[100]; - JS_snprintf(buf, sizeof buf, "[object %s]", - JSVAL_TO_OBJECT(v)->getClass()->name); + JS_snprintf(buf, sizeof buf, "[object %s]", obj->getClass()->name); str = JS_NewStringCopyZ(cx, buf); } ac.leave(); if (!str || !cx->compartment->wrap(cx, &str)) return NULL; return str; @@ -633,17 +633,17 @@ StackTraceToString(JSContext *cx, JSExnP elem = priv->stackElems; for (endElem = elem + priv->stackDepth; elem != endElem; elem++) { if (elem->funName) { APPEND_STRING_TO_STACK(elem->funName); APPEND_CHAR_TO_STACK('('); for (i = 0; i != elem->argc; i++, values++) { if (i > 0) APPEND_CHAR_TO_STACK(','); - str = ValueToShortSource(cx, *values); + str = ValueToShortSource(cx, Valueify(*values)); if (!str) goto bad; APPEND_STRING_TO_STACK(str); } APPEND_CHAR_TO_STACK(')'); } APPEND_CHAR_TO_STACK('@'); if (elem->filename) {
--- a/js/src/jsexn.h +++ b/js/src/jsexn.h @@ -97,14 +97,16 @@ js_ErrorFromException(JSContext *cx, jsv extern const JSErrorFormatString * js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale, const uintN errorNumber); /* * Make a copy of errobj parented to scope. * * cx must be in the same compartment as scope. errobj may be in a different - * compartment, but it must be an Error object (not a wrapper of one). + * compartment, but it must be an Error object (not a wrapper of one) and it + * must not be one of the prototype objects created by js_InitExceptionClasses + * (errobj->getPrivate() must not be NULL). */ extern JSObject * js_CopyErrorObject(JSContext *cx, JSObject *errobj, JSObject *scope); #endif /* jsexn_h___ */
--- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -1246,18 +1246,19 @@ StackFrame::getValidCalleeObject(JSConte return true; } if (shape->hasSlot()) { Value v = thisp->getSlot(shape->slot); JSObject *clone; if (IsFunctionObject(v, &clone) && - GET_FUNCTION_PRIVATE(cx, clone) == fun && - clone->hasMethodObj(*thisp)) { + clone->getFunctionPrivate() == fun && + clone->hasMethodObj(*thisp)) + { JS_ASSERT(clone != &funobj); *vp = v; overwriteCallee(*clone); return true; } } } @@ -1539,18 +1540,18 @@ js_XDRFunctionObject(JSXDRState *xdr, JS JSFunction *fun; uint32 firstword; /* flag telling whether fun->atom is non-null, plus for fun->u.i.skipmin, fun->u.i.wrapper, and 14 bits reserved for future use */ uint32 flagsword; /* word for argument count and fun->flags */ cx = xdr->cx; if (xdr->mode == JSXDR_ENCODE) { - fun = GET_FUNCTION_PRIVATE(cx, *objp); - if (!FUN_INTERPRETED(fun)) { + fun = (*objp)->getFunctionPrivate(); + if (!fun->isInterpreted()) { JSAutoByteString funNameBytes; if (const char *name = GetFunctionNameBytes(cx, fun, &funNameBytes)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_SCRIPTED_FUNCTION, name); } return false; } if (fun->u.i.wrapper) { @@ -1561,21 +1562,21 @@ js_XDRFunctionObject(JSXDRState *xdr, JS } JS_ASSERT((fun->u.i.wrapper & ~1U) == 0); firstword = (fun->u.i.skipmin << 2) | (fun->u.i.wrapper << 1) | !!fun->atom; flagsword = (fun->nargs << 16) | fun->flags; } else { fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, NULL, NULL); if (!fun) return false; - FUN_OBJECT(fun)->clearParent(); - FUN_OBJECT(fun)->clearProto(); + fun->clearParent(); + fun->clearProto(); } - AutoObjectRooter tvr(cx, FUN_OBJECT(fun)); + AutoObjectRooter tvr(cx, fun); if (!JS_XDRUint32(xdr, &firstword)) return false; if ((firstword & 1U) && !js_XDRAtom(xdr, &fun->atom)) return false; if (!JS_XDRUint32(xdr, &flagsword)) return false; @@ -1592,17 +1593,17 @@ js_XDRFunctionObject(JSXDRState *xdr, JS * at the same time as we set the script's owner. */ JSScript *script = fun->u.i.script; if (!js_XDRScript(xdr, &script)) return false; fun->u.i.script = script; if (xdr->mode == JSXDR_DECODE) { - *objp = FUN_OBJECT(fun); + *objp = fun; fun->u.i.script->setOwnerObject(fun); #ifdef CHECK_SCRIPT_OWNER fun->script()->owner = NULL; #endif JS_ASSERT(fun->nargs == fun->script()->bindings.countArgs()); js_CallNewScriptHook(cx, fun->script(), fun); } @@ -1731,17 +1732,17 @@ fun_toStringHelper(JSContext *cx, JSObje return JSProxy::fun_toString(cx, obj, indent); JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, js_Function_str, js_toString_str, "object"); return NULL; } - JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj); + JSFunction *fun = obj->getFunctionPrivate(); if (!fun) return NULL; if (!indent && !cx->compartment->toSourceCache.empty()) { ToSourceCache::Ptr p = cx->compartment->toSourceCache.ref().lookup(fun); if (p) return p->value; } @@ -2024,17 +2025,17 @@ static JSBool fun_isGenerator(JSContext *cx, uintN argc, Value *vp) { JSObject *funobj; if (!IsFunctionObject(vp[1], &funobj)) { JS_SET_RVAL(cx, vp, BooleanValue(false)); return true; } - JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj); + JSFunction *fun = funobj->getFunctionPrivate(); bool result = false; if (fun->isInterpreted()) { JSScript *script = fun->script(); JS_ASSERT(script->length != 0); result = script->code[0] == JSOP_GENERATOR; } @@ -2434,17 +2435,17 @@ js_NewFunction(JSContext *cx, JSObject * fun->u.n.native = native; fun->u.n.trcinfo = NULL; } JS_ASSERT(fun->u.n.native); } fun->atom = atom; /* Set private to self to indicate non-cloned fully initialized function. */ - FUN_OBJECT(fun)->setPrivate(fun); + fun->setPrivate(fun); return fun; } JSObject * JS_FASTCALL js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent, JSObject *proto) { JS_ASSERT(parent); @@ -2648,17 +2649,17 @@ JS_STATIC_ASSERT((JSV2F_CONSTRUCT & JSV2 JSFunction * js_ValueToFunction(JSContext *cx, const Value *vp, uintN flags) { JSObject *funobj; if (!IsFunctionObject(*vp, &funobj)) { js_ReportIsNotFunction(cx, vp, flags); return NULL; } - return GET_FUNCTION_PRIVATE(cx, funobj); + return funobj->getFunctionPrivate(); } JSObject * js_ValueToFunctionObject(JSContext *cx, Value *vp, uintN flags) { JSObject *funobj; if (!IsFunctionObject(*vp, &funobj)) { js_ReportIsNotFunction(cx, vp, flags);
--- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -55,38 +55,38 @@ * or interpreted, and if interpreted, what kind of optimized closure form (if * any) it might be. * * 00 not interpreted * 01 interpreted, neither flat nor null closure * 10 interpreted, flat closure * 11 interpreted, null closure * - * FUN_FLAT_CLOSURE implies FUN_INTERPRETED and u.i.script->upvarsOffset != 0. - * FUN_NULL_CLOSURE implies FUN_INTERPRETED and u.i.script->upvarsOffset == 0. + * isFlatClosure() implies isInterpreted() and u.i.script->upvarsOffset != 0. + * isNullClosure() implies isInterpreted() and u.i.script->upvarsOffset == 0. * - * FUN_INTERPRETED but not FUN_FLAT_CLOSURE and u.i.script->upvarsOffset != 0 + * isInterpreted() but not isFlatClosure() and u.i.script->upvarsOffset != 0 * is an Algol-like function expression or nested function, i.e., a function * that never escapes upward or downward (heapward), and is only ever called. * - * Finally, FUN_INTERPRETED and u.i.script->upvarsOffset == 0 could be either + * Finally, isInterpreted() and u.i.script->upvarsOffset == 0 could be either * a non-closure (a global function definition, or any function that uses no * outer names), or a closure of an escaping function that uses outer names * whose values can't be snapshot (because the outer names could be reassigned * after the closure is formed, or because assignments could not be analyzed * due to with or eval). * * Such a hard-case function must use JSOP_NAME, etc., and reify outer function * activations' call objects, etc. if it's not a global function. * * NB: JSFUN_EXPR_CLOSURE reuses JSFUN_STUB_GSOPS, which is an API request flag * bit only, never stored in fun->flags. * - * If we need more bits in the future, all flags for FUN_INTERPRETED functions - * can move to u.i.script->flags. For now we use function flag bits to minimize + * If we need more bits in the future, all flags for interpreted functions can + * move to u.i.script->flags. For now we use function flag bits to minimize * pointer-chasing. */ #define JSFUN_JOINABLE 0x0001 /* function is null closure that does not appear to call itself via its own name or arguments.callee */ #define JSFUN_PROTOTYPE 0x0800 /* function is Function.prototype for some global object */ @@ -96,29 +96,16 @@ JSFunctionSpec::call points to a JSNativeTraceInfo. */ #define JSFUN_INTERPRETED 0x4000 /* use u.i if kind >= this value else u.n */ #define JSFUN_FLAT_CLOSURE 0x8000 /* flat (aka "display") closure */ #define JSFUN_NULL_CLOSURE 0xc000 /* null closure entrains no scope chain */ #define JSFUN_KINDMASK 0xc000 /* encode interp vs. native and closure optimization level -- see above */ -#define FUN_OBJECT(fun) (static_cast<JSObject *>(fun)) -#define FUN_KIND(fun) ((fun)->flags & JSFUN_KINDMASK) -#define FUN_SET_KIND(fun,k) ((fun)->flags = ((fun)->flags & ~JSFUN_KINDMASK) | (k)) -#define FUN_INTERPRETED(fun) (FUN_KIND(fun) >= JSFUN_INTERPRETED) -#define FUN_FLAT_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_FLAT_CLOSURE) -#define FUN_NULL_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_NULL_CLOSURE) -#define FUN_SCRIPT(fun) (FUN_INTERPRETED(fun) ? (fun)->script() : NULL) -#define FUN_CLASP(fun) (JS_ASSERT(!FUN_INTERPRETED(fun)), \ - fun->u.n.clasp) -#define FUN_TRCINFO(fun) (JS_ASSERT(!FUN_INTERPRETED(fun)), \ - JS_ASSERT((fun)->flags & JSFUN_TRCINFO), \ - fun->u.n.trcinfo) - struct JSFunction : public JSObject_Slots2 { /* Functions always have two fixed slots (FUN_CLASS_RESERVED_SLOTS). */ uint16 nargs; /* maximum number of specified arguments, reflected as f.length/f.arity */ uint16 flags; /* flags, see JSFUN_* below and in jsapi.h */ union U { @@ -140,26 +127,35 @@ struct JSFunction : public JSObject_Slot indirect eval; if true, then this function object's proto is the wrapped object */ js::Shape *names; /* argument and variable names */ } i; void *nativeOrScript; } u; JSAtom *atom; /* name for diagnostics and decompiling */ - bool optimizedClosure() const { return FUN_KIND(this) > JSFUN_INTERPRETED; } - bool isInterpreted() const { return FUN_INTERPRETED(this); } - bool isNative() const { return !FUN_INTERPRETED(this); } + bool optimizedClosure() const { return kind() > JSFUN_INTERPRETED; } + bool isInterpreted() const { return kind() >= JSFUN_INTERPRETED; } + bool isNative() const { return !isInterpreted(); } bool isConstructor() const { return flags & JSFUN_CONSTRUCTOR; } bool isHeavyweight() const { return JSFUN_HEAVYWEIGHT_TEST(flags); } - bool isFlatClosure() const { return FUN_KIND(this) == JSFUN_FLAT_CLOSURE; } + bool isNullClosure() const { return kind() == JSFUN_NULL_CLOSURE; } + bool isFlatClosure() const { return kind() == JSFUN_FLAT_CLOSURE; } bool isFunctionPrototype() const { return flags & JSFUN_PROTOTYPE; } bool isInterpretedConstructor() const { return isInterpreted() && !isFunctionPrototype(); } + + uint16 kind() const { return flags & JSFUN_KINDMASK; } + void setKind(uint16 k) { + JS_ASSERT(!(k & ~JSFUN_KINDMASK)); + flags = (flags & ~JSFUN_KINDMASK) | k; + } + /* Returns the strictness of this function, which must be interpreted. */ inline bool inStrictMode() const; + void setArgCount(uint16 nargs) { JS_ASSERT(this->nargs == 0); this->nargs = nargs; } /* uint16 representation bounds number of call object dynamic slots. */ enum { MAX_ARGS_AND_VARS = 2 * ((1U << 16) - 1) }; @@ -205,16 +201,20 @@ struct JSFunction : public JSObject_Slot inline void setMethodAtom(JSAtom *atom); JSScript *script() const { JS_ASSERT(isInterpreted()); return u.i.script; } + JSScript * maybeScript() const { + return isInterpreted() ? script() : NULL; + } + js::Native native() const { JS_ASSERT(isNative()); return u.n.native; } js::Native maybeNative() const { return isInterpreted() ? NULL : native(); } @@ -222,16 +222,33 @@ struct JSFunction : public JSObject_Slot static uintN offsetOfNativeOrScript() { JS_STATIC_ASSERT(offsetof(U, n.native) == offsetof(U, i.script)); JS_STATIC_ASSERT(offsetof(U, n.native) == offsetof(U, nativeOrScript)); return offsetof(JSFunction, u.nativeOrScript); } /* Number of extra fixed function object slots. */ static const uint32 CLASS_RESERVED_SLOTS = JSObject::FUN_CLASS_RESERVED_SLOTS; + + + js::Class *getConstructorClass() const { + JS_ASSERT(isNative()); + return u.n.clasp; + } + + void setConstructorClass(js::Class *clasp) { + JS_ASSERT(isNative()); + u.n.clasp = clasp; + } + + JSNativeTraceInfo *getTraceInfo() const { + JS_ASSERT(isNative()); + JS_ASSERT(flags & JSFUN_TRCINFO); + return u.n.trcinfo; + } }; /* * Trace-annotated native. This expands to a JSFunctionSpec initializer (like * JS_FN in jsapi.h). fastcall is a FastNative; trcinfo is a * JSNativeTraceInfo*. */ #ifdef JS_TRACER @@ -264,22 +281,16 @@ inline JSFunction * JSObject::getFunctionPrivate() const { JS_ASSERT(isFunction()); return reinterpret_cast<JSFunction *>(getPrivate()); } namespace js { -/* - * NB: jsapi.h and jsobj.h must be included before any call to this macro. - */ -#define VALUE_IS_FUNCTION(cx, v) \ - (!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isFunction()) - static JS_ALWAYS_INLINE bool IsFunctionObject(const js::Value &v) { return v.isObject() && v.toObject().isFunction(); } static JS_ALWAYS_INLINE bool IsFunctionObject(const js::Value &v, JSObject **funobj) @@ -350,24 +361,16 @@ extern JS_ALWAYS_INLINE bool SameTraceType(const Value &lhs, const Value &rhs) { return SameType(lhs, rhs) && (lhs.isPrimitive() || lhs.toObject().isFunction() == rhs.toObject().isFunction()); } /* - * Macro to access the private slot of the function object after the slot is - * initialized. - */ -#define GET_FUNCTION_PRIVATE(cx, funobj) \ - (JS_ASSERT((funobj)->isFunction()), \ - (JSFunction *) (funobj)->getPrivate()) - -/* * Return true if this is a compiler-created internal function accessed by * its own object. Such a function object must not be accessible to script * or embedding code. */ inline bool IsInternalFunctionObject(JSObject *funobj) { JS_ASSERT(funobj->isFunction());
--- a/js/src/jsfuninlines.h +++ b/js/src/jsfuninlines.h @@ -47,17 +47,17 @@ inline bool JSFunction::inStrictMode() const { return script()->strictModeCode; } inline void JSFunction::setJoinable() { - JS_ASSERT(FUN_INTERPRETED(this)); + JS_ASSERT(isInterpreted()); setSlot(METHOD_ATOM_SLOT, js::NullValue()); flags |= JSFUN_JOINABLE; } inline void JSFunction::setMethodAtom(JSAtom *atom) { JS_ASSERT(joinable());
--- a/js/src/jshashtable.h +++ b/js/src/jshashtable.h @@ -293,26 +293,35 @@ class HashTable : private AllocPolicy #ifdef DEBUG friend class js::ReentrancyGuard; mutable bool entered; uint64 mutationCount; #endif static const unsigned sMinSizeLog2 = 4; static const unsigned sMinSize = 1 << sMinSizeLog2; - static const unsigned sSizeLimit = JS_BIT(24); + static const unsigned sMaxInit = JS_BIT(23); + static const unsigned sMaxCapacity = JS_BIT(24); static const unsigned sHashBits = tl::BitSize<HashNumber>::result; static const uint8 sMinAlphaFrac = 64; /* (0x100 * .25) taken from jsdhash.h */ static const uint8 sMaxAlphaFrac = 192; /* (0x100 * .75) taken from jsdhash.h */ static const uint8 sInvMaxAlpha = 171; /* (ceil(0x100 / .75) >> 1) */ static const HashNumber sGoldenRatio = 0x9E3779B9U; /* taken from jsdhash.h */ static const HashNumber sFreeKey = Entry::sFreeKey; static const HashNumber sRemovedKey = Entry::sRemovedKey; static const HashNumber sCollisionBit = Entry::sCollisionBit; + static void staticAsserts() + { + /* Rely on compiler "constant overflow warnings". */ + JS_STATIC_ASSERT(((sMaxInit * sInvMaxAlpha) >> 7) < sMaxCapacity); + JS_STATIC_ASSERT((sMaxCapacity * sInvMaxAlpha) <= UINT32_MAX); + JS_STATIC_ASSERT((sMaxCapacity * sizeof(Entry)) <= UINT32_MAX); + } + static bool isLiveHash(HashNumber hash) { return Entry::isLiveHash(hash); } static HashNumber prepareHash(const Lookup& l) { HashNumber keyHash = HashPolicy::hash(l); @@ -360,34 +369,34 @@ class HashTable : private AllocPolicy { /* Make sure that init isn't called twice. */ JS_ASSERT(table == NULL); /* * Correct for sMaxAlphaFrac such that the table will not resize * when adding 'length' entries. */ - JS_ASSERT(length < (uint32(1) << 23)); + if (length > sMaxInit) { + this->reportAllocOverflow(); + return false; + } uint32 capacity = (length * sInvMaxAlpha) >> 7; if (capacity < sMinSize) capacity = sMinSize; /* FIXME: use JS_CEILING_LOG2 when PGO stops crashing (bug 543034). */ uint32 roundUp = sMinSize, roundUpLog2 = sMinSizeLog2; while (roundUp < capacity) { roundUp <<= 1; ++roundUpLog2; } capacity = roundUp; - if (capacity >= sSizeLimit) { - this->reportAllocOverflow(); - return false; - } + JS_ASSERT(capacity <= sMaxCapacity); table = createTable(*this, capacity); if (!table) return false; setTableSizeLog2(roundUpLog2); METER(memset(&stats, 0, sizeof(stats))); return true; @@ -531,17 +540,17 @@ class HashTable : private AllocPolicy bool changeTableSize(int deltaLog2) { /* Look, but don't touch, until we succeed in getting new entry store. */ Entry *oldTable = table; uint32 oldCap = tableCapacity; uint32 newLog2 = sHashBits - hashShift + deltaLog2; uint32 newCapacity = JS_BIT(newLog2); - if (newCapacity >= sSizeLimit) { + if (newCapacity > sMaxCapacity) { this->reportAllocOverflow(); return false; } Entry *newTable = createTable(*this, newCapacity); if (!newTable) return false;
--- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -507,17 +507,17 @@ Class js_NoSuchMethodClass = { no_such_method_trace /* trace */ }; /* * When JSOP_CALLPROP or JSOP_CALLELEM does not find the method property of * the base object, we search for the __noSuchMethod__ method in the base. * If it exists, we store the method and the property's id into an object of * NoSuchMethod class and store this object into the callee's stack slot. - * Later, js_Invoke will recognise such an object and transfer control to + * Later, Invoke will recognise such an object and transfer control to * NoSuchMethod that invokes the method like: * * this.__noSuchMethod__(id, args) * * where id is the name of the method that this invocation attempted to * call by name, and args is an Array containing this invocation's actual * parameters. */ @@ -616,17 +616,17 @@ RunScript(JSContext *cx, JSScript *scrip /* * Find a function reference and its 'this' value implicit first parameter * under argc arguments on cx's stack, and call the function. Push missing * required arguments, allocate declared local variables, and pop everything * when done. Then push the return value. */ JS_REQUIRES_STACK bool -Invoke(JSContext *cx, const CallArgs &argsRef, MaybeConstruct construct) +InvokeKernel(JSContext *cx, const CallArgs &argsRef, MaybeConstruct construct) { /* N.B. Must be kept in sync with InvokeSessionGuard::start/invoke */ CallArgs args = argsRef; JS_ASSERT(args.argc() <= StackSpace::ARGS_LENGTH_MAX); if (args.calleev().isPrimitive()) { js_ReportIsNotFunction(cx, &args.calleev(), ToReportFlags(construct)); @@ -776,18 +776,18 @@ InvokeSessionGuard::start(JSContext *cx, if (ifg_.pushed()) ifg_.pop(); formals_ = actuals_ = args_.argv(); nformals_ = (unsigned)-1; return true; } bool -ExternalInvoke(JSContext *cx, const Value &thisv, const Value &fval, - uintN argc, Value *argv, Value *rval) +Invoke(JSContext *cx, const Value &thisv, const Value &fval, uintN argc, Value *argv, + Value *rval) { LeaveTrace(cx); InvokeArgsGuard args; if (!cx->stack.pushInvokeArgs(cx, argc, &args)) return false; args.calleev() = fval; @@ -809,18 +809,17 @@ ExternalInvoke(JSContext *cx, const Valu if (!Invoke(cx, args)) return false; *rval = args.rval(); return true; } bool -ExternalInvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv, - Value *rval) +InvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv, Value *rval) { LeaveTrace(cx); InvokeArgsGuard args; if (!cx->stack.pushInvokeArgs(cx, argc, &args)) return false; args.calleev() = fval; @@ -830,28 +829,28 @@ ExternalInvokeConstructor(JSContext *cx, if (!InvokeConstructor(cx, args)) return false; *rval = args.rval(); return true; } bool -ExternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, const Value &fval, - JSAccessMode mode, uintN argc, Value *argv, Value *rval) +InvokeGetterOrSetter(JSContext *cx, JSObject *obj, const Value &fval, uintN argc, Value *argv, + Value *rval) { LeaveTrace(cx); /* - * ExternalInvoke could result in another try to get or set the same id - * again, see bug 355497. + * Invoke could result in another try to get or set the same id again, see + * bug 355497. */ JS_CHECK_RECURSION(cx, return false); - return ExternalInvoke(cx, ObjectValue(*obj), fval, argc, argv, rval); + return Invoke(cx, ObjectValue(*obj), fval, argc, argv, rval); } #if JS_HAS_SHARP_VARS JS_STATIC_ASSERT(SHARP_NSLOTS == 2); static JS_NEVER_INLINE bool InitSharpSlots(JSContext *cx, StackFrame *fp) { @@ -873,18 +872,18 @@ InitSharpSlots(JSContext *cx, StackFrame sharps[0].setUndefined(); sharps[1].setUndefined(); } return true; } #endif bool -Execute(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &thisv, - ExecuteType type, StackFrame *evalInFrame, Value *result) +ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &thisv, + ExecuteType type, StackFrame *evalInFrame, Value *result) { JS_ASSERT_IF(evalInFrame, type == EXECUTE_DEBUG); if (script->isEmpty()) { if (result) result->setUndefined(); return true; } @@ -914,17 +913,17 @@ Execute(JSContext *cx, JSScript *script, *result = fp->returnValue(); Probes::stopExecution(cx, script); return !!ok; } bool -ExternalExecute(JSContext *cx, JSScript *script, JSObject &scopeChainArg, Value *rval) +Execute(JSContext *cx, JSScript *script, JSObject &scopeChainArg, Value *rval) { /* The scope chain could be anything, so innerize just in case. */ JSObject *scopeChain = &scopeChainArg; OBJ_TO_INNER_OBJECT(cx, scopeChain); if (!scopeChain) return false; /* If we were handed a non-native object, complain bitterly. */ @@ -939,18 +938,18 @@ ExternalExecute(JSContext *cx, JSScript scopeChain->makeVarObj(); /* Use the scope chain as 'this', modulo outerization. */ JSObject *thisObj = scopeChain->thisObject(cx); if (!thisObj) return false; Value thisv = ObjectValue(*thisObj); - return Execute(cx, script, *scopeChain, thisv, EXECUTE_GLOBAL, - NULL /* evalInFrame */, rval); + return ExecuteKernel(cx, script, *scopeChain, thisv, EXECUTE_GLOBAL, + NULL /* evalInFrame */, rval); } bool CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs) { JSObject *obj2; JSProperty *prop; uintN oldAttrs; @@ -1185,17 +1184,17 @@ TypeOfValue(JSContext *cx, const Value & return JSTYPE_VOID; if (v.isObject()) return v.toObject().typeOf(cx); JS_ASSERT(v.isBoolean()); return JSTYPE_BOOLEAN; } JS_REQUIRES_STACK bool -InvokeConstructor(JSContext *cx, const CallArgs &argsRef) +InvokeConstructorKernel(JSContext *cx, const CallArgs &argsRef) { JS_ASSERT(!js_FunctionClass.construct); CallArgs args = argsRef; if (args.calleev().isObject()) { JSObject *callee = &args.callee(); Class *clasp = callee->getClass(); if (clasp == &js_FunctionClass) { @@ -1207,17 +1206,17 @@ InvokeConstructor(JSContext *cx, const C bool ok = CallJSNativeConstructor(cx, fun->u.n.native, args); Probes::calloutEnd(cx, fun); return ok; } if (!fun->isInterpretedConstructor()) goto error; - if (!Invoke(cx, args, CONSTRUCT)) + if (!InvokeKernel(cx, args, CONSTRUCT)) return false; JS_ASSERT(args.rval().isObject()); return true; } if (clasp->construct) { args.thisv().setMagicWithObjectOrNullPayload(NULL); return CallJSNativeConstructor(cx, clasp->construct, args); @@ -3981,17 +3980,17 @@ END_CASE(JSOP_ENUMELEM) BEGIN_CASE(JSOP_EVAL) { CallArgs args = CallArgsFromSp(GET_ARGC(regs.pc), regs.sp); if (IsBuiltinEvalForScope(®s.fp()->scopeChain(), args.calleev())) { if (!DirectEval(cx, args)) goto error; } else { - if (!Invoke(cx, args)) + if (!InvokeKernel(cx, args)) goto error; } CHECK_INTERRUPT_HANDLER(); regs.sp = args.spAfterCall(); } END_CASE(JSOP_EVAL) BEGIN_CASE(JSOP_NEW) @@ -4005,20 +4004,20 @@ BEGIN_CASE(JSOP_FUNAPPLY) MaybeConstruct construct = *regs.pc == JSOP_NEW ? CONSTRUCT : NO_CONSTRUCT; JSObject *callee; JSFunction *fun; /* Don't bother trying to fast-path calls to scripted non-constructors. */ if (!IsFunctionObject(args.calleev(), &callee, &fun) || !fun->isInterpretedConstructor()) { if (construct) { - if (!InvokeConstructor(cx, args)) + if (!InvokeConstructorKernel(cx, args)) goto error; } else { - if (!Invoke(cx, args)) + if (!InvokeKernel(cx, args)) goto error; } regs.sp = args.spAfterCall(); CHECK_INTERRUPT_HANDLER(); TRACE_0(NativeCallComplete); len = JSOP_CALL_LENGTH; DO_NEXT_OP(len); } @@ -4585,20 +4584,20 @@ BEGIN_CASE(JSOP_DEFFUN) /* * A top-level function defined in Global or Eval code (see ECMA-262 * Ed. 3), or else a SpiderMonkey extension: a named function statement in * a compound statement (not at the top statement level of global code, or * at the top level of a function body). */ JSFunction *fun; LOAD_FUNCTION(0); - JSObject *obj = FUN_OBJECT(fun); + JSObject *obj = fun; JSObject *obj2; - if (FUN_NULL_CLOSURE(fun)) { + if (fun->isNullClosure()) { /* * Even a null closure needs a parent for principals finding. * FIXME: bug 476950, although debugger users may also demand some kind * of scope link for debugger-assisted eval-in-frame. */ obj2 = ®s.fp()->scopeChain(); } else { JS_ASSERT(!fun->isFlatClosure()); @@ -4725,20 +4724,20 @@ BEGIN_CASE(JSOP_DEFLOCALFUN) * function), parented by the current scope chain, stored in a local * variable slot that the compiler allocated. This is an optimization over * JSOP_DEFFUN that avoids requiring a call object for the outer function's * activation. */ JSFunction *fun; LOAD_FUNCTION(SLOTNO_LEN); JS_ASSERT(fun->isInterpreted()); - JS_ASSERT(!FUN_FLAT_CLOSURE(fun)); - JSObject *obj = FUN_OBJECT(fun); - - if (FUN_NULL_CLOSURE(fun)) { + JS_ASSERT(!fun->isFlatClosure()); + JSObject *obj = fun; + + if (fun->isNullClosure()) { obj = CloneFunctionObject(cx, fun, ®s.fp()->scopeChain()); if (!obj) goto error; } else { JSObject *parent = GetScopeChainFast(cx, regs.fp(), JSOP_DEFLOCALFUN, JSOP_DEFLOCALFUN_LENGTH); if (!parent) goto error; @@ -4777,22 +4776,22 @@ BEGIN_CASE(JSOP_DEFLOCALFUN_FC) } END_CASE(JSOP_DEFLOCALFUN_FC) BEGIN_CASE(JSOP_LAMBDA) { /* Load the specified function object literal. */ JSFunction *fun; LOAD_FUNCTION(0); - JSObject *obj = FUN_OBJECT(fun); + JSObject *obj = fun; /* do-while(0) so we can break instead of using a goto. */ do { JSObject *parent; - if (FUN_NULL_CLOSURE(fun)) { + if (fun->isNullClosure()) { parent = ®s.fp()->scopeChain(); if (obj->getParent() == parent) { jsbytecode *pc2 = AdvanceOverBlockchainOp(regs.pc + JSOP_LAMBDA_LENGTH); JSOp op2 = JSOp(*pc2); /* * Optimize var obj = {method: function () { ... }, ...}, @@ -4840,17 +4839,17 @@ BEGIN_CASE(JSOP_LAMBDA) * Note that we have not yet pushed obj as the final argument, * so regs.sp[1 - (iargc + 2)], and not regs.sp[-(iargc + 2)], * is the callee for this JSOP_CALL. */ const Value &cref = regs.sp[1 - (iargc + 2)]; JSObject *callee; if (IsFunctionObject(cref, &callee)) { - JSFunction *calleeFun = GET_FUNCTION_PRIVATE(cx, callee); + JSFunction *calleeFun = callee->getFunctionPrivate(); if (Native native = calleeFun->maybeNative()) { if ((iargc == 1 && native == array_sort) || (iargc == 2 && native == str_replace)) { break; } } } } else if (op2 == JSOP_NULL) { @@ -6087,17 +6086,17 @@ END_CASE(JSOP_ARRAYPUSH) exit: interpReturnOK = ScriptEpilogueOrGeneratorYield(cx, regs.fp(), interpReturnOK); regs.fp()->setFinishedInInterpreter(); /* * At this point we are inevitably leaving an interpreted function or a * top-level script, and returning to one of: - * (a) an "out of line" call made through js_Invoke; + * (a) an "out of line" call made through Invoke; * (b) a js_Execute activation; * (c) a generator (SendToGenerator, jsiter.c). * * We must not be in an inline frame. The check above ensures that for the * error case and for a normal return, the code jumps directly to parent's * frame pc. */ JS_ASSERT(entryFrame == regs.fp());
--- a/js/src/jsinterp.h +++ b/js/src/jsinterp.h @@ -140,43 +140,54 @@ BoxNonStrictThis(JSContext *cx, const Ca * call represented by |fp|. ComputeThis is necessary because fp->thisValue() * may be set to 'undefined' when 'this' should really be the global object (as * an optimization to avoid global-this computation). */ inline bool ComputeThis(JSContext *cx, StackFrame *fp); /* - * The js::InvokeArgumentsGuard passed to js_Invoke must come from an - * immediately-enclosing successful call to js::StackSpace::pushInvokeArgs, - * i.e., there must have been no un-popped pushes to cx->stack. Furthermore, - * |args.getvp()[0]| should be the callee, |args.getvp()[1]| should be |this|, - * and the range [args.getvp() + 2, args.getvp() + 2 + args.getArgc()) should - * be initialized actual arguments. + * InvokeKernel assumes that the given args have been pushed on the top of the + * VM stack. Additionally, if 'args' is contained in a CallArgsList, that they + * have already been marked 'active'. */ extern bool -Invoke(JSContext *cx, const CallArgs &args, MaybeConstruct construct = NO_CONSTRUCT); +InvokeKernel(JSContext *cx, const CallArgs &args, MaybeConstruct construct = NO_CONSTRUCT); /* - * For calls to natives, the InvokeArgsGuard object provides a record of the - * call for the debugger's callstack. For this to work, the InvokeArgsGuard - * record needs to know when the call is actually active (because the - * InvokeArgsGuard can be pushed long before and popped long after the actual - * call, during which time many stack-observing things can happen). + * Invoke assumes that 'args' has been pushed (via ContextStack::pushInvokeArgs) + * and is currently at the top of the VM stack. */ inline bool Invoke(JSContext *cx, InvokeArgsGuard &args, MaybeConstruct construct = NO_CONSTRUCT) { args.setActive(); - bool ok = Invoke(cx, ImplicitCast<CallArgs>(args), construct); + bool ok = InvokeKernel(cx, args, construct); args.setInactive(); return ok; } /* + * This Invoke overload places the least requirements on the caller: it may be + * called at any time and it takes care of copying the given callee, this, and + * arguments onto the stack. + */ +extern bool +Invoke(JSContext *cx, const Value &thisv, const Value &fval, uintN argc, Value *argv, + Value *rval); + +/* + * This helper takes care of the infinite-recursion check necessary for + * getter/setter calls. + */ +extern bool +InvokeGetterOrSetter(JSContext *cx, JSObject *obj, const Value &fval, uintN argc, Value *argv, + Value *rval); + +/* * Natives like sort/forEach/replace call Invoke repeatedly with the same * callee, this, and number of arguments. To optimize this, such natives can * start an "invoke session" to factor out much of the dynamic setup logic * required by a normal Invoke. Usage is: * * InvokeSessionGuard session(cx); * if (!session.start(cx, callee, thisp, argc, &session)) * ... @@ -193,59 +204,57 @@ Invoke(JSContext *cx, InvokeArgsGuard &a * ... = session.rval(); * } * * // session ended by ~InvokeSessionGuard */ class InvokeSessionGuard; /* - * "External" calls may come from C or C++ code using a JSContext on which no - * JS is running (!cx->fp), so they may need to push a dummy StackFrame. + * InvokeConstructor* implement a function call from a constructor context + * (e.g. 'new') handling the the creation of the new 'this' object. */ +extern JS_REQUIRES_STACK bool +InvokeConstructorKernel(JSContext *cx, const CallArgs &args); +/* See the InvokeArgsGuard overload of Invoke. */ +inline bool +InvokeConstructor(JSContext *cx, InvokeArgsGuard &args) +{ + args.setActive(); + bool ok = InvokeConstructorKernel(cx, ImplicitCast<CallArgs>(args)); + args.setInactive(); + return ok; +} + +/* See the fval overload of Invoke. */ extern bool -ExternalInvoke(JSContext *cx, const Value &thisv, const Value &fval, - uintN argc, Value *argv, Value *rval); - -extern bool -ExternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, const Value &fval, - JSAccessMode mode, uintN argc, Value *argv, Value *rval); +InvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv, Value *rval); /* - * These two functions invoke a function called from a constructor context - * (e.g. 'new'). InvokeConstructor handles the general case where a new object - * needs to be created for/by the constructor. ConstructWithGivenThis directly - * calls the constructor with the given 'this', hence the caller must - * understand the semantics of the constructor call. + * InvokeConstructorWithGivenThis directly calls the constructor with the given + * 'this'; the caller must choose the semantically correct 'this'. */ - -extern JS_REQUIRES_STACK bool -InvokeConstructor(JSContext *cx, const CallArgs &args); - extern JS_REQUIRES_STACK bool InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fval, uintN argc, Value *argv, Value *rval); -extern bool -ExternalInvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv, - Value *rval); - -extern bool -ExternalExecute(JSContext *cx, JSScript *script, JSObject &scopeChain, Value *rval); - /* * Executes a script with the given scopeChain/this. The 'type' indicates * whether this is eval code or global code. To support debugging, the * evalFrame parameter can point to an arbitrary frame in the context's call * stack to simulate executing an eval in that frame. */ extern bool -Execute(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &thisv, - ExecuteType type, StackFrame *evalInFrame, Value *result); +ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &thisv, + ExecuteType type, StackFrame *evalInFrame, Value *result); + +/* Execute a script with the given scopeChain as global code. */ +extern bool +Execute(JSContext *cx, JSScript *script, JSObject &scopeChain, Value *rval); /* Flags to toggle js::Interpret() execution. */ enum InterpMode { JSINTERP_NORMAL = 0, /* interpreter is running normally */ JSINTERP_RECORD = 1, /* interpreter has been started to record/run traces */ JSINTERP_SAFEPOINT = 2, /* interpreter should leave on a method JIT safe point */ JSINTERP_PROFILE = 3 /* interpreter should profile a loop */
--- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -357,17 +357,17 @@ GetCustomIterator(JSContext *cx, JSObjec } if (!cx->runningWithTrustedPrincipals()) ++sCustomIteratorCount; /* Otherwise call it and return that object. */ LeaveTrace(cx); Value arg = BooleanValue((flags & JSITER_FOREACH) == 0); - if (!ExternalInvoke(cx, ObjectValue(*obj), *vp, 1, &arg, vp)) + if (!Invoke(cx, ObjectValue(*obj), *vp, 1, &arg, vp)) return false; if (vp->isPrimitive()) { /* * We are always coming from js_ValueToIterator, and we are no longer on * trace, so the object we are iterating over is on top of the stack (-1). */ JSAutoByteString bytes; if (!js_AtomToPrintableString(cx, atom, &bytes)) @@ -949,17 +949,17 @@ js_IteratorMore(JSContext *cx, JSObject /* We're reentering below and can call anything. */ JS_CHECK_RECURSION(cx, return false); /* Fetch and cache the next value from the iterator. */ if (!ni) { jsid id = ATOM_TO_JSID(cx->runtime->atomState.nextAtom); if (!js_GetMethod(cx, iterobj, id, JSGET_METHOD_BARRIER, rval)) return false; - if (!ExternalInvoke(cx, ObjectValue(*iterobj), *rval, 0, NULL, rval)) { + if (!Invoke(cx, ObjectValue(*iterobj), *rval, 0, NULL, rval)) { /* Check for StopIteration. */ if (!cx->isExceptionPending() || !js_ValueIsStopIteration(cx->getPendingException())) return false; cx->clearPendingException(); cx->iterValue.setMagic(JS_NO_ITER_VALUE); rval->setBoolean(false); return true;
--- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1186,17 +1186,16 @@ EvalKernel(JSContext *cx, const CallArgs * the eval code to use. */ if (!ComputeThis(cx, caller)) return false; thisv = caller->thisValue(); #ifdef DEBUG jsbytecode *callerPC = caller->pcQuadratic(cx); - JS_ASSERT_IF(caller->isFunctionFrame(), caller->fun()->isHeavyweight()); JS_ASSERT(callerPC && js_GetOpcode(cx, caller->script(), callerPC) == JSOP_EVAL); #endif } else { JS_ASSERT(call.callee().getGlobal() == &scopeobj); staticLevel = 0; /* Use the global as 'this', modulo outerization. */ JSObject *thisobj = scopeobj.thisObject(cx); @@ -1270,18 +1269,18 @@ EvalKernel(JSContext *cx, const CallArgs chars, length, filename, lineno, cx->findVersion(), linearStr, staticLevel); if (!compiled) return false; esg.setNewScript(compiled); } - return Execute(cx, esg.script(), scopeobj, thisv, ExecuteType(evalType), - NULL /* evalInFrame */, &call.rval()); + return ExecuteKernel(cx, esg.script(), scopeobj, thisv, ExecuteType(evalType), + NULL /* evalInFrame */, &call.rval()); } /* * We once supported a second argument to eval to use as the scope chain * when evaluating the code string. Warn when such uses are seen so that * authors will know that support for eval(s, o) has been removed. */ static inline bool @@ -1400,18 +1399,18 @@ obj_watch_handler(JSContext *cx, JSObjec } /* Avoid recursion on (obj, id) already being watched on cx. */ AutoResolving resolving(cx, obj, id, AutoResolving::WATCH); if (resolving.alreadyStarted()) return true; Value argv[] = { IdToValue(id), Valueify(old), Valueify(*nvp) }; - return ExternalInvoke(cx, ObjectValue(*obj), ObjectOrNullValue(callable), - JS_ARRAY_LENGTH(argv), argv, Valueify(nvp)); + return Invoke(cx, ObjectValue(*obj), ObjectOrNullValue(callable), JS_ARRAY_LENGTH(argv), argv, + Valueify(nvp)); } static JSBool obj_watch(JSContext *cx, uintN argc, Value *vp) { if (argc <= 1) { js_ReportMissingArg(cx, *vp, 1); return JS_FALSE; @@ -3914,29 +3913,29 @@ DefineConstructorAndPrototype(JSContext * because the constructor currently must have |obj| as its parent. * (FIXME: remove this dependency on the exact identity of the parent, * perhaps as part of bug 638316.) */ JSFunction *fun = js_NewFunction(cx, NULL, constructor, nargs, JSFUN_CONSTRUCTOR, obj, atom); if (!fun) goto bad; - FUN_CLASP(fun) = clasp; + fun->setConstructorClass(clasp); AutoValueRooter tvr2(cx, ObjectValue(*fun)); if (!DefineStandardSlot(cx, obj, key, atom, tvr2.value(), 0, named)) goto bad; /* * Optionally construct the prototype object, before the class has * been fully initialized. Allow the ctor to replace proto with a * different object, as is done for operator new -- and as at least * XML support requires. */ - ctor = FUN_OBJECT(fun); + ctor = fun; if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) { Value rval; if (!InvokeConstructorWithGivenThis(cx, proto, ObjectOrNullValue(ctor), 0, NULL, &rval)) { goto bad; } if (rval.isObject() && &rval.toObject() != proto) proto = &rval.toObject(); @@ -4704,17 +4703,17 @@ DefineNativeProperty(JSContext *cx, JSOb /* Add a new property, or replace an existing one of the same id. */ if (defineHow & DNP_SET_METHOD) { JS_ASSERT(clasp == &js_ObjectClass); JS_ASSERT(IsFunctionObject(value)); JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER))); JS_ASSERT(!getter && !setter); JSObject *funobj = &value.toObject(); - if (FUN_OBJECT(GET_FUNCTION_PRIVATE(cx, funobj)) == funobj) { + if (funobj->getFunctionPrivate() == funobj) { flags |= Shape::METHOD; getter = CastAsPropertyOp(funobj); } } if (const Shape *existingShape = obj->nativeLookup(id)) { if (existingShape->hasSlot()) AbortRecordingIfUnexpectedGlobalWrite(cx, obj, existingShape->slot); @@ -5444,17 +5443,17 @@ JSObject::reportNotExtensible(JSContext NULL, NULL, NULL); } bool JSObject::callMethod(JSContext *cx, jsid id, uintN argc, Value *argv, Value *vp) { Value fval; return js_GetMethod(cx, this, id, JSGET_NO_METHOD_BARRIER, &fval) && - ExternalInvoke(cx, ObjectValue(*this), fval, argc, argv, vp); + Invoke(cx, ObjectValue(*this), fval, argc, argv, vp); } JSBool js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow, Value *vp, JSBool strict) { JSObject *pobj; JSProperty *prop; @@ -5657,17 +5656,17 @@ js_SetPropertyHelper(JSContext *cx, JSOb * Check for Object class here to avoid defining a method on a class * with magic resolve, addProperty, getProperty, etc. hooks. */ if ((defineHow & DNP_SET_METHOD) && obj->canHaveMethodBarrier()) { JS_ASSERT(IsFunctionObject(*vp)); JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER))); JSObject *funobj = &vp->toObject(); - JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj); + JSFunction *fun = funobj->getFunctionPrivate(); if (fun == funobj) { flags |= Shape::METHOD; getter = CastAsPropertyOp(funobj); } } shape = obj->putProperty(cx, id, getter, setter, SHAPE_INVALID_SLOT, attrs, flags, shortid); @@ -5792,17 +5791,17 @@ js_DeleteProperty(JSContext *cx, JSObjec * We do not check suspended frames. They can't be reached via caller, * so the only way they could have the method's joined function object * as callee is through an API abusage. We break any such edge case. */ if (obj->hasMethodBarrier()) { JSObject *funobj; if (IsFunctionObject(v, &funobj)) { - JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj); + JSFunction *fun = funobj->getFunctionPrivate(); if (fun != funobj) { for (StackFrame *fp = cx->maybefp(); fp; fp = fp->prev()) { if (fp->isFunctionFrame() && fp->callee() == fun->compiledFunObj() && fp->thisValue().isObject()) { JSObject *tmp = &fp->thisValue().toObject(); @@ -5849,17 +5848,17 @@ static bool MaybeCallMethod(JSContext *cx, JSObject *obj, jsid id, Value *vp) { if (!js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, vp)) return false; if (!js_IsCallable(*vp)) { *vp = ObjectValue(*obj); return true; } - return ExternalInvoke(cx, ObjectValue(*obj), *vp, 0, NULL, vp); + return Invoke(cx, ObjectValue(*obj), *vp, 0, NULL, vp); } JSBool DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp) { JS_ASSERT(hint == JSTYPE_NUMBER || hint == JSTYPE_STRING || hint == JSTYPE_VOID); JS_ASSERT(!obj->isXML()); @@ -6487,17 +6486,17 @@ dumpValue(const Value &v) else if (v.isInt32()) fprintf(stderr, "%d", v.toInt32()); else if (v.isDouble()) fprintf(stderr, "%g", v.toDouble()); else if (v.isString()) dumpString(v.toString()); else if (v.isObject() && v.toObject().isFunction()) { JSObject *funobj = &v.toObject(); - JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj); + JSFunction *fun = funobj->getFunctionPrivate(); if (fun->atom) { fputs("<function ", stderr); FileEscapedString(stderr, fun->atom, 0); } else { fputs("<unnamed function", stderr); } if (fun->isInterpreted()) { JSScript *script = fun->script();
--- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -213,17 +213,17 @@ JSObject::methodReadBarrier(JSContext *c JS_ASSERT(shape.writable()); JS_ASSERT(shape.slot != SHAPE_INVALID_SLOT); JS_ASSERT(shape.hasDefaultSetter()); JS_ASSERT(!isGlobal()); /* i.e. we are not changing the global shape */ JSObject *funobj = &vp->toObject(); JSFunction *fun = funobj->getFunctionPrivate(); JS_ASSERT(fun == funobj); - JS_ASSERT(FUN_NULL_CLOSURE(fun)); + JS_ASSERT(fun->isNullClosure()); funobj = CloneFunctionObject(cx, fun, funobj->getParent()); if (!funobj) return NULL; funobj->setMethodObj(*this); /* * Replace the method property with an ordinary data property. This is @@ -545,17 +545,17 @@ JSObject::setFlatClosureUpvar(uint32 i, JS_ASSERT(i < getFunctionPrivate()->script()->bindings.countUpvars()); getFlatClosureUpvars()[i] = v; } inline void JSObject::setFlatClosureUpvars(js::Value *upvars) { JS_ASSERT(isFunction()); - JS_ASSERT(FUN_FLAT_CLOSURE(getFunctionPrivate())); + JS_ASSERT(getFunctionPrivate()->isFlatClosure()); setSlot(JSSLOT_FLAT_CLOSURE_UPVARS, PrivateValue(upvars)); } inline bool JSObject::hasMethodObj(const JSObject& obj) const { return JSSLOT_FUN_METHOD_OBJ < numSlots() && getSlot(JSSLOT_FUN_METHOD_OBJ).isObject() &&
--- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -391,17 +391,17 @@ ToDisassemblySource(JSContext *cx, jsval source = JS_sprintf_append(source, "}"); if (!source) return false; bytes->initBytes(source); return true; } if (clasp == &js_FunctionClass) { - JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj); + JSFunction *fun = obj->getFunctionPrivate(); JSString *str = JS_DecompileFunction(cx, fun, JS_DONT_PRETTY_PRINT); if (!str) return false; return bytes->encode(cx, str); } if (clasp == &js_RegExpClass) { AutoValueRooter tvr(cx); @@ -4967,17 +4967,17 @@ static const char native_code_str[] = "\ JSBool js_DecompileFunctionBody(JSPrinter *jp) { JSScript *script; JS_ASSERT(jp->fun); JS_ASSERT(!jp->script); - if (!FUN_INTERPRETED(jp->fun)) { + if (!jp->fun->isInterpreted()) { js_printf(jp, native_code_str); return JS_TRUE; } script = jp->fun->script(); return DecompileBody(jp, script, script->code); } @@ -5006,17 +5006,17 @@ js_DecompileFunction(JSPrinter *jp) js_puts(jp, "("); } js_printf(jp, "%s ", js_function_str); if (fun->atom && !QuoteString(&jp->sprinter, fun->atom, 0)) return JS_FALSE; js_puts(jp, "("); - if (!FUN_INTERPRETED(fun)) { + if (!fun->isInterpreted()) { js_printf(jp, ") {\n"); jp->indent += 4; js_printf(jp, native_code_str); jp->indent -= 4; js_printf(jp, "\t}"); } else { JSScript *script = fun->script(); #if JS_HAS_DESTRUCTURING
--- a/js/src/jsparse.cpp +++ b/js/src/jsparse.cpp @@ -308,17 +308,17 @@ Parser::newFunctionBox(JSObject *obj, JS if (tc->innermostWith) funbox->tcflags |= TCF_IN_WITH; return funbox; } bool JSFunctionBox::joinable() const { - return FUN_NULL_CLOSURE(function()) && + return function()->isNullClosure() && !(tcflags & (TCF_FUN_USES_ARGUMENTS | TCF_FUN_USES_OWN_NAME)); } bool JSFunctionBox::inAnyDynamicScope() const { for (const JSFunctionBox *funbox = this; funbox; funbox = funbox->parent) { if (funbox->tcflags & (TCF_IN_WITH | TCF_FUN_CALLS_EVAL)) @@ -985,17 +985,17 @@ Compiler::compileScript(JSContext *cx, J } if (callerFrame && callerFrame->isFunctionFrame()) { /* * An eval script in a caller frame needs to have its enclosing * function captured in case it refers to an upvar, and someone * wishes to decompile it while it's running. */ - JSObjectBox *funbox = parser.newObjectBox(FUN_OBJECT(callerFrame->fun())); + JSObjectBox *funbox = parser.newObjectBox(callerFrame->fun()); if (!funbox) goto out; funbox->emitLink = cg.objectList.lastbox; cg.objectList.lastbox = funbox; cg.objectList.length++; #ifdef DEBUG savedCallerFun = true; #endif @@ -1973,18 +1973,18 @@ Parser::newFunction(JSTreeContext *tc, J tc = tc->parent; JSObject *parent = tc->inFunction() ? NULL : tc->scopeChain(); JSFunction *fun = js_NewFunction(context, NULL, NULL, 0, JSFUN_INTERPRETED | (kind == Expression ? JSFUN_LAMBDA : 0), parent, atom); if (fun && !tc->compileAndGo()) { - FUN_OBJECT(fun)->clearParent(); - FUN_OBJECT(fun)->clearProto(); + fun->clearParent(); + fun->clearProto(); } return fun; } static JSBool MatchOrInsertSemicolon(JSContext *cx, TokenStream *ts) { TokenKind tt = ts->peekTokenSameLine(TSF_OPERAND); @@ -2456,22 +2456,22 @@ Parser::setFunctionKinds(JSFunctionBox * if (funbox->shouldUnbrand(methodSets, slowMethodSets)) funbox->tcflags |= TCF_FUN_UNBRAND_THIS; } } JSFunction *fun = funbox->function(); - JS_ASSERT(FUN_KIND(fun) == JSFUN_INTERPRETED); + JS_ASSERT(fun->kind() == JSFUN_INTERPRETED); if (funbox->tcflags & TCF_FUN_HEAVYWEIGHT) { /* nothing to do */ } else if (funbox->inAnyDynamicScope()) { - JS_ASSERT(!FUN_NULL_CLOSURE(fun)); + JS_ASSERT(!fun->isNullClosure()); } else if (pn->pn_type != TOK_UPVARS) { /* * No lexical dependencies => null closure, for best performance. * A null closure needs no scope chain, but alas we've coupled * principals-finding to scope (for good fundamental reasons, but * the implementation overloads the parent slot and we should fix * that). See, e.g., the JSOP_LAMBDA case in jsinterp.cpp. * @@ -2479,17 +2479,17 @@ Parser::setFunctionKinds(JSFunctionBox * * "joined function objects", or not, at its discretion. But real- * world implementations always create unique function objects for * closures, and this can be detected via mutation. Open question: * do popular implementations create unique function objects for * null closures? * * FIXME: bug 476950. */ - FUN_SET_KIND(fun, JSFUN_NULL_CLOSURE); + fun->setKind(JSFUN_NULL_CLOSURE); } else { AtomDefnMapPtr upvars = pn->pn_names; JS_ASSERT(!upvars->empty()); if (!fn->isFunArg()) { /* * This function is Algol-like, it never escapes. * @@ -2507,17 +2507,17 @@ Parser::setFunctionKinds(JSFunctionBox * if (!lexdep->isFreeVar()) { JS_ASSERT(lexdep->frameLevel() <= funbox->level); break; } } if (r.empty()) - FUN_SET_KIND(fun, JSFUN_NULL_CLOSURE); + fun->setKind(JSFUN_NULL_CLOSURE); } else { uintN nupvars = 0, nflattened = 0; /* * For each lexical dependency from this closure to an outer * binding, analyze whether it is safe to copy the binding's * value into a flat closure slot when the closure is formed. */ @@ -2545,23 +2545,23 @@ Parser::setFunctionKinds(JSFunctionBox * * closure. This is safe because we leave fun's kind * set to interpreted, so all functions holding its * upvars will be flagged as heavyweight. */ } } if (nupvars == 0) { - FUN_SET_KIND(fun, JSFUN_NULL_CLOSURE); + fun->setKind(JSFUN_NULL_CLOSURE); } else if (nflattened == nupvars) { /* * We made it all the way through the upvar loop, so it's * safe to optimize to a flat closure. */ - FUN_SET_KIND(fun, JSFUN_FLAT_CLOSURE); + fun->setKind(JSFUN_FLAT_CLOSURE); switch (PN_OP(fn)) { case JSOP_DEFFUN: fn->pn_op = JSOP_DEFFUN_FC; break; case JSOP_DEFLOCALFUN: fn->pn_op = JSOP_DEFLOCALFUN_FC; break; case JSOP_LAMBDA: @@ -2570,17 +2570,17 @@ Parser::setFunctionKinds(JSFunctionBox * default: /* js_EmitTree's case TOK_FUNCTION: will select op. */ JS_ASSERT(PN_OP(fn) == JSOP_NOP); } } } } - if (FUN_KIND(fun) == JSFUN_INTERPRETED && pn->pn_type == TOK_UPVARS) { + if (fun->kind() == JSFUN_INTERPRETED && pn->pn_type == TOK_UPVARS) { /* * One or more upvars cannot be safely snapshot into a flat * closure's non-reserved slot (see JSOP_GETFCSLOT), so we loop * again over all upvars, and for each non-free upvar, ensure that * its containing function has been flagged as heavyweight. * * The emitter must see TCF_FUN_HEAVYWEIGHT accurately before * generating any code for a tree of nested functions. @@ -2616,17 +2616,17 @@ Parser::setFunctionKinds(JSFunctionBox * * must have their OWN_SHAPE flags set; the comments for * js::Bindings::extensibleParents explain why. */ void Parser::markExtensibleScopeDescendants(JSFunctionBox *funbox, bool hasExtensibleParent) { for (; funbox; funbox = funbox->siblings) { /* - * It would be nice to use FUN_KIND(fun) here to recognize functions + * It would be nice to use fun->kind() here to recognize functions * that will never consult their parent chains, and thus don't need * their 'extensible parents' flag set. Filed as bug 619750. */ JS_ASSERT(!funbox->bindings.extensibleParents()); if (hasExtensibleParent) funbox->bindings.setExtensibleParents(); @@ -2658,17 +2658,17 @@ EnterFunction(JSParseNode *fn, JSTreeCon FunctionSyntaxKind kind = Expression) { JSTreeContext *tc = funtc->parent; JSFunction *fun = tc->parser->newFunction(tc, funAtom, kind); if (!fun) return NULL; /* Create box for fun->object early to protect against last-ditch GC. */ - JSFunctionBox *funbox = tc->parser->newFunctionBox(FUN_OBJECT(fun), fn, tc); + JSFunctionBox *funbox = tc->parser->newFunctionBox(fun, fn, tc); if (!funbox) return NULL; /* Initialize non-default members of funtc. */ funtc->flags |= funbox->tcflags; funtc->blockidGen = tc->blockidGen; if (!GenerateBlockId(funtc, funtc->bodyid)) return NULL;
--- a/js/src/jsprobes.cpp +++ b/js/src/jsprobes.cpp @@ -85,20 +85,20 @@ FunctionName(JSContext *cx, const JSFunc if (!atom) return Probes::anonymousName; return bytes->encode(cx, atom) ? bytes->ptr() : Probes::nullName; } static const char * FunctionClassname(const JSFunction *fun) { - if (!fun || FUN_INTERPRETED(fun)) + if (!fun || fun->isInterpreted()) return Probes::nullName; - if (!(fun->flags & JSFUN_TRCINFO) && FUN_CLASP(fun)) - return (char *)FUN_CLASP(fun)->name; + if (!(fun->flags & JSFUN_TRCINFO) && fun->getConstructorClass()) + return fun->getConstructorClass()->name; return Probes::nullName; } /* * These functions call the DTrace macros for the JavaScript USDT probes. * Originally this code was inlined in the JavaScript code; however since * a number of operations are called, these have been placed into functions * to reduce any negative compiler optimization effect that the addition of
--- a/js/src/jspropertycache.cpp +++ b/js/src/jspropertycache.cpp @@ -166,17 +166,17 @@ PropertyCache::fill(JSContext *cx, JSObj * obj with a new shape and set the JSObject::BRANDED flag. * Once this flag is set, any property assignment that * changes the value from or to a different function object * will result in shape being regenerated. */ if (!pobj->branded()) { PCMETER(brandfills++); #ifdef DEBUG_notme - JSFunction *fun = GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(v)); + JSFunction *fun = JSVAL_TO_OBJECT(v)->getFunctionPrivate(); JSAutoByteString funNameBytes; if (const char *funName = GetFunctionNameBytes(cx, fun, &funNameBytes)) { fprintf(stderr, "branding %p (%s) for funobj %p (%s), shape %lu\n", pobj, pobj->getClass()->name, JSVAL_TO_OBJECT(v), funName, obj->shape()); } #endif
--- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -124,20 +124,18 @@ JSProxyHandler::get(JSContext *cx, JSObj vp->setUndefined(); return true; } if (!desc.getter || (!(desc.attrs & JSPROP_GETTER) && desc.getter == PropertyStub)) { *vp = desc.value; return true; } - if (desc.attrs & JSPROP_GETTER) { - return ExternalGetOrSet(cx, receiver, id, CastAsObjectJsval(desc.getter), - JSACC_READ, 0, NULL, vp); - } + if (desc.attrs & JSPROP_GETTER) + return InvokeGetterOrSetter(cx, receiver, CastAsObjectJsval(desc.getter), 0, NULL, vp); if (!(desc.attrs & JSPROP_SHARED)) *vp = desc.value; else vp->setUndefined(); if (desc.attrs & JSPROP_SHORTID) id = INT_TO_JSID(desc.shortid); return CallJSPropertyOp(cx, desc.getter, receiver, id, vp); } @@ -270,32 +268,31 @@ JSProxyHandler::defaultValue(JSContext * return DefaultValue(cx, proxy, hint, vp); } bool JSProxyHandler::call(JSContext *cx, JSObject *proxy, uintN argc, Value *vp) { JS_ASSERT(OperationInProgress(cx, proxy)); AutoValueRooter rval(cx); - JSBool ok = ExternalInvoke(cx, vp[1], GetCall(proxy), argc, JS_ARGV(cx, vp), - rval.addr()); + JSBool ok = Invoke(cx, vp[1], GetCall(proxy), argc, JS_ARGV(cx, vp), rval.addr()); if (ok) JS_SET_RVAL(cx, vp, rval.value()); return ok; } bool JSProxyHandler::construct(JSContext *cx, JSObject *proxy, uintN argc, Value *argv, Value *rval) { JS_ASSERT(OperationInProgress(cx, proxy)); Value fval = GetConstruct(proxy); if (fval.isUndefined()) - return ExternalInvokeConstructor(cx, GetCall(proxy), argc, argv, rval); - return ExternalInvoke(cx, UndefinedValue(), fval, argc, argv, rval); + return InvokeConstructor(cx, GetCall(proxy), argc, argv, rval); + return Invoke(cx, UndefinedValue(), fval, argc, argv, rval); } bool JSProxyHandler::hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp) { JS_ASSERT(OperationInProgress(cx, proxy)); js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS, JSDVG_SEARCH_STACK, ObjectValue(*proxy), NULL); @@ -354,17 +351,17 @@ GetDerivedTrap(JSContext *cx, JSObject * atom == ATOM(iterate)); return GetTrap(cx, handler, atom, fvalp); } static bool Trap(JSContext *cx, JSObject *handler, Value fval, uintN argc, Value* argv, Value *rval) { - return ExternalInvoke(cx, ObjectValue(*handler), fval, argc, argv, rval); + return Invoke(cx, ObjectValue(*handler), fval, argc, argv, rval); } static bool Trap1(JSContext *cx, JSObject *handler, Value fval, jsid id, Value *rval) { JSString *str = js_ValueToString(cx, IdToValue(id)); if (!str) return false; @@ -1112,19 +1109,17 @@ proxy_Call(JSContext *cx, uintN argc, Va return JSProxy::call(cx, proxy, argc, vp); } JSBool proxy_Construct(JSContext *cx, uintN argc, Value *vp) { JSObject *proxy = &JS_CALLEE(cx, vp).toObject(); JS_ASSERT(proxy->isProxy()); - Value rval; - bool ok = JSProxy::construct(cx, proxy, argc, JS_ARGV(cx, vp), &rval); - *vp = rval; + bool ok = JSProxy::construct(cx, proxy, argc, JS_ARGV(cx, vp), vp); return ok; } JS_FRIEND_API(Class) FunctionProxyClass = { "Proxy", Class::NON_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(5), PropertyStub, /* addProperty */ PropertyStub, /* delProperty */ @@ -1310,19 +1305,17 @@ static const uint32 JSSLOT_CALLABLE_CONS static JSBool callable_Call(JSContext *cx, uintN argc, Value *vp) { JSObject *callable = &JS_CALLEE(cx, vp).toObject(); JS_ASSERT(callable->getClass() == &CallableObjectClass); const Value &fval = callable->getSlot(JSSLOT_CALLABLE_CALL); const Value &thisval = vp[1]; - Value rval; - bool ok = ExternalInvoke(cx, thisval, fval, argc, JS_ARGV(cx, vp), &rval); - *vp = rval; + bool ok = Invoke(cx, thisval, fval, argc, JS_ARGV(cx, vp), vp); return ok; } JSBool callable_Construct(JSContext *cx, uintN argc, Value *vp) { JSObject *thisobj = js_CreateThis(cx, &JS_CALLEE(cx, vp).toObject()); if (!thisobj) @@ -1350,30 +1343,28 @@ callable_Construct(JSContext *cx, uintN } JSObject *newobj = NewNativeClassInstance(cx, &js_ObjectClass, proto, proto->getParent()); if (!newobj) return false; /* If the call returns an object, return that, otherwise the original newobj. */ Value rval; - if (!ExternalInvoke(cx, ObjectValue(*newobj), callable->getSlot(JSSLOT_CALLABLE_CALL), - argc, vp + 2, &rval)) { + if (!Invoke(cx, ObjectValue(*newobj), callable->getSlot(JSSLOT_CALLABLE_CALL), + argc, vp + 2, &rval)) { return false; } if (rval.isPrimitive()) vp->setObject(*newobj); else *vp = rval; return true; } - Value rval; - bool ok = ExternalInvoke(cx, ObjectValue(*thisobj), fval, argc, vp + 2, &rval); - *vp = rval; + bool ok = Invoke(cx, ObjectValue(*thisobj), fval, argc, vp + 2, vp); return ok; } Class CallableObjectClass = { "Function", JSCLASS_HAS_RESERVED_SLOTS(2), PropertyStub, /* addProperty */ PropertyStub, /* delProperty */
--- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -226,87 +226,87 @@ class NodeBuilder private: bool callback(Value fun, TokenPos *pos, Value *dst) { if (saveLoc) { Value loc; if (!newNodeLoc(pos, &loc)) return false; Value argv[] = { loc }; - return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); + return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); } Value argv[] = { NullValue() }; /* no zero-length arrays allowed! */ - return ExternalInvoke(cx, userv, fun, 0, argv, dst); + return Invoke(cx, userv, fun, 0, argv, dst); } bool callback(Value fun, Value v1, TokenPos *pos, Value *dst) { if (saveLoc) { Value loc; if (!newNodeLoc(pos, &loc)) return false; Value argv[] = { v1, loc }; - return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); + return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); } Value argv[] = { v1 }; - return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); + return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); } bool callback(Value fun, Value v1, Value v2, TokenPos *pos, Value *dst) { if (saveLoc) { Value loc; if (!newNodeLoc(pos, &loc)) return false; Value argv[] = { v1, v2, loc }; - return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); + return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); } Value argv[] = { v1, v2 }; - return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); + return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); } bool callback(Value fun, Value v1, Value v2, Value v3, TokenPos *pos, Value *dst) { if (saveLoc) { Value loc; if (!newNodeLoc(pos, &loc)) return false; Value argv[] = { v1, v2, v3, loc }; - return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); + return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); } Value argv[] = { v1, v2, v3 }; - return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); + return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); } bool callback(Value fun, Value v1, Value v2, Value v3, Value v4, TokenPos *pos, Value *dst) { if (saveLoc) { Value loc; if (!newNodeLoc(pos, &loc)) return false; Value argv[] = { v1, v2, v3, v4, loc }; - return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); + return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); } Value argv[] = { v1, v2, v3, v4 }; - return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); + return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); } bool callback(Value fun, Value v1, Value v2, Value v3, Value v4, Value v5, TokenPos *pos, Value *dst) { if (saveLoc) { Value loc; if (!newNodeLoc(pos, &loc)) return false; Value argv[] = { v1, v2, v3, v4, v5, loc }; - return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); + return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); } Value argv[] = { v1, v2, v3, v4, v5 }; - return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); + return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst); } Value opt(Value v) { JS_ASSERT_IF(v.isMagic(), v.whyMagic() == JS_SERIALIZE_NO_NODE); return v.isMagic(JS_SERIALIZE_NO_NODE) ? UndefinedValue() : v; } bool atomValue(const char *s, Value *dst) {
--- a/js/src/jsscopeinlines.h +++ b/js/src/jsscopeinlines.h @@ -262,17 +262,17 @@ inline bool Shape::get(JSContext* cx, JSObject *receiver, JSObject* obj, JSObject *pobj, js::Value* vp) const { JS_ASSERT(!JSID_IS_VOID(propid)); JS_ASSERT(!hasDefaultGetter()); if (hasGetterValue()) { JS_ASSERT(!isMethod()); js::Value fval = getterValue(); - return js::ExternalGetOrSet(cx, receiver, propid, fval, JSACC_READ, 0, 0, vp); + return js::InvokeGetterOrSetter(cx, receiver, fval, 0, 0, vp); } if (isMethod()) { vp->setObject(methodObject()); return pobj->methodReadBarrier(cx, *this, vp); } /* @@ -286,17 +286,17 @@ Shape::get(JSContext* cx, JSObject *rece inline bool Shape::set(JSContext* cx, JSObject* obj, bool strict, js::Value* vp) const { JS_ASSERT_IF(hasDefaultSetter(), hasGetterValue()); if (attrs & JSPROP_SETTER) { js::Value fval = setterValue(); - return js::ExternalGetOrSet(cx, obj, propid, fval, JSACC_WRITE, 1, vp, vp); + return js::InvokeGetterOrSetter(cx, obj, fval, 1, vp, vp); } if (attrs & JSPROP_GETTER) return js_ReportGetterOnlyAssignment(cx); /* See the comment in js::Shape::get as to why we check for With. */ if (obj->getClass() == &js_WithClass) obj = js_UnwrapWithObject(cx, obj);
--- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1229,17 +1229,17 @@ JSScript::NewScriptFromCG(JSContext *cx, } script->bindings.transfer(cx, &cg->bindings); fun = NULL; if (cg->inFunction()) { /* * We initialize fun->u.i.script to be the script constructed above - * so that the debugger has a valid FUN_SCRIPT(fun). + * so that the debugger has a valid fun->script(). */ fun = cg->fun(); JS_ASSERT(fun->isInterpreted()); JS_ASSERT(!fun->script()); #ifdef DEBUG if (JSScript::isValidOffset(script->upvarsOffset)) JS_ASSERT(script->upvars()->length == script->bindings.countUpvars()); else
--- a/js/src/jsscriptinlines.h +++ b/js/src/jsscriptinlines.h @@ -115,17 +115,17 @@ CurrentScriptFileAndLine(JSContext *cx, inline JSFunction * JSScript::getFunction(size_t index) { JSObject *funobj = getObject(index); JS_ASSERT(funobj->isFunction()); JS_ASSERT(funobj == (JSObject *) funobj->getPrivate()); JSFunction *fun = (JSFunction *) funobj; - JS_ASSERT(FUN_INTERPRETED(fun)); + JS_ASSERT(fun->isInterpreted()); return fun; } inline JSFunction * JSScript::getCallerFunction() { JS_ASSERT(savedCallerFun); return getFunction(0);
--- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -3499,17 +3499,17 @@ js_ValueToSource(JSContext *cx, const Va } Value rval = NullValue(); Value fval; jsid id = ATOM_TO_JSID(cx->runtime->atomState.toSourceAtom); if (!js_GetMethod(cx, &v.toObject(), id, JSGET_NO_METHOD_BARRIER, &fval)) return false; if (js_IsCallable(fval)) { - if (!ExternalInvoke(cx, v, fval, 0, NULL, &rval)) + if (!Invoke(cx, v, fval, 0, NULL, &rval)) return false; } return js_ValueToString(cx, rval); } namespace js {
--- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -2805,17 +2805,17 @@ ValueToNative(const Value &v, JSValueTyp case JSVAL_TYPE_MAGIC: JS_ASSERT(v.isMagic()); debug_only_print0(LC_TMTracer, "hole "); return; case JSVAL_TYPE_FUNOBJ: { JS_ASSERT(IsFunctionObject(v)); - JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &v.toObject()); + JSFunction* fun = v.toObject().getFunctionPrivate(); #if defined JS_JIT_SPEW if (LogController.lcbits & LC_TMTracer) { char funName[40]; if (fun->atom) JS_PutEscapedFlatString(funName, sizeof funName, fun->atom, 0); else strcpy(funName, "unnamed"); LogController.printf("function<%p:%s> ", (void*)*(JSObject **)slot, funName); @@ -3104,17 +3104,17 @@ NativeToValue(JSContext* cx, Value& v, J break; case JSVAL_TYPE_MAGIC: debug_only_printf(LC_TMTracer, "magic<%d> ", v.whyMagic()); break; case JSVAL_TYPE_FUNOBJ: JS_ASSERT(IsFunctionObject(v)); #if defined JS_JIT_SPEW if (LogController.lcbits & LC_TMTracer) { - JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &v.toObject()); + JSFunction* fun = v.toObject().getFunctionPrivate(); char funName[40]; if (fun->atom) JS_PutEscapedFlatString(funName, sizeof funName, fun->atom, 0); else strcpy(funName, "unnamed"); LogController.printf("function<%p:%s> ", (void*) &v.toObject(), funName); } #endif @@ -3380,17 +3380,17 @@ GetUpvarOnTrace(JSContext* cx, uint32 up FrameInfo* fi = *fip; /* * The loop starts aligned to the top of the stack, so move down to the first meaningful * callee. Then read the callee directly from the frame. */ stackOffset -= fi->callerHeight; JSObject* callee = *(JSObject**)(&state->stackBase[stackOffset]); - JSFunction* fun = GET_FUNCTION_PRIVATE(cx, callee); + JSFunction* fun = callee->getFunctionPrivate(); uintN calleeLevel = fun->script()->staticLevel; if (calleeLevel == upvarLevel) { /* * Now find the upvar's value in the native stack. stackOffset is * the offset of the start of the activation record corresponding * to *fip in the native stack. */ uint32 native_slot = T::native_slot(fi->callerArgc, slot); @@ -10536,17 +10536,17 @@ TraceRecorder::record_JSOP_LEAVEWITH() { return ARECORD_STOP; } static JSBool JS_FASTCALL functionProbe(JSContext *cx, JSFunction *fun, int enter) { #ifdef MOZ_TRACE_JSCALLS - JSScript *script = fun ? FUN_SCRIPT(fun) : NULL; + JSScript *script = fun ? fun->maybeScript() : NULL; if (enter > 0) Probes::enterJSFun(cx, fun, script, enter); else Probes::exitJSFun(cx, fun, script, enter); #endif return true; } @@ -11006,17 +11006,17 @@ TraceRecorder::record_JSOP_OBJTOP() return ARECORD_CONTINUE; } RecordingStatus TraceRecorder::getClassPrototype(JSObject* ctor, LIns*& proto_ins) { // ctor must be a function created via js_InitClass. #ifdef DEBUG - Class *clasp = FUN_CLASP(GET_FUNCTION_PRIVATE(cx, ctor)); + Class *clasp = ctor->getFunctionPrivate()->getConstructorClass(); JS_ASSERT(clasp); TraceMonitor &localtm = *traceMonitor; #endif Value pval; if (!ctor->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom), &pval)) RETURN_ERROR("error getting prototype from constructor"); @@ -11548,17 +11548,17 @@ TraceRecorder::callNative(uintN argc, JS pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK; return RECORD_CONTINUE; } } break; } if (fun->flags & JSFUN_TRCINFO) { - JSNativeTraceInfo *trcinfo = FUN_TRCINFO(fun); + JSNativeTraceInfo *trcinfo = fun->getTraceInfo(); JS_ASSERT(trcinfo && fun->u.n.native == trcinfo->native); /* Try to call a type specialized version of the native. */ if (trcinfo->specializations) { RecordingStatus status = callSpecializedNative(trcinfo, argc, mode == JSOP_NEW); if (status != RECORD_STOP) return status; } @@ -11703,28 +11703,28 @@ TraceRecorder::functionCall(uintN argc, * or JSOP_CALLPROP that callee is a *particular* function, since these hit * the property cache and guard on the object (this) in which the callee * was found. So it's sufficient to test here that the particular function * is interpreted, not guard on that condition. * * Bytecode sequences that push shapeless callees must guard on the callee * class being Function and the function being interpreted. */ - JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &fval.toObject()); + JSFunction* fun = fval.toObject().getFunctionPrivate(); if (Probes::callTrackingActive(cx)) { - JSScript *script = FUN_SCRIPT(fun); + JSScript *script = fun->maybeScript(); if (!script || !script->isEmpty()) { LIns* args[] = { w.immi(1), w.nameImmpNonGC(fun), cx_ins }; LIns* call_ins = w.call(&functionProbe_ci, args); guard(false, w.eqi0(call_ins), MISMATCH_EXIT); } } - if (FUN_INTERPRETED(fun)) + if (fun->isInterpreted()) return interpretedFunctionCall(fval, fun, argc, mode == JSOP_NEW); Native native = fun->maybeNative(); Value* argv = &tval + 1; if (native == js_Array) return newArray(&fval.toObject(), argc, argv, &fval); if (native == js_String && argc == 1) { if (mode == JSOP_NEW) @@ -13612,17 +13612,18 @@ TraceRecorder::guardCallee(Value& callee * after, or vice versa. The function must escape, i.e., be a "funarg", or * else there's no need to guard callee parent at all. So once we know (by * static analysis) that a function may escape, we cannot avoid guarding on * either the private data of the Call object or the Call object itself, if * we wish to optimize for the particular deactivated stack frame (null * private data) case as noted above. */ if (callee_fun->isInterpreted() && - (!FUN_NULL_CLOSURE(callee_fun) || callee_fun->script()->bindings.hasUpvars())) { + (!callee_fun->isNullClosure() || callee_fun->script()->bindings.hasUpvars())) + { JSObject* parent = callee_obj.getParent(); if (parent != globalObj) { if (!parent->isCall()) RETURN_STOP("closure scoped by neither the global object nor a Call object"); guard(true, w.eqp(w.ldpObjParent(callee_ins), w.immpObjGC(parent)), @@ -13814,18 +13815,18 @@ TraceRecorder::record_JSOP_FUNAPPLY() JS_ASSERT(!cx->fp()->hasImacropc()); if (!IsFunctionObject(vp[0])) return record_JSOP_CALL(); RETURN_IF_XML_A(vp[0]); JSObject* obj = &vp[0].toObject(); - JSFunction* fun = GET_FUNCTION_PRIVATE(cx, obj); - if (FUN_INTERPRETED(fun)) + JSFunction* fun = obj->getFunctionPrivate(); + if (fun->isInterpreted()) return record_JSOP_CALL(); bool apply = fun->u.n.native == js_fun_apply; if (!apply && fun->u.n.native != js_fun_call) return record_JSOP_CALL(); /* * We don't trace apply and call with a primitive 'this', which is the @@ -15417,44 +15418,44 @@ TraceRecorder::getFullIndex(ptrdiff_t pc } JS_REQUIRES_STACK AbortableRecordingStatus TraceRecorder::record_JSOP_LAMBDA() { JSFunction* fun; fun = cx->fp()->script()->getFunction(getFullIndex()); - if (FUN_NULL_CLOSURE(fun) && FUN_OBJECT(fun)->getParent() != globalObj) + if (fun->isNullClosure() && fun->getParent() != globalObj) RETURN_STOP_A("Null closure function object parent must be global object"); /* * Emit code to clone a null closure parented by this recorder's global * object, in order to preserve function object evaluation rules observable * via identity and mutation. But don't clone if our result is consumed by * JSOP_SETMETHOD or JSOP_INITMETHOD, since we optimize away the clone for * these combinations and clone only if the "method value" escapes. * * See jsinterp.cpp, the JSOP_LAMBDA null closure case. The JSOP_SETMETHOD and * JSOP_INITMETHOD logic governing the early ARECORD_CONTINUE returns below * must agree with the corresponding break-from-do-while(0) logic there. */ - if (FUN_NULL_CLOSURE(fun) && FUN_OBJECT(fun)->getParent() == &cx->fp()->scopeChain()) { + if (fun->isNullClosure() && fun->getParent() == &cx->fp()->scopeChain()) { jsbytecode *pc2 = AdvanceOverBlockchainOp(cx->regs().pc + JSOP_LAMBDA_LENGTH); JSOp op2 = JSOp(*pc2); if (op2 == JSOP_INITMETHOD) { - stack(0, w.immpObjGC(FUN_OBJECT(fun))); + stack(0, w.immpObjGC(fun)); return ARECORD_CONTINUE; } if (op2 == JSOP_SETMETHOD) { Value lval = stackval(-1); if (!lval.isPrimitive() && lval.toObject().canHaveMethodBarrier()) { - stack(0, w.immpObjGC(FUN_OBJECT(fun))); + stack(0, w.immpObjGC(fun)); return ARECORD_CONTINUE; } } else if (fun->joinable()) { if (op2 == JSOP_CALL) { /* * Array.prototype.sort and String.prototype.replace are * optimized as if they are special form. We know that they * won't leak the joined function object in obj, therefore @@ -15472,36 +15473,39 @@ TraceRecorder::record_JSOP_LAMBDA() JSObject *callee; if (IsFunctionObject(cref, &callee)) { JSFunction *calleeFun = callee->getFunctionPrivate(); Native native = calleeFun->maybeNative(); if ((iargc == 1 && native == array_sort) || (iargc == 2 && native == str_replace)) { - stack(0, w.immpObjGC(FUN_OBJECT(fun))); + stack(0, w.immpObjGC(fun)); return ARECORD_CONTINUE; } } } else if (op2 == JSOP_NULL) { pc2 += JSOP_NULL_LENGTH; op2 = JSOp(*pc2); if (op2 == JSOP_CALL && GET_ARGC(pc2) == 0) { - stack(0, w.immpObjGC(FUN_OBJECT(fun))); + stack(0, w.immpObjGC(fun)); return ARECORD_CONTINUE; } } } LIns *proto_ins; CHECK_STATUS_A(getClassPrototype(JSProto_Function, proto_ins)); LIns* args[] = { w.immpObjGC(globalObj), proto_ins, w.immpFunGC(fun), cx_ins }; LIns* x = w.call(&js_NewNullClosure_ci, args); + guard(false, + w.name(w.eqp0(x), "guard(js_NewNullClosure_ci)"), + OOM_EXIT); stack(0, x); return ARECORD_CONTINUE; } if (GetBlockChainFast(cx, cx->fp(), JSOP_LAMBDA, JSOP_LAMBDA_LENGTH)) RETURN_STOP_A("Unable to trace creating lambda in let"); LIns *proto_ins; @@ -15519,17 +15523,17 @@ TraceRecorder::record_JSOP_LAMBDA() } JS_REQUIRES_STACK AbortableRecordingStatus TraceRecorder::record_JSOP_LAMBDA_FC() { JSFunction* fun; fun = cx->fp()->script()->getFunction(getFullIndex()); - if (FUN_OBJECT(fun)->getParent() != globalObj) + if (fun->getParent() != globalObj) return ARECORD_STOP; if (GetBlockChainFast(cx, cx->fp(), JSOP_LAMBDA_FC, JSOP_LAMBDA_FC_LENGTH)) RETURN_STOP_A("Unable to trace creating lambda in let"); LIns* args[] = { scopeChain(), w.immpFunGC(fun), cx_ins }; LIns* closure_ins = w.call(&js_AllocFlatClosure_ci, args); guard(false, @@ -15667,19 +15671,19 @@ TraceRecorder::record_JSOP_ARGCNT() } stack(0, w.immd(fp->numActualArgs())); return ARECORD_CONTINUE; } JS_REQUIRES_STACK AbortableRecordingStatus TraceRecorder::record_DefLocalFunSetSlot(uint32 slot, JSObject* obj) { - JSFunction* fun = GET_FUNCTION_PRIVATE(cx, obj); - - if (FUN_NULL_CLOSURE(fun) && FUN_OBJECT(fun)->getParent() == globalObj) { + JSFunction* fun = obj->getFunctionPrivate(); + + if (fun->isNullClosure() && fun->getParent() == globalObj) { LIns *proto_ins; CHECK_STATUS_A(getClassPrototype(JSProto_Function, proto_ins)); LIns* args[] = { w.immpObjGC(globalObj), proto_ins, w.immpFunGC(fun), cx_ins }; LIns* x = w.call(&js_NewNullClosure_ci, args); var(slot, x); return ARECORD_CONTINUE; } @@ -16007,17 +16011,17 @@ TraceRecorder::record_JSOP_CALLPROP() PCVal pcval; CHECK_STATUS_A(test_property_cache(obj, obj_ins, obj2, pcval)); if (pcval.isNull()) RETURN_STOP_A("callprop of missing method"); if (pcval.isFunObj()) { if (l.isPrimitive()) { - JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &pcval.toFunObj()); + JSFunction* fun = pcval.toFunObj().getFunctionPrivate(); if (fun->isInterpreted() && !fun->inStrictMode()) RETURN_STOP_A("callee does not accept primitive |this|"); } set(&l, w.immpObjGC(&pcval.toFunObj())); } else { if (l.isPrimitive()) RETURN_STOP_A("callprop of primitive method"); JS_ASSERT_IF(pcval.isShape(), !pcval.toShape()->isMethod());
--- a/js/src/jswrapper.cpp +++ b/js/src/jswrapper.cpp @@ -479,17 +479,17 @@ AutoCompartment::leave() ErrorCopier::~ErrorCopier() { JSContext *cx = ac.context; if (cx->compartment == ac.destination && ac.origin != ac.destination && cx->isExceptionPending()) { Value exc = cx->getPendingException(); - if (exc.isObject() && exc.toObject().isError()) { + if (exc.isObject() && exc.toObject().isError() && exc.toObject().getPrivate()) { cx->clearPendingException(); ac.leave(); JSObject *copyobj = js_CopyErrorObject(cx, &exc.toObject(), scope); if (copyobj) cx->setPendingException(ObjectValue(*copyobj)); } } }
--- a/js/src/jsxml.cpp +++ b/js/src/jsxml.cpp @@ -1638,17 +1638,17 @@ fail: */ static JSBool GetXMLSetting(JSContext *cx, const char *name, jsval *vp) { jsval v; if (!js_FindClassObject(cx, NULL, JSProto_XML, Valueify(&v))) return JS_FALSE; - if (!VALUE_IS_FUNCTION(cx, v)) { + if (JSVAL_IS_PRIMITIVE(v) || !JSVAL_TO_OBJECT(v)->isFunction()) { *vp = JSVAL_VOID; return JS_TRUE; } return JS_GetProperty(cx, JSVAL_TO_OBJECT(v), name, vp); } static JSBool GetBooleanXMLSetting(JSContext *cx, const char *name, JSBool *bp) @@ -5148,17 +5148,18 @@ JS_FRIEND_DATA(Class) js_XMLClass = { static JSXML * StartNonListXMLMethod(JSContext *cx, jsval *vp, JSObject **objp) { JSXML *xml; JSFunction *fun; char numBuf[12]; - JS_ASSERT(VALUE_IS_FUNCTION(cx, *vp)); + JS_ASSERT(!JSVAL_IS_PRIMITIVE(*vp)); + JS_ASSERT(JSVAL_TO_OBJECT(*vp)->isFunction()); *objp = ToObject(cx, Valueify(&vp[1])); if (!*objp) return NULL; if (!(*objp)->isXML()) { ReportIncompatibleMethod(cx, Valueify(vp), &js_XMLClass); return NULL; } @@ -5172,17 +5173,17 @@ StartNonListXMLMethod(JSContext *cx, jsv *objp = js_GetXMLObject(cx, xml); if (!*objp) return NULL; vp[1] = OBJECT_TO_JSVAL(*objp); return xml; } } - fun = GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(*vp)); + fun = JSVAL_TO_OBJECT(*vp)->getFunctionPrivate(); JS_snprintf(numBuf, sizeof numBuf, "%u", xml->xml_kids.length); JSAutoByteString funNameBytes; if (const char *funName = GetFunctionNameBytes(cx, fun, &funNameBytes)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NON_LIST_XML_METHOD, funName, numBuf); } return NULL; } @@ -7495,17 +7496,17 @@ GetXMLFunction(JSContext *cx, JSObject * * See comments before xml_lookupProperty about the need for the proto * chain lookup. */ JSObject *target = obj; AutoObjectRooter tvr(cx); for (;;) { if (!js_GetProperty(cx, target, id, Valueify(vp))) return false; - if (VALUE_IS_FUNCTION(cx, *vp)) + if (!JSVAL_IS_PRIMITIVE(*vp) && JSVAL_TO_OBJECT(*vp)->isFunction()) return true; target = target->getProto(); if (target == NULL || !target->isNative()) break; tvr.setObject(target); } JSXML *xml = (JSXML *) obj->getPrivate();
--- a/js/src/methodjit/InvokeHelpers.cpp +++ b/js/src/methodjit/InvokeHelpers.cpp @@ -109,16 +109,17 @@ top: // But the first ops of exception handlers generated by our // bytecode compiler cannot throw, so this is not possible. if (offset - tn->start > tn->length) continue; if (tn->stackDepth > cx->regs().sp - fp->base()) continue; jsbytecode *pc = script->main + tn->start + tn->length; + cx->regs().pc = pc; JSBool ok = js_UnwindScope(cx, tn->stackDepth, JS_TRUE); JS_ASSERT(cx->regs().sp == fp->base() + tn->stackDepth); switch (tn->kind) { case JSTRY_CATCH: JS_ASSERT(js_GetOpcode(cx, fp->script(), pc) == JSOP_ENTERBLOCK); #if JS_HAS_GENERATORS @@ -186,24 +187,24 @@ InlineReturn(VMFrame &f) *f.regs.pc == JSOP_FUNCALL || *f.regs.pc == JSOP_FUNAPPLY); f.regs.pc += JSOP_CALL_LENGTH; } void JS_FASTCALL stubs::SlowCall(VMFrame &f, uint32 argc) { - if (!Invoke(f.cx, CallArgsFromSp(argc, f.regs.sp))) + if (!InvokeKernel(f.cx, CallArgsFromSp(argc, f.regs.sp))) THROW(); } void JS_FASTCALL stubs::SlowNew(VMFrame &f, uint32 argc) { - if (!InvokeConstructor(f.cx, CallArgsFromSp(argc, f.regs.sp))) + if (!InvokeConstructorKernel(f.cx, CallArgsFromSp(argc, f.regs.sp))) THROW(); } /* * HitStackQuota is called after the early prologue pushing the new frame would * overflow f.stackLimit. */ void JS_FASTCALL @@ -373,17 +374,17 @@ stubs::UncachedNewHelper(VMFrame &f, uin CallArgs args = CallArgsFromSp(argc, f.regs.sp); /* Try to do a fast inline call before the general Invoke path. */ if (IsFunctionObject(args.calleev(), &ucr->fun) && ucr->fun->isInterpretedConstructor()) { ucr->callee = &args.callee(); if (!UncachedInlineCall(f, CONSTRUCT, &ucr->codeAddr, &ucr->unjittable, argc)) THROW(); } else { - if (!InvokeConstructor(cx, args)) + if (!InvokeConstructorKernel(cx, args)) THROW(); } } void * JS_FASTCALL stubs::UncachedCall(VMFrame &f, uint32 argc) { UncachedCallResult ucr; @@ -392,17 +393,17 @@ stubs::UncachedCall(VMFrame &f, uint32 a } void JS_FASTCALL stubs::Eval(VMFrame &f, uint32 argc) { CallArgs args = CallArgsFromSp(argc, f.regs.sp); if (!IsBuiltinEvalForScope(&f.fp()->scopeChain(), args.calleev())) { - if (!Invoke(f.cx, args)) + if (!InvokeKernel(f.cx, args)) THROW(); return; } JS_ASSERT(f.fp() == f.cx->fp()); if (!DirectEval(f.cx, args)) THROW(); @@ -414,32 +415,32 @@ stubs::UncachedCallHelper(VMFrame &f, ui { ucr->init(); JSContext *cx = f.cx; CallArgs args = CallArgsFromSp(argc, f.regs.sp); if (IsFunctionObject(args.calleev(), &ucr->callee)) { ucr->callee = &args.callee(); - ucr->fun = GET_FUNCTION_PRIVATE(cx, ucr->callee); + ucr->fun = ucr->callee->getFunctionPrivate(); if (ucr->fun->isInterpreted()) { if (!UncachedInlineCall(f, NO_CONSTRUCT, &ucr->codeAddr, &ucr->unjittable, argc)) THROW(); return; } if (ucr->fun->isNative()) { if (!CallJSNative(cx, ucr->fun->u.n.native, args)) THROW(); return; } } - if (!Invoke(f.cx, args)) + if (!InvokeKernel(f.cx, args)) THROW(); return; } void JS_FASTCALL stubs::PutActivationObjects(VMFrame &f) {
--- a/js/src/methodjit/PolyIC.cpp +++ b/js/src/methodjit/PolyIC.cpp @@ -553,17 +553,17 @@ class SetPropCompiler : public PICStubCo uintN flags = 0; PropertyOp getter = clasp->getProperty; if (pic.kind == ic::PICInfo::SETMETHOD) { if (!obj->canHaveMethodBarrier()) return disable("can't have method barrier"); JSObject *funobj = &f.regs.sp[-1].toObject(); - if (funobj != GET_FUNCTION_PRIVATE(cx, funobj)) + if (funobj != funobj->getFunctionPrivate()) return disable("mismatched function"); flags |= Shape::METHOD; getter = CastAsPropertyOp(funobj); } /* * Define the property but do not set it yet. For setmethod,
--- a/js/src/methodjit/StubCalls.cpp +++ b/js/src/methodjit/StubCalls.cpp @@ -699,19 +699,19 @@ stubs::DefFun(VMFrame &f, JSFunction *fu StackFrame *fp = f.fp(); /* * A top-level function defined in Global or Eval code (see ECMA-262 * Ed. 3), or else a SpiderMonkey extension: a named function statement in * a compound statement (not at the top statement level of global code, or * at the top level of a function body). */ - JSObject *obj = FUN_OBJECT(fun); + JSObject *obj = fun; - if (FUN_NULL_CLOSURE(fun)) { + if (fun->isNullClosure()) { /* * Even a null closure needs a parent for principals finding. * FIXME: bug 476950, although debugger users may also demand some kind * of scope link for debugger-assisted eval-in-frame. */ obj2 = &fp->scopeChain(); } else { JS_ASSERT(!fun->isFlatClosure()); @@ -1320,20 +1320,20 @@ stubs::DefLocalFun(VMFrame &f, JSFunctio /* * Define a local function (i.e., one nested at the top level of another * function), parented by the current scope chain, stored in a local * variable slot that the compiler allocated. This is an optimization over * JSOP_DEFFUN that avoids requiring a call object for the outer function's * activation. */ JS_ASSERT(fun->isInterpreted()); - JS_ASSERT(!FUN_FLAT_CLOSURE(fun)); - JSObject *obj = FUN_OBJECT(fun); + JS_ASSERT(!fun->isFlatClosure()); + JSObject *obj = fun; - if (FUN_NULL_CLOSURE(fun)) { + if (fun->isNullClosure()) { obj = CloneFunctionObject(f.cx, fun, &f.fp()->scopeChain()); if (!obj) THROWV(NULL); } else { JSObject *parent = GetScopeChainFast(f.cx, f.fp(), JSOP_DEFLOCALFUN, JSOP_DEFLOCALFUN_LENGTH); if (!parent) THROWV(NULL); @@ -1376,43 +1376,43 @@ stubs::RegExp(VMFrame &f, JSObject *rege if (!obj) THROWV(NULL); return obj; } JSObject * JS_FASTCALL stubs::LambdaForInit(VMFrame &f, JSFunction *fun) { - JSObject *obj = FUN_OBJECT(fun); - if (FUN_NULL_CLOSURE(fun) && obj->getParent() == &f.fp()->scopeChain()) { + JSObject *obj = fun; + if (fun->isNullClosure() && obj->getParent() == &f.fp()->scopeChain()) { fun->setMethodAtom(f.fp()->script()->getAtom(GET_SLOTNO(f.regs.pc))); return obj; } return Lambda(f, fun); } JSObject * JS_FASTCALL stubs::LambdaForSet(VMFrame &f, JSFunction *fun) { - JSObject *obj = FUN_OBJECT(fun); - if (FUN_NULL_CLOSURE(fun) && obj->getParent() == &f.fp()->scopeChain()) { + JSObject *obj = fun; + if (fun->isNullClosure() && obj->getParent() == &f.fp()->scopeChain()) { const Value &lref = f.regs.sp[-1]; if (lref.isObject() && lref.toObject().canHaveMethodBarrier()) { fun->setMethodAtom(f.fp()->script()->getAtom(GET_SLOTNO(f.regs.pc))); return obj; } } return Lambda(f, fun); } JSObject * JS_FASTCALL stubs::LambdaJoinableForCall(VMFrame &f, JSFunction *fun) { - JSObject *obj = FUN_OBJECT(fun); - if (FUN_NULL_CLOSURE(fun) && obj->getParent() == &f.fp()->scopeChain()) { + JSObject *obj = fun; + if (fun->isNullClosure() && obj->getParent() == &f.fp()->scopeChain()) { /* * Array.prototype.sort and String.prototype.replace are * optimized as if they are special form. We know that they * won't leak the joined function object in obj, therefore * we don't need to clone that compiler- created function * object for identity/mutation reasons. */ int iargc = GET_ARGC(f.regs.pc); @@ -1438,34 +1438,34 @@ stubs::LambdaJoinableForCall(VMFrame &f, } } return Lambda(f, fun); } JSObject * JS_FASTCALL stubs::LambdaJoinableForNull(VMFrame &f, JSFunction *fun) { - JSObject *obj = FUN_OBJECT(fun); - if (FUN_NULL_CLOSURE(fun) && obj->getParent() == &f.fp()->scopeChain()) { + JSObject *obj = fun; + if (fun->isNullClosure() && obj->getParent() == &f.fp()->scopeChain()) { jsbytecode *pc2 = f.regs.pc + JSOP_NULL_LENGTH; JSOp op2 = JSOp(*pc2); if (op2 == JSOP_CALL && GET_ARGC(pc2) == 0) return obj; } return Lambda(f, fun); } JSObject * JS_FASTCALL stubs::Lambda(VMFrame &f, JSFunction *fun) { - JSObject *obj = FUN_OBJECT(fun); + JSObject *obj = fun; JSObject *parent; - if (FUN_NULL_CLOSURE(fun)) { + if (fun->isNullClosure()) { parent = &f.fp()->scopeChain(); } else { parent = GetScopeChainFast(f.cx, f.fp(), JSOP_LAMBDA, JSOP_LAMBDA_LENGTH); if (!parent) THROWV(NULL); } obj = CloneFunctionObject(f.cx, fun, parent);
--- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -1549,25 +1549,25 @@ ValueToScript(JSContext *cx, jsval v) JSObject *obj = JSVAL_TO_OBJECT(v); JSClass *clasp = JS_GET_CLASS(cx, obj); if (clasp == Jsvalify(&js_ScriptClass)) { script = (JSScript *) JS_GetPrivate(cx, obj); } else if (clasp == Jsvalify(&js_GeneratorClass)) { JSGenerator *gen = (JSGenerator *) JS_GetPrivate(cx, obj); fun = gen->floatingFrame()->fun(); - script = FUN_SCRIPT(fun); + script = fun->script(); } } if (!script) { fun = JS_ValueToFunction(cx, v); if (!fun) return NULL; - script = FUN_SCRIPT(fun); + script = fun->maybeScript(); if (!script) { JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_SCRIPTS_ONLY); } } return script; } @@ -1987,35 +1987,35 @@ TryNotes(JSContext *cx, JSScript *script } static bool DisassembleValue(JSContext *cx, jsval v, bool lines, bool recursive, Sprinter *sp) { JSScript *script = ValueToScript(cx, v); if (!script) return false; - if (VALUE_IS_FUNCTION(cx, v)) { + if (!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isFunction()) { JSFunction *fun = JS_ValueToFunction(cx, v); if (fun && (fun->flags & ~7U)) { uint16 flags = fun->flags; Sprint(sp, "flags:"); #define SHOW_FLAG(flag) if (flags & JSFUN_##flag) Sprint(sp, " " #flag); SHOW_FLAG(LAMBDA); SHOW_FLAG(HEAVYWEIGHT); SHOW_FLAG(EXPR_CLOSURE); SHOW_FLAG(TRCINFO); #undef SHOW_FLAG - if (FUN_INTERPRETED(fun)) { - if (FUN_NULL_CLOSURE(fun)) + if (fun->isInterpreted()) { + if (fun->isNullClosure()) Sprint(sp, " NULL_CLOSURE"); - else if (FUN_FLAT_CLOSURE(fun)) + else if (fun->isFlatClosure()) Sprint(sp, " FLAT_CLOSURE"); JSScript *script = fun->script(); if (script->bindings.hasUpvars()) { Sprint(sp, "\nupvars: {\n"); Vector<JSAtom *> localNames(cx); if (!script->bindings.getLocalNameArray(cx, &localNames)) @@ -2693,17 +2693,17 @@ Clone(JSContext *cx, uintN argc, jsval * if (!JSVAL_IS_PRIMITIVE(argv[0]) && JSVAL_TO_OBJECT(argv[0])->isCrossCompartmentWrapper()) { JSObject *obj = JSVAL_TO_OBJECT(argv[0])->unwrap(); if (!ac.enter(cx, obj)) return JS_FALSE; argv[0] = OBJECT_TO_JSVAL(obj); } - if (VALUE_IS_FUNCTION(cx, argv[0])) { + if (!JSVAL_IS_PRIMITIVE(argv[0]) && JSVAL_TO_OBJECT(argv[0])->isFunction()) { funobj = JSVAL_TO_OBJECT(argv[0]); } else { JSFunction *fun = JS_ValueToFunction(cx, argv[0]); if (!fun) return JS_FALSE; funobj = JS_GetFunctionObject(fun); } }
new file mode 100644 --- /dev/null +++ b/js/src/tests/ecma_5/extensions/JSON-string-replacer-overflow.js @@ -0,0 +1,24 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var r1 = [0, 1, 2, 3]; +Object.defineProperty(r1, (1 << 23) - 1, {}); +JSON.stringify({ 0: 0, 1: 1, 2: 2, 3: 3 }, r1) + +var r2 = [0, 1, 2, 3]; +Object.defineProperty(r2, (1 << 30), {}); +try +{ + JSON.stringify({ 0: 0, 1: 1, 2: 2, 3: 3 }, r2) +} +catch (e) +{ + assertEq(""+e, "InternalError: allocation size overflow"); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete");
--- a/js/src/tests/ecma_5/extensions/jstests.list +++ b/js/src/tests/ecma_5/extensions/jstests.list @@ -11,16 +11,17 @@ script bug496985.js script bug566661.js script array-toString-recursion.js skip-if(!xulRuntime.shell) script cross-global-eval-is-indirect.js # needs newGlobal() script eval-native-callback-is-indirect.js script extension-methods-reject-null-undefined-this.js skip-if(!xulRuntime.shell) script function-definition-with.js # needs evaluate() script function-properties.js script iterator-in-catch.js +script JSON-string-replacer-overflow.js skip-if(!xulRuntime.shell) script legacy-JSON.js # needs parseLegacyJSON fails script nested-delete-name-in-evalcode.js # bug 604301, at a minimum script proxy-strict.js script regress-bug567606.js script regress-bug607284.js script regress-bug629723.js script strict-function-statements.js script strict-option-redeclared-parameter.js
--- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -515,17 +515,17 @@ Debugger::handleUncaughtException(AutoCo { JSContext *cx = ac.context; if (cx->isExceptionPending()) { if (callHook && uncaughtExceptionHook) { Value fval = ObjectValue(*uncaughtExceptionHook); Value exc = cx->getPendingException(); Value rv; cx->clearPendingException(); - if (ExternalInvoke(cx, ObjectValue(*object), fval, 1, &exc, &rv)) + if (Invoke(cx, ObjectValue(*object), fval, 1, &exc, &rv)) return vp ? parseResumptionValue(ac, true, rv, vp, false) : JSTRAP_CONTINUE; } if (cx->isExceptionPending()) { JS_ReportPendingException(cx); cx->clearPendingException(); } } @@ -621,17 +621,17 @@ CallMethodIfPresent(JSContext *cx, JSObj Value *rval) { rval->setUndefined(); JSAtom *atom = js_Atomize(cx, name, strlen(name)); Value fval; return atom && js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, &fval) && (!js_IsCallable(fval) || - ExternalInvoke(cx, ObjectValue(*obj), fval, argc, argv, rval)); + Invoke(cx, ObjectValue(*obj), fval, argc, argv, rval)); } JSTrapStatus Debugger::fireDebuggerStatement(JSContext *cx, Value *vp) { JSObject *hook = getHook(OnDebuggerStatement); JS_ASSERT(hook); JS_ASSERT(hook->isCallable()); @@ -642,17 +642,17 @@ Debugger::fireDebuggerStatement(JSContex if (!ac.enter()) return JSTRAP_ERROR; Value argv[1]; if (!getScriptFrame(cx, fp, argv)) return handleUncaughtException(ac, vp, false); Value rv; - bool ok = ExternalInvoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv); + bool ok = Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv); return parseResumptionValue(ac, ok, rv, vp); } JSTrapStatus Debugger::fireExceptionUnwind(JSContext *cx, Value *vp) { JSObject *hook = getHook(OnExceptionUnwind); JS_ASSERT(hook); @@ -667,17 +667,17 @@ Debugger::fireExceptionUnwind(JSContext return JSTRAP_ERROR; Value argv[2]; argv[1] = exc; if (!getScriptFrame(cx, fp, &argv[0]) || !wrapDebuggeeValue(cx, &argv[1])) return handleUncaughtException(ac, vp, false); Value rv; - bool ok = ExternalInvoke(cx, ObjectValue(*object), ObjectValue(*hook), 2, argv, &rv); + bool ok = Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 2, argv, &rv); JSTrapStatus st = parseResumptionValue(ac, ok, rv, vp); if (st == JSTRAP_CONTINUE) cx->setPendingException(exc); return st; } void Debugger::fireEnterFrame(JSContext *cx) @@ -692,17 +692,17 @@ Debugger::fireEnterFrame(JSContext *cx) return; Value argv[1]; if (!getScriptFrame(cx, fp, &argv[0])) { handleUncaughtException(ac, NULL, false); return; } Value rv; - if (!ExternalInvoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv)) + if (!Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv)) handleUncaughtException(ac, NULL, true); } void Debugger::fireNewScript(JSContext *cx, JSScript *script, JSObject *obj, NewScriptKind kind) { JSObject *hook = getHook(OnNewScript); JS_ASSERT(hook); @@ -717,17 +717,17 @@ Debugger::fireNewScript(JSContext *cx, J if (!dsobj) { handleUncaughtException(ac, NULL, false); return; } Value argv[1]; argv[0].setObject(*dsobj); Value rv; - if (!ExternalInvoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv)) + if (!Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv)) handleUncaughtException(ac, NULL, true); } JSTrapStatus Debugger::dispatchHook(JSContext *cx, js::Value *vp, Hook which) { JS_ASSERT(which == OnDebuggerStatement || which == OnExceptionUnwind); @@ -2653,31 +2653,35 @@ DebuggerFrame_getLive(JSContext *cx, uin namespace js { JSBool EvaluateInScope(JSContext *cx, JSObject *scobj, StackFrame *fp, const jschar *chars, uintN length, const char *filename, uintN lineno, Value *rval) { assertSameCompartment(cx, scobj, fp); + /* Execute assumes an already-computed 'this" value. */ + if (!ComputeThis(cx, fp)) + return false; + /* * NB: This function breaks the assumption that the compiler can see all * calls and properly compute a static level. In order to get around this, * we use a static level that will cause us not to attempt to optimize * variable references made by this frame. */ JSScript *script = Compiler::compileScript(cx, scobj, fp, fp->scopeChain().principals(cx), TCF_COMPILE_N_GO, chars, length, filename, lineno, cx->findVersion(), NULL, UpvarCookie::UPVAR_LEVEL_LIMIT); if (!script) return false; - bool ok = Execute(cx, script, *scobj, fp->thisValue(), EXECUTE_DEBUG, fp, rval); + bool ok = ExecuteKernel(cx, script, *scobj, fp->thisValue(), EXECUTE_DEBUG, fp, rval); js_DestroyScript(cx, script, 6); return ok; } } enum EvalBindingsMode { WithoutBindings, WithBindings }; @@ -2998,16 +3002,17 @@ DebuggerObject_getOwnPropertyDescriptor( /* Bug: This can cause the debuggee to run! */ AutoPropertyDescriptorRooter desc(cx); { AutoCompartment ac(cx, obj); if (!ac.enter() || !cx->compartment->wrapId(cx, &id)) return false; + ErrorCopier ec(ac, dbg->toJSObject()); if (!GetOwnPropertyDescriptor(cx, obj, id, &desc)) return false; } if (desc.obj) { /* Rewrap the debuggee values in desc for the debugger. */ if (!dbg->wrapDebuggeeValue(cx, &desc.value)) return false; @@ -3034,16 +3039,17 @@ DebuggerObject_getOwnPropertyNames(JSCon THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "getOwnPropertyNames", args, dbg, obj); AutoIdVector keys(cx); { AutoCompartment ac(cx, obj); if (!ac.enter()) return false; + ErrorCopier ec(ac, dbg->toJSObject()); if (!GetPropertyNames(cx, obj, JSITER_OWNONLY | JSITER_HIDDEN, &keys)) return false; } AutoValueVector vals(cx); if (!vals.resize(keys.length())) return false; @@ -3372,17 +3378,17 @@ ApplyOrCall(JSContext *cx, uintN argc, V return false; } /* * Call the function. Use newCompletionValue to return to the debugger * compartment and populate args.rval(). */ Value rval; - bool ok = ExternalInvoke(cx, thisv, calleev, callArgc, callArgv, &rval); + bool ok = Invoke(cx, thisv, calleev, callArgc, callArgv, &rval); return dbg->newCompletionValue(ac, ok, rval, &args.rval()); } static JSBool DebuggerObject_apply(JSContext *cx, uintN argc, Value *vp) { return ApplyOrCall(cx, argc, vp, ApplyMode); }
--- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -209,17 +209,17 @@ GlobalObject::createConstructor(JSContex JSFunction *fun = js_NewFunction(cx, NULL, ctor, length, JSFUN_CONSTRUCTOR, this, name); if (!fun) return NULL; /* * Remember the class this function is a constructor for so that we know to * create an object of this class when we call the constructor. */ - FUN_CLASP(fun) = clasp; + fun->setConstructorClass(clasp); return fun; } static JSObject * CreateBlankProto(JSContext *cx, Class *clasp, JSObject &proto, GlobalObject &global) { JS_ASSERT(clasp != &js_ObjectClass); JS_ASSERT(clasp != &js_FunctionClass);
--- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -249,16 +249,23 @@ CallArgsFromVp(uintN argc, Value *vp) JS_ALWAYS_INLINE CallArgs CallArgsFromSp(uintN argc, Value *sp) { return CallArgsFromArgv(argc, sp - argc); } /*****************************************************************************/ +/* + * For calls to natives, the InvokeArgsGuard object provides a record of the + * call for the debugger's callstack. For this to work, the InvokeArgsGuard + * record needs to know when the call is actually active (because the + * InvokeArgsGuard can be pushed long before and popped long after the actual + * call, during which time many stack-observing things can happen). + */ class CallArgsList : public CallArgs { friend class StackSegment; CallArgsList *prev_; bool active_; public: friend CallArgsList CallArgsListFromVp(uintN, Value *, CallArgsList *); friend CallArgsList CallArgsListFromArgv(uintN, Value *, CallArgsList *);
--- a/js/src/xpconnect/src/xpcwrappednativejsops.cpp +++ b/js/src/xpconnect/src/xpcwrappednativejsops.cpp @@ -1571,17 +1571,17 @@ XPC_WN_CallMethod(JSContext *cx, uintN a JSObject* funobj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)); JSObject* obj = JS_THIS_OBJECT(cx, vp); if (!obj) return JS_FALSE; #ifdef DEBUG_slimwrappers { - JSFunction* fun = GET_FUNCTION_PRIVATE(cx, funobj); + JSFunction* fun = funobj->getFunctionPrivate(); JSString *funid = JS_GetFunctionId(fun); JSAutoByteString bytes; const char *funname = !funid ? "" : bytes.encode(cx, funid) ? bytes.ptr() : "<error>"; SLIM_LOG_WILL_MORPH_FOR_PROP(cx, obj, funname); } #endif if(IS_SLIM_WRAPPER(obj) && !MorphSlimWrapper(cx, obj)) return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); @@ -1610,17 +1610,17 @@ XPC_WN_GetterSetter(JSContext *cx, uintN return JS_FALSE; #ifdef DEBUG_slimwrappers { const char* funname = nsnull; JSAutoByteString bytes; if(JS_TypeOfValue(cx, JS_CALLEE(cx, vp)) == JSTYPE_FUNCTION) { - JSString *funid = JS_GetFunctionId(GET_FUNCTION_PRIVATE(cx, funobj)); + JSString *funid = JS_GetFunctionId(funobj->getFunctionPrivate()); funname = !funid ? "" : bytes.encode(cx, funid) ? bytes.ptr() : "<error>"; } SLIM_LOG_WILL_MORPH_FOR_PROP(cx, obj, funname); } #endif if(IS_SLIM_WRAPPER(obj) && !MorphSlimWrapper(cx, obj)) return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
--- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -9406,31 +9406,43 @@ SetExternalResourceIsActive(nsIDocument* { nsIPresShell* shell = aDocument->GetShell(); if (shell) { shell->SetIsActive(*static_cast<PRBool*>(aClosure)); } return PR_TRUE; } +static void +SetPluginIsActive(nsIContent* aContent, void* aClosure) +{ + nsIFrame *frame = aContent->GetPrimaryFrame(); + nsIObjectFrame *objectFrame = do_QueryFrame(frame); + if (objectFrame) { + objectFrame->SetIsDocumentActive(*static_cast<PRBool*>(aClosure)); + } +} + nsresult PresShell::SetIsActive(PRBool aIsActive) { NS_PRECONDITION(mDocument, "should only be called with a document"); mIsActive = aIsActive; nsPresContext* presContext = GetPresContext(); if (presContext && presContext->RefreshDriver()->PresContext() == presContext) { presContext->RefreshDriver()->SetThrottled(!mIsActive); } // Propagate state-change to my resource documents' PresShells mDocument->EnumerateExternalResources(SetExternalResourceIsActive, &aIsActive); + mDocument->EnumerateFreezableElements(SetPluginIsActive, + &aIsActive); nsresult rv = UpdateImageLockingState(); #ifdef ACCESSIBILITY if (aIsActive) { nsAccessibilityService* accService = AccService(); if (accService) { accService->PresShellActivated(this); } }
--- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -62,17 +62,16 @@ #include "nsIDOMHTMLTextAreaElement.h" #include "nsNodeInfoManager.h" #include "nsIURI.h" #include "nsGUIEvent.h" #include "nsContentCreatorFunctions.h" #include "nsISupportsPrimitives.h" #include "nsAutoPtr.h" #include "nsPresState.h" -#include "nsIGlobalHistory3.h" #include "nsDocShellCID.h" #include "nsIHTMLDocument.h" #include "nsEventDispatcher.h" #include "nsContentUtils.h" #include "nsLayoutUtils.h" #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" #endif
--- a/layout/generic/nsIObjectFrame.h +++ b/layout/generic/nsIObjectFrame.h @@ -89,11 +89,18 @@ public: * is currently active in this frame. */ virtual void StopPlugin() = 0; /** * Get the native widget for the plugin, if any. */ virtual nsIWidget* GetWidget() = 0; + + /** + * Update plugin active state. Frame should update if it is on an active tab + * or not and forward that information to the plugin to make it possible to + * throttle down plugin instance in non active case. + */ + virtual void SetIsDocumentActive(PRBool aIsActive) = 0; }; #endif /* nsIObjectFrame_h___ */
--- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -2490,16 +2490,26 @@ nsObjectFrame::GetCursor(const nsPoint& if (!useDOMCursor) { return NS_ERROR_FAILURE; } return nsObjectFrameSuper::GetCursor(aPoint, aCursor); } void +nsObjectFrame::SetIsDocumentActive(PRBool aIsActive) +{ +#ifndef XP_MACOSX + if (mInstanceOwner) { + mInstanceOwner->UpdateDocumentActiveState(aIsActive); + } +#endif +} + +void nsObjectFrame::NotifyContentObjectWrapper() { nsCOMPtr<nsIDocument> doc = mContent->GetDocument(); if (!doc) return; nsIScriptGlobalObject *sgo = doc->GetScriptGlobalObject(); if (!sgo)
--- a/layout/generic/nsObjectFrame.h +++ b/layout/generic/nsObjectFrame.h @@ -123,16 +123,17 @@ public: virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext); NS_METHOD GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance); virtual nsresult Instantiate(nsIChannel* aChannel, nsIStreamListener** aStreamListener); virtual nsresult Instantiate(const char* aMimeType, nsIURI* aURI); virtual void TryNotifyContentObjectWrapper(); virtual void StopPlugin(); + virtual void SetIsDocumentActive(PRBool aIsActive); /* * Stop a plugin instance. If aDelayedStop is true, the plugin will * be stopped at a later point when it's safe to do so (i.e. not * while destroying the frame tree). Delayed stopping is only * implemented on Win32 for now. */ void StopPluginInternal(PRBool aDelayedStop);
--- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -1103,16 +1103,21 @@ InitSystemMetrics() sSystemMetrics->AppendElement(nsGkAtoms::windows_default_theme); } rv = lookAndFeel->GetMetric(nsILookAndFeel::eMetric_MacGraphiteTheme, metricResult); if (NS_SUCCEEDED(rv) && metricResult) { sSystemMetrics->AppendElement(nsGkAtoms::mac_graphite_theme); } + rv = lookAndFeel->GetMetric(nsILookAndFeel::eMetric_MacLionTheme, metricResult); + if (NS_SUCCEEDED(rv) && metricResult) { + sSystemMetrics->AppendElement(nsGkAtoms::mac_lion_theme); + } + rv = lookAndFeel->GetMetric(nsILookAndFeel::eMetric_DWMCompositor, metricResult); if (NS_SUCCEEDED(rv) && metricResult) { sSystemMetrics->AppendElement(nsGkAtoms::windows_compositor); } rv = lookAndFeel->GetMetric(nsILookAndFeel::eMetric_WindowsClassic, metricResult); if (NS_SUCCEEDED(rv) && metricResult) { sSystemMetrics->AppendElement(nsGkAtoms::windows_classic);
--- a/layout/style/nsMediaFeatures.cpp +++ b/layout/style/nsMediaFeatures.cpp @@ -517,16 +517,23 @@ nsMediaFeatures::features[] = { { &nsGkAtoms::_moz_mac_graphite_theme, nsMediaFeature::eMinMaxNotAllowed, nsMediaFeature::eBoolInteger, { &nsGkAtoms::mac_graphite_theme }, GetSystemMetric }, { + &nsGkAtoms::_moz_mac_lion_theme, + nsMediaFeature::eMinMaxNotAllowed, + nsMediaFeature::eBoolInteger, + { &nsGkAtoms::mac_lion_theme }, + GetSystemMetric + }, + { &nsGkAtoms::_moz_windows_compositor, nsMediaFeature::eMinMaxNotAllowed, nsMediaFeature::eBoolInteger, { &nsGkAtoms::windows_compositor }, GetSystemMetric }, { &nsGkAtoms::_moz_windows_classic,
--- a/layout/style/test/test_media_queries.html +++ b/layout/style/test/test_media_queries.html @@ -545,72 +545,77 @@ function run() { expression_should_be_parseable("-moz-scrollbar-start-forward"); expression_should_be_parseable("-moz-scrollbar-end-backward"); expression_should_be_parseable("-moz-scrollbar-end-forward"); expression_should_be_parseable("-moz-scrollbar-thumb-proportional"); expression_should_be_parseable("-moz-images-in-menus"); expression_should_be_parseable("-moz-images-in-buttons"); expression_should_be_parseable("-moz-windows-default-theme"); expression_should_be_parseable("-moz-mac-graphite-theme"); + expression_should_be_parseable("-moz-mac-lion-theme"); expression_should_be_parseable("-moz-windows-compositor"); expression_should_be_parseable("-moz-windows-classic"); expression_should_be_parseable("-moz-touch-enabled"); expression_should_be_parseable("-moz-maemo-classic"); expression_should_be_parseable("-moz-scrollbar-start-backward: 0"); expression_should_be_parseable("-moz-scrollbar-start-forward: 0"); expression_should_be_parseable("-moz-scrollbar-end-backward: 0"); expression_should_be_parseable("-moz-scrollbar-end-forward: 0"); expression_should_be_parseable("-moz-scrollbar-thumb-proportional: 0"); expression_should_be_parseable("-moz-images-in-menus: 0"); expression_should_be_parseable("-moz-images-in-buttons: 0"); expression_should_be_parseable("-moz-windows-default-theme: 0"); expression_should_be_parseable("-moz-mac-graphite-theme: 0"); + expression_should_be_parseable("-moz-mac-lion-theme: 0"); expression_should_be_parseable("-moz-windows-compositor: 0"); expression_should_be_parseable("-moz-windows-classic: 0"); expression_should_be_parseable("-moz-touch-enabled: 0"); expression_should_be_parseable("-moz-maemo-classic: 0"); expression_should_be_parseable("-moz-scrollbar-start-backward: 1"); expression_should_be_parseable("-moz-scrollbar-start-forward: 1"); expression_should_be_parseable("-moz-scrollbar-end-backward: 1"); expression_should_be_parseable("-moz-scrollbar-end-forward: 1"); expression_should_be_parseable("-moz-scrollbar-thumb-proportional: 1"); expression_should_be_parseable("-moz-images-in-menus: 1"); expression_should_be_parseable("-moz-images-in-buttons: 1"); expression_should_be_parseable("-moz-windows-default-theme: 1"); expression_should_be_parseable("-moz-mac-graphite-theme: 1"); + expression_should_be_parseable("-moz-mac-lion-theme: 1"); expression_should_be_parseable("-moz-windows-compositor: 1"); expression_should_be_parseable("-moz-windows-classic: 1"); expression_should_be_parseable("-moz-touch-enabled: 1"); expression_should_be_parseable("-moz-maemo-classic: 1"); expression_should_not_be_parseable("-moz-scrollbar-start-backward: -1"); expression_should_not_be_parseable("-moz-scrollbar-start-forward: -1"); expression_should_not_be_parseable("-moz-scrollbar-end-backward: -1"); expression_should_not_be_parseable("-moz-scrollbar-end-forward: -1"); expression_should_not_be_parseable("-moz-scrollbar-thumb-proportional: -1"); expression_should_not_be_parseable("-moz-images-in-menus: -1"); expression_should_not_be_parseable("-moz-images-in-buttons: -1"); expression_should_not_be_parseable("-moz-windows-default-theme: -1"); expression_should_not_be_parseable("-moz-mac-graphite-theme: -1"); + expression_should_not_be_parseable("-moz-mac-lion-theme: -1"); expression_should_not_be_parseable("-moz-windows-compositor: -1"); expression_should_not_be_parseable("-moz-windows-classic: -1"); expression_should_not_be_parseable("-moz-touch-enabled: -1"); expression_should_not_be_parseable("-moz-maemo-classic: -1"); expression_should_not_be_parseable("-moz-scrollbar-start-backward: true"); expression_should_not_be_parseable("-moz-scrollbar-start-forward: true"); expression_should_not_be_parseable("-moz-scrollbar-end-backward: true"); expression_should_not_be_parseable("-moz-scrollbar-end-forward: true"); expression_should_not_be_parseable("-moz-scrollbar-thumb-proportional: true"); expression_should_not_be_parseable("-moz-images-in-menus: true"); expression_should_not_be_parseable("-moz-images-in-buttons: true"); expression_should_not_be_parseable("-moz-windows-default-theme: true"); expression_should_not_be_parseable("-moz-mac-graphite-theme: true"); + expression_should_not_be_parseable("-moz-mac-lion-theme: true"); expression_should_not_be_parseable("-moz-windows-compositor: true"); expression_should_not_be_parseable("-moz-windows-classic: true"); expression_should_not_be_parseable("-moz-touch-enabled: true"); expression_should_not_be_parseable("-moz-maemo-classic: true"); // windows theme media queries expression_should_be_parseable("-moz-windows-theme: aero"); expression_should_be_parseable("-moz-windows-theme: luna-blue");
--- a/mobile/app/mobile.js +++ b/mobile/app/mobile.js @@ -367,17 +367,17 @@ pref("privacy.item.syncAccount", true); #ifdef MOZ_PLATFORM_MAEMO pref("plugins.force.wmode", "opaque"); #endif // URL to the Learn More link XXX this is the firefox one. Bug 495578 fixes this. pref("browser.geolocation.warning.infoURL", "http://www.mozilla.com/%LOCALE%/firefox/geolocation/"); // base url for the wifi geolocation network provider -pref("geo.wifi.uri", "https://www.google.com/loc/json"); +pref("geo.wifi.uri", "https://maps.googleapis.com/maps/api/browserlocation/json"); // enable geo pref("geo.enabled", true); // content sink control -- controls responsiveness during page load // see https://bugzilla.mozilla.org/show_bug.cgi?id=481566#c9 pref("content.sink.enable_perf_mode", 2); // 0 - switch, 1 - interactive, 2 - perf pref("content.sink.pending_event_mode", 0);
--- a/mobile/chrome/content/bindings/browser.js +++ b/mobile/chrome/content/bindings/browser.js @@ -619,16 +619,23 @@ let ContentScroll = { return; sendAsyncMessage("MozScrolledAreaChanged", { width: aEvent.width, height: aEvent.height, left: aEvent.x }); + // Send event only after painting to make sure content views in the parent process have + // been updated. + addEventListener("MozAfterPaint", function afterPaint() { + removeEventListener("MozAfterPaint", afterPaint, false); + sendAsyncMessage("Content:UpdateDisplayPort"); + }, false); + break; } } }, sendScroll: function sendScroll() { let scrollOffset = this.getScrollOffset(content); if (this._scrollOffset.x == scrollOffset.x && this._scrollOffset.y == scrollOffset.y)
--- a/mobile/chrome/content/bindings/browser.xml +++ b/mobile/chrome/content/bindings/browser.xml @@ -129,25 +129,34 @@ self.loadFavicon(json.href, json.charset); break; case "search": self._searchEngines.push({ title: json.title, href: json.href }); break; } break; - case "MozScrolledAreaChanged": + case "MozScrolledAreaChanged": { self._contentDocumentWidth = json.width; self._contentDocumentHeight = json.height; self._contentDocumentLeft = (json.left < 0) ? json.left : 0; // Recalculate whether the visible area is actually in bounds let view = self.getRootView(); view.scrollBy(0, 0); break; + } + + case "Content:UpdateDisplayPort": { + // Recalculate whether the visible area is actually in bounds + let view = self.getRootView(); + view.scrollBy(0, 0); + view._updateCacheViewport(); + break; + } } } }) ]]></field> <method name="loadFavicon"> <parameter name="aURL"/> <parameter name="aCharset"/> @@ -567,16 +576,17 @@ this.messageManager.loadFrameScript("chrome://browser/content/bindings/browser.js", true); this.messageManager.addMessageListener("DOMTitleChanged", this._messageListenerLocal); this.messageManager.addMessageListener("DOMLinkAdded", this._messageListenerLocal); this.messageManager.addMessageListener("pageshow", this._messageListenerLocal); this.messageManager.addMessageListener("pagehide", this._messageListenerLocal); this.messageManager.addMessageListener("DOMPopupBlocked", this._messageListenerLocal); this.messageManager.addMessageListener("MozScrolledAreaChanged", this._messageListenerLocal); + this.messageManager.addMessageListener("Content:UpdateDisplayPort", this._messageListenerLocal); this._webProgress._init(); // Remove event listeners added by toolkit <browser> binding. this.removeEventListener("pageshow", this.onPageShow, true); this.removeEventListener("pagehide", this.onPageHide, true); this.removeEventListener("DOMPopupBlocked", this.onPopupBlocked, true); ]]>
--- a/mobile/chrome/content/browser.js +++ b/mobile/chrome/content/browser.js @@ -382,22 +382,16 @@ var Browser = { messageManager.addMessageListener("Browser:CertException", this); messageManager.addMessageListener("Browser:BlockedSite", this); messageManager.addMessageListener("Browser:ErrorPage", this); // Broadcast a UIReady message so add-ons know we are finished with startup let event = document.createEvent("Events"); event.initEvent("UIReady", true, false); window.dispatchEvent(event); - - // If we have an opener this was not the first window opened and will not - // receive an initial resize event. instead we fire the resize handler manually - // Bug 610834 - if (window.opener) - resizeHandler({ target: window }); }, _alertShown: function _alertShown() { // ensure that the full notification still visible, even if the urlbar is floating if (BrowserUI.isToolbarLocked()) Browser.pageScrollboxScroller.scrollTo(0, 0); },
--- a/mobile/chrome/content/common-ui.js +++ b/mobile/chrome/content/common-ui.js @@ -1338,31 +1338,51 @@ var SelectionHelper = { window.removeEventListener("keypress", this, true); Elements.browsers.removeEventListener("URLChanged", this, true); Elements.browsers.removeEventListener("SizeChanged", this, true); Elements.browsers.removeEventListener("ZoomChanged", this, true); }, handleEvent: function handleEvent(aEvent) { switch (aEvent.type) { + case "PanBegin": + window.removeEventListener("PanBegin", this, true); + window.addEventListener("PanFinished", this, true); + this._start.hidden = true; + this._end.hidden = true; + break; + case "PanFinished": + window.removeEventListener("PanFinished", this, true); + try { + this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionMeasure", {}); + } catch (e) { + Cu.reportError(e); + } + break case "TapDown": if (aEvent.target == this._start || aEvent.target == this._end) { this.target = aEvent.target; this.deltaX = (aEvent.clientX - this.target.left); this.deltaY = (aEvent.clientY - this.target.top); window.addEventListener("TapMove", this, true); } else { - this.hide(aEvent); + window.addEventListener("PanBegin", this, true); + this.target = null; } break; case "TapUp": - window.removeEventListener("TapMove", this, true); - this.target = null; - this.deltaX = -1; - this.deltaY = -1; + if (this.target) { + window.removeEventListener("TapMove", this, true); + this.target = null; + this.deltaX = -1; + this.deltaY = -1; + } else { + window.removeEventListener("PanBegin", self, true); + self.hide(aEvent); + } break; case "TapMove": if (this.target) { this.target.left = aEvent.clientX - this.deltaX; this.target.top = aEvent.clientY - this.deltaY; let rect = this.target.getBoundingClientRect(); let data = this.target == this._start ? { x: rect.right, y: rect.top, type: "start" } : { x: rect.left, y: rect.top, type: "end" }; let pos = this.popupState.target.transformClientToBrowser(data.x || 0, data.y || 0); @@ -1370,20 +1390,28 @@ var SelectionHelper = { type: data.type, x: pos.x, y: pos.y }; this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionMove", json); } break; case "resize": - case "keypress": - case "URLChanged": case "SizeChanged": case "ZoomChanged": + { + try { + this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionMeasure", {}); + } catch (e) { + Cu.reportError(e); + } + break + } + case "URLChanged": + case "keypress": this.hide(aEvent); break; } }, receiveMessage: function sh_receiveMessage(aMessage) { let json = aMessage.json; switch (aMessage.name) {
--- a/mobile/chrome/content/content.js +++ b/mobile/chrome/content/content.js @@ -1346,63 +1346,68 @@ var SelectionHandler = { cache: {}, selectedText: "", contentWindow: null, init: function sh_init() { addMessageListener("Browser:SelectionStart", this); addMessageListener("Browser:SelectionEnd", this); addMessageListener("Browser:SelectionMove", this); + addMessageListener("Browser:SelectionMeasure", this); + }, + + getCurrentWindowAndOffset: function(x, y, offset) { + let utils = Util.getWindowUtils(content); + let elem = utils.elementFromPoint(x, y, true, false); + while (elem && (elem instanceof HTMLIFrameElement || elem instanceof HTMLFrameElement)) { + // adjust client coordinates' origin to be top left of iframe viewport + let rect = elem.getBoundingClientRect(); + scrollOffset = ContentScroll.getScrollOffset(elem.ownerDocument.defaultView); + offset.x += rect.left; + x -= rect.left; + + offset.y += rect.top + scrollOffset.y; + y -= rect.top + scrollOffset.y; + utils = elem.contentDocument.defaultView.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); + elem = utils.elementFromPoint(x, y, true, false); + } + if (!elem) + return; + + return { contentWindow: elem.ownerDocument.defaultView, offset: offset }; }, receiveMessage: function sh_receiveMessage(aMessage) { let scrollOffset = ContentScroll.getScrollOffset(content); let utils = Util.getWindowUtils(content); let json = aMessage.json; switch (aMessage.name) { case "Browser:SelectionStart": { // Clear out the text cache this.selectedText = ""; // if this is an iframe, dig down to find the document that was clicked let x = json.x - scrollOffset.x; let y = json.y - scrollOffset.y; - let offset = scrollOffset; - let elem = utils.elementFromPoint(x, y, true, false); - while (elem && (elem instanceof HTMLIFrameElement || elem instanceof HTMLFrameElement)) { - // adjust client coordinates' origin to be top left of iframe viewport - let rect = elem.getBoundingClientRect(); - scrollOffset = ContentScroll.getScrollOffset(elem.ownerDocument.defaultView); - offset.x += rect.left; - x -= rect.left; - - offset.y += rect.top + scrollOffset.y; - y -= rect.top + scrollOffset.y; - utils = elem.contentDocument.defaultView.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); - elem = utils.elementFromPoint(x, y, true, false); - } - if (!elem) - return; - - let contentWindow = elem.ownerDocument.defaultView; + let { contentWindow: contentWindow, offset: offset } = this.getCurrentWindowAndOffset(x, y, scrollOffset); let currentDocShell = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell); // Remove any previous selected or created ranges. Tapping anywhere on a // page will create an empty range. let selection = contentWindow.getSelection(); selection.removeAllRanges(); - // Position the caret using a fake mouse click - utils.sendMouseEventToWindow("mousedown", x, y, 0, 1, 0, true); - utils.sendMouseEventToWindow("mouseup", x, y, 0, 1, 0, true); + try { + let caretPos = contentWindow.document.caretPositionFromPoint(json.x - scrollOffset.x, json.y - scrollOffset.y); + let selcon = currentDocShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay).QueryInterface(Ci.nsISelectionController); + let sel = selcon.getSelection(1); + sel.collapse(caretPos.offsetNode, caretPos.offset); - // Select the word nearest the caret - try { - let selcon = currentDocShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay).QueryInterface(Ci.nsISelectionController); + // Select the word nearest the caret selcon.wordMove(false, false); selcon.wordMove(true, true); } catch(e) { // If we couldn't select the word at the given point, bail return; } // Find the selected text rect and send it back so the handles can position correctly @@ -1433,69 +1438,95 @@ var SelectionHandler = { let tap = { x: json.x - this.cache.offset.x, y: json.y - this.cache.offset.y }; pointInSelection = (tap.x > this.cache.rect.left && tap.x < this.cache.rect.right) && (tap.y > this.cache.rect.top && tap.y < this.cache.rect.bottom); try { // The selection might already be gone if (this.contentWindow) this.contentWindow.getSelection().removeAllRanges(); this.contentWindow = null; - } catch(e) {} + } catch(e) { + Cu.reportError(e); + } if (pointInSelection && this.selectedText.length) { let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); clipboard.copyString(this.selectedText); sendAsyncMessage("Browser:SelectionCopied", { succeeded: true }); } else { sendAsyncMessage("Browser:SelectionCopied", { succeeded: false }); } break; } case "Browser:SelectionMove": if (!this.contentWindow) return; - // Hack to avoid setting focus in a textbox [Bugs 654352 & 667243] - let elemUnder = elementFromPoint(json.x - scrollOffset.x, json.y - scrollOffset.y); - if (elemUnder && elemUnder instanceof Ci.nsIDOMHTMLInputElement || elemUnder instanceof Ci.nsIDOMHTMLTextAreaElement) - return; + let x = json.x - scrollOffset.x; + let y = json.y - scrollOffset.y; - // Limit the selection to the initial content window (don't leave or enter iframes) - if (elemUnder && elemUnder.ownerDocument.defaultView != this.contentWindow) - return; + try { + let caretPos = this.contentWindow.document.caretPositionFromPoint(x, y); + if (caretPos.offsetNode == null || + caretPos.offsetNode instanceof Ci.nsIDOMHTMLInputElement || + caretPos.offsetNode instanceof Ci.nsIDOMHTMLTextAreaElement || + caretPos.offsetNode.ownerDocument.defaultView != this.contentWindow) + return; - // Use fake mouse events to update the selection - if (json.type == "end") { - // Keep the cache in "client" coordinates, but translate for the mouse event - this.cache.end = { x: json.x, y: json.y }; - let end = { x: this.cache.end.x - scrollOffset.x, y: this.cache.end.y - scrollOffset.y }; - utils.sendMouseEventToWindow("mousedown", end.x, end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true); - utils.sendMouseEventToWindow("mouseup", end.x, end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true); - } else { - // Keep the cache in "client" coordinates, but translate for the mouse event - this.cache.start = { x: json.x, y: json.y }; - let start = { x: this.cache.start.x - scrollOffset.x, y: this.cache.start.y - scrollOffset.y }; - let end = { x: this.cache.end.x - scrollOffset.x, y: this.cache.end.y - scrollOffset.y }; + // Keep the cache in "client" coordinates + if (json.type == "end") + this.cache.end = { x: json.x, y: json.y }; + else + this.cache.start = { x: json.x, y: json.y }; - utils.sendMouseEventToWindow("mousedown", start.x, start.y, 0, 0, 0, true); - utils.sendMouseEventToWindow("mouseup", start.x, start.y, 0, 0, 0, true); - - utils.sendMouseEventToWindow("mousedown", end.x, end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true); - utils.sendMouseEventToWindow("mouseup", end.x, end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true); + let currentDocShell = this.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell); + let selcon = currentDocShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay).QueryInterface(Ci.nsISelectionController); + let sel = selcon.getSelection(1); + if (json.type != "end") { + let focusOffset = sel.focusOffset; + let focusNode = sel.focusNode; + sel.collapse(caretPos.offsetNode, caretPos.offset); + sel.extend(focusNode, focusOffset); + } else { + sel.extend(caretPos.offsetNode, caretPos.offset); + } + } catch(e) { + Cu.reportError(e); + return; } // Cache the selected text since the selection might be gone by the time we get the "end" message let selection = this.contentWindow.getSelection() this.selectedText = selection.toString().trim(); // Update the rect we use to test when finishing the clipboard operation let range = selection.getRangeAt(0).QueryInterface(Ci.nsIDOMNSRange); this.cache.rect = this._extractFromRange(range, this.cache.offset).rect; break; + case "Browser:SelectionMeasure": { + let selection = this.contentWindow.getSelection(); + let range = selection.getRangeAt(0).QueryInterface(Ci.nsIDOMNSRange); + if (!range) + return; + + // Cache the selected text since the selection might be gone by the time we get the "end" message + this.selectedText = selection.toString().trim(); + + // If the range didn't have any text, let's bail + if (!this.selectedText.length) { + selection.removeAllRanges(); + return; + } + + this.cache = this._extractFromRange(range, this.cache.offset); + + sendAsyncMessage("Browser:SelectionRange", this.cache); + break; + } } }, _extractFromRange: function sh_extractFromRange(aRange, aOffset) { let cache = { start: {}, end: {}, rect: { left: Number.MAX_VALUE, top: Number.MAX_VALUE, right: 0, bottom: 0 } }; let rects = aRange.getClientRects(); for (let i=0; i<rects.length; i++) { if (i == 0) {
--- a/mobile/installer/debian/fennec.aegis.in +++ b/mobile/installer/debian/fennec.aegis.in @@ -1,7 +1,10 @@ <aegis> <request> <credential name="TrackerReadAccess" /> <credential name="TrackerWriteAccess" /> + <credential name="Location" /> + <for path="@installdir@/@MOZ_APP_NAME@" /> + <for path="@installdir@/plugin-container" /> </request> </aegis>
--- a/modules/libreg/src/Makefile.in +++ b/modules/libreg/src/Makefile.in @@ -63,21 +63,16 @@ EXPORT_LIBRARY = 1 USE_STATIC_LIBS = 1 SDK_LIBRARY = $(LIBRARY) include $(topsrcdir)/config/config.mk DEFINES += -DUSE_BUFFERED_REGISTRY_IO -# Memory mapped files are not supported under QNX, Neutrino, HP-UX and BeOS -#ifeq (,$(filter BeOS HP-UX QNX,$(OS_ARCH))) -#CSRCS += mmapio.c -#DEFINES += -DUSE_MMAP_REGISTRY_IO -#endif include $(topsrcdir)/config/rules.mk R_%.o: %.c $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) -DSTANDALONE_REGISTRY $< ifdef _MSC_VER # Don't include directives about which CRT to use
deleted file mode 100644 --- a/modules/libreg/src/mmapio.c +++ /dev/null @@ -1,213 +0,0 @@ -/* ***** 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 Communicator. - * - * The Initial Developer of the Original Code is - * James L. Nance. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * James L. Nance <jim_nance@yahoo.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 <string.h> -#include "mmapio.h" -#include "prmem.h" -#include "prlog.h" - -struct MmioFileStruct -{ - PRFileDesc *fd; - PRFileMap *fileMap; - PRUint32 fsize; /* The size of the file */ - PRUint32 msize; /* The size of the mmap()ed area */ - PRInt32 pos; /* Our logical position for doing I/O */ - char *addr; /* The base address of our mapping */ - PRBool needSeek; /* Do we need to seek to pos before doing a write() */ -}; - -PRStatus mmio_FileSeek(MmioFile *mmio, PRInt32 offset, PRSeekWhence whence) -{ - mmio->needSeek = PR_TRUE; - - switch(whence) { - case PR_SEEK_SET: - mmio->pos = offset; - break; - case PR_SEEK_END: - mmio->pos = mmio->fsize + offset; - break; - case PR_SEEK_CUR: - mmio->pos = mmio->pos + offset; - break; - default: - return PR_FAILURE; - } - - if(mmio->pos<0) { - mmio->pos = 0; - } - - return PR_SUCCESS; -} - -PRInt32 mmio_FileRead(MmioFile *mmio, char *dest, PRInt32 count) -{ - static PRFileMapProtect prot = PR_PROT_READONLY; - static PRInt64 fsize_l; - - /* First see if we are going to try and read past the end of the file - * and shorten count if we are. - */ - if(mmio->pos+count > mmio->fsize) { - count = mmio->fsize - mmio->pos; - } - - if(count<1) { - return 0; - } - - /* Check to see if we need to remap for this read */ - if(mmio->pos+count > mmio->msize) { - if(mmio->addr && mmio->msize) { - PR_ASSERT(mmio->fileMap); - PR_MemUnmap(mmio->addr, mmio->msize); - PR_CloseFileMap(mmio->fileMap); - mmio->addr = NULL; - mmio->msize = 0; - } - - LL_UI2L(fsize_l, mmio->fsize); - mmio->fileMap = PR_CreateFileMap(mmio->fd, fsize_l, prot); - - if(!mmio->fileMap) { - return -1; - } - - mmio->addr = PR_MemMap(mmio->fileMap, 0, fsize_l); - - if(!mmio->addr) { - return -1; - } - - mmio->msize = mmio->fsize; - } - - memcpy(dest, mmio->addr+mmio->pos, count); - - mmio->pos += count; - mmio->needSeek = PR_TRUE; - - return count; -} - -PRInt32 mmio_FileWrite(MmioFile *mmio, const char *src, PRInt32 count) -{ - PRInt32 wcode; - - if(mmio->needSeek) { - PR_Seek(mmio->fd, mmio->pos, PR_SEEK_SET); - mmio->needSeek = PR_FALSE; - } - - /* If this system does not keep mmap() and write() synchronized, we can - ** force it to by doing an munmap() when we do a write. This will - ** obviously slow things down but fortunatly we do not do that many - ** writes from within mozilla. Platforms which need this may want to - ** use the new USE_BUFFERED_REGISTRY_IO code instead of this code though. - */ -#if MMAP_MISSES_WRITES - if(mmio->addr && mmio->msize) { - PR_ASSERT(mmio->fileMap); - PR_MemUnmap(mmio->addr, mmio->msize); - PR_CloseFileMap(mmio->fileMap); - mmio->addr = NULL; - mmio->msize = 0; - } -#endif - - wcode = PR_Write(mmio->fd, src, count); - - if(wcode>0) { - mmio->pos += wcode; - if(mmio->pos>mmio->fsize) { - mmio->fsize=mmio->pos; - } - } - - return wcode; -} - -PRInt32 mmio_FileTell(MmioFile *mmio) -{ - return mmio->pos; -} - -PRStatus mmio_FileClose(MmioFile *mmio) -{ - if(mmio->addr && mmio->msize) { - PR_ASSERT(mmio->fileMap); - PR_MemUnmap(mmio->addr, mmio->msize); - PR_CloseFileMap(mmio->fileMap); - } - - PR_Close(mmio->fd); - - memset(mmio, 0, sizeof(*mmio)); /* Catch people who try to keep using it */ - - PR_Free(mmio); - - return PR_SUCCESS; -} - -MmioFile *mmio_FileOpen(char *path, PRIntn flags, PRIntn mode) -{ - PRFileDesc *fd = PR_Open(path, flags, mode); - PRFileInfo info; - MmioFile *mmio; - - if(!fd) { - return NULL; - } - - mmio = PR_MALLOC(sizeof(MmioFile)); - - if(!mmio || PR_FAILURE==PR_GetOpenFileInfo(fd, &info)) { - PR_Close(fd); - return NULL; - } - - mmio->fd = fd; - mmio->fileMap = NULL; - mmio->fsize = info.size; - mmio->msize = 0; - mmio->pos = 0; - mmio->addr = NULL; - mmio->needSeek = PR_FALSE; - - return mmio; -}
deleted file mode 100644 --- a/modules/libreg/src/mmapio.h +++ /dev/null @@ -1,47 +0,0 @@ -/* ***** 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 Communicator. - * - * The Initial Developer of the Original Code is - * James L. Nance. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * James L. Nance <jim_nance@yahoo.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 "prio.h" - -typedef struct MmioFileStruct MmioFile; - -PRStatus mmio_FileSeek(MmioFile *file, PRInt32 offset, PRSeekWhence whence); -PRInt32 mmio_FileRead(MmioFile *file, char *dest, PRInt32 count); -PRInt32 mmio_FileWrite(MmioFile *file, const char *src, PRInt32 count); -PRInt32 mmio_FileTell(MmioFile *file); -PRStatus mmio_FileClose(MmioFile *file); -MmioFile *mmio_FileOpen(char *path, PRIntn flags, PRIntn mode);
--- a/modules/libreg/src/vr_stubs.h +++ b/modules/libreg/src/vr_stubs.h @@ -132,36 +132,17 @@ typedef FILE * XP_File; #else /* not standalone, use NSPR */ /*-------------------------------------*/ /* Alternate fileI/O function mappings */ /*-------------------------------------*/ -#if USE_MMAP_REGISTRY_IO - /*-----------------------------------------------*/ - /* NSPR mememory-mapped I/O (write through) */ - /* unfortunately this isn't supported on the Mac */ - /*-----------------------------------------------*/ -#define USE_NSPR_MODES - -#include "mmapio.h" -#define XP_FileSeek(file,offset,whence) mmio_FileSeek((file),(offset),(whence)) -#define XP_FileRead(dest,count,file) mmio_FileRead((file), (dest), (count)) -#define XP_FileWrite(src,count,file) mmio_FileWrite((file), (src), (count)) -#define XP_FileTell(file) mmio_FileTell(file) -#define XP_FileClose(file) mmio_FileClose(file) -#define XP_FileOpen(path, mode) mmio_FileOpen((path), mode ) -#define XP_FileFlush(file) ((void)1) -#define XP_FileSetBufferSize(file, bufsize) (-1) - -typedef MmioFile* XP_File; - -#elif USE_BUFFERED_REGISTRY_IO +#if USE_BUFFERED_REGISTRY_IO /*-----------------------------------------------*/ /* home-grown XP buffering */ /* writes are buffered too so use flush! */ /*-----------------------------------------------*/ #define USE_STDIO_MODES #include "nr_bufio.h" #define XP_FileSeek(file,offset,whence) bufio_Seek((file),(offset),(whence))
--- a/netwerk/build/Makefile.in +++ b/netwerk/build/Makefile.in @@ -135,16 +135,13 @@ endif ifdef NECKO_WIFI SHARED_LIBRARY_LIBS += \ ../wifi/$(LIB_PREFIX)neckowifi_s.$(LIB_SUFFIX) \ $(NULL) LOCAL_INCLUDES += -I$(srcdir)/../wifi endif - -DEFINES += -DNECKO_OFFLINE_CACHE - include $(topsrcdir)/config/config.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk include $(topsrcdir)/config/rules.mk DEFINES += -DIMPL_NS_NET
--- a/netwerk/build/nsNetModule.cpp +++ b/netwerk/build/nsNetModule.cpp @@ -210,21 +210,19 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsNestedA #ifdef NS_BUILD_REFCNT_LOGGING #include "nsAboutBloat.h" #endif #include "nsAboutCache.h" #include "nsAboutCacheEntry.h" NS_GENERIC_FACTORY_CONSTRUCTOR(nsAboutCacheEntry) #endif -#ifdef NECKO_OFFLINE_CACHE NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsOfflineCacheDevice, nsOfflineCacheDevice::GetInstance) NS_GENERIC_FACTORY_CONSTRUCTOR(nsApplicationCacheNamespace) NS_GENERIC_FACTORY_CONSTRUCTOR(nsApplicationCache) -#endif #ifdef NECKO_PROTOCOL_file // file #include "nsFileProtocolHandler.h" NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFileProtocolHandler, Init) #endif #ifdef NECKO_PROTOCOL_ftp @@ -764,21 +762,19 @@ NS_DEFINE_NAMED_CID(NS_ABOUT_BLOAT_MODUL #endif NS_DEFINE_NAMED_CID(NS_ABOUT_CACHE_MODULE_CID); NS_DEFINE_NAMED_CID(NS_ABOUT_CACHE_ENTRY_MODULE_CID); #endif NS_DEFINE_NAMED_CID(NS_SOCKSSOCKETPROVIDER_CID); NS_DEFINE_NAMED_CID(NS_SOCKS4SOCKETPROVIDER_CID); NS_DEFINE_NAMED_CID(NS_UDPSOCKETPROVIDER_CID); NS_DEFINE_NAMED_CID(NS_CACHESERVICE_CID); -#ifdef NECKO_OFFLINE_CACHE NS_DEFINE_NAMED_CID(NS_APPLICATIONCACHESERVICE_CID); NS_DEFINE_NAMED_CID(NS_APPLICATIONCACHENAMESPACE_CID); NS_DEFINE_NAMED_CID(NS_APPLICATIONCACHE_CID); -#endif #ifdef NECKO_COOKIES NS_DEFINE_NAMED_CID(NS_COOKIEMANAGER_CID); NS_DEFINE_NAMED_CID(NS_COOKIESERVICE_CID); #endif #ifdef NECKO_WIFI NS_DEFINE_NAMED_CID(NS_WIFI_MONITOR_COMPONENT_CID); #endif #ifdef NECKO_PROTOCOL_data @@ -897,21 +893,19 @@ static const mozilla::Module::CIDEntry k #endif { &kNS_ABOUT_CACHE_MODULE_CID, false, NULL, nsAboutCache::Create }, { &kNS_ABOUT_CACHE_ENTRY_MODULE_CID, false, NULL, nsAboutCacheEntryConstructor }, #endif { &kNS_SOCKSSOCKETPROVIDER_CID, false, NULL, nsSOCKSSocketProvider::CreateV5 }, { &kNS_SOCKS4SOCKETPROVIDER_CID, false, NULL, nsSOCKSSocketProvider::CreateV4 }, { &kNS_UDPSOCKETPROVIDER_CID, false, NULL, nsUDPSocketProviderConstructor }, { &kNS_CACHESERVICE_CID, false, NULL, nsCacheService::Create }, -#ifdef NECKO_OFFLINE_CACHE { &kNS_APPLICATIONCACHESERVICE_CID, false, NULL, nsOfflineCacheDeviceConstructor }, { &kNS_APPLICATIONCACHENAMESPACE_CID, false, NULL, nsApplicationCacheNamespaceConstructor }, { &kNS_APPLICATIONCACHE_CID, false, NULL, nsApplicationCacheConstructor }, -#endif #ifdef NECKO_COOKIES { &kNS_COOKIEMANAGER_CID, false, NULL, nsICookieServiceConstructor }, { &kNS_COOKIESERVICE_CID, false, NULL, nsICookieServiceConstructor }, #endif #ifdef NECKO_WIFI { &kNS_WIFI_MONITOR_COMPONENT_CID, false, NULL, nsWifiMonitorConstructor }, #endif #ifdef NECKO_PROTOCOL_data @@ -1039,21 +1033,19 @@ static const mozilla::Module::ContractID #endif { NS_ABOUT_MODULE_CONTRACTID_PREFIX "cache", &kNS_ABOUT_CACHE_MODULE_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "cache-entry", &kNS_ABOUT_CACHE_ENTRY_MODULE_CID }, #endif { NS_NETWORK_SOCKET_CONTRACTID_PREFIX "socks", &kNS_SOCKSSOCKETPROVIDER_CID }, { NS_NETWORK_SOCKET_CONTRACTID_PREFIX "socks4", &kNS_SOCKS4SOCKETPROVIDER_CID }, { NS_NETWORK_SOCKET_CONTRACTID_PREFIX "udp", &kNS_UDPSOCKETPROVIDER_CID }, { NS_CACHESERVICE_CONTRACTID, &kNS_CACHESERVICE_CID }, -#ifdef NECKO_OFFLINE_CACHE { NS_APPLICATIONCACHESERVICE_CONTRACTID, &kNS_APPLICATIONCACHESERVICE_CID }, { NS_APPLICATIONCACHENAMESPACE_CONTRACTID, &kNS_APPLICATIONCACHENAMESPACE_CID }, { NS_APPLICATIONCACHE_CONTRACTID, &kNS_APPLICATIONCACHE_CID }, -#endif #ifdef NECKO_COOKIES { NS_COOKIEMANAGER_CONTRACTID, &kNS_COOKIEMANAGER_CID }, { NS_COOKIESERVICE_CONTRACTID, &kNS_COOKIESERVICE_CID }, #endif #ifdef NECKO_WIFI { NS_WIFI_MONITOR_CONTRACTID, &kNS_WIFI_MONITOR_COMPONENT_CID }, #endif #ifdef NECKO_PROTOCOL_data
--- a/netwerk/cache/Makefile.in +++ b/netwerk/cache/Makefile.in @@ -67,32 +67,25 @@ EXPORTS = \ CPPSRCS = \ nsCache.cpp \ nsCacheEntry.cpp \ nsCacheEntryDescriptor.cpp \ nsCacheMetaData.cpp \ nsCacheService.cpp \ nsCacheSession.cpp \ nsMemoryCacheDevice.cpp \ - nsDiskCacheDeviceSQL.cpp \ - $(NULL) - -ifdef NECKO_DISK_CACHE -CPPSRCS += \ nsDiskCacheBinding.cpp \ nsDiskCacheBlockFile.cpp \ nsDiskCacheDevice.cpp \ + nsDiskCacheDeviceSQL.cpp \ nsDiskCacheEntry.cpp \ nsDiskCacheMap.cpp \ nsDiskCacheStreams.cpp \ nsDeleteDir.cpp \ $(NULL) -endif - -DEFINES += -DNECKO_OFFLINE_CACHE LOCAL_INCLUDES = \ -I$(srcdir)/../base/src \ $(NULL) include $(topsrcdir)/config/rules.mk DEFINES += -DIMPL_NS_NET
--- a/netwerk/cache/nsCacheService.cpp +++ b/netwerk/cache/nsCacheService.cpp @@ -47,20 +47,17 @@ #include "nsCacheService.h" #include "nsCacheRequest.h" #include "nsCacheEntry.h" #include "nsCacheEntryDescriptor.h" #include "nsCacheDevice.h" #include "nsMemoryCacheDevice.h" #include "nsICacheVisitor.h" #include "nsDiskCacheDevice.h" - -#ifdef NECKO_OFFLINE_CACHE #include "nsDiskCacheDeviceSQL.h" -#endif #include "nsIMemoryReporter.h" #include "nsIObserverService.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" #include "nsIPrefBranch2.h" #include "nsILocalFile.h" #include "nsIOService.h" @@ -107,28 +104,24 @@ using namespace mozilla; static const char * observerList[] = { "profile-before-change", "profile-do-change", NS_XPCOM_SHUTDOWN_OBSERVER_ID, NS_PRIVATE_BROWSING_SWITCH_TOPIC }; static const char * prefList[] = { -#ifdef NECKO_DISK_CACHE DISK_CACHE_ENABLE_PREF, DISK_CACHE_SMART_SIZE_ENABLED_PREF, DISK_CACHE_CAPACITY_PREF, DISK_CACHE_DIR_PREF, DISK_CACHE_MAX_ENTRY_SIZE_PREF, -#endif -#ifdef NECKO_OFFLINE_CACHE OFFLINE_CACHE_ENABLE_PREF, OFFLINE_CACHE_CAPACITY_PREF, OFFLINE_CACHE_DIR_PREF, -#endif MEMORY_CACHE_ENABLE_PREF, MEMORY_CACHE_CAPACITY_PREF, MEMORY_CACHE_MAX_ENTRY_SIZE_PREF }; // Cache sizes, in KB const PRInt32 DEFAULT_CACHE_SIZE = 250 * 1024; // 250 MB const PRInt32 MIN_CACHE_SIZE = 50 * 1024; // 50 MB @@ -405,17 +398,16 @@ nsCacheProfilePrefObserver::Observe(nsIS // ignore pref changes until we're done switch profiles if (!mHaveProfile) return NS_OK; nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(subject, &rv); if (NS_FAILED(rv)) return rv; -#ifdef NECKO_DISK_CACHE // which preference changed? if (!strcmp(DISK_CACHE_ENABLE_PREF, data.get())) { if (!mInPrivateBrowsing) { rv = branch->GetBoolPref(DISK_CACHE_ENABLE_PREF, &mDiskCacheEnabled); if (NS_FAILED(rv)) return rv; @@ -473,20 +465,18 @@ nsCacheProfilePrefObserver::Observe(nsIS #if 0 } else if (!strcmp(DISK_CACHE_DIR_PREF, data.get())) { // XXX We probaby don't want to respond to this pref except after // XXX profile changes. Ideally, there should be somekind of user // XXX notification that the pref change won't take effect until // XXX the next time the profile changes (browser launch) #endif - } else -#endif // !NECKO_DISK_CACHE - -#ifdef NECKO_OFFLINE_CACHE + } else + // which preference changed? if (!strcmp(OFFLINE_CACHE_ENABLE_PREF, data.get())) { if (!mInPrivateBrowsing) { rv = branch->GetBoolPref(OFFLINE_CACHE_ENABLE_PREF, &mOfflineCacheEnabled); if (NS_FAILED(rv)) return rv; nsCacheService::SetOfflineCacheEnabled(OfflineCacheEnabled()); @@ -502,17 +492,16 @@ nsCacheProfilePrefObserver::Observe(nsIS #if 0 } else if (!strcmp(OFFLINE_CACHE_DIR_PREF, data.get())) { // XXX We probaby don't want to respond to this pref except after // XXX profile changes. Ideally, there should be some kind of user // XXX notification that the pref change won't take effect until // XXX the next time the profile changes (browser launch) #endif } else -#endif // !NECKO_OFFLINE_CACHE if (!strcmp(MEMORY_CACHE_ENABLE_PREF, data.get())) { rv = branch->GetBoolPref(MEMORY_CACHE_ENABLE_PREF, &mMemoryCacheEnabled); if (NS_FAILED(rv)) return rv; nsCacheService::SetMemoryCache(); @@ -534,49 +523,39 @@ nsCacheProfilePrefObserver::Observe(nsIS nsCacheService::SetMemoryCacheMaxEntrySize(mMemoryCacheMaxEntrySize); } } else if (!strcmp(NS_PRIVATE_BROWSING_SWITCH_TOPIC, topic)) { if (!strcmp(NS_PRIVATE_BROWSING_ENTER, data.get())) { mInPrivateBrowsing = PR_TRUE; nsCacheService::OnEnterExitPrivateBrowsing(); -#ifdef NECKO_DISK_CACHE mDiskCacheEnabled = PR_FALSE; nsCacheService::SetDiskCacheEnabled(DiskCacheEnabled()); -#endif // !NECKO_DISK_CACHE - -#ifdef NECKO_OFFLINE_CACHE + mOfflineCacheEnabled = PR_FALSE; nsCacheService::SetOfflineCacheEnabled(OfflineCacheEnabled()); -#endif // !NECKO_OFFLINE_CACHE } else if (!strcmp(NS_PRIVATE_BROWSING_LEAVE, data.get())) { mInPrivateBrowsing = PR_FALSE; nsCacheService::OnEnterExitPrivateBrowsing(); -#if defined(NECKO_DISK_CACHE) || defined(NECKO_OFFLINE_CACHE) nsCOMPtr<nsIPrefBranch> branch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; -#endif // !NECKO_DISK_CACHE && !NECKO_OFFLINE_CACHE - -#ifdef NECKO_DISK_CACHE + mDiskCacheEnabled = PR_TRUE; // by default enabled (void) branch->GetBoolPref(DISK_CACHE_ENABLE_PREF, &mDiskCacheEnabled); nsCacheService::SetDiskCacheEnabled(DiskCacheEnabled()); -#endif // !NECKO_DISK_CACHE - -#ifdef NECKO_OFFLINE_CACHE + mOfflineCacheEnabled = PR_TRUE; // by default enabled (void) branch->GetBoolPref(OFFLINE_CACHE_ENABLE_PREF, &mOfflineCacheEnabled); nsCacheService::SetOfflineCacheEnabled(OfflineCacheEnabled()); -#endif // !NECKO_OFFLINE_CACHE } } return NS_OK; } /* Computes our best guess for the default size of the user's disk cache, * based on the amount of space they have free on their hard drive. @@ -669,17 +648,16 @@ nsCacheProfilePrefObserver::PermittedToS } nsresult nsCacheProfilePrefObserver::ReadPrefs(nsIPrefBranch* branch) { nsresult rv = NS_OK; -#ifdef NECKO_DISK_CACHE // read disk cache device prefs if (!mInPrivateBrowsing) { mDiskCacheEnabled = PR_TRUE; // presume disk cache is enabled (void) branch->GetBoolPref(DISK_CACHE_ENABLE_PREF, &mDiskCacheEnabled); } mDiskCacheCapacity = DISK_CACHE_CAPACITY; (void)branch->GetIntPref(DISK_CACHE_CAPACITY_PREF, &mDiskCacheCapacity); @@ -765,19 +743,17 @@ nsCacheProfilePrefObserver::ReadPrefs(ns if (firstSmartSizeRun) { // It is no longer our first run rv = branch->SetBoolPref(DISK_CACHE_SMART_SIZE_FIRST_RUN_PREF, PR_FALSE); if (NS_FAILED(rv)) NS_WARNING("Failed setting first_run pref in ReadPrefs."); } } -#endif // !NECKO_DISK_CACHE - -#ifdef NECKO_OFFLINE_CACHE + // read offline cache device prefs if (!mInPrivateBrowsing) { mOfflineCacheEnabled = PR_TRUE; // presume offline cache is enabled (void) branch->GetBoolPref(OFFLINE_CACHE_ENABLE_PREF, &mOfflineCacheEnabled); } mOfflineCacheCapacity = OFFLINE_CACHE_CAPACITY; @@ -810,18 +786,17 @@ nsCacheProfilePrefObserver::ReadPrefs(ns // use current process directory during development rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR, getter_AddRefs(directory)); } #endif if (directory) mOfflineCacheParentDirectory = do_QueryInterface(directory, &rv); } -#endif // !NECKO_OFFLINE_CACHE - + // read memory cache device prefs (void) branch->GetBoolPref(MEMORY_CACHE_ENABLE_PREF, &mMemoryCacheEnabled); mMemoryCacheCapacity = -1; (void) branch->GetIntPref(MEMORY_CACHE_CAPACITY_PREF, &mMemoryCacheCapacity); (void) branch->GetIntPref(MEMORY_CACHE_MAX_ENTRY_SIZE_PREF, @@ -1116,26 +1091,22 @@ nsCacheService::Shutdown() // to be safe NS_UnregisterMemoryReporter(MemoryCacheReporter); MemoryCacheReporter = nsnull; // deallocate memory and disk caches delete mMemoryDevice; mMemoryDevice = nsnull; -#ifdef NECKO_DISK_CACHE delete mDiskDevice; mDiskDevice = nsnull; -#endif // !NECKO_DISK_CACHE - -#ifdef NECKO_OFFLINE_CACHE + NS_IF_RELEASE(mOfflineDevice); -#endif // !NECKO_OFFLINE_CACHE - -#if defined(NECKO_DISK_CACHE) && defined(PR_LOGGING) + +#ifdef PR_LOGGING LogCacheStatistics(); #endif mCacheIOThread.swap(cacheIOThread); } } // lock if (cacheIOThread) @@ -1216,44 +1187,40 @@ nsCacheService::EvictEntriesForClient(co NS_CACHESERVICE_EMPTYCACHE_TOPIC_ID, nsnull); } } nsCacheServiceAutoLock lock; nsresult res = NS_OK; -#ifdef NECKO_DISK_CACHE if (storagePolicy == nsICache::STORE_ANYWHERE || storagePolicy == nsICache::STORE_ON_DISK) { if (mEnableDiskDevice) { nsresult rv; if (!mDiskDevice) rv = CreateDiskDevice(); if (mDiskDevice) rv = mDiskDevice->EvictEntries(clientID); if (NS_FAILED(rv)) res = rv; } } -#endif // ! NECKO_DISK_CACHE - -#ifdef NECKO_OFFLINE_CACHE + // Only clear the offline cache if it has been specifically asked for. if (storagePolicy == nsICache::STORE_OFFLINE) { if (mEnableOfflineDevice) { nsresult rv; if (!mOfflineDevice) rv = CreateOfflineDevice(); if (mOfflineDevice) rv = mOfflineDevice->EvictEntries(clientID); if (NS_FAILED(rv)) res = rv; } } -#endif // ! NECKO_OFFLINE_CACHE if (storagePolicy == nsICache::STORE_ANYWHERE || storagePolicy == nsICache::STORE_IN_MEMORY) { // If there is no memory device, there is no need to evict it... if (mMemoryDevice) { nsresult rv; rv = mMemoryDevice->EvictEntries(clientID); @@ -1313,37 +1280,33 @@ NS_IMETHODIMP nsCacheService::VisitEntri nsresult rv = NS_OK; // If there is no memory device, there are then also no entries to visit... if (mMemoryDevice) { rv = mMemoryDevice->Visit(visitor); if (NS_FAILED(rv)) return rv; } -#ifdef NECKO_DISK_CACHE if (mEnableDiskDevice) { if (!mDiskDevice) { rv = CreateDiskDevice(); if (NS_FAILED(rv)) return rv; } rv = mDiskDevice->Visit(visitor); if (NS_FAILED(rv)) return rv; } -#endif // !NECKO_DISK_CACHE - -#ifdef NECKO_OFFLINE_CACHE + if (mEnableOfflineDevice) { if (!mOfflineDevice) { rv = CreateOfflineDevice(); if (NS_FAILED(rv)) return rv; } rv = mOfflineDevice->Visit(visitor); if (NS_FAILED(rv)) return rv; } -#endif // !NECKO_OFFLINE_CACHE // XXX notify any shutdown process that visitation is complete for THIS visitor. // XXX keep queue of visitors return NS_OK; } @@ -1364,17 +1327,16 @@ NS_IMETHODIMP nsCacheService::GetCacheIO } /** * Internal Methods */ nsresult nsCacheService::CreateDiskDevice() { -#ifdef NECKO_DISK_CACHE if (!mInitialized) return NS_ERROR_NOT_AVAILABLE; if (!mEnableDiskDevice) return NS_ERROR_NOT_AVAILABLE; if (mDiskDevice) return NS_OK; mDiskDevice = new nsDiskCacheDevice; if (!mDiskDevice) return NS_ERROR_OUT_OF_MEMORY; // set the preferences @@ -1390,26 +1352,21 @@ nsCacheService::CreateDiskDevice() printf("### - disabling disk cache for this session.\n"); printf("###\n"); #endif mEnableDiskDevice = PR_FALSE; delete mDiskDevice; mDiskDevice = nsnull; } return rv; -#else // !NECKO_DISK_CACHE - NS_NOTREACHED("nsCacheService::CreateDiskDevice"); - return NS_ERROR_NOT_IMPLEMENTED; -#endif } nsresult nsCacheService::CreateOfflineDevice() { -#ifdef NECKO_OFFLINE_CACHE CACHE_LOG_ALWAYS(("Creating offline device")); if (!mInitialized) return NS_ERROR_NOT_AVAILABLE; if (!mEnableOfflineDevice) return NS_ERROR_NOT_AVAILABLE; if (mOfflineDevice) return NS_OK; mOfflineDevice = new nsOfflineCacheDevice; if (!mOfflineDevice) return NS_ERROR_OUT_OF_MEMORY; @@ -1425,20 +1382,16 @@ nsCacheService::CreateOfflineDevice() if (NS_FAILED(rv)) { CACHE_LOG_DEBUG(("mOfflineDevice->Init() failed (0x%.8x)\n", rv)); CACHE_LOG_DEBUG((" - disabling offline cache for this session.\n")); mEnableOfflineDevice = PR_FALSE; NS_RELEASE(mOfflineDevice); } return rv; -#else // !NECKO_DISK_CACHE - NS_NOTREACHED("nsCacheService::CreateOfflineDevice"); - return NS_ERROR_NOT_IMPLEMENTED; -#endif } nsresult nsCacheService::CreateMemoryDevice() { if (!mInitialized) return NS_ERROR_NOT_AVAILABLE; if (!mEnableMemoryDevice) return NS_ERROR_NOT_AVAILABLE; if (mMemoryDevice) return NS_OK; @@ -1815,60 +1768,55 @@ nsCacheService::SearchCacheDevices(nsCSt CACHE_LOG_DEBUG(("Searching mMemoryDevice for key %s found: 0x%p, " "collision: %d\n", key->get(), entry, collision)); } } if (!entry && ((policy == nsICache::STORE_ANYWHERE) || (policy == nsICache::STORE_ON_DISK))) { -#ifdef NECKO_DISK_CACHE if (mEnableDiskDevice) { if (!mDiskDevice) { nsresult rv = CreateDiskDevice(); if (NS_FAILED(rv)) return nsnull; } entry = mDiskDevice->FindEntry(key, collision); } -#endif // !NECKO_DISK_CACHE } if (!entry && (policy == nsICache::STORE_OFFLINE || (policy == nsICache::STORE_ANYWHERE && gIOService->IsOffline()))) { -#ifdef NECKO_OFFLINE_CACHE if (mEnableOfflineDevice) { if (!mOfflineDevice) { nsresult rv = CreateOfflineDevice(); if (NS_FAILED(rv)) return nsnull; } entry = mOfflineDevice->FindEntry(key, collision); } -#endif // !NECKO_OFFLINE_CACHE } return entry; } nsCacheDevice * nsCacheService::EnsureEntryHasDevice(nsCacheEntry * entry) { nsCacheDevice * device = entry->CacheDevice(); // return device if found, possibly null if the entry is doomed i.e prevent // doomed entries to bind to a device (see e.g. bugs #548406 and #596443) if (device || entry->IsDoomed()) return device; PRInt64 predictedDataSize = entry->PredictedDataSize(); -#ifdef NECKO_DISK_CACHE if (entry->IsStreamData() && entry->IsAllowedOnDisk() && mEnableDiskDevice) { // this is the default if (!mDiskDevice) { (void)CreateDiskDevice(); // ignore the error (check for mDiskDevice instead) } if (mDiskDevice) { // Bypass the cache if Content-Length says the entry will be too big @@ -1882,17 +1830,16 @@ nsCacheService::EnsureEntryHasDevice(nsC entry->MarkBinding(); // enter state of binding nsresult rv = mDiskDevice->BindEntry(entry); entry->ClearBinding(); // exit state of binding if (NS_SUCCEEDED(rv)) device = mDiskDevice; } } -#endif // !NECKO_DISK_CACHE // if we can't use mDiskDevice, try mMemoryDevice if (!device && mEnableMemoryDevice && entry->IsAllowedInMemory()) { if (!mMemoryDevice) { (void)CreateMemoryDevice(); // ignore the error (check for mMemoryDevice instead) } if (mMemoryDevice) { // Bypass the cache if Content-Length says entry will be too big @@ -1906,32 +1853,30 @@ nsCacheService::EnsureEntryHasDevice(nsC entry->MarkBinding(); // enter state of binding nsresult rv = mMemoryDevice->BindEntry(entry); entry->ClearBinding(); // exit state of binding if (NS_SUCCEEDED(rv)) device = mMemoryDevice; } } -#ifdef NECKO_OFFLINE_CACHE if (!device && entry->IsStreamData() && entry->IsAllowedOffline() && mEnableOfflineDevice) { if (!mOfflineDevice) { (void)CreateOfflineDevice(); // ignore the error (check for mOfflineDevice instead) } if (mOfflineDevice) { entry->MarkBinding(); nsresult rv = mOfflineDevice->BindEntry(entry); entry->ClearBinding(); if (NS_SUCCEEDED(rv)) device = mOfflineDevice; } } -#endif // ! NECKO_OFFLINE_CACHE if (device) entry->SetCacheDevice(device); return device; } PRInt64 nsCacheService::MemoryDeviceSize() @@ -1999,35 +1944,31 @@ nsCacheService::OnProfileShutdown(PRBool gService->DoomActiveEntries(); gService->ClearDoomList(); // Make sure to wait for any pending cache-operations before // proceeding with destructive actions (bug #620660) (void) SyncWithCacheIOThread(); -#ifdef NECKO_DISK_CACHE if (gService->mDiskDevice && gService->mEnableDiskDevice) { if (cleanse) gService->mDiskDevice->EvictEntries(nsnull); gService->mDiskDevice->Shutdown(); } gService->mEnableDiskDevice = PR_FALSE; -#endif // !NECKO_DISK_CACHE - -#ifdef NECKO_OFFLINE_CACHE + if (gService->mOfflineDevice && gService->mEnableOfflineDevice) { if (cleanse) gService->mOfflineDevice->EvictEntries(nsnull); gService->mOfflineDevice->Shutdown(); } gService->mEnableOfflineDevice = PR_FALSE; -#endif // !NECKO_OFFLINE_CACHE if (gService->mMemoryDevice) { // clear memory cache gService->mMemoryDevice->EvictEntries(nsnull); } } @@ -2040,46 +1981,42 @@ nsCacheService::OnProfileChanged() CACHE_LOG_DEBUG(("nsCacheService::OnProfileChanged")); nsCacheServiceAutoLock lock; gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled(); gService->mEnableOfflineDevice = gService->mObserver->OfflineCacheEnabled(); gService->mEnableMemoryDevice = gService->mObserver->MemoryCacheEnabled(); -#ifdef NECKO_DISK_CACHE if (gService->mDiskDevice) { gService->mDiskDevice->SetCacheParentDirectory(gService->mObserver->DiskCacheParentDirectory()); gService->mDiskDevice->SetCapacity(gService->mObserver->DiskCacheCapacity()); // XXX initialization of mDiskDevice could be made lazily, if mEnableDiskDevice is false nsresult rv = gService->mDiskDevice->Init(); if (NS_FAILED(rv)) { NS_ERROR("nsCacheService::OnProfileChanged: Re-initializing disk device failed"); gService->mEnableDiskDevice = PR_FALSE; // XXX delete mDiskDevice? } } -#endif // !NECKO_DISK_CACHE - -#ifdef NECKO_OFFLINE_CACHE + if (gService->mOfflineDevice) { gService->mOfflineDevice->SetCacheParentDirectory(gService->mObserver->OfflineCacheParentDirectory()); gService->mOfflineDevice->SetCapacity(gService->mObserver->OfflineCacheCapacity()); // XXX initialization of mOfflineDevice could be made lazily, if mEnableOfflineDevice is false nsresult rv = gService->mOfflineDevice->Init(); if (NS_FAILED(rv)) { NS_ERROR("nsCacheService::OnProfileChanged: Re-initializing offline device failed"); gService->mEnableOfflineDevice = PR_FALSE; // XXX delete mOfflineDevice? } } -#endif // !NECKO_OFFLINE_CACHE - + // If memoryDevice exists, reset its size to the new profile if (gService->mMemoryDevice) { if (gService->mEnableMemoryDevice) { // make sure that capacity is reset to the right value PRInt32 capacity = gService->mObserver->MemoryCacheCapacity(); CACHE_LOG_DEBUG(("Resetting memory device capacity to %d\n", capacity)); gService->mMemoryDevice->SetCapacity(capacity); @@ -2103,37 +2040,33 @@ nsCacheService::SetDiskCacheEnabled(PRBo void nsCacheService::SetDiskCacheCapacity(PRInt32 capacity) { if (!gService) return; nsCacheServiceAutoLock lock; -#ifdef NECKO_DISK_CACHE if (gService->mDiskDevice) { gService->mDiskDevice->SetCapacity(capacity); } -#endif // !NECKO_DISK_CACHE - + if (gService->mObserver) gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled(); } void nsCacheService::SetDiskCacheMaxEntrySize(PRInt32 maxSize) { if (!gService) return; nsCacheServiceAutoLock lock; -#ifdef NECKO_DISK_CACHE if (gService->mDiskDevice) { gService->mDiskDevice->SetMaxEntrySize(maxSize); } -#endif // !NECKO_DISK_CACHE } void nsCacheService::SetMemoryCacheMaxEntrySize(PRInt32 maxSize) { if (!gService) return; nsCacheServiceAutoLock lock; @@ -2151,21 +2084,19 @@ nsCacheService::SetOfflineCacheEnabled(P } void nsCacheService::SetOfflineCacheCapacity(PRInt32 capacity) { if (!gService) return; nsCacheServiceAutoLock lock; -#ifdef NECKO_OFFLINE_CACHE if (gService->mOfflineDevice) { gService->mOfflineDevice->SetCapacity(capacity); } -#endif // !NECKO_OFFLINE_CACHE gService->mEnableOfflineDevice = gService->mObserver->OfflineCacheEnabled(); } void nsCacheService::SetMemoryCache() {
--- a/netwerk/necko-config.h.in +++ b/netwerk/necko-config.h.in @@ -32,18 +32,16 @@ * 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 ***** */ #ifndef _NECKO_CONFIG_H_ #define _NECKO_CONFIG_H_ -#undef NECKO_DISK_CACHE - #undef NECKO_COOKIES #undef NECKO_WIFI #undef NECKO_PROTOCOL_about #undef NECKO_PROTOCOL_data #undef NECKO_PROTOCOL_device #undef NECKO_PROTOCOL_file
--- a/other-licenses/android/APKOpen.cpp +++ b/other-licenses/android/APKOpen.cpp @@ -228,16 +228,17 @@ extern "C" NS_EXPORT void JNICALL \ Java_org_mozilla_gecko_GeckoAppShell_ ## name(JNIEnv *jenv, jclass jc, type1 one, type2 two, type3 three) \ { \ f_ ## name(jenv, jc, one, two, three); \ } SHELL_WRAPPER0(nativeInit) SHELL_WRAPPER1(nativeRun, jstring) SHELL_WRAPPER1(notifyGeckoOfEvent, jobject) +SHELL_WRAPPER0(processNextNativeEvent) SHELL_WRAPPER1(setSurfaceView, jobject) SHELL_WRAPPER0(onResume) SHELL_WRAPPER0(onLowMemory) SHELL_WRAPPER3(callObserver, jstring, jstring, jstring) SHELL_WRAPPER1(removeObserver, jstring) SHELL_WRAPPER2(onChangeNetworkLinkStatus, jstring, jstring) SHELL_WRAPPER1(reportJavaCrash, jstring) @@ -671,16 +672,17 @@ loadLibs(const char *apkName) if (!xul_handle) __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't get a handle to libxul!"); #define GETFUNC(name) f_ ## name = (name ## _t) __wrap_dlsym(xul_handle, "Java_org_mozilla_gecko_GeckoAppShell_" #name) GETFUNC(nativeInit); GETFUNC(nativeRun); GETFUNC(notifyGeckoOfEvent); + GETFUNC(processNextNativeEvent); GETFUNC(setSurfaceView); GETFUNC(onResume); GETFUNC(onLowMemory); GETFUNC(callObserver); GETFUNC(removeObserver); GETFUNC(onChangeNetworkLinkStatus); GETFUNC(reportJavaCrash); #undef GETFUNC
--- a/security/manager/pki/resources/content/viewCertDetails.js +++ b/security/manager/pki/resources/content/viewCertDetails.js @@ -254,17 +254,17 @@ function DisplayVerificationData(cert, r } else if (verifystate == cert.ISSUER_UNKNOWN) { verifystr = bundle.GetStringFromName('certNotVerified_IssuerUnknown'); } else if (verifystate == cert.INVALID_CA) { verifystr = bundle.GetStringFromName('certNotVerified_CAInvalid'); } else { /* if (verifystate == cert.NOT_VERIFIED_UNKNOWN || == USAGE_NOT_ALLOWED) */ verifystr = bundle.GetStringFromName('certNotVerified_Unknown'); } var verified=document.getElementById('verified'); - verified.setAttribute("value", verifystr); + verified.textContent = verifystr; if (count > 0) { var verifyInfoBox = document.getElementById('verify_info_box'); for (var i=0; i<count; i++) { AddUsage(usageList[i],verifyInfoBox); } } }
--- a/storage/test/test_file_perms.cpp +++ b/storage/test/test_file_perms.cpp @@ -44,18 +44,17 @@ * This file tests that the file permissions of the sqlite files match what * we request they be */ void test_file_perms() { nsCOMPtr<nsIFile> profDir; - nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, - getter_AddRefs(profDir)); + (void)NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(profDir)); nsCOMPtr<nsILocalFile> sqlite_file = do_QueryInterface(profDir); sqlite_file->Append(NS_LITERAL_STRING("places.sqlite")); PRUint32 perms = 0; sqlite_file->GetPermissions(&perms); // This reflexts the permissions defined by SQLITE_DEFAULT_FILE_PERMISSIONS in // db/sqlite3/src/Makefile.in and must be kept in sync with that #ifdef ANDROID
--- a/toolkit/components/places/PlacesUtils.jsm +++ b/toolkit/components/places/PlacesUtils.jsm @@ -2161,20 +2161,16 @@ XPCOMUtils.defineLazyServiceGetter(Place XPCOMUtils.defineLazyGetter(PlacesUtils, "bhistory", function() { return PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory); }); XPCOMUtils.defineLazyGetter(PlacesUtils, "ghistory2", function() { return PlacesUtils.history.QueryInterface(Ci.nsIGlobalHistory2); }); -XPCOMUtils.defineLazyGetter(PlacesUtils, "ghistory3", function() { - return PlacesUtils.history.QueryInterface(Ci.nsIGlobalHistory3); -}); - XPCOMUtils.defineLazyServiceGetter(PlacesUtils, "favicons", "@mozilla.org/browser/favicon-service;1", "nsIFaviconService"); XPCOMUtils.defineLazyServiceGetter(PlacesUtils, "bookmarks", "@mozilla.org/browser/nav-bookmarks-service;1", "nsINavBookmarksService");
--- a/toolkit/components/places/nsNavHistory.cpp +++ b/toolkit/components/places/nsNavHistory.cpp @@ -207,35 +207,33 @@ static const PRInt64 USECS_PER_DAY = LL_ NS_IMPL_THREADSAFE_ADDREF(nsNavHistory) NS_IMPL_THREADSAFE_RELEASE(nsNavHistory) NS_IMPL_CLASSINFO(nsNavHistory, NULL, nsIClassInfo::SINGLETON, NS_NAVHISTORYSERVICE_CID) NS_INTERFACE_MAP_BEGIN(nsNavHistory) NS_INTERFACE_MAP_ENTRY(nsINavHistoryService) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIGlobalHistory2, nsIGlobalHistory3) - NS_INTERFACE_MAP_ENTRY(nsIGlobalHistory3) + NS_INTERFACE_MAP_ENTRY(nsIGlobalHistory2) NS_INTERFACE_MAP_ENTRY(nsIDownloadHistory) NS_INTERFACE_MAP_ENTRY(nsIBrowserHistory) NS_INTERFACE_MAP_ENTRY(nsIObserver) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsICharsetResolver) NS_INTERFACE_MAP_ENTRY(nsPIPlacesDatabase) NS_INTERFACE_MAP_ENTRY(nsPIPlacesHistoryListenersNotifier) NS_INTERFACE_MAP_ENTRY(mozIStorageVacuumParticipant) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsINavHistoryService) NS_IMPL_QUERY_CLASSINFO(nsNavHistory) NS_INTERFACE_MAP_END // We don't care about flattening everything -NS_IMPL_CI_INTERFACE_GETTER5( +NS_IMPL_CI_INTERFACE_GETTER4( nsNavHistory , nsINavHistoryService -, nsIGlobalHistory3 , nsIGlobalHistory2 , nsIDownloadHistory , nsIBrowserHistory ) namespace { static PRInt64 GetSimpleBookmarksQueryFolder( @@ -466,18 +464,16 @@ nsNavHistory::Init() // recent events hash tables NS_ENSURE_TRUE(mRecentTyped.Init(RECENT_EVENTS_INITIAL_CACHE_SIZE), NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(mRecentLink.Init(RECENT_EVENTS_INITIAL_CACHE_SIZE), NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(mRecentBookmark.Init(RECENT_EVENTS_INITIAL_CACHE_SIZE), NS_ERROR_OUT_OF_MEMORY); - NS_ENSURE_TRUE(mRecentRedirects.Init(RECENT_EVENTS_INITIAL_CACHE_SIZE), - NS_ERROR_OUT_OF_MEMORY); // Embed visits hash table. NS_ENSURE_TRUE(mEmbedVisits.Init(EMBED_VISITS_INITIAL_CACHE_SIZE), NS_ERROR_OUT_OF_MEMORY); /***************************************************************************** *** IMPORTANT NOTICE! *** @@ -2721,19 +2717,18 @@ nsNavHistory::AddVisit(nsIURI* aURI, PRT // FIXME bug 325241: make a way to observe hidden URLs if (!hidden) { NotifyOnVisit(aURI, *aVisitID, aTime, aSessionID, referringVisitID, aTransitionType, guid); } // Normally docshell sends the link visited observer notification for us (this // will tell all the documents to update their visited link coloring). - // However, for redirects (since we implement nsIGlobalHistory3) and downloads - // (since we implement nsIDownloadHistory) this will not happen and we need to - // send it ourselves. + // However, for redirects and downloads (since we implement nsIDownloadHistory) + // this will not happen and we need to send it ourselves. if (newItem && (aIsRedirect || aTransitionType == TRANSITION_DOWNLOAD)) { nsCOMPtr<nsIObserverService> obsService = do_GetService(NS_OBSERVERSERVICE_CONTRACTID); if (obsService) obsService->NotifyObservers(aURI, NS_LINK_VISITED_EVENT_TOPIC, nsnull); } // Because we implement IHistory, we always have to notify about the visit. @@ -4834,21 +4829,17 @@ nsNavHistory::AddURIInternal(nsIURI* aUR // nsNavHistory::AddVisitChain // // This function is sits between AddURI (which is called when a page is // visited) and AddVisit (which creates the DB entries) to figure out what // we should add and what are the detailed parameters that should be used // (like referring visit ID and typed/bookmarked state). // // This function walks up the referring chain and recursively calls itself, -// each time calling InternalAdd to create a new history entry. (When we -// get notified of redirects, we don't actually add any history entries, just -// save them in mRecentRedirects. This function will add all of them for a -// given destination page when that page is actually visited.) -// See GetRedirectFor for more information about how redirects work. +// each time calling InternalAdd to create a new history entry. nsresult nsNavHistory::AddVisitChain(nsIURI* aURI, PRTime aTime, PRBool aToplevel, PRBool aIsRedirect, nsIURI* aReferrerURI, PRInt64* aVisitID, @@ -4864,62 +4855,20 @@ nsNavHistory::AddVisitChain(nsIURI* aURI // A visit is considered EMBED if it's in a frame and the page visit does not // come from a user's action (like clicking a link), otherwise is FRAMED_LINK. // An embed visit should not appear in history views. // See bug 381453 for details. PRBool isEmbedVisit = !aToplevel && !CheckIsRecentEvent(&mRecentLink, spec); - // Check if this visit came from a redirect. PRUint32 transitionType = 0; - PRTime redirectTime = 0; - nsCAutoString redirectSourceUrl; - if (GetRedirectFor(spec, redirectSourceUrl, &redirectTime, &transitionType)) { - // redirectSourceUrl redirected to aURL, at redirectTime, with - // a transitionType redirect. - nsCOMPtr<nsIURI> redirectSourceURI; - rv = NS_NewURI(getter_AddRefs(redirectSourceURI), redirectSourceUrl); - NS_ENSURE_SUCCESS(rv, rv); - - // Don't add a new visit if a page redirects to itself. - PRBool redirectIsSame; - if (NS_SUCCEEDED(aURI->Equals(redirectSourceURI, &redirectIsSame)) && - redirectIsSame) - return NS_OK; - - // Recusively call addVisitChain to walk up the chain till the first - // not-redirected URI. - // Ensure that the sources have a visit time smaller than aTime, otherwise - // visits would end up incorrectly ordered. - PRTime sourceTime = NS_MIN(redirectTime, aTime - 1); - PRInt64 sourceVisitId = 0; - rv = AddVisitChain(redirectSourceURI, sourceTime, aToplevel, - PR_TRUE, // Is a redirect. - aReferrerURI, // This one is the originating source. - &sourceVisitId, // Get back the visit id of the source. - aSessionID); - NS_ENSURE_SUCCESS(rv, rv); - - // All the visits for preceding pages in the redirects chain have been - // added, now add the visit to aURI. - if (isEmbedVisit) - transitionType = nsINavHistoryService::TRANSITION_EMBED; - else if (!aToplevel) - transitionType = nsINavHistoryService::TRANSITION_FRAMED_LINK; - - // This page is result of a redirect, save the source page in from_visit, - // to be able to walk up the chain. - // See bug 411966 and bug 428690 for details. - // TODO: Add a closure table with a chain id to easily reconstruct chains - // without having to recurse through the table. See bug 468710. - fromVisitURI = redirectSourceURI; - } - else if (aReferrerURI) { - // This page does not come from a redirect and had a referrer. + + if (aReferrerURI) { + // This page had a referrer. // Check if the referrer has a previous visit. PRTime lastVisitTime; PRInt64 referringVisitId; PRBool referrerHasPreviousVisit = FindLastVisit(aReferrerURI, &referringVisitId, &lastVisitTime, aSessionID); // Don't add a new visit if the referring site is the same as @@ -5077,117 +5026,16 @@ nsNavHistory::GetPageTitle(nsIURI* aURI, } rv = stmt->GetString(nsNavHistory::kGetInfoIndex_Title, aTitle); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } -// nsNavHistory::GetURIGeckoFlags -// -// FIXME: should we try to use annotations for this stuff? - -NS_IMETHODIMP -nsNavHistory::GetURIGeckoFlags(nsIURI* aURI, PRUint32* aResult) -{ - NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread"); - NS_ENSURE_ARG(aURI); - NS_ENSURE_ARG_POINTER(aResult); - - return NS_ERROR_NOT_IMPLEMENTED; -} - - -// nsNavHistory::SetURIGeckoFlags -// -// FIXME: should we try to use annotations for this stuff? - -NS_IMETHODIMP -nsNavHistory::SetURIGeckoFlags(nsIURI* aURI, PRUint32 aFlags) -{ - NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread"); - NS_ENSURE_ARG(aURI); - - return NS_ERROR_NOT_IMPLEMENTED; -} - -// nsIGlobalHistory3 *********************************************************** - -// nsNavHistory::AddDocumentRedirect -// -// This adds a redirect mapping from the destination of the redirect to the -// source, time, and type. This mapping is used by GetRedirectFor when we -// get a page added to reconstruct the redirects that happened when a page -// is visited. See GetRedirectFor for more information - -// this is the expiration callback function that deletes stale entries -PLDHashOperator nsNavHistory::ExpireNonrecentRedirects( - nsCStringHashKey::KeyType aKey, RedirectInfo& aData, void* aUserArg) -{ - PRInt64* threshold = reinterpret_cast<PRInt64*>(aUserArg); - if (aData.mTimeCreated < *threshold) - return PL_DHASH_REMOVE; - return PL_DHASH_NEXT; -} - -NS_IMETHODIMP -nsNavHistory::AddDocumentRedirect(nsIChannel *aOldChannel, - nsIChannel *aNewChannel, - PRInt32 aFlags, - PRBool aToplevel) -{ - NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread"); - NS_ENSURE_ARG(aOldChannel); - NS_ENSURE_ARG(aNewChannel); - - // Ignore internal redirects. - // These redirects are not initiated by the remote server, but specific to the - // channel implementation, so they are ignored. - if (aFlags & nsIChannelEventSink::REDIRECT_INTERNAL) - return NS_OK; - - nsresult rv; - nsCOMPtr<nsIURI> oldURI, newURI; - rv = aOldChannel->GetURI(getter_AddRefs(oldURI)); - NS_ENSURE_SUCCESS(rv, rv); - rv = aNewChannel->GetURI(getter_AddRefs(newURI)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCString oldSpec, newSpec; - rv = oldURI->GetSpec(oldSpec); - NS_ENSURE_SUCCESS(rv, rv); - rv = newURI->GetSpec(newSpec); - NS_ENSURE_SUCCESS(rv, rv); - - if (mRecentRedirects.Count() > RECENT_EVENT_QUEUE_MAX_LENGTH) { - // Expire outdated cached redirects. - PRInt64 threshold = PR_Now() - RECENT_EVENT_THRESHOLD; - mRecentRedirects.Enumerate(ExpireNonrecentRedirects, - reinterpret_cast<void*>(&threshold)); - } - - RedirectInfo info; - - // Remove any old entries for this redirect destination, since they are going - // to be replaced. - if (mRecentRedirects.Get(newSpec, &info)) - mRecentRedirects.Remove(newSpec); - // Save the new redirect info. - info.mSourceURI = oldSpec; - info.mTimeCreated = PR_Now(); - if (aFlags & nsIChannelEventSink::REDIRECT_TEMPORARY) - info.mType = TRANSITION_REDIRECT_TEMPORARY; - else - info.mType = TRANSITION_REDIRECT_PERMANENT; - mRecentRedirects.Put(newSpec, info); - - return NS_OK; -} - //////////////////////////////////////////////////////////////////////////////// //// mozIStorageVacuumParticipant NS_IMETHODIMP nsNavHistory::GetDatabaseConnection(mozIStorageConnection** _DBConnection) { return GetDBConnection(_DBConnection); @@ -6328,87 +6176,16 @@ void nsNavHistory::ExpireNonrecentEvents(RecentEventHash* hashTable) { PRInt64 threshold = GetNow() - RECENT_EVENT_THRESHOLD; hashTable->Enumerate(ExpireNonrecentEventsCallback, reinterpret_cast<void*>(&threshold)); } -// nsNavHistory::GetRedirectFor -// -// Given a destination URI, this finds a recent redirect that resulted in -// this URI. If it finds one, it will put the redirect source info into -// the out params and return true. If there is no matching redirect, it will -// return false. -// -// @param aDestination The destination URI spec of the redirect to look for. -// @param aSource Will be filled with the redirect source URI when a -// redirect is found. -// @param aTime Will be filled with the time the redirect happened -// when a redirect is found. -// @param aRedirectType Will be filled with the redirect type when a redirect -// is found. Will be either -// TRANSITION_REDIRECT_PERMANENT or -// TRANSITION_REDIRECT_TEMPORARY -// @returns True if the redirect is found. -// -// HOW REDIRECT TRACKING WORKS -// --------------------------- -// When we get an AddDocumentRedirect message, we store the redirect in -// our mRecentRedirects which maps the destination URI to a source,time pair. -// When we get a new URI, we see if there were any redirects to this page -// in the hash table. If found, we know that the page came through the given -// redirect and add it. -// -// Example: Page S redirects throught R1, then R2, to give page D. Page S -// will have been already added to history. -// - AddDocumentRedirect(R1, R2) -// - AddDocumentRedirect(R2, D) -// - AddURI(uri=D, referrer=S) -// -// When we get the AddURI(D), we see the hash table has a value for D from R2. -// We have to recursively check that source since there could be more than -// one redirect, as in this case. Here we see there was a redirect to R2 from -// R1. The referrer for D is S, so we know S->R1->R2->D. -// -// Alternatively, the user could have typed or followed a bookmark from S. -// In this case, with two redirects we'll get: -// - MarkPageAsTyped(S) -// - AddDocumentRedirect(S, R) -// - AddDocumentRedirect(R, D) -// - AddURI(uri=D, referrer=null) -// We need to be careful to add a visit to S in this case with an incoming -// transition of typed and an outgoing transition of redirect. -// -// Note that this can get confused in some cases where you have a page -// open in more than one window loading at the same time. This should be rare, -// however, and should not affect much. - -PRBool -nsNavHistory::GetRedirectFor(const nsACString& aDestination, - nsACString& aSource, - PRTime* aTime, - PRUint32* aRedirectType) -{ - RedirectInfo info; - if (mRecentRedirects.Get(aDestination, &info)) { - // Consume the redirect entry, it's no longer useful. - mRecentRedirects.Remove(aDestination); - if (info.mTimeCreated < GetNow() - RECENT_EVENT_THRESHOLD) - return PR_FALSE; // too long ago, probably invalid - aSource = info.mSourceURI; - *aTime = info.mTimeCreated; - *aRedirectType = info.mType; - return PR_TRUE; - } - return PR_FALSE; -} - - // nsNavHistory::RowToResult // // Here, we just have a generic row. It could be a query, URL, visit, // or full visit. nsresult nsNavHistory::RowToResult(mozIStorageValueArray* aRow, nsNavHistoryQueryOptions* aOptions,
--- a/toolkit/components/places/nsNavHistory.h +++ b/toolkit/components/places/nsNavHistory.h @@ -42,17 +42,16 @@ #ifndef nsNavHistory_h_ #define nsNavHistory_h_ #include "nsINavHistoryService.h" #include "nsPIPlacesDatabase.h" #include "nsPIPlacesHistoryListenersNotifier.h" #include "nsIBrowserHistory.h" #include "nsIGlobalHistory.h" -#include "nsIGlobalHistory3.h" #include "nsIDownloadHistory.h" #include "nsIPrefService.h" #include "nsIPrefBranch2.h" #include "nsIObserverService.h" #include "nsICollation.h" #include "nsIStringBundle.h" #include "nsITimer.h" @@ -96,19 +95,16 @@ #ifdef MOZ_XUL // Fired after autocomplete feedback has been updated. #define TOPIC_AUTOCOMPLETE_FEEDBACK_UPDATED "places-autocomplete-feedback-updated" #endif // Fired after frecency has been updated. #define TOPIC_FRECENCY_UPDATED "places-frecency-updated" -// Fired after frecency has been updated. -#define TOPIC_FRECENCY_UPDATED "places-frecency-updated" - // Fired when Places is shutting down. Any code should stop accessing Places // APIs after this notification. If you need to listen for Places shutdown // you should only use this notification, next ones are intended only for // internal Places use. #define TOPIC_PLACES_SHUTDOWN "places-shutdown" // For Internal use only. Fired when connection is about to be closed, only // cleanup tasks should run at this stage, nothing should be added to the // database, nor APIs should be called. @@ -166,33 +162,31 @@ class PlacesSQLQueryBuilder; class nsIAutoCompleteController; // nsNavHistory class nsNavHistory : public nsSupportsWeakReference , public nsINavHistoryService , public nsIObserver , public nsIBrowserHistory - , public nsIGlobalHistory3 , public nsIDownloadHistory , public nsICharsetResolver , public nsPIPlacesDatabase , public nsPIPlacesHistoryListenersNotifier , public mozIStorageVacuumParticipant { friend class PlacesSQLQueryBuilder; public: nsNavHistory(); NS_DECL_ISUPPORTS NS_DECL_NSINAVHISTORYSERVICE NS_DECL_NSIGLOBALHISTORY2 - NS_DECL_NSIGLOBALHISTORY3 NS_DECL_NSIDOWNLOADHISTORY NS_DECL_NSIBROWSERHISTORY NS_DECL_NSIOBSERVER NS_DECL_NSPIPLACESDATABASE NS_DECL_NSPIPLACESHISTORYLISTENERSNOTIFIER NS_DECL_MOZISTORAGEVACUUMPARTICIPANT @@ -845,29 +839,16 @@ protected: }; nsTHashtable<VisitHashKey> mEmbedVisits; PRBool CheckIsRecentEvent(RecentEventHash* hashTable, const nsACString& url); void ExpireNonrecentEvents(RecentEventHash* hashTable); - // redirect tracking. See GetRedirectFor for a description of how this works. - struct RedirectInfo { - nsCString mSourceURI; - PRTime mTimeCreated; - PRUint32 mType; // one of TRANSITION_REDIRECT_[TEMPORARY,PERMANENT] - }; - typedef nsDataHashtable<nsCStringHashKey, RedirectInfo> RedirectHash; - RedirectHash mRecentRedirects; - static PLDHashOperator ExpireNonrecentRedirects( - nsCStringHashKey::KeyType aKey, RedirectInfo& aData, void* aUserArg); - PRBool GetRedirectFor(const nsACString& aDestination, nsACString& aSource, - PRTime* aTime, PRUint32* aRedirectType); - // Sessions tracking. PRInt64 mLastSessionID; #ifdef MOZ_XUL nsresult AutoCompleteFeedback(PRInt32 aIndex, nsIAutoCompleteController *aController); #endif
--- a/toolkit/components/places/tests/mochitest/bug_411966/redirect.js +++ b/toolkit/components/places/tests/mochitest/bug_411966/redirect.js @@ -48,18 +48,16 @@ ok(Cc != null, "Access Cc"); var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"]. getService(Ci.nsINavHistoryService); ok(histsvc != null, "Could not get History Service"); var bhist = histsvc.QueryInterface(Ci.nsIBrowserHistory); ok(bhist != null, "Could not get Browser History Service"); var ghist = Cc["@mozilla.org/browser/global-history;2"]. getService(Ci.nsIGlobalHistory2); ok(ghist != null, "Could not get Global History Service"); -var ghist3 = ghist.QueryInterface(Ci.nsIGlobalHistory3); -ok(ghist3 != null, "Could not get Global History Service"); var ios = Cc["@mozilla.org/network/io-service;1"]. getService(Components.interfaces.nsIIOService); ok(ios != null, "Could not get IO Service"); var storage = Cc["@mozilla.org/storage/service;1"]. getService(Ci.mozIStorageService); ok(storage != null, "Could not get Storage Service"); // Get database connection. @@ -108,17 +106,16 @@ StreamListener.prototype = { throw("Could not get page."); this.mChannel = null; }, // nsIChannelEventSink asyncOnChannelRedirect: function (aOldChannel, aNewChannel, aFlags, callback) { netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); - ghist3.addDocumentRedirect(aOldChannel, aNewChannel, aFlags, true); // If redirecting, store the new channel this.mChannel = aNewChannel; callback.onRedirectVerifyCallback(Components.results.NS_OK); }, // nsIInterfaceRequestor getInterface: function (aIID) { netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
--- a/toolkit/components/places/tests/network/test_history_redirects.js +++ b/toolkit/components/places/tests/network/test_history_redirects.js @@ -3,17 +3,16 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ /* Tests history redirects handling */ let hs = Cc["@mozilla.org/browser/nav-history-service;1"]. getService(Ci.nsINavHistoryService); let bh = hs.QueryInterface(Ci.nsIBrowserHistory); -let ghist3 = hs.QueryInterface(Ci.nsIGlobalHistory3); const PERMA_REDIR_PATH = "/permaredir"; const TEMP_REDIR_PATH = "/tempredir"; const FOUND_PATH = "/found"; const HTTPSVR = new nsHttpServer(); const PORT = 4444; HTTPSVR.registerPathHandler(PERMA_REDIR_PATH, permaRedirHandler); @@ -176,23 +175,18 @@ ChannelListener.prototype = { do_log_info("onStopRequest"); this._got_onstoprequest++; let success = Components.isSuccessCode(status); do_check_true(success); do_check_true(this._got_onstartrequest); do_check_true(this._got_onchannelredirect); do_check_true(this._buffer.length > 0); - // The referrer is wrong since it's the first element in the redirects - // chain, but this is good, since it will test a special path. - ghist3.addURI(uri(FOUND_URL), false, true, uri(PERMA_REDIR_URL)); - continue_test(); }, // nsIChannelEventSink asyncOnChannelRedirect: function (aOldChannel, aNewChannel, aFlags, callback) { do_log_info("onChannelRedirect"); this._got_onchannelredirect = true; - ghist3.addDocumentRedirect(aOldChannel, aNewChannel, aFlags, true); callback.onRedirectVerifyCallback(Components.results.NS_OK); }, };
--- a/toolkit/content/aboutSupport.js +++ b/toolkit/content/aboutSupport.js @@ -61,17 +61,16 @@ const PREFS_WHITELIST = [ "browser.zoom.", "dom.", "extensions.checkCompatibility", "extensions.lastAppVersion", "font.", "general.useragent.", "gfx.", "html5.", - "mozilla.widget.render-mode", "layers.", "javascript.", "keyword.", "layout.css.dpi", "network.", "places.", "plugin.", "plugins.",
--- a/toolkit/toolkit-makefiles.sh +++ b/toolkit/toolkit-makefiles.sh @@ -317,17 +317,16 @@ MAKEFILES_libvorbis=" media/libvorbis/lib/Makefile media/libvorbis/include/Makefile media/libvorbis/include/vorbis/Makefile " MAKEFILES_libtremor=" media/libtremor/Makefile media/libtremor/lib/Makefile - media/libtremor/include/Makefile media/libtremor/include/tremor/Makefile " MAKEFILES_libvpx=" media/libvpx/Makefile " MAKEFILES_libtheora="
--- a/widget/public/nsILookAndFeel.h +++ b/widget/public/nsILookAndFeel.h @@ -245,16 +245,26 @@ public: * being used. * * The value of this metric is not used on other platforms. These platforms * should return NS_ERROR_NOT_IMPLEMENTED when queried for this metric. */ eMetric_MacGraphiteTheme, /* + * A Boolean value to determine whether the Mac OS X Lion-specific theming + * should be used. + * + * The value of this metric is not used on non-Mac platforms. These + * platforms should return NS_ERROR_NOT_IMPLEMENTED when queried for this + * metric. + */ + eMetric_MacLionTheme, + + /* * A Boolean value to determine whether Mameo is using the new Fremantle * theme. * * The value of this metric is not used on other platforms. These platforms * should return NS_ERROR_NOT_IMPLEMENTED when queried for this metric. */ eMetric_MaemoClassic,
--- a/widget/src/android/AndroidJNI.cpp +++ b/widget/src/android/AndroidJNI.cpp @@ -59,16 +59,17 @@ using namespace mozilla; /* Forward declare all the JNI methods as extern "C" */ extern "C" { NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_nativeInit(JNIEnv *, jclass); NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoOfEvent(JNIEnv *, jclass, jobject event); + NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_processNextNativeEvent(JNIEnv *, jclass); NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_setSurfaceView(JNIEnv *jenv, jclass, jobject sv); NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onResume(JNIEnv *, jclass); NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onLowMemory(JNIEnv *, jclass); NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_callObserver(JNIEnv *, jclass, jstring observerKey, jstring topic, jstring data); NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_removeObserver(JNIEnv *jenv, jclass, jstring jObserverKey); NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus(JNIEnv *, jclass, jstring status, jstring type); NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_reportJavaCrash(JNIEnv *, jclass, jstring stack); } @@ -88,16 +89,24 @@ NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoOfEvent(JNIEnv *jenv, jclass jc, jobject event) { // poke the appshell if (nsAppShell::gAppShell) nsAppShell::gAppShell->PostEvent(new AndroidGeckoEvent(jenv, event)); } NS_EXPORT void JNICALL +Java_org_mozilla_gecko_GeckoAppShell_processNextNativeEvent(JNIEnv *jenv, jclass) +{ + // poke the appshell + if (nsAppShell::gAppShell) + nsAppShell::gAppShell->ProcessNextNativeEvent(PR_FALSE); +} + +NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_setSurfaceView(JNIEnv *jenv, jclass, jobject obj) { AndroidBridge::Bridge()->SetSurfaceView(jenv->NewGlobalRef(obj)); } NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onLowMemory(JNIEnv *jenv, jclass jc) {
--- a/widget/src/android/AndroidJavaWrappers.cpp +++ b/widget/src/android/AndroidJavaWrappers.cpp @@ -453,16 +453,29 @@ AndroidGeckoEvent::Init(int aType) void AndroidGeckoEvent::Init(int x1, int y1, int x2, int y2) { mType = DRAW; mRect.SetEmpty(); } void +AndroidGeckoEvent::Init(AndroidGeckoEvent *aResizeEvent) +{ + NS_ASSERTION(aResizeEvent->Type() == SIZE_CHANGED, "Init called on non-SIZE_CHANGED event"); + + mType = FORCED_RESIZE; + mTime = aResizeEvent->mTime; + mP0.x = aResizeEvent->mP0.x; + mP0.y = aResizeEvent->mP0.y; + mP1.x = aResizeEvent->mP1.x; + mP1.y = aResizeEvent->mP1.y; +} + +void AndroidGeckoSurfaceView::Init(jobject jobj) { NS_ASSERTION(wrapped_obj == nsnull, "Init called on non-null wrapped_obj!"); wrapped_obj = jobj; } int
--- a/widget/src/android/AndroidJavaWrappers.h +++ b/widget/src/android/AndroidJavaWrappers.h @@ -381,20 +381,24 @@ public: Init(aType); } AndroidGeckoEvent(int x1, int y1, int x2, int y2) { Init(x1, y1, x2, y2); } AndroidGeckoEvent(JNIEnv *jenv, jobject jobj) { Init(jenv, jobj); } + AndroidGeckoEvent(