diff --git a/b2g/chrome/content/commandUtil.js b/b2g/chrome/content/commandUtil.js deleted file mode 100644 index 5482d16a5b8..00000000000 --- a/b2g/chrome/content/commandUtil.js +++ /dev/null @@ -1,165 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Command Updater - */ -let CommandUpdater = { - /** - * Gets a controller that can handle a particular command. - * @param {string} command - * A command to locate a controller for, preferring controllers that - * show the command as enabled. - * @return {object} In this order of precedence: - * - the first controller supporting the specified command - * associated with the focused element that advertises the - * command as ENABLED. - * - the first controller supporting the specified command - * associated with the global window that advertises the - * command as ENABLED. - * - the first controller supporting the specified command - * associated with the focused element. - * - the first controller supporting the specified command - * associated with the global window. - */ - _getControllerForCommand: function(command) { - try { - let commandDispatcher = top.document.commandDispatcher; - let controller = commandDispatcher.getControllerForCommand(command); - if (controller && controller.isCommandEnabled(command)) - return controller; - } - catch (e) { } - - let controllerCount = window.controllers.getControllerCount(); - for (let i = 0; i < controllerCount; ++i) { - let current = window.controllers.getControllerAt(i); - try { - if (current.supportsCommand(command) && - current.isCommandEnabled(command)) - return current; - } - catch (e) { } - } - return controller || window.controllers.getControllerForCommand(command); - }, - - /** - * Updates the state of a XUL element for the specified command - * depending on its state. - * @param {string} command - * The name of the command to update the XUL element for. - */ - updateCommand: function(command) { - let enabled = false; - try { - let controller = this._getControllerForCommand(command); - if (controller) { - enabled = controller.isCommandEnabled(command); - } - } - catch (ex) { } - - this.enableCommand(command, enabled); - }, - - /** - * Updates the state of a XUL element for the specified command - * depending on its state. - * @param {string} command - * The name of the command to update the XUL element for. - */ - updateCommands: function(_commands) { - let commands = _commands.split(','); - for (let command in commands) { - this.updateCommand(commands[command]); - } - }, - - /** - * Enables or disables a XUL element. - * @param {string} command - * The name of the command to enable or disable. - * @param {bool} enabled - * true if the command should be enabled, false otherwise. - */ - enableCommand: function(command, enabled) { - let element = document.getElementById(command); - if (!element) - return; - - if (enabled) - element.removeAttribute('disabled'); - else - element.setAttribute('disabled', 'true'); - }, - - /** - * Performs the action associated with a specified command using the most - * relevant controller. - * @param {string} command - * The command to perform. - */ - doCommand: function(command) { - let controller = this._getControllerForCommand(command); - if (!controller) - return; - controller.doCommand(command); - }, - - /** - * Changes the label attribute for the specified command. - * @param {string} command - * The command to update. - * @param {string} labelAttribute - * The label value to use. - */ - setMenuValue: function(command, labelAttribute) { - let commandNode = top.document.getElementById(command); - if (commandNode) { - let label = commandNode.getAttribute(labelAttribute); - if (label) - commandNode.setAttribute('label', label); - } - }, - - /** - * Changes the accesskey attribute for the specified command. - * @param {string} command - * The command to update. - * @param {string} valueAttribute - * The value attribute to use. - */ - setAccessKey: function(command, valueAttribute) { - let commandNode = top.document.getElementById(command); - if (commandNode) { - let value = commandNode.getAttribute(valueAttribute); - if (value) - commandNode.setAttribute('accesskey', value); - } - }, - - /** - * Inform all the controllers attached to a node that an event has occurred - * (e.g. the tree controllers need to be informed of blur events so that they - * can change some of the menu items back to their default values) - * @param {node} node - * The node receiving the event. - * @param {event} event - * The event. - */ - onEvent: function(node, event) { - let numControllers = node.controllers.getControllerCount(); - let controller; - - for (let i = 0; i < numControllers; i++) { - controller = node.controllers.getControllerAt(i); - if (controller) - controller.onEvent(event); - } - } -}; - diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js index ec3c8e5b02d..1fa02a83c1e 100644 --- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -33,11 +33,15 @@ XPCOMUtils.defineLazyGetter(Services, 'idle', function() { .getService(Ci.nsIIdleService); }); -XPCOMUtils.defineLazyServiceGetter(Services, 'fm', function(){ - return Cc['@mozilla.org/focus-managr;1'] - .getService(Ci.nsFocusManager); +XPCOMUtils.defineLazyGetter(Services, 'audioManager', function() { + return Cc['@mozilla.org/telephony/audiomanager;1'] + .getService(Ci.nsIAudioManager); }); +XPCOMUtils.defineLazyServiceGetter(Services, 'fm', function() { + return Cc['@mozilla.org/focus-manager;1'] + .getService(Ci.nsFocusManager); +}); #ifndef MOZ_WIDGET_GONK // In order to use http:// scheme instead of file:// scheme @@ -74,9 +78,6 @@ function addPermissions(urls) { } var shell = { - // FIXME/bug 678695: this should be a system setting - preferredScreenBrightness: 1.0, - isDebug: false, get contentBrowser() { @@ -111,13 +112,23 @@ var shell = { return alert(msg); } - window.controllers.appendController(this); - window.addEventListener('keypress', this); + ['keydown', 'keypress', 'keyup'].forEach((function listenKey(type) { + window.addEventListener(type, this, false, true); + window.addEventListener(type, this, true, true); + }).bind(this)); + window.addEventListener('MozApplicationManifest', this); - window.addEventListener("AppCommand", this); window.addEventListener('mozfullscreenchange', this); this.contentBrowser.addEventListener('load', this, true); + // Until the volume can be set from the content side, set it to a + // a specific value when the device starts. This way the front-end + // can display a notification when the volume change and show a volume + // level modified from this point. + try { + Services.audioManager.masterVolume = 0.5; + } catch(e) {} + try { Services.io.offline = false; @@ -159,35 +170,8 @@ var shell = { }, stop: function shell_stop() { - window.controllers.removeController(this); - window.removeEventListener('keypress', this); window.removeEventListener('MozApplicationManifest', this); - window.removeEventListener('AppCommand', this); - }, - - supportsCommand: function shell_supportsCommand(cmd) { - let isSupported = false; - switch (cmd) { - case 'cmd_close': - isSupported = true; - break; - default: - isSupported = false; - break; - } - return isSupported; - }, - - isCommandEnabled: function shell_isCommandEnabled(cmd) { - return true; - }, - - doCommand: function shell_doCommand(cmd) { - switch (cmd) { - case 'cmd_close': - content.postMessage('appclose', '*'); - break; - } + window.removeEventListener('mozfullscreenchange', this); }, toggleDebug: function shell_toggleDebug() { @@ -202,9 +186,7 @@ var shell = { } }, - changeVolume: function shell_changeVolume(aDelta) { - let audioManager = Cc["@mozilla.org/telephony/audiomanager;1"].getService(Ci.nsIAudioManager); - + changeVolume: function shell_changeVolume(delta) { let steps = 10; try { steps = Services.prefs.getIntPref("media.volume.steps"); @@ -212,7 +194,11 @@ var shell = { steps = 1; } catch(e) {} - let volume = audioManager.masterVolume + aDelta / steps; + let audioManager = Services.audioManager; + if (!audioManager) + return; + + let volume = audioManager.masterVolume + delta / steps; if (volume > 1) volume = 1; if (volume < 0) @@ -220,44 +206,58 @@ var shell = { audioManager.masterVolume = volume; }, + forwardKeyToHomescreen: function shell_forwardKeyToHomescreen(evt) { + let generatedEvent = content.document.createEvent('KeyboardEvent'); + generatedEvent.initKeyEvent(evt.type, true, true, evt.view, evt.ctrlKey, + evt.altKey, evt.shiftKey, evt.metaKey, + evt.keyCode, evt.charCode); + + content.dispatchEvent(generatedEvent); + }, + handleEvent: function shell_handleEvent(evt) { switch (evt.type) { + case 'keydown': + case 'keyup': case 'keypress': - switch (evt.keyCode) { - case evt.DOM_VK_HOME: - this.sendEvent(content, 'home'); - break; - case evt.DOM_VK_SLEEP: - this.toggleScreen(); - - let details = { - 'enabled': screen.mozEnabled - }; - this.sendEvent(content, 'sleep', details); - break; - case evt.DOM_VK_ESCAPE: - if (evt.defaultPrevented) - return; - this.doCommand('cmd_close'); - break; + // If the home key is pressed, always forward it to the homescreen + if (evt.eventPhase == evt.CAPTURING_PHASE) { + if (evt.keyCode == evt.VK_DOM_HOME) { + window.setTimeout(this.forwardKeyToHomescreen, 0, evt); + evt.preventDefault(); + evt.stopPropagation(); + } + return; } - break; - case 'AppCommand': - switch (evt.command) { - case 'Menu': - if (Services.prefs.getBoolPref('b2g.keys.menu.enabled')) - this.sendEvent(content, 'menu'); - break; - case 'Search': - if (Services.prefs.getBoolPref('b2g.keys.search.enabled')) - this.toggleDebug(); - break; - case 'VolumeUp': - this.changeVolume(1); - break; - case 'VolumeDown': - this.changeVolume(-1); - break; + + // If one of the other keys is used in an application and is + // cancelled via preventDefault, do nothing. + let homescreen = (evt.target.ownerDocument.defaultView == content); + if (!homescreen && evt.defaultPrevented) + return; + + // If one of the other keys is used in an application and is + // not used forward it to the homescreen + if (!homescreen) + window.setTimeout(this.forwardKeyToHomescreen, 0, evt); + + // For debug purposes and because some of the APIs are not yet exposed + // to the content, let's react on some of the keyup events. + if (evt.type == 'keyup') { + switch (evt.keyCode) { + case evt.DOM_VK_F5: + if (Services.prefs.getBoolPref('b2g.keys.search.enabled')) + this.toggleDebug(); + break; + + case evt.DOM_VK_PAGE_DOWN: + this.changeVolume(-1); + break; + + case evt.DOM_VK_PAGE_UP: + this.changeVolume(1); + break; + } } break; @@ -270,7 +270,6 @@ var shell = { break; case 'load': this.contentBrowser.removeEventListener('load', this, true); - this.turnScreenOn(); let chromeWindow = window.QueryInterface(Ci.nsIDOMChromeWindow); chromeWindow.browserDOMWindow = new nsBrowserAccess(); @@ -317,20 +316,6 @@ var shell = { let event = content.document.createEvent('CustomEvent'); event.initCustomEvent(type, true, true, details ? details : {}); content.dispatchEvent(event); - }, - toggleScreen: function shell_toggleScreen() { - if (screen.mozEnabled) - this.turnScreenOff(); - else - this.turnScreenOn(); - }, - turnScreenOff: function shell_turnScreenOff() { - screen.mozEnabled = false; - screen.mozBrightness = 0.0; - }, - turnScreenOn: function shell_turnScreenOn() { - screen.mozEnabled = true; - screen.mozBrightness = this.preferredScreenBrightness; } }; @@ -339,7 +324,7 @@ var shell = { observe: function(subject, topic, time) { if (topic === "idle") { // TODO: Check wakelock status. See bug 697132. - shell.turnScreenOff(); + screen.mozEnabled = false; } }, } diff --git a/b2g/chrome/content/shell.xul b/b2g/chrome/content/shell.xul index 92f35b486b4..d4e623a565e 100644 --- a/b2g/chrome/content/shell.xul +++ b/b2g/chrome/content/shell.xul @@ -15,7 +15,6 @@ onload="shell.start();" onunload="shell.stop();"> - + diff --git a/dom/plugins/test/reftest/reftest.list b/dom/plugins/test/reftest/reftest.list index 397ebfc69f0..d49eb38e5a6 100644 --- a/dom/plugins/test/reftest/reftest.list +++ b/dom/plugins/test/reftest/reftest.list @@ -1,6 +1,9 @@ # basic sanity checking random-if(!haveTestPlugin) != plugin-sanity.html about:blank +random-if(!haveTestPlugin) != plugin-asyncbitmap-sanity.html about:blank fails-if(!haveTestPlugin) == plugin-sanity.html div-sanity.html +fails-if(!haveTestPlugin) == plugin-asyncbitmap-sanity.html div-sanity.html +skip-if(!haveTestPlugin) == plugin-asyncbitmap-update.html plugin-async-update-ref.html fails-if(!haveTestPlugin) == plugin-alpha-zindex.html div-alpha-zindex.html fails-if(!haveTestPlugin) == plugin-alpha-opacity.html div-alpha-opacity.html random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == windowless-clipping-1.html windowless-clipping-1-ref.html # bug 631832 diff --git a/dom/plugins/test/testplugin/nptest.cpp b/dom/plugins/test/testplugin/nptest.cpp index 261260659e4..e0698a81c36 100644 --- a/dom/plugins/test/testplugin/nptest.cpp +++ b/dom/plugins/test/testplugin/nptest.cpp @@ -540,6 +540,39 @@ DuplicateNPVariant(NPVariant& aDest, const NPVariant& aSrc) } } +void +drawAsyncBitmapColor(InstanceData* instanceData) +{ + NPP npp = instanceData->npp; + + PRUint32 *pixelData = (PRUint32*)instanceData->backBuffer->bitmap.data; + + PRUint32 rgba = instanceData->scriptableObject->drawColor; + + unsigned char subpixels[4]; + subpixels[0] = rgba & 0xFF; + subpixels[1] = (rgba & 0xFF00) >> 8; + subpixels[2] = (rgba & 0xFF0000) >> 16; + subpixels[3] = (rgba & 0xFF000000) >> 24; + + subpixels[0] = PRUint8(float(subpixels[3] * subpixels[0]) / 0xFF); + subpixels[1] = PRUint8(float(subpixels[3] * subpixels[1]) / 0xFF); + subpixels[2] = PRUint8(float(subpixels[3] * subpixels[2]) / 0xFF); + PRUint32 premultiplied; + memcpy(&premultiplied, subpixels, sizeof(premultiplied)); + + for (PRUint32* lastPixel = pixelData + instanceData->backBuffer->size.width * instanceData->backBuffer->size.height; + pixelData < lastPixel; + ++pixelData) { + *pixelData = premultiplied; + } + + NPN_SetCurrentAsyncSurface(npp, instanceData->backBuffer, NULL); + NPAsyncSurface *oldFront = instanceData->frontBuffer; + instanceData->frontBuffer = instanceData->backBuffer; + instanceData->backBuffer = oldFront; +} + // // function signatures // @@ -746,6 +779,9 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* instanceData->eventModel = 0; instanceData->closeStream = false; instanceData->wantsAllStreams = false; + instanceData->asyncDrawing = AD_NONE; + instanceData->frontBuffer = NULL; + instanceData->backBuffer = NULL; instance->pdata = instanceData; TestNPObject* scriptableObject = (TestNPObject*)NPN_CreateObject(instance, &sNPClass); @@ -782,6 +818,13 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* requestWindow = true; } } + else if (strcmp(argn[i], "asyncmodel") == 0) { + if (strcmp(argv[i], "bitmap") == 0) { + if (pluginSupportsAsyncBitmapDrawing()) { + instanceData->asyncDrawing = AD_BITMAP; + } + } + } if (strcmp(argn[i], "streammode") == 0) { if (strcmp(argv[i], "normal") == 0) { instanceData->streamMode = NP_NORMAL; @@ -884,6 +927,16 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* NPN_SetValue(instance, NPPVpluginTransparentBool, (void*)true); } + if (instanceData->asyncDrawing == AD_BITMAP) { + NPBool supportsAsyncBitmap = false; + if ((NPN_GetValue(instance, NPNVsupportsAsyncBitmapSurfaceBool, &supportsAsyncBitmap) == NPERR_NO_ERROR) && + supportsAsyncBitmap) { + NPN_SetValue(instance, NPPVpluginDrawingModel, (void*)NPDrawingModelAsyncBitmapSurface); + } else { + instanceData->asyncDrawing = AD_NONE; + } + } + instanceData->lastReportedPrivateModeState = false; instanceData->lastMouseX = instanceData->lastMouseY = -1; instanceData->widthAtLastPaint = -1; @@ -969,6 +1022,16 @@ NPP_Destroy(NPP instance, NPSavedData** save) currentrange = nextrange; } + if (instanceData->frontBuffer) { + NPN_SetCurrentAsyncSurface(instance, NULL, NULL); + NPN_FinalizeAsyncSurface(instance, instanceData->frontBuffer); + NPN_MemFree(instanceData->frontBuffer); + } + if (instanceData->backBuffer) { + NPN_FinalizeAsyncSurface(instance, instanceData->backBuffer); + NPN_MemFree(instanceData->backBuffer); + } + pluginInstanceShutdown(instanceData); NPN_ReleaseObject(instanceData->scriptableObject); @@ -1000,6 +1063,35 @@ NPP_SetWindow(NPP instance, NPWindow* window) if (instanceData->hasWidget && oldWindow != instanceData->window.window) { pluginWidgetInit(instanceData, oldWindow); } + + if (instanceData->asyncDrawing == AD_BITMAP) { + if (instanceData->frontBuffer && + instanceData->frontBuffer->size.width == window->width && + instanceData->frontBuffer->size.height == window->height) { + return NPERR_NO_ERROR; + } + if (instanceData->frontBuffer) { + NPN_FinalizeAsyncSurface(instance, instanceData->frontBuffer); + NPN_MemFree(instanceData->frontBuffer); + } + if (instanceData->backBuffer) { + NPN_FinalizeAsyncSurface(instance, instanceData->backBuffer); + NPN_MemFree(instanceData->backBuffer); + } + instanceData->frontBuffer = (NPAsyncSurface*)NPN_MemAlloc(sizeof(NPAsyncSurface)); + instanceData->backBuffer = (NPAsyncSurface*)NPN_MemAlloc(sizeof(NPAsyncSurface)); + + NPSize size; + size.width = window->width; + size.height = window->height; + + memcpy(instanceData->backBuffer, instanceData->frontBuffer, sizeof(NPAsyncSurface)); + + NPN_InitAsyncSurface(instance, &size, NPImageFormatBGRA32, NULL, instanceData->frontBuffer); + NPN_InitAsyncSurface(instance, &size, NPImageFormatBGRA32, NULL, instanceData->backBuffer); + + drawAsyncBitmapColor(instanceData); + } return NPERR_NO_ERROR; } @@ -1751,6 +1843,25 @@ NPN_URLRedirectResponse(NPP instance, void* notifyData, NPBool allow) return sBrowserFuncs->urlredirectresponse(instance, notifyData, allow); } +NPError +NPN_InitAsyncSurface(NPP instance, NPSize *size, NPImageFormat format, + void *initData, NPAsyncSurface *surface) +{ + return sBrowserFuncs->initasyncsurface(instance, size, format, initData, surface); +} + +NPError +NPN_FinalizeAsyncSurface(NPP instance, NPAsyncSurface *surface) +{ + return sBrowserFuncs->finalizeasyncsurface(instance, surface); +} + +void +NPN_SetCurrentAsyncSurface(NPP instance, NPAsyncSurface *surface, NPRect *changed) +{ + sBrowserFuncs->setcurrentasyncsurface(instance, surface, changed); +} + // // npruntime object functions // @@ -2621,7 +2732,11 @@ setColor(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* r r.top = 0; r.right = id->window.width; r.bottom = id->window.height; - NPN_InvalidateRect(npp, &r); + if (id->asyncDrawing == AD_NONE) { + NPN_InvalidateRect(npp, &r); + } else if (id->asyncDrawing == AD_BITMAP) { + drawAsyncBitmapColor(id); + } VOID_TO_NPVARIANT(*result); return true; diff --git a/dom/plugins/test/testplugin/nptest.h b/dom/plugins/test/testplugin/nptest.h index 8aed73ef6cf..b210b57a771 100644 --- a/dom/plugins/test/testplugin/nptest.h +++ b/dom/plugins/test/testplugin/nptest.h @@ -61,6 +61,11 @@ typedef enum { FUNCTION_NPP_WRITE_RPC } TestFunction; +typedef enum { + AD_NONE, + AD_BITMAP +} AsyncDrawing; + typedef enum { ACTIVATION_STATE_UNKNOWN, ACTIVATION_STATE_ACTIVATED, @@ -140,6 +145,9 @@ typedef struct InstanceData { bool closeStream; std::string lastKeyText; bool wantsAllStreams; + AsyncDrawing asyncDrawing; + NPAsyncSurface *frontBuffer; + NPAsyncSurface *backBuffer; } InstanceData; void notifyDidPaint(InstanceData* instanceData); diff --git a/dom/plugins/test/testplugin/nptest_droid.cpp b/dom/plugins/test/testplugin/nptest_droid.cpp index 46239a766c2..85beff1b39a 100644 --- a/dom/plugins/test/testplugin/nptest_droid.cpp +++ b/dom/plugins/test/testplugin/nptest_droid.cpp @@ -49,6 +49,12 @@ pluginSupportsWindowlessMode() return true; } +bool +pluginSupportsAsyncBitmapDrawing() +{ + return false; +} + NPError pluginInstanceInit(InstanceData* instanceData) { diff --git a/dom/plugins/test/testplugin/nptest_gtk2.cpp b/dom/plugins/test/testplugin/nptest_gtk2.cpp index e025deeb7bc..471fddd8272 100644 --- a/dom/plugins/test/testplugin/nptest_gtk2.cpp +++ b/dom/plugins/test/testplugin/nptest_gtk2.cpp @@ -70,6 +70,12 @@ pluginSupportsWindowlessMode() return true; } +bool +pluginSupportsAsyncBitmapDrawing() +{ + return false; +} + NPError pluginInstanceInit(InstanceData* instanceData) { diff --git a/dom/plugins/test/testplugin/nptest_macosx.mm b/dom/plugins/test/testplugin/nptest_macosx.mm index dd7379ec738..067e9beb8f7 100644 --- a/dom/plugins/test/testplugin/nptest_macosx.mm +++ b/dom/plugins/test/testplugin/nptest_macosx.mm @@ -49,6 +49,12 @@ pluginSupportsWindowlessMode() return true; } +bool +pluginSupportsAsyncBitmapDrawing() +{ + return false; +} + NPError pluginInstanceInit(InstanceData* instanceData) { diff --git a/dom/plugins/test/testplugin/nptest_os2.cpp b/dom/plugins/test/testplugin/nptest_os2.cpp index cd55e5ed66a..041d1001c8c 100644 --- a/dom/plugins/test/testplugin/nptest_os2.cpp +++ b/dom/plugins/test/testplugin/nptest_os2.cpp @@ -47,6 +47,12 @@ pluginSupportsWindowlessMode() return true; } +bool +pluginSupportsAsyncBitmapDrawing() +{ + return false; +} + NPError pluginInstanceInit(InstanceData* instanceData) { diff --git a/dom/plugins/test/testplugin/nptest_platform.h b/dom/plugins/test/testplugin/nptest_platform.h index 361fca3de47..39e9d7cf7ba 100644 --- a/dom/plugins/test/testplugin/nptest_platform.h +++ b/dom/plugins/test/testplugin/nptest_platform.h @@ -48,6 +48,11 @@ bool pluginSupportsWindowMode(); */ bool pluginSupportsWindowlessMode(); +/** + * Returns true if the plugin supports async bitmap drawing. + */ +bool pluginSupportsAsyncBitmapDrawing(); + /** * Initialize the plugin instance. Returning an error here will cause the * plugin instantiation to fail. diff --git a/dom/plugins/test/testplugin/nptest_qt.cpp b/dom/plugins/test/testplugin/nptest_qt.cpp index 15e77e1da1f..49c648b4f16 100644 --- a/dom/plugins/test/testplugin/nptest_qt.cpp +++ b/dom/plugins/test/testplugin/nptest_qt.cpp @@ -57,6 +57,12 @@ pluginSupportsWindowlessMode() return true; } +bool +pluginSupportsAsyncBitmapDrawing() +{ + return false; +} + NPError pluginInstanceInit(InstanceData* instanceData) { diff --git a/dom/plugins/test/testplugin/nptest_windows.cpp b/dom/plugins/test/testplugin/nptest_windows.cpp index 549bdadcb23..89b3f94342e 100644 --- a/dom/plugins/test/testplugin/nptest_windows.cpp +++ b/dom/plugins/test/testplugin/nptest_windows.cpp @@ -60,14 +60,22 @@ pluginSupportsWindowlessMode() return true; } +bool +pluginSupportsAsyncBitmapDrawing() +{ + return true; +} + NPError pluginInstanceInit(InstanceData* instanceData) { + NPP npp = instanceData->npp; + instanceData->platformData = static_cast (NPN_MemAlloc(sizeof(PlatformData))); if (!instanceData->platformData) return NPERR_OUT_OF_MEMORY_ERROR; - + instanceData->platformData->childWindow = NULL; return NPERR_NO_ERROR; } @@ -83,6 +91,7 @@ void pluginDoSetWindow(InstanceData* instanceData, NPWindow* newWindow) { instanceData->window = *newWindow; + NPP npp = instanceData->npp; } #define CHILD_WIDGET_SIZE 10 diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index 2dbcbd4a209..3eab2cb8c03 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -253,6 +253,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl) { (PRFuncPtr*) &mSymbols.fTexParameteri, { "TexParameteri", NULL } }, { (PRFuncPtr*) &mSymbols.fTexParameterf, { "TexParameterf", NULL } }, { (PRFuncPtr*) &mSymbols.fGetString, { "GetString", NULL } }, + { (PRFuncPtr*) &mSymbols.fGetTexLevelParameteriv, { "GetTexLevelParameteriv", NULL } }, { (PRFuncPtr*) &mSymbols.fGetTexParameterfv, { "GetTexParameterfv", NULL } }, { (PRFuncPtr*) &mSymbols.fGetTexParameteriv, { "GetTexParameteriv", NULL } }, { (PRFuncPtr*) &mSymbols.fGetUniformfv, { "GetUniformfv", "GetUniformfvARB", NULL } }, @@ -494,6 +495,13 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl) mInitialized = false; } } + + // Load developer symbols, don't fail if we can't find them. + SymLoadStruct auxSymbols[] = { + { (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", NULL } }, + { NULL, { NULL } }, + }; + LoadSymbols(&auxSymbols[0], trygl, prefix); } if (mInitialized) { @@ -1598,10 +1606,73 @@ GLContext::MarkDestroyed() mSymbols.Zero(); } +static void SwapRAndBComponents(gfxImageSurface* aSurf) +{ + gfxIntSize size = aSurf->GetSize(); + for (int j = 0; j < size.height; ++j) { + PRUint32 *row = (PRUint32*) (aSurf->Data() + aSurf->Stride() * j); + for (int i = 0; i < size.width; ++i) { + *row = (*row & 0xff00ff00) | ((*row & 0xff) << 16) | ((*row & 0xff0000) >> 16); + row++; + } + } +} + +static already_AddRefed YInvertImageSurface(gfxImageSurface* aSurf) +{ + gfxIntSize size = aSurf->GetSize(); + nsRefPtr temp = new gfxImageSurface(size, aSurf->Format()); + nsRefPtr ctx = new gfxContext(temp); + ctx->SetOperator(gfxContext::OPERATOR_SOURCE); + ctx->Scale(1.0, -1.0); + ctx->Translate(-gfxPoint(0.0, size.height)); + ctx->SetSource(aSurf); + ctx->Paint(); + return temp.forget(); +} + +already_AddRefed +GLContext::GetTexImage(GLuint aTexture, bool aYInvert, ShaderProgramType aShader) +{ + MakeCurrent(); + fFinish(); + fActiveTexture(LOCAL_GL_TEXTURE0); + fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture); + + gfxIntSize size; + fGetTexLevelParameteriv(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_TEXTURE_WIDTH, &size.width); + fGetTexLevelParameteriv(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_TEXTURE_HEIGHT, &size.height); + + nsRefPtr surf = new gfxImageSurface(size, gfxASurface::ImageFormatARGB32); + if (!surf || surf->CairoStatus()) { + return NULL; + } + + PRUint32 currentPackAlignment = 0; + fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, (GLint*)¤tPackAlignment); + if (currentPackAlignment != 4) { + fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4); + } + fGetTexImage(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, surf->Data()); + if (currentPackAlignment != 4) { + fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment); + } + + if (aShader == RGBALayerProgramType || aShader == RGBXLayerProgramType) { + SwapRAndBComponents(surf); + } + + if (aYInvert) { + surf = YInvertImageSurface(surf); + } + return surf.forget(); +} + already_AddRefed GLContext::ReadTextureImage(GLuint aTexture, const gfxIntSize& aSize, - GLenum aTextureFormat) + GLenum aTextureFormat, + bool aYInvert) { MakeCurrent(); @@ -1664,6 +1735,8 @@ GLContext::ReadTextureImage(GLuint aTexture, fs = fCreateShader(LOCAL_GL_FRAGMENT_SHADER); fShaderSource(vs, 1, (const GLchar**) &vShader, NULL); fShaderSource(fs, 1, (const GLchar**) &fShader, NULL); + fCompileShader(vs); + fCompileShader(fs); prog = fCreateProgram(); fAttachShader(prog, vs); fAttachShader(prog, fs); @@ -1707,9 +1780,15 @@ GLContext::ReadTextureImage(GLuint aTexture, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, isurf->Data()); + SwapRAndBComponents(isurf); + if (oldPackAlignment != 4) fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, oldPackAlignment); + if (aYInvert) { + isurf = YInvertImageSurface(isurf); + } + cleanup: // note that deleting 0 has no effect in any of these calls fDeleteRenderbuffers(1, &rb); diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 506590bb9b5..b4dda84795f 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -1233,7 +1233,10 @@ public: */ already_AddRefed ReadTextureImage(GLuint aTexture, const gfxIntSize& aSize, - GLenum aTextureFormat); + GLenum aTextureFormat, + bool aYInvert = false); + + already_AddRefed GetTexImage(GLuint aTexture, bool aYInvert, ShaderProgramType aShader); /** * Call ReadPixels into an existing gfxImageSurface for the given bounds. @@ -2122,6 +2125,22 @@ public: return result; } + void fGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *img) { + if (!mSymbols.fGetTexImage) { + return; + } + BEFORE_GL_CALL; + mSymbols.fGetTexImage(target, level, format, type, img); + AFTER_GL_CALL; + }; + + void fGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) + { + BEFORE_GL_CALL; + mSymbols.fGetTexLevelParameteriv(target, level, pname, params); + AFTER_GL_CALL; + } + void fGetTexParameterfv(GLenum target, GLenum pname, const GLfloat *params) { BEFORE_GL_CALL; mSymbols.fGetTexParameterfv(target, pname, params); diff --git a/gfx/gl/GLContextSymbols.h b/gfx/gl/GLContextSymbols.h index 39734d9d0bc..51f6164eda4 100644 --- a/gfx/gl/GLContextSymbols.h +++ b/gfx/gl/GLContextSymbols.h @@ -155,6 +155,10 @@ struct GLContextSymbols PFNGLTEXPARAMETERFPROC fTexParameterf; typedef GLubyte* (GLAPIENTRY * PFNGLGETSTRINGPROC) (GLenum); PFNGLGETSTRINGPROC fGetString; + typedef void (GLAPIENTRY * PFNGLGETTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid* image); + PFNGLGETTEXIMAGEPROC fGetTexImage; + typedef void (GLAPIENTRY * PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint *params); + PFNGLGETTEXLEVELPARAMETERIVPROC fGetTexLevelParameteriv; typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); PFNGLGETTEXPARAMETERFVPROC fGetTexParameterfv; typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); diff --git a/gfx/layers/ImageLayers.cpp b/gfx/layers/ImageLayers.cpp index d55f757a711..b561ef69c81 100644 --- a/gfx/layers/ImageLayers.cpp +++ b/gfx/layers/ImageLayers.cpp @@ -36,6 +36,7 @@ * ***** END LICENSE BLOCK ***** */ #include "mozilla/ipc/Shmem.h" +#include "mozilla/ipc/CrossProcessMutex.h" #include "ImageLayers.h" #include "gfxImageSurface.h" #include "yuv_convert.h" @@ -119,15 +120,91 @@ ImageContainer::SetCurrentImage(Image *aImage) { ReentrantMonitorAutoEnter mon(mReentrantMonitor); + if (mRemoteData) { + NS_ASSERTION(mRemoteDataMutex, "Should have remote data mutex when having remote data!"); + mRemoteDataMutex->Lock(); + // This is important since it ensures we won't change the active image + // when we currently have a locked image that depends on mRemoteData. + } + mActiveImage = aImage; CurrentImageChanged(); + + if (mRemoteData) { + mRemoteDataMutex->Unlock(); + } +} + +bool +ImageContainer::HasCurrentImage() +{ + ReentrantMonitorAutoEnter mon(mReentrantMonitor); + + if (mRemoteData) { + CrossProcessMutexAutoLock autoLock(*mRemoteDataMutex); + + EnsureActiveImage(); + + return !!mActiveImage.get(); + } + + return !!mActiveImage.get(); +} + +already_AddRefed +ImageContainer::LockCurrentImage() +{ + ReentrantMonitorAutoEnter mon(mReentrantMonitor); + + if (mRemoteData) { + NS_ASSERTION(mRemoteDataMutex, "Should have remote data mutex when having remote data!"); + mRemoteDataMutex->Lock(); + } + + EnsureActiveImage(); + + nsRefPtr retval = mActiveImage; + return retval.forget(); } already_AddRefed -ImageContainer::GetCurrentAsSurface(gfxIntSize *aSize) +ImageContainer::LockCurrentAsSurface(gfxIntSize *aSize, Image** aCurrentImage) { ReentrantMonitorAutoEnter mon(mReentrantMonitor); + if (mRemoteData) { + NS_ASSERTION(mRemoteDataMutex, "Should have remote data mutex when having remote data!"); + mRemoteDataMutex->Lock(); + + EnsureActiveImage(); + + if (aCurrentImage) { + NS_IF_ADDREF(mActiveImage); + *aCurrentImage = mActiveImage.get(); + } + + if (!mActiveImage) { + return nsnull; + } + + if (mActiveImage->GetFormat() == Image::REMOTE_IMAGE_BITMAP) { + nsRefPtr newSurf = + new gfxImageSurface(mRemoteData->mBitmap.mData, mRemoteData->mSize, mRemoteData->mBitmap.mStride, + mRemoteData->mFormat == RemoteImageData::BGRX32 ? + gfxASurface::ImageFormatARGB32 : + gfxASurface::ImageFormatRGB24); + + *aSize = newSurf->GetSize(); + + return newSurf.forget(); + } + } + + if (aCurrentImage) { + NS_IF_ADDREF(mActiveImage); + *aCurrentImage = mActiveImage.get(); + } + if (!mActiveImage) { return nsnull; } @@ -136,11 +213,45 @@ ImageContainer::GetCurrentAsSurface(gfxIntSize *aSize) return mActiveImage->GetAsSurface(); } +void +ImageContainer::UnlockCurrentImage() +{ + if (mRemoteData) { + NS_ASSERTION(mRemoteDataMutex, "Should have remote data mutex when having remote data!"); + mRemoteDataMutex->Unlock(); + } +} + +already_AddRefed +ImageContainer::GetCurrentAsSurface(gfxIntSize *aSize) +{ + ReentrantMonitorAutoEnter mon(mReentrantMonitor); + + if (mRemoteData) { + CrossProcessMutexAutoLock autoLock(*mRemoteDataMutex); + EnsureActiveImage(); + + *aSize = mRemoteData->mSize; + return mActiveImage ? mActiveImage->GetAsSurface() : nsnull; + } + + *aSize = mActiveImage->GetSize(); + return mActiveImage ? mActiveImage->GetAsSurface() : nsnull; +} + gfxIntSize ImageContainer::GetCurrentSize() { ReentrantMonitorAutoEnter mon(mReentrantMonitor); + if (mRemoteData) { + CrossProcessMutexAutoLock autoLock(*mRemoteDataMutex); + + // We don't need to ensure we have an active image here, as we need to + // be in the mutex anyway, and this is easiest to return from there. + return mRemoteData->mSize; + } + if (!mActiveImage) { return gfxIntSize(0,0); } @@ -148,6 +259,47 @@ ImageContainer::GetCurrentSize() return mActiveImage->GetSize(); } +void +ImageContainer::SetRemoteImageData(RemoteImageData *aData, CrossProcessMutex *aMutex) +{ + ReentrantMonitorAutoEnter mon(mReentrantMonitor); + NS_ASSERTION(!mActiveImage, "No active image expected when SetRemoteImageData is called."); + NS_ASSERTION(!mRemoteData, "No remote data expected when SetRemoteImageData is called."); + + mRemoteData = aData; + + if (aData) { + memset(aData, 0, sizeof(RemoteImageData)); + } else { + mActiveImage = nsnull; + } + + mRemoteDataMutex = aMutex; +} + +void +ImageContainer::EnsureActiveImage() +{ + if (mRemoteData) { + if (mRemoteData->mWasUpdated) { + mActiveImage = nsnull; + } + + if (mRemoteData->mType == RemoteImageData::RAW_BITMAP && + mRemoteData->mBitmap.mData && !mActiveImage) { + nsRefPtr newImg = new RemoteBitmapImage(); + + newImg->mFormat = mRemoteData->mFormat; + newImg->mData = mRemoteData->mBitmap.mData; + newImg->mSize = mRemoteData->mSize; + newImg->mStride = mRemoteData->mBitmap.mStride; + mRemoteData->mWasUpdated = false; + + mActiveImage = newImg; + } + } +} + PlanarYCbCrImage::PlanarYCbCrImage(BufferRecycleBin *aRecycleBin) : Image(nsnull, PLANAR_YCBCR) , mBufferSize(0) @@ -270,6 +422,21 @@ MacIOSurfaceImage::Update(ImageContainer* aContainer) } } #endif +already_AddRefed +RemoteBitmapImage::GetAsSurface() +{ + nsRefPtr newSurf = + new gfxImageSurface(mSize, + mFormat == RemoteImageData::BGRX32 ? gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32); + + for (int y = 0; y < mSize.height; y++) { + memcpy(newSurf->Data() + newSurf->Stride() * y, + mData + mStride * y, + mSize.width * 4); + } + + return newSurf.forget(); +} } } diff --git a/gfx/layers/ImageLayers.h b/gfx/layers/ImageLayers.h index 7e6d69f2124..525d6c4bf69 100644 --- a/gfx/layers/ImageLayers.h +++ b/gfx/layers/ImageLayers.h @@ -54,6 +54,12 @@ #endif namespace mozilla { + +class CrossProcessMutex; +namespace ipc { +class Shmem; +} + namespace layers { enum StereoMode { @@ -120,7 +126,12 @@ public: * * It wraps an IOSurface object and binds it directly to a GL texture. */ - MAC_IO_SURFACE + MAC_IO_SURFACE, + + /** + * An bitmap image that can be shared with a remote process. + */ + REMOTE_IMAGE_BITMAP }; Format GetFormat() { return mFormat; } @@ -194,6 +205,12 @@ FormatInList(const Image::Format* aFormats, PRUint32 aNumFormats, return false; } +class CompositionNotifySink +{ +public: + virtual void DidComposite() = 0; +}; + /** * A class that manages Image creation for a LayerManager. The only reason * we need a separate class here is that LayerMananers aren't threadsafe @@ -225,6 +242,46 @@ protected: BufferRecycleBin *aRecycleBin); }; + +/** + * This struct is used to store RemoteImages, it is meant to be able to live in + * shared memory. Therefor it should not contain a vtable pointer. Remote + * users can manipulate the data in this structure to specify what image is to + * be drawn by the container. When accessing this data users should make sure + * the mutex synchronizing access to the structure is held! + */ +struct RemoteImageData { + enum Type { + /** + * This is a format that uses raw bitmap data. + */ + RAW_BITMAP + }; + /* These formats describe the format in the memory byte-order */ + enum Format { + /* 8 bits per channel */ + BGRA32, + /* 8 bits per channel, alpha channel is ignored */ + BGRX32 + }; + + // This should be set to true if a change was made so that the ImageContainer + // knows to throw out any cached RemoteImage objects. + bool mWasUpdated; + Type mType; + Format mFormat; + gfxIntSize mSize; + union { + struct { + /* This pointer is set by a remote process, however it will be set to + * the container process' address the memory of the raw bitmap resides + * at. + */ + unsigned char *mData; + int mStride; + } mBitmap; + }; +}; /** * A class that manages Images for an ImageLayer. The only reason @@ -242,7 +299,10 @@ public: mPaintCount(0), mPreviousImagePainted(false), mImageFactory(new ImageFactory()), - mRecycleBin(new BufferRecycleBin()) + mRecycleBin(new BufferRecycleBin()), + mRemoteData(nsnull), + mRemoteDataMutex(nsnull), + mCompositionNotifySink(nsnull) {} ~ImageContainer(); @@ -266,26 +326,37 @@ public: * aImage can be null. While it's null, nothing will be painted. * * The Image data must not be modified after this method is called! + * + * Implementations must call CurrentImageChanged() while holding + * mReentrantMonitor. */ void SetCurrentImage(Image* aImage); /** - * Get the current Image. - * This has to add a reference since otherwise there are race conditions - * where the current image is destroyed before the caller can add - * a reference. + * Returns if the container currently has an image. * Can be called on any thread. This method takes mReentrantMonitor * when accessing thread-shared state. - * Implementations must call CurrentImageChanged() while holding - * mReentrantMonitor. */ - already_AddRefed GetCurrentImage() - { - ReentrantMonitorAutoEnter mon(mReentrantMonitor); + bool HasCurrentImage(); - nsRefPtr retval = mActiveImage; - return retval.forget(); - } + /** + * Lock the current Image. + * This has to add a reference since otherwise there are race conditions + * where the current image is destroyed before the caller can add + * a reference. This lock strictly guarantees the underlying image remains + * valid, it does not mean the current image cannot change. + * Can be called on any thread. This method will lock the cross-process + * mutex to ensure remote processes cannot alter underlying data. This call + * -must- be balanced by a call to UnlockCurrentImage and users should avoid + * holding the image locked for a long time. + */ + already_AddRefed LockCurrentImage(); + + /** + * This call unlocks the image. For remote images releasing the cross-process + * mutex. + */ + void UnlockCurrentImage(); /** * Get the current image as a gfxASurface. This is useful for fallback @@ -301,9 +372,25 @@ public: * modify it. * Can be called on any thread. This method takes mReentrantMonitor * when accessing thread-shared state. + * If the current image is a remote image, that is, if it is an image that + * may be shared accross processes, calling this function will make + * a copy of the image data while holding the mRemoteDataMutex. If possible, + * the lock methods should be used to avoid the copy, however this should be + * avoided if the surface is required for a long period of time. */ already_AddRefed GetCurrentAsSurface(gfxIntSize* aSizeResult); + /** + * This is similar to GetCurrentAsSurface, however this does not make a copy + * of the image data and requires the user to call UnlockCurrentImage when + * done with the image data. Once UnlockCurrentImage has been called the + * surface returned by this function is no longer valid! This works for any + * type of image. Optionally a pointer can be passed to receive the current + * image. + */ + already_AddRefed LockCurrentAsSurface(gfxIntSize* aSizeResult, + Image** aCurrentImage = nsnull); + /** * Returns the size of the image in pixels. * Can be called on any thread. This method takes mReentrantMonitor when accessing @@ -354,7 +441,8 @@ public: */ void NotifyPaintedImage(Image* aPainted) { ReentrantMonitorAutoEnter mon(mReentrantMonitor); - nsRefPtr current = GetCurrentImage(); + + nsRefPtr current = mActiveImage; if (aPainted == current) { if (mPaintTime.IsNull()) { mPaintTime = TimeStamp::Now(); @@ -367,11 +455,40 @@ public: mPaintCount++; mPreviousImagePainted = true; } + + if (mCompositionNotifySink) { + mCompositionNotifySink->DidComposite(); + } } + void SetCompositionNotifySink(CompositionNotifySink *aSink) { + mCompositionNotifySink = aSink; + } + + /** + * This function is called to tell the ImageContainer where the + * (cross-process) segment lives where the shared data about possible + * remote images are stored. In addition to this a CrossProcessMutex object + * is passed telling the container how to synchronize access to this data. + * NOTE: This should be called during setup of the container and not after + * usage has started. + */ + void SetRemoteImageData(RemoteImageData *aRemoteData, + CrossProcessMutex *aRemoteDataMutex); + /** + * This can be used to check if the container has RemoteData set. + */ + RemoteImageData *GetRemoteImageData() { return mRemoteData; } + protected: typedef mozilla::ReentrantMonitor ReentrantMonitor; + // This is called to ensure we have an active image, this may not be true + // when we're storing image information in a RemoteImageData structure. + // NOTE: If we have remote data mRemoteDataMutex should be locked when + // calling this function! + void EnsureActiveImage(); + // ReentrantMonitor to protect thread safe access to the "current // image", and any other state which is shared between threads. ReentrantMonitor mReentrantMonitor; @@ -407,6 +524,56 @@ protected: gfxIntSize mScaleHint; nsRefPtr mRecycleBin; + + // This contains the remote image data for this container, if this is NULL + // that means the container has no other process that may control its active + // image. + RemoteImageData *mRemoteData; + + // This cross-process mutex is used to synchronise access to mRemoteData. + // When this mutex is held, we will always be inside the mReentrantMonitor + // however the same is not true vice versa. + CrossProcessMutex *mRemoteDataMutex; + + CompositionNotifySink *mCompositionNotifySink; +}; + +class AutoLockImage +{ +public: + AutoLockImage(ImageContainer *aContainer) : mContainer(aContainer) { mImage = mContainer->LockCurrentImage(); } + AutoLockImage(ImageContainer *aContainer, gfxASurface **aSurface) : mContainer(aContainer) { + *aSurface = mContainer->LockCurrentAsSurface(&mSize, getter_AddRefs(mImage)).get(); + } + ~AutoLockImage() { if (mContainer) { mContainer->UnlockCurrentImage(); } } + + Image* GetImage() { return mImage; } + const gfxIntSize &GetSize() { return mSize; } + + void Unlock() { + if (mContainer) { + mImage = nsnull; + mContainer->UnlockCurrentImage(); + mContainer = nsnull; + } + } + + /** Things get a little tricky here, because our underlying image can -still- + * change, and OS X requires a complicated callback mechanism to update this + * we need to support staying the lock and getting the new image in a proper + * way. This method makes any images retrieved with GetImage invalid! + */ + void Refresh() { + if (mContainer) { + mContainer->UnlockCurrentImage(); + mImage = mContainer->LockCurrentImage(); + } + } + +private: + ImageContainer *mContainer; + nsRefPtr mImage; + gfxIntSize mSize; }; /** @@ -676,6 +843,20 @@ private: }; #endif +class RemoteBitmapImage : public Image { +public: + RemoteBitmapImage() : Image(NULL, REMOTE_IMAGE_BITMAP) {} + + already_AddRefed GetAsSurface(); + + gfxIntSize GetSize() { return mSize; } + + unsigned char *mData; + int mStride; + gfxIntSize mSize; + RemoteImageData::Format mFormat; +}; + } } diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index 58e24b4330f..4ba34421289 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -458,6 +458,10 @@ ContainerLayer::DefaultComputeEffectiveTransforms(const gfx3DMatrix& aTransformT float opacity = GetEffectiveOpacity(); if (opacity != 1.0f && HasMultipleChildren()) { useIntermediateSurface = true; +#ifdef MOZ_DUMP_PAINTING + } else if (gfxUtils::sDumpPainting) { + useIntermediateSurface = true; +#endif } else { useIntermediateSurface = false; gfxMatrix contTransform; @@ -552,17 +556,60 @@ LayerManager::StopFrameTimeRecording() static nsACString& PrintInfo(nsACString& aTo, ShadowLayer* aShadowLayer); +#ifdef MOZ_DUMP_PAINTING +template +void WriteSnapshotLinkToDumpFile(T* aObj, FILE* aFile) +{ + nsCString string(aObj->Name()); + string.Append("-"); + string.AppendInt((PRUint64)aObj); + fprintf(aFile, "href=\"javascript:ViewImage('%s')\"", string.BeginReading()); +} + +template +void WriteSnapshotToDumpFile_internal(T* aObj, gfxASurface* aSurf) +{ + nsCString string(aObj->Name()); + string.Append("-"); + string.AppendInt((PRUint64)aObj); + fprintf(gfxUtils::sDumpPaintFile, "array[\"%s\"]=\"", string.BeginReading()); + aSurf->DumpAsDataURL(gfxUtils::sDumpPaintFile); + fprintf(gfxUtils::sDumpPaintFile, "\";"); +} + +void WriteSnapshotToDumpFile(Layer* aLayer, gfxASurface* aSurf) +{ + WriteSnapshotToDumpFile_internal(aLayer, aSurf); +} + +void WriteSnapshotToDumpFile(LayerManager* aManager, gfxASurface* aSurf) +{ + WriteSnapshotToDumpFile_internal(aManager, aSurf); +} +#endif + void Layer::Dump(FILE* aFile, const char* aPrefix) { + fprintf(aFile, "
  • "); DumpSelf(aFile, aPrefix); + fprintf(aFile, ""); if (Layer* kid = GetFirstChild()) { nsCAutoString pfx(aPrefix); pfx += " "; + fprintf(aFile, "
      "); kid->Dump(aFile, pfx.get()); + fprintf(aFile, "
    "); } + fprintf(aFile, "
  • "); if (Layer* next = GetNextSibling()) next->Dump(aFile, aPrefix); } @@ -714,17 +761,27 @@ void LayerManager::Dump(FILE* aFile, const char* aPrefix) { FILE* file = FILEOrDefault(aFile); - + + fprintf(file, "", pfx.get()); return; } - + + fprintf(file, "
      "); GetRoot()->Dump(file, pfx.get()); + fprintf(file, "
    "); } void diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 299bb51b151..565d0de1bfc 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1345,6 +1345,11 @@ protected: bool mDirty; }; +#ifdef MOZ_DUMP_PAINTING +void WriteSnapshotToDumpFile(Layer* aLayer, gfxASurface* aSurf); +void WriteSnapshotToDumpFile(LayerManager* aManager, gfxASurface* aSurf); +#endif + } } diff --git a/gfx/layers/basic/BasicLayers.cpp b/gfx/layers/basic/BasicLayers.cpp index 882e5e6064f..97de77617c1 100644 --- a/gfx/layers/basic/BasicLayers.cpp +++ b/gfx/layers/basic/BasicLayers.cpp @@ -904,9 +904,11 @@ BasicImageLayer::GetAndPaintCurrentImage(gfxContext* aContext, mContainer->SetImageFactory(mManager->IsCompositingCheap() ? nsnull : BasicManager()->GetImageFactory()); - nsRefPtr image = mContainer->GetCurrentImage(); + nsRefPtr surface; + AutoLockImage autoLock(mContainer, getter_AddRefs(surface)); + Image *image = autoLock.GetImage(); + mSize = autoLock.GetSize(); - nsRefPtr surface = mContainer->GetCurrentAsSurface(&mSize); if (!surface || surface->CairoStatus()) { return nsnull; } @@ -2522,13 +2524,16 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext) return; } - nsRefPtr image = mContainer->GetCurrentImage(); + AutoLockImage autoLock(mContainer); + + Image *image = autoLock.GetImage(); + if (!image) { return; } if (image->GetFormat() == Image::PLANAR_YCBCR && BasicManager()->IsCompositingCheap()) { - PlanarYCbCrImage *YCbCrImage = static_cast(image.get()); + PlanarYCbCrImage *YCbCrImage = static_cast(image); const PlanarYCbCrImage::Data *data = YCbCrImage->GetData(); NS_ASSERTION(data, "Must be able to retrieve yuv data from image!"); diff --git a/gfx/layers/d3d10/ImageLayerD3D10.cpp b/gfx/layers/d3d10/ImageLayerD3D10.cpp index c8ebf2319c7..7fd8cf7f450 100644 --- a/gfx/layers/d3d10/ImageLayerD3D10.cpp +++ b/gfx/layers/d3d10/ImageLayerD3D10.cpp @@ -44,6 +44,34 @@ namespace mozilla { namespace layers { + +static already_AddRefed +DataToTexture(ID3D10Device *aDevice, + unsigned char *data, + int stride, + const gfxIntSize &aSize) +{ + D3D10_SUBRESOURCE_DATA srdata; + + CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, + aSize.width, + aSize.height, + 1, 1); + desc.Usage = D3D10_USAGE_IMMUTABLE; + + srdata.pSysMem = data; + srdata.SysMemPitch = stride; + + nsRefPtr texture; + HRESULT hr = aDevice->CreateTexture2D(&desc, &srdata, getter_AddRefs(texture)); + + if (FAILED(hr)) { + LayerManagerD3D10::ReportFailure(NS_LITERAL_CSTRING("Failed to create texture for data"), + hr); + } + + return texture.forget(); +} static already_AddRefed SurfaceToTexture(ID3D10Device *aDevice, @@ -78,26 +106,7 @@ SurfaceToTexture(ID3D10Device *aDevice, context->Paint(); } - D3D10_SUBRESOURCE_DATA data; - - CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, - imageSurface->GetSize().width, - imageSurface->GetSize().height, - 1, 1); - desc.Usage = D3D10_USAGE_IMMUTABLE; - - data.pSysMem = imageSurface->Data(); - data.SysMemPitch = imageSurface->Stride(); - - nsRefPtr texture; - HRESULT hr = aDevice->CreateTexture2D(&desc, &data, getter_AddRefs(texture)); - - if (FAILED(hr)) { - LayerManagerD3D10::ReportFailure(NS_LITERAL_CSTRING("Failed to create texture for image surface"), - hr); - } - - return texture.forget(); + return DataToTexture(aDevice, imageSurface->Data(), imageSurface->Stride(), aSize); } Layer* @@ -109,11 +118,14 @@ ImageLayerD3D10::GetLayer() void ImageLayerD3D10::RenderLayer() { - if (!GetContainer()) { + ImageContainer *container = GetContainer(); + if (!container) { return; } - nsRefPtr image = GetContainer()->GetCurrentImage(); + AutoLockImage autoLock(container); + + Image *image = autoLock.GetImage(); if (!image) { return; } @@ -122,27 +134,51 @@ ImageLayerD3D10::RenderLayer() ID3D10EffectTechnique *technique; - if (image->GetFormat() == Image::CAIRO_SURFACE) + if (image->GetFormat() == Image::CAIRO_SURFACE || image->GetFormat() == Image::REMOTE_IMAGE_BITMAP) { - CairoImage *cairoImage = - static_cast(image.get()); + bool hasAlpha = false; + gfxIntSize size; - if (!cairoImage->mSurface) { - return; - } + if (image->GetFormat() == Image::REMOTE_IMAGE_BITMAP) { + RemoteBitmapImage *remoteImage = + static_cast(image); + + if (!image->GetBackendData(LayerManager::LAYERS_D3D10)) { + nsAutoPtr dat = new TextureD3D10BackendData(); + dat->mTexture = DataToTexture(device(), remoteImage->mData, remoteImage->mStride, remoteImage->mSize); - if (!cairoImage->GetBackendData(LayerManager::LAYERS_D3D10)) { - nsAutoPtr dat(new CairoD3D10BackendData()); - dat->mTexture = SurfaceToTexture(device(), cairoImage->mSurface, cairoImage->mSize); - - if (dat->mTexture) { - device()->CreateShaderResourceView(dat->mTexture, NULL, getter_AddRefs(dat->mSRView)); - cairoImage->SetBackendData(LayerManager::LAYERS_D3D10, dat.forget()); + if (dat->mTexture) { + device()->CreateShaderResourceView(dat->mTexture, NULL, getter_AddRefs(dat->mSRView)); + image->SetBackendData(LayerManager::LAYERS_D3D10, dat.forget()); + } } + + hasAlpha = remoteImage->mFormat == RemoteImageData::BGRA32; + size = remoteImage->mSize; + } else { + CairoImage *cairoImage = + static_cast(image); + + if (!cairoImage->mSurface) { + return; + } + + if (!image->GetBackendData(LayerManager::LAYERS_D3D10)) { + nsAutoPtr dat = new TextureD3D10BackendData(); + dat->mTexture = SurfaceToTexture(device(), cairoImage->mSurface, cairoImage->mSize); + + if (dat->mTexture) { + device()->CreateShaderResourceView(dat->mTexture, NULL, getter_AddRefs(dat->mSRView)); + image->SetBackendData(LayerManager::LAYERS_D3D10, dat.forget()); + } + } + + hasAlpha = cairoImage->mSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA; + size = cairoImage->mSize; } - CairoD3D10BackendData *data = - static_cast(cairoImage->GetBackendData(LayerManager::LAYERS_D3D10)); + TextureD3D10BackendData *data = + static_cast(image->GetBackendData(LayerManager::LAYERS_D3D10)); if (!data) { return; @@ -154,7 +190,7 @@ ImageLayerD3D10::RenderLayer() return; } - if (cairoImage->mSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA) { + if (hasAlpha) { if (mFilter == gfxPattern::FILTER_NEAREST) { technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPoint"); } else { @@ -174,12 +210,12 @@ ImageLayerD3D10::RenderLayer() ShaderConstantRectD3D10( (float)0, (float)0, - (float)cairoImage->mSize.width, - (float)cairoImage->mSize.height) + (float)size.width, + (float)size.height) ); } else if (image->GetFormat() == Image::PLANAR_YCBCR) { PlanarYCbCrImage *yuvImage = - static_cast(image.get()); + static_cast(image); if (!yuvImage->mBufferSize) { return; @@ -262,11 +298,15 @@ ImageLayerD3D10::RenderLayer() (float)yuvImage->mData.mPicSize.height / yuvImage->mData.mYSize.height) ); } + + bool resetTexCoords = image->GetFormat() == Image::PLANAR_YCBCR; + image = nsnull; + autoLock.Unlock(); technique->GetPassByIndex(0)->Apply(0); device()->Draw(4, 0); - if (image->GetFormat() == Image::PLANAR_YCBCR) { + if (resetTexCoords) { effect()->GetVariableByName("vTextureCoords")->AsVector()-> SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f)); } diff --git a/gfx/layers/d3d10/ImageLayerD3D10.h b/gfx/layers/d3d10/ImageLayerD3D10.h index 9b6e2f3c6c9..828adce9ab5 100644 --- a/gfx/layers/d3d10/ImageLayerD3D10.h +++ b/gfx/layers/d3d10/ImageLayerD3D10.h @@ -74,7 +74,7 @@ struct PlanarYCbCrD3D10BackendData : public ImageBackendData nsRefPtr mCrView; }; -struct CairoD3D10BackendData : public ImageBackendData +struct TextureD3D10BackendData : public ImageBackendData { nsRefPtr mTexture; nsRefPtr mSRView; diff --git a/gfx/layers/d3d9/ImageLayerD3D9.cpp b/gfx/layers/d3d9/ImageLayerD3D9.cpp index d1fde75106b..b99221f10c1 100644 --- a/gfx/layers/d3d9/ImageLayerD3D9.cpp +++ b/gfx/layers/d3d9/ImageLayerD3D9.cpp @@ -53,23 +53,11 @@ namespace mozilla { namespace layers { static already_AddRefed -SurfaceToTexture(IDirect3DDevice9 *aDevice, - gfxASurface *aSurface, - const gfxIntSize &aSize) +DataToTexture(IDirect3DDevice9 *aDevice, + unsigned char *aData, + int aStride, + const gfxIntSize &aSize) { - - nsRefPtr imageSurface = aSurface->GetAsImageSurface(); - - if (!imageSurface) { - imageSurface = new gfxImageSurface(aSize, - gfxASurface::ImageFormatARGB32); - - nsRefPtr context = new gfxContext(imageSurface); - context->SetSource(aSurface); - context->SetOperator(gfxContext::OPERATOR_SOURCE); - context->Paint(); - } - nsRefPtr texture; nsRefPtr deviceEx; aDevice->QueryInterface(IID_IDirect3DDevice9Ex, @@ -103,7 +91,7 @@ SurfaceToTexture(IDirect3DDevice9 *aDevice, surface->LockRect(&lockedRect, NULL, 0); for (int y = 0; y < aSize.height; y++) { memcpy((char*)lockedRect.pBits + lockedRect.Pitch * y, - imageSurface->Data() + imageSurface->Stride() * y, + aData + aStride * y, aSize.width * 4); } surface->UnlockRect(); @@ -127,7 +115,7 @@ SurfaceToTexture(IDirect3DDevice9 *aDevice, // use memcpy for (int y = 0; y < aSize.height; y++) { memcpy((char*)lockrect.pBits + lockrect.Pitch * y, - imageSurface->Data() + imageSurface->Stride() * y, + aData + aStride * y, aSize.width * 4); } @@ -137,6 +125,27 @@ SurfaceToTexture(IDirect3DDevice9 *aDevice, return texture.forget(); } +static already_AddRefed +SurfaceToTexture(IDirect3DDevice9 *aDevice, + gfxASurface *aSurface, + const gfxIntSize &aSize) +{ + + nsRefPtr imageSurface = aSurface->GetAsImageSurface(); + + if (!imageSurface) { + imageSurface = new gfxImageSurface(aSize, + gfxASurface::ImageFormatARGB32); + + nsRefPtr context = new gfxContext(imageSurface); + context->SetSource(aSurface); + context->SetOperator(gfxContext::OPERATOR_SOURCE); + context->Paint(); + } + + return DataToTexture(aDevice, imageSurface->Data(), imageSurface->Stride(), aSize); +} + static void AllocateTexturesYCbCr(PlanarYCbCrImage *aImage, IDirect3DDevice9 *aDevice, LayerManagerD3D9 *aManager) @@ -302,37 +311,61 @@ ImageLayerD3D9::GetLayer() void ImageLayerD3D9::RenderLayer() { - if (!GetContainer()) { + ImageContainer *container = GetContainer(); + if (!container) { return; } - nsRefPtr image = GetContainer()->GetCurrentImage(); + AutoLockImage autoLock(container); + + Image *image = autoLock.GetImage(); if (!image) { return; } SetShaderTransformAndOpacity(); - if (image->GetFormat() == Image::CAIRO_SURFACE) + if (image->GetFormat() == Image::CAIRO_SURFACE || image->GetFormat() == Image::REMOTE_IMAGE_BITMAP) { - CairoImage *cairoImage = - static_cast(image.get()); + bool hasAlpha = false; + gfxIntSize size; - if (!cairoImage->mSurface) { - return; - } - - if (!cairoImage->GetBackendData(LayerManager::LAYERS_D3D9)) { - nsAutoPtr dat(new CairoD3D9BackendData()); - dat->mTexture = SurfaceToTexture(device(), cairoImage->mSurface, cairoImage->mSize); - - if (dat->mTexture) { - cairoImage->SetBackendData(LayerManager::LAYERS_D3D9, dat.forget()); + if (image->GetFormat() == Image::REMOTE_IMAGE_BITMAP) { + RemoteBitmapImage *remoteImage = + static_cast(image); + + if (!image->GetBackendData(LayerManager::LAYERS_D3D9)) { + nsAutoPtr dat = new TextureD3D9BackendData(); + dat->mTexture = DataToTexture(device(), remoteImage->mData, remoteImage->mStride, remoteImage->mSize); + if (dat->mTexture) { + image->SetBackendData(LayerManager::LAYERS_D3D9, dat.forget()); + } } + + hasAlpha = remoteImage->mFormat == RemoteImageData::BGRA32; + size = remoteImage->mSize; + } else { + CairoImage *cairoImage = + static_cast(image); + + if (!cairoImage->mSurface) { + return; + } + + if (!image->GetBackendData(LayerManager::LAYERS_D3D9)) { + nsAutoPtr dat = new TextureD3D9BackendData(); + dat->mTexture = SurfaceToTexture(device(), cairoImage->mSurface, cairoImage->mSize); + if (dat->mTexture) { + image->SetBackendData(LayerManager::LAYERS_D3D9, dat.forget()); + } + } + + hasAlpha = cairoImage->mSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA; + size = cairoImage->mSize; } - CairoD3D9BackendData *data = - static_cast(cairoImage->GetBackendData(LayerManager::LAYERS_D3D9)); + TextureD3D9BackendData *data = + static_cast(image->GetBackendData(LayerManager::LAYERS_D3D9)); if (!data) { return; @@ -344,12 +377,6 @@ ImageLayerD3D9::RenderLayer() return; } - gfxIntSize size; - nsRefPtr surface = - GetContainer()->GetCurrentAsSurface(&size); - nsRefPtr texture = - SurfaceToTexture(device(), surface, size); - device()->SetVertexShaderConstantF(CBvLayerQuad, ShaderConstantRect(0, 0, @@ -357,7 +384,7 @@ ImageLayerD3D9::RenderLayer() size.height), 1); - if (surface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA) { + if (hasAlpha) { mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER); } else { mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBLAYER); @@ -367,7 +394,12 @@ ImageLayerD3D9::RenderLayer() device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); } - device()->SetTexture(0, texture); + device()->SetTexture(0, data->mTexture); + + image = nsnull; + data = nsnull; + autoLock.Unlock(); + device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); if (mFilter == gfxPattern::FILTER_NEAREST) { device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); @@ -375,7 +407,7 @@ ImageLayerD3D9::RenderLayer() } } else { PlanarYCbCrImage *yuvImage = - static_cast(image.get()); + static_cast(image); if (!yuvImage->mBufferSize) { return; @@ -459,6 +491,10 @@ ImageLayerD3D9::RenderLayer() device()->SetTexture(1, data->mCbTexture); device()->SetTexture(2, data->mCrTexture); + image = nsnull; + data = nsnull; + autoLock.Unlock(); + device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); device()->SetVertexShaderConstantF(CBvTextureCoords, diff --git a/gfx/layers/d3d9/ImageLayerD3D9.h b/gfx/layers/d3d9/ImageLayerD3D9.h index 60bf4f547b9..ead250e02c2 100644 --- a/gfx/layers/d3d9/ImageLayerD3D9.h +++ b/gfx/layers/d3d9/ImageLayerD3D9.h @@ -71,7 +71,7 @@ public: }; -struct CairoD3D9BackendData : public ImageBackendData +struct TextureD3D9BackendData : public ImageBackendData { nsRefPtr mTexture; }; diff --git a/gfx/layers/opengl/ContainerLayerOGL.cpp b/gfx/layers/opengl/ContainerLayerOGL.cpp index 1db510645a9..b7e8a58adf5 100644 --- a/gfx/layers/opengl/ContainerLayerOGL.cpp +++ b/gfx/layers/opengl/ContainerLayerOGL.cpp @@ -256,6 +256,14 @@ ContainerRender(Container* aContainer, if (needsFramebuffer) { // Unbind the current framebuffer and rebind the previous one. +#ifdef MOZ_DUMP_PAINTING + if (gfxUtils::sDumpPainting) { + nsRefPtr surf = + aContainer->gl()->GetTexImage(containerSurface, true, aManager->GetFBOLayerProgramType()); + + WriteSnapshotToDumpFile(aContainer, surf); + } +#endif // Restore the viewport aContainer->gl()->PopViewportRect(); diff --git a/gfx/layers/opengl/ImageLayerOGL.cpp b/gfx/layers/opengl/ImageLayerOGL.cpp index 999a3fd10fc..959e5c945db 100644 --- a/gfx/layers/opengl/ImageLayerOGL.cpp +++ b/gfx/layers/opengl/ImageLayerOGL.cpp @@ -214,19 +214,26 @@ void ImageLayerOGL::RenderLayer(int, const nsIntPoint& aOffset) { - if (!GetContainer()) + nsRefPtr container = GetContainer(); + + if (!container) return; mOGLManager->MakeCurrent(); - nsRefPtr image = GetContainer()->GetCurrentImage(); + AutoLockImage autoLock(container); + + Image *image = autoLock.GetImage(); if (!image) { return; } + NS_ASSERTION(image->GetFormat() != Image::REMOTE_IMAGE_BITMAP, + "Remote images aren't handled yet in OGL layers!"); + if (image->GetFormat() == Image::PLANAR_YCBCR) { PlanarYCbCrImage *yuvImage = - static_cast(image.get()); + static_cast(image); if (!yuvImage->mBufferSize) { return; @@ -276,7 +283,7 @@ ImageLayerOGL::RenderLayer(int, gl()->fActiveTexture(LOCAL_GL_TEXTURE0); } else if (image->GetFormat() == Image::CAIRO_SURFACE) { CairoImage *cairoImage = - static_cast(image.get()); + static_cast(image); if (!cairoImage->mSurface) { return; @@ -424,16 +431,18 @@ ImageLayerOGL::RenderLayer(int, #ifdef XP_MACOSX } else if (image->GetFormat() == Image::MAC_IO_SURFACE) { MacIOSurfaceImage *ioImage = - static_cast(image.get()); + static_cast(image); if (!mOGLManager->GetThebesLayerCallback()) { // If its an empty transaction we still need to update // the plugin IO Surface and make sure we grab the // new image ioImage->Update(GetContainer()); - image = GetContainer()->GetCurrentImage(); + image = nsnull; + autoLock.Refresh(); + image = autoLock.GetImage(); gl()->MakeCurrent(); - ioImage = static_cast(image.get()); + ioImage = static_cast(image); } if (!ioImage) { diff --git a/gfx/layers/opengl/LayerManagerOGL.cpp b/gfx/layers/opengl/LayerManagerOGL.cpp index e36f5ddb142..6cf649e0252 100644 --- a/gfx/layers/opengl/LayerManagerOGL.cpp +++ b/gfx/layers/opengl/LayerManagerOGL.cpp @@ -54,6 +54,8 @@ #include "LayerManagerOGLShaders.h" #include "gfxContext.h" +#include "gfxUtils.h" +#include "gfxPlatform.h" #include "nsIWidget.h" #include "GLContext.h" @@ -779,8 +781,20 @@ LayerManagerOGL::Render() mWidget->DrawWindowOverlay(this, rect); +#ifdef MOZ_DUMP_PAINTING + if (gfxUtils::sDumpPainting) { + nsIntRect rect; + mWidget->GetBounds(rect); + nsRefPtr surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(rect.Size(), gfxASurface::CONTENT_COLOR_ALPHA); + nsRefPtr ctx = new gfxContext(surf); + CopyToTarget(ctx); + + WriteSnapshotToDumpFile(this, surf); + } +#endif + if (mTarget) { - CopyToTarget(); + CopyToTarget(mTarget); mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0); return; } @@ -986,7 +1000,7 @@ LayerManagerOGL::SetupBackBuffer(int aWidth, int aHeight) } void -LayerManagerOGL::CopyToTarget() +LayerManagerOGL::CopyToTarget(gfxContext *aTarget) { nsIntRect rect; mWidget->GetBounds(rect); @@ -1050,11 +1064,11 @@ LayerManagerOGL::CopyToTarget() } } - mTarget->SetOperator(gfxContext::OPERATOR_SOURCE); - mTarget->Scale(1.0, -1.0); - mTarget->Translate(-gfxPoint(0.0, height)); - mTarget->SetSource(imageSurface); - mTarget->Paint(); + aTarget->SetOperator(gfxContext::OPERATOR_SOURCE); + aTarget->Scale(1.0, -1.0); + aTarget->Translate(-gfxPoint(0.0, height)); + aTarget->SetSource(imageSurface); + aTarget->Paint(); } LayerManagerOGL::ProgramType LayerManagerOGL::sLayerProgramTypes[] = { diff --git a/gfx/layers/opengl/LayerManagerOGL.h b/gfx/layers/opengl/LayerManagerOGL.h index db296f88837..3a5ef168b57 100644 --- a/gfx/layers/opengl/LayerManagerOGL.h +++ b/gfx/layers/opengl/LayerManagerOGL.h @@ -236,9 +236,13 @@ public: } ColorTextureLayerProgram *GetFBOLayerProgram() { + return static_cast(mPrograms[GetFBOLayerProgramType()]); + } + + gl::ShaderProgramType GetFBOLayerProgramType() { if (mFBOTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) - return static_cast(mPrograms[gl::RGBARectLayerProgramType]); - return static_cast(mPrograms[gl::RGBALayerProgramType]); + return gl::RGBARectLayerProgramType; + return gl::RGBALayerProgramType; } GLContext *gl() const { return mGLContext; } @@ -451,7 +455,7 @@ private: /** * Copies the content of our backbuffer to the set transaction target. */ - void CopyToTarget(); + void CopyToTarget(gfxContext *aTarget); /** * Updates all layer programs with a new projection matrix. diff --git a/gfx/layers/opengl/ThebesLayerOGL.cpp b/gfx/layers/opengl/ThebesLayerOGL.cpp index 1ae5b7b0026..fc8dc205401 100644 --- a/gfx/layers/opengl/ThebesLayerOGL.cpp +++ b/gfx/layers/opengl/ThebesLayerOGL.cpp @@ -145,6 +145,15 @@ ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset, mTexImageOnWhite->EndUpdate(); } +#ifdef MOZ_DUMP_PAINTING + if (gfxUtils::sDumpPainting) { + nsRefPtr surf = + gl()->GetTexImage(mTexImage->GetTextureID(), false, mTexImage->GetShaderProgramType()); + + WriteSnapshotToDumpFile(mLayer, surf); + } +#endif + PRInt32 passes = mTexImageOnWhite ? 2 : 1; for (PRInt32 pass = 1; pass <= passes; ++pass) { LayerProgram *program; diff --git a/gfx/thebes/gfxASurface.cpp b/gfx/thebes/gfxASurface.cpp index 75f9d1c70e8..a940daaaa83 100644 --- a/gfx/thebes/gfxASurface.cpp +++ b/gfx/thebes/gfxASurface.cpp @@ -716,9 +716,16 @@ gfxASurface::WriteAsPNG(const char* aFile) } void -gfxASurface::DumpAsDataURL() +gfxASurface::DumpAsDataURL(FILE* aOutput) { + WriteAsPNG_internal(aOutput, false); +} + +void +gfxASurface::PrintAsDataURL() +{ WriteAsPNG_internal(stdout, false); + fprintf(stdout, "\n"); } void @@ -776,7 +783,6 @@ gfxASurface::WriteAsPNG_internal(FILE* aFile, bool aBinary) for (PRInt32 x = 0; x < w; ++x) { printf("%x ", reinterpret_cast(imgsurf->Data())[y*imgsurf->Stride()+ x]); } - printf("\n"); } return; } @@ -846,7 +852,6 @@ gfxASurface::WriteAsPNG_internal(FILE* aFile, bool aBinary) if (aFile) { fprintf(aFile, "%s", string.BeginReading()); - fprintf(aFile, "\n"); } else { nsCOMPtr clipboard(do_GetService("@mozilla.org/widget/clipboardhelper;1", &rv)); if (clipboard) { diff --git a/gfx/thebes/gfxASurface.h b/gfx/thebes/gfxASurface.h index 05895b090d0..21d7977b2d8 100644 --- a/gfx/thebes/gfxASurface.h +++ b/gfx/thebes/gfxASurface.h @@ -257,10 +257,15 @@ public: */ void WriteAsPNG(const char* aFile); + /** + * Write as a PNG encoded Data URL to a file. + */ + void DumpAsDataURL(FILE* aOutput = stdout); + /** * Write as a PNG encoded Data URL to stdout. */ - void DumpAsDataURL(); + void PrintAsDataURL(); /** * Copy a PNG encoded Data URL to the clipboard. diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index 621126d67fa..d1b600010ee 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -692,4 +692,8 @@ gfxUtils::CopyAsDataURL(DrawTarget* aDT) NS_WARNING("Failed to get Thebes surface!"); } } + +bool gfxUtils::sDumpPainting = getenv("MOZ_DUMP_PAINT_LIST") != 0; +bool gfxUtils::sDumpPaintingToFile = getenv("MOZ_DUMP_PAINT_TO_FILE") != 0; +FILE *gfxUtils::sDumpPaintFile = NULL; #endif diff --git a/gfx/thebes/gfxUtils.h b/gfx/thebes/gfxUtils.h index 5da826fa793..d9a1f86697b 100644 --- a/gfx/thebes/gfxUtils.h +++ b/gfx/thebes/gfxUtils.h @@ -167,7 +167,12 @@ public: * Copy a PNG encoded Data URL to the clipboard. */ static void CopyAsDataURL(mozilla::gfx::DrawTarget* aDT); + + static bool sDumpPainting; + static bool sDumpPaintingToFile; + static FILE* sDumpPaintFile; #endif }; + #endif diff --git a/image/src/imgLoader.cpp b/image/src/imgLoader.cpp index cf36776e2e6..d3c91aa1d07 100644 --- a/image/src/imgLoader.cpp +++ b/image/src/imgLoader.cpp @@ -137,182 +137,194 @@ static void PrintImageDecoders() #endif NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ImagesMallocSizeOf, "images") - + class imgMemoryReporter MOZ_FINAL : - public nsIMemoryReporter + public nsIMemoryMultiReporter { public: - enum ReporterType { - CHROME_BIT = PR_BIT(0), - USED_BIT = PR_BIT(1), - RAW_BIT = PR_BIT(2), - HEAP_BIT = PR_BIT(3), - - ChromeUsedRaw = CHROME_BIT | USED_BIT | RAW_BIT | HEAP_BIT, - ChromeUsedUncompressedHeap = CHROME_BIT | USED_BIT | HEAP_BIT, - ChromeUsedUncompressedNonheap = CHROME_BIT | USED_BIT, - ChromeUnusedRaw = CHROME_BIT | RAW_BIT | HEAP_BIT, - ChromeUnusedUncompressedHeap = CHROME_BIT | HEAP_BIT, - ChromeUnusedUncompressedNonheap = CHROME_BIT, - ContentUsedRaw = USED_BIT | RAW_BIT | HEAP_BIT, - ContentUsedUncompressedHeap = USED_BIT | HEAP_BIT, - ContentUsedUncompressedNonheap = USED_BIT, - ContentUnusedRaw = RAW_BIT | HEAP_BIT, - ContentUnusedUncompressedHeap = HEAP_BIT, - ContentUnusedUncompressedNonheap = 0 - }; - - imgMemoryReporter(ReporterType aType) - : mType(aType) + imgMemoryReporter() { - // If the RAW bit is set, HEAP should also be set, because we don't - // currently understand storing compressed image data off the heap. - NS_ASSERTION(!(aType & RAW_BIT) || (aType & HEAP_BIT), - "RAW bit should imply HEAP bit."); } NS_DECL_ISUPPORTS - NS_IMETHOD GetProcess(nsACString &process) + NS_IMETHOD GetName(nsACString &name) { - process.Truncate(); + name.Assign("images"); return NS_OK; } - NS_IMETHOD GetPath(nsACString &path) + NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *callback, + nsISupports *closure) { - if (mType == ChromeUsedRaw) { - path.AssignLiteral("explicit/images/chrome/used/raw"); - } else if (mType == ChromeUsedUncompressedHeap) { - path.AssignLiteral("explicit/images/chrome/used/uncompressed-heap"); - } else if (mType == ChromeUsedUncompressedNonheap) { - path.AssignLiteral("explicit/images/chrome/used/uncompressed-nonheap"); - } else if (mType == ChromeUnusedRaw) { - path.AssignLiteral("explicit/images/chrome/unused/raw"); - } else if (mType == ChromeUnusedUncompressedHeap) { - path.AssignLiteral("explicit/images/chrome/unused/uncompressed-heap"); - } else if (mType == ChromeUnusedUncompressedNonheap) { - path.AssignLiteral("explicit/images/chrome/unused/uncompressed-nonheap"); - } else if (mType == ContentUsedRaw) { - path.AssignLiteral("explicit/images/content/used/raw"); - } else if (mType == ContentUsedUncompressedHeap) { - path.AssignLiteral("explicit/images/content/used/uncompressed-heap"); - } else if (mType == ContentUsedUncompressedNonheap) { - path.AssignLiteral("explicit/images/content/used/uncompressed-nonheap"); - } else if (mType == ContentUnusedRaw) { - path.AssignLiteral("explicit/images/content/unused/raw"); - } else if (mType == ContentUnusedUncompressedHeap) { - path.AssignLiteral("explicit/images/content/unused/uncompressed-heap"); - } else if (mType == ContentUnusedUncompressedNonheap) { - path.AssignLiteral("explicit/images/content/unused/uncompressed-nonheap"); + AllSizes chrome; + AllSizes content; + imgLoader::sChromeCache.EnumerateRead(EntryAllSizes, &chrome); + imgLoader::sCache.EnumerateRead(EntryAllSizes, &content); + +#define REPORT(_path, _kind, _amount, _desc) \ + do { \ + nsresult rv; \ + rv = callback->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \ + _kind, nsIMemoryReporter::UNITS_BYTES, _amount, \ + NS_LITERAL_CSTRING(_desc), closure); \ + NS_ENSURE_SUCCESS(rv, rv); \ + } while (0) + + REPORT("explicit/images/chrome/used/raw", + nsIMemoryReporter::KIND_HEAP, chrome.mUsedRaw, + "Memory used by in-use chrome images (compressed data)."); + + REPORT("explicit/images/chrome/used/uncompressed-heap", + nsIMemoryReporter::KIND_HEAP, chrome.mUsedUncompressedHeap, + "Memory used by in-use chrome images (uncompressed data)."); + + REPORT("explicit/images/chrome/used/uncompressed-nonheap", + nsIMemoryReporter::KIND_NONHEAP, chrome.mUsedUncompressedNonheap, + "Memory used by in-use chrome images (uncompressed data)."); + + REPORT("explicit/images/chrome/unused/raw", + nsIMemoryReporter::KIND_HEAP, chrome.mUnusedRaw, + "Memory used by not in-use chrome images (compressed data)."); + + REPORT("explicit/images/chrome/unused/uncompressed-heap", + nsIMemoryReporter::KIND_HEAP, chrome.mUnusedUncompressedHeap, + "Memory used by not in-use chrome images (uncompressed data)."); + + REPORT("explicit/images/chrome/unused/uncompressed-nonheap", + nsIMemoryReporter::KIND_NONHEAP, chrome.mUnusedUncompressedNonheap, + "Memory used by not in-use chrome images (uncompressed data)."); + + REPORT("explicit/images/content/used/raw", + nsIMemoryReporter::KIND_HEAP, content.mUsedRaw, + "Memory used by in-use content images (compressed data)."); + + REPORT("explicit/images/content/used/uncompressed-heap", + nsIMemoryReporter::KIND_HEAP, content.mUsedUncompressedHeap, + "Memory used by in-use content images (uncompressed data)."); + + REPORT("explicit/images/content/used/uncompressed-nonheap", + nsIMemoryReporter::KIND_NONHEAP, content.mUsedUncompressedNonheap, + "Memory used by in-use content images (uncompressed data)."); + + REPORT("explicit/images/content/unused/raw", + nsIMemoryReporter::KIND_HEAP, content.mUnusedRaw, + "Memory used by not in-use content images (compressed data)."); + + REPORT("explicit/images/content/unused/uncompressed-heap", + nsIMemoryReporter::KIND_HEAP, content.mUnusedUncompressedHeap, + "Memory used by not in-use content images (uncompressed data)."); + + REPORT("explicit/images/content/unused/uncompressed-nonheap", + nsIMemoryReporter::KIND_NONHEAP, content.mUnusedUncompressedNonheap, + "Memory used by not in-use content images (uncompressed data)."); + +#undef REPORT + + return NS_OK; + } + + NS_IMETHOD GetExplicitNonHeap(PRInt64 *n) + { + size_t n2 = 0; + imgLoader::sChromeCache.EnumerateRead(EntryExplicitNonHeapSize, &n2); + imgLoader::sCache.EnumerateRead(EntryExplicitNonHeapSize, &n2); + *n = n2; + return NS_OK; + } + + static PRInt64 GetImagesContentUsedUncompressed() + { + size_t n = 0; + imgLoader::sCache.EnumerateRead(EntryUsedUncompressedSize, &n); + return n; + } + +private: + struct AllSizes { + size_t mUsedRaw; + size_t mUsedUncompressedHeap; + size_t mUsedUncompressedNonheap; + size_t mUnusedRaw; + size_t mUnusedUncompressedHeap; + size_t mUnusedUncompressedNonheap; + + AllSizes() { + memset(this, 0, sizeof(*this)); } - return NS_OK; - } - - NS_IMETHOD GetKind(PRInt32 *kind) - { - if (mType & HEAP_BIT) { - *kind = KIND_HEAP; - } - else { - *kind = KIND_MAPPED; - } - return NS_OK; - } - - NS_IMETHOD GetUnits(PRInt32 *units) - { - *units = UNITS_BYTES; - return NS_OK; - } - - struct EnumArg { - EnumArg(ReporterType aType) - : rtype(aType), n(0) - { } - - ReporterType rtype; - size_t n; }; - static PLDHashOperator EnumEntries(const nsACString&, - imgCacheEntry *entry, - void *userArg) + static PLDHashOperator EntryAllSizes(const nsACString&, + imgCacheEntry *entry, + void *userArg) { - EnumArg *arg = static_cast(userArg); - ReporterType rtype = arg->rtype; - - if (rtype & USED_BIT) { - if (entry->HasNoProxies()) - return PL_DHASH_NEXT; - } else { - if (!entry->HasNoProxies()) - return PL_DHASH_NEXT; - } - nsRefPtr req = entry->GetRequest(); Image *image = static_cast(req->mImage.get()); - if (!image) - return PL_DHASH_NEXT; - - if (rtype & RAW_BIT) { - arg->n += image->HeapSizeOfSourceWithComputedFallback(ImagesMallocSizeOf); - } else if (rtype & HEAP_BIT) { - arg->n += image->HeapSizeOfDecodedWithComputedFallback(ImagesMallocSizeOf); - } else { - arg->n += image->NonHeapSizeOfDecoded(); + if (image) { + AllSizes *sizes = static_cast(userArg); + if (entry->HasNoProxies()) { + sizes->mUnusedRaw += + image->HeapSizeOfSourceWithComputedFallback(ImagesMallocSizeOf); + sizes->mUnusedUncompressedHeap += + image->HeapSizeOfDecodedWithComputedFallback(ImagesMallocSizeOf); + sizes->mUnusedUncompressedNonheap += image->NonHeapSizeOfDecoded(); + } else { + sizes->mUsedRaw += + image->HeapSizeOfSourceWithComputedFallback(ImagesMallocSizeOf); + sizes->mUsedUncompressedHeap += + image->HeapSizeOfDecodedWithComputedFallback(ImagesMallocSizeOf); + sizes->mUsedUncompressedNonheap += image->NonHeapSizeOfDecoded(); + } } return PL_DHASH_NEXT; } - NS_IMETHOD GetAmount(PRInt64 *amount) + static PLDHashOperator EntryExplicitNonHeapSize(const nsACString&, + imgCacheEntry *entry, + void *userArg) { - EnumArg arg(mType); - if (mType & CHROME_BIT) { - imgLoader::sChromeCache.EnumerateRead(EnumEntries, &arg); - } else { - imgLoader::sCache.EnumerateRead(EnumEntries, &arg); + size_t *n = static_cast(userArg); + nsRefPtr req = entry->GetRequest(); + Image *image = static_cast(req->mImage.get()); + if (image) { + *n += image->NonHeapSizeOfDecoded(); } - *amount = arg.n; - return NS_OK; + return PL_DHASH_NEXT; } - NS_IMETHOD GetDescription(nsACString &desc) + static PLDHashOperator EntryUsedUncompressedSize(const nsACString&, + imgCacheEntry *entry, + void *userArg) { - if (mType == ChromeUsedRaw) { - desc.AssignLiteral("Memory used by in-use chrome images (compressed data)."); - } else if (mType == ChromeUsedUncompressedHeap) { - desc.AssignLiteral("Memory used by in-use chrome images (uncompressed data)."); - } else if (mType == ChromeUsedUncompressedNonheap) { - desc.AssignLiteral("Memory used by in-use chrome images (uncompressed data)."); - } else if (mType == ChromeUnusedRaw) { - desc.AssignLiteral("Memory used by not in-use chrome images (compressed data)."); - } else if (mType == ChromeUnusedUncompressedHeap) { - desc.AssignLiteral("Memory used by not in-use chrome images (uncompressed data)."); - } else if (mType == ChromeUnusedUncompressedNonheap) { - desc.AssignLiteral("Memory used by not in-use chrome images (uncompressed data)."); - } else if (mType == ContentUsedRaw) { - desc.AssignLiteral("Memory used by in-use content images (compressed data)."); - } else if (mType == ContentUsedUncompressedHeap) { - desc.AssignLiteral("Memory used by in-use content images (uncompressed data)."); - } else if (mType == ContentUsedUncompressedNonheap) { - desc.AssignLiteral("Memory used by in-use content images (uncompressed data)."); - } else if (mType == ContentUnusedRaw) { - desc.AssignLiteral("Memory used by not in-use content images (compressed data)."); - } else if (mType == ContentUnusedUncompressedHeap) { - desc.AssignLiteral("Memory used by not in-use content images (uncompressed data)."); - } else if (mType == ContentUnusedUncompressedNonheap) { - desc.AssignLiteral("Memory used by not in-use content images (uncompressed data)."); + if (!entry->HasNoProxies()) { + size_t *n = static_cast(userArg); + nsRefPtr req = entry->GetRequest(); + Image *image = static_cast(req->mImage.get()); + if (image) { + *n += image->HeapSizeOfDecodedWithComputedFallback(ImagesMallocSizeOf); + *n += image->NonHeapSizeOfDecoded(); + } } - return NS_OK; - } - ReporterType mType; + return PL_DHASH_NEXT; + } }; -NS_IMPL_ISUPPORTS1(imgMemoryReporter, nsIMemoryReporter) +// This is used by telemetry. +NS_MEMORY_REPORTER_IMPLEMENT( + ImagesContentUsedUncompressed, + "images-content-used-uncompressed", + KIND_OTHER, + UNITS_BYTES, + imgMemoryReporter::GetImagesContentUsedUncompressed, + "This is the sum of the 'explicit/images/content/used/uncompressed-heap' " + "and 'explicit/images/content/used/uncompressed-nonheap' numbers. However, " + "it is measured at a different time and so may give slightly different " + "results.") + +NS_IMPL_ISUPPORTS1(imgMemoryReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS3(nsProgressNotificationProxy, nsIProgressEventSink, @@ -922,18 +934,8 @@ nsresult imgLoader::InitCache() else sCacheMaxSize = 5 * 1024 * 1024; - NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ChromeUsedRaw)); - NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ChromeUsedUncompressedHeap)); - NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ChromeUsedUncompressedNonheap)); - NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ChromeUnusedRaw)); - NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ChromeUnusedUncompressedHeap)); - NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ChromeUnusedUncompressedNonheap)); - NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ContentUsedRaw)); - NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ContentUsedUncompressedHeap)); - NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ContentUsedUncompressedNonheap)); - NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ContentUnusedRaw)); - NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ContentUnusedUncompressedHeap)); - NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ContentUnusedUncompressedNonheap)); + NS_RegisterMemoryMultiReporter(new imgMemoryReporter()); + NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(ImagesContentUsedUncompressed)); return NS_OK; } diff --git a/ipc/glue/CrossProcessMutex.h b/ipc/glue/CrossProcessMutex.h new file mode 100644 index 00000000000..aa757edc166 --- /dev/null +++ b/ipc/glue/CrossProcessMutex.h @@ -0,0 +1,133 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * ***** 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 Corporation 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): + * Bas Schouten + * + * 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 mozilla_CrossProcessMutex_h +#define mozilla_CrossProcessMutex_h + +#include "base/process.h" +#include "mozilla/Mutex.h" + +namespace IPC { +template +struct ParamTraits; +} + +// +// Provides: +// +// - CrossProcessMutex, a non-recursive mutex that can be shared across processes +// - CrossProcessMutexAutoLock, an RAII class for ensuring that Mutexes are +// properly locked and unlocked +// +// Using CrossProcessMutexAutoLock/CrossProcessMutexAutoUnlock is MUCH +// preferred to making bare calls to CrossProcessMutex.Lock and Unlock. +// +namespace mozilla { +#ifdef XP_WIN +typedef HANDLE CrossProcessMutexHandle; +#else +// Stub for other platforms. We can't use uintptr_t here since different +// processes could disagree on its size. +typedef uintptr_t CrossProcessMutexHandle; +#endif + +class NS_COM_GLUE CrossProcessMutex +{ +public: + /** + * CrossProcessMutex + * @param name A name which can reference this lock (currently unused) + **/ + CrossProcessMutex(const char* aName); + /** + * CrossProcessMutex + * @param handle A handle of an existing cross process mutex that can be + * opened. + */ + CrossProcessMutex(CrossProcessMutexHandle aHandle); + + /** + * ~CrossProcessMutex + **/ + ~CrossProcessMutex(); + + /** + * Lock + * This will lock the mutex. Any other thread in any other process that + * has access to this mutex calling lock will block execution until the + * initial caller of lock has made a call to Unlock. + * + * If the owning process is terminated unexpectedly the mutex will be + * released. + **/ + void Lock(); + + /** + * Unlock + * This will unlock the mutex. A single thread currently waiting on a lock + * call will resume execution and aquire ownership of the lock. No + * guarantees are made as to the order in which waiting threads will resume + * execution. + **/ + void Unlock(); + + /** + * ShareToProcess + * This function is called to generate a serializable structure that can + * be sent to the specified process and opened on the other side. + * + * @returns A handle that can be shared to another process + */ + CrossProcessMutexHandle ShareToProcess(base::ProcessHandle aTarget); + +private: + friend struct IPC::ParamTraits; + + CrossProcessMutex(); + CrossProcessMutex(const CrossProcessMutex&); + CrossProcessMutex &operator=(const CrossProcessMutex&); + +#ifdef XP_WIN + HANDLE mMutex; +#endif +}; + +typedef BaseAutoLock CrossProcessMutexAutoLock; +typedef BaseAutoUnlock CrossProcessMutexAutoUnlock; + +} +#endif diff --git a/ipc/glue/CrossProcessMutex_unimplemented.cpp b/ipc/glue/CrossProcessMutex_unimplemented.cpp new file mode 100644 index 00000000000..a23f246c8c4 --- /dev/null +++ b/ipc/glue/CrossProcessMutex_unimplemented.cpp @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * ***** 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 Corporation 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): + * Bas Schouten + * + * 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 "CrossProcessMutex.h" + +#include "nsDebug.h" + +namespace mozilla { + +CrossProcessMutex::CrossProcessMutex(const char*) +{ + NS_RUNTIMEABORT("Cross-process mutices not allowed on this platform."); +} + +CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle) +{ + NS_RUNTIMEABORT("Cross-process mutices not allowed on this platform."); +} + +CrossProcessMutex::~CrossProcessMutex() +{ + NS_RUNTIMEABORT("Cross-process mutices not allowed on this platform - woah! We should've aborted by now!"); +} + +void +CrossProcessMutex::Lock() +{ + NS_RUNTIMEABORT("Cross-process mutices not allowed on this platform - woah! We should've aborted by now!"); +} + +void +CrossProcessMutex::Unlock() +{ + NS_RUNTIMEABORT("Cross-process mutices not allowed on this platform - woah! We should've aborted by now!"); +} + +CrossProcessMutexHandle +CrossProcessMutex::ShareToProcess(base::ProcessHandle aHandle) +{ + NS_RUNTIMEABORT("Cross-process mutices not allowed on this platform - woah! We should've aborted by now!"); + return NULL; +} + +} diff --git a/ipc/glue/CrossProcessMutex_windows.cpp b/ipc/glue/CrossProcessMutex_windows.cpp new file mode 100644 index 00000000000..6509c2bce78 --- /dev/null +++ b/ipc/glue/CrossProcessMutex_windows.cpp @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * ***** 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 Corporation 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): + * Bas Schouten + * + * 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 + +#include "base/process_util.h" +#include "CrossProcessMutex.h" +#include "nsDebug.h" +#include "nsTraceRefcnt.h" + +using namespace base; + +namespace mozilla { + +CrossProcessMutex::CrossProcessMutex(const char*) +{ + // We explicitly share this using DuplicateHandle, we do -not- want this to + // be inherited by child processes by default! So no security attributes are + // given. + mMutex = ::CreateMutexA(NULL, FALSE, NULL); + if (!mMutex) { + NS_RUNTIMEABORT("This shouldn't happen - failed to create mutex!"); + } + MOZ_COUNT_CTOR(CrossProcessMutex); +} + +CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle aHandle) +{ + DWORD flags; + if (!::GetHandleInformation(aHandle, &flags)) { + NS_RUNTIMEABORT("Attempt to construct a mutex from an invalid handle!"); + } + mMutex = aHandle; +} + +CrossProcessMutex::~CrossProcessMutex() +{ + NS_ASSERTION(mMutex, "Improper construction of mutex or double free."); + ::CloseHandle(mMutex); + MOZ_COUNT_DTOR(CrossProcessMutex); +} + +void +CrossProcessMutex::Lock() +{ + NS_ASSERTION(mMutex, "Improper construction of mutex."); + ::WaitForSingleObject(mMutex, INFINITE); +} + +void +CrossProcessMutex::Unlock() +{ + NS_ASSERTION(mMutex, "Improper construction of mutex."); + ::ReleaseMutex(mMutex); +} + +CrossProcessMutexHandle +CrossProcessMutex::ShareToProcess(ProcessHandle aHandle) +{ + HANDLE newHandle; + bool succeeded = ::DuplicateHandle(GetCurrentProcessHandle(), + mMutex, aHandle, &newHandle, + NULL, FALSE, DUPLICATE_SAME_ACCESS); + + if (!succeeded) { + return NULL; + } + + return newHandle; +} + +} diff --git a/ipc/glue/Makefile.in b/ipc/glue/Makefile.in index 4a349c78507..5fe0f380366 100644 --- a/ipc/glue/Makefile.in +++ b/ipc/glue/Makefile.in @@ -56,6 +56,7 @@ EXPORTS_IPC = IPCMessageUtils.h EXPORTS_mozilla/ipc = \ AsyncChannel.h \ BrowserProcessSubThread.h \ + CrossProcessMutex.h \ GeckoChildProcessHost.h \ IOThreadChild.h \ ProcessChild.h \ @@ -111,12 +112,14 @@ CPPSRCS += \ SharedMemory_windows.cpp \ Transport_win.cpp \ WindowsMessageLoop.cpp \ + CrossProcessMutex_windows.cpp \ $(NULL) else # POSIX CPPSRCS += \ SharedMemory_posix.cpp \ Transport_posix.cpp \ + CrossProcessMutex_unimplemented.cpp \ $(NULL) endif #} diff --git a/ipc/testshell/XPCShellEnvironment.cpp b/ipc/testshell/XPCShellEnvironment.cpp index 10d389d53d7..c297635df6e 100644 --- a/ipc/testshell/XPCShellEnvironment.cpp +++ b/ipc/testshell/XPCShellEnvironment.cpp @@ -507,10 +507,12 @@ DumpHeap(JSContext *cx, } } - ok = JS_DumpHeap(cx, dumpFile, startThing, startTraceKind, thingToFind, + ok = JS_DumpHeap(JS_GetRuntime(cx), dumpFile, startThing, startTraceKind, thingToFind, maxDepth, thingToIgnore); if (dumpFile != stdout) fclose(dumpFile); + if (!ok) + JS_ReportOutOfMemory(cx); return ok; not_traceable_arg: diff --git a/js/jsd/jsd_xpc.cpp b/js/jsd/jsd_xpc.cpp index cd437c43e11..4617eb47e23 100644 --- a/js/jsd/jsd_xpc.cpp +++ b/js/jsd/jsd_xpc.cpp @@ -2835,7 +2835,7 @@ jsdService::DumpHeap(const nsACString &fileName) rv = NS_ERROR_FAILURE; } else { JSContext *cx = JSD_GetDefaultJSContext (mCx); - if (!JS_DumpHeap(cx, file, NULL, JSTRACE_OBJECT, NULL, (size_t)-1, NULL)) + if (!JS_DumpHeap(JS_GetRuntime(cx), file, NULL, JSTRACE_OBJECT, NULL, (size_t)-1, NULL)) rv = NS_ERROR_FAILURE; if (file != stdout) fclose(file); diff --git a/js/public/HashTable.h b/js/public/HashTable.h index 53a82ff6eb8..48cb7775744 100644 --- a/js/public/HashTable.h +++ b/js/public/HashTable.h @@ -1062,7 +1062,7 @@ class HashMap */ typedef typename Impl::Range Range; Range all() const { return impl.all(); } - size_t count() const { return impl.count(); } + uint32_t count() const { return impl.count(); } size_t capacity() const { return impl.capacity(); } size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const { return impl.sizeOfExcludingThis(mallocSizeOf); @@ -1272,7 +1272,7 @@ class HashSet */ typedef typename Impl::Range Range; Range all() const { return impl.all(); } - size_t count() const { return impl.count(); } + uint32_t count() const { return impl.count(); } size_t capacity() const { return impl.capacity(); } size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const { return impl.sizeOfExcludingThis(mallocSizeOf); diff --git a/js/public/Utility.h b/js/public/Utility.h index e5f72ce7c8c..c3027269b71 100644 --- a/js/public/Utility.h +++ b/js/public/Utility.h @@ -115,7 +115,7 @@ extern JS_PUBLIC_DATA(uint32_t) OOM_counter; /* data race, who cares. */ # define JS_OOM_POSSIBLY_FAIL() \ do \ { \ - if (OOM_counter++ >= OOM_maxAllocations) { \ + if (++OOM_counter > OOM_maxAllocations) { \ return NULL; \ } \ } while (0) diff --git a/js/src/build/autoconf/frameptr.m4 b/js/src/build/autoconf/frameptr.m4 index 77a6d71aedc..cfda09f56fb 100644 --- a/js/src/build/autoconf/frameptr.m4 +++ b/js/src/build/autoconf/frameptr.m4 @@ -3,8 +3,13 @@ dnl disabling frame pointers in this architecture based on the configure dnl options AC_DEFUN([MOZ_SET_FRAMEPTR_FLAGS], [ + case "$target" in + *android*) + unwind_tables="-funwind-tables" + ;; + esac if test "$GNU_CC"; then - MOZ_ENABLE_FRAME_PTR="-fno-omit-frame-pointer" + MOZ_ENABLE_FRAME_PTR="-fno-omit-frame-pointer $unwind_tables" MOZ_DISABLE_FRAME_PTR="-fomit-frame-pointer" else case "$target" in diff --git a/js/src/builtin/MapObject.cpp b/js/src/builtin/MapObject.cpp index 1d2d50f3a35..bd348814282 100644 --- a/js/src/builtin/MapObject.cpp +++ b/js/src/builtin/MapObject.cpp @@ -42,6 +42,7 @@ #include "jscntxt.h" #include "jsgcmark.h" +#include "jsiter.h" #include "jsobj.h" #include "vm/GlobalObject.h" @@ -62,7 +63,7 @@ InitClass(JSContext *cx, GlobalObject *global, Class *clasp, JSProtoKey key, Nat proto->setPrivate(NULL); JSAtom *atom = cx->runtime->atomState.classAtoms[key]; - JSFunction *ctor = global->createConstructor(cx, construct, clasp, atom, 0); + JSFunction *ctor = global->createConstructor(cx, construct, clasp, atom, 1); if (!ctor || !LinkConstructorAndPrototype(cx, ctor, proto) || !DefinePropertiesAndBrand(cx, proto, NULL, methods) || @@ -165,6 +166,7 @@ Class MapObject::class_ = { }; JSFunctionSpec MapObject::methods[] = { + JS_FN("size", size, 0, 0), JS_FN("get", get, 1, 0), JS_FN("has", has, 1, 0), JS_FN("set", set, 2, 0), @@ -201,6 +203,37 @@ MapObject::finalize(JSContext *cx, JSObject *obj) cx->delete_(map); } +class AddToMap { + private: + ValueMap *map; + + public: + AddToMap(ValueMap *map) : map(map) {} + + bool operator()(JSContext *cx, const Value &v) { + JSObject *pairobj = js_ValueToNonNullObject(cx, v); + if (!pairobj) + return false; + + Value key; + if (!pairobj->getElement(cx, 0, &key)) + return false; + HashableValue hkey; + if (!hkey.setValue(cx, key)) + return false; + + Value val; + if (!pairobj->getElement(cx, 1, &val)) + return false; + + if (!map->put(hkey, val)) { + js_ReportOutOfMemory(cx); + return false; + } + return true; + } +}; + JSBool MapObject::construct(JSContext *cx, unsigned argc, Value *vp) { @@ -209,11 +242,21 @@ MapObject::construct(JSContext *cx, unsigned argc, Value *vp) return false; ValueMap *map = cx->new_(cx->runtime); - if (!map || !map->init()) + if (!map) return false; + if (!map->init()) { + js_ReportOutOfMemory(cx); + return false; + } obj->setPrivate(map); - CallArgsFromVp(argc, vp).rval().setObject(*obj); + CallArgs args = CallArgsFromVp(argc, vp); + if (args.hasDefined(0)) { + if (!ForOf(cx, args[0], AddToMap(map))) + return false; + } + + args.rval().setObject(*obj); return true; } @@ -240,6 +283,15 @@ MapObject::construct(JSContext *cx, unsigned argc, Value *vp) if (args.length() > 0 && !key.setValue(cx, args[0])) \ return false +JSBool +MapObject::size(JSContext *cx, unsigned argc, Value *vp) +{ + THIS_MAP(get, cx, argc, vp, args, map); + JS_STATIC_ASSERT(sizeof map.count() <= sizeof(uint32_t)); + args.rval().setNumber(map.count()); + return true; +} + JSBool MapObject::get(JSContext *cx, unsigned argc, Value *vp) { @@ -267,7 +319,10 @@ MapObject::set(JSContext *cx, unsigned argc, Value *vp) { THIS_MAP(set, cx, argc, vp, args, map); ARG0_KEY(cx, args, key); - map.put(key, args.length() > 1 ? args[1] : UndefinedValue()); + if (!map.put(key, args.length() > 1 ? args[1] : UndefinedValue())) { + js_ReportOutOfMemory(cx); + return false; + } args.rval().setUndefined(); return true; } @@ -314,6 +369,7 @@ Class SetObject::class_ = { }; JSFunctionSpec SetObject::methods[] = { + JS_FN("size", size, 0, 0), JS_FN("has", has, 1, 0), JS_FN("add", add, 1, 0), JS_FN("delete", delete_, 1, 0), @@ -348,6 +404,25 @@ SetObject::finalize(JSContext *cx, JSObject *obj) cx->delete_(set); } +class AddToSet { + private: + ValueSet *set; + + public: + AddToSet(ValueSet *set) : set(set) {} + + bool operator()(JSContext *cx, const Value &v) { + HashableValue key; + if (!key.setValue(cx, v)) + return false; + if (!set->put(key)) { + js_ReportOutOfMemory(cx); + return false; + } + return true; + } +}; + JSBool SetObject::construct(JSContext *cx, unsigned argc, Value *vp) { @@ -356,17 +431,36 @@ SetObject::construct(JSContext *cx, unsigned argc, Value *vp) return false; ValueSet *set = cx->new_(cx->runtime); - if (!set || !set->init()) + if (!set) return false; + if (!set->init()) { + js_ReportOutOfMemory(cx); + return false; + } obj->setPrivate(set); - CallArgsFromVp(argc, vp).rval().setObject(*obj); + CallArgs args = CallArgsFromVp(argc, vp); + if (args.hasDefined(0)) { + if (!ForOf(cx, args[0], AddToSet(set))) + return false; + } + + args.rval().setObject(*obj); return true; } #define THIS_SET(native, cx, argc, vp, args, set) \ UNPACK_THIS(SetObject, native, cx, argc, vp, args, set) +JSBool +SetObject::size(JSContext *cx, unsigned argc, Value *vp) +{ + THIS_SET(has, cx, argc, vp, args, set); + JS_STATIC_ASSERT(sizeof set.count() <= sizeof(uint32_t)); + args.rval().setNumber(set.count()); + return true; +} + JSBool SetObject::has(JSContext *cx, unsigned argc, Value *vp) { @@ -381,8 +475,10 @@ SetObject::add(JSContext *cx, unsigned argc, Value *vp) { THIS_SET(add, cx, argc, vp, args, set); ARG0_KEY(cx, args, key); - if (!set.put(key)) + if (!set.put(key)) { + js_ReportOutOfMemory(cx); return false; + } args.rval().setUndefined(); return true; } diff --git a/js/src/builtin/MapObject.h b/js/src/builtin/MapObject.h index a3997653468..fd3354545ab 100644 --- a/js/src/builtin/MapObject.h +++ b/js/src/builtin/MapObject.h @@ -89,6 +89,7 @@ class MapObject : public JSObject { static void mark(JSTracer *trc, JSObject *obj); static void finalize(JSContext *cx, JSObject *obj); static JSBool construct(JSContext *cx, unsigned argc, Value *vp); + static JSBool size(JSContext *cx, unsigned argc, Value *vp); static JSBool get(JSContext *cx, unsigned argc, Value *vp); static JSBool has(JSContext *cx, unsigned argc, Value *vp); static JSBool set(JSContext *cx, unsigned argc, Value *vp); @@ -106,6 +107,7 @@ class SetObject : public JSObject { static void mark(JSTracer *trc, JSObject *obj); static void finalize(JSContext *cx, JSObject *obj); static JSBool construct(JSContext *cx, unsigned argc, Value *vp); + static JSBool size(JSContext *cx, unsigned argc, Value *vp); static JSBool has(JSContext *cx, unsigned argc, Value *vp); static JSBool add(JSContext *cx, unsigned argc, Value *vp); static JSBool delete_(JSContext *cx, unsigned argc, Value *vp); diff --git a/js/src/builtin/RegExp.cpp b/js/src/builtin/RegExp.cpp index fb22436c575..745831a3b11 100644 --- a/js/src/builtin/RegExp.cpp +++ b/js/src/builtin/RegExp.cpp @@ -244,7 +244,7 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args) */ JSObject &sourceObj = sourceValue.toObject(); - if (args.length() >= 2 && !args[1].isUndefined()) { + if (args.hasDefined(1)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NEWREGEXP_FLAGGED); return false; } @@ -293,7 +293,7 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args) } RegExpFlag flags = RegExpFlag(0); - if (args.length() > 1 && !args[1].isUndefined()) { + if (args.hasDefined(1)) { JSString *flagStr = ToString(cx, args[1]); if (!flagStr) return false; @@ -343,8 +343,9 @@ regexp_construct(JSContext *cx, unsigned argc, Value *vp) * Otherwise, delegate to the standard constructor. * See ECMAv5 15.10.3.1. */ - if (args.length() >= 1 && IsObjectWithClass(args[0], ESClass_RegExp, cx) && - (args.length() == 1 || args[1].isUndefined())) + if (args.hasDefined(0) && + IsObjectWithClass(args[0], ESClass_RegExp, cx) && + !args.hasDefined(1)) { args.rval() = args[0]; return true; diff --git a/js/src/config/system-headers b/js/src/config/system-headers index 5bddb364965..2fc1b1c3f7d 100644 --- a/js/src/config/system-headers +++ b/js/src/config/system-headers @@ -913,6 +913,7 @@ sechash.h secoidt.h certdb.h secerr.h +nssutil.h nssb64.h secasn1.h secder.h diff --git a/js/src/jit-test/tests/basic/bug730888.js b/js/src/jit-test/tests/basic/bug730888.js new file mode 100644 index 00000000000..5d328d6aa52 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug730888.js @@ -0,0 +1,14 @@ + +(function() { + for (var i = 0; i < 64; ++i) { + var name; + switch (this) { + case 0: name = 'firstAttr'; break; + case 1: name = 'secondAttr'; + case 2: name = 'thirdAttr'; break; + } + switch (name) { + case 'firstAttr': assertEq(result, 'value'); break; + } + } +})(); diff --git a/js/src/jit-test/tests/basic/bug732087.js b/js/src/jit-test/tests/basic/bug732087.js new file mode 100644 index 00000000000..852b4142b6a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug732087.js @@ -0,0 +1,6 @@ +gczeal(2,1); +var count = 0; +var a = {__noSuchMethod__: function() { count++; } } +for (var i = 0; i < 10; i++) { + a.b(); +} diff --git a/js/src/jit-test/tests/collections/Map-constructor-1.js b/js/src/jit-test/tests/collections/Map-constructor-1.js new file mode 100644 index 00000000000..304747ff8ae --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-constructor-1.js @@ -0,0 +1,6 @@ +// The Map constructor creates an empty Map by default. + +assertEq(Map().size(), 0); +assertEq((new Map).size(), 0); +assertEq(Map(undefined).size(), 0); +assertEq(new Map(undefined).size(), 0); diff --git a/js/src/jit-test/tests/collections/Map-constructor-2.js b/js/src/jit-test/tests/collections/Map-constructor-2.js new file mode 100644 index 00000000000..91c0fd5afd0 --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-constructor-2.js @@ -0,0 +1,6 @@ +// The Map constructor can take an argument that is an array of pairs. + +var arr = [["zero", 0], ["one", 1], ["two", 2]]; +var m = Map(arr); +for (var [k, v] of arr) + assertEq(m.get(k), v); diff --git a/js/src/jit-test/tests/collections/Map-constructor-3.js b/js/src/jit-test/tests/collections/Map-constructor-3.js new file mode 100644 index 00000000000..76881a51dfd --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-constructor-3.js @@ -0,0 +1,9 @@ +// Map can take an argument that is an array of singleton arrays. + +var arr = [["a"], ["b"], ["c"]]; +var m = Map(arr); +assertEq(m.size(), 3); +for (var [k, _] of arr) { + assertEq(m.has(k), true); + assertEq(m.get(k), undefined); +} diff --git a/js/src/jit-test/tests/collections/Map-constructor-4.js b/js/src/jit-test/tests/collections/Map-constructor-4.js new file mode 100644 index 00000000000..8bd34c3fd38 --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-constructor-4.js @@ -0,0 +1,6 @@ +// Map(x) throws if x is not iterable (unless x is undefined). + +load(libdir + "asserts.js"); +var nonIterables = [null, true, 1, -0, 3.14, NaN, "", "xyzzy", {}, Math, this]; +for (let k of nonIterables) + assertThrowsInstanceOf(function () { Map(k); }, TypeError); diff --git a/js/src/jit-test/tests/collections/Map-constructor-5.js b/js/src/jit-test/tests/collections/Map-constructor-5.js new file mode 100644 index 00000000000..9fc4c2e4031 --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-constructor-5.js @@ -0,0 +1,7 @@ +// Map(arr) throws if arr contains holes (or undefined values). + +load(libdir + "asserts.js"); +assertThrowsInstanceOf(function () { Map([undefined]); }, TypeError); +assertThrowsInstanceOf(function () { Map([null]); }, TypeError); +assertThrowsInstanceOf(function () { Map([[0, 0], [1, 1], , [3, 3]]); }, TypeError); +assertThrowsInstanceOf(function () { Map([[0, 0], [1, 1], ,]); }, TypeError); diff --git a/js/src/jit-test/tests/collections/Map-constructor-duplicates.js b/js/src/jit-test/tests/collections/Map-constructor-duplicates.js new file mode 100644 index 00000000000..9fade316ac3 --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-constructor-duplicates.js @@ -0,0 +1,8 @@ +// When the argument to Map contains a key multiple times, the last value is retained. + +var arg = [["zero", 7], ["one", 1], ["two", 4], ["zero", 8], ["two", 2], ["zero", 0]]; +var m = Map(arg); +assertEq(m.get("zero"), 0); +assertEq(m.get("one"), 1); +assertEq(m.get("two"), 2); +assertEq(m.size(), 3); diff --git a/js/src/jit-test/tests/collections/Map-constructor-generator-1.js b/js/src/jit-test/tests/collections/Map-constructor-generator-1.js new file mode 100644 index 00000000000..21fc6c5e70b --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-constructor-generator-1.js @@ -0,0 +1,19 @@ +// The argument to Map can be a generator. + +var done = false; +function data(n) { + var s = ''; + for (var i = 0; i < n; i++) { + yield [s, i]; + s += '.'; + } + done = true; +} + +var m = Map(data(50)); +assertEq(done, true); // the constructor consumes the argument +assertEq(m.size(), 50); +assertEq(m.get(""), 0); +assertEq(m.get("....."), 5); +assertEq(m.get(Array(49+1).join(".")), 49); +assertEq(m.has(undefined), false); diff --git a/js/src/jit-test/tests/collections/Map-constructor-generator-2.js b/js/src/jit-test/tests/collections/Map-constructor-generator-2.js new file mode 100644 index 00000000000..afbe2e1d38c --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-constructor-generator-2.js @@ -0,0 +1,8 @@ +// The argument to Map can be a generator-expression. + +var arr = [1, 2, "green", "red"]; +var m = Map([v, v] for (v of arr)); +assertEq(m.size(), 4); + +for (var i = 0; i < 4; i++) + assertEq(m.get(arr[i]), arr[i]); diff --git a/js/src/jit-test/tests/collections/Map-constructor-generator-3.js b/js/src/jit-test/tests/collections/Map-constructor-generator-3.js new file mode 100644 index 00000000000..44e9479f83b --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-constructor-generator-3.js @@ -0,0 +1,8 @@ +// The argument to Map may be a generator-iterator that produces no values. + +assertEq(Map(x for (x of [])).size(), 0); + +function none() { + if (0) yield 0; +} +assertEq(Map(none()).size(), 0); diff --git a/js/src/jit-test/tests/collections/Map-constructor-generator-exception.js b/js/src/jit-test/tests/collections/Map-constructor-generator-exception.js new file mode 100644 index 00000000000..3bd55388831 --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-constructor-generator-exception.js @@ -0,0 +1,12 @@ +// Iterating over the argument to Map can throw. The exception is propagated. + +load(libdir + "asserts.js"); + +function data2() { + yield [{}, "XR22/Z"]; + yield [{}, "23D-BN"]; + throw "oops"; +} + +var it = data2(); +assertThrowsValue(function () { Map(it); }, "oops"); diff --git a/js/src/jit-test/tests/collections/Map-delete-size.js b/js/src/jit-test/tests/collections/Map-delete-size.js new file mode 100644 index 00000000000..5ece89c63a6 --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-delete-size.js @@ -0,0 +1,14 @@ +// map.delete(k) decrements the map size iff an entry was actually removed. + +var m = Map(); +m.delete(3); +assertEq(m.size(), 0); +m.set({}, 'ok'); +m.set(Math, 'ok'); +assertEq(m.size(), 2); +m.delete({}); +assertEq(m.size(), 2); +m.delete(Math); +assertEq(m.size(), 1); +m.delete(Math); +assertEq(m.size(), 1); diff --git a/js/src/jit-test/tests/collections/Map-set-size.js b/js/src/jit-test/tests/collections/Map-set-size.js new file mode 100644 index 00000000000..f0a4cdfde14 --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-set-size.js @@ -0,0 +1,14 @@ +// map.set(k, v) increments the map size iff map didn't already have an entry for k. + +var m = Map(); +m.set('a', 0); +assertEq(m.size(), 1); +m.set('a', 0); +assertEq(m.size(), 1); +m.set('a', undefined); +assertEq(m.size(), 1); + +m.set('b', 2); +assertEq(m.size(), 2); +m.set('a', 1); +assertEq(m.size(), 2); diff --git a/js/src/jit-test/tests/collections/Map-size.js b/js/src/jit-test/tests/collections/Map-size.js new file mode 100644 index 00000000000..325abdc1a9a --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-size.js @@ -0,0 +1,6 @@ +// Each Map has its own size. + +var m1 = Map(), m2 = Map(); +m1.set("x", 3); +assertEq(m1.size(), 1); +assertEq(m2.size(), 0); diff --git a/js/src/jit-test/tests/collections/Map-surfaces-1.js b/js/src/jit-test/tests/collections/Map-surfaces-1.js index e8f3d6790f4..3d38a813e04 100644 --- a/js/src/jit-test/tests/collections/Map-surfaces-1.js +++ b/js/src/jit-test/tests/collections/Map-surfaces-1.js @@ -7,7 +7,7 @@ assertEq(desc.writable, true); assertEq(typeof Map, 'function'); assertEq(Object.keys(Map).length, 0); -assertEq(Map.length, 0); +assertEq(Map.length, 1); assertEq(Map.name, "Map"); assertEq(Object.getPrototypeOf(Map.prototype), Object.prototype); @@ -27,6 +27,7 @@ function checkMethod(name, arity) { assertEq(desc.value.length, arity); } +checkMethod("size", 0); checkMethod("get", 1); checkMethod("has", 1); checkMethod("set", 2); diff --git a/js/src/jit-test/tests/collections/Map-surfaces-2.js b/js/src/jit-test/tests/collections/Map-surfaces-2.js index 9ca168fbd95..ca5e8d26e58 100644 --- a/js/src/jit-test/tests/collections/Map-surfaces-2.js +++ b/js/src/jit-test/tests/collections/Map-surfaces-2.js @@ -9,6 +9,7 @@ function testcase(obj, fn) { } function test(obj) { + testcase(obj, Map.prototype.size); testcase(obj, Map.prototype.get, "x"); testcase(obj, Map.prototype.has, "x"); testcase(obj, Map.prototype.set, "x", 1); diff --git a/js/src/jit-test/tests/collections/Set-add-size.js b/js/src/jit-test/tests/collections/Set-add-size.js new file mode 100644 index 00000000000..381bd111d13 --- /dev/null +++ b/js/src/jit-test/tests/collections/Set-add-size.js @@ -0,0 +1,11 @@ +// set.add(v) increments set.size() iff the set did not already contain v. + +var s = Set(); +for (var i = 0; i < 10; i++) { + assertEq(s.size(), i); + s.add(i); +} +for (var i = 0; i < 10; i++) { + assertEq(s.size(), 10); + s.add(i); +} diff --git a/js/src/jit-test/tests/collections/Set-constructor-1.js b/js/src/jit-test/tests/collections/Set-constructor-1.js new file mode 100644 index 00000000000..f7c75067ee7 --- /dev/null +++ b/js/src/jit-test/tests/collections/Set-constructor-1.js @@ -0,0 +1,6 @@ +// The Set constructor creates an empty Set by default. + +assertEq(Set().size(), 0); +assertEq((new Set).size(), 0); +assertEq(Set(undefined).size(), 0); +assertEq(new Set(undefined).size(), 0); diff --git a/js/src/jit-test/tests/collections/Set-constructor-2.js b/js/src/jit-test/tests/collections/Set-constructor-2.js new file mode 100644 index 00000000000..92dccc84919 --- /dev/null +++ b/js/src/jit-test/tests/collections/Set-constructor-2.js @@ -0,0 +1,18 @@ +// The Set constructor can take an argument that is an array. + +var s = Set([]); +assertEq(s.size(), 0); +assertEq(s.has(undefined), false); + +s = Set(["one", "two", "three"]); +assertEq(s.size(), 3); +assertEq(s.has("one"), true); +assertEq(s.has("eleventeen"), false); + +var a = [{}, {}, {}]; +s = Set(a); +assertEq(s.size(), 3); +for (let obj of a) + assertEq(s.has(obj), true); +assertEq(s.has({}), false); +assertEq(s.has("three"), false); diff --git a/js/src/jit-test/tests/collections/Set-constructor-3.js b/js/src/jit-test/tests/collections/Set-constructor-3.js new file mode 100644 index 00000000000..7238c0610c3 --- /dev/null +++ b/js/src/jit-test/tests/collections/Set-constructor-3.js @@ -0,0 +1,11 @@ +// The argument to Set may contain a value multiple times. Duplicates are discarded. + +assertEq(Set(["testing", "testing", 123]).size(), 2); + +var values = [undefined, null, false, NaN, 0, -0, 6.022e23, -Infinity, "", "xyzzy", {}, Math.sin]; +for (let v of values) { + var a = [v, {}, {}, {}, v, {}, v, v]; + var s = Set(a); + assertEq(s.size(), 5); + assertEq(s.has(v), true); +} diff --git a/js/src/jit-test/tests/collections/Set-constructor-generator-1.js b/js/src/jit-test/tests/collections/Set-constructor-generator-1.js new file mode 100644 index 00000000000..26db09ba41e --- /dev/null +++ b/js/src/jit-test/tests/collections/Set-constructor-generator-1.js @@ -0,0 +1,12 @@ +// The argument to Set can be a generator. + +function hexData(n) { + for (var i = 0; i < n; i++) + yield i.toString(16); +} + +var s = Set(hexData(256)); +assertEq(s.size(), 256); +assertEq(s.has("0"), true); +assertEq(s.has(0), false); +assertEq(s.has("ff"), true); diff --git a/js/src/jit-test/tests/collections/Set-constructor-generator-2.js b/js/src/jit-test/tests/collections/Set-constructor-generator-2.js new file mode 100644 index 00000000000..4e65253fe06 --- /dev/null +++ b/js/src/jit-test/tests/collections/Set-constructor-generator-2.js @@ -0,0 +1,8 @@ +// The argument to Set can be a generator-expression. + +var s = Set(k * k for (k of [1, 2, 3, 4])); +assertEq(s.size(), 4); +assertEq(s.has(1), true); +assertEq(s.has(4), true); +assertEq(s.has(9), true); +assertEq(s.has(16), true); diff --git a/js/src/jit-test/tests/collections/Set-delete-size.js b/js/src/jit-test/tests/collections/Set-delete-size.js new file mode 100644 index 00000000000..e02234a99bd --- /dev/null +++ b/js/src/jit-test/tests/collections/Set-delete-size.js @@ -0,0 +1,15 @@ +// set.delete(v) decrements set.size() iff the set contained v. + +var s = Set(); +for (var i = 0; i < 10; i++) + s.add(i); + +for (var i = 10; i > 0; i--) { + assertEq(s.size(), i); + assertEq(s.delete(i), false); + assertEq(s.size(), i); + assertEq(s.delete(i - 1), true); + assertEq(s.size(), i - 1); + assertEq(s.delete(i - 1), false); + assertEq(s.size(), i - 1); +} diff --git a/js/src/jit-test/tests/collections/Set-size.js b/js/src/jit-test/tests/collections/Set-size.js new file mode 100644 index 00000000000..b82c24e96a7 --- /dev/null +++ b/js/src/jit-test/tests/collections/Set-size.js @@ -0,0 +1,7 @@ +// Each Set has its own size. + +var s1 = Set(), s2 = Set(); +for (var i = 0; i < 30; i++) + s1.add(i); +assertEq(s1.size(), 30); +assertEq(s2.size(), 0); diff --git a/js/src/jit-test/tests/collections/Set-surfaces-1.js b/js/src/jit-test/tests/collections/Set-surfaces-1.js index c63b024f69d..b4989140c46 100644 --- a/js/src/jit-test/tests/collections/Set-surfaces-1.js +++ b/js/src/jit-test/tests/collections/Set-surfaces-1.js @@ -7,7 +7,7 @@ assertEq(desc.writable, true); assertEq(typeof Set, 'function'); assertEq(Object.keys(Set).length, 0); -assertEq(Set.length, 0); +assertEq(Set.length, 1); assertEq(Set.name, "Set"); assertEq(Object.getPrototypeOf(Set.prototype), Object.prototype); diff --git a/js/src/jit-test/tests/for-of/array-holes-2.js b/js/src/jit-test/tests/for-of/array-holes-2.js index 7090e636eae..cc37aedf2ac 100644 --- a/js/src/jit-test/tests/for-of/array-holes-2.js +++ b/js/src/jit-test/tests/for-of/array-holes-2.js @@ -1,8 +1,8 @@ -// for-of does not consult Object.prototype when it encounters a hole. +// for-of consults Object.prototype when it encounters a hole. -Object.prototype[1] = 'FAIL'; +Object.prototype[1] = 'peek'; var log = []; for (var x of [0, , 2, 3]) log.push(x); -assertEq(log[1], undefined); -assertEq(log.join(), "0,,2,3"); +assertEq(log[1], 'peek'); +assertEq(log.join(), "0,peek,2,3"); diff --git a/js/src/jit-test/tests/for-of/array-holes-3.js b/js/src/jit-test/tests/for-of/array-holes-3.js index 7eecfe3816d..9b4d087bde5 100644 --- a/js/src/jit-test/tests/for-of/array-holes-3.js +++ b/js/src/jit-test/tests/for-of/array-holes-3.js @@ -1,8 +1,8 @@ -// for-of does not consult Array.prototype when it encounters a hole. +// for-of consults Array.prototype when it encounters a hole. -Array.prototype[1] = 'FAIL'; +Array.prototype[1] = 'peek'; var log = []; for (var x of [0, , 2, 3]) log.push(x); -assertEq(log[1], undefined); -assertEq(log.join(), "0,,2,3"); +assertEq(log[1], 'peek'); +assertEq(log.join(), "0,peek,2,3"); diff --git a/js/src/jit-test/tests/for-of/array-holes-4.js b/js/src/jit-test/tests/for-of/array-holes-4.js index 871ed685a1f..865111f3eb3 100644 --- a/js/src/jit-test/tests/for-of/array-holes-4.js +++ b/js/src/jit-test/tests/for-of/array-holes-4.js @@ -1,10 +1,10 @@ -// for-of on an Array does not consult the prototype chain when it encounters a hole. +// for-of on an Array consults the prototype chain when it encounters a hole. -var m = {1: 'FAIL'}; +var m = {1: 'peek'}; var a = [0, , 2, 3]; a.__proto__ = m; var log = []; for (var x of a) log.push(x); -assertEq(log[1], undefined); -assertEq(log.join(), "0,,2,3"); +assertEq(log[1], 'peek'); +assertEq(log.join(), "0,peek,2,3"); diff --git a/js/src/jit-test/tests/for-of/array-holes-5.js b/js/src/jit-test/tests/for-of/array-holes-5.js new file mode 100644 index 00000000000..3f70ed123b5 --- /dev/null +++ b/js/src/jit-test/tests/for-of/array-holes-5.js @@ -0,0 +1,6 @@ +// for-of does not skip trailing holes; the value is undefined. + +var log = ""; +for (var x of [1, 2, 3,,]) + log += x; +assertEq(log, "123undefined"); diff --git a/js/src/jit-test/tests/for-of/array-holes-6.js b/js/src/jit-test/tests/for-of/array-holes-6.js new file mode 100644 index 00000000000..2b4703fbce1 --- /dev/null +++ b/js/src/jit-test/tests/for-of/array-holes-6.js @@ -0,0 +1,8 @@ +// for-of visits each hole in an array full of holes. + +var n = 0; +for (var x of Array(5)) { + assertEq(x, undefined); + n++; +} +assertEq(n, 5); diff --git a/js/src/jit-test/tests/for-of/array-holes-7.js b/js/src/jit-test/tests/for-of/array-holes-7.js new file mode 100644 index 00000000000..05fe7d1f4e5 --- /dev/null +++ b/js/src/jit-test/tests/for-of/array-holes-7.js @@ -0,0 +1,5 @@ +// for-of visits inherited properties in an array full of holes. + +Object.prototype[1] = "O"; +Array.prototype[2] = "A"; +assertEq([x for (x of Array(4))].join(","), ",O,A,"); diff --git a/js/src/jit-test/tests/for-of/array-holes-slow.js b/js/src/jit-test/tests/for-of/array-holes-slow.js index c4961398c70..7478ee6ac48 100644 --- a/js/src/jit-test/tests/for-of/array-holes-slow.js +++ b/js/src/jit-test/tests/for-of/array-holes-slow.js @@ -1,13 +1,13 @@ -// for-of on a slow Array does not consult the prototype chain when it encounters a hole. +// for-of on a slow Array consults the prototype chain when it encounters a hole. var a = [0, , , 3]; a.slow = true; -Object.prototype[1] = 'FAIL1'; -Array.prototype[2] = 'FAIL2'; +Object.prototype[1] = 'peek1'; +Array.prototype[2] = 'peek2'; var log = []; for (var x of a) log.push(x); -assertEq(log[1], undefined); -assertEq(log[2], undefined); -assertEq(log.join(), "0,,,3"); +assertEq(log[1], 'peek1'); +assertEq(log[2], 'peek2'); +assertEq(log.join(), "0,peek1,peek2,3"); diff --git a/js/src/jsanalyze.cpp b/js/src/jsanalyze.cpp index 5552a957bb9..c46f50ee5e5 100644 --- a/js/src/jsanalyze.cpp +++ b/js/src/jsanalyze.cpp @@ -1316,6 +1316,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx) SlotValue &v = (*pending)[i]; if (v.slot < numSlots && liveness(v.slot).firstWrite(code->loop) != UINT32_MAX) { if (v.value.kind() != SSAValue::PHI || v.value.phiOffset() != offset) { + JS_ASSERT(v.value.phiOffset() < offset); SSAValue ov = v.value; if (!makePhi(cx, v.slot, offset, &ov)) return; @@ -1524,19 +1525,14 @@ ScriptAnalysis::analyzeSSA(JSContext *cx) jsint high = GET_JUMP_OFFSET(pc2); pc2 += JUMP_OFFSET_LEN; - Vector *pending = NULL; - uint32_t pendingOffset = 0; - for (jsint i = low; i <= high; i++) { unsigned targetOffset = offset + GET_JUMP_OFFSET(pc2); if (targetOffset != offset) - checkBranchTarget(cx, targetOffset, branchTargets, values, stackDepth, - &pending, &pendingOffset); + checkBranchTarget(cx, targetOffset, branchTargets, values, stackDepth); pc2 += JUMP_OFFSET_LEN; } - checkBranchTarget(cx, defaultOffset, branchTargets, values, stackDepth, - &pending, &pendingOffset); + checkBranchTarget(cx, defaultOffset, branchTargets, values, stackDepth); break; } @@ -1546,20 +1542,15 @@ ScriptAnalysis::analyzeSSA(JSContext *cx) unsigned npairs = GET_UINT16(pc2); pc2 += UINT16_LEN; - Vector *pending = NULL; - uint32_t pendingOffset = 0; - while (npairs) { pc2 += UINT32_INDEX_LEN; unsigned targetOffset = offset + GET_JUMP_OFFSET(pc2); - checkBranchTarget(cx, targetOffset, branchTargets, values, stackDepth, - &pending, &pendingOffset); + checkBranchTarget(cx, targetOffset, branchTargets, values, stackDepth); pc2 += JUMP_OFFSET_LEN; npairs--; } - checkBranchTarget(cx, defaultOffset, branchTargets, values, stackDepth, - &pending, &pendingOffset); + checkBranchTarget(cx, defaultOffset, branchTargets, values, stackDepth); break; } @@ -1696,7 +1687,7 @@ ScriptAnalysis::mergeValue(JSContext *cx, uint32_t offset, const SSAValue &v, Sl if (v == pv->value) return; - if (pv->value.kind() != SSAValue::PHI || pv->value.phiOffset() != offset) { + if (pv->value.kind() != SSAValue::PHI || pv->value.phiOffset() < offset) { SSAValue ov = pv->value; if (makePhi(cx, pv->slot, offset, &pv->value)) { insertPhi(cx, pv->value, v); @@ -1705,6 +1696,7 @@ ScriptAnalysis::mergeValue(JSContext *cx, uint32_t offset, const SSAValue &v, Sl return; } + JS_ASSERT(pv->value.phiOffset() == offset); insertPhi(cx, pv->value, v); } @@ -1726,8 +1718,7 @@ ScriptAnalysis::checkPendingValue(JSContext *cx, const SSAValue &v, uint32_t slo void ScriptAnalysis::checkBranchTarget(JSContext *cx, uint32_t targetOffset, Vector &branchTargets, - SSAValueInfo *values, uint32_t stackDepth, - Vector **ppending, uint32_t *ppendingOffset) + SSAValueInfo *values, uint32_t stackDepth) { unsigned targetDepth = getCode(targetOffset).stackDepth; JS_ASSERT(targetDepth <= stackDepth); @@ -1744,25 +1735,11 @@ ScriptAnalysis::checkBranchTarget(JSContext *cx, uint32_t targetOffset, mergeValue(cx, targetOffset, values[v.slot].v, &v); } } else { - if (ppending && *ppending) { - JS_ASSERT(*ppendingOffset != targetOffset); - pending = *ppending; - getCode(Min(targetOffset, *ppendingOffset)).switchSharesPending = true; - } else { - pending = cx->new_< Vector >(cx); - if (!pending) { - setOOM(cx); - return; - } - } - if (!branchTargets.append(targetOffset)) { + pending = cx->new_< Vector >(cx); + if (!pending || !branchTargets.append(targetOffset)) { setOOM(cx); return; } - if (ppending) { - *ppending = pending; - *ppendingOffset = Max(targetOffset, *ppendingOffset); - } } /* @@ -1822,13 +1799,6 @@ ScriptAnalysis::mergeBranchTarget(JSContext *cx, SSAValueInfo &value, uint32_t s const Bytecode &code = getCode(branchTargets[i]); - /* - * If the pending array for this offset is shared with a later branch - * target, it will be updated when that offset is handled. - */ - if (code.switchSharesPending) - continue; - Vector *pending = code.pendingValues; checkPendingValue(cx, value.v, slot, pending); } @@ -1893,8 +1863,7 @@ ScriptAnalysis::freezeNewValues(JSContext *cx, uint32_t offset) unsigned count = pending->length(); if (count == 0) { - if (!code.switchSharesPending) - cx->delete_(pending); + cx->delete_(pending); return; } @@ -1909,8 +1878,7 @@ ScriptAnalysis::freezeNewValues(JSContext *cx, uint32_t offset) code.newValues[count].slot = 0; code.newValues[count].value.clear(); - if (!code.switchSharesPending) - cx->delete_(pending); + cx->delete_(pending); } CrossSSAValue diff --git a/js/src/jsanalyze.h b/js/src/jsanalyze.h index 23f4a3fc06c..0711cf47ddd 100644 --- a/js/src/jsanalyze.h +++ b/js/src/jsanalyze.h @@ -142,12 +142,6 @@ class Bytecode bool getStringElement:1; /* GETELEM which has accessed string properties. */ bool accessGetter: 1; /* Property read on a shape with a getter hook. */ - /* - * Switch target other than the last one, which shares its pending values - * with a later offset during SSA analysis. - */ - bool switchSharesPending : 1; - /* Stack depth before this opcode. */ uint32_t stackDepth; @@ -1213,8 +1207,7 @@ class ScriptAnalysis void checkPendingValue(JSContext *cx, const SSAValue &v, uint32_t slot, Vector *pending); void checkBranchTarget(JSContext *cx, uint32_t targetOffset, Vector &branchTargets, - SSAValueInfo *values, uint32_t stackDepth, - Vector **ppending = NULL, uint32_t *ppendingOffset = NULL); + SSAValueInfo *values, uint32_t stackDepth); void checkExceptionTarget(JSContext *cx, uint32_t catchOffset, Vector &exceptionTargets); void mergeBranchTarget(JSContext *cx, SSAValueInfo &value, uint32_t slot, diff --git a/js/src/jsapi-tests/testIntern.cpp b/js/src/jsapi-tests/testIntern.cpp index 5e5af0c79a4..d593949f643 100644 --- a/js/src/jsapi-tests/testIntern.cpp +++ b/js/src/jsapi-tests/testIntern.cpp @@ -23,12 +23,11 @@ struct StringWrapper bool strOk; } sw; -JSBool -GCCallback(JSContext *cx, JSGCStatus status) +void +FinalizeCallback(JSContext *cx, JSFinalizeStatus status) { - if (status == JSGC_MARK_END) + if (status == JSFINALIZE_START) sw.strOk = !JS_IsAboutToBeFinalized(sw.str); - return true; } BEGIN_TEST(testInternAcrossGC) @@ -36,7 +35,7 @@ BEGIN_TEST(testInternAcrossGC) sw.str = JS_InternString(cx, "wrapped chars that another test shouldn't be using"); sw.strOk = false; CHECK(sw.str); - JS_SetGCCallback(cx, GCCallback); + JS_SetFinalizeCallback(rt, FinalizeCallback); JS_GC(cx); CHECK(sw.strOk); return true; diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index e306f2952db..464fdacfecf 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -755,6 +755,7 @@ JSRuntime::JSRuntime() #endif gcCallback(NULL), gcSliceCallback(NULL), + gcFinalizeCallback(NULL), gcMallocBytes(0), gcBlackRootsTraceOp(NULL), gcBlackRootsData(NULL), @@ -1072,14 +1073,14 @@ JS_YieldRequest(JSContext *cx) #endif } -JS_PUBLIC_API(jsrefcount) +JS_PUBLIC_API(unsigned) JS_SuspendRequest(JSContext *cx) { #ifdef JS_THREADSAFE JSRuntime *rt = cx->runtime; JS_ASSERT(rt->onOwnerThread()); - jsrefcount saveDepth = rt->requestDepth; + unsigned saveDepth = rt->requestDepth; if (!saveDepth) return 0; @@ -1093,7 +1094,7 @@ JS_SuspendRequest(JSContext *cx) } JS_PUBLIC_API(void) -JS_ResumeRequest(JSContext *cx, jsrefcount saveDepth) +JS_ResumeRequest(JSContext *cx, unsigned saveDepth) { #ifdef JS_THREADSAFE JSRuntime *rt = cx->runtime; @@ -2428,9 +2429,9 @@ JS_SetExtraGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data) } JS_PUBLIC_API(void) -JS_TracerInit(JSTracer *trc, JSContext *cx, JSTraceCallback callback) +JS_TracerInit(JSTracer *trc, JSRuntime *rt, JSTraceCallback callback) { - InitTracer(trc, cx->runtime, cx, callback); + InitTracer(trc, rt, callback); } JS_PUBLIC_API(void) @@ -2605,7 +2606,7 @@ struct JSHeapDumpNode { typedef struct JSDumpingTracer { JSTracer base; JSDHashTable visited; - JSBool ok; + bool ok; void *startThing; void *thingToFind; void *thingToIgnore; @@ -2619,7 +2620,6 @@ DumpNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind) { void *thing = *thingp; JSDumpingTracer *dtrc; - JSContext *cx; JSDHashEntryStub *entry; JS_ASSERT(trc->callback == DumpNotify); @@ -2628,8 +2628,6 @@ DumpNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind) if (!dtrc->ok || thing == dtrc->thingToIgnore) return; - cx = trc->context; - /* * Check if we have already seen thing unless it is thingToFind to include * it to the graph each time we reach it and print all live things that @@ -2650,8 +2648,7 @@ DumpNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind) entry = (JSDHashEntryStub *) JS_DHashTableOperate(&dtrc->visited, thing, JS_DHASH_ADD); if (!entry) { - JS_ReportOutOfMemory(cx); - dtrc->ok = JS_FALSE; + dtrc->ok = false; return; } if (entry->key) @@ -2664,7 +2661,7 @@ DumpNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind) size_t bytes = offsetof(JSHeapDumpNode, edgeName) + edgeNameSize; JSHeapDumpNode *node = (JSHeapDumpNode *) OffTheBooks::malloc_(bytes); if (!node) { - dtrc->ok = JS_FALSE; + dtrc->ok = false; return; } @@ -2685,7 +2682,6 @@ DumpNode(JSDumpingTracer *dtrc, FILE* fp, JSHeapDumpNode *node) { JSHeapDumpNode *prev, *following; size_t chainLimit; - JSBool ok; enum { MAX_PARENTS_TO_PRINT = 10 }; JS_PrintTraceThingInfo(dtrc->buffer, sizeof dtrc->buffer, @@ -2718,21 +2714,21 @@ DumpNode(JSDumpingTracer *dtrc, FILE* fp, JSHeapDumpNode *node) node = prev; prev = following; - ok = JS_TRUE; + bool ok = true; do { /* Loop must continue even when !ok to restore the parent chain. */ if (ok) { if (!prev) { /* Print edge from some runtime root or startThing. */ if (fputs(node->edgeName, fp) < 0) - ok = JS_FALSE; + ok = false; } else { JS_PrintTraceThingInfo(dtrc->buffer, sizeof dtrc->buffer, &dtrc->base, prev->thing, prev->kind, JS_FALSE); if (fprintf(fp, "(%p %s).%s", prev->thing, dtrc->buffer, node->edgeName) < 0) { - ok = JS_FALSE; + ok = false; } } } @@ -2746,7 +2742,7 @@ DumpNode(JSDumpingTracer *dtrc, FILE* fp, JSHeapDumpNode *node) } JS_PUBLIC_API(JSBool) -JS_DumpHeap(JSContext *cx, FILE *fp, void* startThing, JSGCTraceKind startKind, +JS_DumpHeap(JSRuntime *rt, FILE *fp, void* startThing, JSGCTraceKind startKind, void *thingToFind, size_t maxDepth, void *thingToIgnore) { JSDumpingTracer dtrc; @@ -2757,12 +2753,11 @@ JS_DumpHeap(JSContext *cx, FILE *fp, void* startThing, JSGCTraceKind startKind, if (maxDepth == 0) return JS_TRUE; - JS_TracerInit(&dtrc.base, cx, DumpNotify); + JS_TracerInit(&dtrc.base, rt, DumpNotify); if (!JS_DHashTableInit(&dtrc.visited, JS_DHashGetStubOps(), NULL, sizeof(JSDHashEntryStub), JS_DHASH_DEFAULT_CAPACITY(100))) { - JS_ReportOutOfMemory(cx); - return JS_FALSE; + return false; } dtrc.ok = JS_TRUE; dtrc.startThing = startThing; @@ -2863,23 +2858,18 @@ JS_MaybeGC(JSContext *cx) MaybeGC(cx); } -JS_PUBLIC_API(JSGCCallback) -JS_SetGCCallback(JSContext *cx, JSGCCallback cb) +JS_PUBLIC_API(void) +JS_SetGCCallback(JSRuntime *rt, JSGCCallback cb) { - AssertNoGC(cx); - CHECK_REQUEST(cx); - return JS_SetGCCallbackRT(cx->runtime, cb); + AssertNoGC(rt); + rt->gcCallback = cb; } -JS_PUBLIC_API(JSGCCallback) -JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb) +JS_PUBLIC_API(void) +JS_SetFinalizeCallback(JSRuntime *rt, JSFinalizeCallback cb) { - JSGCCallback oldcb; - AssertNoGC(rt); - oldcb = rt->gcCallback; - rt->gcCallback = cb; - return oldcb; + rt->gcFinalizeCallback = cb; } JS_PUBLIC_API(JSBool) @@ -3352,6 +3342,12 @@ JS_IsNative(JSObject *obj) return obj->isNative(); } +JS_PUBLIC_API(JSRuntime *) +JS_GetObjectRuntime(JSObject *obj) +{ + return obj->compartment()->rt; +} + JS_PUBLIC_API(JSBool) JS_FreezeObject(JSContext *cx, JSObject *obj) { @@ -4451,16 +4447,16 @@ JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, } #ifdef JS_THREADSAFE -JS_PUBLIC_API(jsrefcount) +JS_PUBLIC_API(int) JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals) { return JS_ATOMIC_INCREMENT(&principals->refcount); } -JS_PUBLIC_API(jsrefcount) +JS_PUBLIC_API(int) JS_DropPrincipals(JSContext *cx, JSPrincipals *principals) { - jsrefcount rc = JS_ATOMIC_DECREMENT(&principals->refcount); + int rc = JS_ATOMIC_DECREMENT(&principals->refcount); if (rc == 0) principals->destroy(cx, principals); return rc; diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 27fb83d4ca0..aa6b992d230 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1426,17 +1426,20 @@ typedef JSBool (* JSContextCallback)(JSContext *cx, unsigned contextOp); typedef enum JSGCStatus { - /* These callbacks happen outside the GC lock. */ JSGC_BEGIN, - JSGC_END, - - /* These callbacks happen within the GC lock. */ - JSGC_MARK_END, - JSGC_FINALIZE_END + JSGC_END } JSGCStatus; -typedef JSBool -(* JSGCCallback)(JSContext *cx, JSGCStatus status); +typedef void +(* JSGCCallback)(JSRuntime *rt, JSGCStatus status); + +typedef enum JSFinalizeStatus { + JSFINALIZE_START, + JSFINALIZE_END +} JSFinalizeStatus; + +typedef void +(* JSFinalizeCallback)(JSContext *cx, JSFinalizeStatus status); /* * Generic trace operation that calls JS_CallTracer on each traceable thing @@ -2348,11 +2351,11 @@ JS_EndRequest(JSContext *cx); extern JS_PUBLIC_API(void) JS_YieldRequest(JSContext *cx); -extern JS_PUBLIC_API(jsrefcount) +extern JS_PUBLIC_API(unsigned) JS_SuspendRequest(JSContext *cx); extern JS_PUBLIC_API(void) -JS_ResumeRequest(JSContext *cx, jsrefcount saveDepth); +JS_ResumeRequest(JSContext *cx, unsigned saveDepth); extern JS_PUBLIC_API(JSBool) JS_IsInRequest(JSRuntime *rt); @@ -2393,7 +2396,7 @@ class JSAutoRequest { protected: JSContext *mContext; - jsrefcount mSaveDepth; + unsigned mSaveDepth; JS_DECL_USE_GUARD_OBJECT_NOTIFIER #if 0 @@ -2425,7 +2428,7 @@ class JSAutoSuspendRequest { protected: JSContext *mContext; - jsrefcount mSaveDepth; + unsigned mSaveDepth; JS_DECL_USE_GUARD_OBJECT_NOTIFIER #if 0 @@ -3119,7 +3122,6 @@ typedef void struct JSTracer { JSRuntime *runtime; - JSContext *context; JSTraceCallback callback; JSTraceNamePrinter debugPrinter; const void *debugPrintArg; @@ -3218,7 +3220,7 @@ JS_CallTracer(JSTracer *trc, void *thing, JSGCTraceKind kind); * API for JSTraceCallback implementations. */ extern JS_PUBLIC_API(void) -JS_TracerInit(JSTracer *trc, JSContext *cx, JSTraceCallback callback); +JS_TracerInit(JSTracer *trc, JSRuntime *rt, JSTraceCallback callback); extern JS_PUBLIC_API(void) JS_TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind); @@ -3251,7 +3253,7 @@ JS_GetTraceEdgeName(JSTracer *trc, char *buffer, int bufferSize); * thingToIgnore: thing to ignore during the graph traversal when non-null. */ extern JS_PUBLIC_API(JSBool) -JS_DumpHeap(JSContext *cx, FILE *fp, void* startThing, JSGCTraceKind kind, +JS_DumpHeap(JSRuntime *rt, FILE *fp, void* startThing, JSGCTraceKind kind, void *thingToFind, size_t maxDepth, void *thingToIgnore); #endif @@ -3268,11 +3270,11 @@ JS_CompartmentGC(JSContext *cx, JSCompartment *comp); extern JS_PUBLIC_API(void) JS_MaybeGC(JSContext *cx); -extern JS_PUBLIC_API(JSGCCallback) -JS_SetGCCallback(JSContext *cx, JSGCCallback cb); +extern JS_PUBLIC_API(void) +JS_SetGCCallback(JSRuntime *rt, JSGCCallback cb); -extern JS_PUBLIC_API(JSGCCallback) -JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb); +extern JS_PUBLIC_API(void) +JS_SetFinalizeCallback(JSRuntime *rt, JSFinalizeCallback cb); extern JS_PUBLIC_API(JSBool) JS_IsGCMarkingTracer(JSTracer *trc); @@ -3708,6 +3710,9 @@ JS_IsExtensible(JSObject *obj); extern JS_PUBLIC_API(JSBool) JS_IsNative(JSObject *obj); +extern JS_PUBLIC_API(JSRuntime *) +JS_GetObjectRuntime(JSObject *obj); + /* * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default * proto if proto's actual parameter value is null. @@ -4080,7 +4085,7 @@ struct JSPrincipals { char *codebase; /* Don't call "destroy"; use reference counting macros below. */ - jsrefcount refcount; + int refcount; void (* destroy)(JSContext *cx, JSPrincipals *); JSBool (* subsume)(JSPrincipals *, JSPrincipals *); @@ -4090,10 +4095,10 @@ struct JSPrincipals { #define JSPRINCIPALS_HOLD(cx, principals) JS_HoldPrincipals(cx,principals) #define JSPRINCIPALS_DROP(cx, principals) JS_DropPrincipals(cx,principals) -extern JS_PUBLIC_API(jsrefcount) +extern JS_PUBLIC_API(int) JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals); -extern JS_PUBLIC_API(jsrefcount) +extern JS_PUBLIC_API(int) JS_DropPrincipals(JSContext *cx, JSPrincipals *principals); #else diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 82137bf0678..89cb4d25345 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -1876,13 +1876,13 @@ array_join(JSContext *cx, unsigned argc, Value *vp) CallArgs args = CallArgsFromVp(argc, vp); JSString *str; - if (args.length() == 0 || args[0].isUndefined()) { - str = NULL; - } else { + if (args.hasDefined(0)) { str = ToString(cx, args[0]); if (!str) return JS_FALSE; args[0].setString(str); + } else { + str = NULL; } JSObject *obj = ToObject(cx, &args.thisv()); if (!obj) @@ -2188,7 +2188,7 @@ js::array_sort(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); Value fval; - if (args.length() > 0 && !args[0].isUndefined()) { + if (args.hasDefined(0)) { if (args[0].isPrimitive()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_SORT_ARG); return false; @@ -3026,7 +3026,7 @@ array_slice(JSContext *cx, unsigned argc, Value *vp) } begin = (jsuint)d; - if (args.length() > 1 && !args[1].isUndefined()) { + if (args.hasDefined(1)) { if (!ToInteger(cx, args[1], &d)) return false; if (d < 0) { diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 6289d6324d3..3604a2f3eed 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -86,7 +86,7 @@ struct JSSharpInfo { typedef js::HashMap JSSharpTable; struct JSSharpObjectMap { - jsrefcount depth; + unsigned depth; uint32_t sharpgen; JSSharpTable table; @@ -293,7 +293,7 @@ struct JSRuntime : js::RuntimeFriendFields js::RootedValueMap gcRootsHash; js::GCLocks gcLocksHash; - jsrefcount gcKeepAtoms; + unsigned gcKeepAtoms; size_t gcBytes; size_t gcMaxBytes; size_t gcMaxMallocBytes; @@ -304,7 +304,7 @@ struct JSRuntime : js::RuntimeFriendFields * in MaybeGC. */ volatile uint32_t gcNumArenasFreeCommitted; - js::FullGCMarker gcMarker; + js::GCMarker gcMarker; void *gcVerifyData; bool gcChunkAllocationSinceLastGC; int64_t gcNextFullGCTime; @@ -437,6 +437,7 @@ struct JSRuntime : js::RuntimeFriendFields JSGCCallback gcCallback; js::GCSliceCallback gcSliceCallback; + JSFinalizeCallback gcFinalizeCallback; private: /* diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 5f72ceed4b2..45451bc7ec7 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -73,7 +73,6 @@ JSCompartment::JSCompartment(JSRuntime *rt) : rt(rt), principals(NULL), needsBarrier_(false), - barrierMarker_(rt->gcMarker.sizeLimit()), gcBytes(0), gcTriggerBytes(0), gcLastBytes(0), @@ -128,9 +127,6 @@ JSCompartment::init(JSContext *cx) if (!scriptFilenameTable.init()) return false; - if (!barrierMarker_.init()) - return false; - return debuggees.init(); } diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index 76baa0b15fc..fc22037a23e 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -193,7 +193,6 @@ struct JSCompartment js::gc::ArenaLists arenas; bool needsBarrier_; - js::BarrierGCMarker barrierMarker_; bool needsBarrier() { return needsBarrier_; @@ -201,7 +200,7 @@ struct JSCompartment js::GCMarker *barrierTracer() { JS_ASSERT(needsBarrier_); - return &barrierMarker_; + return &rt->gcMarker; } size_t gcBytes; @@ -271,10 +270,10 @@ struct JSCompartment #ifdef DEBUG /* Property metering. */ - jsrefcount livePropTreeNodes; - jsrefcount totalPropTreeNodes; - jsrefcount propTreeKidsChunks; - jsrefcount liveDictModeNodes; + unsigned livePropTreeNodes; + unsigned totalPropTreeNodes; + unsigned propTreeKidsChunks; + unsigned liveDictModeNodes; #endif /* Set of all unowned base shapes in the compartment. */ diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp index 5a43d326cd2..2a244796a59 100644 --- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -746,7 +746,7 @@ Exception(JSContext *cx, unsigned argc, Value *vp) /* Set the 'message' property. */ JSString *message; - if (args.length() != 0 && !args[0].isUndefined()) { + if (args.hasDefined(0)) { message = ToString(cx, args[0]); if (!message) return false; diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index ad2dd2670f2..f7d1423bd01 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -468,17 +468,17 @@ struct DumpingChildInfo { {} }; -typedef HashSet, ContextAllocPolicy> PtrSet; +typedef HashSet, SystemAllocPolicy> PtrSet; struct JSDumpHeapTracer : public JSTracer { PtrSet visited; FILE *output; - Vector nodes; + Vector nodes; char buffer[200]; bool rootTracing; - JSDumpHeapTracer(JSContext *cx, FILE *fp) - : visited(cx), output(fp), nodes(cx) + JSDumpHeapTracer(FILE *fp) + : output(fp) {} }; @@ -530,10 +530,10 @@ DumpHeapVisitChild(JSTracer *trc, void **thingp, JSGCTraceKind kind) } void -js::DumpHeapComplete(JSContext *cx, FILE *fp) +js::DumpHeapComplete(JSRuntime *rt, FILE *fp) { - JSDumpHeapTracer dtrc(cx, fp); - JS_TracerInit(&dtrc, cx, DumpHeapPushIfNew); + JSDumpHeapTracer dtrc(fp); + JS_TracerInit(&dtrc, rt, DumpHeapPushIfNew); if (!dtrc.visited.init(10000)) return; diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 3df59b3d655..87eee7c7c5f 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -221,7 +221,7 @@ typedef bool * fp is the file for the dump output. */ extern JS_FRIEND_API(void) -DumpHeapComplete(JSContext *cx, FILE *fp); +DumpHeapComplete(JSRuntime *rt, FILE *fp); #endif @@ -519,15 +519,15 @@ IsObjectInContextCompartment(const JSObject *obj, const JSContext *cx); #define JSITER_FOR_OF 0x20 /* harmony for-of loop */ inline uintptr_t -GetContextStackLimit(const JSContext *cx) +GetNativeStackLimit(const JSRuntime *rt) { - return RuntimeFriendFields::get(GetRuntime(cx))->nativeStackLimit; + return RuntimeFriendFields::get(rt)->nativeStackLimit; } #define JS_CHECK_RECURSION(cx, onerror) \ JS_BEGIN_MACRO \ int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(js::GetContextStackLimit(cx), &stackDummy_)) { \ + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), &stackDummy_)) { \ js_ReportOverRecursed(cx); \ onerror; \ } \ diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 6730967ee92..ca91d8920df 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -70,11 +70,6 @@ * barriers. However, they must be marked in the first slice. Roots are things * like the C stack and the VM stack, since it would be too expensive to put * barriers on them. - * - * Write barriers are handled using the compartment's barrierMarker_ - * JSTracer. This includes a per-compartment stack of GC things that have been - * write-barriered. This stack is processed in each GC slice. The barrierMarker_ - * is also used during write barrier verification (VerifyBarriers below). */ #include @@ -1450,14 +1445,14 @@ namespace js { namespace gc { inline void -ArenaLists::prepareForIncrementalGC(JSCompartment *comp) +ArenaLists::prepareForIncrementalGC(JSRuntime *rt) { for (size_t i = 0; i != FINALIZE_LIMIT; ++i) { FreeSpan *headSpan = &freeLists[i]; if (!headSpan->isEmpty()) { ArenaHeader *aheader = headSpan->arenaHeader(); aheader->allocatedDuringIncremental = true; - comp->barrierMarker_.delayMarkingArena(aheader); + rt->gcMarker.delayMarkingArena(aheader); } } } @@ -1517,7 +1512,7 @@ ArenaLists::allocateFromArena(JSCompartment *comp, AllocKind thingKind) aheader->setAsFullyUsed(); if (JS_UNLIKELY(comp->needsBarrier())) { aheader->allocatedDuringIncremental = true; - comp->barrierMarker_.delayMarkingArena(aheader); + comp->rt->gcMarker.delayMarkingArena(aheader); } return freeLists[thingKind].infallibleAllocate(Arena::thingSize(thingKind)); } @@ -1546,7 +1541,7 @@ ArenaLists::allocateFromArena(JSCompartment *comp, AllocKind thingKind) if (JS_UNLIKELY(comp->needsBarrier())) { aheader->allocatedDuringIncremental = true; - comp->barrierMarker_.delayMarkingArena(aheader); + comp->rt->gcMarker.delayMarkingArena(aheader); } aheader->next = al->head; if (!al->head) { @@ -1823,10 +1818,9 @@ js_UnlockGCThingRT(JSRuntime *rt, void *thing) namespace js { void -InitTracer(JSTracer *trc, JSRuntime *rt, JSContext *cx, JSTraceCallback callback) +InitTracer(JSTracer *trc, JSRuntime *rt, JSTraceCallback callback) { trc->runtime = rt; - trc->context = cx; trc->callback = callback; trc->debugPrinter = NULL; trc->debugPrintArg = NULL; @@ -1875,8 +1869,8 @@ SliceBudget::checkOverBudget() return over; } -GCMarker::GCMarker(size_t sizeLimit) - : stack(sizeLimit), +GCMarker::GCMarker() + : stack(size_t(-1)), color(BLACK), started(false), unmarkedArenaStackTop(NULL), @@ -1886,17 +1880,15 @@ GCMarker::GCMarker(size_t sizeLimit) } bool -GCMarker::init(bool lazy) +GCMarker::init() { - if (!stack.init(lazy ? 0 : MARK_STACK_LENGTH)) - return false; - return true; + return stack.init(MARK_STACK_LENGTH); } void -GCMarker::start(JSRuntime *rt, JSContext *cx) +GCMarker::start(JSRuntime *rt) { - InitTracer(this, rt, cx, NULL); + InitTracer(this, rt, NULL); JS_ASSERT(!started); started = true; color = BLACK; @@ -1927,6 +1919,10 @@ GCMarker::stop() JS_ASSERT(grayRoots.empty()); grayFailed = false; + + /* Free non-ballast stack memory. */ + stack.reset(); + grayRoots.clearAndFree(); } void @@ -2130,8 +2126,6 @@ SetMarkStackLimit(JSRuntime *rt, size_t limit) { JS_ASSERT(!rt->gcRunning); rt->gcMarker.setSizeLimit(limit); - for (CompartmentsIter c(rt); !c.done(); c.next()) - c->barrierMarker_.setSizeLimit(limit); } } /* namespace js */ @@ -2162,8 +2156,7 @@ gc_root_traversal(JSTracer *trc, const RootEntry &entry) * that mark callbacks are not in place during compartment GCs. */ JSTracer checker; - JS_ASSERT(trc->runtime == trc->context->runtime); - JS_TracerInit(&checker, trc->context, EmptyMarkCallback); + JS_TracerInit(&checker, trc->runtime, EmptyMarkCallback); ConservativeGCTest test = MarkIfGCThingWord(&checker, reinterpret_cast(ptr)); if (test != CGCT_VALID && entry.value.name) { fprintf(stderr, @@ -3014,7 +3007,7 @@ MarkWeakReferences(GCMarker *gcmarker) static void MarkGrayAndWeak(JSRuntime *rt) { - FullGCMarker *gcmarker = &rt->gcMarker; + GCMarker *gcmarker = &rt->gcMarker; JS_ASSERT(gcmarker->isDrained()); MarkWeakReferences(gcmarker); @@ -3055,9 +3048,6 @@ EndMarkPhase(JSContext *cx) ValidateIncrementalMarking(cx); #endif - if (rt->gcCallback) - (void) rt->gcCallback(cx, JSGC_MARK_END); - #ifdef DEBUG /* Make sure that we didn't mark an object in another compartment */ if (rt->gcCurrentCompartment) { @@ -3079,7 +3069,7 @@ ValidateIncrementalMarking(JSContext *cx) return; JSRuntime *rt = cx->runtime; - FullGCMarker *gcmarker = &rt->gcMarker; + GCMarker *gcmarker = &rt->gcMarker; /* Save existing mark bits. */ for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) { @@ -3146,7 +3136,7 @@ ValidateIncrementalMarking(JSContext *cx) while (thing < end) { Cell *cell = (Cell *)thing; if (bitmap->isMarked(cell, BLACK) && !incBitmap.isMarked(cell, BLACK)) { - JS_DumpHeap(cx, stdout, NULL, JSGCTraceKind(0), NULL, 100000, NULL); + JS_DumpHeap(rt, stdout, NULL, JSGCTraceKind(0), NULL, 100000, NULL); printf("Assertion cell: %p (%d)\n", (void *)cell, cell->getAllocKind()); } JS_ASSERT_IF(bitmap->isMarked(cell, BLACK), incBitmap.isMarked(cell, BLACK)); @@ -3179,6 +3169,9 @@ SweepPhase(JSContext *cx, JSGCInvocationKind gckind) for (GCCompartmentsIter c(rt); !c.done(); c.next()) c->arenas.purge(); + if (rt->gcFinalizeCallback) + rt->gcFinalizeCallback(cx, JSFINALIZE_START); + /* * Sweep phase. * @@ -3274,8 +3267,8 @@ SweepPhase(JSContext *cx, JSGCInvocationKind gckind) { gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_XPCONNECT); - if (rt->gcCallback) - (void) rt->gcCallback(cx, JSGC_FINALIZE_END); + if (rt->gcFinalizeCallback) + rt->gcFinalizeCallback(cx, JSFINALIZE_END); } for (CompartmentsIter c(rt); !c.done(); c.next()) @@ -3290,7 +3283,7 @@ MarkAndSweep(JSContext *cx, JSGCInvocationKind gckind) AutoUnlockGC unlock(rt); - rt->gcMarker.start(rt, cx); + rt->gcMarker.start(rt); JS_ASSERT(!rt->gcMarker.callback); BeginMarkPhase(rt); @@ -3325,15 +3318,8 @@ class AutoHeapSession { /* ...while this class is to be used only for garbage collection. */ class AutoGCSession : AutoHeapSession { public: - explicit AutoGCSession(JSContext *cx, JSCompartment *comp); + explicit AutoGCSession(JSRuntime *rt, JSCompartment *comp); ~AutoGCSession(); - - private: - /* - * We should not be depending on cx->compartment in the GC, so set it to - * NULL to look for violations. - */ - SwitchToCompartment switcher; }; /* Start a new heap session. */ @@ -3351,9 +3337,8 @@ AutoHeapSession::~AutoHeapSession() runtime->gcRunning = false; } -AutoGCSession::AutoGCSession(JSContext *cx, JSCompartment *comp) - : AutoHeapSession(cx->runtime), - switcher(cx, (JSCompartment *)NULL) +AutoGCSession::AutoGCSession(JSRuntime *rt, JSCompartment *comp) + : AutoHeapSession(rt) { JS_ASSERT(!runtime->gcCurrentCompartment); runtime->gcCurrentCompartment = comp; @@ -3385,11 +3370,9 @@ ResetIncrementalGC(JSRuntime *rt, const char *reason) return; for (CompartmentsIter c(rt); !c.done(); c.next()) { - if (!rt->gcIncrementalCompartment || rt->gcIncrementalCompartment == c) { + if (!rt->gcIncrementalCompartment || rt->gcIncrementalCompartment == c) c->needsBarrier_ = false; - c->barrierMarker_.reset(); - c->barrierMarker_.stop(); - } + JS_ASSERT(!c->needsBarrier_); } @@ -3439,7 +3422,7 @@ AutoGCSlice::~AutoGCSlice() for (GCCompartmentsIter c(rt); !c.done(); c.next()) { if (rt->gcIncrementalState == MARK) { c->needsBarrier_ = true; - c->arenas.prepareForIncrementalGC(c); + c->arenas.prepareForIncrementalGC(rt); } else { JS_ASSERT(rt->gcIncrementalState == NO_INCREMENTAL); @@ -3482,13 +3465,11 @@ IncrementalGCSlice(JSContext *cx, int64_t budget, JSGCInvocationKind gckind) } if (rt->gcIncrementalState == MARK_ROOTS) { - rt->gcMarker.start(rt, cx); + rt->gcMarker.start(rt); JS_ASSERT(IS_GC_MARKING_TRACER(&rt->gcMarker)); - for (GCCompartmentsIter c(rt); !c.done(); c.next()) { + for (GCCompartmentsIter c(rt); !c.done(); c.next()) c->discardJitCode(cx); - c->barrierMarker_.start(rt, NULL); - } BeginMarkPhase(rt); @@ -3503,21 +3484,10 @@ IncrementalGCSlice(JSContext *cx, int64_t budget, JSGCInvocationKind gckind) if (!rt->gcMarker.hasBufferedGrayRoots()) sliceBudget.reset(); - rt->gcMarker.context = cx; bool finished = rt->gcMarker.drainMarkStack(sliceBudget); - for (GCCompartmentsIter c(rt); !c.done(); c.next()) { - c->barrierMarker_.context = cx; - finished &= c->barrierMarker_.drainMarkStack(sliceBudget); - c->barrierMarker_.context = NULL; - } - if (finished) { JS_ASSERT(rt->gcMarker.isDrained()); -#ifdef DEBUG - for (GCCompartmentsIter c(rt); !c.done(); c.next()) - JS_ASSERT(c->barrierMarker_.isDrained()); -#endif if (initialState == MARK && !rt->gcLastMarkSlice) rt->gcLastMarkSlice = true; else @@ -3532,8 +3502,6 @@ IncrementalGCSlice(JSContext *cx, int64_t budget, JSGCInvocationKind gckind) rt->gcMarker.stop(); /* JIT code was already discarded during sweeping. */ - for (GCCompartmentsIter c(rt); !c.done(); c.next()) - c->barrierMarker_.stop(); rt->gcIncrementalCompartment = NULL; @@ -3645,7 +3613,7 @@ GCCycle(JSContext *cx, JSCompartment *comp, int64_t budget, JSGCInvocationKind g if (rt->gcRunning) return; - AutoGCSession gcsession(cx, comp); + AutoGCSession gcsession(rt, comp); /* Don't GC if we are reporting an OOM. */ if (rt->inOOMReport) @@ -3728,10 +3696,8 @@ Collect(JSContext *cx, JSCompartment *comp, int64_t budget, * is the last context). Invoke the callback regardless. */ if (rt->gcIncrementalState == NO_INCREMENTAL) { - if (JSGCCallback callback = rt->gcCallback) { - if (!callback(cx, JSGC_BEGIN) && rt->hasContexts()) - return; - } + if (JSGCCallback callback = rt->gcCallback) + callback(rt, JSGC_BEGIN); } { @@ -3743,7 +3709,7 @@ Collect(JSContext *cx, JSCompartment *comp, int64_t budget, if (rt->gcIncrementalState == NO_INCREMENTAL) { if (JSGCCallback callback = rt->gcCallback) - (void) callback(cx, JSGC_END); + callback(rt, JSGC_END); } /* @@ -3954,17 +3920,9 @@ NewCompartment(JSContext *cx, JSPrincipals *principals) * it. Otherwise we might fail the mark the newly created * compartment fully. */ - if (rt->gcIncrementalState == MARK) { + if (rt->gcIncrementalState == MARK) rt->gcCompartmentCreated = true; - /* - * Start the tracer so that it's legal to stop() it when - * resetting the GC. - */ - if (!rt->gcIncrementalCompartment) - compartment->barrierMarker_.start(rt, NULL); - } - if (rt->compartments.append(compartment)) return compartment; } @@ -4110,7 +4068,7 @@ struct VerifyNode EdgeValue edges[1]; }; -typedef HashMap NodeMap; +typedef HashMap, SystemAllocPolicy> NodeMap; /* * The verifier data structures are simple. The entire graph is stored in a @@ -4139,7 +4097,7 @@ struct VerifyTracer : JSTracer { char *term; NodeMap nodemap; - VerifyTracer(JSContext *cx) : root(NULL), nodemap(cx) {} + VerifyTracer() : root(NULL) {} ~VerifyTracer() { js_free(root); } }; @@ -4230,13 +4188,13 @@ StartVerifyBarriers(JSContext *cx) PurgeRuntime(rt); - VerifyTracer *trc = new (js_malloc(sizeof(VerifyTracer))) VerifyTracer(cx); + VerifyTracer *trc = new (js_malloc(sizeof(VerifyTracer))) VerifyTracer; rt->gcNumber++; trc->number = rt->gcNumber; trc->count = 0; - JS_TracerInit(trc, cx, AccumulateEdge); + JS_TracerInit(trc, rt, AccumulateEdge); const size_t size = 64 * 1024 * 1024; trc->root = (VerifyNode *)js_malloc(size); @@ -4277,10 +4235,10 @@ StartVerifyBarriers(JSContext *cx) rt->gcVerifyData = trc; rt->gcIncrementalState = MARK; + rt->gcMarker.start(rt); for (CompartmentsIter c(rt); !c.done(); c.next()) { c->needsBarrier_ = true; - c->barrierMarker_.start(rt, NULL); - c->arenas.prepareForIncrementalGC(c); + c->arenas.prepareForIncrementalGC(rt); } return; @@ -4385,7 +4343,7 @@ EndVerifyBarriers(JSContext *cx) rt->gcVerifyData = NULL; rt->gcIncrementalState = NO_INCREMENTAL; - JS_TracerInit(trc, cx, MarkFromAutorooter); + JS_TracerInit(trc, rt, MarkFromAutorooter); AutoGCRooter::traceAll(trc); @@ -4394,10 +4352,10 @@ EndVerifyBarriers(JSContext *cx) * Verify that all the current roots were reachable previously, or else * are marked. */ - JS_TracerInit(trc, cx, CheckReachable); + JS_TracerInit(trc, rt, CheckReachable); MarkRuntime(trc, true); - JS_TracerInit(trc, cx, CheckEdge); + JS_TracerInit(trc, rt, CheckEdge); /* Start after the roots. */ VerifyNode *node = NextNode(trc->root); @@ -4416,10 +4374,8 @@ EndVerifyBarriers(JSContext *cx) } } - for (CompartmentsIter c(rt); !c.done(); c.next()) { - c->barrierMarker_.reset(); - c->barrierMarker_.stop(); - } + rt->gcMarker.reset(); + rt->gcMarker.stop(); trc->~VerifyTracer(); js_free(trc); diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 155cf1a570c..d696e33e203 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -1175,7 +1175,7 @@ struct ArenaLists { } } - inline void prepareForIncrementalGC(JSCompartment *comp); + inline void prepareForIncrementalGC(JSRuntime *rt); /* * Temporarily copy the free list heads to the arenas so the code can see @@ -1410,7 +1410,7 @@ GCDebugSlice(JSContext *cx, int64_t objCount); namespace js { void -InitTracer(JSTracer *trc, JSRuntime *rt, JSContext *cx, JSTraceCallback callback); +InitTracer(JSTracer *trc, JSRuntime *rt, JSTraceCallback callback); #ifdef JS_THREADSAFE @@ -1766,13 +1766,13 @@ struct GCMarker : public JSTracer { } public: - explicit GCMarker(size_t sizeLimit); - bool init(bool lazy); + explicit GCMarker(); + bool init(); void setSizeLimit(size_t size) { stack.setSizeLimit(size); } size_t sizeLimit() const { return stack.sizeLimit; } - void start(JSRuntime *rt, JSContext *cx); + void start(JSRuntime *rt); void stop(); void reset(); @@ -1910,22 +1910,6 @@ struct GCMarker : public JSTracer { Vector grayRoots; }; -struct BarrierGCMarker : public GCMarker { - BarrierGCMarker(size_t sizeLimit) : GCMarker(sizeLimit) {} - - bool init() { - return GCMarker::init(true); - } -}; - -struct FullGCMarker : public GCMarker { - FullGCMarker() : GCMarker(size_t(-1)) {} - - bool init() { - return GCMarker::init(false); - } -}; - void SetMarkStackLimit(JSRuntime *rt, size_t limit); diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index 7e67fae0abe..34f26faf53c 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -477,7 +477,7 @@ GetCustomIterator(JSContext *cx, JSObject *obj, unsigned flags, Value *vp) return false; if (vp->isPrimitive()) { /* - * We are always coming from js_ValueToIterator, and we are no longer on + * 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; @@ -1157,45 +1157,8 @@ ElementIteratorObject::iteratorNext(JSContext *cx, Value *vp) } JS_ASSERT(i + 1 > i); - - /* Simple fast path for dense arrays. */ - if (obj->isDenseArray()) { - *vp = obj->getDenseArrayElement(i); - if (vp->isMagic(JS_ARRAY_HOLE)) - vp->setUndefined(); - } else { - /* Make a jsid for this index. */ - jsid id; - if (i < uint32_t(INT32_MAX) && INT_FITS_IN_JSID(i)) { - id = INT_TO_JSID(i); - } else { - Value v = DoubleValue(i); - if (!js_ValueToStringId(cx, v, &id)) - goto error; - } - - /* Find out if this object has an element i. */ - bool has; - if (obj->isProxy()) { - /* js_HasOwnProperty does not work on proxies. */ - if (!Proxy::hasOwn(cx, obj, id, &has)) - goto error; - } else { - JSObject *obj2; - JSProperty *prop; - if (!js_HasOwnProperty(cx, obj->getOps()->lookupGeneric, obj, id, &obj2, &prop)) - goto error; - has = !!prop; - } - - /* Populate *vp. */ - if (has) { - if (!obj->getElement(cx, obj, i, vp)) - goto error; - } else { - vp->setUndefined(); - } - } + if (!obj->getElement(cx, obj, i, vp)) + goto error; /* On success, bump the index. */ setIndex(i + 1); @@ -1684,7 +1647,7 @@ generator_op(JSContext *cx, Native native, JSGeneratorOp op, Value *vp, unsigned break; case JSGENOP_SEND: - if (args.length() >= 1 && !args[0].isUndefined()) { + if (args.hasDefined(0)) { js_ReportValueError(cx, JSMSG_BAD_GENERATOR_SEND, JSDVG_SEARCH_STACK, args[0], NULL); return false; diff --git a/js/src/jsiter.h b/js/src/jsiter.h index 9634b27c661..92104f785ff 100644 --- a/js/src/jsiter.h +++ b/js/src/jsiter.h @@ -183,7 +183,7 @@ EnumeratedIdVectorToIterator(JSContext *cx, JSObject *obj, unsigned flags, js::A /* * Convert the value stored in *vp to its iteration object. The flags should - * contain JSITER_ENUMERATE if js_ValueToIterator is called when enumerating + * contain JSITER_ENUMERATE if js::ValueToIterator is called when enumerating * for-in semantics are required, and when the caller can guarantee that the * iterator will never be exposed to scripts. */ @@ -221,6 +221,71 @@ js_IteratorNext(JSContext *cx, JSObject *iterobj, js::Value *rval); extern JSBool js_ThrowStopIteration(JSContext *cx); +namespace js { + +/* + * Get the next value from an iterator object. + * + * On success, store the next value in *vp and return true; if there are no + * more values, store the magic value JS_NO_ITER_VALUE in *vp and return true. + */ +inline bool +Next(JSContext *cx, JSObject *iter, Value *vp) +{ + if (!js_IteratorMore(cx, iter, vp)) + return false; + if (vp->toBoolean()) + return js_IteratorNext(cx, iter, vp); + vp->setMagic(JS_NO_ITER_VALUE); + return true; +} + +/* + * Imitate a for-of loop. This does the equivalent of the JS code: + * + * for (let v of iterable) + * op(v); + * + * But the actual signature of op must be: + * bool op(JSContext *cx, const Value &v); + * + * There is no feature like JS 'break'. op must return false only + * in case of exception or error. + */ +template +bool +ForOf(JSContext *cx, const Value &iterable, Op op) +{ + Value iterv(iterable); + if (!ValueToIterator(cx, JSITER_FOR_OF, &iterv)) + return false; + JSObject *iter = &iterv.toObject(); + + bool ok = true; + while (ok) { + Value v; + ok = Next(cx, iter, &v); + if (ok) { + if (v.isMagic(JS_NO_ITER_VALUE)) + break; + ok = op(cx, v); + } + } + + bool throwing = !ok && cx->isExceptionPending(); + Value exc; + if (throwing) { + exc = cx->getPendingException(); + cx->clearPendingException(); + } + bool closedOK = CloseIterator(cx, iter); + if (throwing && closedOK) + cx->setPendingException(exc); + return ok && closedOK; +} + +} /* namespace js */ + #if JS_HAS_GENERATORS /* diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index 51f4d4a69c4..e9d64733011 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -623,7 +623,7 @@ num_toStringHelper(JSContext *cx, Native native, unsigned argc, Value *vp) return ok; int32_t base = 10; - if (args.length() != 0 && !args[0].isUndefined()) { + if (args.hasDefined(0)) { double d2; if (!ToInteger(cx, args[0], &d2)) return false; @@ -850,10 +850,11 @@ num_toExponential(JSContext *cx, unsigned argc, Value *vp) static JSBool num_toPrecision(JSContext *cx, unsigned argc, Value *vp) { - if (argc == 0 || vp[2].isUndefined()) + CallArgs args = CallArgsFromVp(argc, vp); + if (!args.hasDefined(0)) return num_toStringHelper(cx, num_toPrecision, 0, vp); return num_to(cx, num_toPrecision, DTOSTR_STANDARD, DTOSTR_PRECISION, 1, MAX_PRECISION, 0, - CallArgsFromVp(argc, vp)); + args); } static JSFunctionSpec number_methods[] = { diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 5914df0ad6d..dd4ac258b53 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1188,16 +1188,16 @@ obj_watch(JSContext *cx, unsigned argc, Value *vp) { if (argc <= 1) { js_ReportMissingArg(cx, *vp, 1); - return JS_FALSE; + return false; } JSObject *callable = js_ValueToCallableObject(cx, &vp[3], 0); if (!callable) - return JS_FALSE; + return false; jsid propid; if (!ValueToId(cx, vp[2], &propid)) - return JS_FALSE; + return false; JSObject *obj = ToObject(cx, &vp[1]); if (!obj) @@ -1206,14 +1206,12 @@ obj_watch(JSContext *cx, unsigned argc, Value *vp) Value tmp; unsigned attrs; if (!CheckAccess(cx, obj, propid, JSACC_WATCH, &tmp, &attrs)) - return JS_FALSE; + return false; vp->setUndefined(); - if (attrs & JSPROP_READONLY) - return JS_TRUE; if (obj->isDenseArray() && !obj->makeDenseArraySlow(cx)) - return JS_FALSE; + return false; return JS_SetWatchPoint(cx, obj, propid, obj_watch_handler, callable); } @@ -1227,7 +1225,7 @@ obj_unwatch(JSContext *cx, unsigned argc, Value *vp) jsid id; if (argc != 0) { if (!ValueToId(cx, vp[2], &id)) - return JS_FALSE; + return false; } else { id = JSID_VOID; } @@ -2366,18 +2364,19 @@ obj_create(JSContext *cx, unsigned argc, Value *vp) if (argc == 0) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED, "Object.create", "0", "s"); - return JS_FALSE; + return false; } - const Value &v = vp[2]; + CallArgs args = CallArgsFromVp(argc, vp); + const Value &v = args[0]; if (!v.isObjectOrNull()) { char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL); if (!bytes) - return JS_FALSE; + return false; JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE, bytes, "not an object or null"); JS_free(cx, bytes); - return JS_FALSE; + return false; } JSObject *proto = v.toObjectOrNull(); @@ -2390,27 +2389,27 @@ obj_create(JSContext *cx, unsigned argc, Value *vp) * Use the callee's global as the parent of the new object to avoid dynamic * scoping (i.e., using the caller's global). */ - JSObject *obj = NewObjectWithGivenProto(cx, &ObjectClass, proto, &vp->toObject().global()); + JSObject *obj = NewObjectWithGivenProto(cx, &ObjectClass, proto, &args.callee().global()); if (!obj) - return JS_FALSE; - vp->setObject(*obj); /* Root and prepare for eventual return. */ + return false; /* Don't track types or array-ness for objects created here. */ MarkTypeObjectUnknownProperties(cx, obj->type()); /* 15.2.3.5 step 4. */ - if (argc > 1 && !vp[3].isUndefined()) { - if (vp[3].isPrimitive()) { + if (args.hasDefined(1)) { + if (args[1].isPrimitive()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_NONNULL_OBJECT); - return JS_FALSE; + return false; } - if (!DefineProperties(cx, obj, &vp[3].toObject())) - return JS_FALSE; + if (!DefineProperties(cx, obj, &args[1].toObject())) + return false; } /* 5. Return obj. */ - return JS_TRUE; + args.rval().setObject(*obj); + return true; } static JSBool diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index edf17f324f9..e8a14d574f0 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -1251,18 +1251,14 @@ proxy_TraceObject(JSTracer *trc, JSObject *obj) MarkCrossCompartmentSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "private"); MarkCrossCompartmentSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 0), "extra0"); MarkCrossCompartmentSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 1), "extra1"); - if (IsFunctionProxy(obj)) { - MarkCrossCompartmentSlot(trc, &GetCall(obj), "call"); - MarkCrossCompartmentSlot(trc, &GetFunctionProxyConstruct(obj), "construct"); - } } static void proxy_TraceFunction(JSTracer *trc, JSObject *obj) { - proxy_TraceObject(trc, obj); MarkCrossCompartmentSlot(trc, &GetCall(obj), "call"); MarkCrossCompartmentSlot(trc, &GetFunctionProxyConstruct(obj), "construct"); + proxy_TraceObject(trc, obj); } static JSBool diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index 1731a805280..d2d5d7ddc8d 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -96,7 +96,6 @@ JS_BEGIN_EXTERN_C /* Scalar typedefs. */ typedef int32_t jsint; typedef uint32_t jsuint; -typedef int32_t jsrefcount; /* PRInt32 if JS_THREADSAFE, see jslock.h */ #ifdef WIN32 typedef wchar_t jschar; diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp index 66ce40757a8..bf06fb1e644 100644 --- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -639,11 +639,15 @@ NodeBuilder::newNode(ASTType type, TokenPos *pos, JSObject **dst) bool NodeBuilder::newArray(NodeVector &elts, Value *dst) { - JSObject *array = NewDenseEmptyArray(cx); + const size_t len = elts.length(); + if (len > UINT32_MAX) { + js_ReportAllocationOverflow(cx); + return false; + } + JSObject *array = NewDenseAllocatedArray(cx, uint32_t(len)); if (!array) return false; - const size_t len = elts.length(); for (size_t i = 0; i < len; i++) { Value val = elts[i]; diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 418bbc92d46..2e0878895aa 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -597,7 +597,7 @@ str_substring(JSContext *cx, unsigned argc, Value *vp) else if (begin > length) begin = length; - if (args.length() > 1 && !args[1].isUndefined()) { + if (args.hasDefined(1)) { if (!ValueToIntegerRange(cx, args[1], &end)) return false; @@ -1429,7 +1429,7 @@ class StringRegExpGuard if (!RegExpToShared(cx, args[0].toObject(), &re_)) return false; } else { - if (convertVoid && (args.length() == 0 || args[0].isUndefined())) { + if (convertVoid && !args.hasDefined(0)) { fm.patstr = cx->runtime->emptyString; return true; } @@ -2555,7 +2555,7 @@ js::str_split(JSContext *cx, unsigned argc, Value *vp) /* Step 5: Use the second argument as the split limit, if given. */ uint32_t limit; - if (args.length() > 1 && !args[1].isUndefined()) { + if (args.hasDefined(1)) { double d; if (!ToNumber(cx, args[1], &d)) return false; @@ -2567,8 +2567,8 @@ js::str_split(JSContext *cx, unsigned argc, Value *vp) /* Step 8. */ RegExpGuard re; JSLinearString *sepstr = NULL; - bool sepUndefined = (args.length() == 0 || args[0].isUndefined()); - if (!sepUndefined) { + bool sepDefined = args.hasDefined(0); + if (sepDefined) { if (IsObjectWithClass(args[0], ESClass_RegExp, cx)) { if (!RegExpToShared(cx, args[0].toObject(), &re)) return false; @@ -2590,7 +2590,7 @@ js::str_split(JSContext *cx, unsigned argc, Value *vp) } /* Step 10. */ - if (sepUndefined) { + if (!sepDefined) { Value v = StringValue(str); JSObject *aobj = NewDenseCopiedArray(cx, 1, &v); if (!aobj) @@ -2643,9 +2643,7 @@ str_substr(JSContext *cx, unsigned argc, Value *vp) begin = 0; } - if (args.length() == 1 || args[1].isUndefined()) { - len = length - begin; - } else { + if (args.hasDefined(1)) { if (!ValueToIntegerRange(cx, args[1], &len)) return false; @@ -2656,6 +2654,8 @@ str_substr(JSContext *cx, unsigned argc, Value *vp) if (uint32_t(length) < uint32_t(begin + len)) len = length - begin; + } else { + len = length - begin; } str = js_NewDependentString(cx, str, size_t(begin), size_t(len)); @@ -2739,9 +2739,7 @@ str_slice(JSContext *cx, unsigned argc, Value *vp) begin = length; } - if (args.length() == 1 || args[1].isUndefined()) { - end = length; - } else { + if (args.hasDefined(1)) { if (!ToInteger(cx, args[1], &end)) return false; if (end < 0) { @@ -2753,6 +2751,8 @@ str_slice(JSContext *cx, unsigned argc, Value *vp) } if (end < begin) end = begin; + } else { + end = length; } str = js_NewDependentString(cx, str, diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index bd6e6bfd03c..1de2ec70ba5 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -1474,7 +1474,7 @@ struct JSCountHeapNode { typedef struct JSCountHeapTracer { JSTracer base; JSDHashTable visited; - JSBool ok; + bool ok; JSCountHeapNode *traceList; JSCountHeapNode *recycleList; } JSCountHeapTracer; @@ -1495,8 +1495,7 @@ CountHeapNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind) entry = (JSDHashEntryStub *) JS_DHashTableOperate(&countTracer->visited, thing, JS_DHASH_ADD); if (!entry) { - JS_ReportOutOfMemory(trc->context); - countTracer->ok = JS_FALSE; + countTracer->ok = false; return; } if (entry->key) @@ -1509,7 +1508,7 @@ CountHeapNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind) } else { node = (JSCountHeapNode *) js_malloc(sizeof *node); if (!node) { - countTracer->ok = JS_FALSE; + countTracer->ok = false; return; } } @@ -1580,14 +1579,14 @@ CountHeap(JSContext *cx, unsigned argc, jsval *vp) } } - JS_TracerInit(&countTracer.base, cx, CountHeapNotify); + JS_TracerInit(&countTracer.base, JS_GetRuntime(cx), CountHeapNotify); if (!JS_DHashTableInit(&countTracer.visited, JS_DHashGetStubOps(), NULL, sizeof(JSDHashEntryStub), JS_DHASH_DEFAULT_CAPACITY(100))) { JS_ReportOutOfMemory(cx); return JS_FALSE; } - countTracer.ok = JS_TRUE; + countTracer.ok = true; countTracer.traceList = NULL; countTracer.recycleList = NULL; @@ -1612,11 +1611,15 @@ CountHeap(JSContext *cx, unsigned argc, jsval *vp) js_free(node); } JS_DHashTableFinish(&countTracer.visited); + if (!countTracer.ok) { + JS_ReportOutOfMemory(cx); + return false; + } - return countTracer.ok && JS_NewNumberValue(cx, (double) counter, vp); + return JS_NewNumberValue(cx, (double) counter, vp); } -static jsrefcount finalizeCount = 0; +static unsigned finalizeCount = 0; static void finalize_counter_finalize(JSContext *cx, JSObject *obj) @@ -2533,12 +2536,16 @@ DumpHeap(JSContext *cx, unsigned argc, jsval *vp) } } - ok = JS_DumpHeap(cx, dumpFile, startThing, startTraceKind, thingToFind, + ok = JS_DumpHeap(JS_GetRuntime(cx), dumpFile, startThing, startTraceKind, thingToFind, maxDepth, thingToIgnore); if (dumpFile != stdout) fclose(dumpFile); + if (!ok) { + JS_ReportOutOfMemory(cx); + return false; + } JS_SET_RVAL(cx, vp, JSVAL_VOID); - return ok; + return true; not_traceable_arg: JS_ReportError(cx, "argument '%s' is not null or a heap-allocated thing", diff --git a/js/src/shell/jsheaptools.cpp b/js/src/shell/jsheaptools.cpp index 52bb084a5df..03cc6a56c36 100644 --- a/js/src/shell/jsheaptools.cpp +++ b/js/src/shell/jsheaptools.cpp @@ -133,7 +133,7 @@ class HeapReverser : public JSTracer { struct Edge { public: Edge(char *name, void *origin) : name(name), origin(origin) { } - ~Edge() { free(name); } + ~Edge() { js_free(name); } /* * Move constructor and move assignment. These allow us to live in @@ -166,12 +166,12 @@ class HeapReverser : public JSTracer { * The result of a reversal is a map from Cells' addresses to Node * structures describing their incoming edges. */ - typedef HashMap Map; + typedef HashMap, SystemAllocPolicy> Map; Map map; /* Construct a HeapReverser for |context|'s heap. */ - HeapReverser(JSContext *cx) : map(cx), roots(cx), rooter(cx, 0, NULL), work(cx), parent(NULL) { - JS_TracerInit(this, cx, traverseEdgeWithThis); + HeapReverser(JSContext *cx) : rooter(cx, 0, NULL), parent(NULL) { + JS_TracerInit(this, JS_GetRuntime(cx), traverseEdgeWithThis); } bool init() { return map.init(); } @@ -193,7 +193,7 @@ class HeapReverser : public JSTracer { * rule. This is kind of dumb, but JSAPI doesn't provide any less restricted * way to register arrays of roots. */ - Vector roots; + Vector roots; AutoArrayRooter rooter; /* @@ -232,7 +232,7 @@ class HeapReverser : public JSTracer { * A stack of work items. We represent the stack explicitly to avoid * overflowing the C++ stack when traversing long chains of objects. */ - Vector work; + Vector work; /* When traverseEdge is called, the Cell and kind at which the edge originated. */ void *parent; @@ -323,7 +323,7 @@ HeapReverser::getEdgeDescription() { if (!debugPrinter && debugPrintIndex == (size_t) -1) { const char *arg = static_cast(debugPrintArg); - char *name = static_cast(context->malloc_(strlen(arg) + 1)); + char *name = static_cast(js_malloc(strlen(arg) + 1)); if (!name) return NULL; strcpy(name, arg); @@ -332,7 +332,7 @@ HeapReverser::getEdgeDescription() /* Lovely; but a fixed size is required by JSTraceNamePrinter. */ static const int nameSize = 200; - char *name = static_cast(context->malloc_(nameSize)); + char *name = static_cast(js_malloc(nameSize)); if (!name) return NULL; if (debugPrinter) @@ -342,7 +342,7 @@ HeapReverser::getEdgeDescription() static_cast(debugPrintArg), debugPrintIndex); /* Shrink storage to fit. */ - return static_cast(context->realloc_(name, strlen(name) + 1)); + return static_cast(js_realloc(name, strlen(name) + 1)); } diff --git a/js/src/tests/js1_8_5/extensions/jstests.list b/js/src/tests/js1_8_5/extensions/jstests.list index 5eada86a356..67b23a0a997 100644 --- a/js/src/tests/js1_8_5/extensions/jstests.list +++ b/js/src/tests/js1_8_5/extensions/jstests.list @@ -34,6 +34,8 @@ script findReferences-01.js script findReferences-02.js script findReferences-03.js script findReferences-04.js +script regress-604781-1.js +script regress-604781-2.js script regress-627859.js script regress-627984-1.js script regress-627984-2.js diff --git a/js/src/tests/js1_8_5/extensions/reflect-parse.js b/js/src/tests/js1_8_5/extensions/reflect-parse.js index 8406708b702..fef2b352ac1 100644 --- a/js/src/tests/js1_8_5/extensions/reflect-parse.js +++ b/js/src/tests/js1_8_5/extensions/reflect-parse.js @@ -312,10 +312,10 @@ assertExpr("[1,,,2,,,3]", arrExpr([lit(1),,,lit(2),,,lit(3)])); assertExpr("[,1,2,3]", arrExpr([,lit(1),lit(2),lit(3)])); assertExpr("[,,1,2,3]", arrExpr([,,lit(1),lit(2),lit(3)])); assertExpr("[,,,1,2,3]", arrExpr([,,,lit(1),lit(2),lit(3)])); -assertExpr("[,,,1,2,3,]", arrExpr([,,,lit(1),lit(2),lit(3)])); -assertExpr("[,,,1,2,3,,]", arrExpr([,,,lit(1),lit(2),lit(3),])); -assertExpr("[,,,1,2,3,,,]", arrExpr([,,,lit(1),lit(2),lit(3),,])); -assertExpr("[,,,,,]", arrExpr([,,,,])); +assertExpr("[,,,1,2,3,]", arrExpr([,,,lit(1),lit(2),lit(3),])); +assertExpr("[,,,1,2,3,,]", arrExpr([,,,lit(1),lit(2),lit(3),,])); +assertExpr("[,,,1,2,3,,,]", arrExpr([,,,lit(1),lit(2),lit(3),,,])); +assertExpr("[,,,,,]", arrExpr([,,,,,])); assertExpr("({})", objExpr([])); assertExpr("({x:1})", objExpr([{ key: ident("x"), value: lit(1) }])); assertExpr("({x:1, y:2})", objExpr([{ key: ident("x"), value: lit(1) }, @@ -436,9 +436,10 @@ assertStmt("function f() { function g() { } function g() { } }", funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])), funDecl(ident("g"), [], blockStmt([]))]))); -assertStmt("function f() { function g() { } function g() { return 42 } }", - funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])), - funDecl(ident("g"), [], blockStmt([returnStmt(lit(42))]))]))); +// Fails due to parser quirks (bug 638577) +//assertStmt("function f() { function g() { } function g() { return 42 } }", +// funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])), +// funDecl(ident("g"), [], blockStmt([returnStmt(lit(42))]))]))); assertStmt("function f() { var x = 42; var x = 43; }", funDecl(ident("f"), [], blockStmt([varDecl([{ id: ident("x"), init: lit(42) }]), diff --git a/js/src/tests/js1_8_5/extensions/regress-604781-1.js b/js/src/tests/js1_8_5/extensions/regress-604781-1.js new file mode 100644 index 00000000000..a7c43f95d22 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-604781-1.js @@ -0,0 +1,24 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var watcherCount, setterCount; +function watcher(id, oldval, newval) { watcherCount++; return newval; } +function setter(newval) { setterCount++; } + +var p = { set x(v) { setter(v); } }; +p.watch('x', watcher); + +watcherCount = setterCount = 0; +p.x = 2; +assertEq(setterCount, 1); +assertEq(watcherCount, 1); + +var o = Object.defineProperty({}, 'x', { set:setter, enumerable:true, configurable:true }); +o.watch('x', watcher); + +watcherCount = setterCount = 0; +o.x = 2; +assertEq(setterCount, 1); +assertEq(watcherCount, 1); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-604781-2.js b/js/src/tests/js1_8_5/extensions/regress-604781-2.js new file mode 100644 index 00000000000..7aba4a274d7 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-604781-2.js @@ -0,0 +1,13 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var log; +function watcher(id, old, newval) { log += 'watcher'; return newval; } +var o = { set x(v) { log += 'setter'; } }; +o.watch('x', watcher); +Object.defineProperty(o, 'x', {value: 3, writable: true}); +log = ''; +o.x = 3; +assertEq(log, 'watcher'); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/shell.js b/js/src/tests/js1_8_5/extensions/shell.js index dce4b7cba7f..e4b4493486f 100644 --- a/js/src/tests/js1_8_5/extensions/shell.js +++ b/js/src/tests/js1_8_5/extensions/shell.js @@ -139,6 +139,9 @@ var Match = throw new MatchError("expected array-like object, got " + quote(act)); var length = exp.length; + if (act.length !== exp.length) + throw new MatchError("expected array-like object of length " + length + ", got " + quote(act)); + for (var i = 0; i < length; i++) { if (i in exp) { if (!(i in act)) diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 2d593ad8422..d22f88d420a 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -736,7 +736,7 @@ ContextStack::pushInvokeArgs(JSContext *cx, unsigned argc, InvokeArgsGuard *iag) if (!firstUnused) return false; - MakeRangeGCSafe(firstUnused, argc); + MakeRangeGCSafe(firstUnused, nvars); ImplicitCast(*iag) = CallArgsFromVp(argc, firstUnused); diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index ccc1eb6de4c..2da836275d4 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -251,6 +251,7 @@ class CallArgs : public CallReceiver Value *array() const { return argv_; } unsigned length() const { return argc_; } Value *end() const { return argv_ + argc_; } + bool hasDefined(unsigned i) const { return i < argc_ && !argv_[i].isUndefined(); } }; JS_ALWAYS_INLINE CallArgs diff --git a/js/xpconnect/shell/xpcshell.cpp b/js/xpconnect/shell/xpcshell.cpp index 663106daa58..0e8f98bccad 100644 --- a/js/xpconnect/shell/xpcshell.cpp +++ b/js/xpconnect/shell/xpcshell.cpp @@ -644,10 +644,12 @@ DumpHeap(JSContext *cx, unsigned argc, jsval *vp) } } - ok = JS_DumpHeap(cx, dumpFile, startThing, startTraceKind, thingToFind, + ok = JS_DumpHeap(JS_GetRuntime(cx), dumpFile, startThing, startTraceKind, thingToFind, maxDepth, thingToIgnore); if (dumpFile != gOutFile) fclose(dumpFile); + if (!ok) + JS_ReportOutOfMemory(cx); return ok; not_traceable_arg: diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 076274b8489..fc711aa6629 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -654,30 +654,56 @@ SweepCompartment(nsCStringHashKey& aKey, JSCompartment *compartment, void *aClos return PL_DHASH_NEXT; } -// static -JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status) +/* static */ void +XPCJSRuntime::GCCallback(JSRuntime *rt, JSGCStatus status) { XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance(); if (!self) - return true; + return; switch (status) { case JSGC_BEGIN: { - if (!NS_IsMainThread()) { - return false; - } - // We seem to sometime lose the unrooted global flag. Restore it // here. FIXME: bug 584495. JSContext *iter = nsnull; - while (JSContext *acx = JS_ContextIterator(JS_GetRuntime(cx), &iter)) { + while (JSContext *acx = JS_ContextIterator(rt, &iter)) { if (!js::HasUnrootedGlobal(acx)) JS_ToggleOptions(acx, JSOPTION_UNROOTED_GLOBAL); } break; } - case JSGC_MARK_END: + case JSGC_END: + { + // Do any deferred releases of native objects. +#ifdef XPC_TRACK_DEFERRED_RELEASES + printf("XPC - Begin deferred Release of %d nsISupports pointers\n", + self->mNativesToReleaseArray.Length()); +#endif + DoDeferredRelease(self->mNativesToReleaseArray); +#ifdef XPC_TRACK_DEFERRED_RELEASES + printf("XPC - End deferred Releases\n"); +#endif + + self->GetXPConnect()->ClearGCBeforeCC(); + break; + } + } + + nsTArray callbacks(self->extraGCCallbacks); + for (PRUint32 i = 0; i < callbacks.Length(); ++i) + callbacks[i](rt, status); +} + +/* static */ void +XPCJSRuntime::FinalizeCallback(JSContext *cx, JSFinalizeStatus status) +{ + XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance(); + if (!self) + return; + + switch (status) { + case JSFINALIZE_START: { NS_ASSERTION(!self->mDoingFinalization, "bad state"); @@ -710,7 +736,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status) self->mDoingFinalization = true; break; } - case JSGC_FINALIZE_END: + case JSFINALIZE_END: { NS_ASSERTION(self->mDoingFinalization, "bad state"); self->mDoingFinalization = false; @@ -897,36 +923,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status) break; } - case JSGC_END: - { - // NOTE that this event happens outside of the gc lock in - // the js engine. So this could be simultaneous with the - // events above. - - // Do any deferred releases of native objects. -#ifdef XPC_TRACK_DEFERRED_RELEASES - printf("XPC - Begin deferred Release of %d nsISupports pointers\n", - self->mNativesToReleaseArray.Length()); -#endif - DoDeferredRelease(self->mNativesToReleaseArray); -#ifdef XPC_TRACK_DEFERRED_RELEASES - printf("XPC - End deferred Releases\n"); -#endif - - self->GetXPConnect()->ClearGCBeforeCC(); - break; - } - default: - break; } - - nsTArray callbacks(self->extraGCCallbacks); - for (PRUint32 i = 0; i < callbacks.Length(); ++i) { - if (!callbacks[i](cx, status)) - return false; - } - - return true; } //static @@ -2067,7 +2064,8 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect) JS_SetNativeStackQuota(mJSRuntime, 128 * sizeof(size_t) * 1024); JS_SetContextCallback(mJSRuntime, ContextCallback); JS_SetCompartmentCallback(mJSRuntime, CompartmentCallback); - JS_SetGCCallbackRT(mJSRuntime, GCCallback); + JS_SetGCCallback(mJSRuntime, GCCallback); + JS_SetFinalizeCallback(mJSRuntime, FinalizeCallback); JS_SetExtraGCRootsTracer(mJSRuntime, TraceBlackJS, this); JS_SetGrayGCRootsTracer(mJSRuntime, TraceGrayJS, this); JS_SetWrapObjectCallbacks(mJSRuntime, diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index f7044586fb2..82fff2e41af 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -228,21 +228,17 @@ nsXPConnect::ReleaseXPConnectSingleton() // force a dump of the JavaScript gc heap if JS is still alive // if requested through XPC_SHUTDOWN_HEAP_DUMP environment variable { - // autoscope - XPCCallContext ccx(NATIVE_CALLER); - if (ccx.IsValid()) { - const char* dumpName = getenv("XPC_SHUTDOWN_HEAP_DUMP"); - if (dumpName) { - FILE* dumpFile = (*dumpName == '\0' || - strcmp(dumpName, "stdout") == 0) - ? stdout - : fopen(dumpName, "w"); - if (dumpFile) { - JS_DumpHeap(ccx, dumpFile, nsnull, JSTRACE_OBJECT, nsnull, - static_cast(-1), nsnull); - if (dumpFile != stdout) - fclose(dumpFile); - } + const char* dumpName = getenv("XPC_SHUTDOWN_HEAP_DUMP"); + if (dumpName) { + FILE* dumpFile = (*dumpName == '\0' || + strcmp(dumpName, "stdout") == 0) + ? stdout + : fopen(dumpName, "w"); + if (dumpFile) { + JS_DumpHeap(xpc->GetRuntime()->GetJSRuntime(), dumpFile, nsnull, + JSTRACE_OBJECT, nsnull, static_cast(-1), nsnull); + if (dumpFile != stdout) + fclose(dumpFile); } } } @@ -499,11 +495,11 @@ TraceWeakMappingChild(JSTracer *trc, void **thingp, JSGCTraceKind kind) struct NoteWeakMapsTracer : public js::WeakMapTracer { - NoteWeakMapsTracer(JSContext *cx, js::WeakMapTraceCallback cb, + NoteWeakMapsTracer(JSRuntime *rt, js::WeakMapTraceCallback cb, nsCycleCollectionTraversalCallback &cccb) - : js::WeakMapTracer(js::GetRuntime(cx), cb), mCb(cccb), mChildTracer(cccb) + : js::WeakMapTracer(rt, cb), mCb(cccb), mChildTracer(cccb) { - JS_TracerInit(&mChildTracer, cx, TraceWeakMappingChild); + JS_TracerInit(&mChildTracer, rt, TraceWeakMappingChild); } nsCycleCollectionTraversalCallback &mCb; NoteWeakMapChildrenTracer mChildTracer; @@ -598,8 +594,7 @@ nsXPConnect::BeginCycleCollection(nsCycleCollectionTraversalCallback &cb, GetRuntime()->AddXPConnectRoots(cb); - NoteWeakMapsTracer trc(mCycleCollectionContext->GetJSContext(), - TraceWeakMapping, cb); + NoteWeakMapsTracer trc(GetRuntime()->GetJSRuntime(), TraceWeakMapping, cb); js::TraceWeakMaps(&trc); return NS_OK; @@ -724,7 +719,7 @@ UnmarkGrayChildren(JSTracer *trc, void **thingp, JSGCTraceKind kind) { void *thing = *thingp; int stackDummy; - if (!JS_CHECK_STACK_SIZE(js::GetContextStackLimit(trc->context), &stackDummy)) { + if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(trc->runtime), &stackDummy)) { /* * If we run out of stack, we take a more drastic measure: require that * we GC again before the next CC. @@ -753,17 +748,9 @@ xpc_UnmarkGrayObjectRecursive(JSObject *obj) // Unmark. js::gc::AsCell(obj)->unmark(js::gc::GRAY); - // Tracing requires a JSContext... - JSContext *cx; - nsXPConnect* xpc = nsXPConnect::GetXPConnect(); - if (!xpc || NS_FAILED(xpc->GetSafeJSContext(&cx)) || !cx) { - NS_ERROR("Failed to get safe JSContext!"); - return; - } - // Trace children. JSTracer trc; - JS_TracerInit(&trc, cx, UnmarkGrayChildren); + JS_TracerInit(&trc, JS_GetObjectRuntime(obj), UnmarkGrayChildren); JS_TraceChildren(&trc, obj, JSTRACE_OBJECT); } @@ -861,8 +848,6 @@ WrapperIsNotMainThreadOnly(XPCWrappedNative *wrapper) NS_IMETHODIMP nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb) { - JSContext *cx = mCycleCollectionContext->GetJSContext(); - JSGCTraceKind traceKind = js_GetGCThingTraceKind(p); JSObject *obj = nsnull; js::Class *clazz = nsnull; @@ -970,7 +955,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb) TraversalTracer trc(cb); - JS_TracerInit(&trc, cx, NoteJSChild); + JS_TracerInit(&trc, GetRuntime()->GetJSRuntime(), NoteJSChild); trc.eagerlyTraceWeakMaps = false; JS_TraceChildren(&trc, p, traceKind); @@ -1222,7 +1207,7 @@ xpc_CreateGlobalObject(JSContext *cx, JSClass *clasp, #ifdef DEBUG if (clasp->flags & JSCLASS_XPCONNECT_GLOBAL) { VerifyTraceXPCGlobalCalledTracer trc; - JS_TracerInit(&trc.base, cx, VerifyTraceXPCGlobalCalled); + JS_TracerInit(&trc.base, JS_GetRuntime(cx), VerifyTraceXPCGlobalCalled); trc.ok = false; JS_TraceChildren(&trc.base, *global, JSTRACE_OBJECT); NS_ABORT_IF_FALSE(trc.ok, "Trace hook needs to call TraceXPCGlobal if JSCLASS_XPCONNECT_GLOBAL is set."); @@ -2779,13 +2764,12 @@ void DumpJSHeap(FILE* file) { NS_ABORT_IF_FALSE(NS_IsMainThread(), "Must dump GC heap on main thread."); - JSContext *cx; nsXPConnect* xpc = nsXPConnect::GetXPConnect(); - if (!xpc || NS_FAILED(xpc->GetSafeJSContext(&cx)) || !cx) { - NS_ERROR("Failed to get safe JSContext!"); + if (!xpc) { + NS_ERROR("Failed to get nsXPConnect instance!"); return; } - js::DumpHeapComplete(cx, file); + js::DumpHeapComplete(xpc->GetRuntime()->GetJSRuntime(), file); } #endif diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 7b6317b64c2..76a9d11a0d8 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -751,7 +751,8 @@ public: void AddXPConnectRoots(nsCycleCollectionTraversalCallback& cb); void UnmarkSkippableJSHolders(); - static JSBool GCCallback(JSContext *cx, JSGCStatus status); + static void GCCallback(JSRuntime *rt, JSGCStatus status); + static void FinalizeCallback(JSContext *cx, JSFinalizeStatus status); inline void AddVariantRoot(XPCTraceableVariant* variant); inline void AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS); @@ -3585,7 +3586,7 @@ struct XPCJSContextInfo { bool savedFrameChain; // Greater than 0 if a request was suspended. - jsrefcount suspendDepth; + unsigned suspendDepth; }; class XPCJSContextStack diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index cbfe365af17..cbd19264671 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -1312,6 +1312,19 @@ ContainerState::FindThebesLayerFor(nsDisplayItem* aItem, return layer.forget(); } +#ifdef MOZ_DUMP_PAINTING +static void +DumpPaintedImage(nsDisplayItem* aItem, gfxASurface* aSurf) +{ + nsCString string(aItem->Name()); + string.Append("-"); + string.AppendInt((PRUint64)aItem); + fprintf(gfxUtils::sDumpPaintFile, "array[\"%s\"]=\"", string.BeginReading()); + aSurf->DumpAsDataURL(gfxUtils::sDumpPaintFile); + fprintf(gfxUtils::sDumpPaintFile, "\";"); +} +#endif + static void PaintInactiveLayer(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, @@ -1319,23 +1332,47 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder, { // This item has an inactive layer. Render it to a ThebesLayer // using a temporary BasicLayerManager. + PRInt32 appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem); + nsIntRect itemVisibleRect = + aItem->GetVisibleRect().ToOutsidePixels(appUnitsPerDevPixel); + + nsRefPtr context = aContext; +#ifdef MOZ_DUMP_PAINTING + nsRefPtr surf; + if (gfxUtils::sDumpPainting) { + surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(itemVisibleRect.Size(), + gfxASurface::CONTENT_COLOR_ALPHA); + surf->SetDeviceOffset(-itemVisibleRect.TopLeft()); + context = new gfxContext(surf); + } +#endif + nsRefPtr tempManager = new BasicLayerManager(); - tempManager->BeginTransactionWithTarget(aContext); + tempManager->BeginTransactionWithTarget(context); nsRefPtr layer = aItem->BuildLayer(aBuilder, tempManager, FrameLayerBuilder::ContainerParameters()); if (!layer) { tempManager->EndTransaction(nsnull, nsnull); return; } - PRInt32 appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem); - nsIntRect itemVisibleRect = - aItem->GetVisibleRect().ToOutsidePixels(appUnitsPerDevPixel); RestrictVisibleRegionForLayer(layer, itemVisibleRect); - + tempManager->SetRoot(layer); aBuilder->LayerBuilder()->WillEndTransaction(tempManager); tempManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer, aBuilder); aBuilder->LayerBuilder()->DidEndTransaction(tempManager); + +#ifdef MOZ_DUMP_PAINTING + if (gfxUtils::sDumpPainting) { + DumpPaintedImage(aItem, surf); + + surf->SetDeviceOffset(gfxPoint(0, 0)); + aContext->SetSource(surf, itemVisibleRect.TopLeft()); + aContext->Rectangle(itemVisibleRect); + aContext->Fill(); + aItem->SetPainted(); + } +#endif } /* @@ -2002,6 +2039,32 @@ FrameLayerBuilder::GetDedicatedLayer(nsIFrame* aFrame, PRUint32 aDisplayItemKey) return nsnull; } +#ifdef MOZ_DUMP_PAINTING +static void DebugPaintItem(nsRenderingContext* aDest, nsDisplayItem *aItem, nsDisplayListBuilder* aBuilder) +{ + nsRect appUnitBounds = aItem->GetBounds(aBuilder); + gfxRect bounds(appUnitBounds.x, appUnitBounds.y, appUnitBounds.width, appUnitBounds.height); + bounds.ScaleInverse(aDest->AppUnitsPerDevPixel()); + + nsRefPtr surf = + gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height), + gfxASurface::CONTENT_COLOR_ALPHA); + surf->SetDeviceOffset(-bounds.TopLeft()); + nsRefPtr context = new gfxContext(surf); + nsRefPtr ctx = new nsRenderingContext(); + ctx->Init(aDest->DeviceContext(), context); + + aItem->Paint(aBuilder, ctx); + DumpPaintedImage(aItem, surf); + aItem->SetPainted(); + + surf->SetDeviceOffset(gfxPoint(0, 0)); + aDest->ThebesContext()->SetSource(surf, bounds.TopLeft()); + aDest->ThebesContext()->Rectangle(bounds); + aDest->ThebesContext()->Fill(); +} +#endif + /* * A note on residual transforms: * @@ -2176,7 +2239,16 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer, if (frame) { frame->AddStateBits(NS_FRAME_PAINTED_THEBES); } - cdi->mItem->Paint(builder, rc); +#ifdef MOZ_DUMP_PAINTING + + if (gfxUtils::sDumpPainting) { + DebugPaintItem(rc, cdi->mItem, builder); + } else { +#else + { +#endif + cdi->mItem->Paint(builder, rc); + } } if (builder->LayerBuilder()->CheckDOMModified()) @@ -2210,10 +2282,10 @@ FrameLayerBuilder::CheckDOMModified() #ifdef MOZ_DUMP_PAINTING void -FrameLayerBuilder::DumpRetainedLayerTree() +FrameLayerBuilder::DumpRetainedLayerTree(FILE* aFile) { if (mRetainingManager) { - mRetainingManager->Dump(stdout); + mRetainingManager->Dump(aFile); } } #endif diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index 28f6be8703e..3ada391b581 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -249,7 +249,7 @@ public: * Dumps this FrameLayerBuilder's retained layer manager's retained * layer tree to stderr. */ - void DumpRetainedLayerTree(); + void DumpRetainedLayerTree(FILE* aFile = stdout); #endif /******* PRIVATE METHODS to FrameLayerBuilder.cpp ********/ diff --git a/layout/base/crashtests/727601.html b/layout/base/crashtests/727601.html new file mode 100644 index 00000000000..cc6ef390b1e --- /dev/null +++ b/layout/base/crashtests/727601.html @@ -0,0 +1,3 @@ + + + diff --git a/layout/base/crashtests/crashtests.list b/layout/base/crashtests/crashtests.list index b6b9926f710..dc435316367 100644 --- a/layout/base/crashtests/crashtests.list +++ b/layout/base/crashtests/crashtests.list @@ -350,3 +350,4 @@ needs-focus pref(accessibility.browsewithcaret,true) load 699353-1.html load 707098.html load 722137.html load 725535.html +load 727601.html diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp index b5eaaac1dc3..28b44382a32 100644 --- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -52,7 +52,6 @@ #include "nsContainerFrame.h" #include "nsInlineFrame.h" #include "nsPlaceholderFrame.h" -#include "nsContainerFrame.h" #include "nsFirstLetterFrame.h" #include "nsUnicodeProperties.h" #include "nsTextFrame.h" diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index d7c4646989c..7efed165331 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -220,7 +220,6 @@ NS_NewSVGFEImageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); nsIFrame* NS_NewSVGFEUnstyledLeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); -#include "nsIDocument.h" #include "nsIScrollable.h" #include "nsINodeInfo.h" #include "prenv.h" @@ -7606,8 +7605,9 @@ ApplyRenderingChangeToTree(nsPresContext* aPresContext, nsIFrame* aFrame, nsChangeHint aChange) { - NS_ASSERTION(!(aChange & nsChangeHint_UpdateTransformLayer) || aFrame->IsTransformed(), - "Only transformed frames should have UpdateTransformLayer hint"); + NS_ASSERTION(!(aChange & nsChangeHint_UpdateTransformLayer) || + aFrame->GetStyleDisplay()->HasTransform(), + "Only transform style should give a UpdateTransformLayer hint"); nsIPresShell *shell = aPresContext->PresShell(); if (shell->IsPaintingSuppressed()) { diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index f4e178d0632..b4f489eb4d9 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -2602,7 +2602,14 @@ nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBui // reference frame size (~viewport), allowing a 1/8th fuzz factor // for shadows, borders, etc. refSize += nsSize(refSize.width / 8, refSize.height / 8); - return aFrame->GetVisualOverflowRectRelativeToSelf().Size() <= refSize; + if (aFrame->GetVisualOverflowRectRelativeToSelf().Size() <= refSize) { + // Bug 717521 - pre-render max 4096 x 4096 device pixels. + nscoord max = aFrame->PresContext()->DevPixelsToAppUnits(4096); + nsRect visual = aFrame->GetVisualOverflowRect(); + if (visual.width <= max && visual.height <= max) { + return true; + } + } } return false; } diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index a5615cd4810..d65ad3b297b 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -566,8 +566,12 @@ public: // This is never instantiated directly (it has pure virtual methods), so no // need to count constructors and destructors. - nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) : - mFrame(aFrame) { + nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) + : mFrame(aFrame) +#ifdef MOZ_DUMP_PAINTING + , mPainted(false) +#endif + { if (aFrame) { mToReferenceFrame = aBuilder->ToReferenceFrame(aFrame); } @@ -715,6 +719,19 @@ public: * aCtx must be set up as for nsDisplayList::Paint. */ virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) {} + +#ifdef MOZ_DUMP_PAINTING + /** + * Mark this display item as being painted via FrameLayerBuilder::DrawThebesLayer. + */ + bool Painted() { return mPainted; } + + /** + * Check if this display item has been painted. + */ + void SetPainted() { mPainted = true; } +#endif + /** * Get the layer drawn by this display item. Call this only if * GetLayerState() returns something other than LAYER_NONE. @@ -850,6 +867,10 @@ protected: // of the item. Paint implementations can use this to limit their drawing. // Guaranteed to be contained in GetBounds(). nsRect mVisibleRect; +#ifdef MOZ_DUMP_PAINTING + // True if this frame has been painted. + bool mPainted; +#endif }; /** diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index a8d03c2f408..2a60c31cbcf 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -166,14 +166,10 @@ static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printset #include "nsIWindowWatcher.h" // Printing -#include "nsPrintEngine.h" #include "nsPagePrintTimer.h" #endif // NS_PRINTING -// FrameSet -#include "nsIDocument.h" - //focus #include "nsIDOMEventTarget.h" #include "nsIDOMEventListener.h" @@ -191,9 +187,6 @@ static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printset #include "prenv.h" #include -//switch to page layout -#include "nsGfxCIID.h" - #include "nsObserverService.h" #include "mozilla/dom/Element.h" diff --git a/layout/base/nsLayoutDebugger.cpp b/layout/base/nsLayoutDebugger.cpp index 734df7453bc..df4e2599674 100644 --- a/layout/base/nsLayoutDebugger.cpp +++ b/layout/base/nsLayoutDebugger.cpp @@ -153,16 +153,16 @@ nsLayoutDebugger::GetStyleSize(nsIPresShell* aPresentation, #ifdef MOZ_DUMP_PAINTING static void PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList, - PRInt32 aIndent, FILE* aOutput) + FILE* aOutput) { + fprintf(aOutput, ""); } void nsFrame::PrintDisplayList(nsDisplayListBuilder* aBuilder, - const nsDisplayList& aList) + const nsDisplayList& aList, + FILE* aFile) { - PrintDisplayListTo(aBuilder, aList, 0, stdout); + PrintDisplayListTo(aBuilder, aList, aFile); } #endif diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index cf6670d18ad..5b50bba3eca 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -92,7 +92,6 @@ #endif #include "nsGenericHTMLElement.h" #include "imgIRequest.h" -#include "imgIContainer.h" #include "nsIImageLoadingContent.h" #include "nsCOMPtr.h" #include "nsListControlFrame.h" @@ -1381,8 +1380,8 @@ nsLayoutUtils::CombineBreakType(PRUint8 aOrigBreakType, #ifdef MOZ_DUMP_PAINTING #include -static bool gDumpPaintList = getenv("MOZ_DUMP_PAINT_LIST") != 0; static bool gDumpEventList = false; +int gPaintCount = 0; #endif nsresult @@ -1774,10 +1773,22 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram } #ifdef MOZ_DUMP_PAINTING - if (gDumpPaintList) { - fprintf(stdout, "Painting --- before optimization (dirty %d,%d,%d,%d):\n", + if (gfxUtils::sDumpPainting) { + if (gfxUtils::sDumpPaintingToFile) { + nsCString string("dump-"); + string.AppendInt(gPaintCount); + string.Append(".html"); + gfxUtils::sDumpPaintFile = fopen(string.BeginReading(), "w"); + } else { + gfxUtils::sDumpPaintFile = stdout; + } + fprintf(gfxUtils::sDumpPaintFile, ""); + fprintf(gfxUtils::sDumpPaintFile, "Painting --- before optimization (dirty %d,%d,%d,%d):\n", dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height); - nsFrame::PrintDisplayList(&builder, list); + nsFrame::PrintDisplayList(&builder, list, gfxUtils::sDumpPaintFile); + if (gfxUtils::sDumpPaintingToFile) { + fprintf(gfxUtils::sDumpPaintFile, "Painting --- after optimization:\n"); + nsFrame::PrintDisplayList(&builder, list, gfxUtils::sDumpPaintFile); - fprintf(stdout, "Painting --- retained layer tree:\n"); - builder.LayerBuilder()->DumpRetainedLayerTree(); + fprintf(gfxUtils::sDumpPaintFile, "Painting --- retained layer tree:\n"); + builder.LayerBuilder()->DumpRetainedLayerTree(gfxUtils::sDumpPaintFile); + fprintf(gfxUtils::sDumpPaintFile, ""); + + if (gfxUtils::sDumpPaintingToFile) { + fclose(gfxUtils::sDumpPaintFile); + } + gfxUtils::sDumpPaintFile = NULL; + gPaintCount++; } #endif diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index fe415a0aee0..a89e07f38d1 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -67,7 +67,6 @@ #include "nsIWeakReferenceUtils.h" #include "nsCSSRendering.h" #include "prprf.h" -#include "nsContentPolicyUtils.h" #include "nsIDOMDocument.h" #include "nsAutoPtr.h" #include "nsEventStateManager.h" diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index e1a5f476f00..c45502efd85 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -8034,8 +8034,6 @@ nsIPresShell::RemoveRefreshObserverExternal(nsARefreshObserver* aObserver, // Start of DEBUG only code #ifdef NS_DEBUG -#include "nsViewsCID.h" -#include "nsWidgetsCID.h" #include "nsIURL.h" #include "nsILinkHandler.h" diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index 5361278d1d7..d2dc08f232f 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -147,9 +147,6 @@ using mozilla::dom::telephony::AudioManager; #include "nsEditor.h" #include "nsPlaintextEditor.h" #include "nsEditorController.h" //CID -#include "nsIController.h" -#include "nsIControllerContext.h" -#include "nsIControllerCommandTable.h" #include "nsHTMLEditor.h" #include "nsTextServicesDocument.h" @@ -160,7 +157,6 @@ using mozilla::dom::telephony::AudioManager; #include "nsSystemPrincipal.h" #include "nsNullPrincipal.h" #include "nsNetCID.h" -#include "nsINodeInfo.h" #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_PLATFORM_MAEMO) #include "nsHapticFeedback.h" #endif diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp index 7910e51600c..6dd77c043f1 100644 --- a/layout/build/nsLayoutStatics.cpp +++ b/layout/build/nsLayoutStatics.cpp @@ -82,7 +82,6 @@ #include "nsCrossSiteListenerProxy.h" #include "nsHTMLDNSPrefetch.h" #include "nsHtml5Module.h" -#include "nsCrossSiteListenerProxy.h" #include "nsFocusManager.h" #include "nsFrameList.h" #include "nsListControlFrame.h" diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index b975874cb33..3f605eae2f6 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -77,7 +77,6 @@ #include "nsAccessibilityService.h" #endif #include "nsIServiceManager.h" -#include "nsIDOMNode.h" #include "nsGUIEvent.h" #include "nsAutoPtr.h" #include "nsStyleSet.h" diff --git a/layout/forms/nsFileControlFrame.cpp b/layout/forms/nsFileControlFrame.cpp index 253929fb470..aa220848f0f 100644 --- a/layout/forms/nsFileControlFrame.cpp +++ b/layout/forms/nsFileControlFrame.cpp @@ -57,7 +57,6 @@ #include "nsIPresShell.h" #include "nsXPCOM.h" #include "nsISupportsPrimitives.h" -#include "nsIComponentManager.h" #include "nsPIDOMWindow.h" #include "nsIFilePicker.h" #include "nsIDOMMouseEvent.h" @@ -70,7 +69,6 @@ #include "nsContentUtils.h" #include "nsDisplayList.h" #include "nsIDOMNSEvent.h" -#include "nsIDOMHTMLInputElement.h" #include "nsEventListenerManager.h" #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" @@ -78,13 +76,11 @@ #include "nsInterfaceHashtable.h" #include "nsURIHashKey.h" -#include "nsILocalFile.h" #include "nsNetCID.h" #include "nsWeakReference.h" #include "nsIVariant.h" #include "mozilla/Services.h" #include "nsDirectoryServiceDefs.h" -#include "nsHTMLInputElement.h" #include "nsICapturePicker.h" #include "nsIFileURL.h" #include "nsDOMFile.h" diff --git a/layout/forms/nsGfxCheckboxControlFrame.cpp b/layout/forms/nsGfxCheckboxControlFrame.cpp index 5a8270fdc81..246f2b6143b 100644 --- a/layout/forms/nsGfxCheckboxControlFrame.cpp +++ b/layout/forms/nsGfxCheckboxControlFrame.cpp @@ -47,7 +47,6 @@ #include "nsIDOMHTMLInputElement.h" #include "nsDisplayList.h" #include "nsCSSAnonBoxes.h" -#include "nsIDOMHTMLInputElement.h" static void PaintCheckMark(nsIFrame* aFrame, diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index d1792ff95ea..10cfb0b6831 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -76,7 +76,6 @@ #include "nsAccessibilityService.h" #endif #include "nsHTMLSelectElement.h" -#include "nsIPrivateDOMEvent.h" #include "nsCSSRendering.h" #include "nsITheme.h" #include "nsIDOMEventListener.h" diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index 6430be12409..86288ae6e93 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -76,7 +76,6 @@ #include "nsIDOMDocument.h" #include "nsIDOMHTMLElement.h" #include "nsIPresShell.h" -#include "nsIComponentManager.h" #include "nsBoxLayoutState.h" //for keylistener for "return" check @@ -96,10 +95,8 @@ #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" #endif -#include "nsIServiceManager.h" #include "nsIDOMNode.h" -#include "nsIEditorObserver.h" #include "nsITransactionManager.h" #include "nsIDOMText.h" //for multiline getselection #include "nsNodeInfoManager.h" diff --git a/layout/generic/TextOverflow.cpp b/layout/generic/TextOverflow.cpp index 64f3b4f7cd4..8b1ee71f3a7 100644 --- a/layout/generic/TextOverflow.cpp +++ b/layout/generic/TextOverflow.cpp @@ -179,9 +179,10 @@ class nsDisplayTextOverflowMarker : public nsDisplayItem public: nsDisplayTextOverflowMarker(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, const nsRect& aRect, nscoord aAscent, - const nsString& aString) + const nsString& aString, + PRUint32 aIndex) : nsDisplayItem(aBuilder, aFrame), mRect(aRect), mString(aString), - mAscent(aAscent) { + mAscent(aAscent), mIndex(aIndex) { MOZ_COUNT_CTOR(nsDisplayTextOverflowMarker); } #ifdef NS_BUILD_REFCNT_LOGGING @@ -196,6 +197,10 @@ public: } virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); + + virtual PRUint32 GetPerFrameKey() { + return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); + } void PaintTextToContext(nsRenderingContext* aCtx, nsPoint aOffsetFromRect); NS_DISPLAY_DECL_NAME("TextOverflow", TYPE_TEXT_OVERFLOW) @@ -203,6 +208,7 @@ private: nsRect mRect; // in reference frame coordinates const nsString mString; // the marker text nscoord mAscent; // baseline for the marker text in mRect + PRUint32 mIndex; }; static void @@ -720,7 +726,7 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine, markerRect += mBuilder->ToReferenceFrame(mBlock); nsDisplayItem* marker = new (mBuilder) nsDisplayTextOverflowMarker(mBuilder, mBlock, markerRect, - aLine->GetAscent(), mLeft.mMarkerString); + aLine->GetAscent(), mLeft.mMarkerString, 0); if (marker) { marker = ClipMarker(mBuilder, mBlock, marker, mContentArea + mBuilder->ToReferenceFrame(mBlock), @@ -736,7 +742,7 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine, markerRect += mBuilder->ToReferenceFrame(mBlock); nsDisplayItem* marker = new (mBuilder) nsDisplayTextOverflowMarker(mBuilder, mBlock, markerRect, - aLine->GetAscent(), mRight.mMarkerString); + aLine->GetAscent(), mRight.mMarkerString, 1); if (marker) { marker = ClipMarker(mBuilder, mBlock, marker, mContentArea + mBuilder->ToReferenceFrame(mBlock), diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp index ef898ecd296..256af22dd31 100644 --- a/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/layout/generic/nsAbsoluteContainingBlock.cpp @@ -44,7 +44,6 @@ #include "nsAbsoluteContainingBlock.h" #include "nsContainerFrame.h" #include "nsIPresShell.h" -#include "nsContainerFrame.h" #include "nsHTMLParts.h" #include "nsPresContext.h" #include "nsFrameManager.h" diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index d2f869a1be9..8a4193b3257 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -69,7 +69,6 @@ #include "nsIBaseWindow.h" #include "nsThemeConstants.h" #include "nsCSSFrameConstructor.h" -#include "nsThemeConstants.h" #include "mozilla/dom/Element.h" #ifdef NS_DEBUG diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index 05335911dbb..d75e62af473 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -728,7 +728,8 @@ public: public: static void PrintDisplayList(nsDisplayListBuilder* aBuilder, - const nsDisplayList& aList); + const nsDisplayList& aList, + FILE* aFile = stdout); #endif }; diff --git a/layout/generic/nsFrameSetFrame.cpp b/layout/generic/nsFrameSetFrame.cpp index cd1348d1b3f..405b4ea455a 100644 --- a/layout/generic/nsFrameSetFrame.cpp +++ b/layout/generic/nsFrameSetFrame.cpp @@ -57,7 +57,6 @@ #include "nsStyleConsts.h" #include "nsStyleContext.h" #include "nsHTMLParts.h" -#include "nsIComponentManager.h" #include "nsGUIEvent.h" #include "nsRenderingContext.h" #include "nsIServiceManager.h" diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index a4c911deae5..76639aff591 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -53,7 +53,6 @@ #include "nsIDocument.h" #include "nsFontMetrics.h" #include "nsIDocumentObserver.h" -#include "nsIDocument.h" #include "nsBoxLayoutState.h" #include "nsINodeInfo.h" #include "nsScrollbarFrame.h" diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index d3c0ef74174..77643194400 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -62,7 +62,6 @@ #include "nsILinkHandler.h" #include "nsIURL.h" #include "nsIIOService.h" -#include "nsIURL.h" #include "nsILoadGroup.h" #include "nsISupportsPriority.h" #include "nsIServiceManager.h" @@ -80,7 +79,6 @@ #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" #endif -#include "nsIServiceManager.h" #include "nsIDOMNode.h" #include "nsGUIEvent.h" #include "nsLayoutUtils.h" diff --git a/layout/generic/nsImageMap.cpp b/layout/generic/nsImageMap.cpp index cf1a31f8b66..dfeb49678bb 100644 --- a/layout/generic/nsImageMap.cpp +++ b/layout/generic/nsImageMap.cpp @@ -59,7 +59,6 @@ #include "nsIConsoleService.h" #include "nsIScriptError.h" #include "nsIStringBundle.h" -#include "nsIDocument.h" #include "nsContentUtils.h" namespace dom = mozilla::dom; diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index a23ba83d453..d24cdb12400 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -98,7 +98,6 @@ #include "nsIImageLoadingContent.h" #include "nsIObjectLoadingContent.h" #include "nsPIDOMWindow.h" -#include "nsIDOMElement.h" #include "nsContentUtils.h" #include "nsDisplayList.h" #include "nsAttrName.h" @@ -1190,8 +1189,7 @@ nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } nsRefPtr container = GetImageContainer(); - nsRefPtr currentImage = container ? container->GetCurrentImage() : nsnull; - if (!currentImage || !isVisible || + if (container && container->HasCurrentImage() || !isVisible || container->GetCurrentSize() != gfxIntSize(window->width, window->height)) { mInstanceOwner->NotifyPaintWaiter(aBuilder); } diff --git a/layout/generic/nsSelection.cpp b/layout/generic/nsSelection.cpp index 1c3e39ccd45..2d26bde5a3a 100644 --- a/layout/generic/nsSelection.cpp +++ b/layout/generic/nsSelection.cpp @@ -67,7 +67,6 @@ #include "nsTArray.h" #include "nsIScrollableFrame.h" #include "nsCCUncollectableMarker.h" -#include "nsISelectionListener.h" #include "nsIContentIterator.h" #include "nsIDocumentEncoder.h" @@ -97,7 +96,6 @@ static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID); #include "nsITimer.h" #include "nsIServiceManager.h" #include "nsFrameManager.h" -#include "nsIScrollableFrame.h" // notifications #include "nsIDOMDocument.h" #include "nsIDocument.h" diff --git a/layout/generic/nsSimplePageSequence.cpp b/layout/generic/nsSimplePageSequence.cpp index c574fb691ba..5936dc22909 100644 --- a/layout/generic/nsSimplePageSequence.cpp +++ b/layout/generic/nsSimplePageSequence.cpp @@ -57,7 +57,6 @@ #define OFFSET_NOT_SET -1 // Print Options -#include "nsIPrintSettings.h" #include "nsIPrintOptions.h" #include "nsGfxCIID.h" #include "nsIServiceManager.h" diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp index 297ceb10ab1..b57d5af5193 100644 --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -6444,7 +6444,7 @@ FindEndOfPunctuationRun(const nsTextFragment* aFrag, PRInt32 i; for (i = aStart; i < aEnd - aOffset; ++i) { - if (nsContentUtils::IsPunctuationMarkAt(aFrag, aOffset + i)) { + if (nsContentUtils::IsFirstLetterPunctuationAt(aFrag, aOffset + i)) { aIter->SetOriginalOffset(aOffset + i); FindClusterEnd(aTextRun, aEnd, aIter); i = aIter->GetOriginalOffset() - aOffset; diff --git a/layout/generic/nsVideoFrame.cpp b/layout/generic/nsVideoFrame.cpp index 90253950c90..828711b1a3e 100644 --- a/layout/generic/nsVideoFrame.cpp +++ b/layout/generic/nsVideoFrame.cpp @@ -56,12 +56,10 @@ #include "nsBoxFrame.h" #include "nsImageFrame.h" #include "nsIImageLoadingContent.h" -#include "nsDisplayList.h" #include "nsCSSRendering.h" #include "nsContentUtils.h" #ifdef ACCESSIBILITY -#include "nsIServiceManager.h" #include "nsAccessibilityService.h" #endif diff --git a/layout/generic/punct_marks.x-ccmap b/layout/generic/punct_marks.x-ccmap deleted file mode 100644 index 072687de908..00000000000 --- a/layout/generic/punct_marks.x-ccmap +++ /dev/null @@ -1,1353 +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.org code. - * - * The Initial Developer of the Original Code is - * Jungshik Shin - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * 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 ***** */ - - /*======================================================== - This file contains a precompiled CCMap for a class of Unicode - characters (punct_marks) to be identified quickly by Mozilla. - It was generated by ccmapbin.pl which you can find under - mozilla/intl/unicharutil/tools. - - Enumerated below are characters included in the precompiled CCMap - which is human-readable but not so human-friendly. If you - needs to modify the list of characters belonging to "punct_marks", - you have to make a new file (with the name of your choice) - listing characters (one character per line) you want to put - into "punct_marks" in the format - - 0xuuuu // comment - - In addition, the input file can have the following optional lines that - read - - VARIABLE::gPuncCharsCCMapExt - CLASS::punct_marks - DESCRIPTION:: description of a character class - FILE:: mozilla source file to include the output file - - - Then, run the following in the current directory. - - perl ccmapbin.pl input_file [gPuncCharsCCMapExt [punct_marks]] - - which will generate punct_marks.ccmap (or punct_marks.x-ccmap if the ccmap - includes non-BMP characters.). gPuncCharsCCMapExt is used as the prefix - in macros for the array initializer and the array size. - - (see bug 180266, bug 167136, and bug 224337) - - Additional notes: - The input file for this ccmap file was generated with the following shell commands: - (see bug 263411 for details) - - cut -d ';' -f 1-3 UnicodeData-Latest.txt | egrep 'Ps|Pe|Po|Pf|Pi' | cut -d ';' -f 1-2 \ - | sed -e 's/;/ : /' -e 's/^/ 0X/' - */ - -/* - VARIABLE:: gPuncCharsCCMapExt - CLASS:: punct_marks - DESCRIPTION:: Punctuation Marks (Unicode char. classes: Ps, Pe, Po, Pi, Pf) - - 0X000021 : EXCLAMATION MARK - 0X000022 : QUOTATION MARK - 0X000023 : NUMBER SIGN - 0X000025 : PERCENT SIGN - 0X000026 : AMPERSAND - 0X000027 : APOSTROPHE - 0X000028 : LEFT PARENTHESIS - 0X000029 : RIGHT PARENTHESIS - 0X00002A : ASTERISK - 0X00002C : COMMA - 0X00002E : FULL STOP - 0X00002F : SOLIDUS - 0X00003A : COLON - 0X00003B : SEMICOLON - 0X00003F : QUESTION MARK - 0X000040 : COMMERCIAL AT - 0X00005B : LEFT SQUARE BRACKET - 0X00005C : REVERSE SOLIDUS - 0X00005D : RIGHT SQUARE BRACKET - 0X00007B : LEFT CURLY BRACKET - 0X00007D : RIGHT CURLY BRACKET - 0X0000A1 : INVERTED EXCLAMATION MARK - 0X0000A7 : SECTION SIGN - 0X0000AB : LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0X0000B6 : PILCROW SIGN - 0X0000B7 : MIDDLE DOT - 0X0000BB : RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0X0000BF : INVERTED QUESTION MARK - 0X00037E : GREEK QUESTION MARK - 0X000387 : GREEK ANO TELEIA - 0X00055A : ARMENIAN APOSTROPHE - 0X00055B : ARMENIAN EMPHASIS MARK - 0X00055C : ARMENIAN EXCLAMATION MARK - 0X00055D : ARMENIAN COMMA - 0X00055E : ARMENIAN QUESTION MARK - 0X00055F : ARMENIAN ABBREVIATION MARK - 0X000589 : ARMENIAN FULL STOP - 0X0005C0 : HEBREW PUNCTUATION PASEQ - 0X0005C3 : HEBREW PUNCTUATION SOF PASUQ - 0X0005C6 : HEBREW PUNCTUATION NUN HAFUKHA - 0X0005F3 : HEBREW PUNCTUATION GERESH - 0X0005F4 : HEBREW PUNCTUATION GERSHAYIM - 0X000609 : ARABIC-INDIC PER MILLE SIGN - 0X00060A : ARABIC-INDIC PER TEN THOUSAND SIGN - 0X00060C : ARABIC COMMA - 0X00060D : ARABIC DATE SEPARATOR - 0X00061B : ARABIC SEMICOLON - 0X00061E : ARABIC TRIPLE DOT PUNCTUATION MARK - 0X00061F : ARABIC QUESTION MARK - 0X00066A : ARABIC PERCENT SIGN - 0X00066B : ARABIC DECIMAL SEPARATOR - 0X00066C : ARABIC THOUSANDS SEPARATOR - 0X00066D : ARABIC FIVE POINTED STAR - 0X0006D4 : ARABIC FULL STOP - 0X000700 : SYRIAC END OF PARAGRAPH - 0X000701 : SYRIAC SUPRALINEAR FULL STOP - 0X000702 : SYRIAC SUBLINEAR FULL STOP - 0X000703 : SYRIAC SUPRALINEAR COLON - 0X000704 : SYRIAC SUBLINEAR COLON - 0X000705 : SYRIAC HORIZONTAL COLON - 0X000706 : SYRIAC COLON SKEWED LEFT - 0X000707 : SYRIAC COLON SKEWED RIGHT - 0X000708 : SYRIAC SUPRALINEAR COLON SKEWED LEFT - 0X000709 : SYRIAC SUBLINEAR COLON SKEWED RIGHT - 0X00070A : SYRIAC CONTRACTION - 0X00070B : SYRIAC HARKLEAN OBELUS - 0X00070C : SYRIAC HARKLEAN METOBELUS - 0X00070D : SYRIAC HARKLEAN ASTERISCUS - 0X0007F7 : NKO SYMBOL GBAKURUNEN - 0X0007F8 : NKO COMMA - 0X0007F9 : NKO EXCLAMATION MARK - 0X000830 : SAMARITAN PUNCTUATION NEQUDAA - 0X000831 : SAMARITAN PUNCTUATION AFSAAQ - 0X000832 : SAMARITAN PUNCTUATION ANGED - 0X000833 : SAMARITAN PUNCTUATION BAU - 0X000834 : SAMARITAN PUNCTUATION ATMAAU - 0X000835 : SAMARITAN PUNCTUATION SHIYYAALAA - 0X000836 : SAMARITAN ABBREVIATION MARK - 0X000837 : SAMARITAN PUNCTUATION MELODIC QITSA - 0X000838 : SAMARITAN PUNCTUATION ZIQAA - 0X000839 : SAMARITAN PUNCTUATION QITSA - 0X00083A : SAMARITAN PUNCTUATION ZAEF - 0X00083B : SAMARITAN PUNCTUATION TURU - 0X00083C : SAMARITAN PUNCTUATION ARKAANU - 0X00083D : SAMARITAN PUNCTUATION SOF MASHFAAT - 0X00083E : SAMARITAN PUNCTUATION ANNAAU - 0X00085E : MANDAIC PUNCTUATION - 0X000964 : DEVANAGARI DANDA - 0X000965 : DEVANAGARI DOUBLE DANDA - 0X000970 : DEVANAGARI ABBREVIATION SIGN - 0X000AF0 : GUJARATI ABBREVIATION SIGN - 0X000DF4 : SINHALA PUNCTUATION KUNDDALIYA - 0X000E4F : THAI CHARACTER FONGMAN - 0X000E5A : THAI CHARACTER ANGKHANKHU - 0X000E5B : THAI CHARACTER KHOMUT - 0X000F04 : TIBETAN MARK INITIAL YIG MGO MDUN MA - 0X000F05 : TIBETAN MARK CLOSING YIG MGO SGAB MA - 0X000F06 : TIBETAN MARK CARET YIG MGO PHUR SHAD MA - 0X000F07 : TIBETAN MARK YIG MGO TSHEG SHAD MA - 0X000F08 : TIBETAN MARK SBRUL SHAD - 0X000F09 : TIBETAN MARK BSKUR YIG MGO - 0X000F0A : TIBETAN MARK BKA- SHOG YIG MGO - 0X000F0B : TIBETAN MARK INTERSYLLABIC TSHEG - 0X000F0C : TIBETAN MARK DELIMITER TSHEG BSTAR - 0X000F0D : TIBETAN MARK SHAD - 0X000F0E : TIBETAN MARK NYIS SHAD - 0X000F0F : TIBETAN MARK TSHEG SHAD - 0X000F10 : TIBETAN MARK NYIS TSHEG SHAD - 0X000F11 : TIBETAN MARK RIN CHEN SPUNGS SHAD - 0X000F12 : TIBETAN MARK RGYA GRAM SHAD - 0X000F14 : TIBETAN MARK GTER TSHEG - 0X000F3A : TIBETAN MARK GUG RTAGS GYON - 0X000F3B : TIBETAN MARK GUG RTAGS GYAS - 0X000F3C : TIBETAN MARK ANG KHANG GYON - 0X000F3D : TIBETAN MARK ANG KHANG GYAS - 0X000F85 : TIBETAN MARK PALUTA - 0X000FD0 : TIBETAN MARK BSKA- SHOG GI MGO RGYAN - 0X000FD1 : TIBETAN MARK MNYAM YIG GI MGO RGYAN - 0X000FD2 : TIBETAN MARK NYIS TSHEG - 0X000FD3 : TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA - 0X000FD4 : TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA - 0X000FD9 : TIBETAN MARK LEADING MCHAN RTAGS - 0X000FDA : TIBETAN MARK TRAILING MCHAN RTAGS - 0X00104A : MYANMAR SIGN LITTLE SECTION - 0X00104B : MYANMAR SIGN SECTION - 0X00104C : MYANMAR SYMBOL LOCATIVE - 0X00104D : MYANMAR SYMBOL COMPLETED - 0X00104E : MYANMAR SYMBOL AFOREMENTIONED - 0X00104F : MYANMAR SYMBOL GENITIVE - 0X0010FB : GEORGIAN PARAGRAPH SEPARATOR - 0X001360 : ETHIOPIC SECTION MARK - 0X001361 : ETHIOPIC WORDSPACE - 0X001362 : ETHIOPIC FULL STOP - 0X001363 : ETHIOPIC COMMA - 0X001364 : ETHIOPIC SEMICOLON - 0X001365 : ETHIOPIC COLON - 0X001366 : ETHIOPIC PREFACE COLON - 0X001367 : ETHIOPIC QUESTION MARK - 0X001368 : ETHIOPIC PARAGRAPH SEPARATOR - 0X00166D : CANADIAN SYLLABICS CHI SIGN - 0X00166E : CANADIAN SYLLABICS FULL STOP - 0X00169B : OGHAM FEATHER MARK - 0X00169C : OGHAM REVERSED FEATHER MARK - 0X0016EB : RUNIC SINGLE PUNCTUATION - 0X0016EC : RUNIC MULTIPLE PUNCTUATION - 0X0016ED : RUNIC CROSS PUNCTUATION - 0X001735 : PHILIPPINE SINGLE PUNCTUATION - 0X001736 : PHILIPPINE DOUBLE PUNCTUATION - 0X0017D4 : KHMER SIGN KHAN - 0X0017D5 : KHMER SIGN BARIYOOSAN - 0X0017D6 : KHMER SIGN CAMNUC PII KUUH - 0X0017D8 : KHMER SIGN BEYYAL - 0X0017D9 : KHMER SIGN PHNAEK MUAN - 0X0017DA : KHMER SIGN KOOMUUT - 0X001800 : MONGOLIAN BIRGA - 0X001801 : MONGOLIAN ELLIPSIS - 0X001802 : MONGOLIAN COMMA - 0X001803 : MONGOLIAN FULL STOP - 0X001804 : MONGOLIAN COLON - 0X001805 : MONGOLIAN FOUR DOTS - 0X001807 : MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER - 0X001808 : MONGOLIAN MANCHU COMMA - 0X001809 : MONGOLIAN MANCHU FULL STOP - 0X00180A : MONGOLIAN NIRUGU - 0X001944 : LIMBU EXCLAMATION MARK - 0X001945 : LIMBU QUESTION MARK - 0X001A1E : BUGINESE PALLAWA - 0X001A1F : BUGINESE END OF SECTION - 0X001AA0 : TAI THAM SIGN WIANG - 0X001AA1 : TAI THAM SIGN WIANGWAAK - 0X001AA2 : TAI THAM SIGN SAWAN - 0X001AA3 : TAI THAM SIGN KEOW - 0X001AA4 : TAI THAM SIGN HOY - 0X001AA5 : TAI THAM SIGN DOKMAI - 0X001AA6 : TAI THAM SIGN REVERSED ROTATED RANA - 0X001AA8 : TAI THAM SIGN KAAN - 0X001AA9 : TAI THAM SIGN KAANKUU - 0X001AAA : TAI THAM SIGN SATKAAN - 0X001AAB : TAI THAM SIGN SATKAANKUU - 0X001AAC : TAI THAM SIGN HANG - 0X001AAD : TAI THAM SIGN CAANG - 0X001B5A : BALINESE PANTI - 0X001B5B : BALINESE PAMADA - 0X001B5C : BALINESE WINDU - 0X001B5D : BALINESE CARIK PAMUNGKAH - 0X001B5E : BALINESE CARIK SIKI - 0X001B5F : BALINESE CARIK PAREREN - 0X001B60 : BALINESE PAMENENG - 0X001BFC : BATAK SYMBOL BINDU NA METEK - 0X001BFD : BATAK SYMBOL BINDU PINARBORAS - 0X001BFE : BATAK SYMBOL BINDU JUDUL - 0X001BFF : BATAK SYMBOL BINDU PANGOLAT - 0X001C3B : LEPCHA PUNCTUATION TA-ROL - 0X001C3C : LEPCHA PUNCTUATION NYET THYOOM TA-ROL - 0X001C3D : LEPCHA PUNCTUATION CER-WA - 0X001C3E : LEPCHA PUNCTUATION TSHOOK CER-WA - 0X001C3F : LEPCHA PUNCTUATION TSHOOK - 0X001C7E : OL CHIKI PUNCTUATION MUCAAD - 0X001C7F : OL CHIKI PUNCTUATION DOUBLE MUCAAD - 0X001CC0 : SUNDANESE PUNCTUATION BINDU SURYA - 0X001CC1 : SUNDANESE PUNCTUATION BINDU PANGLONG - 0X001CC2 : SUNDANESE PUNCTUATION BINDU PURNAMA - 0X001CC3 : SUNDANESE PUNCTUATION BINDU CAKRA - 0X001CC4 : SUNDANESE PUNCTUATION BINDU LEU SATANGA - 0X001CC5 : SUNDANESE PUNCTUATION BINDU KA SATANGA - 0X001CC6 : SUNDANESE PUNCTUATION BINDU DA SATANGA - 0X001CC7 : SUNDANESE PUNCTUATION BINDU BA SATANGA - 0X001CD3 : VEDIC SIGN NIHSHVASA - 0X002016 : DOUBLE VERTICAL LINE - 0X002017 : DOUBLE LOW LINE - 0X002018 : LEFT SINGLE QUOTATION MARK - 0X002019 : RIGHT SINGLE QUOTATION MARK - 0X00201A : SINGLE LOW-9 QUOTATION MARK - 0X00201B : SINGLE HIGH-REVERSED-9 QUOTATION MARK - 0X00201C : LEFT DOUBLE QUOTATION MARK - 0X00201D : RIGHT DOUBLE QUOTATION MARK - 0X00201E : DOUBLE LOW-9 QUOTATION MARK - 0X00201F : DOUBLE HIGH-REVERSED-9 QUOTATION MARK - 0X002020 : DAGGER - 0X002021 : DOUBLE DAGGER - 0X002022 : BULLET - 0X002023 : TRIANGULAR BULLET - 0X002024 : ONE DOT LEADER - 0X002025 : TWO DOT LEADER - 0X002026 : HORIZONTAL ELLIPSIS - 0X002027 : HYPHENATION POINT - 0X002030 : PER MILLE SIGN - 0X002031 : PER TEN THOUSAND SIGN - 0X002032 : PRIME - 0X002033 : DOUBLE PRIME - 0X002034 : TRIPLE PRIME - 0X002035 : REVERSED PRIME - 0X002036 : REVERSED DOUBLE PRIME - 0X002037 : REVERSED TRIPLE PRIME - 0X002038 : CARET - 0X002039 : SINGLE LEFT-POINTING ANGLE QUOTATION MARK - 0X00203A : SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - 0X00203B : REFERENCE MARK - 0X00203C : DOUBLE EXCLAMATION MARK - 0X00203D : INTERROBANG - 0X00203E : OVERLINE - 0X002041 : CARET INSERTION POINT - 0X002042 : ASTERISM - 0X002043 : HYPHEN BULLET - 0X002045 : LEFT SQUARE BRACKET WITH QUILL - 0X002046 : RIGHT SQUARE BRACKET WITH QUILL - 0X002047 : DOUBLE QUESTION MARK - 0X002048 : QUESTION EXCLAMATION MARK - 0X002049 : EXCLAMATION QUESTION MARK - 0X00204A : TIRONIAN SIGN ET - 0X00204B : REVERSED PILCROW SIGN - 0X00204C : BLACK LEFTWARDS BULLET - 0X00204D : BLACK RIGHTWARDS BULLET - 0X00204E : LOW ASTERISK - 0X00204F : REVERSED SEMICOLON - 0X002050 : CLOSE UP - 0X002051 : TWO ASTERISKS ALIGNED VERTICALLY - 0X002053 : SWUNG DASH - 0X002055 : FLOWER PUNCTUATION MARK - 0X002056 : THREE DOT PUNCTUATION - 0X002057 : QUADRUPLE PRIME - 0X002058 : FOUR DOT PUNCTUATION - 0X002059 : FIVE DOT PUNCTUATION - 0X00205A : TWO DOT PUNCTUATION - 0X00205B : FOUR DOT MARK - 0X00205C : DOTTED CROSS - 0X00205D : TRICOLON - 0X00205E : VERTICAL FOUR DOTS - 0X00207D : SUPERSCRIPT LEFT PARENTHESIS - 0X00207E : SUPERSCRIPT RIGHT PARENTHESIS - 0X00208D : SUBSCRIPT LEFT PARENTHESIS - 0X00208E : SUBSCRIPT RIGHT PARENTHESIS - 0X002329 : LEFT-POINTING ANGLE BRACKET - 0X00232A : RIGHT-POINTING ANGLE BRACKET - 0X002768 : MEDIUM LEFT PARENTHESIS ORNAMENT - 0X002769 : MEDIUM RIGHT PARENTHESIS ORNAMENT - 0X00276A : MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT - 0X00276B : MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT - 0X00276C : MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT - 0X00276D : MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT - 0X00276E : HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT - 0X00276F : HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT - 0X002770 : HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT - 0X002771 : HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT - 0X002772 : LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT - 0X002773 : LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT - 0X002774 : MEDIUM LEFT CURLY BRACKET ORNAMENT - 0X002775 : MEDIUM RIGHT CURLY BRACKET ORNAMENT - 0X0027C5 : LEFT S-SHAPED BAG DELIMITER - 0X0027C6 : RIGHT S-SHAPED BAG DELIMITER - 0X0027E6 : MATHEMATICAL LEFT WHITE SQUARE BRACKET - 0X0027E7 : MATHEMATICAL RIGHT WHITE SQUARE BRACKET - 0X0027E8 : MATHEMATICAL LEFT ANGLE BRACKET - 0X0027E9 : MATHEMATICAL RIGHT ANGLE BRACKET - 0X0027EA : MATHEMATICAL LEFT DOUBLE ANGLE BRACKET - 0X0027EB : MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET - 0X0027EC : MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET - 0X0027ED : MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET - 0X0027EE : MATHEMATICAL LEFT FLATTENED PARENTHESIS - 0X0027EF : MATHEMATICAL RIGHT FLATTENED PARENTHESIS - 0X002983 : LEFT WHITE CURLY BRACKET - 0X002984 : RIGHT WHITE CURLY BRACKET - 0X002985 : LEFT WHITE PARENTHESIS - 0X002986 : RIGHT WHITE PARENTHESIS - 0X002987 : Z NOTATION LEFT IMAGE BRACKET - 0X002988 : Z NOTATION RIGHT IMAGE BRACKET - 0X002989 : Z NOTATION LEFT BINDING BRACKET - 0X00298A : Z NOTATION RIGHT BINDING BRACKET - 0X00298B : LEFT SQUARE BRACKET WITH UNDERBAR - 0X00298C : RIGHT SQUARE BRACKET WITH UNDERBAR - 0X00298D : LEFT SQUARE BRACKET WITH TICK IN TOP CORNER - 0X00298E : RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER - 0X00298F : LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER - 0X002990 : RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER - 0X002991 : LEFT ANGLE BRACKET WITH DOT - 0X002992 : RIGHT ANGLE BRACKET WITH DOT - 0X002993 : LEFT ARC LESS-THAN BRACKET - 0X002994 : RIGHT ARC GREATER-THAN BRACKET - 0X002995 : DOUBLE LEFT ARC GREATER-THAN BRACKET - 0X002996 : DOUBLE RIGHT ARC LESS-THAN BRACKET - 0X002997 : LEFT BLACK TORTOISE SHELL BRACKET - 0X002998 : RIGHT BLACK TORTOISE SHELL BRACKET - 0X0029D8 : LEFT WIGGLY FENCE - 0X0029D9 : RIGHT WIGGLY FENCE - 0X0029DA : LEFT DOUBLE WIGGLY FENCE - 0X0029DB : RIGHT DOUBLE WIGGLY FENCE - 0X0029FC : LEFT-POINTING CURVED ANGLE BRACKET - 0X0029FD : RIGHT-POINTING CURVED ANGLE BRACKET - 0X002CF9 : COPTIC OLD NUBIAN FULL STOP - 0X002CFA : COPTIC OLD NUBIAN DIRECT QUESTION MARK - 0X002CFB : COPTIC OLD NUBIAN INDIRECT QUESTION MARK - 0X002CFC : COPTIC OLD NUBIAN VERSE DIVIDER - 0X002CFE : COPTIC FULL STOP - 0X002CFF : COPTIC MORPHOLOGICAL DIVIDER - 0X002D70 : TIFINAGH SEPARATOR MARK - 0X002E00 : RIGHT ANGLE SUBSTITUTION MARKER - 0X002E01 : RIGHT ANGLE DOTTED SUBSTITUTION MARKER - 0X002E02 : LEFT SUBSTITUTION BRACKET - 0X002E03 : RIGHT SUBSTITUTION BRACKET - 0X002E04 : LEFT DOTTED SUBSTITUTION BRACKET - 0X002E05 : RIGHT DOTTED SUBSTITUTION BRACKET - 0X002E06 : RAISED INTERPOLATION MARKER - 0X002E07 : RAISED DOTTED INTERPOLATION MARKER - 0X002E08 : DOTTED TRANSPOSITION MARKER - 0X002E09 : LEFT TRANSPOSITION BRACKET - 0X002E0A : RIGHT TRANSPOSITION BRACKET - 0X002E0B : RAISED SQUARE - 0X002E0C : LEFT RAISED OMISSION BRACKET - 0X002E0D : RIGHT RAISED OMISSION BRACKET - 0X002E0E : EDITORIAL CORONIS - 0X002E0F : PARAGRAPHOS - 0X002E10 : FORKED PARAGRAPHOS - 0X002E11 : REVERSED FORKED PARAGRAPHOS - 0X002E12 : HYPODIASTOLE - 0X002E13 : DOTTED OBELOS - 0X002E14 : DOWNWARDS ANCORA - 0X002E15 : UPWARDS ANCORA - 0X002E16 : DOTTED RIGHT-POINTING ANGLE - 0X002E18 : INVERTED INTERROBANG - 0X002E19 : PALM BRANCH - 0X002E1B : TILDE WITH RING ABOVE - 0X002E1C : LEFT LOW PARAPHRASE BRACKET - 0X002E1D : RIGHT LOW PARAPHRASE BRACKET - 0X002E1E : TILDE WITH DOT ABOVE - 0X002E1F : TILDE WITH DOT BELOW - 0X002E20 : LEFT VERTICAL BAR WITH QUILL - 0X002E21 : RIGHT VERTICAL BAR WITH QUILL - 0X002E22 : TOP LEFT HALF BRACKET - 0X002E23 : TOP RIGHT HALF BRACKET - 0X002E24 : BOTTOM LEFT HALF BRACKET - 0X002E25 : BOTTOM RIGHT HALF BRACKET - 0X002E26 : LEFT SIDEWAYS U BRACKET - 0X002E27 : RIGHT SIDEWAYS U BRACKET - 0X002E28 : LEFT DOUBLE PARENTHESIS - 0X002E29 : RIGHT DOUBLE PARENTHESIS - 0X002E2A : TWO DOTS OVER ONE DOT PUNCTUATION - 0X002E2B : ONE DOT OVER TWO DOTS PUNCTUATION - 0X002E2C : SQUARED FOUR DOT PUNCTUATION - 0X002E2D : FIVE DOT MARK - 0X002E2E : REVERSED QUESTION MARK - 0X002E30 : RING POINT - 0X002E31 : WORD SEPARATOR MIDDLE DOT - 0X002E32 : TURNED COMMA - 0X002E33 : RAISED DOT - 0X002E34 : RAISED COMMA - 0X002E35 : TURNED SEMICOLON - 0X002E36 : DAGGER WITH LEFT GUARD - 0X002E37 : DAGGER WITH RIGHT GUARD - 0X002E38 : TURNED DAGGER - 0X002E39 : TOP HALF SECTION SIGN - 0X003001 : IDEOGRAPHIC COMMA - 0X003002 : IDEOGRAPHIC FULL STOP - 0X003003 : DITTO MARK - 0X003008 : LEFT ANGLE BRACKET - 0X003009 : RIGHT ANGLE BRACKET - 0X00300A : LEFT DOUBLE ANGLE BRACKET - 0X00300B : RIGHT DOUBLE ANGLE BRACKET - 0X00300C : LEFT CORNER BRACKET - 0X00300D : RIGHT CORNER BRACKET - 0X00300E : LEFT WHITE CORNER BRACKET - 0X00300F : RIGHT WHITE CORNER BRACKET - 0X003010 : LEFT BLACK LENTICULAR BRACKET - 0X003011 : RIGHT BLACK LENTICULAR BRACKET - 0X003014 : LEFT TORTOISE SHELL BRACKET - 0X003015 : RIGHT TORTOISE SHELL BRACKET - 0X003016 : LEFT WHITE LENTICULAR BRACKET - 0X003017 : RIGHT WHITE LENTICULAR BRACKET - 0X003018 : LEFT WHITE TORTOISE SHELL BRACKET - 0X003019 : RIGHT WHITE TORTOISE SHELL BRACKET - 0X00301A : LEFT WHITE SQUARE BRACKET - 0X00301B : RIGHT WHITE SQUARE BRACKET - 0X00301D : REVERSED DOUBLE PRIME QUOTATION MARK - 0X00301E : DOUBLE PRIME QUOTATION MARK - 0X00301F : LOW DOUBLE PRIME QUOTATION MARK - 0X00303D : PART ALTERNATION MARK - 0X0030FB : KATAKANA MIDDLE DOT - 0X00A4FE : LISU PUNCTUATION COMMA - 0X00A4FF : LISU PUNCTUATION FULL STOP - 0X00A60D : VAI COMMA - 0X00A60E : VAI FULL STOP - 0X00A60F : VAI QUESTION MARK - 0X00A673 : SLAVONIC ASTERISK - 0X00A67E : CYRILLIC KAVYKA - 0X00A6F2 : BAMUM NJAEMLI - 0X00A6F3 : BAMUM FULL STOP - 0X00A6F4 : BAMUM COLON - 0X00A6F5 : BAMUM COMMA - 0X00A6F6 : BAMUM SEMICOLON - 0X00A6F7 : BAMUM QUESTION MARK - 0X00A874 : PHAGS-PA SINGLE HEAD MARK - 0X00A875 : PHAGS-PA DOUBLE HEAD MARK - 0X00A876 : PHAGS-PA MARK SHAD - 0X00A877 : PHAGS-PA MARK DOUBLE SHAD - 0X00A8CE : SAURASHTRA DANDA - 0X00A8CF : SAURASHTRA DOUBLE DANDA - 0X00A8F8 : DEVANAGARI SIGN PUSHPIKA - 0X00A8F9 : DEVANAGARI GAP FILLER - 0X00A8FA : DEVANAGARI CARET - 0X00A92E : KAYAH LI SIGN CWI - 0X00A92F : KAYAH LI SIGN SHYA - 0X00A95F : REJANG SECTION MARK - 0X00A9C1 : JAVANESE LEFT RERENGGAN - 0X00A9C2 : JAVANESE RIGHT RERENGGAN - 0X00A9C3 : JAVANESE PADA ANDAP - 0X00A9C4 : JAVANESE PADA MADYA - 0X00A9C5 : JAVANESE PADA LUHUR - 0X00A9C6 : JAVANESE PADA WINDU - 0X00A9C7 : JAVANESE PADA PANGKAT - 0X00A9C8 : JAVANESE PADA LINGSA - 0X00A9C9 : JAVANESE PADA LUNGSI - 0X00A9CA : JAVANESE PADA ADEG - 0X00A9CB : JAVANESE PADA ADEG ADEG - 0X00A9CC : JAVANESE PADA PISELEH - 0X00A9CD : JAVANESE TURNED PADA PISELEH - 0X00A9DE : JAVANESE PADA TIRTA TUMETES - 0X00A9DF : JAVANESE PADA ISEN-ISEN - 0X00AA5C : CHAM PUNCTUATION SPIRAL - 0X00AA5D : CHAM PUNCTUATION DANDA - 0X00AA5E : CHAM PUNCTUATION DOUBLE DANDA - 0X00AA5F : CHAM PUNCTUATION TRIPLE DANDA - 0X00AADE : TAI VIET SYMBOL HO HOI - 0X00AADF : TAI VIET SYMBOL KOI KOI - 0X00AAF0 : MEETEI MAYEK CHEIKHAN - 0X00AAF1 : MEETEI MAYEK AHANG KHUDAM - 0X00ABEB : MEETEI MAYEK CHEIKHEI - 0X00FD3E : ORNATE LEFT PARENTHESIS - 0X00FD3F : ORNATE RIGHT PARENTHESIS - 0X00FE10 : PRESENTATION FORM FOR VERTICAL COMMA - 0X00FE11 : PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA - 0X00FE12 : PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP - 0X00FE13 : PRESENTATION FORM FOR VERTICAL COLON - 0X00FE14 : PRESENTATION FORM FOR VERTICAL SEMICOLON - 0X00FE15 : PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK - 0X00FE16 : PRESENTATION FORM FOR VERTICAL QUESTION MARK - 0X00FE17 : PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET - 0X00FE18 : PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET - 0X00FE19 : PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS - 0X00FE30 : PRESENTATION FORM FOR VERTICAL TWO DOT LEADER - 0X00FE35 : PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS - 0X00FE36 : PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS - 0X00FE37 : PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET - 0X00FE38 : PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET - 0X00FE39 : PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET - 0X00FE3A : PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET - 0X00FE3B : PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET - 0X00FE3C : PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET - 0X00FE3D : PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET - 0X00FE3E : PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET - 0X00FE3F : PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET - 0X00FE40 : PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET - 0X00FE41 : PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET - 0X00FE42 : PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET - 0X00FE43 : PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET - 0X00FE44 : PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET - 0X00FE45 : SESAME DOT - 0X00FE46 : WHITE SESAME DOT - 0X00FE47 : PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET - 0X00FE48 : PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET - 0X00FE49 : DASHED OVERLINE - 0X00FE4A : CENTRELINE OVERLINE - 0X00FE4B : WAVY OVERLINE - 0X00FE4C : DOUBLE WAVY OVERLINE - 0X00FE50 : SMALL COMMA - 0X00FE51 : SMALL IDEOGRAPHIC COMMA - 0X00FE52 : SMALL FULL STOP - 0X00FE54 : SMALL SEMICOLON - 0X00FE55 : SMALL COLON - 0X00FE56 : SMALL QUESTION MARK - 0X00FE57 : SMALL EXCLAMATION MARK - 0X00FE59 : SMALL LEFT PARENTHESIS - 0X00FE5A : SMALL RIGHT PARENTHESIS - 0X00FE5B : SMALL LEFT CURLY BRACKET - 0X00FE5C : SMALL RIGHT CURLY BRACKET - 0X00FE5D : SMALL LEFT TORTOISE SHELL BRACKET - 0X00FE5E : SMALL RIGHT TORTOISE SHELL BRACKET - 0X00FE5F : SMALL NUMBER SIGN - 0X00FE60 : SMALL AMPERSAND - 0X00FE61 : SMALL ASTERISK - 0X00FE68 : SMALL REVERSE SOLIDUS - 0X00FE6A : SMALL PERCENT SIGN - 0X00FE6B : SMALL COMMERCIAL AT - 0X00FF01 : FULLWIDTH EXCLAMATION MARK - 0X00FF02 : FULLWIDTH QUOTATION MARK - 0X00FF03 : FULLWIDTH NUMBER SIGN - 0X00FF05 : FULLWIDTH PERCENT SIGN - 0X00FF06 : FULLWIDTH AMPERSAND - 0X00FF07 : FULLWIDTH APOSTROPHE - 0X00FF08 : FULLWIDTH LEFT PARENTHESIS - 0X00FF09 : FULLWIDTH RIGHT PARENTHESIS - 0X00FF0A : FULLWIDTH ASTERISK - 0X00FF0C : FULLWIDTH COMMA - 0X00FF0E : FULLWIDTH FULL STOP - 0X00FF0F : FULLWIDTH SOLIDUS - 0X00FF1A : FULLWIDTH COLON - 0X00FF1B : FULLWIDTH SEMICOLON - 0X00FF1F : FULLWIDTH QUESTION MARK - 0X00FF20 : FULLWIDTH COMMERCIAL AT - 0X00FF3B : FULLWIDTH LEFT SQUARE BRACKET - 0X00FF3C : FULLWIDTH REVERSE SOLIDUS - 0X00FF3D : FULLWIDTH RIGHT SQUARE BRACKET - 0X00FF5B : FULLWIDTH LEFT CURLY BRACKET - 0X00FF5D : FULLWIDTH RIGHT CURLY BRACKET - 0X00FF5F : FULLWIDTH LEFT WHITE PARENTHESIS - 0X00FF60 : FULLWIDTH RIGHT WHITE PARENTHESIS - 0X00FF61 : HALFWIDTH IDEOGRAPHIC FULL STOP - 0X00FF62 : HALFWIDTH LEFT CORNER BRACKET - 0X00FF63 : HALFWIDTH RIGHT CORNER BRACKET - 0X00FF64 : HALFWIDTH IDEOGRAPHIC COMMA - 0X00FF65 : HALFWIDTH KATAKANA MIDDLE DOT - 0X010100 : AEGEAN WORD SEPARATOR LINE - 0X010101 : AEGEAN WORD SEPARATOR DOT - 0X010102 : AEGEAN CHECK MARK - 0X01039F : UGARITIC WORD DIVIDER - 0X0103D0 : OLD PERSIAN WORD DIVIDER - 0X010857 : IMPERIAL ARAMAIC SECTION SIGN - 0X01091F : PHOENICIAN WORD SEPARATOR - 0X01093F : LYDIAN TRIANGULAR MARK - 0X010A50 : KHAROSHTHI PUNCTUATION DOT - 0X010A51 : KHAROSHTHI PUNCTUATION SMALL CIRCLE - 0X010A52 : KHAROSHTHI PUNCTUATION CIRCLE - 0X010A53 : KHAROSHTHI PUNCTUATION CRESCENT BAR - 0X010A54 : KHAROSHTHI PUNCTUATION MANGALAM - 0X010A55 : KHAROSHTHI PUNCTUATION LOTUS - 0X010A56 : KHAROSHTHI PUNCTUATION DANDA - 0X010A57 : KHAROSHTHI PUNCTUATION DOUBLE DANDA - 0X010A58 : KHAROSHTHI PUNCTUATION LINES - 0X010A7F : OLD SOUTH ARABIAN NUMERIC INDICATOR - 0X010B39 : AVESTAN ABBREVIATION MARK - 0X010B3A : TINY TWO DOTS OVER ONE DOT PUNCTUATION - 0X010B3B : SMALL TWO DOTS OVER ONE DOT PUNCTUATION - 0X010B3C : LARGE TWO DOTS OVER ONE DOT PUNCTUATION - 0X010B3D : LARGE ONE DOT OVER TWO DOTS PUNCTUATION - 0X010B3E : LARGE TWO RINGS OVER ONE RING PUNCTUATION - 0X010B3F : LARGE ONE RING OVER TWO RINGS PUNCTUATION - 0X011047 : BRAHMI DANDA - 0X011048 : BRAHMI DOUBLE DANDA - 0X011049 : BRAHMI PUNCTUATION DOT - 0X01104A : BRAHMI PUNCTUATION DOUBLE DOT - 0X01104B : BRAHMI PUNCTUATION LINE - 0X01104C : BRAHMI PUNCTUATION CRESCENT BAR - 0X01104D : BRAHMI PUNCTUATION LOTUS - 0X0110BB : KAITHI ABBREVIATION SIGN - 0X0110BC : KAITHI ENUMERATION SIGN - 0X0110BE : KAITHI SECTION MARK - 0X0110BF : KAITHI DOUBLE SECTION MARK - 0X0110C0 : KAITHI DANDA - 0X0110C1 : KAITHI DOUBLE DANDA - 0X011140 : CHAKMA SECTION MARK - 0X011141 : CHAKMA DANDA - 0X011142 : CHAKMA DOUBLE DANDA - 0X011143 : CHAKMA QUESTION MARK - 0X0111C5 : SHARADA DANDA - 0X0111C6 : SHARADA DOUBLE DANDA - 0X0111C7 : SHARADA ABBREVIATION SIGN - 0X0111C8 : SHARADA SEPARATOR - 0X012470 : CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER - 0X012471 : CUNEIFORM PUNCTUATION SIGN VERTICAL COLON - 0X012472 : CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON - 0X012473 : CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON -*/ - -#if (defined(IS_LITTLE_ENDIAN) && ALU_SIZE == 64) -// Precompiled CCMap for Little Endian(64bit) -#define gPuncCharsCCMapExt_SIZE 1028 -#define gPuncCharsCCMapExt_INITIALIZER \ -/* EXTFLG */ 0x0000,0x0000,0x0001,0x02E0, \ -/* 000000 */ 0x0030,0x00F0,0x0190,0x0210,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0230,0x0010,0x0010,0x0010,0x0010,0x02A0, \ -/* 000010 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000020 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000030 */ 0x0040,0x0020,0x0020,0x0050,0x0020,0x0060,0x0070,0x0080, \ - 0x0090,0x00A0,0x00B0,0x0020,0x0020,0x00C0,0x00D0,0x00E0, \ -/* 000040 */ 0x0000,0x0000,0xD7EE,0x8C00,0x0001,0x3800,0x0000,0x2800, \ - 0x0000,0x0000,0x0882,0x88C0,0x0000,0x0000,0x0000,0x0000, \ -/* 000050 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000, \ - 0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000060 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0xFC00,0x0000,0x0000, \ - 0x0200,0x0000,0x0000,0x0000,0x0049,0x0000,0x0000,0x0018, \ -/* 000070 */ 0x3600,0xC800,0x0000,0x0000,0x0000,0x0000,0x3C00,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0010,0x0000,0x0000, \ -/* 000080 */ 0x3FFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380, \ -/* 000090 */ 0x0000,0x0000,0x0000,0x7FFF,0x0000,0x4000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000a0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x0001, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000b0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001, \ -/* 0000c0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0010, \ -/* 0000d0 */ 0x0000,0x0000,0x0000,0x0000,0x8000,0x0C00,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000e0 */ 0xFFF0,0x0017,0x0000,0x3C00,0x0000,0x0000,0x0000,0x0000, \ - 0x0020,0x0000,0x0000,0x0000,0x0000,0x061F,0x0000,0x0000, \ -/* 0000f0 */ 0x0100,0x0020,0x0020,0x0110,0x0020,0x0020,0x0120,0x0130, \ - 0x0140,0x0150,0x0160,0x0170,0x0180,0x0020,0x0020,0x0020, \ -/* 000100 */ 0x0000,0x0000,0x0000,0x0000,0xFC00,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800, \ -/* 000110 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01FF,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000120 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x0000, \ - 0x0000,0x1800,0x0000,0x0000,0x0000,0x0000,0x3800,0x0000, \ -/* 000130 */ 0x0000,0x0000,0x0000,0x0060,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0770,0x0000,0x0000, \ -/* 000140 */ 0x07BF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000150 */ 0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000160 */ 0x0000,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x3F7F,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000170 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0xFC00,0x0001,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xF000, \ -/* 000180 */ 0x0000,0x0000,0x0000,0xF800,0x0000,0x0000,0x0000,0xC000, \ - 0x0000,0x0000,0x0000,0x0000,0x00FF,0x0008,0x0000,0x0000, \ -/* 000190 */ 0x01A0,0x0020,0x0020,0x01B0,0x0020,0x0020,0x0020,0x01C0, \ - 0x0020,0x01D0,0x0020,0x0020,0x01E0,0x01F0,0x0200,0x0020, \ -/* 0001a0 */ 0x0000,0xFFC0,0x00FF,0x7FFF,0xFFEE,0x7FEB,0x0000,0x6000, \ - 0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0001b0 */ 0x0000,0x0000,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0001c0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFF00,0x003F, \ - 0x0000,0x0000,0x0000,0x0000,0x0060,0x0000,0xFFC0,0x0000, \ -/* 0001d0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0xFFF8,0x01FF,0x0000,0x0000,0x0000,0x0F00,0x0000,0x3000, \ -/* 0001e0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xDE00, \ -/* 0001f0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000200 */ 0xFFFF,0xFB7F,0x7FFF,0x03FF,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000210 */ 0x0220,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000220 */ 0xFF0E,0xEFF3,0x0000,0x2000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800, \ -/* 000230 */ 0x0020,0x0020,0x0020,0x0020,0x0240,0x0020,0x0250,0x0020, \ - 0x0260,0x0270,0x0280,0x0290,0x0020,0x0020,0x0020,0x0020, \ -/* 000240 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xC000, \ -/* 000250 */ 0xE000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4008, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00FC, \ -/* 000260 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00F0, \ - 0x0000,0x0000,0x0000,0x0000,0xC000,0x0000,0x0000,0x0700, \ -/* 000270 */ 0x0000,0x0000,0xC000,0x0000,0x0000,0x8000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x3FFE,0xC000,0x0000,0x0000, \ -/* 000280 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0xF000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0xC000,0x0000,0x0003, \ -/* 000290 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0000, \ -/* 0002a0 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x02B0,0x02C0,0x02D0, \ -/* 0002b0 */ 0x0000,0x0000,0x0000,0xC000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002c0 */ 0x0000,0x03FF,0x0000,0xFFE1,0x1FFF,0xFEF7,0x0D03,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002d0 */ 0xD7EE,0x8C00,0x0001,0x3800,0x0000,0xA800,0x003F,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002e0 */ 0x0310,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000, \ - 0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000, \ -/* 0002f0 */ 0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000, \ - 0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000, \ -/* 000300 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000310 */ 0x0030,0x00A0,0x00D0,0x0010,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010, \ -/* 000320 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000330 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000340 */ 0x0020,0x0040,0x0020,0x0050,0x0020,0x0020,0x0020,0x0020, \ - 0x0060,0x0070,0x0080,0x0090,0x0020,0x0020,0x0020,0x0020, \ -/* 000350 */ 0x0007,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000360 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x8000,0x0000,0x0000,0x0000,0x0001,0x0000,0x0000, \ -/* 000370 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000380 */ 0x0000,0x8000,0x0000,0x8000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000390 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x01FF,0x0000,0x8000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0003a0 */ 0x0000,0x0000,0x0000,0xFE00,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0003b0 */ 0x00B0,0x00C0,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 0003c0 */ 0x0000,0x0000,0x0000,0x0000,0x3F80,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0xD800,0x0003,0x0000,0x0000,0x0000, \ -/* 0003d0 */ 0x0000,0x0000,0x0000,0x0000,0x000F,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x01E0,0x0000,0x0000,0x0000, \ -/* 0003e0 */ 0x0020,0x0020,0x0020,0x0020,0x00E0,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 0003f0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000F, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -#elif defined(IS_LITTLE_ENDIAN) -// Precompiled CCMap for Little Endian(16/32bit) -#define gPuncCharsCCMapExt_SIZE 1026 -#define gPuncCharsCCMapExt_INITIALIZER \ -/* EXTFLG */ 0x0001,0x02E0, \ -/* 000000 */ 0x0030,0x00F0,0x0190,0x0210,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0230,0x0010,0x0010,0x0010,0x0010,0x02A0, \ -/* 000010 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000020 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000030 */ 0x0040,0x0020,0x0020,0x0050,0x0020,0x0060,0x0070,0x0080, \ - 0x0090,0x00A0,0x00B0,0x0020,0x0020,0x00C0,0x00D0,0x00E0, \ -/* 000040 */ 0x0000,0x0000,0xD7EE,0x8C00,0x0001,0x3800,0x0000,0x2800, \ - 0x0000,0x0000,0x0882,0x88C0,0x0000,0x0000,0x0000,0x0000, \ -/* 000050 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000, \ - 0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000060 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0xFC00,0x0000,0x0000, \ - 0x0200,0x0000,0x0000,0x0000,0x0049,0x0000,0x0000,0x0018, \ -/* 000070 */ 0x3600,0xC800,0x0000,0x0000,0x0000,0x0000,0x3C00,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0010,0x0000,0x0000, \ -/* 000080 */ 0x3FFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380, \ -/* 000090 */ 0x0000,0x0000,0x0000,0x7FFF,0x0000,0x4000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000a0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x0001, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000b0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001, \ -/* 0000c0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0010, \ -/* 0000d0 */ 0x0000,0x0000,0x0000,0x0000,0x8000,0x0C00,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000e0 */ 0xFFF0,0x0017,0x0000,0x3C00,0x0000,0x0000,0x0000,0x0000, \ - 0x0020,0x0000,0x0000,0x0000,0x0000,0x061F,0x0000,0x0000, \ -/* 0000f0 */ 0x0100,0x0020,0x0020,0x0110,0x0020,0x0020,0x0120,0x0130, \ - 0x0140,0x0150,0x0160,0x0170,0x0180,0x0020,0x0020,0x0020, \ -/* 000100 */ 0x0000,0x0000,0x0000,0x0000,0xFC00,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800, \ -/* 000110 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01FF,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000120 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x0000, \ - 0x0000,0x1800,0x0000,0x0000,0x0000,0x0000,0x3800,0x0000, \ -/* 000130 */ 0x0000,0x0000,0x0000,0x0060,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0770,0x0000,0x0000, \ -/* 000140 */ 0x07BF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000150 */ 0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000160 */ 0x0000,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x3F7F,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000170 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0xFC00,0x0001,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xF000, \ -/* 000180 */ 0x0000,0x0000,0x0000,0xF800,0x0000,0x0000,0x0000,0xC000, \ - 0x0000,0x0000,0x0000,0x0000,0x00FF,0x0008,0x0000,0x0000, \ -/* 000190 */ 0x01A0,0x0020,0x0020,0x01B0,0x0020,0x0020,0x0020,0x01C0, \ - 0x0020,0x01D0,0x0020,0x0020,0x01E0,0x01F0,0x0200,0x0020, \ -/* 0001a0 */ 0x0000,0xFFC0,0x00FF,0x7FFF,0xFFEE,0x7FEB,0x0000,0x6000, \ - 0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0001b0 */ 0x0000,0x0000,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0001c0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFF00,0x003F, \ - 0x0000,0x0000,0x0000,0x0000,0x0060,0x0000,0xFFC0,0x0000, \ -/* 0001d0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0xFFF8,0x01FF,0x0000,0x0000,0x0000,0x0F00,0x0000,0x3000, \ -/* 0001e0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xDE00, \ -/* 0001f0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000200 */ 0xFFFF,0xFB7F,0x7FFF,0x03FF,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000210 */ 0x0220,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000220 */ 0xFF0E,0xEFF3,0x0000,0x2000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800, \ -/* 000230 */ 0x0020,0x0020,0x0020,0x0020,0x0240,0x0020,0x0250,0x0020, \ - 0x0260,0x0270,0x0280,0x0290,0x0020,0x0020,0x0020,0x0020, \ -/* 000240 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xC000, \ -/* 000250 */ 0xE000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4008, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00FC, \ -/* 000260 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00F0, \ - 0x0000,0x0000,0x0000,0x0000,0xC000,0x0000,0x0000,0x0700, \ -/* 000270 */ 0x0000,0x0000,0xC000,0x0000,0x0000,0x8000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x3FFE,0xC000,0x0000,0x0000, \ -/* 000280 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0xF000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0xC000,0x0000,0x0003, \ -/* 000290 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0000, \ -/* 0002a0 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x02B0,0x02C0,0x02D0, \ -/* 0002b0 */ 0x0000,0x0000,0x0000,0xC000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002c0 */ 0x0000,0x03FF,0x0000,0xFFE1,0x1FFF,0xFEF7,0x0D03,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002d0 */ 0xD7EE,0x8C00,0x0001,0x3800,0x0000,0xA800,0x003F,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002e0 */ 0x0310,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000, \ - 0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000, \ -/* 0002f0 */ 0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000, \ - 0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000, \ -/* 000300 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000310 */ 0x0030,0x00A0,0x00D0,0x0010,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010, \ -/* 000320 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000330 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000340 */ 0x0020,0x0040,0x0020,0x0050,0x0020,0x0020,0x0020,0x0020, \ - 0x0060,0x0070,0x0080,0x0090,0x0020,0x0020,0x0020,0x0020, \ -/* 000350 */ 0x0007,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000360 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x8000,0x0000,0x0000,0x0000,0x0001,0x0000,0x0000, \ -/* 000370 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000380 */ 0x0000,0x8000,0x0000,0x8000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000390 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x01FF,0x0000,0x8000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0003a0 */ 0x0000,0x0000,0x0000,0xFE00,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0003b0 */ 0x00B0,0x00C0,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 0003c0 */ 0x0000,0x0000,0x0000,0x0000,0x3F80,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0xD800,0x0003,0x0000,0x0000,0x0000, \ -/* 0003d0 */ 0x0000,0x0000,0x0000,0x0000,0x000F,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x01E0,0x0000,0x0000,0x0000, \ -/* 0003e0 */ 0x0020,0x0020,0x0020,0x0020,0x00E0,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 0003f0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000F, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -#elif (ALU_SIZE == 16) -// Precompiled CCMap for Big Endian(16bit) -#define gPuncCharsCCMapExt_SIZE 1026 -#define gPuncCharsCCMapExt_INITIALIZER \ -/* EXTFLG */ 0x0001,0x02E0, \ -/* 000000 */ 0x0030,0x00F0,0x0190,0x0210,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0230,0x0010,0x0010,0x0010,0x0010,0x02A0, \ -/* 000010 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000020 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000030 */ 0x0040,0x0020,0x0020,0x0050,0x0020,0x0060,0x0070,0x0080, \ - 0x0090,0x00A0,0x00B0,0x0020,0x0020,0x00C0,0x00D0,0x00E0, \ -/* 000040 */ 0x0000,0x0000,0xD7EE,0x8C00,0x0001,0x3800,0x0000,0x2800, \ - 0x0000,0x0000,0x0882,0x88C0,0x0000,0x0000,0x0000,0x0000, \ -/* 000050 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000, \ - 0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000060 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0xFC00,0x0000,0x0000, \ - 0x0200,0x0000,0x0000,0x0000,0x0049,0x0000,0x0000,0x0018, \ -/* 000070 */ 0x3600,0xC800,0x0000,0x0000,0x0000,0x0000,0x3C00,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0010,0x0000,0x0000, \ -/* 000080 */ 0x3FFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380, \ -/* 000090 */ 0x0000,0x0000,0x0000,0x7FFF,0x0000,0x4000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000a0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x0001, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000b0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001, \ -/* 0000c0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0010, \ -/* 0000d0 */ 0x0000,0x0000,0x0000,0x0000,0x8000,0x0C00,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000e0 */ 0xFFF0,0x0017,0x0000,0x3C00,0x0000,0x0000,0x0000,0x0000, \ - 0x0020,0x0000,0x0000,0x0000,0x0000,0x061F,0x0000,0x0000, \ -/* 0000f0 */ 0x0100,0x0020,0x0020,0x0110,0x0020,0x0020,0x0120,0x0130, \ - 0x0140,0x0150,0x0160,0x0170,0x0180,0x0020,0x0020,0x0020, \ -/* 000100 */ 0x0000,0x0000,0x0000,0x0000,0xFC00,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800, \ -/* 000110 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01FF,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000120 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x0000, \ - 0x0000,0x1800,0x0000,0x0000,0x0000,0x0000,0x3800,0x0000, \ -/* 000130 */ 0x0000,0x0000,0x0000,0x0060,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0770,0x0000,0x0000, \ -/* 000140 */ 0x07BF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000150 */ 0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000160 */ 0x0000,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x3F7F,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000170 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0xFC00,0x0001,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xF000, \ -/* 000180 */ 0x0000,0x0000,0x0000,0xF800,0x0000,0x0000,0x0000,0xC000, \ - 0x0000,0x0000,0x0000,0x0000,0x00FF,0x0008,0x0000,0x0000, \ -/* 000190 */ 0x01A0,0x0020,0x0020,0x01B0,0x0020,0x0020,0x0020,0x01C0, \ - 0x0020,0x01D0,0x0020,0x0020,0x01E0,0x01F0,0x0200,0x0020, \ -/* 0001a0 */ 0x0000,0xFFC0,0x00FF,0x7FFF,0xFFEE,0x7FEB,0x0000,0x6000, \ - 0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0001b0 */ 0x0000,0x0000,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0001c0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFF00,0x003F, \ - 0x0000,0x0000,0x0000,0x0000,0x0060,0x0000,0xFFC0,0x0000, \ -/* 0001d0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0xFFF8,0x01FF,0x0000,0x0000,0x0000,0x0F00,0x0000,0x3000, \ -/* 0001e0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xDE00, \ -/* 0001f0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000200 */ 0xFFFF,0xFB7F,0x7FFF,0x03FF,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000210 */ 0x0220,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000220 */ 0xFF0E,0xEFF3,0x0000,0x2000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800, \ -/* 000230 */ 0x0020,0x0020,0x0020,0x0020,0x0240,0x0020,0x0250,0x0020, \ - 0x0260,0x0270,0x0280,0x0290,0x0020,0x0020,0x0020,0x0020, \ -/* 000240 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xC000, \ -/* 000250 */ 0xE000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4008, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00FC, \ -/* 000260 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00F0, \ - 0x0000,0x0000,0x0000,0x0000,0xC000,0x0000,0x0000,0x0700, \ -/* 000270 */ 0x0000,0x0000,0xC000,0x0000,0x0000,0x8000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x3FFE,0xC000,0x0000,0x0000, \ -/* 000280 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0xF000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0xC000,0x0000,0x0003, \ -/* 000290 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0000, \ -/* 0002a0 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x02B0,0x02C0,0x02D0, \ -/* 0002b0 */ 0x0000,0x0000,0x0000,0xC000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002c0 */ 0x0000,0x03FF,0x0000,0xFFE1,0x1FFF,0xFEF7,0x0D03,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002d0 */ 0xD7EE,0x8C00,0x0001,0x3800,0x0000,0xA800,0x003F,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002e0 */ 0x0000,0x0310,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300, \ - 0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300, \ -/* 0002f0 */ 0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300, \ - 0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300, \ -/* 000300 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000310 */ 0x0030,0x00A0,0x00D0,0x0010,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010, \ -/* 000320 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000330 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000340 */ 0x0020,0x0040,0x0020,0x0050,0x0020,0x0020,0x0020,0x0020, \ - 0x0060,0x0070,0x0080,0x0090,0x0020,0x0020,0x0020,0x0020, \ -/* 000350 */ 0x0007,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000360 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x8000,0x0000,0x0000,0x0000,0x0001,0x0000,0x0000, \ -/* 000370 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000380 */ 0x0000,0x8000,0x0000,0x8000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000390 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x01FF,0x0000,0x8000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0003a0 */ 0x0000,0x0000,0x0000,0xFE00,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0003b0 */ 0x00B0,0x00C0,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 0003c0 */ 0x0000,0x0000,0x0000,0x0000,0x3F80,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0xD800,0x0003,0x0000,0x0000,0x0000, \ -/* 0003d0 */ 0x0000,0x0000,0x0000,0x0000,0x000F,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x01E0,0x0000,0x0000,0x0000, \ -/* 0003e0 */ 0x0020,0x0020,0x0020,0x0020,0x00E0,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 0003f0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000F, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -#elif (ALU_SIZE == 32) -// Precompiled CCMap for Big Endian(32bit) -#define gPuncCharsCCMapExt_SIZE 1026 -#define gPuncCharsCCMapExt_INITIALIZER \ -/* EXTFLG */ 0x0001,0x02E0, \ -/* 000000 */ 0x0030,0x00F0,0x0190,0x0210,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0230,0x0010,0x0010,0x0010,0x0010,0x02A0, \ -/* 000010 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000020 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000030 */ 0x0040,0x0020,0x0020,0x0050,0x0020,0x0060,0x0070,0x0080, \ - 0x0090,0x00A0,0x00B0,0x0020,0x0020,0x00C0,0x00D0,0x00E0, \ -/* 000040 */ 0x0000,0x0000,0x8C00,0xD7EE,0x3800,0x0001,0x2800,0x0000, \ - 0x0000,0x0000,0x88C0,0x0882,0x0000,0x0000,0x0000,0x0000, \ -/* 000050 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x0000, \ - 0x0000,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000060 */ 0x0000,0x0000,0x0000,0x0000,0xFC00,0x0000,0x0000,0x0000, \ - 0x0000,0x0200,0x0000,0x0000,0x0000,0x0049,0x0018,0x0000, \ -/* 000070 */ 0xC800,0x3600,0x0000,0x0000,0x0000,0x0000,0x0000,0x3C00, \ - 0x0000,0x0000,0x0000,0x0000,0x0010,0x0000,0x0000,0x0000, \ -/* 000080 */ 0x0000,0x3FFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0000, \ -/* 000090 */ 0x0000,0x0000,0x7FFF,0x0000,0x4000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000a0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0x0030, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000b0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0x0000, \ -/* 0000c0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0010,0x0000, \ -/* 0000d0 */ 0x0000,0x0000,0x0000,0x0000,0x0C00,0x8000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000e0 */ 0x0017,0xFFF0,0x3C00,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0020,0x0000,0x0000,0x061F,0x0000,0x0000,0x0000, \ -/* 0000f0 */ 0x0100,0x0020,0x0020,0x0110,0x0020,0x0020,0x0120,0x0130, \ - 0x0140,0x0150,0x0160,0x0170,0x0180,0x0020,0x0020,0x0020, \ -/* 000100 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0xFC00,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0000, \ -/* 000110 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01FF, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000120 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000, \ - 0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800, \ -/* 000130 */ 0x0000,0x0000,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0770,0x0000,0x0000,0x0000, \ -/* 000140 */ 0x0000,0x07BF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000150 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000160 */ 0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x3F7F,0x0000,0x0000,0x0000,0x0000, \ -/* 000170 */ 0x0000,0x0000,0x0000,0x0000,0xFC00,0x0000,0x0000,0x0001, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xF000,0x0000, \ -/* 000180 */ 0x0000,0x0000,0xF800,0x0000,0x0000,0x0000,0xC000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0008,0x00FF,0x0000,0x0000, \ -/* 000190 */ 0x01A0,0x0020,0x0020,0x01B0,0x0020,0x0020,0x0020,0x01C0, \ - 0x0020,0x01D0,0x0020,0x0020,0x01E0,0x01F0,0x0200,0x0020, \ -/* 0001a0 */ 0xFFC0,0x0000,0x7FFF,0x00FF,0x7FEB,0xFFEE,0x6000,0x0000, \ - 0x0000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0001b0 */ 0x0000,0x0000,0x0000,0x0600,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0001c0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x003F,0xFF00, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0000,0xFFC0, \ -/* 0001d0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x01FF,0xFFF8,0x0000,0x0000,0x0F00,0x0000,0x3000,0x0000, \ -/* 0001e0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xDE00,0x0000, \ -/* 0001f0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000200 */ 0xFB7F,0xFFFF,0x03FF,0x7FFF,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000210 */ 0x0220,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000220 */ 0xEFF3,0xFF0E,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0000, \ -/* 000230 */ 0x0020,0x0020,0x0020,0x0020,0x0240,0x0020,0x0250,0x0020, \ - 0x0260,0x0270,0x0280,0x0290,0x0020,0x0020,0x0020,0x0020, \ -/* 000240 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xC000,0x0000, \ -/* 000250 */ 0x0000,0xE000,0x0000,0x0000,0x0000,0x0000,0x4008,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00FC,0x0000, \ -/* 000260 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00F0,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0xC000,0x0700,0x0000, \ -/* 000270 */ 0x0000,0x0000,0x0000,0xC000,0x8000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0xC000,0x3FFE,0x0000,0x0000, \ -/* 000280 */ 0x0000,0x0000,0x0000,0x0000,0xF000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0xC000,0x0000,0x0003,0x0000, \ -/* 000290 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800, \ -/* 0002a0 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x02B0,0x02C0,0x02D0, \ -/* 0002b0 */ 0x0000,0x0000,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002c0 */ 0x03FF,0x0000,0xFFE1,0x0000,0xFEF7,0x1FFF,0x0000,0x0D03, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002d0 */ 0x8C00,0xD7EE,0x3800,0x0001,0xA800,0x0000,0x0000,0x003F, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002e0 */ 0x0000,0x0310,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300, \ - 0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300, \ -/* 0002f0 */ 0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300, \ - 0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300, \ -/* 000300 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000310 */ 0x0030,0x00A0,0x00D0,0x0010,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010, \ -/* 000320 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000330 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000340 */ 0x0020,0x0040,0x0020,0x0050,0x0020,0x0020,0x0020,0x0020, \ - 0x0060,0x0070,0x0080,0x0090,0x0020,0x0020,0x0020,0x0020, \ -/* 000350 */ 0x0000,0x0007,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000360 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x8000,0x0000,0x0000,0x0000,0x0001,0x0000,0x0000,0x0000, \ -/* 000370 */ 0x0000,0x0000,0x0000,0x0000,0x0080,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000380 */ 0x8000,0x0000,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000390 */ 0x0000,0x0000,0x0000,0x0000,0x01FF,0x0000,0x8000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0003a0 */ 0x0000,0x0000,0xFE00,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0003b0 */ 0x00B0,0x00C0,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 0003c0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x3F80,0x0000,0x0000, \ - 0x0000,0x0000,0xD800,0x0000,0x0000,0x0003,0x0000,0x0000, \ -/* 0003d0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x000F,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x01E0,0x0000,0x0000, \ -/* 0003e0 */ 0x0020,0x0020,0x0020,0x0020,0x00E0,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 0003f0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000F,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -#elif (ALU_SIZE == 64) -// Precompiled CCMap for Big Endian(64bit) -#define gPuncCharsCCMapExt_SIZE 1028 -#define gPuncCharsCCMapExt_INITIALIZER \ -/* EXTFLG */ 0x0000,0x0000,0x0001,0x02E0, \ -/* 000000 */ 0x0030,0x00F0,0x0190,0x0210,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0230,0x0010,0x0010,0x0010,0x0010,0x02A0, \ -/* 000010 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000020 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000030 */ 0x0040,0x0020,0x0020,0x0050,0x0020,0x0060,0x0070,0x0080, \ - 0x0090,0x00A0,0x00B0,0x0020,0x0020,0x00C0,0x00D0,0x00E0, \ -/* 000040 */ 0x8C00,0xD7EE,0x0000,0x0000,0x2800,0x0000,0x3800,0x0001, \ - 0x88C0,0x0882,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000050 */ 0x0000,0x0000,0x0000,0x0000,0x4000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0080,0x0000,0x0000,0x0000,0x0000, \ -/* 000060 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFC00,0x0000, \ - 0x0000,0x0000,0x0000,0x0200,0x0018,0x0000,0x0000,0x0049, \ -/* 000070 */ 0x0000,0x0000,0xC800,0x3600,0x0000,0x3C00,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0010,0x0000, \ -/* 000080 */ 0x0000,0x0000,0x0000,0x3FFF,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0380,0x0000,0x0000,0x0000, \ -/* 000090 */ 0x7FFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000a0 */ 0x0000,0x0000,0x0000,0x0000,0x0001,0x0030,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000b0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0001,0x0000,0x0000,0x0000, \ -/* 0000c0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0010,0x0000,0x0000,0x0000, \ -/* 0000d0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0C00,0x8000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0000e0 */ 0x3C00,0x0000,0x0017,0xFFF0,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0020,0x0000,0x0000,0x061F,0x0000, \ -/* 0000f0 */ 0x0100,0x0020,0x0020,0x0110,0x0020,0x0020,0x0120,0x0130, \ - 0x0140,0x0150,0x0160,0x0170,0x0180,0x0020,0x0020,0x0020, \ -/* 000100 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFC00, \ - 0x0000,0x0000,0x0000,0x0000,0x0800,0x0000,0x0000,0x0000, \ -/* 000110 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x01FF,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000120 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x0000,0x0000, \ - 0x0000,0x0000,0x1800,0x0000,0x0000,0x3800,0x0000,0x0000, \ -/* 000130 */ 0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0770,0x0000, \ -/* 000140 */ 0x0000,0x0000,0x0000,0x07BF,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000150 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0030, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000160 */ 0x0000,0x0000,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x3F7F,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000170 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0xFC00,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0xF000,0x0000,0x0000,0x0000, \ -/* 000180 */ 0xF800,0x0000,0x0000,0x0000,0xC000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0008,0x00FF, \ -/* 000190 */ 0x01A0,0x0020,0x0020,0x01B0,0x0020,0x0020,0x0020,0x01C0, \ - 0x0020,0x01D0,0x0020,0x0020,0x01E0,0x01F0,0x0200,0x0020, \ -/* 0001a0 */ 0x7FFF,0x00FF,0xFFC0,0x0000,0x6000,0x0000,0x7FEB,0xFFEE, \ - 0x0000,0x0000,0x0000,0x6000,0x0000,0x0000,0x0000,0x0000, \ -/* 0001b0 */ 0x0000,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0001c0 */ 0x0000,0x0000,0x0000,0x0000,0x003F,0xFF00,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0xFFC0,0x0000,0x0060, \ -/* 0001d0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x01FF,0xFFF8,0x3000,0x0000,0x0F00,0x0000, \ -/* 0001e0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0xDE00,0x0000,0x0000,0x0000, \ -/* 0001f0 */ 0x0000,0x0000,0x0000,0x0000,0x0001,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000200 */ 0x03FF,0x7FFF,0xFB7F,0xFFFF,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000210 */ 0x0220,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000220 */ 0x2000,0x0000,0xEFF3,0xFF0E,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0800,0x0000,0x0000,0x0000, \ -/* 000230 */ 0x0020,0x0020,0x0020,0x0020,0x0240,0x0020,0x0250,0x0020, \ - 0x0260,0x0270,0x0280,0x0290,0x0020,0x0020,0x0020,0x0020, \ -/* 000240 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0xC000,0x0000,0x0000,0x0000, \ -/* 000250 */ 0x0000,0x0000,0x0000,0xE000,0x4008,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x00FC,0x0000,0x0000,0x0000, \ -/* 000260 */ 0x0000,0x0000,0x0000,0x0000,0x00F0,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0700,0x0000,0x0000,0xC000, \ -/* 000270 */ 0x0000,0xC000,0x0000,0x0000,0x0000,0x0000,0x8000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xC000,0x3FFE, \ -/* 000280 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xF000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0003,0x0000,0xC000,0x0000, \ -/* 000290 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0000,0x0000, \ -/* 0002a0 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x02B0,0x02C0,0x02D0, \ -/* 0002b0 */ 0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002c0 */ 0xFFE1,0x0000,0x03FF,0x0000,0x0000,0x0D03,0xFEF7,0x1FFF, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002d0 */ 0x3800,0x0001,0x8C00,0xD7EE,0x0000,0x003F,0xA800,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0002e0 */ 0x0000,0x0310,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300, \ - 0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300, \ -/* 0002f0 */ 0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300, \ - 0x0000,0x0300,0x0000,0x0300,0x0000,0x0300,0x0000,0x0300, \ -/* 000300 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000310 */ 0x0030,0x00A0,0x00D0,0x0010,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010, \ -/* 000320 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000330 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000340 */ 0x0020,0x0040,0x0020,0x0050,0x0020,0x0020,0x0020,0x0020, \ - 0x0060,0x0070,0x0080,0x0090,0x0020,0x0020,0x0020,0x0020, \ -/* 000350 */ 0x0000,0x0000,0x0000,0x0007,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000360 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x8000,0x0000,0x0000,0x0000,0x0001,0x0000, \ -/* 000370 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000380 */ 0x8000,0x0000,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000390 */ 0x0000,0x0000,0x0000,0x0000,0x8000,0x0000,0x01FF,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0003a0 */ 0xFE00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 0003b0 */ 0x00B0,0x00C0,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 0003c0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3F80, \ - 0xD800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0003, \ -/* 0003d0 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000F, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01E0, \ -/* 0003e0 */ 0x0020,0x0020,0x0020,0x0020,0x00E0,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 0003f0 */ 0x0000,0x0000,0x0000,0x0000,0x000F,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -#else -#error "We don't support this architecture." -#endif - diff --git a/layout/printing/nsPrintEngine.cpp b/layout/printing/nsPrintEngine.cpp index 2331ce35c47..08affc70ffc 100644 --- a/layout/printing/nsPrintEngine.cpp +++ b/layout/printing/nsPrintEngine.cpp @@ -88,7 +88,6 @@ static const char sPrintSettingsServiceContractID[] = "@mozilla.org/gfx/printset // Print error dialog #include "nsIPrompt.h" #include "nsIWindowWatcher.h" -#include "nsIStringBundle.h" // Printing Prompts #include "nsIPrintingPromptService.h" @@ -106,7 +105,6 @@ static const char kPrintingPromptService[] = "@mozilla.org/embedcomp/printingpro // Misc #include "nsISupportsUtils.h" -#include "nsIFrame.h" #include "nsIScriptContext.h" #include "nsILinkHandler.h" #include "nsIDOMDocument.h" @@ -141,7 +139,6 @@ static const char kPrintingPromptService[] = "@mozilla.org/embedcomp/printingpro #include "nsIDocShellTreeNode.h" #include "nsIDocShellTreeOwner.h" #include "nsIWebBrowserChrome.h" -#include "nsIDocShell.h" #include "nsIBaseWindow.h" #include "nsILayoutHistoryState.h" #include "nsFrameManager.h" @@ -156,7 +153,6 @@ static const char kPrintingPromptService[] = "@mozilla.org/embedcomp/printingpro #include "nsIContentViewer.h" #include "nsIDocumentViewerPrint.h" -#include "nsPIDOMWindow.h" #include "nsFocusManager.h" #include "nsRange.h" #include "nsCDefaultURIFixup.h" diff --git a/layout/reftests/svg/smil/sort/sort-additive-1.svg b/layout/reftests/svg/smil/sort/sort-additive-1.svg index 4e6b0689817..53f452f0041 100644 --- a/layout/reftests/svg/smil/sort/sort-additive-1.svg +++ b/layout/reftests/svg/smil/sort/sort-additive-1.svg @@ -1,40 +1,18 @@ + class="reftest-wait"> diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index b3814a413c4..3f5451773ad 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -60,7 +60,6 @@ #include "pldhash.h" #include "nsHashtable.h" #include "nsICSSPseudoComparator.h" -#include "nsCSSRuleProcessor.h" #include "mozilla/css/StyleRule.h" #include "mozilla/css/GroupRule.h" #include "nsIDocument.h" diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 1093d418c67..949a46e9608 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -82,8 +82,6 @@ #include "nsPrintfCString.h" #include "mozilla/Util.h" -#include "mozilla/Util.h" - #if defined(_MSC_VER) || defined(__MINGW32__) #include #ifdef _MSC_VER diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index 39e22b2d216..803247c85f1 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -38,7 +38,6 @@ #include "nsTableFrame.h" #include "nsTableColFrame.h" #include "nsTableCellFrame.h" -#include "nsTableFrame.h" #include "nsTableRowGroupFrame.h" #include "nsTablePainter.h" #include "nsStyleContext.h" diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 0754f482fbc..53062d11451 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -58,7 +58,6 @@ #include "nsPresContext.h" #include "nsCSSRendering.h" -#include "nsStyleConsts.h" #include "nsGkAtoms.h" #include "nsCSSAnonBoxes.h" #include "nsIPresShell.h" @@ -66,7 +65,6 @@ #include "nsIDOMHTMLElement.h" #include "nsIDOMHTMLBodyElement.h" #include "nsFrameManager.h" -#include "nsCSSRendering.h" #include "nsLayoutErrors.h" #include "nsAutoPtr.h" #include "nsCSSFrameConstructor.h" diff --git a/layout/xul/base/src/nsBoxFrame.cpp b/layout/xul/base/src/nsBoxFrame.cpp index c9d07056389..476a9cd0877 100644 --- a/layout/xul/base/src/nsBoxFrame.cpp +++ b/layout/xul/base/src/nsBoxFrame.cpp @@ -97,7 +97,6 @@ #include "mozilla/Preferences.h" // Needed for Print Preview -#include "nsIDocument.h" #include "nsIURI.h" using namespace mozilla; diff --git a/layout/xul/base/src/nsBoxObject.cpp b/layout/xul/base/src/nsBoxObject.cpp index 298ed17b6e4..4556f52918c 100644 --- a/layout/xul/base/src/nsBoxObject.cpp +++ b/layout/xul/base/src/nsBoxObject.cpp @@ -41,7 +41,6 @@ #include "nsIDocument.h" #include "nsIPresShell.h" #include "nsPresContext.h" -#include "nsIDocument.h" #include "nsIContent.h" #include "nsIFrame.h" #include "nsIDocShell.h" @@ -53,7 +52,6 @@ #else #include "nsIDOMElement.h" #endif -#include "nsIFrame.h" #include "nsLayoutUtils.h" #include "nsISupportsPrimitives.h" #include "prtypes.h" diff --git a/layout/xul/base/src/nsImageBoxFrame.cpp b/layout/xul/base/src/nsImageBoxFrame.cpp index c03af4042d8..02510f805d9 100644 --- a/layout/xul/base/src/nsImageBoxFrame.cpp +++ b/layout/xul/base/src/nsImageBoxFrame.cpp @@ -56,7 +56,6 @@ #include "nsIPresShell.h" #include "nsIDocument.h" #include "nsIHTMLDocument.h" -#include "nsStyleConsts.h" #include "nsImageMap.h" #include "nsILinkHandler.h" #include "nsIURL.h" @@ -68,7 +67,6 @@ #include "nsINameSpaceManager.h" #include "nsTextFragment.h" #include "nsIDOMHTMLMapElement.h" -#include "nsBoxLayoutState.h" #include "nsIDOMDocument.h" #include "nsTransform2D.h" #include "nsITheme.h" diff --git a/layout/xul/base/src/nsMenuPopupFrame.cpp b/layout/xul/base/src/nsMenuPopupFrame.cpp index 5a8c76e8bc5..421f3d9e6ba 100644 --- a/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/layout/xul/base/src/nsMenuPopupFrame.cpp @@ -80,7 +80,6 @@ #include "nsIDocShellTreeOwner.h" #include "nsIBaseWindow.h" #include "nsISound.h" -#include "nsIRootBox.h" #include "nsIScreenManager.h" #include "nsIServiceManager.h" #include "nsThemeConstants.h" diff --git a/layout/xul/base/src/nsSprocketLayout.cpp b/layout/xul/base/src/nsSprocketLayout.cpp index 047dfb3a79a..8168ec5b813 100644 --- a/layout/xul/base/src/nsSprocketLayout.cpp +++ b/layout/xul/base/src/nsSprocketLayout.cpp @@ -52,7 +52,6 @@ #include "nsIPresShell.h" #include "nsContainerFrame.h" #include "nsBoxFrame.h" -#include "nsBoxFrame.h" nsBoxLayout* nsSprocketLayout::gInstance = nsnull; diff --git a/layout/xul/base/src/nsXULPopupManager.cpp b/layout/xul/base/src/nsXULPopupManager.cpp index 1f3c3a03c8f..953e7530583 100644 --- a/layout/xul/base/src/nsXULPopupManager.cpp +++ b/layout/xul/base/src/nsXULPopupManager.cpp @@ -61,11 +61,9 @@ #include "nsPIDOMWindow.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIBaseWindow.h" -#include "nsIDocShellTreeItem.h" #include "nsIDOMMouseEvent.h" #include "nsCaret.h" #include "nsIDocument.h" -#include "nsPIDOMWindow.h" #include "nsPIWindowRoot.h" #include "nsFrameManager.h" #include "nsIObserverService.h" diff --git a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp index fd45024e4ad..423cc145a03 100644 --- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp +++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp @@ -72,7 +72,6 @@ #include "nsIDOMDocument.h" #include "nsIDOMXULElement.h" #include "nsIDocument.h" -#include "nsIContent.h" #include "mozilla/css/StyleRule.h" #include "nsCSSRendering.h" #include "nsIXULTemplateBuilder.h" diff --git a/mobile/android/base/DoorHangerPopup.java b/mobile/android/base/DoorHangerPopup.java index 4aa1af2db54..1f6f98bcd1c 100644 --- a/mobile/android/base/DoorHangerPopup.java +++ b/mobile/android/base/DoorHangerPopup.java @@ -132,6 +132,9 @@ public class DoorHangerPopup extends PopupWindow { return; } + if (!mInflated) + init(); + // Hide old doorhangers for (int i = 0; i < mContent.getChildCount(); i++) { DoorHanger dh = (DoorHanger) mContent.getChildAt(i); diff --git a/mobile/android/base/GeckoApp.java b/mobile/android/base/GeckoApp.java index a6ea912db8d..a868c6f88c3 100644 --- a/mobile/android/base/GeckoApp.java +++ b/mobile/android/base/GeckoApp.java @@ -583,9 +583,10 @@ abstract public class GeckoApp String viewportJSON = viewportMetrics.toJSON(); // If the title, uri and viewport haven't changed, the old screenshot is probably valid + // Ordering of .equals() below is important since mLast* variables may be null if (viewportJSON.equals(mLastViewport) && - mLastTitle.equals(lastHistoryEntry.mTitle) && - mLastSnapshotUri.equals(lastHistoryEntry.mUri)) + lastHistoryEntry.mTitle.equals(mLastTitle) && + lastHistoryEntry.mUri.equals(mLastSnapshotUri)) return; mLastViewport = viewportJSON; diff --git a/mobile/android/base/GeckoAppShell.java b/mobile/android/base/GeckoAppShell.java index c9447e6f945..99a66ac39db 100644 --- a/mobile/android/base/GeckoAppShell.java +++ b/mobile/android/base/GeckoAppShell.java @@ -455,10 +455,13 @@ public class GeckoAppShell final int width, final int height) { getHandler().post(new Runnable() { public void run() { + final Tab tab = Tabs.getInstance().getTab(tabId); + if (tab == null) + return; + Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); b.copyPixelsFromBuffer(data); freeDirectBuffer(data); - final Tab tab = Tabs.getInstance().getTab(tabId); GeckoApp.mAppContext.processThumbnail(tab, b, null); } }); diff --git a/mobile/android/chrome/content/SelectHelper.js b/mobile/android/chrome/content/SelectHelper.js new file mode 100644 index 00000000000..fd406aaec10 --- /dev/null +++ b/mobile/android/chrome/content/SelectHelper.js @@ -0,0 +1,139 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +var SelectHelper = { + _uiBusy: false, + + handleClick: function(aTarget) { + // if we're busy looking at a select we want to eat any clicks that + // come to us, but not to process them + if (this._uiBusy) + return true; + + let target = aTarget; + while (target) { + if (this._isMenu(target) && !target.disabled) { + this._uiBusy = true; + target.focus(); + let list = this.getListForElement(target); + this.show(list, target); + target = null; + this._uiBusy = false; + return true; + } + if (target) + target = target.parentNode; + } + return false; + }, + + show: function(aList, aElement) { + let data = JSON.parse(sendMessageToJava({ gecko: aList })); + let selected = data.button; + if (selected == -1) + return; + + if (aElement instanceof Ci.nsIDOMXULMenuListElement) { + aElement.selectedIndex = selected; + } else if (aElement instanceof HTMLSelectElement) { + if (!(selected instanceof Array)) { + let temp = []; + for (let i = 0; i < aList.listitems.length; i++) { + temp[i] = (i == selected); + } + selected = temp; + } + let i = 0; + this.forOptions(aElement, function(aNode) { + aNode.selected = selected[i++]; + }); + } + this.fireOnChange(aElement); + }, + + _isMenu: function(aElement) { + return (aElement instanceof HTMLSelectElement || + aElement instanceof Ci.nsIDOMXULMenuListElement); + }, + + getListForElement: function(aElement) { + let result = { + type: "Prompt:Show", + multiple: aElement.multiple, + selected: [], + listitems: [] + }; + + if (aElement.multiple) { + result.buttons = [ + { label: Strings.browser.GetStringFromName("selectHelper.closeMultipleSelectDialog") }, + ]; + } + + let index = 0; + this.forOptions(aElement, function(aNode, aOptions) { + let item = { + label: aNode.text || aNode.label, + isGroup: aOptions.isGroup, + inGroup: aOptions.inGroup, + disabled: aNode.disabled, + id: index + } + if (aOptions.inGroup) + item.disabled = item.disabled || aNode.parentNode.disabled; + + result.listitems[index] = item; + result.selected[index] = aNode.selected; + index++; + }); + return result; + }, + + forOptions: function(aElement, aFunction) { + let parent = aElement; + if (aElement instanceof Ci.nsIDOMXULMenuListElement) + parent = aElement.menupopup; + let children = parent.children; + let numChildren = children.length; + + // if there are no children in this select, we add a dummy row so that at least something appears + if (numChildren == 0) + aFunction.call(this, { label: "" }, { isGroup: false, inGroup: false }); + + for (let i = 0; i < numChildren; i++) { + let child = children[i]; + if (child instanceof HTMLOptionElement || + child instanceof Ci.nsIDOMXULSelectControlItemElement) { + // This is a regular choice under no group. + aFunction.call(this, child, { + isGroup: false, inGroup: false + }); + } else if (child instanceof HTMLOptGroupElement) { + aFunction.call(this, child, { + isGroup: true, inGroup: false + }); + + let subchildren = child.children; + let numSubchildren = subchildren.length; + for (let j = 0; j < numSubchildren; j++) { + let subchild = subchildren[j]; + aFunction.call(this, subchild, { + isGroup: false, inGroup: true + }); + } + } + } + }, + + fireOnChange: function(aElement) { + let evt = aElement.ownerDocument.createEvent("Events"); + evt.initEvent("change", true, true, aElement.defaultView, 0, + false, false, + false, false, null); + setTimeout(function() { + aElement.dispatchEvent(evt); + }, 0); + } +}; diff --git a/mobile/android/chrome/content/aboutAddons.js b/mobile/android/chrome/content/aboutAddons.js index a394d6436db..b8a867b872a 100644 --- a/mobile/android/chrome/content/aboutAddons.js +++ b/mobile/android/chrome/content/aboutAddons.js @@ -8,23 +8,20 @@ let Ci = Components.interfaces, Cc = Components.classes, Cu = Components.utils; Cu.import("resource://gre/modules/Services.jsm") Cu.import("resource://gre/modules/AddonManager.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); let gStringBundle = Services.strings.createBundle("chrome://browser/locale/aboutAddons.properties"); -let gChromeWin = null; -function getChromeWin() { - if (!gChromeWin) { - gChromeWin = window - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShellTreeItem) - .rootTreeItem - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow) - .QueryInterface(Ci.nsIDOMChromeWindow); - } - return gChromeWin; -} +XPCOMUtils.defineLazyGetter(window, "gChromeWin", function() + window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShellTreeItem) + .rootTreeItem + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow) + .QueryInterface(Ci.nsIDOMChromeWindow)); + +XPCOMUtils.defineLazyGetter(window, "SelectHelper", function() gChromeWin.SelectHelper); function init() { window.addEventListener("popstate", onPopState, false); @@ -44,7 +41,7 @@ function openLink(aElement) { try { let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter); let url = formatter.formatURLPref(aElement.getAttribute("pref")); - let BrowserApp = getChromeWin().BrowserApp; + let BrowserApp = gChromeWin.BrowserApp; BrowserApp.addTab(url, { selected: true, parentId: BrowserApp.selectedTab.id }); } catch (ex) {} } diff --git a/mobile/android/chrome/content/bindings.xml b/mobile/android/chrome/content/bindings.xml index 283e3ebeb5c..70e68f8bb67 100644 --- a/mobile/android/chrome/content/bindings.xml +++ b/mobile/android/chrome/content/bindings.xml @@ -94,7 +94,7 @@ return; this.focus(); - MenuListHelperUI.show(this); + SelectHelper.handleClick(this); ]]> diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index efd9b74a38f..43b22a98830 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -51,6 +51,18 @@ XPCOMUtils.defineLazyGetter(this, "PluralForm", function() { return PluralForm; }); +// Lazily-loaded browser scripts: +[ + ["SelectHelper", "chrome://browser/content/SelectHelper.js"], +].forEach(function (aScript) { + let [name, script] = aScript; + XPCOMUtils.defineLazyGetter(window, name, function() { + let sandbox = {}; + Services.scriptloader.loadSubScript(script, sandbox); + return sandbox[name]; + }); +}); + XPCOMUtils.defineLazyServiceGetter(this, "Haptic", "@mozilla.org/widget/hapticfeedback;1", "nsIHapticFeedback"); @@ -2266,7 +2278,7 @@ var BrowserEventHandler = { } } else if (aTopic == "Gesture:SingleTap") { let element = this._highlightElement; - if (element && !FormAssistant.handleClick(element)) { + if (element && !SelectHelper.handleClick(element)) { try { let data = JSON.parse(aData); [data.x, data.y] = ElementTouchHelper.toScreenCoords(element.ownerDocument.defaultView, data.x, data.y); @@ -2795,7 +2807,6 @@ var FormAssistant = { // Used to keep track of the element that corresponds to the current // autocomplete suggestions _currentInputElement: null, - _uiBusy: false, init: function() { Services.obs.addObserver(this, "FormAssist:AutoComplete", false); @@ -2881,123 +2892,8 @@ var FormAssistant = { } return suggestions; - }, - - show: function(aList, aElement) { - let data = JSON.parse(sendMessageToJava({ gecko: aList })); - let selected = data.button; - if (selected == -1) - return; - - if (!(selected instanceof Array)) { - let temp = []; - for (let i = 0; i < aList.listitems.length; i++) { - temp[i] = (i == selected); - } - selected = temp; - } - this.forOptions(aElement, function(aNode, aIndex) { - aNode.selected = selected[aIndex]; - }); - this.fireOnChange(aElement); - }, - - handleClick: function(aTarget) { - // if we're busy looking at a select we want to eat any clicks that - // come to us, but not to process them - if (this._uiBusy) - return true; - - let target = aTarget; - while (target) { - if (this._isSelectElement(target) && !target.disabled) { - this._uiBusy = true; - target.focus(); - let list = this.getListForElement(target); - this.show(list, target); - target = null; - this._uiBusy = false; - return true; - } - if (target) - target = target.parentNode; - } - return false; - }, - - fireOnChange: function(aElement) { - let evt = aElement.ownerDocument.createEvent("Events"); - evt.initEvent("change", true, true, aElement.defaultView, 0, - false, false, - false, false, null); - setTimeout(function() { - aElement.dispatchEvent(evt); - }, 0); - }, - - _isSelectElement: function(aElement) { - return (aElement instanceof HTMLSelectElement); - }, - - getListForElement: function(aElement) { - let result = { - type: "Prompt:Show", - multiple: aElement.multiple, - selected: [], - listitems: [] - }; - - if (aElement.multiple) { - result.buttons = [ - { label: Strings.browser.GetStringFromName("selectHelper.closeMultipleSelectDialog") }, - ]; - } - - this.forOptions(aElement, function(aNode, aIndex, aIsGroup, aInGroup) { - let item = { - label: aNode.text || aNode.label, - isGroup: aIsGroup, - inGroup: aInGroup, - disabled: aNode.disabled, - id: aIndex - } - if (aInGroup) - item.disabled = item.disabled || aNode.parentNode.disabled; - - result.listitems[aIndex] = item; - result.selected[aIndex] = aNode.selected; - }); - return result; - }, - - forOptions: function(aElement, aFunction) { - let optionIndex = 0; - let children = aElement.children; - let numChildren = children.length; - // if there are no children in this select, we add a dummy row so that at least something appears - if (numChildren == 0) - aFunction.call(this, {label:""}, optionIndex); - for (let i = 0; i < numChildren; i++) { - let child = children[i]; - if (child instanceof HTMLOptionElement) { - // This is a regular choice under no group. - aFunction.call(this, child, optionIndex, false, false); - optionIndex++; - } else if (child instanceof HTMLOptGroupElement) { - aFunction.call(this, child, optionIndex, true, false); - optionIndex++; - - let subchildren = child.children; - let numSubchildren = subchildren.length; - for (let j = 0; j < numSubchildren; j++) { - let subchild = subchildren[j]; - aFunction.call(this, subchild, optionIndex, false, true); - optionIndex++; - } - } - } } -} +}; var XPInstallObserver = { init: function xpi_init() { @@ -3782,7 +3678,7 @@ var ClipboardHelper = { return false; } } -} +}; var PluginHelper = { showDoorHanger: function(aTab) { diff --git a/mobile/android/chrome/jar.mn b/mobile/android/chrome/jar.mn index 84afd575c07..7fe708b425a 100644 --- a/mobile/android/chrome/jar.mn +++ b/mobile/android/chrome/jar.mn @@ -24,6 +24,7 @@ chrome.jar: content/exceptions.js (content/exceptions.js) * content/downloads.js (content/downloads.js) content/netError.xhtml (content/netError.xhtml) + content/SelectHelper.js (content/SelectHelper.js) % override chrome://global/content/config.xul chrome://browser/content/config.xhtml % override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml diff --git a/mobile/android/themes/core/content.css b/mobile/android/themes/core/content.css index 8aa7faa76da..978f9cc8dbb 100644 --- a/mobile/android/themes/core/content.css +++ b/mobile/android/themes/core/content.css @@ -366,3 +366,7 @@ input > .anonymous-div:after { video { image-rendering: -moz-crisp-edges; } + +xul|menulist { + -moz-binding: url("chrome://browser/content/bindings.xml#menulist"); +} diff --git a/mobile/xul/chrome/content/about.xhtml b/mobile/xul/chrome/content/about.xhtml index 63e97d2d8b4..437149ef517 100644 --- a/mobile/xul/chrome/content/about.xhtml +++ b/mobile/xul/chrome/content/about.xhtml @@ -90,6 +90,19 @@ + + diff --git a/toolkit/components/autocomplete/nsAutoCompleteController.cpp b/toolkit/components/autocomplete/nsAutoCompleteController.cpp index 95aec25dd24..ed7c461a21c 100644 --- a/toolkit/components/autocomplete/nsAutoCompleteController.cpp +++ b/toolkit/components/autocomplete/nsAutoCompleteController.cpp @@ -85,7 +85,9 @@ nsAutoCompleteController::nsAutoCompleteController() : mSearchStatus(nsAutoCompleteController::STATUS_NONE), mRowCount(0), mSearchesOngoing(0), - mFirstSearchResult(false) + mSearchesFailed(0), + mFirstSearchResult(false), + mImmediateSearchesCount(0) { } @@ -161,6 +163,7 @@ nsAutoCompleteController::SetInput(nsIAutoCompleteInput *aInput) mResults.SetCapacity(searchCount); mSearches.SetCapacity(searchCount); mMatchCounts.SetLength(searchCount); + mImmediateSearchesCount = 0; const char *searchCID = kAutoCompleteSearchCID; @@ -173,8 +176,17 @@ nsAutoCompleteController::SetInput(nsIAutoCompleteInput *aInput) // Use the created cid to get a pointer to the search service and store it for later nsCOMPtr search = do_GetService(cid.get()); - if (search) + if (search) { mSearches.AppendObject(search); + + // Count immediate searches. + PRUint16 searchType = nsIAutoCompleteSearchDescriptor::SEARCH_TYPE_DELAYED; + nsCOMPtr searchDesc = + do_QueryInterface(search); + if (searchDesc && NS_SUCCEEDED(searchDesc->GetSearchType(&searchType)) && + searchType == nsIAutoCompleteSearchDescriptor::SEARCH_TYPE_IMMEDIATE) + mImmediateSearchesCount++; + } } return NS_OK; @@ -184,7 +196,7 @@ NS_IMETHODIMP nsAutoCompleteController::StartSearch(const nsAString &aSearchString) { mSearchString = aSearchString; - StartSearchTimer(); + StartSearches(); return NS_OK; } @@ -262,7 +274,7 @@ nsAutoCompleteController::HandleText() return NS_OK; } - StartSearchTimer(); + StartSearches(); return NS_OK; } @@ -488,7 +500,7 @@ nsAutoCompleteController::HandleKeyNavigation(PRUint32 aKey, bool *_retval) return NS_OK; } - StartSearchTimer(); + StartSearches(); } } } @@ -727,7 +739,16 @@ NS_IMETHODIMP nsAutoCompleteController::Notify(nsITimer *timer) { mTimer = nsnull; - StartSearch(); + + if (mImmediateSearchesCount == 0) { + // If there were no immediate searches, BeforeSearches has not yet been + // called, so do it now. + nsresult rv = BeforeSearches(); + if (NS_FAILED(rv)) + return rv; + } + StartSearch(nsIAutoCompleteSearchDescriptor::SEARCH_TYPE_DELAYED); + AfterSearches(); return NS_OK; } @@ -1002,31 +1023,50 @@ nsAutoCompleteController::ClosePopup() } nsresult -nsAutoCompleteController::StartSearch() +nsAutoCompleteController::BeforeSearches() { NS_ENSURE_STATE(mInput); - nsCOMPtr input(mInput); + mSearchStatus = nsIAutoCompleteController::STATUS_SEARCHING; mDefaultIndexCompleted = false; - // Cache the current results so that we can pass these through to all the - // searches without losing them - nsCOMArray resultCache; - if (!resultCache.AppendObjects(mResults)) { + // The first search result will clear mResults array, though we should pass + // the previous result to each search to allow them to reuse it. So we + // temporarily cache current results till AfterSearches(). + if (!mResultCache.AppendObjects(mResults)) { return NS_ERROR_OUT_OF_MEMORY; } - PRUint32 count = mSearches.Count(); - mSearchesOngoing = count; + mSearchesOngoing = mSearches.Count(); + mSearchesFailed = 0; mFirstSearchResult = true; // notify the input that the search is beginning - input->OnSearchBegin(); + mInput->OnSearchBegin(); - PRUint32 searchesFailed = 0; - for (PRUint32 i = 0; i < count; ++i) { + return NS_OK; +} + +nsresult +nsAutoCompleteController::StartSearch(PRUint16 aSearchType) +{ + NS_ENSURE_STATE(mInput); + nsCOMPtr input = mInput; + + for (PRInt32 i = 0; i < mSearches.Count(); ++i) { nsCOMPtr search = mSearches[i]; - nsIAutoCompleteResult *result = resultCache.SafeObjectAt(i); + + // Filter on search type. Not all the searches implement this interface, + // in such a case just consider them delayed. + PRUint16 searchType = nsIAutoCompleteSearchDescriptor::SEARCH_TYPE_DELAYED; + nsCOMPtr searchDesc = + do_QueryInterface(search); + if (searchDesc) + searchDesc->GetSearchType(&searchType); + if (searchType != aSearchType) + continue; + + nsIAutoCompleteResult *result = mResultCache.SafeObjectAt(i); if (result) { PRUint16 searchResult; @@ -1044,7 +1084,7 @@ nsAutoCompleteController::StartSearch() rv = search->StartSearch(mSearchString, searchParam, result, static_cast(this)); if (NS_FAILED(rv)) { - ++searchesFailed; + ++mSearchesFailed; --mSearchesOngoing; } // Because of the joy of nested event loops (which can easily happen when some @@ -1058,12 +1098,17 @@ nsAutoCompleteController::StartSearch() } } - if (searchesFailed == count) - PostSearchCleanup(); - return NS_OK; } +void +nsAutoCompleteController::AfterSearches() +{ + mResultCache.Clear(); + if (mSearchesFailed == mSearches.Count()) + PostSearchCleanup(); +} + NS_IMETHODIMP nsAutoCompleteController::StopSearch() { @@ -1087,7 +1132,7 @@ nsAutoCompleteController::StopSearch() } nsresult -nsAutoCompleteController::StartSearchTimer() +nsAutoCompleteController::StartSearches() { // Don't create a new search timer if we're already waiting for one to fire. // If we don't check for this, we won't be able to cancel the original timer @@ -1095,9 +1140,37 @@ nsAutoCompleteController::StartSearchTimer() if (mTimer || !mInput) return NS_OK; + // Get the timeout for delayed searches. PRUint32 timeout; mInput->GetTimeout(&timeout); + PRUint32 immediateSearchesCount = mImmediateSearchesCount; + if (timeout == 0) { + // All the searches should be executed immediately. + immediateSearchesCount = mSearches.Count(); + } + + if (immediateSearchesCount > 0) { + nsresult rv = BeforeSearches(); + if (NS_FAILED(rv)) + return rv; + StartSearch(nsIAutoCompleteSearchDescriptor::SEARCH_TYPE_IMMEDIATE); + + if (mSearches.Count() == immediateSearchesCount) { + // Either all searches are immediate, or the timeout is 0. In the + // latter case we still have to execute the delayed searches, otherwise + // this will be a no-op. + StartSearch(nsIAutoCompleteSearchDescriptor::SEARCH_TYPE_DELAYED); + + // All the searches have been started, just finish. + AfterSearches(); + return NS_OK; + } + } + + MOZ_ASSERT(timeout > 0, "Trying to delay searches with a 0 timeout!"); + + // Now start the delayed searches. nsresult rv; mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv); if (NS_FAILED(rv)) diff --git a/toolkit/components/autocomplete/nsAutoCompleteController.h b/toolkit/components/autocomplete/nsAutoCompleteController.h index 83bca63ba93..0ece7a909bf 100644 --- a/toolkit/components/autocomplete/nsAutoCompleteController.h +++ b/toolkit/components/autocomplete/nsAutoCompleteController.h @@ -74,9 +74,11 @@ protected: nsresult OpenPopup(); nsresult ClosePopup(); - nsresult StartSearch(); - - nsresult StartSearchTimer(); + nsresult StartSearch(PRUint16 aSearchType); + + nsresult BeforeSearches(); + nsresult StartSearches(); + void AfterSearches(); nsresult ClearSearchTimer(); nsresult ProcessResult(PRInt32 aSearchIndex, nsIAutoCompleteResult *aResult); @@ -111,8 +113,14 @@ protected: nsCOMArray mSearches; nsCOMArray mResults; + // Caches the match counts for the current ongoing results to allow + // incremental results to keep the rowcount up to date. nsTArray mMatchCounts; - + // Temporarily keeps the results alive while invoking startSearch() for each + // search. This is needed to allow the searches to reuse the previous result, + // since otherwise the first search clears mResults. + nsCOMArray mResultCache; + nsCOMPtr mTimer; nsCOMPtr mSelection; nsCOMPtr mTree; @@ -126,7 +134,9 @@ protected: PRUint16 mSearchStatus; PRUint32 mRowCount; PRUint32 mSearchesOngoing; + PRUint32 mSearchesFailed; bool mFirstSearchResult; + PRUint32 mImmediateSearchesCount; }; #endif /* __nsAutoCompleteController__ */ diff --git a/toolkit/components/autocomplete/nsIAutoCompleteSearch.idl b/toolkit/components/autocomplete/nsIAutoCompleteSearch.idl index 4b09c6527d2..335c4bf46e8 100644 --- a/toolkit/components/autocomplete/nsIAutoCompleteSearch.idl +++ b/toolkit/components/autocomplete/nsIAutoCompleteSearch.idl @@ -82,3 +82,20 @@ interface nsIAutoCompleteObserver : nsISupports */ void onUpdateSearchResult(in nsIAutoCompleteSearch search, in nsIAutoCompleteResult result); }; + +[scriptable, uuid(02314d6e-b730-40cc-a215-221554d77064)] +interface nsIAutoCompleteSearchDescriptor : nsISupports +{ + // The search is started after the timeout specified by the corresponding + // nsIAutoCompleteInput implementation. + const unsigned short SEARCH_TYPE_DELAYED = 0; + // The search is started synchronously, before any delayed searches. + const unsigned short SEARCH_TYPE_IMMEDIATE = 1; + + /** + * Identifies the search behavior. + * Should be one of the SEARCH_TYPE_* constants above. + * Defaults to SEARCH_TYPE_DELAYED. + */ + readonly attribute unsigned short searchType; +}; diff --git a/toolkit/components/autocomplete/tests/unit/test_immediate_search.js b/toolkit/components/autocomplete/tests/unit/test_immediate_search.js new file mode 100644 index 00000000000..4c2d0edfbd4 --- /dev/null +++ b/toolkit/components/autocomplete/tests/unit/test_immediate_search.js @@ -0,0 +1,160 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +function AutoCompleteImmediateSearch(aName, aResult) { + this.name = aName; + this._result = aResult; +} +AutoCompleteImmediateSearch.prototype = Object.create(AutoCompleteSearchBase.prototype); +AutoCompleteImmediateSearch.prototype.searchType = + Ci.nsIAutoCompleteSearchDescriptor.SEARCH_TYPE_IMMEDIATE; +AutoCompleteImmediateSearch.prototype.QueryInterface = + XPCOMUtils.generateQI([Ci.nsIFactory, + Ci.nsIAutoCompleteSearch, + Ci.nsIAutoCompleteSearchDescriptor]); + +function AutoCompleteDelayedSearch(aName, aResult) { + this.name = aName; + this._result = aResult; +} +AutoCompleteDelayedSearch.prototype = Object.create(AutoCompleteSearchBase.prototype); + +function AutoCompleteResult(aValues, aDefaultIndex) { + this._values = aValues; + this.defaultIndex = aDefaultIndex; +} +AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype); + +function run_test() { + run_next_test(); +} + +/** + * An immediate search should be executed synchronously. + */ +add_test(function test_immediate_search() { + let immediateResults = ["mozillaTest"]; + let inputStr = "moz"; + + let immediateSearch = new AutoCompleteImmediateSearch( + "immediate", new AutoCompleteResult(["moz-immediate"], 0)); + registerAutoCompleteSearch(immediateSearch); + let delayedSearch = new AutoCompleteDelayedSearch( + "delayed", new AutoCompleteResult(["moz-delayed"], 0)); + registerAutoCompleteSearch(delayedSearch); + + let controller = Cc["@mozilla.org/autocomplete/controller;1"]. + getService(Ci.nsIAutoCompleteController); + + let input = new AutoCompleteInputBase([delayedSearch.name, + immediateSearch.name]); + input.completeDefaultIndex = true; + input.textValue = inputStr; + + // Caret must be at the end. Autofill doesn't happen unless you're typing + // characters at the end. + let strLen = inputStr.length; + input.selectTextRange(strLen, strLen); + + controller.input = input; + controller.startSearch(inputStr); + + // Immediately check the result, the immediate search should have finished. + do_check_eq(input.textValue, "moz-immediate"); + + // Wait for both queries to finish. + input.onSearchComplete = function() { + // Sanity check. + do_check_eq(input.textValue, "moz-immediate"); + + unregisterAutoCompleteSearch(immediateSearch); + unregisterAutoCompleteSearch(delayedSearch); + run_next_test(); + }; +}); + +/** + * An immediate search should be executed before any delayed search. + */ +add_test(function test_immediate_search_notimeout() { + let immediateResults = ["mozillaTest"]; + let inputStr = "moz"; + + let immediateSearch = new AutoCompleteImmediateSearch( + "immediate", new AutoCompleteResult(["moz-immediate"], 0)); + registerAutoCompleteSearch(immediateSearch); + + let delayedSearch = new AutoCompleteDelayedSearch( + "delayed", new AutoCompleteResult(["moz-delayed"], 0)); + registerAutoCompleteSearch(delayedSearch); + + let controller = Cc["@mozilla.org/autocomplete/controller;1"]. + getService(Ci.nsIAutoCompleteController); + + let input = new AutoCompleteInputBase([delayedSearch.name, + immediateSearch.name]); + input.completeDefaultIndex = true; + input.textValue = inputStr; + input.timeout = 0; + + // Caret must be at the end. Autofill doesn't happen unless you're typing + // characters at the end. + let strLen = inputStr.length; + input.selectTextRange(strLen, strLen); + + controller.input = input; + let complete = false; + input.onSearchComplete = function() { + complete = true; + }; + controller.startSearch(inputStr); + do_check_true(complete); + + // Immediately check the result, the immediate search should have finished. + do_check_eq(input.textValue, "moz-immediate"); + + unregisterAutoCompleteSearch(immediateSearch); + unregisterAutoCompleteSearch(delayedSearch); + run_next_test(); +}); + +/** + * A delayed search should be executed synchronously with a zero timeout. + */ +add_test(function test_delayed_search_notimeout() { + let immediateResults = ["mozillaTest"]; + let inputStr = "moz"; + + let delayedSearch = new AutoCompleteDelayedSearch( + "delayed", new AutoCompleteResult(["moz-delayed"], 0)); + registerAutoCompleteSearch(delayedSearch); + + let controller = Cc["@mozilla.org/autocomplete/controller;1"]. + getService(Ci.nsIAutoCompleteController); + + let input = new AutoCompleteInputBase([delayedSearch.name]); + input.completeDefaultIndex = true; + input.textValue = inputStr; + input.timeout = 0; + + // Caret must be at the end. Autofill doesn't happen unless you're typing + // characters at the end. + let strLen = inputStr.length; + input.selectTextRange(strLen, strLen); + + controller.input = input; + let complete = false; + input.onSearchComplete = function() { + complete = true; + }; + controller.startSearch(inputStr); + do_check_true(complete); + + // Immediately check the result, the delayed search should have finished. + do_check_eq(input.textValue, "moz-delayed"); + + unregisterAutoCompleteSearch(delayedSearch); + run_next_test(); +}); diff --git a/toolkit/components/autocomplete/tests/unit/xpcshell.ini b/toolkit/components/autocomplete/tests/unit/xpcshell.ini index 0cf15a67ab7..b6f59fe2168 100644 --- a/toolkit/components/autocomplete/tests/unit/xpcshell.ini +++ b/toolkit/components/autocomplete/tests/unit/xpcshell.ini @@ -12,5 +12,6 @@ tail = [test_badDefaultIndex.js] [test_completeDefaultIndex_casing.js] [test_hiddenResult.js] +[test_immediate_search.js] [test_previousResult.js] [test_stopSearch.js] diff --git a/toolkit/components/places/Database.cpp b/toolkit/components/places/Database.cpp index a284f308144..7d2466a8b4e 100644 --- a/toolkit/components/places/Database.cpp +++ b/toolkit/components/places/Database.cpp @@ -1856,8 +1856,7 @@ Database::Shutdown() nsRefPtr closeListener = new BlockingConnectionCloseCallback(); (void)mMainConn->AsyncClose(closeListener); - // The spinning is temporarily disabled. See bug 728653. - //closeListener->Spin(); + closeListener->Spin(); // Don't set this earlier, otherwise some internal helper used on shutdown // may bail out. diff --git a/toolkit/components/places/nsPlacesAutoComplete.js b/toolkit/components/places/nsPlacesAutoComplete.js index 36a7f90e89a..df0656152fc 100644 --- a/toolkit/components/places/nsPlacesAutoComplete.js +++ b/toolkit/components/places/nsPlacesAutoComplete.js @@ -1477,6 +1477,10 @@ urlInlineComplete.prototype = { } }, + ////////////////////////////////////////////////////////////////////////////// + //// nsIAutoCompleteSearchDescriptor + get searchType() Ci.nsIAutoCompleteSearchDescriptor.SEARCH_TYPE_IMMEDIATE, + ////////////////////////////////////////////////////////////////////////////// //// mozIStorageStatementCallback @@ -1609,6 +1613,7 @@ urlInlineComplete.prototype = { QueryInterface: XPCOMUtils.generateQI([ Ci.nsIAutoCompleteSearch, + Ci.nsIAutoCompleteSearchDescriptor, Ci.mozIStorageStatementCallback, Ci.nsIObserver, Ci.nsISupportsWeakReference, diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/Telemetry.cpp index f4b132963bb..38600447c4d 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -318,26 +318,41 @@ ReflectHistogramAndSamples(JSContext *cx, JSObject *obj, Histogram *h, return REFLECT_CORRUPT; } - JSObject *counts_array; - JSObject *rarray; + if (!JS_DefineProperty(cx, obj, "min", INT_TO_JSVAL(h->declared_min()), NULL, NULL, JSPROP_ENUMERATE) + && JS_DefineProperty(cx, obj, "max", INT_TO_JSVAL(h->declared_max()), NULL, NULL, JSPROP_ENUMERATE) + && JS_DefineProperty(cx, obj, "histogram_type", INT_TO_JSVAL(h->histogram_type()), NULL, NULL, JSPROP_ENUMERATE) + && JS_DefineProperty(cx, obj, "sum", DOUBLE_TO_JSVAL(ss.sum()), NULL, NULL, JSPROP_ENUMERATE)) { + return REFLECT_FAILURE; + } + const size_t count = h->bucket_count(); - if (!(JS_DefineProperty(cx, obj, "min", INT_TO_JSVAL(h->declared_min()), NULL, NULL, JSPROP_ENUMERATE) - && JS_DefineProperty(cx, obj, "max", INT_TO_JSVAL(h->declared_max()), NULL, NULL, JSPROP_ENUMERATE) - && JS_DefineProperty(cx, obj, "histogram_type", INT_TO_JSVAL(h->histogram_type()), NULL, NULL, JSPROP_ENUMERATE) - && JS_DefineProperty(cx, obj, "sum", DOUBLE_TO_JSVAL(ss.sum()), NULL, NULL, JSPROP_ENUMERATE) - && (rarray = JS_NewArrayObject(cx, count, NULL)) - && JS_DefineProperty(cx, obj, "ranges", OBJECT_TO_JSVAL(rarray), NULL, NULL, JSPROP_ENUMERATE) - && FillRanges(cx, rarray, h) - && (counts_array = JS_NewArrayObject(cx, count, NULL)) - && JS_DefineProperty(cx, obj, "counts", OBJECT_TO_JSVAL(counts_array), NULL, NULL, JSPROP_ENUMERATE) - )) { + JSObject *rarray = JS_NewArrayObject(cx, count, nsnull); + if (!rarray) { + return REFLECT_FAILURE; + } + JS::AutoObjectRooter aroot(cx, rarray); + if (!(FillRanges(cx, rarray, h) + && JS_DefineProperty(cx, obj, "ranges", OBJECT_TO_JSVAL(rarray), + NULL, NULL, JSPROP_ENUMERATE))) { + return REFLECT_FAILURE; + } + + JSObject *counts_array = JS_NewArrayObject(cx, count, NULL); + if (!counts_array) { + return REFLECT_FAILURE; + } + JS::AutoObjectRooter croot(cx, counts_array); + if (!JS_DefineProperty(cx, obj, "counts", OBJECT_TO_JSVAL(counts_array), + NULL, NULL, JSPROP_ENUMERATE)) { return REFLECT_FAILURE; } for (size_t i = 0; i < count; i++) { - if (!JS_DefineElement(cx, counts_array, i, INT_TO_JSVAL(ss.counts(i)), NULL, NULL, JSPROP_ENUMERATE)) { + if (!JS_DefineElement(cx, counts_array, i, INT_TO_JSVAL(ss.counts(i)), + NULL, NULL, JSPROP_ENUMERATE)) { return REFLECT_FAILURE; } } + return REFLECT_OK; } @@ -393,9 +408,10 @@ JSHistogram_Snapshot(JSContext *cx, unsigned argc, jsval *vp) } Histogram *h = static_cast(JS_GetPrivate(obj)); - JSObject *snapshot = JS_NewObject(cx, NULL, NULL, NULL); + JSObject *snapshot = JS_NewObject(cx, nsnull, nsnull, nsnull); if (!snapshot) return JS_FALSE; + JS::AutoObjectRooter sroot(cx, snapshot); switch (ReflectHistogramSnapshot(cx, snapshot, h)) { case REFLECT_FAILURE: @@ -426,10 +442,14 @@ WrapAndReturnHistogram(Histogram *h, JSContext *cx, jsval *ret) JSObject *obj = JS_NewObject(cx, &JSHistogram_class, NULL, NULL); if (!obj) return NS_ERROR_FAILURE; + JS::AutoObjectRooter root(cx, obj); + if (!(JS_DefineFunction (cx, obj, "add", JSHistogram_Add, 1, 0) + && JS_DefineFunction (cx, obj, "snapshot", JSHistogram_Snapshot, 1, 0))) { + return NS_ERROR_FAILURE; + } *ret = OBJECT_TO_JSVAL(obj); JS_SetPrivate(obj, h); - return (JS_DefineFunction (cx, obj, "add", JSHistogram_Add, 1, 0) - && JS_DefineFunction (cx, obj, "snapshot", JSHistogram_Snapshot, 1, 0)) ? NS_OK : NS_ERROR_FAILURE; + return NS_OK; } TelemetryImpl::TelemetryImpl(): @@ -479,8 +499,11 @@ TelemetryImpl::StatementReflector(SlowSQLEntryType *entry, JSContext *cx, jsval totalTime = UINT_TO_JSVAL(entry->mData.totalTime); JSObject *arrayObj = JS_NewArrayObject(cx, 2, nsnull); - return (arrayObj - && JS_SetElement(cx, arrayObj, 0, &hitCount) + if (!arrayObj) { + return false; + } + JS::AutoObjectRooter root(cx, arrayObj); + return (JS_SetElement(cx, arrayObj, 0, &hitCount) && JS_SetElement(cx, arrayObj, 1, &totalTime) && JS_DefineProperty(cx, obj, sql.BeginReading(), @@ -494,18 +517,19 @@ TelemetryImpl::AddSQLInfo(JSContext *cx, JSObject *rootObj, bool mainThread) JSObject *statsObj = JS_NewObject(cx, NULL, NULL, NULL); if (!statsObj) return false; - - JSBool ok = JS_DefineProperty(cx, rootObj, - mainThread ? "mainThread" : "otherThreads", - OBJECT_TO_JSVAL(statsObj), - NULL, NULL, JSPROP_ENUMERATE); - if (!ok) - return false; + JS::AutoObjectRooter root(cx, statsObj); AutoHashtable &sqlMap = (mainThread ? mSlowSQLOnMainThread : mSlowSQLOnOtherThread); - return sqlMap.ReflectHashtable(StatementReflector, cx, statsObj); + if (!sqlMap.ReflectHashtable(StatementReflector, cx, statsObj)) { + return false; + } + + return JS_DefineProperty(cx, rootObj, + mainThread ? "mainThread" : "otherThreads", + OBJECT_TO_JSVAL(statsObj), + NULL, NULL, JSPROP_ENUMERATE); } nsresult @@ -778,6 +802,7 @@ TelemetryImpl::GetHistogramSnapshots(JSContext *cx, jsval *ret) if (!hobj) { return NS_ERROR_FAILURE; } + JS::AutoObjectRooter root(cx, hobj); switch (ReflectHistogramSnapshot(cx, hobj, h)) { case REFLECT_CORRUPT: // We can still hit this case even if ShouldReflectHistograms @@ -806,7 +831,11 @@ TelemetryImpl::AddonHistogramReflector(AddonHistogramEntryType *entry, } JSObject *snapshot = JS_NewObject(cx, NULL, NULL, NULL); - js::AutoObjectRooter r(cx, snapshot); + if (!snapshot) { + // Just consider this to be skippable. + return true; + } + JS::AutoObjectRooter r(cx, snapshot); switch (ReflectHistogramSnapshot(cx, snapshot, entry->mData.h)) { case REFLECT_FAILURE: case REFLECT_CORRUPT: @@ -833,7 +862,7 @@ TelemetryImpl::AddonReflector(AddonEntryType *entry, if (!subobj) { return false; } - js::AutoObjectRooter r(cx, subobj); + JS::AutoObjectRooter r(cx, subobj); AddonHistogramMapType *map = entry->mData; if (!(map->ReflectHashtable(AddonHistogramReflector, cx, subobj) @@ -854,7 +883,7 @@ TelemetryImpl::GetAddonHistogramSnapshots(JSContext *cx, jsval *ret) if (!obj) { return NS_ERROR_FAILURE; } - js::AutoObjectRooter r(cx, obj); + JS::AutoObjectRooter r(cx, obj); if (!mAddonMap.ReflectHashtable(AddonReflector, cx, obj)) { return NS_ERROR_FAILURE; @@ -889,6 +918,7 @@ TelemetryImpl::GetRegisteredHistograms(JSContext *cx, jsval *ret) JSObject *info = JS_NewObject(cx, NULL, NULL, NULL); if (!info) return NS_ERROR_FAILURE; + JS::AutoObjectRooter root(cx, info); for (size_t i = 0; i < count; ++i) { JSString *comment = JS_InternString(cx, gHistograms[i].comment); @@ -983,7 +1013,7 @@ TelemetrySessionData::SampleReflector(EntryType *entry, JSContext *cx, if (!snapshot) { return false; } - js::AutoObjectRooter root(cx, snapshot); + JS::AutoObjectRooter root(cx, snapshot); return (ReflectHistogramAndSamples(cx, snapshot, h, entry->mData) && JS_DefineProperty(cx, snapshots, h->histogram_name().c_str(), @@ -998,7 +1028,7 @@ TelemetrySessionData::GetSnapshots(JSContext *cx, jsval *ret) if (!snapshots) { return NS_ERROR_FAILURE; } - js::AutoObjectRooter root(cx, snapshots); + JS::AutoObjectRooter root(cx, snapshots); if (!mSampleSetMap.ReflectHashtable(SampleReflector, cx, snapshots)) { return NS_ERROR_FAILURE; diff --git a/toolkit/components/telemetry/TelemetryPing.js b/toolkit/components/telemetry/TelemetryPing.js index a1f347465d5..a51df5a7c31 100644 --- a/toolkit/components/telemetry/TelemetryPing.js +++ b/toolkit/components/telemetry/TelemetryPing.js @@ -62,7 +62,7 @@ const MEM_HISTOGRAMS = { "explicit": "MEMORY_EXPLICIT", "resident": "MEMORY_RESIDENT", "storage-sqlite": "MEMORY_STORAGE_SQLITE", - "explicit/images/content/used/uncompressed": + "images-content-used-uncompressed": "MEMORY_IMAGES_CONTENT_USED_UNCOMPRESSED", "heap-allocated": "MEMORY_HEAP_ALLOCATED", "page-faults-hard": "PAGE_FAULTS_HARD", diff --git a/widget/gonk/nsAppShell.cpp b/widget/gonk/nsAppShell.cpp index a33274c35c1..718f306986b 100644 --- a/widget/gonk/nsAppShell.cpp +++ b/widget/gonk/nsAppShell.cpp @@ -240,14 +240,6 @@ sendKeyEvent(PRUint32 keyCode, bool down, uint64_t timeMs) } } -static void -sendSpecialKeyEvent(nsIAtom *command, uint64_t timeMs) -{ - nsCommandEvent event(true, nsGkAtoms::onAppCommand, command, NULL); - event.time = timeMs; - nsWindow::DispatchInputEvent(event); -} - static void maybeSendKeyEvent(int keyCode, bool pressed, uint64_t timeMs) { @@ -256,12 +248,10 @@ maybeSendKeyEvent(int keyCode, bool pressed, uint64_t timeMs) sendKeyEvent(NS_VK_ESCAPE, pressed, timeMs); break; case KEY_MENU: - if (!pressed) - sendSpecialKeyEvent(nsGkAtoms::Menu, timeMs); + sendKeyEvent(NS_VK_CONTEXT_MENU, pressed, timeMs); break; case KEY_SEARCH: - if (pressed) - sendSpecialKeyEvent(nsGkAtoms::Search, timeMs); + sendKeyEvent(NS_VK_F5, pressed, timeMs); break; case KEY_HOME: sendKeyEvent(NS_VK_HOME, pressed, timeMs); @@ -270,12 +260,10 @@ maybeSendKeyEvent(int keyCode, bool pressed, uint64_t timeMs) sendKeyEvent(NS_VK_SLEEP, pressed, timeMs); break; case KEY_VOLUMEUP: - if (pressed) - sendSpecialKeyEvent(nsGkAtoms::VolumeUp, timeMs); + sendKeyEvent(NS_VK_PAGE_UP, pressed, timeMs); break; case KEY_VOLUMEDOWN: - if (pressed) - sendSpecialKeyEvent(nsGkAtoms::VolumeDown, timeMs); + sendKeyEvent(NS_VK_PAGE_DOWN, pressed, timeMs); break; default: VERBOSE_LOG("Got unknown key event code. type 0x%04x code 0x%04x value %d", diff --git a/xpcom/glue/Mutex.h b/xpcom/glue/Mutex.h index 80db53cadf7..8ca41f673cd 100644 --- a/xpcom/glue/Mutex.h +++ b/xpcom/glue/Mutex.h @@ -165,7 +165,8 @@ private: * * MUCH PREFERRED to bare calls to Mutex.Lock and Unlock. */ -class NS_COM_GLUE NS_STACK_CLASS MutexAutoLock +template +class NS_COM_GLUE NS_STACK_CLASS BaseAutoLock { public: /** @@ -176,7 +177,7 @@ public: * @param aLock A valid mozilla::Mutex* returned by * mozilla::Mutex::NewMutex. **/ - MutexAutoLock(mozilla::Mutex& aLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : + BaseAutoLock(T& aLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : mLock(&aLock) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; @@ -184,21 +185,22 @@ public: mLock->Lock(); } - ~MutexAutoLock(void) { + ~BaseAutoLock(void) { mLock->Unlock(); } private: - MutexAutoLock(); - MutexAutoLock(MutexAutoLock&); - MutexAutoLock& operator=(MutexAutoLock&); + BaseAutoLock(); + BaseAutoLock(BaseAutoLock&); + BaseAutoLock& operator=(BaseAutoLock&); static void* operator new(size_t) CPP_THROW_NEW; static void operator delete(void*); - mozilla::Mutex* mLock; + T* mLock; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; +typedef BaseAutoLock MutexAutoLock; /** * MutexAutoUnlock @@ -207,10 +209,11 @@ private: * * MUCH PREFERRED to bare calls to Mutex.Unlock and Lock. */ -class NS_COM_GLUE NS_STACK_CLASS MutexAutoUnlock +template +class NS_COM_GLUE NS_STACK_CLASS BaseAutoUnlock { public: - MutexAutoUnlock(mozilla::Mutex& aLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : + BaseAutoUnlock(T& aLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : mLock(&aLock) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; @@ -218,22 +221,23 @@ public: mLock->Unlock(); } - ~MutexAutoUnlock() + ~BaseAutoUnlock() { mLock->Lock(); } private: - MutexAutoUnlock(); - MutexAutoUnlock(MutexAutoUnlock&); - MutexAutoUnlock& operator =(MutexAutoUnlock&); + BaseAutoUnlock(); + BaseAutoUnlock(BaseAutoUnlock&); + BaseAutoUnlock& operator =(BaseAutoUnlock&); static void* operator new(size_t) CPP_THROW_NEW; static void operator delete(void*); - mozilla::Mutex* mLock; + T* mLock; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; +typedef BaseAutoUnlock MutexAutoUnlock; } // namespace mozilla diff --git a/xulrunner/stub/Makefile.in b/xulrunner/stub/Makefile.in index 67a5f157109..4f4d414aeb9 100644 --- a/xulrunner/stub/Makefile.in +++ b/xulrunner/stub/Makefile.in @@ -45,6 +45,10 @@ include $(DEPTH)/config/autoconf.mk MODULE = xulrunner +# Statically link against the RTL on windows +USE_STATIC_LIBS = 1 +# Don't create a dependency on mozglue +MOZ_GLUE_LDFLAGS = CPPSRCS = nsXULStub.cpp