Merge last PGO-green changeset of mozilla-inbound to mozilla-central

This commit is contained in:
Ed Morley 2012-08-13 19:08:26 +01:00
Родитель 6ecc3ed030 6f560428f4
Коммит 94d1e10bd0
133 изменённых файлов: 1948 добавлений и 1322 удалений

Просмотреть файл

@ -87,20 +87,12 @@ endif
CONFIG_TOOLS = $(MOZ_BUILD_ROOT)/config
AUTOCONF_TOOLS = $(topsrcdir)/build/autoconf
ifeq ($(OS_ARCH),QNX)
ifeq ($(OS_TARGET),NTO)
LD := qcc -Vgcc_ntox86 -nostdlib
else
LD := $(CC)
endif
endif
#
# Strip off the excessively long version numbers on these platforms,
# but save the version to allow multiple versions of the same base
# platform to be built in the same tree.
#
ifneq (,$(filter FreeBSD HP-UX Linux NetBSD OpenBSD OSF1 SunOS,$(OS_ARCH)))
ifneq (,$(filter FreeBSD HP-UX Linux NetBSD OpenBSD SunOS,$(OS_ARCH)))
OS_RELEASE := $(basename $(OS_RELEASE))
# Allow the user to ignore the OS_VERSION, which is usually irrelevant.

Просмотреть файл

@ -500,17 +500,6 @@ endif # HAS_EXTRAEXPORTS
endif # IS_COMPONENT
endif # AIX
#
# OSF1: add -B symbolic flag for components
#
ifeq ($(OS_ARCH),OSF1)
ifdef IS_COMPONENT
ifeq ($(GNU_CC)$(GNU_CXX),)
EXTRA_DSO_LDOPTS += -B symbolic
endif
endif
endif
#
# Linux: add -Bsymbolic flag for components
#

Просмотреть файл

@ -607,10 +607,7 @@ PRInt32
nsGenericElement::GetScrollTop()
{
nsIScrollableFrame* sf = GetScrollFrame();
return sf ?
nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollPosition().y) :
0;
return sf ? sf->GetScrollPositionCSSPixels().y : 0;
}
NS_IMETHODIMP
@ -626,9 +623,7 @@ nsGenericElement::SetScrollTop(PRInt32 aScrollTop)
{
nsIScrollableFrame* sf = GetScrollFrame();
if (sf) {
nsPoint pt = sf->GetScrollPosition();
sf->ScrollToCSSPixels(nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
aScrollTop));
sf->ScrollToCSSPixels(nsIntPoint(sf->GetScrollPositionCSSPixels().x, aScrollTop));
}
return NS_OK;
}
@ -637,10 +632,7 @@ PRInt32
nsGenericElement::GetScrollLeft()
{
nsIScrollableFrame* sf = GetScrollFrame();
return sf ?
nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollPosition().x) :
0;
return sf ? sf->GetScrollPositionCSSPixels().x : 0;
}
NS_IMETHODIMP
@ -656,9 +648,7 @@ nsGenericElement::SetScrollLeft(PRInt32 aScrollLeft)
{
nsIScrollableFrame* sf = GetScrollFrame();
if (sf) {
nsPoint pt = sf->GetScrollPosition();
sf->ScrollToCSSPixels(nsIntPoint(aScrollLeft,
nsPresContext::AppUnitsToIntCSSPixels(pt.y)));
sf->ScrollToCSSPixels(nsIntPoint(aScrollLeft, sf->GetScrollPositionCSSPixels().y));
}
return NS_OK;
}

Просмотреть файл

@ -4645,23 +4645,20 @@ nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
return nullptr;
}
CanvasRenderingContext2DUserDataAzure *userData = nullptr;
if (aBuilder->IsPaintingToWindow()) {
// Make the layer tell us whenever a transaction finishes (including
// the current transaction), so we can clear our invalidation state and
// start invalidating again. We need to do this for the layer that is
// being painted to a window (there shouldn't be more than one at a time,
// and if there is, flushing the invalidation state more often than
// necessary is harmless).
// Make the layer tell us whenever a transaction finishes (including
// the current transaction), so we can clear our invalidation state and
// start invalidating again. We need to do this for all layers since
// callers of DrawWindow may be expecting to receive normal invalidation
// notifications after this paint.
// The layer will be destroyed when we tear down the presentation
// (at the latest), at which time this userData will be destroyed,
// releasing the reference to the element.
// The userData will receive DidTransactionCallbacks, which flush the
// the invalidation state to indicate that the canvas is up to date.
userData = new CanvasRenderingContext2DUserDataAzure(this);
canvasLayer->SetDidTransactionCallback(
CanvasRenderingContext2DUserDataAzure::DidTransactionCallback, userData);
}
// The layer will be destroyed when we tear down the presentation
// (at the latest), at which time this userData will be destroyed,
// releasing the reference to the element.
// The userData will receive DidTransactionCallbacks, which flush the
// the invalidation state to indicate that the canvas is up to date.
userData = new CanvasRenderingContext2DUserDataAzure(this);
canvasLayer->SetDidTransactionCallback(
CanvasRenderingContext2DUserDataAzure::DidTransactionCallback, userData);
canvasLayer->SetUserData(&g2DContextLayerUserData, userData);
CanvasLayer::Data data;

Просмотреть файл

@ -332,7 +332,6 @@ public:
static DeltaValues AccelerateWheelDelta(widget::WheelEvent* aEvent,
bool aAllowScrollSpeedOverride);
static bool IsAccelerationEnabled();
enum {
kScrollSeriesTimeout = 80
@ -588,12 +587,6 @@ nsMouseWheelTransaction::GetIgnoreMoveDelayTime()
return Preferences::GetUint("mousewheel.transaction.ignoremovedelay", 100);
}
bool
nsMouseWheelTransaction::IsAccelerationEnabled()
{
return GetAccelerationStart() >= 0 && GetAccelerationFactor() > 0;
}
DeltaValues
nsMouseWheelTransaction::AccelerateWheelDelta(widget::WheelEvent* aEvent,
bool aAllowScrollSpeedOverride)

Просмотреть файл

@ -61,7 +61,6 @@ var observers = os.enumerateObservers("invalidformsubmit");
*/
if (observers.hasMoreElements()) {
document.getElementById('av').addEventListener("invalid", function(aEvent) {
aEvent.target.removeAttribute("invalid", arguments.callee, false);
ok(true, "formnovalidate should not apply on if not set on the submit " +
@ -133,6 +132,8 @@ if (observers.hasMoreElements()) {
SimpleTest.waitForFocus(function() {
document.getElementById('a').click();
});
} else {
todo(false, "No 'invalidformsubmit' observers. Skip test.");
}
</script>

Просмотреть файл

@ -98,6 +98,8 @@ if (observers.hasMoreElements()) {
checkPseudoClass(textarea, false);
checkPseudoClass(input, false);
checkPseudoClass(select, false);
} else {
todo(false, "No 'invalidformsubmit' observers. Skip test.");
}
</script>

Просмотреть файл

@ -104,6 +104,8 @@ if (observers.hasMoreElements()) {
checkPseudoClass(textarea, false);
checkPseudoClass(input, false);
checkPseudoClass(select, false);
} else {
todo(false, "No 'invalidformsubmit' observers. Skip test.");
}
</script>

Просмотреть файл

@ -54,6 +54,8 @@
#include "nsIDOMGlobalPropertyInitializer.h"
using namespace mozilla::dom::power;
// This should not be in the namespace.
DOMCI_DATA(Navigator, mozilla::dom::Navigator)
@ -1029,11 +1031,11 @@ Navigator::GetMozPower(nsIDOMMozPowerManager** aPower)
*aPower = nullptr;
if (!mPowerManager) {
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(win, NS_OK);
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_OK);
mPowerManager = new power::PowerManager();
mPowerManager->Init(win);
mPowerManager = PowerManager::CheckPermissionAndCreateInstance(window);
NS_ENSURE_TRUE(mPowerManager, NS_OK);
}
nsCOMPtr<nsIDOMMozPowerManager> power(mPowerManager);

Просмотреть файл

@ -540,6 +540,7 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
#include "LockedFile.h"
#include "GeneratedEvents.h"
#include "mozilla/Likely.h"
#include "nsDebug.h"
#undef None // something included above defines this preprocessor symbol, maybe Xlib headers
#include "WebGLContext.h"
@ -2073,8 +2074,10 @@ SetParentToWindow(nsGlobalWindow *win, JSObject **parent)
if (MOZ_UNLIKELY(!*parent)) {
// The only known case where this can happen is when the inner window has
// been torn down. See bug 691178 comment 11.
MOZ_ASSERT(win->IsClosedOrClosing());
// been torn down. See bug 691178 comment 11. Should be a fatal MOZ_ASSERT,
// but we've found a way to hit it too often in mochitests. See bugs 777875
// 778424, 781078.
NS_ASSERTION(win->IsClosedOrClosing(), "win should be closed or closing");
return NS_ERROR_FAILURE;
}
return NS_OK;

Просмотреть файл

@ -4322,11 +4322,13 @@ nsGlobalWindow::GetScrollXY(PRInt32* aScrollX, PRInt32* aScrollY,
return GetScrollXY(aScrollX, aScrollY, true);
}
if (aScrollX)
*aScrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x);
if (aScrollY)
*aScrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y);
nsIntPoint scrollPosCSSPixels = sf->GetScrollPositionCSSPixels();
if (aScrollX) {
*aScrollX = scrollPosCSSPixels.x;
}
if (aScrollY) {
*aScrollY = scrollPosCSSPixels.y;
}
return NS_OK;
}

Просмотреть файл

@ -654,6 +654,12 @@ PluginInstanceParent::RecvShow(const NPRect& updatedRect,
}
mFrontSurface = surface;
if (!surface) {
ImageContainer* container = GetImageContainer();
if (container) {
container->SetCurrentImage(nullptr);
}
}
RecvNPN_InvalidateRect(updatedRect);
PLUGIN_LOG_DEBUG((" (RecvShow invalidated for surface %p)",

Просмотреть файл

@ -6,9 +6,10 @@
#include "mozilla/Hal.h"
#include "PowerManager.h"
#include "WakeLock.h"
#include "nsContentUtils.h"
#include "nsDOMClassInfoID.h"
#include "nsIDOMWakeLockListener.h"
#include "nsIDocument.h"
#include "nsIPermissionManager.h"
#include "nsIPowerManagerService.h"
#include "nsIPrincipal.h"
#include "nsPIDOMWindow.h"
@ -57,33 +58,9 @@ PowerManager::Shutdown()
return NS_OK;
}
bool
PowerManager::CheckPermission()
{
if (nsContentUtils::IsCallerChrome()) {
return true;
}
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(win, false);
nsCOMPtr<nsIDocument> doc = do_QueryInterface(win->GetExtantDocument());
NS_ENSURE_TRUE(doc, false);
nsCOMPtr<nsIURI> uri;
doc->NodePrincipal()->GetURI(getter_AddRefs(uri));
if (!nsContentUtils::URIIsChromeOrInPref(uri, "dom.power.whitelist")) {
return false;
}
return true;
}
NS_IMETHODIMP
PowerManager::Reboot()
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_STATE(pmService);
@ -96,8 +73,6 @@ PowerManager::Reboot()
NS_IMETHODIMP
PowerManager::PowerOff()
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_STATE(pmService);
@ -110,8 +85,6 @@ PowerManager::PowerOff()
NS_IMETHODIMP
PowerManager::AddWakeLockListener(nsIDOMMozWakeLockListener *aListener)
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
// already added? bail out.
if (mListeners.Contains(aListener))
return NS_OK;
@ -123,8 +96,6 @@ PowerManager::AddWakeLockListener(nsIDOMMozWakeLockListener *aListener)
NS_IMETHODIMP
PowerManager::RemoveWakeLockListener(nsIDOMMozWakeLockListener *aListener)
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
mListeners.RemoveElement(aListener);
return NS_OK;
}
@ -132,8 +103,6 @@ PowerManager::RemoveWakeLockListener(nsIDOMMozWakeLockListener *aListener)
NS_IMETHODIMP
PowerManager::GetWakeLockState(const nsAString &aTopic, nsAString &aState)
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_STATE(pmService);
@ -163,11 +132,6 @@ PowerManager::Callback(const nsAString &aTopic, const nsAString &aState)
NS_IMETHODIMP
PowerManager::GetScreenEnabled(bool *aEnabled)
{
if (!CheckPermission()) {
*aEnabled = true;
return NS_OK;
}
*aEnabled = hal::GetScreenEnabled();
return NS_OK;
}
@ -175,10 +139,6 @@ PowerManager::GetScreenEnabled(bool *aEnabled)
NS_IMETHODIMP
PowerManager::SetScreenEnabled(bool aEnabled)
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
// TODO bug 707589: When the screen's state changes, all visible windows
// should fire a visibility change event.
hal::SetScreenEnabled(aEnabled);
return NS_OK;
}
@ -186,11 +146,6 @@ PowerManager::SetScreenEnabled(bool aEnabled)
NS_IMETHODIMP
PowerManager::GetScreenBrightness(double *aBrightness)
{
if (!CheckPermission()) {
*aBrightness = 1;
return NS_OK;
}
*aBrightness = hal::GetScreenBrightness();
return NS_OK;
}
@ -198,8 +153,6 @@ PowerManager::GetScreenBrightness(double *aBrightness)
NS_IMETHODIMP
PowerManager::SetScreenBrightness(double aBrightness)
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
NS_ENSURE_TRUE(0 <= aBrightness && aBrightness <= 1, NS_ERROR_INVALID_ARG);
hal::SetScreenBrightness(aBrightness);
return NS_OK;
@ -208,11 +161,6 @@ PowerManager::SetScreenBrightness(double aBrightness)
NS_IMETHODIMP
PowerManager::GetCpuSleepAllowed(bool *aAllowed)
{
if (!CheckPermission()) {
*aAllowed = true;
return NS_OK;
}
*aAllowed = hal::GetCpuSleepAllowed();
return NS_OK;
}
@ -220,12 +168,40 @@ PowerManager::GetCpuSleepAllowed(bool *aAllowed)
NS_IMETHODIMP
PowerManager::SetCpuSleepAllowed(bool aAllowed)
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
hal::SetCpuSleepAllowed(aAllowed);
return NS_OK;
}
already_AddRefed<PowerManager>
PowerManager::CheckPermissionAndCreateInstance(nsPIDOMWindow* aWindow)
{
nsPIDOMWindow* innerWindow = aWindow->IsInnerWindow() ?
aWindow :
aWindow->GetCurrentInnerWindow();
// Need the document for security check.
nsCOMPtr<nsIDocument> document = innerWindow->GetExtantDoc();
NS_ENSURE_TRUE(document, nullptr);
nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
nsCOMPtr<nsIPermissionManager> permMgr =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
NS_ENSURE_TRUE(permMgr, nullptr);
PRUint32 permission = nsIPermissionManager::DENY_ACTION;
permMgr->TestPermissionFromPrincipal(principal, "power", &permission);
if (permission != nsIPermissionManager::ALLOW_ACTION) {
return nullptr;
}
nsRefPtr<PowerManager> powerManager = new PowerManager();
powerManager->Init(aWindow);
return powerManager.forget();
}
} // power
} // dom
} // mozilla

Просмотреть файл

@ -12,6 +12,8 @@
#include "nsIDOMWindow.h"
#include "nsWeakReference.h"
class nsPIDOMWindow;
namespace mozilla {
namespace dom {
namespace power {
@ -31,8 +33,10 @@ public:
nsresult Init(nsIDOMWindow *aWindow);
nsresult Shutdown();
static already_AddRefed<PowerManager>
CheckPermissionAndCreateInstance(nsPIDOMWindow*);
private:
bool CheckPermission();
nsWeakPtr mWindow;
nsTArray<nsCOMPtr<nsIDOMMozWakeLockListener> > mListeners;

Просмотреть файл

@ -1,10 +1,13 @@
/* 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";
waitForExplicitFinish();
let kPrefNode = "dom.power.whitelist";
let kPageSource1 = "data:text/html,1";
let kPageSource2 = "data:text/html,2";
let kUrlSource = "http://mochi.test:8888/";
let kDataSource = "data:text/html,";
let gOldPref;
let gWin, gWin1, gWin2;
@ -13,7 +16,7 @@ let gLock, gLock1, gLock2;
let gCurStepIndex = -1;
let gSteps = [
function basicWakeLock() {
gTab = gBrowser.addTab(kPageSource1);
gTab = gBrowser.addTab(kUrlSource);
gWin = gBrowser.getBrowserForTab(gTab).contentWindow;
let browser = gBrowser.getBrowserForTab(gTab);
@ -51,7 +54,7 @@ let gSteps = [
}, true);
},
function multiWakeLock() {
gTab = gBrowser.addTab(kPageSource1);
gTab = gBrowser.addTab(kUrlSource);
gWin = gBrowser.getBrowserForTab(gTab).contentWindow;
let browser = gBrowser.getBrowserForTab(gTab);
@ -100,9 +103,9 @@ let gSteps = [
}, true);
},
function crossTabWakeLock1() {
gTab1 = gBrowser.addTab(kPageSource1);
gTab1 = gBrowser.addTab(kUrlSource);
gWin1 = gBrowser.getBrowserForTab(gTab1).contentWindow;
gTab2 = gBrowser.addTab(kPageSource1);
gTab2 = gBrowser.addTab(kUrlSource);
gWin2 = gBrowser.getBrowserForTab(gTab2).contentWindow;
gBrowser.selectedTab = gTab1;
@ -138,7 +141,7 @@ let gSteps = [
gWin2.removeEventListener("pageshow", onPageShow, true);
executeSoon(runNextStep);
}, true);
gWin2.location = kPageSource2;
gWin2.location = kDataSource;
},
function crossTabWakeLock3() {
is(gWin1.navigator.mozPower.getWakeLockState("test"), "unlocked",
@ -166,7 +169,7 @@ let gSteps = [
gWin2.removeEventListener("pageshow", onPageShow, true);
executeSoon(runNextStep);
}, true);
gWin2.location = kPageSource2;
gWin2.location = kDataSource;
},
function crossTabWakeLock6() {
is(gWin1.navigator.mozPower.getWakeLockState("test"), "unlocked",
@ -219,18 +222,12 @@ function runNextStep() {
if (gCurStepIndex < gSteps.length) {
gSteps[gCurStepIndex]();
} else {
Services.prefs.setCharPref(kPrefNode, gOldPref);
SpecialPowers.removePermission("power", kUrlSource);
finish();
}
}
function test() {
try {
gOldPref = Services.prefs.getCharPref(kPrefNode);
} catch (e) {
gOldPref = "";
}
// data url inherits its parent's principal, which is |about:| here.
Services.prefs.setCharPref(kPrefNode, "about:");
SpecialPowers.addPermission("power", true, kUrlSource);
runNextStep();
}

Просмотреть файл

@ -16,6 +16,18 @@
ok('mozPower' in navigator, "navigator.mozPower should exist");
/** Test permission **/
SpecialPowers.removePermission("power", document);
power = navigator.mozPower;
ok(!power, "Shouldn't be able to access power manager without permission.");
SpecialPowers.addPermission("power", true, document);
power = navigator.mozPower;
ok(power, "Shouldn be able to access power manager with permission.");
</script>
</pre>
</body>

Просмотреть файл

@ -541,7 +541,7 @@ RadioInterfaceLayer.prototype = {
newInfo.state == RIL.GECKO_MOBILE_CONNECTION_STATE_REGISTERED &&
(!newInfo.roaming || this._isDataRoamingEnabled());
let haveDataConnection =
newInfo.type != GECKO_MOBILE_CONNECTION_STATE_UNKNOWN;
newInfo.type != RIL.GECKO_MOBILE_CONNECTION_STATE_UNKNOWN;
if (isRegistered && haveDataConnection) {
debug("Radio is ready for data connection.");
@ -680,8 +680,9 @@ RadioInterfaceLayer.prototype = {
case nsIRadioInterfaceLayer.CALL_STATE_DIALING: // Fall through...
case nsIRadioInterfaceLayer.CALL_STATE_CONNECTED:
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL;
gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION,
nsIAudioManager.FORCE_NONE);
let force = this.speakerEnabled ? nsIAudioManager.FORCE_SPEAKER
: nsIAudioManager.FORCE_NONE;
gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, force);
debug("Active call, put audio system into PHONE_STATE_IN_CALL: "
+ gAudioManager.phoneState);
break;

Просмотреть файл

@ -53,14 +53,14 @@ const PDU_HEX_OCTET_SIZE = 4;
const DEFAULT_EMERGENCY_NUMBERS = ["112", "911"];
let RILQUIRKS_CALLSTATE_EXTRA_UINT32 = false;
let RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = false;
// This flag defaults to true since on RIL v6 and later, we get the
// version number via the UNSOLICITED_RIL_CONNECTED parcel.
let RILQUIRKS_V5_LEGACY = true;
let RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL = false;
let RILQUIRKS_MODEM_DEFAULTS_TO_EMERGENCY_MODE = false;
let RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS = false;
let RILQUIRKS_CALLSTATE_EXTRA_UINT32 = libcutils.property_get("ro.moz.ril.callstate_extra_int");
let RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = libcutils.property_get("ro.moz.ril.callstate_down_is_up");
// This may change at runtime since in RIL v6 and later, we get the version
// number via the UNSOLICITED_RIL_CONNECTED parcel.
let RILQUIRKS_V5_LEGACY = libcutils.property_get("ro.moz.ril.v5_legacy");
let RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL = libcutils.property_get("ro.moz.ril.dial_emergency_call");
let RILQUIRKS_MODEM_DEFAULTS_TO_EMERGENCY_MODE = libcutils.property_get("ro.moz.ril.emergency_by_default");
let RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS = libcutils.property_get("ro.moz.ril.simstate_extra_field");
// Marker object.
let PENDING_NETWORK_TYPE = {};
@ -691,71 +691,6 @@ let RIL = {
}
},
/**
* Set quirk flags based on the RIL model detected. Note that this
* requires the RIL being "warmed up" first, which happens when on
* an incoming or outgoing voice call or data call.
*/
rilQuirksInitialized: false,
initRILQuirks: function initRILQuirks() {
if (this.rilQuirksInitialized) {
return;
}
let ril_impl = libcutils.property_get("gsm.version.ril-impl");
if (DEBUG) debug("Detected RIL implementation " + ril_impl);
switch (ril_impl) {
case "Samsung RIL(IPC) v2.0":
// The Samsung Galaxy S2 I-9100 radio sends an extra Uint32 in the
// call state.
let model_id = libcutils.property_get("ril.model_id");
if (DEBUG) debug("Detected RIL model " + model_id);
if (!model_id) {
// On some RIL models, the RIL has to be "warmed up" for us to read this property.
// It apparently isn't warmed up yet, going to try again later.
if (DEBUG) debug("Could not detect correct model_id. Going to try later.");
return;
}
if (model_id == "I9100") {
if (DEBUG) {
debug("Detected I9100, enabling " +
"RILQUIRKS_CALLSTATE_EXTRA_UINT32, " +
"RILQUIRKS_DATACALLSTATE_DOWN_IS_UP, " +
"RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL.");
}
RILQUIRKS_CALLSTATE_EXTRA_UINT32 = true;
RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = true;
RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL = true;
}
if (model_id == "I9023" || model_id == "I9020") {
if (DEBUG) {
debug("Detected I9020/I9023, enabling " +
"RILQUIRKS_DATACALLSTATE_DOWN_IS_UP");
}
RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = true;
}
break;
case "Qualcomm RIL 1.0":
let product_model = libcutils.property_get("ro.product.model");
if (DEBUG) debug("Detected product model " + product_model);
if (product_model == "otoro1") {
if (DEBUG) debug("Enabling RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS.");
RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS = true;
}
if (DEBUG) {
debug("Detected Qualcomm RIL 1.0, " +
"disabling RILQUIRKS_V5_LEGACY and " +
"enabling RILQUIRKS_MODEM_DEFAULTS_TO_EMERGENCY_MODE.");
}
RILQUIRKS_V5_LEGACY = false;
RILQUIRKS_MODEM_DEFAULTS_TO_EMERGENCY_MODE = true;
break;
}
this.rilQuirksInitialized = true;
},
/**
* Parse an integer from a string, falling back to a default value
* if the the provided value is not a string or does not contain a valid
@ -2261,8 +2196,6 @@ let RIL = {
},
_processVoiceRegistrationState: function _processVoiceRegistrationState(state) {
this.initRILQuirks();
let rs = this.voiceRegistrationState;
let stateChanged = this._processCREG(rs, state);
if (stateChanged && rs.connected) {
@ -2951,8 +2884,6 @@ RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length, opti
return;
}
this.initRILQuirks();
let calls_length = 0;
// The RIL won't even send us the length integer if there are no active calls.
// So only read this integer if the parcel actually has it.
@ -3477,7 +3408,6 @@ RIL[REQUEST_DATA_CALL_LIST] = function REQUEST_DATA_CALL_LIST(length, options) {
return;
}
this.initRILQuirks();
if (!length) {
this._processDataCallList(null);
return;
@ -3736,7 +3666,6 @@ RIL[UNSOLICITED_RIL_CONNECTED] = function UNSOLICITED_RIL_CONNECTED(length) {
// Prevent response id collision between UNSOLICITED_RIL_CONNECTED and
// UNSOLICITED_VOICE_RADIO_TECH_CHANGED for Akami on gingerbread branch.
if (!length) {
this.initRILQuirks();
return;
}

Просмотреть файл

@ -1578,6 +1578,25 @@ DrawTargetD2D::FinalizeRTForOperation(CompositionOp aOperator, const Pattern &aP
mDevice->Draw(4, 0);
}
TemporaryRef<ID2D1Geometry>
DrawTargetD2D::ConvertRectToGeometry(const D2D1_RECT_F& aRect)
{
RefPtr<ID2D1RectangleGeometry> rectGeom;
factory()->CreateRectangleGeometry(&aRect, byRef(rectGeom));
return rectGeom.forget();
}
static D2D1_RECT_F
IntersectRect(const D2D1_RECT_F& aRect1, const D2D1_RECT_F& aRect2)
{
D2D1_RECT_F result;
result.left = max(aRect1.left, aRect2.left);
result.top = max(aRect1.top, aRect2.top);
result.right = min(aRect1.right, aRect2.right);
result.bottom = min(aRect1.bottom, aRect2.bottom);
return result;
}
TemporaryRef<ID2D1Geometry>
DrawTargetD2D::GetClippedGeometry()
{
@ -1585,46 +1604,58 @@ DrawTargetD2D::GetClippedGeometry()
return mCurrentClippedGeometry;
}
RefPtr<ID2D1GeometrySink> currentSink;
factory()->CreatePathGeometry(byRef(mCurrentClippedGeometry));
mCurrentClippedGeometry->Open(byRef(currentSink));
// if pathGeom is null then pathRect represents the path.
RefPtr<ID2D1Geometry> pathGeom;
D2D1_RECT_F pathRect;
std::vector<DrawTargetD2D::PushedClip>::iterator iter = mPushedClips.begin();
if (iter->mPath) {
RefPtr<ID2D1PathGeometry> tmpGeometry;
factory()->CreatePathGeometry(byRef(tmpGeometry));
RefPtr<ID2D1GeometrySink> currentSink;
tmpGeometry->Open(byRef(currentSink));
iter->mPath->GetGeometry()->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
iter->mTransform, currentSink);
currentSink->Close();
pathGeom = tmpGeometry.forget();
} else {
RefPtr<ID2D1RectangleGeometry> rectGeom;
factory()->CreateRectangleGeometry(iter->mBounds, byRef(rectGeom));
rectGeom->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
D2D1::IdentityMatrix(), currentSink);
pathRect = iter->mBounds;
}
currentSink->Close();
iter++;
for (;iter != mPushedClips.end(); iter++) {
if (!pathGeom) {
if (iter->mPath) {
pathGeom = ConvertRectToGeometry(pathRect);
} else {
pathRect = IntersectRect(pathRect, iter->mBounds);
continue;
}
}
RefPtr<ID2D1PathGeometry> newGeom;
factory()->CreatePathGeometry(byRef(newGeom));
RefPtr<ID2D1GeometrySink> currentSink;
newGeom->Open(byRef(currentSink));
if (iter->mPath) {
mCurrentClippedGeometry->CombineWithGeometry(iter->mPath->GetGeometry(), D2D1_COMBINE_MODE_INTERSECT,
iter->mTransform, currentSink);
pathGeom->CombineWithGeometry(iter->mPath->GetGeometry(), D2D1_COMBINE_MODE_INTERSECT,
iter->mTransform, currentSink);
} else {
RefPtr<ID2D1RectangleGeometry> rectGeom;
factory()->CreateRectangleGeometry(iter->mBounds, byRef(rectGeom));
mCurrentClippedGeometry->CombineWithGeometry(rectGeom, D2D1_COMBINE_MODE_INTERSECT,
D2D1::IdentityMatrix(), currentSink);
RefPtr<ID2D1Geometry> rectGeom = ConvertRectToGeometry(iter->mBounds);
pathGeom->CombineWithGeometry(rectGeom, D2D1_COMBINE_MODE_INTERSECT,
D2D1::IdentityMatrix(), currentSink);
}
currentSink->Close();
mCurrentClippedGeometry = newGeom;
pathGeom = newGeom.forget();
}
if (!pathGeom) {
pathGeom = ConvertRectToGeometry(pathRect);
}
mCurrentClippedGeometry = pathGeom.forget();
return mCurrentClippedGeometry;
}

Просмотреть файл

@ -182,6 +182,7 @@ private:
const DrawOptions &aOptions = DrawOptions());
TemporaryRef<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
TemporaryRef<ID2D1Geometry> ConvertRectToGeometry(const D2D1_RECT_F& aRect);
TemporaryRef<ID2D1Geometry> GetClippedGeometry();
TemporaryRef<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f);
@ -205,7 +206,7 @@ private:
RefPtr<ID3D10Device1> mDevice;
RefPtr<ID3D10Texture2D> mTexture;
RefPtr<ID3D10Texture2D> mCurrentClipMaskTexture;
RefPtr<ID2D1PathGeometry> mCurrentClippedGeometry;
RefPtr<ID2D1Geometry> mCurrentClippedGeometry;
mutable RefPtr<ID2D1RenderTarget> mRT;
// We store this to prevent excessive SetTextRenderingParams calls.

Просмотреть файл

@ -181,6 +181,13 @@ public:
* EndTransaction returns.
*/
virtual void BeginTransactionWithTarget(gfxContext* aTarget) = 0;
enum EndTransactionFlags {
END_DEFAULT = 0,
END_NO_IMMEDIATE_REDRAW = 1 << 0, // Do not perform the drawing phase
END_NO_COMPOSITE = 1 << 1 // Do not composite after drawing thebes layer contents.
};
/**
* Attempts to end an "empty transaction". There must have been no
* changes to the layer tree since the BeginTransaction().
@ -189,7 +196,7 @@ public:
* returns false, and the caller must proceed with a normal layer tree
* update and EndTransaction.
*/
virtual bool EndEmptyTransaction() = 0;
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) = 0;
/**
* Function called to draw the contents of each ThebesLayer.
@ -223,11 +230,6 @@ public:
const nsIntRegion& aRegionToInvalidate,
void* aCallbackData);
enum EndTransactionFlags {
END_DEFAULT = 0,
END_NO_IMMEDIATE_REDRAW = 1 << 0 // Do not perform the drawing phase
};
/**
* Finish the construction phase of the transaction, perform the
* drawing phase, and end the transaction.
@ -239,6 +241,9 @@ public:
void* aCallbackData,
EndTransactionFlags aFlags = END_DEFAULT) = 0;
virtual bool HasShadowManagerInternal() const { return false; }
bool HasShadowManager() const { return HasShadowManagerInternal(); }
bool IsSnappingEffectiveTransforms() { return mSnapEffectiveTransforms; }
/**

Просмотреть файл

@ -421,6 +421,12 @@ BasicLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
mTransactionIncomplete = false;
if (aFlags & END_NO_COMPOSITE) {
// TODO: We should really just set mTarget to null and make sure we can handle that further down the call chain
nsRefPtr<gfxASurface> surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(1, 1), gfxASurface::CONTENT_COLOR);
mTarget = new gfxContext(surf);
}
if (mTarget && mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) {
nsIntRect clipRect;
if (HasShadowManager()) {
@ -450,9 +456,19 @@ BasicLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
}
}
PaintLayer(mTarget, mRoot, aCallback, aCallbackData, nullptr);
if (mWidget) {
FlashWidgetUpdateArea(mTarget);
if (aFlags & END_NO_COMPOSITE) {
if (IsRetained()) {
// Clip the destination out so that we don't draw to it, and
// only end up validating ThebesLayers.
mTarget->Clip(gfxRect(0, 0, 0, 0));
PaintLayer(mTarget, mRoot, aCallback, aCallbackData, nullptr);
}
// If we're not retained, then don't composite means do nothing at all.
} else {
PaintLayer(mTarget, mRoot, aCallback, aCallbackData, nullptr);
if (mWidget) {
FlashWidgetUpdateArea(mTarget);
}
}
if (!mTransactionIncomplete) {
@ -508,13 +524,13 @@ BasicLayerManager::FlashWidgetUpdateArea(gfxContext *aContext)
}
bool
BasicLayerManager::EndEmptyTransaction()
BasicLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
{
if (!mRoot) {
return false;
}
return EndTransactionInternal(nullptr, nullptr);
return EndTransactionInternal(nullptr, nullptr, aFlags);
}
void
@ -1039,9 +1055,9 @@ BasicShadowLayerManager::EndTransaction(DrawThebesLayerCallback aCallback,
}
bool
BasicShadowLayerManager::EndEmptyTransaction()
BasicShadowLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
{
if (!BasicLayerManager::EndEmptyTransaction()) {
if (!BasicLayerManager::EndEmptyTransaction(aFlags)) {
// Return without calling ForwardTransaction. This leaves the
// ShadowLayerForwarder transaction open; the following
// EndTransaction will complete it.

Просмотреть файл

@ -87,7 +87,7 @@ public:
virtual void BeginTransaction();
virtual void BeginTransactionWithTarget(gfxContext* aTarget);
virtual bool EndEmptyTransaction();
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags = END_DEFAULT);
@ -150,8 +150,6 @@ public:
void PopGroupToSourceWithCachedSurface(gfxContext *aTarget, gfxContext *aPushed);
virtual bool IsCompositingCheap() { return false; }
virtual bool HasShadowManagerInternal() const { return false; }
bool HasShadowManager() const { return HasShadowManagerInternal(); }
virtual PRInt32 GetMaxTextureSize() const { return PR_INT32_MAX; }
protected:
@ -221,7 +219,7 @@ public:
virtual void SetDefaultTarget(gfxContext* aContext, BufferMode aDoubleBuffering,
ScreenRotation aRotation) MOZ_OVERRIDE;
virtual void BeginTransactionWithTarget(gfxContext* aTarget);
virtual bool EndEmptyTransaction();
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags = END_DEFAULT);

Просмотреть файл

@ -27,9 +27,7 @@ BasicThebesLayer::CreateBuffer(Buffer::ContentType aType, const nsIntSize& aSize
referenceSurface = defaultTarget->CurrentSurface();
} else {
nsIWidget* widget = BasicManager()->GetRetainerWidget();
if (widget) {
referenceSurface = widget->GetThebesSurface();
} else {
if (!widget || !(referenceSurface = widget->GetThebesSurface())) {
referenceSurface = BasicManager()->GetTarget()->CurrentSurface();
}
}

Просмотреть файл

@ -28,82 +28,95 @@ ContainerLayerD3D10::~ContainerLayerD3D10()
RemoveChild(mFirstChild);
}
}
template<class Container>
static void
ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter)
{
aChild->SetParent(aContainer);
if (!aAfter) {
Layer *oldFirstChild = aContainer->GetFirstChild();
aContainer->mFirstChild = aChild;
aChild->SetNextSibling(oldFirstChild);
aChild->SetPrevSibling(nullptr);
if (oldFirstChild) {
oldFirstChild->SetPrevSibling(aChild);
} else {
aContainer->mLastChild = aChild;
}
NS_ADDREF(aChild);
aContainer->DidInsertChild(aChild);
return;
}
for (Layer *child = aContainer->GetFirstChild();
child; child = child->GetNextSibling()) {
if (aAfter == child) {
Layer *oldNextSibling = child->GetNextSibling();
child->SetNextSibling(aChild);
aChild->SetNextSibling(oldNextSibling);
if (oldNextSibling) {
oldNextSibling->SetPrevSibling(aChild);
} else {
aContainer->mLastChild = aChild;
}
aChild->SetPrevSibling(child);
NS_ADDREF(aChild);
aContainer->DidInsertChild(aChild);
return;
}
}
NS_WARNING("Failed to find aAfter layer!");
}
template<class Container>
static void
ContainerRemoveChild(Container* aContainer, Layer* aChild)
{
if (aContainer->GetFirstChild() == aChild) {
aContainer->mFirstChild = aContainer->GetFirstChild()->GetNextSibling();
if (aContainer->mFirstChild) {
aContainer->mFirstChild->SetPrevSibling(nullptr);
} else {
aContainer->mLastChild = nullptr;
}
aChild->SetNextSibling(nullptr);
aChild->SetPrevSibling(nullptr);
aChild->SetParent(nullptr);
aContainer->DidRemoveChild(aChild);
NS_RELEASE(aChild);
return;
}
Layer *lastChild = nullptr;
for (Layer *child = aContainer->GetFirstChild(); child;
child = child->GetNextSibling()) {
if (child == aChild) {
// We're sure this is not our first child. So lastChild != NULL.
lastChild->SetNextSibling(child->GetNextSibling());
if (child->GetNextSibling()) {
child->GetNextSibling()->SetPrevSibling(lastChild);
} else {
aContainer->mLastChild = lastChild;
}
child->SetNextSibling(nullptr);
child->SetPrevSibling(nullptr);
child->SetParent(nullptr);
aContainer->DidRemoveChild(aChild);
NS_RELEASE(aChild);
return;
}
lastChild = child;
}
}
void
ContainerLayerD3D10::InsertAfter(Layer* aChild, Layer* aAfter)
{
aChild->SetParent(this);
if (!aAfter) {
Layer *oldFirstChild = GetFirstChild();
mFirstChild = aChild;
aChild->SetNextSibling(oldFirstChild);
aChild->SetPrevSibling(nullptr);
if (oldFirstChild) {
oldFirstChild->SetPrevSibling(aChild);
} else {
mLastChild = aChild;
}
NS_ADDREF(aChild);
DidInsertChild(aChild);
return;
}
for (Layer *child = GetFirstChild();
child; child = child->GetNextSibling()) {
if (aAfter == child) {
Layer *oldNextSibling = child->GetNextSibling();
child->SetNextSibling(aChild);
aChild->SetNextSibling(oldNextSibling);
if (oldNextSibling) {
oldNextSibling->SetPrevSibling(aChild);
} else {
mLastChild = aChild;
}
aChild->SetPrevSibling(child);
NS_ADDREF(aChild);
DidInsertChild(aChild);
return;
}
}
NS_WARNING("Failed to find aAfter layer!");
ContainerInsertAfter(this, aChild, aAfter);
}
void
ContainerLayerD3D10::RemoveChild(Layer *aChild)
{
if (GetFirstChild() == aChild) {
mFirstChild = GetFirstChild()->GetNextSibling();
if (mFirstChild) {
mFirstChild->SetPrevSibling(nullptr);
} else {
mLastChild = nullptr;
}
aChild->SetNextSibling(nullptr);
aChild->SetPrevSibling(nullptr);
aChild->SetParent(nullptr);
DidRemoveChild(aChild);
NS_RELEASE(aChild);
return;
}
Layer *lastChild = nullptr;
for (Layer *child = GetFirstChild(); child;
child = child->GetNextSibling()) {
if (child == aChild) {
// We're sure this is not our first child. So lastChild != NULL.
lastChild->SetNextSibling(child->GetNextSibling());
if (child->GetNextSibling()) {
child->GetNextSibling()->SetPrevSibling(lastChild);
} else {
mLastChild = lastChild;
}
child->SetNextSibling(nullptr);
child->SetPrevSibling(nullptr);
child->SetParent(nullptr);
DidRemoveChild(aChild);
NS_RELEASE(aChild);
return;
}
lastChild = child;
}
ContainerRemoveChild(this, aChild);
}
Layer*
@ -368,18 +381,23 @@ ShadowContainerLayerD3D10::ShadowContainerLayerD3D10(LayerManagerD3D10 *aManager
mImplData = static_cast<LayerD3D10*>(this);
}
ShadowContainerLayerD3D10::~ShadowContainerLayerD3D10() {}
ShadowContainerLayerD3D10::~ShadowContainerLayerD3D10()
{
while (mFirstChild) {
RemoveChild(mFirstChild);
}
}
void
ShadowContainerLayerD3D10::InsertAfter(Layer* aChild, Layer* aAfter)
{
mFirstChild = aChild;
ContainerInsertAfter(this, aChild, aAfter);
}
void
ShadowContainerLayerD3D10::RemoveChild(Layer* aChild)
{
ContainerRemoveChild(this, aChild);
}
void
@ -409,6 +427,10 @@ ShadowContainerLayerD3D10::Validate()
void
ShadowContainerLayerD3D10::LayerManagerDestroyed()
{
while (mFirstChild) {
GetFirstChildD3D10()->LayerManagerDestroyed();
RemoveChild(mFirstChild);
}
}
} /* layers */

Просмотреть файл

@ -11,9 +11,18 @@
namespace mozilla {
namespace layers {
template<class Container>
static void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
static void ContainerRemoveChild(Container* aContainer, Layer* aChild);
class ContainerLayerD3D10 : public ContainerLayer,
public LayerD3D10
{
template<class Container>
friend void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
friend void ContainerRemoveChild(Container* aContainer, Layer* aChild);
public:
ContainerLayerD3D10(LayerManagerD3D10 *aManager);
~ContainerLayerD3D10();
@ -47,6 +56,10 @@ public:
class ShadowContainerLayerD3D10 : public ShadowContainerLayer,
public LayerD3D10
{
template<class Container>
friend void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
friend void ContainerRemoveChild(Container* aContainer, Layer* aChild);
public:
ShadowContainerLayerD3D10(LayerManagerD3D10 *aManager);
~ShadowContainerLayerD3D10();

Просмотреть файл

@ -200,7 +200,7 @@ LayerManagerD3D10::Initialize(bool force)
mInputLayout = attachments->mInputLayout;
}
if (HasShadowManager()) {
if (ShadowLayerForwarder::HasShadowManager()) {
reporter.SetSuccessful();
return true;
}
@ -335,12 +335,12 @@ LayerManagerD3D10::BeginTransactionWithTarget(gfxContext* aTarget)
}
bool
LayerManagerD3D10::EndEmptyTransaction()
LayerManagerD3D10::EndEmptyTransaction(EndTransactionFlags aFlags)
{
if (!mRoot)
return false;
EndTransaction(nullptr, nullptr);
EndTransaction(nullptr, nullptr, aFlags);
return true;
}
@ -362,7 +362,7 @@ LayerManagerD3D10::EndTransaction(DrawThebesLayerCallback aCallback,
Log();
#endif
Render();
Render(aFlags);
mCurrentCallbackInfo.Callback = nullptr;
mCurrentCallbackInfo.CallbackData = nullptr;
}
@ -703,10 +703,14 @@ LayerManagerD3D10::EnsureReadbackManager()
}
void
LayerManagerD3D10::Render()
LayerManagerD3D10::Render(EndTransactionFlags aFlags)
{
static_cast<LayerD3D10*>(mRoot->ImplData())->Validate();
if (aFlags & END_NO_COMPOSITE) {
return;
}
SetupPipeline();
float black[] = { 0, 0, 0, 0 };

Просмотреть файл

@ -85,7 +85,7 @@ public:
virtual void BeginTransactionWithTarget(gfxContext* aTarget);
virtual bool EndEmptyTransaction();
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
struct CallbackInfo {
DrawThebesLayerCallback Callback;
@ -178,7 +178,7 @@ private:
void VerifyBufferSize();
void EnsureReadbackManager();
void Render();
void Render(EndTransactionFlags aFlags);
nsRefPtr<ID3D10Device1> mDevice;

Просмотреть файл

@ -187,6 +187,9 @@ void
CanvasLayerD3D9::RenderLayer()
{
UpdateSurface();
if (mD3DManager->CompositingDisabled()) {
return;
}
FireDidTransactionCallback();
if (!mTexture)
@ -355,7 +358,7 @@ ShadowCanvasLayerD3D9::GetLayer()
void
ShadowCanvasLayerD3D9::RenderLayer()
{
if (!mBuffer) {
if (!mBuffer || mD3DManager->CompositingDisabled()) {
return;
}

Просмотреть файл

@ -19,6 +19,9 @@ RenderColorLayerD3D9(ColorLayer* aLayer, LayerManagerD3D9 *aManager)
{
// XXX we might be able to improve performance by using
// IDirect3DDevice9::Clear
if (aManager->CompositingDisabled()) {
return;
}
nsIntRect visibleRect = aLayer->GetEffectiveVisibleRegion().GetBounds();

Просмотреть файл

@ -147,20 +147,23 @@ ContainerRender(Container* aContainer,
aContainer->mSupportsComponentAlphaChildren = false;
if (useIntermediate) {
aManager->device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget));
HRESULT hr = aManager->device()->CreateTexture(visibleRect.width, visibleRect.height, 1,
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, getter_AddRefs(renderTexture),
NULL);
if (FAILED(hr)) {
aManager->ReportFailure(NS_LITERAL_CSTRING("ContainerLayerD3D9::ContainerRender(): Failed to create texture"),
hr);
return;
}
nsRefPtr<IDirect3DSurface9> renderSurface;
renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface));
aManager->device()->SetRenderTarget(0, renderSurface);
if (!aManager->CompositingDisabled()) {
aManager->device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget));
HRESULT hr = aManager->device()->CreateTexture(visibleRect.width, visibleRect.height, 1,
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, getter_AddRefs(renderTexture),
NULL);
if (FAILED(hr)) {
aManager->ReportFailure(NS_LITERAL_CSTRING("ContainerLayerD3D9::ContainerRender(): Failed to create texture"),
hr);
return;
}
nsRefPtr<IDirect3DSurface9> renderSurface;
renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface));
aManager->device()->SetRenderTarget(0, renderSurface);
}
if (aContainer->mVisibleRegion.GetNumRects() == 1 &&
(aContainer->GetContentFlags() & aContainer->CONTENT_OPAQUE)) {
@ -182,12 +185,14 @@ ContainerRender(Container* aContainer,
::OffsetRect(&src,
visibleRect.x + PRInt32(transform.x0),
visibleRect.y + PRInt32(transform.y0));
hr = aManager->device()->
StretchRect(previousRenderTarget, &src, renderSurface, &dest, D3DTEXF_NONE);
if (!aManager->CompositingDisabled()) {
hr = aManager->device()->
StretchRect(previousRenderTarget, &src, renderSurface, &dest, D3DTEXF_NONE);
}
}
if (hr == S_OK) {
aContainer->mSupportsComponentAlphaChildren = true;
} else {
} else if (!aManager->CompositingDisabled()) {
aManager->device()->
Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 0, 0);
}
@ -256,7 +261,7 @@ ContainerRender(Container* aContainer,
aManager->device()->SetScissorRect(&containerD3D9ClipRect);
if (useIntermediate) {
if (useIntermediate && !aManager->CompositingDisabled()) {
aManager->device()->SetRenderTarget(0, previousRenderTarget);
aManager->device()->SetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1);
aManager->device()->SetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4);

Просмотреть файл

@ -355,7 +355,7 @@ void
ImageLayerD3D9::RenderLayer()
{
ImageContainer *container = GetContainer();
if (!container) {
if (!container || mD3DManager->CompositingDisabled()) {
return;
}
@ -609,6 +609,10 @@ ShadowImageLayerD3D9::GetLayer()
void
ShadowImageLayerD3D9::RenderLayer()
{
if (mD3DManager->CompositingDisabled()) {
return;
}
if (mBuffer) {
mBuffer->RenderTo(mD3DManager, GetEffectiveVisibleRegion());
} else if (mYCbCrImage) {

Просмотреть файл

@ -121,7 +121,7 @@ LayerManagerD3D9::EndConstruction()
}
bool
LayerManagerD3D9::EndEmptyTransaction()
LayerManagerD3D9::EndEmptyTransaction(EndTransactionFlags aFlags)
{
// If the device reset count from our last EndTransaction doesn't match
// the current device reset count, the device must have been reset one or
@ -130,7 +130,7 @@ LayerManagerD3D9::EndEmptyTransaction()
if (!mRoot || mDeviceResetCount != mDeviceManager->GetDeviceResetCount())
return false;
EndTransaction(nullptr, nullptr);
EndTransaction(nullptr, nullptr, aFlags);
return true;
}
@ -149,6 +149,7 @@ LayerManagerD3D9::EndTransaction(DrawThebesLayerCallback aCallback,
// so we don't need to pass any global transform here.
mRoot->ComputeEffectiveTransforms(gfx3DMatrix());
SetCompositingDisabled(aFlags & END_NO_COMPOSITE);
Render();
/* Clean this out for sanity */
mCurrentCallbackInfo.Callback = NULL;
@ -284,6 +285,12 @@ LayerManagerD3D9::Render()
deviceManager()->SetupRenderState();
SetupPipeline();
if (CompositingDisabled()) {
static_cast<LayerD3D9*>(mRoot->ImplData())->RenderLayer();
return;
}
nsIntRect rect;
mWidget->GetClientBounds(rect);

Просмотреть файл

@ -98,7 +98,7 @@ public:
void EndConstruction();
virtual bool EndEmptyTransaction();
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
struct CallbackInfo {
DrawThebesLayerCallback Callback;
@ -176,6 +176,9 @@ public:
void ReportFailure(const nsACString &aMsg, HRESULT aCode);
bool CompositingDisabled() { return mCompositingDisabled; }
void SetCompositingDisabled(bool aCompositingDisabled) { mCompositingDisabled = aCompositingDisabled; }
private:
/* Default device manager instance */
static DeviceManagerD3D9 *mDefaultDeviceManager;
@ -208,6 +211,12 @@ private:
*/
PRUint32 mDeviceResetCount;
/*
* True if we should only be drawing layer contents, not
* compositing them to the target.
*/
bool mCompositingDisabled;
/*
* Render the current layer tree to the active target.
*/

Просмотреть файл

@ -237,6 +237,10 @@ ThebesLayerD3D9::RenderThebesLayer(ReadbackProcessor* aReadback)
mValidRegion = neededRegion;
}
if (mD3DManager->CompositingDisabled()) {
return;
}
SetShaderTransformAndOpacity();
if (mode == SURFACE_COMPONENT_ALPHA) {
@ -655,7 +659,7 @@ ShadowThebesLayerD3D9::IsEmpty()
void
ShadowThebesLayerD3D9::RenderThebesLayer()
{
if (!mBuffer) {
if (!mBuffer || mD3DManager->CompositingDisabled()) {
return;
}
NS_ABORT_IF_FALSE(mBuffer, "should have a buffer here");

Просмотреть файл

@ -229,6 +229,9 @@ CanvasLayerOGL::RenderLayer(int aPreviousDestination,
const nsIntPoint& aOffset)
{
UpdateSurface();
if (mOGLManager->CompositingDisabled()) {
return;
}
FireDidTransactionCallback();
mOGLManager->MakeCurrent();
@ -446,6 +449,9 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
return;
}
if (mOGLManager->CompositingDisabled()) {
return;
}
mOGLManager->MakeCurrent();
gfx3DMatrix effectiveTransform = GetEffectiveTransform();

Просмотреть файл

@ -12,6 +12,10 @@ static void
RenderColorLayer(ColorLayer* aLayer, LayerManagerOGL *aManager,
const nsIntPoint& aOffset)
{
if (aManager->CompositingDisabled()) {
return;
}
aManager->MakeCurrent();
// XXX we might be able to improve performance by using glClear

Просмотреть файл

@ -179,12 +179,14 @@ ContainerRender(Container* aContainer,
}
aContainer->gl()->PushViewportRect();
framebufferRect -= childOffset;
aManager->CreateFBOWithTexture(framebufferRect,
mode,
aPreviousFrameBuffer,
&frameBuffer,
&containerSurface);
framebufferRect -= childOffset;
if (!aManager->CompositingDisabled()) {
aManager->CreateFBOWithTexture(framebufferRect,
mode,
aPreviousFrameBuffer,
&frameBuffer,
&containerSurface);
}
childOffset.x = visibleRect.x;
childOffset.y = visibleRect.y;
} else {
@ -239,45 +241,47 @@ ContainerRender(Container* aContainer,
aManager->SetupPipeline(viewport.width, viewport.height,
LayerManagerOGL::ApplyWorldTransform);
aContainer->gl()->PopScissorRect();
aContainer->gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer);
aContainer->gl()->fDeleteFramebuffers(1, &frameBuffer);
aContainer->gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
if (!aManager->CompositingDisabled()) {
aContainer->gl()->fDeleteFramebuffers(1, &frameBuffer);
aContainer->gl()->fBindTexture(aManager->FBOTextureTarget(), containerSurface);
aContainer->gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
MaskType maskType = MaskNone;
if (aContainer->GetMaskLayer()) {
if (!aContainer->GetTransform().CanDraw2D()) {
maskType = Mask3d;
} else {
maskType = Mask2d;
aContainer->gl()->fBindTexture(aManager->FBOTextureTarget(), containerSurface);
MaskType maskType = MaskNone;
if (aContainer->GetMaskLayer()) {
if (!aContainer->GetTransform().CanDraw2D()) {
maskType = Mask3d;
} else {
maskType = Mask2d;
}
}
ShaderProgramOGL *rgb =
aManager->GetFBOLayerProgram(maskType);
rgb->Activate();
rgb->SetLayerQuadRect(visibleRect);
rgb->SetLayerTransform(transform);
rgb->SetLayerOpacity(opacity);
rgb->SetRenderOffset(aOffset);
rgb->SetTextureUnit(0);
rgb->LoadMask(aContainer->GetMaskLayer());
if (rgb->GetTexCoordMultiplierUniformLocation() != -1) {
// 2DRect case, get the multiplier right for a sampler2DRect
rgb->SetTexCoordMultiplier(visibleRect.width, visibleRect.height);
}
// Drawing is always flipped, but when copying between surfaces we want to avoid
// this. Pass true for the flip parameter to introduce a second flip
// that cancels the other one out.
aManager->BindAndDrawQuad(rgb, true);
// Clean up resources. This also unbinds the texture.
aContainer->gl()->fDeleteTextures(1, &containerSurface);
}
ShaderProgramOGL *rgb =
aManager->GetFBOLayerProgram(maskType);
rgb->Activate();
rgb->SetLayerQuadRect(visibleRect);
rgb->SetLayerTransform(transform);
rgb->SetLayerOpacity(opacity);
rgb->SetRenderOffset(aOffset);
rgb->SetTextureUnit(0);
rgb->LoadMask(aContainer->GetMaskLayer());
if (rgb->GetTexCoordMultiplierUniformLocation() != -1) {
// 2DRect case, get the multiplier right for a sampler2DRect
rgb->SetTexCoordMultiplier(visibleRect.width, visibleRect.height);
}
// Drawing is always flipped, but when copying between surfaces we want to avoid
// this. Pass true for the flip parameter to introduce a second flip
// that cancels the other one out.
aManager->BindAndDrawQuad(rgb, true);
// Clean up resources. This also unbinds the texture.
aContainer->gl()->fDeleteTextures(1, &containerSurface);
} else {
aContainer->gl()->PopScissorRect();
}

Просмотреть файл

@ -225,7 +225,7 @@ ImageLayerOGL::RenderLayer(int,
{
nsRefPtr<ImageContainer> container = GetContainer();
if (!container)
if (!container || mOGLManager->CompositingDisabled())
return;
mOGLManager->MakeCurrent();
@ -875,6 +875,9 @@ void
ShadowImageLayerOGL::RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset)
{
if (mOGLManager->CompositingDisabled()) {
return;
}
mOGLManager->MakeCurrent();
if (mImageContainerID) {
ImageContainerParent::SetCompositorIDForImage(mImageContainerID,

Просмотреть файл

@ -380,12 +380,12 @@ LayerManagerOGL::BeginTransactionWithTarget(gfxContext *aTarget)
}
bool
LayerManagerOGL::EndEmptyTransaction()
LayerManagerOGL::EndEmptyTransaction(EndTransactionFlags aFlags)
{
if (!mRoot)
return false;
EndTransaction(nullptr, nullptr);
EndTransaction(nullptr, nullptr, aFlags);
return true;
}
@ -411,6 +411,7 @@ LayerManagerOGL::EndTransaction(DrawThebesLayerCallback aCallback,
mThebesLayerCallback = aCallback;
mThebesLayerCallbackData = aCallbackData;
SetCompositingDisabled(aFlags & END_NO_COMPOSITE);
Render();
@ -774,6 +775,13 @@ LayerManagerOGL::Render()
mGLContext->fScissor(0, 0, width, height);
}
if (CompositingDisabled()) {
RootLayer()->RenderLayer(mGLContext->IsDoubleBuffered() ? 0 : mBackBufferFBO,
nsIntPoint(0, 0));
mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
return;
}
mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
// If the Java compositor is being used, this clear will be done in

Просмотреть файл

@ -102,7 +102,7 @@ public:
void EndConstruction();
virtual bool EndEmptyTransaction();
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags = END_DEFAULT);
@ -350,6 +350,9 @@ public:
*/
void SetSurfaceSize(int width, int height);
bool CompositingDisabled() { return mCompositingDisabled; }
void SetCompositingDisabled(bool aCompositingDisabled) { mCompositingDisabled = aCompositingDisabled; }
private:
/** Widget associated with this layer manager */
nsIWidget *mWidget;
@ -391,6 +394,7 @@ private:
/** Misc */
bool mHasBGRA;
bool mCompositingDisabled;
/**
* When rendering to an EGL surface (e.g. on Android), we rely on being told

Просмотреть файл

@ -88,6 +88,8 @@ public:
void RenderTo(const nsIntPoint& aOffset, LayerManagerOGL* aManager,
PRUint32 aFlags);
void EndUpdate();
nsIntSize GetSize() {
if (mTexImage)
return mTexImage->GetSize();
@ -108,6 +110,17 @@ protected:
bool mInitialised;
};
void ThebesLayerBufferOGL::EndUpdate()
{
if (mTexImage && mTexImage->InUpdate()) {
mTexImage->EndUpdate();
}
if (mTexImageOnWhite && mTexImageOnWhite->InUpdate()) {
mTexImageOnWhite->EndUpdate();
}
}
void
ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset,
LayerManagerOGL* aManager,
@ -118,13 +131,7 @@ ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset,
if (!mTexImage || !Initialised())
return;
if (mTexImage->InUpdate()) {
mTexImage->EndUpdate();
}
if (mTexImageOnWhite && mTexImageOnWhite->InUpdate()) {
mTexImageOnWhite->EndUpdate();
}
EndUpdate();
#ifdef MOZ_DUMP_PAINTING
if (gfxUtils::sDumpPainting) {
@ -838,6 +845,11 @@ ThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer,
}
}
if (mOGLManager->CompositingDisabled()) {
mBuffer->EndUpdate();
return;
}
// Drawing thebes layers can change the current context, reset it.
gl()->MakeCurrent();
@ -1099,7 +1111,7 @@ void
ShadowThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset)
{
if (!mBuffer) {
if (!mBuffer || mOGLManager->CompositingDisabled()) {
return;
}
NS_ABORT_IF_FALSE(mBuffer, "should have a buffer here");

Просмотреть файл

@ -86,9 +86,11 @@ class EvalScriptGuard
EvalCacheLookup lookup_;
EvalCache::AddPtr p_;
Rooted<JSLinearString*> lookupStr_;
public:
EvalScriptGuard(JSContext *cx)
: cx_(cx), script_(cx)
: cx_(cx), script_(cx), lookupStr_(cx)
{
lookup_.str = NULL;
}
@ -98,6 +100,7 @@ class EvalScriptGuard
CallDestroyScriptHook(cx_->runtime->defaultFreeOp(), script_);
script_->isActiveEval = false;
script_->isCachedEval = true;
lookup_.str = lookupStr_;
if (lookup_.str && IsEvalCacheCandidate(script_))
cx_->runtime->evalCache.relookupOrAdd(p_, lookup_, script_);
}
@ -105,6 +108,7 @@ class EvalScriptGuard
void lookupInEvalCache(JSLinearString *str, JSFunction *caller, unsigned staticLevel)
{
lookupStr_ = str;
lookup_.str = str;
lookup_.caller = caller;
lookup_.staticLevel = staticLevel;

Просмотреть файл

@ -823,6 +823,8 @@ MapIteratorObject::next_impl(JSContext *cx, CallArgs args)
}
Value pair[2] = { range->front().key.get(), range->front().value };
AutoValueArray root(cx, pair, 2);
JSObject *pairobj = NewDenseCopiedArray(cx, 2, pair);
if (!pairobj)
return false;
@ -970,7 +972,7 @@ MapObject::construct(JSContext *cx, unsigned argc, Value *vp)
if (args.hasDefined(0)) {
ForOfIterator iter(cx, args[0]);
while (iter.next()) {
JSObject *pairobj = js_ValueToNonNullObject(cx, iter.value());
RootedObject pairobj(cx, js_ValueToNonNullObject(cx, iter.value()));
if (!pairobj)
return false;

Просмотреть файл

@ -87,20 +87,12 @@ endif
CONFIG_TOOLS = $(MOZ_BUILD_ROOT)/config
AUTOCONF_TOOLS = $(topsrcdir)/build/autoconf
ifeq ($(OS_ARCH),QNX)
ifeq ($(OS_TARGET),NTO)
LD := qcc -Vgcc_ntox86 -nostdlib
else
LD := $(CC)
endif
endif
#
# Strip off the excessively long version numbers on these platforms,
# but save the version to allow multiple versions of the same base
# platform to be built in the same tree.
#
ifneq (,$(filter FreeBSD HP-UX Linux NetBSD OpenBSD OSF1 SunOS,$(OS_ARCH)))
ifneq (,$(filter FreeBSD HP-UX Linux NetBSD OpenBSD SunOS,$(OS_ARCH)))
OS_RELEASE := $(basename $(OS_RELEASE))
# Allow the user to ignore the OS_VERSION, which is usually irrelevant.

Просмотреть файл

@ -500,17 +500,6 @@ endif # HAS_EXTRAEXPORTS
endif # IS_COMPONENT
endif # AIX
#
# OSF1: add -B symbolic flag for components
#
ifeq ($(OS_ARCH),OSF1)
ifdef IS_COMPONENT
ifeq ($(GNU_CC)$(GNU_CXX),)
EXTRA_DSO_LDOPTS += -B symbolic
endif
endif
endif
#
# Linux: add -Bsymbolic flag for components
#

Просмотреть файл

@ -303,8 +303,10 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
if (!GetOrderedBindings(cx, funsc.bindings, &names))
return false;
RootedPropertyName name(cx);
for (unsigned i = 0; i < nargs; i++) {
if (!DefineArg(fn, names[i].maybeName, i, &parser))
name = names[i].maybeName;
if (!DefineArg(fn, name, i, &parser))
return false;
}
}

Просмотреть файл

@ -469,7 +469,7 @@ CheckStrictAssignment(JSContext *cx, Parser *parser, ParseNode *lhs)
* tc's token stream if pn is NULL.
*/
bool
CheckStrictBinding(JSContext *cx, Parser *parser, PropertyName *name, ParseNode *pn)
CheckStrictBinding(JSContext *cx, Parser *parser, HandlePropertyName name, ParseNode *pn)
{
if (!parser->tc->sc->needStrictChecks())
return true;
@ -489,7 +489,7 @@ CheckStrictBinding(JSContext *cx, Parser *parser, PropertyName *name, ParseNode
}
static bool
ReportBadParameter(JSContext *cx, Parser *parser, JSAtom *name, unsigned errorNumber)
ReportBadParameter(JSContext *cx, Parser *parser, HandlePropertyName name, unsigned errorNumber)
{
Definition *dn = parser->tc->decls.lookupFirst(name);
JSAutoByteString bytes;
@ -878,13 +878,13 @@ MakeDefIntoUse(Definition *dn, ParseNode *pn, JSAtom *atom, Parser *parser)
* of CheckDestructuring and its friends.
*/
typedef bool
(*Binder)(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser);
(*Binder)(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser);
static bool
BindLet(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser);
BindLet(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser);
static bool
BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser);
BindVarOrConst(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser);
struct frontend::BindData {
BindData(JSContext *cx) : let(cx) {}
@ -1139,7 +1139,7 @@ LeaveFunction(ParseNode *fn, Parser *parser, PropertyName *funName = NULL,
* and the formals specified by the Function constructor.
*/
bool
frontend::DefineArg(ParseNode *pn, PropertyName *name, unsigned i, Parser *parser)
frontend::DefineArg(ParseNode *pn, HandlePropertyName name, unsigned i, Parser *parser)
{
JSContext *cx = parser->context;
TreeContext *tc = parser->tc;
@ -1179,7 +1179,7 @@ frontend::DefineArg(ParseNode *pn, PropertyName *name, unsigned i, Parser *parse
#if JS_HAS_DESTRUCTURING
static bool
BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser)
BindDestructuringArg(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser)
{
TreeContext *tc = parser->tc;
JS_ASSERT(tc->sc->inFunction());
@ -1189,13 +1189,13 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser
* bindings aren't added to tc->sc->bindings until after all arguments have
* been parsed.
*/
if (tc->decls.lookupFirst(atom)) {
if (tc->decls.lookupFirst(name)) {
parser->reportError(NULL, JSMSG_DESTRUCT_DUP_ARG);
return false;
}
ParseNode *pn = data->pn;
if (!CheckStrictBinding(cx, parser, atom->asPropertyName(), pn))
if (!CheckStrictBinding(cx, parser, name, pn))
return false;
/*
@ -1220,7 +1220,7 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser
pn->setOp(JSOP_SETLOCAL);
pn->pn_dflags |= PND_BOUND;
return Define(pn, atom, tc);
return Define(pn, name, tc);
}
#endif /* JS_HAS_DESTRUCTURING */
@ -2020,11 +2020,11 @@ ReportRedeclaration(JSContext *cx, Parser *parser, ParseNode *pn, bool isConst,
* data->pn in a slot of the block object.
*/
static bool
BindLet(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser)
BindLet(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser)
{
TreeContext *tc = parser->tc;
ParseNode *pn = data->pn;
if (!CheckStrictBinding(cx, parser, atom->asPropertyName(), pn))
if (!CheckStrictBinding(cx, parser, name, pn))
return false;
Rooted<StaticBlockObject *> blockObj(cx, data->let.blockObj);
@ -2040,10 +2040,10 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser)
*/
if (data->let.varContext == HoistVars) {
JS_ASSERT(!tc->atBodyLevel());
Definition *dn = tc->decls.lookupFirst(atom);
Definition *dn = tc->decls.lookupFirst(name);
if (dn && dn->pn_blockid == tc->blockid())
return ReportRedeclaration(cx, parser, pn, dn->isConst(), atom);
if (!Define(pn, atom, tc, true))
return ReportRedeclaration(cx, parser, pn, dn->isConst(), name);
if (!Define(pn, name, tc, true))
return false;
}
@ -2064,11 +2064,11 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser)
* slot indexed by blockCount off the class-reserved slot base.
*/
bool redeclared;
RootedId id(cx, AtomToId(atom));
RootedId id(cx, NameToId(name));
Shape *shape = StaticBlockObject::addVar(cx, blockObj, id, blockCount, &redeclared);
if (!shape) {
if (redeclared)
ReportRedeclaration(cx, parser, pn, false, atom);
ReportRedeclaration(cx, parser, pn, false, name);
return false;
}
@ -2163,20 +2163,18 @@ BindFunctionLocal(JSContext *cx, BindData *data, DefinitionList::Range &defs, Tr
}
static bool
BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom_, Parser *parser)
BindVarOrConst(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser)
{
RootedAtom atom(cx, atom_);
TreeContext *tc = parser->tc;
ParseNode *pn = data->pn;
/* Default best op for pn is JSOP_NAME; we'll try to improve below. */
pn->setOp(JSOP_NAME);
if (!CheckStrictBinding(cx, parser, atom->asPropertyName(), pn))
if (!CheckStrictBinding(cx, parser, name, pn))
return false;
StmtInfoTC *stmt = LexicalLookup(tc, atom, NULL, (StmtInfoTC *)NULL);
StmtInfoTC *stmt = LexicalLookup(tc, name, NULL, (StmtInfoTC *)NULL);
if (stmt && stmt->type == STMT_WITH) {
pn->pn_dflags |= PND_DEOPTIMIZED;
@ -2184,11 +2182,11 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom_, Parser *parser)
return true;
}
DefinitionList::Range defs = tc->decls.lookupMulti(atom);
DefinitionList::Range defs = tc->decls.lookupMulti(name);
JS_ASSERT_IF(stmt, !defs.empty());
if (defs.empty()) {
if (!Define(pn, atom, tc))
if (!Define(pn, name, tc))
return false;
if (data->op == JSOP_DEFCONST)
@ -2210,32 +2208,32 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom_, Parser *parser)
Definition *dn = defs.front();
Definition::Kind dn_kind = dn->kind();
if (dn_kind == Definition::ARG) {
JSAutoByteString name;
if (!js_AtomToPrintableString(cx, atom, &name))
JSAutoByteString bytes;
if (!js_AtomToPrintableString(cx, name, &bytes))
return false;
if (data->op == JSOP_DEFCONST) {
parser->reportError(pn, JSMSG_REDECLARED_PARAM, name.ptr());
parser->reportError(pn, JSMSG_REDECLARED_PARAM, bytes.ptr());
return false;
}
if (!parser->reportStrictWarning(pn, JSMSG_VAR_HIDES_ARG, name.ptr()))
if (!parser->reportStrictWarning(pn, JSMSG_VAR_HIDES_ARG, bytes.ptr()))
return false;
} else {
bool error = (data->op == JSOP_DEFCONST ||
dn_kind == Definition::CONST ||
(dn_kind == Definition::LET &&
(stmt->type != STMT_CATCH || OuterLet(tc, stmt, atom))));
(stmt->type != STMT_CATCH || OuterLet(tc, stmt, name))));
if (cx->hasStrictOption()
? data->op != JSOP_DEFVAR || dn_kind != Definition::VAR
: error)
{
JSAutoByteString name;
JSAutoByteString bytes;
Parser::Reporter reporter =
error ? &Parser::reportError : &Parser::reportStrictWarning;
if (!js_AtomToPrintableString(cx, atom, &name) ||
if (!js_AtomToPrintableString(cx, name, &bytes) ||
!(parser->*reporter)(pn, JSMSG_REDECLARED_VAR,
Definition::kindString(dn_kind), name.ptr()))
Definition::kindString(dn_kind), bytes.ptr()))
{
return false;
}
@ -2329,8 +2327,10 @@ BindDestructuringVar(JSContext *cx, BindData *data, ParseNode *pn, Parser *parse
{
JS_ASSERT(pn->isKind(PNK_NAME));
RootedPropertyName name(cx, pn->pn_atom->asPropertyName());
data->pn = pn;
if (!data->binder(cx, data, pn->pn_atom, parser))
if (!data->binder(cx, data, name, parser))
return false;
/*
@ -3437,7 +3437,7 @@ Parser::tryStatement()
case TOK_NAME:
{
JSAtom *label = tokenStream.currentToken().name();
RootedPropertyName label(context, tokenStream.currentToken().name());
pn3 = NewBindingNode(label, this);
if (!pn3)
return NULL;
@ -4148,7 +4148,7 @@ Parser::variables(ParseNodeKind kind, StaticBlockObject *blockObj, VarContext va
return NULL;
}
PropertyName *name = tokenStream.currentToken().name();
RootedPropertyName name(context, tokenStream.currentToken().name());
pn2 = NewBindingNode(name, this, varContext);
if (!pn2)
return NULL;

Просмотреть файл

@ -327,7 +327,7 @@ Parser::reportStrictModeError(ParseNode *pn, unsigned errorNumber, ...)
}
bool
DefineArg(ParseNode *pn, PropertyName *name, unsigned i, Parser *parser);
DefineArg(ParseNode *pn, HandlePropertyName name, unsigned i, Parser *parser);
} /* namespace frontend */
} /* namespace js */

Просмотреть файл

@ -283,5 +283,10 @@ for (var i = 0; i <4; i++) {
plainText += plainText;
}
// root checks performed during integer conversion operations can poison
// crypto integers in this test.
if (relaxRootChecks)
relaxRootChecks();
var md5Output = hex_md5(plainText);
assertEq(md5Output, "a831e91e0f70eddcb70dc61c6f82f6cd")

Просмотреть файл

@ -221,5 +221,10 @@ for (var i = 0; i <4; i++) {
plainText += plainText;
}
// root checks performed during integer conversion operations can poison
// crypto integers in this test.
if (relaxRootChecks)
relaxRootChecks();
var sha1Output = hex_sha1(plainText);
assertEq(sha1Output, "2524d264def74cce2498bf112bedf00e6c0b796d")

Просмотреть файл

@ -596,10 +596,12 @@ JS_ValueToUint64(JSContext *cx, jsval v, uint64_t *ip)
}
JS_PUBLIC_API(JSBool)
JS_ValueToInt32(JSContext *cx, jsval v, int32_t *ip)
JS_ValueToInt32(JSContext *cx, jsval vArg, int32_t *ip)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
RootedValue v(cx, vArg);
assertSameCompartment(cx, v);
if (v.isInt32()) {
@ -616,7 +618,7 @@ JS_ValueToInt32(JSContext *cx, jsval v, int32_t *ip)
if (MOZ_DOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) {
js_ReportValueError(cx, JSMSG_CANT_CONVERT,
JSDVG_SEARCH_STACK, v, NULL);
JSDVG_SEARCH_STACK, v, NullPtr());
return false;
}
@ -4957,12 +4959,14 @@ JS_BindCallable(JSContext *cx, JSObject *targetArg, JSRawObject newThis)
JSBool
js_generic_native_method_dispatcher(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JSFunctionSpec *fs = (JSFunctionSpec *)
vp->toObject().toFunction()->getExtendedSlot(0).toPrivate();
JS_ASSERT((fs->flags & JSFUN_GENERIC_NATIVE) != 0);
if (argc < 1) {
js_ReportMissingArg(cx, *vp, 0);
js_ReportMissingArg(cx, args.calleev(), 0);
return JS_FALSE;
}
@ -5918,8 +5922,8 @@ JS_New(JSContext *cx, JSObject *ctorArg, unsigned argc, jsval *argv)
if (!cx->stack.pushInvokeArgs(cx, argc, &args))
return NULL;
args.calleev().setObject(*ctor);
args.thisv().setNull();
args.setCallee(ObjectValue(*ctor));
args.setThis(NullValue());
PodCopy(args.array(), argv, argc);
if (!InvokeConstructor(cx, args))

Просмотреть файл

@ -1053,15 +1053,16 @@ class JS_PUBLIC_API(AutoGCRooter) {
STRING = -14, /* js::AutoStringRooter */
IDVECTOR = -15, /* js::AutoIdVector */
OBJVECTOR = -16, /* js::AutoObjectVector */
SCRIPTVECTOR =-17, /* js::AutoScriptVector */
PROPDESC = -18, /* js::PropDesc::AutoRooter */
SHAPERANGE = -19, /* js::Shape::Range::AutoRooter */
STACKSHAPE = -20, /* js::StackShape::AutoRooter */
STACKBASESHAPE=-21,/* js::StackBaseShape::AutoRooter */
BINDINGS = -22, /* js::Bindings::AutoRooter */
GETTERSETTER =-23, /* js::AutoRooterGetterSetter */
REGEXPSTATICS=-24, /* js::RegExpStatics::AutoRooter */
HASHABLEVALUE=-25
STRINGVECTOR =-17, /* js::AutoStringVector */
SCRIPTVECTOR =-18, /* js::AutoScriptVector */
PROPDESC = -19, /* js::PropDesc::AutoRooter */
SHAPERANGE = -20, /* js::Shape::Range::AutoRooter */
STACKSHAPE = -21, /* js::StackShape::AutoRooter */
STACKBASESHAPE=-22,/* js::StackBaseShape::AutoRooter */
BINDINGS = -23, /* js::Bindings::AutoRooter */
GETTERSETTER =-24, /* js::AutoRooterGetterSetter */
REGEXPSTATICS=-25, /* js::RegExpStatics::AutoRooter */
HASHABLEVALUE=-26
};
private:
@ -1255,6 +1256,7 @@ class AutoVectorRooter : protected AutoGCRooter
}
size_t length() const { return vector.length(); }
bool empty() const { return vector.empty(); }
bool append(const T &v) { return vector.append(v); }
bool append(const AutoVectorRooter<T> &other) {
@ -1381,8 +1383,15 @@ class CallReceiver
friend CallReceiver CallReceiverFromArgv(Value *);
Value *base() const { return argv_ - 2; }
JSObject &callee() const { JS_ASSERT(!usedRval_); return argv_[-2].toObject(); }
Value &calleev() const { JS_ASSERT(!usedRval_); return argv_[-2]; }
Value &thisv() const { return argv_[-1]; }
JS::HandleValue calleev() const {
JS_ASSERT(!usedRval_);
return JS::HandleValue::fromMarkedLocation(&argv_[-2]);
}
JS::HandleValue thisv() const {
return JS::HandleValue::fromMarkedLocation(&argv_[-1]);
}
JS::MutableHandleValue rval() const {
setUsedRval();
@ -1394,9 +1403,13 @@ class CallReceiver
return argv_ - 1;
}
void setCallee(Value calleev) {
void setCallee(Value calleev) const {
clearUsedRval();
this->calleev() = calleev;
argv_[-2] = calleev;
}
void setThis(Value thisv) const {
argv_[-1] = thisv;
}
};

Просмотреть файл

@ -1535,7 +1535,7 @@ array_join_sub(JSContext *cx, CallArgs &args, bool locale)
// the annotations in this function apply to both toLocaleString and join.
// Step 1
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -1623,7 +1623,7 @@ array_join_sub(JSContext *cx, CallArgs &args, bool locale)
if (!hole && !elt.isNullOrUndefined()) {
if (locale) {
JSObject *robj = ToObject(cx, elt.address());
JSObject *robj = ToObject(cx, elt);
if (!robj)
return false;
RootedId id(cx, NameToId(cx->runtime->atomState.toLocaleStringAtom));
@ -1657,7 +1657,7 @@ array_toString(JSContext *cx, unsigned argc, Value *vp)
JS_CHECK_RECURSION(cx, return false);
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -1677,8 +1677,8 @@ array_toString(JSContext *cx, unsigned argc, Value *vp)
if (!cx->stack.pushInvokeArgs(cx, 0, &ag))
return false;
ag.calleev() = join;
ag.thisv().setObject(*obj);
ag.setCallee(join);
ag.setThis(ObjectValue(*obj));
/* Do the call. */
if (!Invoke(cx, ag))
@ -1808,7 +1808,7 @@ static JSBool
array_reverse(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -2078,7 +2078,7 @@ SortComparatorFunction::operator()(const Value &a, const Value &b, bool *lessOrE
return false;
ag.setCallee(fval);
ag.thisv() = UndefinedValue();
ag.setThis(UndefinedValue());
ag[0] = a;
ag[1] = b;
@ -2118,7 +2118,7 @@ js::array_sort(JSContext *cx, unsigned argc, Value *vp)
fval.setNull();
}
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -2358,7 +2358,7 @@ JSBool
js::array_push(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -2433,7 +2433,7 @@ JSBool
js::array_pop(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
if (obj->isDenseArray())
@ -2462,7 +2462,7 @@ JSBool
js::array_shift(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return JS_FALSE;
@ -2514,7 +2514,7 @@ static JSBool
array_unshift(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -2636,7 +2636,7 @@ array_splice(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -2855,11 +2855,13 @@ mjit::stubs::ArrayConcatTwoArrays(VMFrame &f)
JSBool
js::array_concat(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Treat our |this| object as the first argument; see ECMA 15.4.4.4. */
Value *p = JS_ARGV(cx, vp) - 1;
Value *p = args.array() - 1;
/* Create a new Array object and root it using *vp. */
RootedObject aobj(cx, ToObject(cx, &vp[1]));
RootedObject aobj(cx, ToObject(cx, args.thisv()));
if (!aobj)
return false;
@ -2874,7 +2876,7 @@ js::array_concat(JSContext *cx, unsigned argc, Value *vp)
return JS_FALSE;
TryReuseArrayType(aobj, nobj);
nobj->setArrayLength(cx, length);
vp->setObject(*nobj);
args.rval().setObject(*nobj);
if (argc == 0)
return JS_TRUE;
argc--;
@ -2883,7 +2885,7 @@ js::array_concat(JSContext *cx, unsigned argc, Value *vp)
nobj = NewDenseEmptyArray(cx);
if (!nobj)
return JS_FALSE;
vp->setObject(*nobj);
args.rval().setObject(*nobj);
length = 0;
}
@ -2932,7 +2934,7 @@ array_slice(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -3011,13 +3013,12 @@ static JSBool
array_indexOfHelper(JSContext *cx, IndexOfKind mode, CallArgs &args)
{
uint32_t length, i, stop;
Value tosearch;
int direction;
JSBool hole;
RootedValue elt(cx);
RootedValue tosearch(cx), elt(cx);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
if (!js_GetLengthProperty(cx, obj, &length))
@ -3139,7 +3140,7 @@ static inline bool
array_readonlyCommon(JSContext *cx, CallArgs &args)
{
/* Step 1. */
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -3180,7 +3181,7 @@ array_readonlyCommon(JSContext *cx, CallArgs &args)
if (!ag.pushed() && !cx->stack.pushInvokeArgs(cx, 3, &ag))
return false;
ag.setCallee(ObjectValue(*callable));
ag.thisv() = thisv;
ag.setThis(thisv);
ag[0] = kValue;
ag[1] = NumberValue(k);
ag[2] = ObjectValue(*obj);
@ -3231,7 +3232,7 @@ array_map(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -3281,7 +3282,7 @@ array_map(JSContext *cx, unsigned argc, Value *vp)
if (!ag.pushed() && !cx->stack.pushInvokeArgs(cx, 3, &ag))
return false;
ag.setCallee(ObjectValue(*callable));
ag.thisv() = thisv;
ag.setThis(thisv);
ag[0] = kValue;
ag[1] = NumberValue(k);
ag[2] = ObjectValue(*obj);
@ -3308,7 +3309,7 @@ array_filter(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -3361,7 +3362,7 @@ array_filter(JSContext *cx, unsigned argc, Value *vp)
if (!ag.pushed() && !cx->stack.pushInvokeArgs(cx, 3, &ag))
return false;
ag.setCallee(ObjectValue(*callable));
ag.thisv() = thisv;
ag.setThis(thisv);
ag[0] = kValue;
ag[1] = NumberValue(k);
ag[2] = ObjectValue(*obj);
@ -3416,7 +3417,7 @@ static inline bool
array_reduceCommon(JSContext *cx, CallArgs &args)
{
/* Step 1. */
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -3430,7 +3431,7 @@ array_reduceCommon(JSContext *cx, CallArgs &args)
js_ReportMissingArg(cx, args.calleev(), 0);
return false;
}
JSObject *callable = ValueToCallable(cx, &args[0]);
RootedObject callable(cx, ValueToCallable(cx, &args[0]));
if (!callable)
return false;
@ -3479,7 +3480,7 @@ array_reduceCommon(JSContext *cx, CallArgs &args)
if (!ag.pushed() && !cx->stack.pushInvokeArgs(cx, 4, &ag))
return false;
ag.setCallee(ObjectValue(*callable));
ag.thisv() = UndefinedValue();
ag.setThis(UndefinedValue());
ag[0] = accumulator;
ag[1] = kValue;
ag[2] = NumberValue(k);
@ -3811,9 +3812,9 @@ js_ArrayInfo(JSContext *cx, unsigned argc, Value *vp)
JSObject *array;
for (unsigned i = 0; i < args.length(); i++) {
Value arg = args[i];
RootedValue arg(cx, args[i]);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, arg, NULL);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, arg, NullPtr());
if (!bytes)
return JS_FALSE;
if (arg.isPrimitive() ||

Просмотреть файл

@ -298,6 +298,9 @@ AtomizeInline(JSContext *cx, const jschar **pchars, size_t length,
SkipRoot skip(cx, &chars);
/* Workaround for hash values in AddPtr being inadvertently poisoned. */
SkipRoot skip2(cx, &p);
if (ocb == TakeCharOwnership) {
key = js_NewString(cx, const_cast<jschar *>(chars), length);
if (!key)

Просмотреть файл

@ -205,8 +205,8 @@ BooleanGetPrimitiveValueSlow(JSContext *cx, JSObject &obj, Value *vp)
InvokeArgsGuard ag;
if (!cx->stack.pushInvokeArgs(cx, 0, &ag))
return false;
ag.calleev() = cx->compartment->maybeGlobal()->booleanValueOf();
ag.thisv().setObject(obj);
ag.setCallee(cx->compartment->maybeGlobal()->booleanValueOf());
ag.setThis(ObjectValue(obj));
if (!Invoke(cx, ag))
return false;
*vp = ag.rval();

Просмотреть файл

@ -810,8 +810,8 @@ js_ReportIsNotDefined(JSContext *cx, const char *name)
}
JSBool
js_ReportIsNullOrUndefined(JSContext *cx, int spindex, const Value &v,
JSString *fallback)
js_ReportIsNullOrUndefined(JSContext *cx, int spindex, HandleValue v,
HandleString fallback)
{
char *bytes;
JSBool ok;
@ -844,11 +844,11 @@ js_ReportIsNullOrUndefined(JSContext *cx, int spindex, const Value &v,
}
void
js_ReportMissingArg(JSContext *cx, const Value &v, unsigned arg)
js_ReportMissingArg(JSContext *cx, HandleValue v, unsigned arg)
{
char argbuf[11];
char *bytes;
JSAtom *atom;
RootedAtom atom(cx);
JS_snprintf(argbuf, sizeof argbuf, "%u", arg);
bytes = NULL;
@ -867,7 +867,7 @@ js_ReportMissingArg(JSContext *cx, const Value &v, unsigned arg)
JSBool
js_ReportValueErrorFlags(JSContext *cx, unsigned flags, const unsigned errorNumber,
int spindex, const Value &v, JSString *fallback,
int spindex, HandleValue v, HandleString fallback,
const char *arg1, const char *arg2)
{
char *bytes;

Просмотреть файл

@ -1728,11 +1728,11 @@ js_ReportIsNotDefined(JSContext *cx, const char *name);
* Report an attempt to access the property of a null or undefined value (v).
*/
extern JSBool
js_ReportIsNullOrUndefined(JSContext *cx, int spindex, const js::Value &v,
JSString *fallback);
js_ReportIsNullOrUndefined(JSContext *cx, int spindex, js::HandleValue v,
js::HandleString fallback);
extern void
js_ReportMissingArg(JSContext *cx, const js::Value &v, unsigned arg);
js_ReportMissingArg(JSContext *cx, js::HandleValue v, unsigned arg);
/*
* Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) as
@ -1741,7 +1741,7 @@ js_ReportMissingArg(JSContext *cx, const js::Value &v, unsigned arg);
*/
extern JSBool
js_ReportValueErrorFlags(JSContext *cx, unsigned flags, const unsigned errorNumber,
int spindex, const js::Value &v, JSString *fallback,
int spindex, js::HandleValue v, js::HandleString fallback,
const char *arg1, const char *arg2);
#define js_ReportValueError(cx,errorNumber,spindex,v,fallback) \
@ -1888,6 +1888,19 @@ class AutoObjectVector : public AutoVectorRooter<JSObject *>
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class AutoStringVector : public AutoVectorRooter<JSString *>
{
public:
explicit AutoStringVector(JSContext *cx
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoVectorRooter<JSString *>(cx, STRINGVECTOR)
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class AutoShapeVector : public AutoVectorRooter<Shape *>
{
public:

Просмотреть файл

@ -2589,8 +2589,10 @@ date_toISOString(JSContext *cx, unsigned argc, Value *vp)
static JSBool
date_toJSON(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -2601,7 +2603,7 @@ date_toJSON(JSContext *cx, unsigned argc, Value *vp)
/* Step 3. */
if (tv.isDouble() && !MOZ_DOUBLE_IS_FINITE(tv.toDouble())) {
vp->setNull();
args.rval().setNull();
return true;
}
@ -2618,16 +2620,16 @@ date_toJSON(JSContext *cx, unsigned argc, Value *vp)
}
/* Step 6. */
InvokeArgsGuard args;
if (!cx->stack.pushInvokeArgs(cx, 0, &args))
InvokeArgsGuard ag;
if (!cx->stack.pushInvokeArgs(cx, 0, &ag))
return false;
args.calleev() = toISO;
args.thisv().setObject(*obj);
ag.setCallee(toISO);
ag.setThis(ObjectValue(*obj));
if (!Invoke(cx, args))
if (!Invoke(cx, ag))
return false;
*vp = args.rval();
args.rval().set(ag.rval());
return true;
}

Просмотреть файл

@ -686,7 +686,7 @@ exn_toSource(JSContext *cx, unsigned argc, Value *vp)
JS_CHECK_RECURSION(cx, return false);
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;

Просмотреть файл

@ -469,7 +469,8 @@ fun_hasInstance(JSContext *cx, HandleObject obj_, const Value *v, JSBool *bp)
* Throw a runtime error if instanceof is called on a function that
* has a non-object as its .prototype value.
*/
js_ReportValueError(cx, JSMSG_BAD_PROTOTYPE, -1, ObjectValue(*obj), NULL);
RootedValue val(cx, ObjectValue(*obj));
js_ReportValueError(cx, JSMSG_BAD_PROTOTYPE, -1, val, NullPtr());
return JS_FALSE;
}
@ -745,13 +746,15 @@ fun_toStringHelper(JSContext *cx, JSObject *obj, unsigned indent)
static JSBool
fun_toString(JSContext *cx, unsigned argc, Value *vp)
{
JS_ASSERT(IsFunctionObject(vp[0]));
CallArgs args = CallArgsFromVp(argc, vp);
JS_ASSERT(IsFunctionObject(args.calleev()));
uint32_t indent = 0;
if (argc != 0 && !ToUint32(cx, vp[2], &indent))
if (args.length() != 0 && !ToUint32(cx, args[0], &indent))
return false;
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, args.thisv());
if (!obj)
return false;
@ -759,7 +762,7 @@ fun_toString(JSContext *cx, unsigned argc, Value *vp)
if (!str)
return false;
vp->setString(str);
args.rval().setString(str);
return true;
}
@ -767,9 +770,10 @@ fun_toString(JSContext *cx, unsigned argc, Value *vp)
static JSBool
fun_toSource(JSContext *cx, unsigned argc, Value *vp)
{
JS_ASSERT(IsFunctionObject(vp[0]));
CallArgs args = CallArgsFromVp(argc, vp);
JS_ASSERT(IsFunctionObject(args.calleev()));
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, args.thisv());
if (!obj)
return false;
@ -777,7 +781,7 @@ fun_toSource(JSContext *cx, unsigned argc, Value *vp)
if (!str)
return false;
vp->setString(str);
args.rval().setString(str);
return true;
}
#endif
@ -809,8 +813,8 @@ js_fun_call(JSContext *cx, unsigned argc, Value *vp)
return JS_FALSE;
/* Push fval, thisv, and the args. */
args.calleev() = fval;
args.thisv() = thisv;
args.setCallee(fval);
args.setThis(thisv);
PodCopy(args.array(), argv, argc);
bool ok = Invoke(cx, args);
@ -855,8 +859,8 @@ js_fun_apply(JSContext *cx, unsigned argc, Value *vp)
return false;
/* Push fval, obj, and aobj's elements as args. */
args.calleev() = fval;
args.thisv() = vp[2];
args.setCallee(fval);
args.setThis(vp[2]);
/* Steps 7-8. */
cx->fp()->forEachUnaliasedActual(CopyTo(args.array()));
@ -886,8 +890,8 @@ js_fun_apply(JSContext *cx, unsigned argc, Value *vp)
return false;
/* Push fval, obj, and aobj's elements as args. */
args.calleev() = fval;
args.thisv() = vp[2];
args.setCallee(fval);
args.setThis(vp[2]);
/* Steps 7-8. */
if (!GetElements(cx, aobj, length, args.array()))
@ -1017,10 +1021,10 @@ CallOrConstructBoundFunction(JSContext *cx, unsigned argc, Value *vp)
PodCopy(args.array() + argslen, vp + 2, argc);
/* 15.3.4.5.1, 15.3.4.5.2 step 5. */
args.calleev().setObject(*target);
args.setCallee(ObjectValue(*target));
if (!constructing)
args.thisv() = boundThis;
args.setThis(boundThis);
if (constructing ? !InvokeConstructor(cx, args) : !Invoke(cx, args))
return false;
@ -1060,7 +1064,7 @@ fun_bind(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
Value &thisv = args.thisv();
Value thisv = args.thisv();
/* Step 2. */
if (!js_IsCallable(thisv)) {
@ -1517,7 +1521,7 @@ js_DefineFunction(JSContext *cx, HandleObject obj, HandleId id, Native native,
void
js::ReportIncompatibleMethod(JSContext *cx, CallReceiver call, Class *clasp)
{
Value &thisv = call.thisv();
Value thisv = call.thisv();
#ifdef DEBUG
if (thisv.isObject()) {

Просмотреть файл

@ -110,7 +110,7 @@ js::BoxNonStrictThis(JSContext *cx, const CallReceiver &call)
* Check for SynthesizeFrame poisoning and fast constructors which
* didn't check their callee properly.
*/
Value &thisv = call.thisv();
Value thisv = call.thisv();
JS_ASSERT(!thisv.isMagic());
#ifdef DEBUG
@ -120,15 +120,17 @@ js::BoxNonStrictThis(JSContext *cx, const CallReceiver &call)
if (thisv.isNullOrUndefined()) {
JSObject *thisp = call.callee().global().thisObject(cx);
JS_ASSERT(!IsPoisonedPtr(thisp));
if (!thisp)
return false;
call.thisv().setObject(*thisp);
call.setThis(ObjectValue(*thisp));
return true;
}
if (!thisv.isObject())
return !!js_PrimitiveToObject(cx, &thisv);
if (!thisv.isObject()) {
if (!js_PrimitiveToObject(cx, &thisv))
return false;
call.setThis(thisv);
}
return true;
}
@ -205,8 +207,8 @@ NoSuchMethod(JSContext *cx, unsigned argc, Value *vp)
JSObject *obj = &vp[0].toObject();
JS_ASSERT(obj->getClass() == &js_NoSuchMethodClass);
args.calleev() = obj->getSlot(JSSLOT_FOUND_FUNCTION);
args.thisv() = vp[1];
args.setCallee(obj->getSlot(JSSLOT_FOUND_FUNCTION));
args.setThis(vp[1]);
args[0] = obj->getSlot(JSSLOT_SAVED_ID);
JSObject *argsobj = NewDenseCopiedArray(cx, argc, vp + 2);
if (!argsobj)
@ -223,7 +225,9 @@ bool
js::ReportIsNotFunction(JSContext *cx, const Value &v, MaybeConstruct construct)
{
unsigned error = construct ? JSMSG_NOT_CONSTRUCTOR : JSMSG_NOT_FUNCTION;
js_ReportValueError3(cx, error, JSDVG_SEARCH_STACK, v, NULL, NULL, NULL);
RootedValue val(cx, v);
js_ReportValueError3(cx, error, JSDVG_SEARCH_STACK, val, NullPtr(), NULL, NULL);
return false;
}
@ -232,7 +236,9 @@ js::ReportIsNotFunction(JSContext *cx, const Value *vp, MaybeConstruct construct
{
ptrdiff_t spIndex = cx->stack.spIndexOf(vp);
unsigned error = construct ? JSMSG_NOT_CONSTRUCTOR : JSMSG_NOT_FUNCTION;
js_ReportValueError3(cx, error, spIndex, *vp, NULL, NULL, NULL);
RootedValue val(cx, *vp);
js_ReportValueError3(cx, error, spIndex, val, NullPtr(), NULL, NULL);
return false;
}
@ -321,7 +327,7 @@ js::InvokeKernel(JSContext *cx, CallArgs args, MaybeConstruct construct)
InitialFrameFlags initial = (InitialFrameFlags) construct;
if (args.calleev().isPrimitive())
return ReportIsNotFunction(cx, &args.calleev(), construct);
return ReportIsNotFunction(cx, args.calleev().address(), construct);
JSObject &callee = args.callee();
Class *clasp = callee.getClass();
@ -334,7 +340,7 @@ js::InvokeKernel(JSContext *cx, CallArgs args, MaybeConstruct construct)
#endif
JS_ASSERT_IF(construct, !clasp->construct);
if (!clasp->call)
return ReportIsNotFunction(cx, &args.calleev(), construct);
return ReportIsNotFunction(cx, args.calleev().address(), construct);
return CallJSNative(cx, clasp->call, args);
}
@ -369,8 +375,8 @@ js::Invoke(JSContext *cx, const Value &thisv, const Value &fval, unsigned argc,
if (!cx->stack.pushInvokeArgs(cx, argc, &args))
return false;
args.calleev() = fval;
args.thisv() = thisv;
args.setCallee(fval);
args.setThis(thisv);
PodCopy(args.array(), argv, argc);
if (args.thisv().isObject()) {
@ -382,7 +388,7 @@ js::Invoke(JSContext *cx, const Value &thisv, const Value &fval, unsigned argc,
JSObject *thisp = args.thisv().toObject().thisObject(cx);
if (!thisp)
return false;
args.thisv().setObject(*thisp);
args.setThis(ObjectValue(*thisp));
}
if (!Invoke(cx, args))
@ -397,10 +403,10 @@ js::InvokeConstructorKernel(JSContext *cx, CallArgs args)
{
JS_ASSERT(!FunctionClass.construct);
args.thisv().setMagic(JS_IS_CONSTRUCTING);
args.setThis(MagicValue(JS_IS_CONSTRUCTING));
if (!args.calleev().isObject())
return ReportIsNotFunction(cx, &args.calleev(), CONSTRUCT);
return ReportIsNotFunction(cx, args.calleev().address(), CONSTRUCT);
JSObject &callee = args.callee();
if (callee.isFunction()) {
@ -414,7 +420,7 @@ js::InvokeConstructorKernel(JSContext *cx, CallArgs args)
}
if (!fun->isInterpretedConstructor())
return ReportIsNotFunction(cx, &args.calleev(), CONSTRUCT);
return ReportIsNotFunction(cx, args.calleev().address(), CONSTRUCT);
if (!InvokeKernel(cx, args, CONSTRUCT))
return false;
@ -425,7 +431,7 @@ js::InvokeConstructorKernel(JSContext *cx, CallArgs args)
Class *clasp = callee.getClass();
if (!clasp->construct)
return ReportIsNotFunction(cx, &args.calleev(), CONSTRUCT);
return ReportIsNotFunction(cx, args.calleev().address(), CONSTRUCT);
return CallJSNativeConstructor(cx, clasp->construct, args);
}
@ -437,8 +443,8 @@ js::InvokeConstructor(JSContext *cx, const Value &fval, unsigned argc, Value *ar
if (!cx->stack.pushInvokeArgs(cx, argc, &args))
return false;
args.calleev() = fval;
args.thisv().setMagic(JS_THIS_POISON);
args.setCallee(fval);
args.setThis(MagicValue(JS_THIS_POISON));
PodCopy(args.array(), argv, argc);
if (!InvokeConstructor(cx, args))
@ -530,8 +536,10 @@ js::HasInstance(JSContext *cx, HandleObject obj, const Value *v, JSBool *bp)
Class *clasp = obj->getClass();
if (clasp->hasInstance)
return clasp->hasInstance(cx, obj, v, bp);
RootedValue val(cx, ObjectValue(*obj));
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
JSDVG_SEARCH_STACK, ObjectValue(*obj), NULL);
JSDVG_SEARCH_STACK, val, NullPtr());
return JS_FALSE;
}
@ -880,8 +888,8 @@ DoIncDec(JSContext *cx, HandleScript script, jsbytecode *pc, const Value &v, Val
#define FETCH_OBJECT(cx, n, obj) \
JS_BEGIN_MACRO \
Value *vp_ = &regs.sp[n]; \
obj = ToObject(cx, (vp_)); \
HandleValue val = HandleValue::fromMarkedLocation(&regs.sp[n]); \
obj = ToObject(cx, (val)); \
if (!obj) \
goto error; \
JS_END_MACRO
@ -1675,9 +1683,9 @@ END_CASE(JSOP_AND)
BEGIN_CASE(JSOP_IN)
{
const Value &rref = regs.sp[-1];
HandleValue rref = HandleValue::fromMarkedLocation(&regs.sp[-1]);
if (!rref.isObject()) {
js_ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, rref, NULL);
js_ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, rref, NullPtr());
goto error;
}
RootedObject &obj = rootObject0;
@ -2204,8 +2212,9 @@ BEGIN_CASE(JSOP_TOID)
* There must be an object value below the id, which will not be popped
* but is necessary in interning the id for XML.
*/
Value objval = regs.sp[-2];
Value idval = regs.sp[-1];
RootedValue &objval = rootValue0, &idval = rootValue1;
objval = regs.sp[-2];
idval = regs.sp[-1];
MutableHandleValue res = MutableHandleValue::fromMarkedLocation(&regs.sp[-1]);
if (!ToIdOperation(cx, objval, idval, res))
@ -2300,8 +2309,11 @@ BEGIN_CASE(JSOP_GETXPROP)
BEGIN_CASE(JSOP_LENGTH)
BEGIN_CASE(JSOP_CALLPROP)
{
RootedValue &lval = rootValue0;
lval = regs.sp[-1];
RootedValue rval(cx);
if (!GetPropertyOperation(cx, script, regs.pc, regs.sp[-1], rval.address()))
if (!GetPropertyOperation(cx, regs.pc, &lval, &rval))
goto error;
TypeScript::Monitor(cx, script, regs.pc, rval);
@ -2315,8 +2327,8 @@ BEGIN_CASE(JSOP_SETGNAME)
BEGIN_CASE(JSOP_SETNAME)
BEGIN_CASE(JSOP_SETPROP)
{
const Value &rval = regs.sp[-1];
const Value &lval = regs.sp[-2];
HandleValue lval = HandleValue::fromMarkedLocation(&regs.sp[-2]);
HandleValue rval = HandleValue::fromMarkedLocation(&regs.sp[-1]);
if (!SetPropertyOperation(cx, regs.pc, lval, rval))
goto error;
@ -2329,10 +2341,11 @@ END_CASE(JSOP_SETPROP)
BEGIN_CASE(JSOP_GETELEM)
BEGIN_CASE(JSOP_CALLELEM)
{
Value &lref = regs.sp[-2];
Value &rref = regs.sp[-1];
MutableHandleValue lval = MutableHandleValue::fromMarkedLocation(&regs.sp[-2]);
HandleValue rval = HandleValue::fromMarkedLocation(&regs.sp[-1]);
MutableHandleValue res = MutableHandleValue::fromMarkedLocation(&regs.sp[-2]);
if (!GetElementOperation(cx, op, lref, rref, res))
if (!GetElementOperation(cx, op, lval, rval, res))
goto error;
TypeScript::Monitor(cx, script, regs.pc, res);
regs.sp--;
@ -3263,9 +3276,10 @@ BEGIN_CASE(JSOP_THROW)
BEGIN_CASE(JSOP_INSTANCEOF)
{
const Value &rref = regs.sp[-1];
RootedValue &rref = rootValue0;
rref = regs.sp[-1];
if (rref.isPrimitive()) {
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS, -1, rref, NULL);
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS, -1, rref, NullPtr());
goto error;
}
RootedObject &obj = rootObject0;
@ -3703,8 +3717,9 @@ BEGIN_CASE(JSOP_YIELD)
JS_ASSERT(!cx->isExceptionPending());
JS_ASSERT(regs.fp()->isNonEvalFunctionFrame());
if (cx->innermostGenerator()->state == JSGEN_CLOSING) {
js_ReportValueError(cx, JSMSG_BAD_GENERATOR_YIELD, JSDVG_SEARCH_STACK,
ObjectValue(regs.fp()->callee()), NULL);
RootedValue &val = rootValue0;
val.setObject(regs.fp()->callee());
js_ReportValueError(cx, JSMSG_BAD_GENERATOR_YIELD, JSDVG_SEARCH_STACK, val, NullPtr());
goto error;
}
regs.fp()->setReturnValue(regs.sp[-1]);

Просмотреть файл

@ -144,7 +144,7 @@ GuardFunApplyArgumentsOptimization(JSContext *cx)
* problem to the value at |spindex| on the stack.
*/
JS_ALWAYS_INLINE JSObject *
ValuePropertyBearer(JSContext *cx, StackFrame *fp, const Value &v, int spindex)
ValuePropertyBearer(JSContext *cx, StackFrame *fp, HandleValue v, int spindex)
{
if (v.isObject())
return &v.toObject();
@ -159,7 +159,7 @@ ValuePropertyBearer(JSContext *cx, StackFrame *fp, const Value &v, int spindex)
return global.getOrCreateBooleanPrototype(cx);
JS_ASSERT(v.isNull() || v.isUndefined());
js_ReportIsNullOrUndefined(cx, spindex, v, NULL);
js_ReportIsNullOrUndefined(cx, spindex, v, NullPtr());
return NULL;
}
@ -205,27 +205,27 @@ GetPropertyGenericMaybeCallXML(JSContext *cx, JSOp op, HandleObject obj, HandleI
}
inline bool
GetPropertyOperation(JSContext *cx, JSScript *script, jsbytecode *pc, Value &lval, Value *vp)
GetPropertyOperation(JSContext *cx, jsbytecode *pc, MutableHandleValue lval, MutableHandleValue vp)
{
JS_ASSERT(vp != &lval);
JS_ASSERT(vp.address() != lval.address());
JSOp op = JSOp(*pc);
if (op == JSOP_LENGTH) {
/* Optimize length accesses on strings, arrays, and arguments. */
if (lval.isString()) {
*vp = Int32Value(lval.toString()->length());
vp.setInt32(lval.toString()->length());
return true;
}
if (IsOptimizedArguments(cx->fp(), &lval)) {
*vp = Int32Value(cx->fp()->numActualArgs());
if (IsOptimizedArguments(cx->fp(), lval.address())) {
vp.setInt32(cx->fp()->numActualArgs());
return true;
}
if (lval.isObject()) {
JSObject *obj = &lval.toObject();
if (obj->isArray()) {
uint32_t length = obj->getArrayLength();
*vp = NumberValue(length);
vp.setNumber(length);
return true;
}
@ -234,19 +234,19 @@ GetPropertyOperation(JSContext *cx, JSScript *script, jsbytecode *pc, Value &lva
if (!argsobj->hasOverriddenLength()) {
uint32_t length = argsobj->initialLength();
JS_ASSERT(length < INT32_MAX);
*vp = Int32Value(int32_t(length));
vp.setInt32(int32_t(length));
return true;
}
}
if (obj->isTypedArray()) {
*vp = Int32Value(TypedArray::length(obj));
vp.setInt32(TypedArray::length(obj));
return true;
}
}
}
RootedObject obj(cx, ValueToObject(cx, lval));
RootedObject obj(cx, ToObjectFromStack(cx, lval));
if (!obj)
return false;
@ -256,40 +256,38 @@ GetPropertyOperation(JSContext *cx, JSScript *script, jsbytecode *pc, Value &lva
JS_PROPERTY_CACHE(cx).test(cx, pc, obj.get(), obj2.get(), entry, name);
if (!name) {
AssertValidPropertyCacheHit(cx, obj, obj2, entry);
if (!NativeGet(cx, obj, obj2, entry->prop, JSGET_CACHE_RESULT, vp))
if (!NativeGet(cx, obj, obj2, entry->prop, JSGET_CACHE_RESULT, vp.address()))
return false;
return true;
}
RootedId id(cx, NameToId(name));
RootedValue value(cx);
if (obj->getOps()->getProperty) {
if (!GetPropertyGenericMaybeCallXML(cx, op, obj, id, &value))
if (!GetPropertyGenericMaybeCallXML(cx, op, obj, id, vp))
return false;
} else {
if (!GetPropertyHelper(cx, obj, id, JSGET_CACHE_RESULT, &value))
if (!GetPropertyHelper(cx, obj, id, JSGET_CACHE_RESULT, vp))
return false;
}
#if JS_HAS_NO_SUCH_METHOD
if (op == JSOP_CALLPROP &&
JS_UNLIKELY(value.isPrimitive()) &&
JS_UNLIKELY(vp.isPrimitive()) &&
lval.isObject())
{
if (!OnUnknownMethod(cx, obj, IdToValue(id), &value))
if (!OnUnknownMethod(cx, obj, IdToValue(id), vp))
return false;
}
#endif
*vp = value;
return true;
}
inline bool
SetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, const Value &rval)
SetPropertyOperation(JSContext *cx, jsbytecode *pc, HandleValue lval, HandleValue rval)
{
RootedObject obj(cx, ValueToObject(cx, lval));
RootedObject obj(cx, ToObjectFromStack(cx, lval));
if (!obj)
return false;
@ -505,10 +503,8 @@ AddOperation(JSContext *cx, const Value &lhs, const Value &rhs, Value *res)
} else
#endif
{
RootedValue lval_(cx, lhs);
RootedValue rval_(cx, rhs);
Value &lval = lval_.get();
Value &rval = rval_.get();
RootedValue lval(cx, lhs);
RootedValue rval(cx, rhs);
/*
* If either operand is an object, any non-integer result must be
@ -516,9 +512,9 @@ AddOperation(JSContext *cx, const Value &lhs, const Value &rhs, Value *res)
*/
bool lIsObject = lval.isObject(), rIsObject = rval.isObject();
if (!ToPrimitive(cx, &lval))
if (!ToPrimitive(cx, lval.address()))
return false;
if (!ToPrimitive(cx, &rval))
if (!ToPrimitive(cx, rval.address()))
return false;
bool lIsString, rIsString;
if ((lIsString = lval.isString()) | (rIsString = rval.isString())) {
@ -629,14 +625,14 @@ FetchElementId(JSContext *cx, JSObject *obj, const Value &idval, jsid *idp, Muta
}
static JS_ALWAYS_INLINE bool
ToIdOperation(JSContext *cx, const Value &objval, const Value &idval, MutableHandleValue res)
ToIdOperation(JSContext *cx, HandleValue objval, HandleValue idval, MutableHandleValue res)
{
if (idval.isInt32()) {
res.set(idval);
return true;
}
JSObject *obj = ValueToObject(cx, objval);
JSObject *obj = ToObjectFromStack(cx, objval);
if (!obj)
return false;
@ -710,7 +706,8 @@ GetObjectElementOperation(JSContext *cx, JSOp op, HandleObject obj, const Value
}
static JS_ALWAYS_INLINE bool
GetElementOperation(JSContext *cx, JSOp op, Value &lref, const Value &rref, MutableHandleValue res)
GetElementOperation(JSContext *cx, JSOp op, MutableHandleValue lref, HandleValue rref,
MutableHandleValue res)
{
JS_ASSERT(op == JSOP_GETELEM || op == JSOP_CALLELEM);
@ -727,7 +724,7 @@ GetElementOperation(JSContext *cx, JSOp op, Value &lref, const Value &rref, Muta
}
StackFrame *fp = cx->fp();
if (IsOptimizedArguments(fp, &lref)) {
if (IsOptimizedArguments(fp, lref.address())) {
if (rref.isInt32()) {
int32_t i = rref.toInt32();
if (i >= 0 && uint32_t(i) < fp->numActualArgs()) {
@ -739,11 +736,11 @@ GetElementOperation(JSContext *cx, JSOp op, Value &lref, const Value &rref, Muta
if (!JSScript::argumentsOptimizationFailed(cx, fp->script()))
return false;
lref = ObjectValue(fp->argsObj());
lref.set(ObjectValue(fp->argsObj()));
}
bool isObject = lref.isObject();
RootedObject obj(cx, ValueToObject(cx, lref));
RootedObject obj(cx, ToObjectFromStack(cx, lref));
if (!obj)
return false;
if (!GetObjectElementOperation(cx, op, obj, rref, res))

Просмотреть файл

@ -343,7 +343,7 @@ GetCustomIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandle
JS_CHECK_RECURSION(cx, return false);
/* Check whether we have a valid __iterator__ method. */
PropertyName *name = cx->runtime->atomState.iteratorIntrinsicAtom;
RootedPropertyName name(cx, cx->runtime->atomState.iteratorIntrinsicAtom);
if (!GetMethod(cx, obj, name, 0, vp))
return false;
@ -368,8 +368,9 @@ GetCustomIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandle
JSAutoByteString bytes;
if (!js_AtomToPrintableString(cx, name, &bytes))
return false;
RootedValue val(cx, ObjectValue(*obj));
js_ReportValueError2(cx, JSMSG_BAD_TRAP_RETURN_VALUE,
-1, ObjectValue(*obj), NULL, bytes.ptr());
-1, val, NullPtr(), bytes.ptr());
return false;
}
return true;
@ -578,7 +579,8 @@ GetIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandleValue
// for this kind of error anyway, but it would throw an inscrutable
// error message about |method| rather than this nice one about |obj|.
if (!method.isObject() || !method.toObject().isCallable()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, ObjectOrNullValue(obj), NULL);
RootedValue val(cx, ObjectOrNullValue(obj));
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, val, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_ITERABLE, bytes);
@ -589,8 +591,10 @@ GetIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandleValue
if (!Invoke(cx, ObjectOrNullValue(obj), method, 0, NULL, vp.address()))
return false;
if (!ToObject(cx, vp.address()))
JSObject *obj = ToObject(cx, vp);
if (!obj)
return false;
vp.setObject(*obj);
return true;
}
@ -846,7 +850,7 @@ const uint32_t CLOSED_INDEX = UINT32_MAX;
JSObject *
ElementIteratorObject::create(JSContext *cx, Handle<Value> target)
{
GlobalObject *global = GetCurrentGlobal(cx);
Rooted<GlobalObject*> global(cx, GetCurrentGlobal(cx));
Rooted<JSObject*> proto(cx, global->getOrCreateElementIteratorPrototype(cx));
if (!proto)
return NULL;
@ -874,16 +878,16 @@ ElementIteratorObject::next(JSContext *cx, unsigned argc, Value *vp)
bool
ElementIteratorObject::next_impl(JSContext *cx, CallArgs args)
{
JSObject *iterobj = &args.thisv().toObject();
RootedObject iterobj(cx, &args.thisv().toObject());
uint32_t i, length;
Value target = iterobj->getReservedSlot(TargetSlot);
RootedValue target(cx, iterobj->getReservedSlot(TargetSlot));
Rooted<JSObject*> obj(cx);
// Get target.length.
if (target.isString()) {
length = uint32_t(target.toString()->length());
} else {
obj = ValueToObject(cx, target);
obj = ToObjectFromStack(cx, target);
if (!obj)
goto close;
if (!js_GetLengthProperty(cx, obj, &length))
@ -1605,8 +1609,9 @@ generator_send_impl(JSContext *cx, CallArgs args)
}
if (gen->state == JSGEN_NEWBORN && args.hasDefined(0)) {
RootedValue val(cx, args[0]);
js_ReportValueError(cx, JSMSG_BAD_GENERATOR_SEND,
JSDVG_SEARCH_STACK, args[0], NULL);
JSDVG_SEARCH_STACK, val, NullPtr());
return false;
}

Просмотреть файл

@ -329,6 +329,8 @@ js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map)
static JSBool
obj_toSource(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
bool comma = false;
const jschar *vchars;
size_t vlength;
@ -345,7 +347,7 @@ obj_toSource(JSContext *cx, unsigned argc, Value *vp)
/* If outermost, we need parentheses to be an expression, not a block. */
bool outermost = (cx->sharpObjectMap.depth == 0);
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -364,7 +366,7 @@ obj_toSource(JSContext *cx, unsigned argc, Value *vp)
JSString *str = js_NewStringCopyZ(cx, "{}");
if (!str)
return false;
vp->setString(str);
args.rval().setString(str);
return true;
}
@ -537,7 +539,7 @@ obj_toSource(JSContext *cx, unsigned argc, Value *vp)
JSString *str = buf.finishString();
if (!str)
return false;
vp->setString(str);
args.rval().setString(str);
return true;
}
#endif /* JS_HAS_TOSOURCE */
@ -594,22 +596,22 @@ InformalValueTypeName(const Value &v)
static JSBool
obj_toString(JSContext *cx, unsigned argc, Value *vp)
{
Value &thisv = vp[1];
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
if (thisv.isUndefined()) {
vp->setString(cx->runtime->atomState.objectUndefinedAtom);
if (args.thisv().isUndefined()) {
args.rval().setString(cx->runtime->atomState.objectUndefinedAtom);
return true;
}
/* Step 2. */
if (thisv.isNull()) {
vp->setString(cx->runtime->atomState.objectNullAtom);
if (args.thisv().isNull()) {
args.rval().setString(cx->runtime->atomState.objectNullAtom);
return true;
}
/* Step 3. */
JSObject *obj = ToObject(cx, &thisv);
JSObject *obj = ToObject(cx, args.thisv());
if (!obj)
return false;
@ -617,7 +619,7 @@ obj_toString(JSContext *cx, unsigned argc, Value *vp)
JSString *str = js::obj_toStringHelper(cx, obj);
if (!str)
return false;
vp->setString(str);
args.rval().setString(str);
return true;
}
@ -630,7 +632,7 @@ obj_toLocaleString(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
JSObject *obj = ToObject(cx, &args.thisv());
JSObject *obj = ToObject(cx, args.thisv());
if (!obj)
return false;
@ -642,10 +644,11 @@ obj_toLocaleString(JSContext *cx, unsigned argc, Value *vp)
static JSBool
obj_valueOf(JSContext *cx, unsigned argc, Value *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
CallArgs args = CallArgsFromVp(argc, vp);
JSObject *obj = ToObject(cx, args.thisv());
if (!obj)
return false;
vp->setObject(*obj);
args.rval().setObject(*obj);
return true;
}
@ -684,20 +687,22 @@ obj_watch_handler(JSContext *cx, JSObject *obj_, jsid id_, jsval old,
static JSBool
obj_watch(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (argc <= 1) {
js_ReportMissingArg(cx, *vp, 1);
js_ReportMissingArg(cx, args.calleev(), 1);
return false;
}
RootedObject callable(cx, ValueToCallable(cx, &vp[3]));
RootedObject callable(cx, ValueToCallable(cx, &args[1]));
if (!callable)
return false;
RootedId propid(cx);
if (!ValueToId(cx, vp[2], propid.address()))
if (!ValueToId(cx, args[0], propid.address()))
return false;
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -706,7 +711,7 @@ obj_watch(JSContext *cx, unsigned argc, Value *vp)
if (!CheckAccess(cx, obj, propid, JSACC_WATCH, &tmp, &attrs))
return false;
vp->setUndefined();
args.rval().setUndefined();
if (obj->isDenseArray() && !JSObject::makeDenseArraySlow(cx, obj))
return false;
@ -716,13 +721,15 @@ obj_watch(JSContext *cx, unsigned argc, Value *vp)
static JSBool
obj_unwatch(JSContext *cx, unsigned argc, Value *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
vp->setUndefined();
args.rval().setUndefined();
jsid id;
if (argc != 0) {
if (!ValueToId(cx, vp[2], &id))
if (!ValueToId(cx, args[0], &id))
return false;
} else {
id = JSID_VOID;
@ -741,21 +748,25 @@ obj_unwatch(JSContext *cx, unsigned argc, Value *vp)
static JSBool
obj_hasOwnProperty(JSContext *cx, unsigned argc, Value *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
return js_HasOwnPropertyHelper(cx, obj->getOps()->lookupGeneric, argc, vp);
return js_HasOwnPropertyHelper(cx, obj->getOps()->lookupGeneric, argc, args.rval().address());
}
JSBool
js_HasOwnPropertyHelper(JSContext *cx, LookupGenericOp lookup, unsigned argc,
Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedId id(cx);
if (!ValueToId(cx, argc != 0 ? vp[2] : UndefinedValue(), id.address()))
if (!ValueToId(cx, args.length() ? args[0] : UndefinedValue(), id.address()))
return JS_FALSE;
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
RootedObject obj2(cx);
@ -764,12 +775,12 @@ js_HasOwnPropertyHelper(JSContext *cx, LookupGenericOp lookup, unsigned argc,
bool has;
if (!Proxy::hasOwn(cx, obj, id, &has))
return false;
vp->setBoolean(has);
args.rval().setBoolean(has);
return true;
}
if (!js_HasOwnProperty(cx, lookup, obj, id, &obj2, &prop))
return JS_FALSE;
vp->setBoolean(!!prop);
args.rval().setBoolean(!!prop);
return JS_TRUE;
}
@ -808,19 +819,21 @@ js_HasOwnProperty(JSContext *cx, LookupGenericOp lookup, HandleObject obj, Handl
static JSBool
obj_isPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
if (argc < 1 || !vp[2].isObject()) {
vp->setBoolean(false);
if (args.length() < 1 || !args[0].isObject()) {
args.rval().setBoolean(false);
return true;
}
/* Step 2. */
JSObject *obj = ToObject(cx, &vp[1]);
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
/* Step 3. */
vp->setBoolean(js_IsDelegate(cx, obj, vp[2]));
args.rval().setBoolean(js_IsDelegate(cx, obj, args[0]));
return true;
}
@ -828,18 +841,20 @@ obj_isPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
static JSBool
obj_propertyIsEnumerable(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
RootedId id(cx);
if (!ValueToId(cx, argc != 0 ? vp[2] : UndefinedValue(), id.address()))
if (!ValueToId(cx, args.length() ? args[0] : UndefinedValue(), id.address()))
return false;
/* Step 2. */
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
/* Steps 3-5. */
return js_PropertyIsEnumerable(cx, obj, id, vp);
return js_PropertyIsEnumerable(cx, obj, id, args.rval().address());
}
JSBool
@ -941,32 +956,34 @@ js::obj_defineSetter(JSContext *cx, unsigned argc, Value *vp)
static JSBool
obj_lookupGetter(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedId id(cx);
if (!ValueToId(cx, argc != 0 ? vp[2] : UndefinedValue(), id.address()))
if (!ValueToId(cx, args.length() ? args[0] : UndefinedValue(), id.address()))
return JS_FALSE;
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return JS_FALSE;
if (obj->isProxy()) {
// The vanilla getter lookup code below requires that the object is
// native. Handle proxies separately.
vp->setUndefined();
args.rval().setUndefined();
AutoPropertyDescriptorRooter desc(cx);
if (!Proxy::getPropertyDescriptor(cx, obj, id, false, &desc))
return JS_FALSE;
if (desc.obj && (desc.attrs & JSPROP_GETTER) && desc.getter)
*vp = CastAsObjectJsval(desc.getter);
args.rval().set(CastAsObjectJsval(desc.getter));
return JS_TRUE;
}
RootedObject pobj(cx);
RootedShape shape(cx);
if (!obj->lookupGeneric(cx, id, &pobj, &shape))
return JS_FALSE;
vp->setUndefined();
args.rval().setUndefined();
if (shape) {
if (pobj->isNative()) {
if (shape->hasGetterValue())
*vp = shape->getterValue();
args.rval().set(shape->getterValue());
}
}
return JS_TRUE;
@ -975,32 +992,34 @@ obj_lookupGetter(JSContext *cx, unsigned argc, Value *vp)
static JSBool
obj_lookupSetter(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedId id(cx);
if (!ValueToId(cx, argc != 0 ? vp[2] : UndefinedValue(), id.address()))
if (!ValueToId(cx, args.length() ? args[0] : UndefinedValue(), id.address()))
return JS_FALSE;
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return JS_FALSE;
if (obj->isProxy()) {
// The vanilla setter lookup code below requires that the object is
// native. Handle proxies separately.
vp->setUndefined();
args.rval().setUndefined();
AutoPropertyDescriptorRooter desc(cx);
if (!Proxy::getPropertyDescriptor(cx, obj, id, false, &desc))
return JS_FALSE;
if (desc.obj && (desc.attrs & JSPROP_SETTER) && desc.setter)
*vp = CastAsObjectJsval(desc.setter);
args.rval().set(CastAsObjectJsval(desc.setter));
return JS_TRUE;
}
RootedObject pobj(cx);
RootedShape shape(cx);
if (!obj->lookupGeneric(cx, id, &pobj, &shape))
return JS_FALSE;
vp->setUndefined();
args.rval().setUndefined();
if (shape) {
if (pobj->isNative()) {
if (shape->hasSetterValue())
*vp = shape->setterValue();
args.rval().set(shape->setterValue());
}
}
return JS_TRUE;
@ -1020,7 +1039,8 @@ obj_getPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
}
if (args[0].isPrimitive()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, vp[2], NULL);
RootedValue val(cx, args[0]);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, val, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
@ -1038,8 +1058,8 @@ obj_getPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
InvokeArgsGuard nested;
if (!cx->stack.pushInvokeArgs(cx, 0, &nested))
return false;
nested.calleev() = cx->global()->protoGetter();
nested.thisv() = args[0];
nested.setCallee(cx->global()->protoGetter());
nested.setThis(args[0]);
if (!Invoke(cx, nested))
return false;
args.rval().set(nested.rval());
@ -1189,9 +1209,9 @@ GetFirstArgumentAsObject(JSContext *cx, unsigned argc, Value *vp, const char *me
return false;
}
const Value &v = vp[2];
RootedValue v(cx, vp[2]);
if (!v.isObject()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE,
@ -1397,9 +1417,10 @@ bool
Throw(JSContext *cx, JSObject *obj, unsigned errorNumber)
{
if (js_ErrorFormatString[errorNumber].argCount == 1) {
RootedValue val(cx, ObjectValue(*obj));
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,
JSDVG_IGNORE_STACK, ObjectValue(*obj),
NULL, NULL, NULL);
JSDVG_IGNORE_STACK, val, NullPtr(),
NULL, NULL);
} else {
JS_ASSERT(js_ErrorFormatString[errorNumber].argCount == 0);
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, errorNumber);
@ -1924,19 +1945,22 @@ js_PopulateObject(JSContext *cx, HandleObject newborn, HandleObject props)
static JSBool
obj_defineProperties(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Steps 1 and 7. */
RootedObject obj(cx);
if (!GetFirstArgumentAsObject(cx, argc, vp, "Object.defineProperties", &obj))
if (!GetFirstArgumentAsObject(cx, args.length(), vp, "Object.defineProperties", &obj))
return false;
vp->setObject(*obj);
args.rval().setObject(*obj);
/* Step 2. */
if (argc < 2) {
if (args.length() < 2) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED,
"Object.defineProperties", "0", "s");
return false;
}
RootedObject props(cx, ToObject(cx, &vp[3]));
RootedValue val(cx, args[1]);
RootedObject props(cx, ToObject(cx, val));
if (!props)
return false;
@ -1955,9 +1979,9 @@ obj_create(JSContext *cx, unsigned argc, Value *vp)
}
CallArgs args = CallArgsFromVp(argc, vp);
const Value &v = args[0];
RootedValue v(cx, args[0]);
if (!v.isObjectOrNull()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE,
@ -4697,9 +4721,10 @@ js_GetPropertyHelperInline(JSContext *cx, HandleObject obj, HandleObject receive
cx->stack.currentScript()->warnedAboutUndefinedProp = true;
/* Ok, bad undefined property reference: whine about it. */
RootedValue val(cx, IdToValue(id));
if (!js_ReportValueErrorFlags(cx, flags, JSMSG_UNDEFINED_PROP,
JSDVG_IGNORE_STACK, IdToValue(id),
NULL, NULL, NULL))
JSDVG_IGNORE_STACK, val, NullPtr(),
NULL, NULL))
{
return false;
}
@ -4809,25 +4834,28 @@ js::CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname)
bool
JSObject::reportReadOnly(JSContext *cx, jsid id, unsigned report)
{
RootedValue val(cx, IdToValue(id));
return js_ReportValueErrorFlags(cx, report, JSMSG_READ_ONLY,
JSDVG_IGNORE_STACK, IdToValue(id), NULL,
JSDVG_IGNORE_STACK, val, NullPtr(),
NULL, NULL);
}
bool
JSObject::reportNotConfigurable(JSContext *cx, jsid id, unsigned report)
{
RootedValue val(cx, IdToValue(id));
return js_ReportValueErrorFlags(cx, report, JSMSG_CANT_DELETE,
JSDVG_IGNORE_STACK, IdToValue(id), NULL,
JSDVG_IGNORE_STACK, val, NullPtr(),
NULL, NULL);
}
bool
JSObject::reportNotExtensible(JSContext *cx, unsigned report)
{
RootedValue val(cx, ObjectValue(*this));
return js_ReportValueErrorFlags(cx, report, JSMSG_OBJECT_NOT_EXTENSIBLE,
JSDVG_IGNORE_STACK, ObjectValue(*this),
NULL, NULL, NULL);
JSDVG_IGNORE_STACK, val, NullPtr(),
NULL, NULL);
}
bool
@ -5265,7 +5293,7 @@ DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp
}
/* Avoid recursive death when decompiling in js_ReportValueError. */
JSString *str;
RootedString str(cx);
if (hint == JSTYPE_STRING) {
str = JS_InternString(cx, clasp->name);
if (!str)
@ -5274,7 +5302,8 @@ DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp
str = NULL;
}
js_ReportValueError2(cx, JSMSG_CANT_CONVERT_TO, JSDVG_SEARCH_STACK, ObjectValue(*obj), str,
RootedValue val(cx, ObjectValue(*obj));
js_ReportValueError2(cx, JSMSG_CANT_CONVERT_TO, JSDVG_SEARCH_STACK, val, str,
(hint == JSTYPE_VOID) ? "primitive type" : JS_TYPE_STR(hint));
return false;
}
@ -5489,21 +5518,22 @@ namespace js {
/* Callers must handle the already-object case . */
JSObject *
ToObjectSlow(JSContext *cx, Value *vp)
ToObjectSlow(JSContext *cx, HandleValue val, bool reportScanStack)
{
JS_ASSERT(!vp->isMagic());
JS_ASSERT(!vp->isObject());
JS_ASSERT(!val.isMagic());
JS_ASSERT(!val.isObject());
if (vp->isNullOrUndefined()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT_TO,
vp->isNull() ? "null" : "undefined", "object");
if (val.isNullOrUndefined()) {
if (reportScanStack) {
js_ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, val, NullPtr());
} else {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT_TO,
val.isNull() ? "null" : "undefined", "object");
}
return NULL;
}
JSObject *obj = PrimitiveToObject(cx, *vp);
if (obj)
vp->setObject(*obj);
return obj;
return PrimitiveToObject(cx, val);
}
}
@ -5515,8 +5545,10 @@ js_ValueToNonNullObject(JSContext *cx, const Value &v)
if (!js_ValueToObjectOrNull(cx, v, &obj))
return NULL;
if (!obj)
js_ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, v, NULL);
if (!obj) {
RootedValue val(cx, v);
js_ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, val, NullPtr());
}
return obj;
}

Просмотреть файл

@ -1334,27 +1334,29 @@ js_ValueToNonNullObject(JSContext *cx, const js::Value &v);
namespace js {
/*
* Invokes the ES5 ToObject algorithm on *vp, writing back the object to vp.
* If *vp might already be an object, use ToObject.
* Invokes the ES5 ToObject algorithm on vp, returning the result. If vp might
* already be an object, use ToObject. reportCantConvert controls how null and
* undefined errors are reported.
*/
extern JSObject *
ToObjectSlow(JSContext *cx, Value *vp);
ToObjectSlow(JSContext *cx, HandleValue vp, bool reportScanStack);
/* For object conversion in e.g. native functions. */
JS_ALWAYS_INLINE JSObject *
ToObject(JSContext *cx, Value *vp)
ToObject(JSContext *cx, HandleValue vp)
{
if (vp->isObject())
return &vp->toObject();
return ToObjectSlow(cx, vp);
if (vp.isObject())
return &vp.toObject();
return ToObjectSlow(cx, vp, false);
}
/* As for ToObject, but preserves the original value. */
inline JSObject *
ValueToObject(JSContext *cx, const Value &v)
/* For converting stack values to objects. */
JS_ALWAYS_INLINE JSObject *
ToObjectFromStack(JSContext *cx, HandleValue vp)
{
if (v.isObject())
return &v.toObject();
return js_ValueToNonNullObject(cx, v);
if (vp.isObject())
return &vp.toObject();
return ToObjectSlow(cx, vp, true);
}
} /* namespace js */

Просмотреть файл

@ -295,8 +295,8 @@ PreprocessValue(JSContext *cx, HandleObject holder, KeyType key, MutableHandleVa
if (!cx->stack.pushInvokeArgs(cx, 1, &args))
return false;
args.calleev() = toJSON;
args.thisv() = vp;
args.setCallee(toJSON);
args.setThis(vp);
args[0] = StringValue(keyStr);
if (!Invoke(cx, args))
@ -317,8 +317,8 @@ PreprocessValue(JSContext *cx, HandleObject holder, KeyType key, MutableHandleVa
if (!cx->stack.pushInvokeArgs(cx, 2, &args))
return false;
args.calleev() = ObjectValue(*scx->replacer);
args.thisv() = ObjectValue(*holder);
args.setCallee(ObjectValue(*scx->replacer));
args.setThis(ObjectValue(*holder));
args[0] = StringValue(keyStr);
args[1] = vp;
@ -838,8 +838,8 @@ Walk(JSContext *cx, HandleObject holder, HandleId name, HandleValue reviver, Mut
if (!cx->stack.pushInvokeArgs(cx, 2, &args))
return false;
args.calleev() = reviver;
args.thisv() = ObjectValue(*holder);
args.setCallee(reviver);
args.setThis(ObjectValue(*holder));
args[0] = StringValue(key);
args[1] = val;

Просмотреть файл

@ -6200,9 +6200,10 @@ DecompileExpressionFromStack(JSContext *cx, int spindex, Value v, char **res)
}
char *
js_DecompileValueGenerator(JSContext *cx, int spindex, jsval v,
JSString *fallback)
js::DecompileValueGenerator(JSContext *cx, int spindex, HandleValue v,
HandleString fallbackArg)
{
RootedString fallback(cx, fallbackArg);
{
char *result;
if (!DecompileExpressionFromStack(cx, spindex, v, &result))

Просмотреть файл

@ -321,22 +321,6 @@ js_DecompileToString(JSContext *cx, const char *name, JSFunction *fun,
unsigned indent, JSBool pretty, JSBool grouped, JSBool strict,
JSDecompilerPtr decompiler);
/*
* Find the source expression that resulted in v, and return a newly allocated
* C-string containing it. Fall back on v's string conversion (fallback) if we
* can't find the bytecode that generated and pushed v on the operand stack.
*
* Search the current stack frame if spindex is JSDVG_SEARCH_STACK. Don't
* look for v on the stack if spindex is JSDVG_IGNORE_STACK. Otherwise,
* spindex is the negative index of v, measured from cx->fp->sp, or from a
* lower frame's sp if cx->fp is native.
*
* The caller must call JS_free on the result after a succsesful call.
*/
extern char *
js_DecompileValueGenerator(JSContext *cx, int spindex, jsval v,
JSString *fallback);
/*
* Given bytecode address pc in script's main program code, return the operand
* stack depth just before (JSOp) *pc executes.
@ -361,12 +345,20 @@ js_GetVariableBytecodeLength(jsbytecode *pc);
namespace js {
static inline char *
DecompileValueGenerator(JSContext *cx, int spindex, const Value &v,
JSString *fallback)
{
return js_DecompileValueGenerator(cx, spindex, v, fallback);
}
/*
* Find the source expression that resulted in v, and return a newly allocated
* C-string containing it. Fall back on v's string conversion (fallback) if we
* can't find the bytecode that generated and pushed v on the operand stack.
*
* Search the current stack frame if spindex is JSDVG_SEARCH_STACK. Don't
* look for v on the stack if spindex is JSDVG_IGNORE_STACK. Otherwise,
* spindex is the negative index of v, measured from cx->fp->sp, or from a
* lower frame's sp if cx->fp is native.
*
* The caller must call JS_free on the result after a succsesful call.
*/
char *
DecompileValueGenerator(JSContext *cx, int spindex, HandleValue v, HandleString fallback);
/*
* Sprintf, but with unlimited and automatically allocated buffering.

Просмотреть файл

@ -352,8 +352,10 @@ bool
BaseProxyHandler::hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp)
{
JS_ASSERT(OperationInProgress(cx, proxy));
RootedValue val(cx, ObjectValue(*proxy));
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
JSDVG_SEARCH_STACK, ObjectValue(*proxy), NULL);
JSDVG_SEARCH_STACK, val, NullPtr());
return false;
}
@ -493,7 +495,7 @@ bool
IndirectProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
CallArgs args)
{
args.thisv() = ObjectValue(*GetProxyTargetObject(&args.thisv().toObject()));
args.setThis(ObjectValue(*GetProxyTargetObject(&args.thisv().toObject())));
if (!test(args.thisv())) {
ReportIncompatible(cx, args);
return false;
@ -825,8 +827,9 @@ ReturnedValueMustNotBePrimitive(JSContext *cx, JSObject *proxy, JSAtom *atom, co
if (v.isPrimitive()) {
JSAutoByteString bytes;
if (js_AtomToPrintableString(cx, atom, &bytes)) {
RootedValue val(cx, ObjectOrNullValue(proxy));
js_ReportValueError2(cx, JSMSG_BAD_TRAP_RETURN_VALUE,
JSDVG_SEARCH_STACK, ObjectOrNullValue(proxy), NULL, bytes.ptr());
JSDVG_SEARCH_STACK, val, NullPtr(), bytes.ptr());
}
return false;
}
@ -1074,10 +1077,12 @@ class AutoPendingProxyOperation {
bool
Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set,
Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy_, jsid id_, bool set,
PropertyDescriptor *desc)
{
JS_CHECK_RECURSION(cx, return false);
RootedObject proxy(cx, proxy_);
RootedId id(cx, id_);
AutoPendingProxyOperation pending(cx, proxy);
BaseProxyHandler *handler = GetProxyHandler(proxy);
if (!handler->hasPrototype())
@ -1193,9 +1198,11 @@ Proxy::enumerate(JSContext *cx, JSObject *proxy, AutoIdVector &props)
}
bool
Proxy::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
Proxy::has(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
{
JS_CHECK_RECURSION(cx, return false);
RootedObject proxy(cx, proxy_);
RootedId id(cx, id_);
AutoPendingProxyOperation pending(cx, proxy);
BaseProxyHandler *handler = GetProxyHandler(proxy);
if (!handler->hasPrototype())
@ -1258,14 +1265,14 @@ Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id
JS_CHECK_RECURSION(cx, return false);
AutoPendingProxyOperation pending(cx, proxy);
BaseProxyHandler *handler = GetProxyHandler(proxy);
JSObject *proto;
RootedObject proto(cx);
if (handler->hasPrototype()) {
// If we're using a prototype, we still want to use the proxy trap unless
// we have a non-own property with a setter.
bool hasOwn;
AutoPropertyDescriptorRooter desc(cx);
if (handler->hasOwn(cx, proxy, id, &hasOwn) && !hasOwn &&
handler->getPrototypeOf(cx, proxy, &proto) && proto &&
handler->getPrototypeOf(cx, proxy, proto.address()) && proto &&
JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, &desc) &&
desc.obj && desc.setter)
{

Просмотреть файл

@ -186,7 +186,7 @@ class NodeBuilder
if (!funv.isObject() || !funv.toObject().isFunction()) {
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_NOT_FUNCTION,
JSDVG_SEARCH_STACK, funv, NULL, NULL, NULL);
JSDVG_SEARCH_STACK, funv, NullPtr(), NULL, NULL);
return false;
}
@ -3183,12 +3183,12 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp)
JSObject *builder = NULL;
Value arg = argc > 1 ? JS_ARGV(cx, vp)[1] : UndefinedValue();
RootedValue arg(cx, argc > 1 ? JS_ARGV(cx, vp)[1] : UndefinedValue());
if (!arg.isNullOrUndefined()) {
if (!arg.isObject()) {
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
JSDVG_SEARCH_STACK, arg, NULL, "not an object", NULL);
JSDVG_SEARCH_STACK, arg, NullPtr(), "not an object", NULL);
return JS_FALSE;
}
@ -3245,7 +3245,7 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp)
if (!prop.isNullOrUndefined()) {
if (!prop.isObject()) {
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
JSDVG_SEARCH_STACK, prop, NULL, "not an object", NULL);
JSDVG_SEARCH_STACK, prop, NullPtr(), "not an object", NULL);
return JS_FALSE;
}
builder = &prop.toObject();

Просмотреть файл

@ -440,7 +440,7 @@ ThisToStringForStringProto(JSContext *cx, CallReceiver call)
Rooted<jsid> id(cx, NameToId(cx->runtime->atomState.toStringAtom));
if (ClassMethodIsNative(cx, obj, &StringClass, id, js_str_toString)) {
JSString *str = obj->asString().unbox();
call.thisv().setString(str);
call.setThis(StringValue(str));
return str;
}
}
@ -454,7 +454,7 @@ ThisToStringForStringProto(JSContext *cx, CallReceiver call)
if (!str)
return NULL;
call.thisv().setString(str);
call.setThis(StringValue(str));
return str;
}
@ -1022,7 +1022,7 @@ StringMatch(const jschar *text, uint32_t textlen,
static const size_t sRopeMatchThresholdRatioLog2 = 5;
/*
* RopeMatch takes the text to search, the patern to search for in the text.
* RopeMatch takes the text to search and the pattern to search for in the text.
* RopeMatch returns false on OOM and otherwise returns the match index through
* the 'match' outparam (-1 for not found).
*/
@ -1148,6 +1148,9 @@ str_contains(JSContext *cx, unsigned argc, Value *vp)
if (!text)
return false;
// XXX fix for moving GC.
SkipRoot skip(cx, &text);
if (args.hasDefined(1)) {
// Step 4
double posDouble;
@ -1325,6 +1328,9 @@ str_startsWith(JSContext *cx, unsigned argc, Value *vp)
if (!text)
return false;
// XXX fix for moving GC.
SkipRoot skip(cx, &text);
if (args.hasDefined(1)) {
// Step 4
double posDouble;
@ -1368,6 +1374,9 @@ str_endsWith(JSContext *cx, unsigned argc, Value *vp)
if (!text)
return false;
// XXX fix for moving GC.
SkipRoot skip(cx, &text);
if (args.hasDefined(1)) {
// Step 5
double endPosDouble;
@ -1978,7 +1987,7 @@ FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t
return false;
args.setCallee(ObjectValue(*lambda));
args.thisv() = UndefinedValue();
args.setThis(UndefinedValue());
/* Push $&, $1, $2, ... */
unsigned argi = 0;
@ -2296,8 +2305,8 @@ str_replace_flat_lambda(JSContext *cx, CallArgs outerArgs, ReplaceData &rdata, c
return false;
CallArgs &args = rdata.args;
args.calleev().setObject(*rdata.lambda);
args.thisv().setUndefined();
args.setCallee(ObjectValue(*rdata.lambda));
args.setThis(UndefinedValue());
Value *sp = args.array();
sp[0].setString(matchStr);
@ -2769,7 +2778,7 @@ static JSBool
str_substr(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JSString *str = ThisToStringForStringProto(cx, args);
RootedString str(cx, ThisToStringForStringProto(cx, args));
if (!str)
return false;

Просмотреть файл

@ -46,8 +46,8 @@ class StringSegmentRange
* If malloc() shows up in any profiles from this vector, we can add a new
* StackAllocPolicy which stashes a reusable freed-at-gc buffer in the cx.
*/
Vector<JSString *, 32> stack;
JSLinearString *cur;
AutoStringVector stack;
Rooted<JSLinearString*> cur;
bool settle(JSString *str) {
while (str->isRope()) {
@ -62,7 +62,7 @@ class StringSegmentRange
public:
StringSegmentRange(JSContext *cx)
: stack(cx), cur(NULL)
: stack(cx), cur(cx)
{}
JS_WARN_UNUSED_RESULT bool init(JSString *str) {

Просмотреть файл

@ -143,10 +143,9 @@ ArrayBufferObject::fun_slice_impl(JSContext *cx, CallArgs args)
JS_ASSERT(IsArrayBuffer(args.thisv()));
Rooted<JSObject*> thisObj(cx, &args.thisv().toObject());
ArrayBufferObject &arrayBuffer = thisObj->asArrayBuffer();
// these are the default values
uint32_t length = arrayBuffer.byteLength();
uint32_t length = thisObj->asArrayBuffer().byteLength();
uint32_t begin = 0, end = length;
if (args.length() > 0) {
@ -162,7 +161,7 @@ ArrayBufferObject::fun_slice_impl(JSContext *cx, CallArgs args)
if (begin > end)
begin = end;
JSObject *nobj = createSlice(cx, arrayBuffer, begin, end);
JSObject *nobj = createSlice(cx, thisObj->asArrayBuffer(), begin, end);
if (!nobj)
return false;
args.rval().setObject(*nobj);
@ -1678,8 +1677,8 @@ class TypedArrayTemplate
if (!cx->stack.pushInvokeArgs(cx, 3, &ag))
return NULL;
ag.calleev() = cx->compartment->maybeGlobal()->createArrayFromBuffer<NativeType>();
ag.thisv() = ObjectValue(*bufobj);
ag.setCallee(cx->compartment->maybeGlobal()->createArrayFromBuffer<NativeType>());
ag.setThis(ObjectValue(*bufobj));
ag[0] = Int32Value(byteOffsetInt);
ag[1] = Int32Value(lengthInt);
ag[2] = ObjectValue(*proto);
@ -2262,8 +2261,8 @@ DataViewObject::class_constructor(JSContext *cx, unsigned argc, Value *vp)
InvokeArgsGuard ag;
if (!cx->stack.pushInvokeArgs(cx, argc + 1, &ag))
return false;
ag.calleev() = global->createDataViewForThis();
ag.thisv() = ObjectValue(*bufobj);
ag.setCallee(global->createDataViewForThis());
ag.setThis(ObjectValue(*bufobj));
PodCopy(ag.array(), args.array(), args.length());
ag[argc] = ObjectValue(*proto);
if (!Invoke(cx, ag))

Просмотреть файл

@ -205,7 +205,7 @@ static JSPropertySpec namespace_props[] = {
static JSBool
namespace_toString(JSContext *cx, unsigned argc, Value *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1]));
if (!obj)
return JS_FALSE;
if (!obj->isNamespace()) {
@ -395,7 +395,7 @@ ConvertQNameToString(JSContext *cx, JSObject *obj)
static JSBool
qname_toString(JSContext *cx, unsigned argc, Value *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1]));
if (!obj)
return false;
@ -1897,8 +1897,9 @@ ToXML(JSContext *cx, jsval v)
return obj;
bad:
RootedValue val(cx, v);
js_ReportValueError(cx, JSMSG_BAD_XML_CONVERSION,
JSDVG_IGNORE_STACK, v, NULL);
JSDVG_IGNORE_STACK, val, NullPtr());
return NULL;
}
@ -1973,8 +1974,9 @@ ToXMLList(JSContext *cx, jsval v)
return listobj;
bad:
RootedValue val(cx, v);
js_ReportValueError(cx, JSMSG_BAD_XMLLIST_CONVERSION,
JSDVG_IGNORE_STACK, v, NULL);
JSDVG_IGNORE_STACK, val, NullPtr());
return NULL;
}
@ -2789,8 +2791,9 @@ ToAttributeName(JSContext *cx, jsval v)
uri = prefix = cx->runtime->emptyString;
} else {
if (JSVAL_IS_PRIMITIVE(v)) {
RootedValue val(cx, v);
js_ReportValueError(cx, JSMSG_BAD_XML_ATTR_NAME,
JSDVG_IGNORE_STACK, v, NULL);
JSDVG_IGNORE_STACK, val, NullPtr());
return NULL;
}
@ -2825,7 +2828,8 @@ ToAttributeName(JSContext *cx, jsval v)
static void
ReportBadXMLName(JSContext *cx, const Value &idval)
{
js_ReportValueError(cx, JSMSG_BAD_XML_NAME, JSDVG_IGNORE_STACK, idval, NULL);
RootedValue val(cx, idval);
js_ReportValueError(cx, JSMSG_BAD_XML_NAME, JSDVG_IGNORE_STACK, val, NullPtr());
}
namespace js {
@ -5372,7 +5376,7 @@ StartNonListXMLMethod(JSContext *cx, jsval *vp, MutableHandleObject objp)
JS_ASSERT(!JSVAL_IS_PRIMITIVE(*vp));
JS_ASSERT(JSVAL_TO_OBJECT(*vp)->isFunction());
objp.set(ToObject(cx, &vp[1]));
objp.set(ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])));
if (!objp)
return NULL;
if (!objp->isXML()) {
@ -5406,7 +5410,7 @@ StartNonListXMLMethod(JSContext *cx, jsval *vp, MutableHandleObject objp)
/* Beware: these two are not bracketed by JS_BEGIN/END_MACRO. */
#define XML_METHOD_PROLOG \
JSObject *obj = ToObject(cx, &vp[1]); \
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])); \
if (!obj) \
return JS_FALSE; \
if (!obj->isXML()) { \
@ -5490,7 +5494,8 @@ xml_attribute(JSContext *cx, unsigned argc, jsval *vp)
JSObject *qn;
if (argc == 0) {
js_ReportMissingArg(cx, *vp, 0);
RootedValue val(cx, *vp);
js_ReportMissingArg(cx, val, 0);
return JS_FALSE;
}
@ -5500,7 +5505,7 @@ xml_attribute(JSContext *cx, unsigned argc, jsval *vp)
vp[2] = OBJECT_TO_JSVAL(qn); /* local root */
RootedId id(cx, OBJECT_TO_JSID(qn));
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])));
if (!obj)
return JS_FALSE;
return GetProperty(cx, obj, id, MutableHandleValue::fromMarkedLocation(vp));
@ -5516,7 +5521,7 @@ xml_attributes(JSContext *cx, unsigned argc, jsval *vp)
return JS_FALSE;
RootedId id(cx, OBJECT_TO_JSID(qn));
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])));
if (!obj)
return JS_FALSE;
return GetProperty(cx, obj, id, MutableHandleValue::fromMarkedLocation(vp));
@ -5676,7 +5681,7 @@ xml_childIndex(JSContext *cx, unsigned argc, jsval *vp)
static JSBool
xml_children(JSContext *cx, unsigned argc, jsval *vp)
{
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])));
if (!obj)
return false;
RootedId name(cx, NameToId(cx->runtime->atomState.starAtom));
@ -5883,7 +5888,7 @@ xml_hasOwnProperty(JSContext *cx, unsigned argc, jsval *vp)
jsval name;
JSBool found;
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1]));
if (!obj)
return JS_FALSE;
if (!obj->isXML()) {
@ -6925,7 +6930,7 @@ xml_toString_helper(JSContext *cx, JSXML *xml)
static JSBool
xml_toSource(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1]));
if (!obj)
return JS_FALSE;
JSString *str = ToXMLString(cx, OBJECT_TO_JSVAL(obj), TO_SOURCE_FLAG);
@ -6952,7 +6957,7 @@ xml_toString(JSContext *cx, unsigned argc, jsval *vp)
static JSBool
xml_toXMLString(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1]));
if (!obj)
return JS_FALSE;
JSString *str = ToXMLString(cx, OBJECT_TO_JSVAL(obj), 0);
@ -6966,7 +6971,7 @@ xml_toXMLString(JSContext *cx, unsigned argc, jsval *vp)
static JSBool
xml_valueOf(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1]));
if (!obj)
return false;
*vp = OBJECT_TO_JSVAL(obj);
@ -7066,7 +7071,7 @@ xml_settings(JSContext *cx, unsigned argc, jsval *vp)
if (!settings)
return false;
*vp = OBJECT_TO_JSVAL(settings);
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])));
if (!obj)
return false;
return CopyXMLSettings(cx, obj, settings);
@ -7078,7 +7083,7 @@ xml_setSettings(JSContext *cx, unsigned argc, jsval *vp)
jsval v;
JSBool ok;
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])));
if (!obj)
return JS_FALSE;
v = (argc == 0) ? JSVAL_VOID : vp[2];
@ -7882,7 +7887,8 @@ js_StepXMLListFilter(JSContext *cx, JSBool initialized)
* value stored in sp[-2].
*/
if (!VALUE_IS_XML(sp[-2])) {
js_ReportValueError(cx, JSMSG_NON_XML_FILTER, -2, sp[-2], NULL);
RootedValue val(cx, sp[-2]);
js_ReportValueError(cx, JSMSG_NON_XML_FILTER, -2, val, NullPtr());
return JS_FALSE;
}
obj = JSVAL_TO_OBJECT(sp[-2]);

Просмотреть файл

@ -1005,7 +1005,8 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
* portion of fun_hasInstance.
*/
if (f.regs.sp[0].isPrimitive()) {
js_ReportValueError(cx, JSMSG_BAD_PROTOTYPE, -1, f.regs.sp[-1], NULL);
RootedValue val(cx, f.regs.sp[-1]);
js_ReportValueError(cx, JSMSG_BAD_PROTOTYPE, -1, val, NullPtr());
return js_InternalThrow(f);
}
nextsp[-1].setBoolean(js_IsDelegate(cx, &f.regs.sp[0].toObject(), f.regs.sp[-2]));

Просмотреть файл

@ -771,7 +771,7 @@ class CallCompiler : public BaseCompiler
return false;
if (callingNew)
args.thisv().setMagic(JS_IS_CONSTRUCTING);
args.setThis(MagicValue(JS_IS_CONSTRUCTING));
RecompilationMonitor monitor(cx);

Просмотреть файл

@ -1948,6 +1948,8 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
}
}
RootedValue objval(f.cx, f.regs.sp[-1]);
if (f.regs.sp[-1].isString()) {
GetPropCompiler cc(f, NULL, *pic, name, stub);
if (name == f.cx->runtime->atomState.lengthAtom) {
@ -1960,7 +1962,7 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
LookupStatus status = cc.generateStringPropertyStub();
if (status == Lookup_Error)
THROW();
JSObject *obj = ValueToObject(f.cx, f.regs.sp[-1]);
JSObject *obj = ToObjectFromStack(f.cx, objval);
if (!obj)
THROW();
if (!obj->getProperty(f.cx, name, MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1])))
@ -1971,7 +1973,7 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
RecompilationMonitor monitor(f.cx);
RootedObject obj(f.cx, ValueToObject(f.cx, f.regs.sp[-1]));
RootedObject obj(f.cx, ToObjectFromStack(f.cx, objval));
if (!obj)
THROW();
@ -1983,7 +1985,7 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
RootedValue v(f.cx);
if (cached) {
if (!GetPropertyOperation(f.cx, f.script(), f.pc(), f.regs.sp[-1], v.address()))
if (!GetPropertyOperation(f.cx, f.pc(), &objval, &v))
THROW();
} else {
if (!obj->getProperty(f.cx, name, &v))
@ -2013,7 +2015,8 @@ ic::SetProp(VMFrame &f, ic::PICInfo *pic)
RecompilationMonitor monitor(f.cx);
JSObject *obj = ValueToObject(f.cx, f.regs.sp[-2]);
RootedValue objval(f.cx, f.regs.sp[-2]);
JSObject *obj = ToObjectFromStack(f.cx, objval);
if (!obj)
THROW();
@ -2550,12 +2553,12 @@ ic::GetElement(VMFrame &f, ic::GetElementIC *ic)
return;
}
RootedValue idval_(cx, f.regs.sp[-1]);
Value &idval = idval_.get();
RootedValue idval(cx, f.regs.sp[-1]);
RecompilationMonitor monitor(cx);
RootedObject obj(cx, ValueToObject(cx, f.regs.sp[-2]));
RootedValue objval(f.cx, f.regs.sp[-2]);
RootedObject obj(cx, ToObjectFromStack(cx, objval));
if (!obj)
THROW();
@ -2583,7 +2586,7 @@ ic::GetElement(VMFrame &f, ic::GetElementIC *ic)
#ifdef DEBUG
f.regs.sp[-2] = MagicValue(JS_GENERIC_MAGIC);
#endif
LookupStatus status = ic->update(f, obj, idval_, id, res);
LookupStatus status = ic->update(f, obj, idval, id, res);
if (status != Lookup_Uncacheable && status != Lookup_NoProperty) {
if (status == Lookup_Error)
THROW();

Просмотреть файл

@ -72,8 +72,8 @@ void JS_FASTCALL
stubs::SetName(VMFrame &f, PropertyName *name)
{
JSContext *cx = f.cx;
const Value &rval = f.regs.sp[-1];
const Value &lval = f.regs.sp[-2];
HandleValue rval = HandleValue::fromMarkedLocation(&f.regs.sp[-1]);
HandleValue lval = HandleValue::fromMarkedLocation(&f.regs.sp[-2]);
if (!SetPropertyOperation(cx, f.pc(), lval, rval))
THROW();
@ -106,11 +106,11 @@ stubs::Name(VMFrame &f)
void JS_FASTCALL
stubs::GetElem(VMFrame &f)
{
Value &lref = f.regs.sp[-2];
Value &rref = f.regs.sp[-1];
MutableHandleValue lval = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-2]);
HandleValue rval = HandleValue::fromMarkedLocation(&f.regs.sp[-1]);
MutableHandleValue res = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-2]);
if (!GetElementOperation(f.cx, JSOp(*f.pc()), lref, rref, res))
if (!GetElementOperation(f.cx, JSOp(*f.pc()), lval, rval, res))
THROW();
}
@ -121,13 +121,13 @@ stubs::SetElem(VMFrame &f)
JSContext *cx = f.cx;
FrameRegs &regs = f.regs;
Value &objval = regs.sp[-3];
HandleValue objval = HandleValue::fromMarkedLocation(&regs.sp[-3]);
Value &idval = regs.sp[-2];
RootedValue rval(cx, regs.sp[-1]);
RootedId id(cx);
Rooted<JSObject*> obj(cx, ValueToObject(cx, objval));
Rooted<JSObject*> obj(cx, ToObjectFromStack(cx, objval));
if (!obj)
THROW();
@ -174,10 +174,10 @@ template void JS_FASTCALL stubs::SetElem<false>(VMFrame &f);
void JS_FASTCALL
stubs::ToId(VMFrame &f)
{
Value &objval = f.regs.sp[-2];
HandleValue objval = HandleValue::fromMarkedLocation(&f.regs.sp[-2]);
MutableHandleValue idval = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1]);
JSObject *obj = ValueToObject(f.cx, objval);
JSObject *obj = ToObjectFromStack(f.cx, objval);
if (!obj)
THROW();
@ -983,8 +983,10 @@ stubs::GetProp(VMFrame &f, PropertyName *name)
JSContext *cx = f.cx;
FrameRegs &regs = f.regs;
MutableHandleValue objval = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1]);
RootedValue rval(cx);
if (!GetPropertyOperation(cx, f.script(), f.pc(), f.regs.sp[-1], rval.address()))
if (!GetPropertyOperation(cx, f.pc(), objval, &rval))
THROW();
regs.sp[-1] = rval;
@ -1142,10 +1144,10 @@ stubs::InstanceOf(VMFrame &f)
JSContext *cx = f.cx;
FrameRegs &regs = f.regs;
const Value &rref = regs.sp[-1];
RootedValue rref(cx, regs.sp[-1]);
if (rref.isPrimitive()) {
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
-1, rref, NULL);
-1, rref, NullPtr());
THROWV(JS_FALSE);
}
RootedObject obj(cx, &rref.toObject());
@ -1167,7 +1169,8 @@ stubs::FastInstanceOf(VMFrame &f)
* Throw a runtime error if instanceof is called on a function that
* has a non-object as its .prototype value.
*/
js_ReportValueError(f.cx, JSMSG_BAD_PROTOTYPE, -1, f.regs.sp[-2], NULL);
RootedValue val(f.cx, f.regs.sp[-2]);
js_ReportValueError(f.cx, JSMSG_BAD_PROTOTYPE, -1, val, NullPtr());
THROW();
}
@ -1365,7 +1368,8 @@ stubs::DelProp(VMFrame &f, PropertyName *name_)
JSContext *cx = f.cx;
RootedPropertyName name(cx, name_);
JSObject *obj = ValueToObject(cx, f.regs.sp[-1]);
RootedValue objval(cx, f.regs.sp[-1]);
JSObject *obj = ToObjectFromStack(cx, objval);
if (!obj)
THROW();
@ -1385,7 +1389,8 @@ stubs::DelElem(VMFrame &f)
{
JSContext *cx = f.cx;
JSObject *obj = ValueToObject(cx, f.regs.sp[-2]);
RootedValue objval(cx, f.regs.sp[-2]);
JSObject *obj = ToObjectFromStack(cx, objval);
if (!obj)
THROW();
@ -1434,7 +1439,8 @@ stubs::In(VMFrame &f)
const Value &rref = f.regs.sp[-1];
if (!rref.isObject()) {
js_ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, rref, NULL);
RootedValue val(cx, rref);
js_ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, val, NullPtr());
THROWV(JS_FALSE);
}

Просмотреть файл

@ -2534,9 +2534,9 @@ NewSandbox(JSContext *cx, bool lazy)
static JSBool
EvalInContext(JSContext *cx, unsigned argc, jsval *vp)
{
JSString *str;
RootedString str(cx);
RootedObject sobj(cx);
if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S / o", &str, sobj.address()))
if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S / o", str.address(), sobj.address()))
return false;
size_t srclen;

Просмотреть файл

@ -105,8 +105,9 @@ ValueToIdentifier(JSContext *cx, const Value &v, jsid *idp)
if (!ValueToId(cx, v, &id))
return false;
if (!JSID_IS_ATOM(id) || !IsIdentifier(JSID_TO_ATOM(id))) {
RootedValue val(cx, v);
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
JSDVG_SEARCH_STACK, v, NULL, "not an identifier", NULL);
JSDVG_SEARCH_STACK, val, NullPtr(), "not an identifier", NULL);
return false;
}
*idp = id;
@ -1472,7 +1473,6 @@ Debugger::sweepAll(FreeOp *fop)
for (GlobalObjectSet::Enum e(dbg->debuggees); !e.empty(); e.popFront())
dbg->removeDebuggeeGlobal(fop, e.front(), NULL, &e);
}
}
for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); c++) {
@ -1971,12 +1971,18 @@ Debugger::removeDebuggeeGlobal(FreeOp *fop, GlobalObject *global,
* for sure, and possibly the compartment's debuggee set.
*/
v->erase(p);
if (v->empty())
global->compartment()->removeDebuggee(fop, global, compartmentEnum);
if (debugEnum)
debugEnum->removeFront();
else
debuggees.remove(global);
/*
* The debuggee needs to be removed from the compartment last, as this can
* trigger GCs if the compartment's debug mode is being changed, and the
* global cannot be rooted on the stack without a cx.
*/
if (v->empty())
global->compartment()->removeDebuggee(fop, global, compartmentEnum);
}
/*
@ -3171,7 +3177,7 @@ DebuggerArguments_getArg(JSContext *cx, unsigned argc, Value *vp)
* Put the Debugger.Frame into the this-value slot, then use THIS_FRAME
* to check that it is still live and get the fp.
*/
args.thisv() = argsobj->getReservedSlot(JSSLOT_DEBUGARGUMENTS_FRAME);
args.setThis(argsobj->getReservedSlot(JSSLOT_DEBUGARGUMENTS_FRAME));
THIS_FRAME(cx, argc, vp, "get argument", ca2, thisobj, fp);
/*
@ -3907,7 +3913,9 @@ DebuggerObject_defineProperties(JSContext *cx, unsigned argc, Value *vp)
{
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "defineProperties", args, dbg, obj);
REQUIRE_ARGC("Debugger.Object.defineProperties", 1);
RootedObject props(cx, ToObject(cx, &args[0]));
RootedValue arg(cx, args[0]);
RootedObject props(cx, ToObject(cx, arg));
if (!props)
return false;

Просмотреть файл

@ -418,10 +418,11 @@ DenseElementsHeader::defineElement(JSContext *cx, Handle<ObjectImpl*> obj, uint3
*succeeded = false;
if (!shouldThrow)
return true;
RootedValue val(cx, ObjectValue(*obj));
MOZ_ALWAYS_FALSE(js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_OBJECT_NOT_EXTENSIBLE,
JSDVG_IGNORE_STACK,
ObjectValue(*obj),
NULL, NULL, NULL));
val, NullPtr(),
NULL, NULL));
return false;
}
@ -466,10 +467,11 @@ TypedElementsHeader<T>::defineElement(JSContext *cx, Handle<ObjectImpl*> obj,
{
/* XXX jwalden This probably isn't how typed arrays should behave... */
*succeeded = false;
RootedValue val(cx, ObjectValue(*obj));
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_OBJECT_NOT_EXTENSIBLE,
JSDVG_IGNORE_STACK,
ObjectValue(*obj),
NULL, NULL, NULL);
val, NullPtr(), NULL, NULL);
return false;
}
@ -629,8 +631,8 @@ js::GetElement(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> recei
return false;
/* Push get, receiver, and no args. */
args.calleev() = get;
args.thisv() = ObjectValue(*current);
args.setCallee(get);
args.setThis(ObjectValue(*current));
bool ok = Invoke(cx, args);
*vp = args.rval();
@ -861,8 +863,8 @@ js::SetElement(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> recei
return false;
/* Push set, receiver, and v as the sole argument. */
args.calleev() = setter;
args.thisv() = ObjectValue(*current);
args.setCallee(setter);
args.setThis(ObjectValue(*current));
args[0] = v;
*succeeded = true;

Просмотреть файл

@ -1369,8 +1369,9 @@ class DebugScopeProxy : public BaseProxyHandler
bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp) MOZ_OVERRIDE
{
RootedValue val(cx, IdToValue(id));
return js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_CANT_DELETE,
JSDVG_IGNORE_STACK, IdToValue(id), NULL,
JSDVG_IGNORE_STACK, val, NullPtr(),
NULL, NULL);
}

Просмотреть файл

@ -3109,7 +3109,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
// check to see if we can reuse a mask image
const MaskLayerImageCache::MaskLayerImageKey* key =
new MaskLayerImageCache::MaskLayerImageKey(roundedRects);
new MaskLayerImageCache::MaskLayerImageKey(roundedRects, aLayer->Manager()->GetBackendType());
const MaskLayerImageCache::MaskLayerImageKey* lookupKey = key;
nsRefPtr<ImageContainer> container =

Просмотреть файл

@ -113,8 +113,9 @@ public:
class MaskLayerImageKey
{
public:
MaskLayerImageKey(const nsTArray<PixelRoundedRect>& aRoundedClipRects)
: mLayerCount(0)
MaskLayerImageKey(const nsTArray<PixelRoundedRect>& aRoundedClipRects, layers::LayersBackend aBackend)
: mBackend(aBackend)
, mLayerCount(0)
, mRoundedClipRects(aRoundedClipRects)
{}
@ -132,6 +133,7 @@ public:
for (PRUint32 i = 0; i < mRoundedClipRects.Length(); ++i) {
hash = AddToHash(hash, mRoundedClipRects[i].Hash());
}
hash = AddToHash(hash, mBackend);
return hash;
}
@ -141,6 +143,7 @@ public:
return mRoundedClipRects == aOther.mRoundedClipRects;
}
layers::LayersBackend mBackend;
mutable PRUint32 mLayerCount;
nsTArray<PixelRoundedRect> mRoundedClipRects;
};

Просмотреть файл

@ -7976,6 +7976,31 @@ nsCSSFrameConstructor::CharacterDataChanged(nsIContent* aContent,
NS_DECLARE_FRAME_PROPERTY(ChangeListProperty, nullptr)
/**
* Return true if aFrame's subtree has placeholders for abs-pos or fixed-pos
* content.
*/
static bool
FrameHasAbsPosPlaceholderDescendants(nsIFrame* aFrame)
{
const nsIFrame::ChildListIDs skip(nsIFrame::kAbsoluteList |
nsIFrame::kFixedList);
for (nsIFrame::ChildListIterator lists(aFrame); !lists.IsDone(); lists.Next()) {
if (!skip.Contains(lists.CurrentID())) {
for (nsFrameList::Enumerator childFrames(lists.CurrentList());
!childFrames.AtEnd(); childFrames.Next()) {
nsIFrame* f = childFrames.get();
if ((f->GetType() == nsGkAtoms::placeholderFrame &&
nsPlaceholderFrame::GetRealFrameForPlaceholder(f)->IsAbsolutelyPositioned()) ||
FrameHasAbsPosPlaceholderDescendants(f)) {
return true;
}
}
}
}
return false;
}
nsresult
nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
{
@ -8036,6 +8061,20 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
continue;
}
if ((hint & nsChangeHint_AddOrRemoveTransform) && frame &&
!(hint & nsChangeHint_ReconstructFrame)) {
if (FrameHasAbsPosPlaceholderDescendants(frame)) {
NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
} else {
// We can just add this state bit unconditionally, since it's
// conservative. Normally frame construction would set this if needed,
// but we're not going to reconstruct the frame so we need to set it.
// It's because we need to set this bit on each affected frame
// that we can't coalesce nsChangeHint_AddOrRemoveTransform hints up
// to ancestors (i.e. it can't be an inherited change hint).
frame->AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
}
}
if (hint & nsChangeHint_ReconstructFrame) {
// If we ever start passing true here, be careful of restyles
// that involve a reframe and animations. In particular, if the

Просмотреть файл

@ -101,6 +101,14 @@ enum nsChangeHint {
*/
nsChangeHint_RecomputePosition = 0x2000,
/**
* Behaves like ReconstructFrame, but only if the frame has descendants
* that are absolutely or fixed position. Use this hint when a style change
* has changed whether the frame is a container for fixed-pos or abs-pos
* elements, but reframing is otherwise not needed.
*/
nsChangeHint_AddOrRemoveTransform = 0x4000,
/**
* We have an optimization when processing change hints which prevents
* us from visiting the descendants of a node when a hint on that node
@ -116,7 +124,8 @@ enum nsChangeHint {
nsChangeHint_UpdateOpacityLayer |
nsChangeHint_UpdateOverflow |
nsChangeHint_ChildrenOnlyTransform |
nsChangeHint_RecomputePosition
nsChangeHint_RecomputePosition |
nsChangeHint_AddOrRemoveTransform
};
// Redefine these operators to return nothing. This will catch any use

Просмотреть файл

@ -1037,7 +1037,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
layerBuilder->WillEndTransaction(layerManager);
bool temp = aBuilder->SetIsCompositingCheap(layerManager->IsCompositingCheap());
layerManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer,
aBuilder);
aBuilder, (aFlags & PAINT_NO_COMPOSITE) ? LayerManager::END_NO_COMPOSITE : LayerManager::END_DEFAULT);
aBuilder->SetIsCompositingCheap(temp);
layerBuilder->DidEndTransaction(layerManager);

Просмотреть файл

@ -24,6 +24,7 @@
#include "FrameLayerBuilder.h"
#include "nsThemeConstants.h"
#include "ImageLayers.h"
#include "nsLayoutUtils.h"
#include "mozilla/StandardInteger.h"
@ -1177,7 +1178,8 @@ public:
PAINT_DEFAULT = 0,
PAINT_USE_WIDGET_LAYERS = 0x01,
PAINT_FLUSH_LAYERS = 0x02,
PAINT_EXISTING_TRANSACTION = 0x04
PAINT_EXISTING_TRANSACTION = 0x04,
PAINT_NO_COMPOSITE = 0x08
};
void PaintRoot(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
PRUint32 aFlags) const;

Просмотреть файл

@ -1217,9 +1217,13 @@ public:
*/
virtual void SynthesizeMouseMove(bool aFromScroll) = 0;
virtual void Paint(nsIView* aViewToPaint, nsIWidget* aWidget,
const nsRegion& aDirtyRegion, const nsIntRegion& aIntDirtyRegion,
bool aWillSendDidPaint) = 0;
enum PaintType {
PaintType_Composite, /* Just composite the layers, don't do ThebesLayer painting. */
PaintType_NoComposite, /* Only paint ThebesLayers, don't composite. */
PaintType_Full /* Do a full transaction. */
};
virtual void Paint(nsIView* aViewToPaint, const nsRegion& aDirtyRegion,
PaintType aType, bool aWillSendDidPaint) = 0;
virtual nsresult HandleEvent(nsIFrame* aFrame,
nsGUIEvent* aEvent,
bool aDontRetargetEvents,

Просмотреть файл

@ -1861,6 +1861,9 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
if (aFlags & PAINT_EXISTING_TRANSACTION) {
flags |= nsDisplayList::PAINT_EXISTING_TRANSACTION;
}
if (aFlags & PAINT_NO_COMPOSITE) {
flags |= nsDisplayList::PAINT_NO_COMPOSITE;
}
list.PaintRoot(&builder, aRenderingContext, flags);

Просмотреть файл

@ -598,7 +598,8 @@ public:
PAINT_HIDE_CARET = 0x20,
PAINT_ALL_CONTINUATIONS = 0x40,
PAINT_TO_WINDOW = 0x80,
PAINT_EXISTING_TRANSACTION = 0x100
PAINT_EXISTING_TRANSACTION = 0x100,
PAINT_NO_COMPOSITE = 0x200
};
/**

Просмотреть файл

@ -5249,9 +5249,8 @@ private:
void
PresShell::Paint(nsIView* aViewToPaint,
nsIWidget* aWidgetToPaint,
const nsRegion& aDirtyRegion,
const nsIntRegion& aIntDirtyRegion,
PaintType aType,
bool aWillSendDidPaint)
{
#ifdef NS_FUNCTION_TIMER
@ -5268,7 +5267,6 @@ PresShell::Paint(nsIView* aViewToPaint,
SAMPLE_LABEL("Paint", "PresShell::Paint");
NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
NS_ASSERTION(aViewToPaint, "null view");
NS_ASSERTION(aWidgetToPaint, "Can't paint without a widget");
nsAutoNotifyDidPaint notifyDidPaint(aWillSendDidPaint);
@ -5279,14 +5277,13 @@ PresShell::Paint(nsIView* aViewToPaint,
bool isRetainingManager;
LayerManager* layerManager =
aWidgetToPaint->GetLayerManager(&isRetainingManager);
aViewToPaint->GetWidget()->GetLayerManager(&isRetainingManager);
NS_ASSERTION(layerManager, "Must be in paint event");
if (mIsFirstPaint) {
layerManager->SetIsFirstPaint();
mIsFirstPaint = false;
}
layerManager->BeginTransaction();
if (frame && isRetainingManager) {
// Try to do an empty transaction, if the frame tree does not
@ -5295,21 +5292,39 @@ PresShell::Paint(nsIView* aViewToPaint,
// draws the window title bar on Mac), because a) it won't work
// and b) below we don't want to clear NS_FRAME_UPDATE_LAYER_TREE,
// that will cause us to forget to update the real layer manager!
if (!(frame->GetStateBits() & NS_FRAME_UPDATE_LAYER_TREE)) {
if (aType == PaintType_Composite) {
if (layerManager->HasShadowManager()) {
return;
}
layerManager->BeginTransaction();
if (layerManager->EndEmptyTransaction()) {
return;
}
NS_WARNING("Must complete empty transaction when compositing!");
} else if (!(frame->GetStateBits() & NS_FRAME_UPDATE_LAYER_TREE)) {
layerManager->BeginTransaction();
if (layerManager->EndEmptyTransaction(LayerManager::END_NO_COMPOSITE)) {
frame->UpdatePaintCountForPaintedPresShells();
presContext->NotifyDidPaintForSubtree();
return;
}
} else {
layerManager->BeginTransaction();
}
frame->RemoveStateBits(NS_FRAME_UPDATE_LAYER_TREE);
} else {
layerManager->BeginTransaction();
}
if (frame) {
frame->ClearPresShellsFromLastPaint();
}
nscolor bgcolor = ComputeBackstopColor(aViewToPaint);
PRUint32 flags = nsLayoutUtils::PAINT_WIDGET_LAYERS | nsLayoutUtils::PAINT_EXISTING_TRANSACTION;
if (aType == PaintType_NoComposite) {
flags |= nsLayoutUtils::PAINT_NO_COMPOSITE;
}
if (frame) {
// Defer invalidates that are triggered during painting, and discard
@ -5319,12 +5334,12 @@ PresShell::Paint(nsIView* aViewToPaint,
frame->BeginDeferringInvalidatesForDisplayRoot(aDirtyRegion);
// We can paint directly into the widget using its layer manager.
nsLayoutUtils::PaintFrame(nullptr, frame, aDirtyRegion, bgcolor,
nsLayoutUtils::PAINT_WIDGET_LAYERS |
nsLayoutUtils::PAINT_EXISTING_TRANSACTION);
nsLayoutUtils::PaintFrame(nullptr, frame, aDirtyRegion, bgcolor, flags);
frame->EndDeferringInvalidatesForDisplayRoot();
presContext->NotifyDidPaintForSubtree();
if (aType != PaintType_Composite) {
presContext->NotifyDidPaintForSubtree();
}
return;
}
@ -5338,9 +5353,13 @@ PresShell::Paint(nsIView* aViewToPaint,
root->SetVisibleRegion(bounds);
layerManager->SetRoot(root);
}
layerManager->EndTransaction(NULL, NULL);
layerManager->EndTransaction(NULL, NULL, aType == PaintType_NoComposite ?
LayerManager::END_NO_COMPOSITE :
LayerManager::END_DEFAULT);
presContext->NotifyDidPaintForSubtree();
if (aType != PaintType_Composite) {
presContext->NotifyDidPaintForSubtree();
}
}
// static

Просмотреть файл

@ -184,9 +184,8 @@ public:
//nsIViewObserver interface
virtual void Paint(nsIView* aViewToPaint, nsIWidget* aWidget,
const nsRegion& aDirtyRegion, const nsIntRegion& aIntDirtyRegion,
bool aWillSendDidPaint);
virtual void Paint(nsIView* aViewToPaint, const nsRegion& aDirtyRegion,
PaintType aType, bool aWillSendDidPaint);
virtual nsresult HandleEvent(nsIFrame* aFrame,
nsGUIEvent* aEvent,
bool aDontRetargetEvents,

Просмотреть файл

@ -414,8 +414,14 @@ nsRefreshDriver::Notify(nsITimer *aTimer)
}
if (mViewManagerFlushIsPending) {
#ifdef DEBUG_INVALIDATIONS
printf("Starting ProcessPendingUpdates\n");
#endif
mViewManagerFlushIsPending = false;
mPresContext->GetPresShell()->GetViewManager()->ProcessPendingUpdates();
#ifdef DEBUG_INVALIDATIONS
printf("Ending ProcessPendingUpdates\n");
#endif
}
if (mThrottled ||

Просмотреть файл

@ -1683,18 +1683,19 @@ void
nsGfxScrollFrameInner::ScrollToCSSPixels(nsIntPoint aScrollPosition)
{
nsPoint current = GetScrollPosition();
nsIntPoint currentCSSPixels = GetScrollPositionCSSPixels();
nsPoint pt(nsPresContext::CSSPixelsToAppUnits(aScrollPosition.x),
nsPresContext::CSSPixelsToAppUnits(aScrollPosition.y));
nscoord halfPixel = nsPresContext::CSSPixelsToAppUnits(0.5f);
nsRect range(pt.x - halfPixel, pt.y - halfPixel, 2*halfPixel - 1, 2*halfPixel - 1);
if (nsPresContext::AppUnitsToIntCSSPixels(current.x) == aScrollPosition.x) {
if (currentCSSPixels.x == aScrollPosition.x) {
pt.x = current.x;
range.x = pt.x;
range.width = 0;
} else {
// current.x must be outside 'range', so we must move in the correct direction.
}
if (nsPresContext::AppUnitsToIntCSSPixels(current.y) == aScrollPosition.y) {
if (currentCSSPixels.y == aScrollPosition.y) {
pt.y = current.y;
range.y = pt.y;
range.height = 0;
@ -1704,6 +1705,14 @@ nsGfxScrollFrameInner::ScrollToCSSPixels(nsIntPoint aScrollPosition)
ScrollTo(pt, nsIScrollableFrame::INSTANT, &range);
}
nsIntPoint
nsGfxScrollFrameInner::GetScrollPositionCSSPixels()
{
nsPoint pt = GetScrollPosition();
return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
nsPresContext::AppUnitsToIntCSSPixels(pt.y));
}
/*
* this method wraps calls to ScrollToImpl(), either in one shot or incrementally,
* based on the setting of the smoothness scroll pref
@ -2547,15 +2556,62 @@ nsGfxScrollFrameInner::GetLineScrollAmount() const
return nsSize(fontHeight, fontHeight);
}
/**
* Compute the scrollport size excluding any fixed-pos headers and
* footers. A header or footer is an box that spans that entire width
* of the viewport and touches the top (or bottom, respectively) of the
* viewport. Headers and footers that cover more than a quarter of the
* the viewport are ignored since they probably aren't true headers and
* footers and we don't want to restrict scrolling too much in such cases.
* This is a bit conservative --- some pages use elements as headers or
* footers that don't span the entire width of the viewport --- but it
* should be a good start.
*/
static nsSize
GetScrollPortSizeExcludingHeadersAndFooters(nsIFrame* aViewportFrame,
const nsRect& aScrollPort)
{
nsFrameList fixedFrames = aViewportFrame->GetChildList(nsIFrame::kFixedList);
nscoord headerBottom = 0;
nscoord footerTop = aScrollPort.height;
for (nsFrameList::Enumerator iterator(fixedFrames); !iterator.AtEnd();
iterator.Next()) {
nsIFrame* f = iterator.get();
nsRect r = f->GetRect().Intersect(aScrollPort);
if (r.x == 0 && r.width == aScrollPort.width &&
r.height <= aScrollPort.height/3) {
if (r.y == 0) {
headerBottom = NS_MAX(headerBottom, r.height);
}
if (r.YMost() == aScrollPort.height) {
footerTop = NS_MIN(footerTop, r.y);
}
}
}
return nsSize(aScrollPort.width, footerTop - headerBottom);
}
nsSize
nsGfxScrollFrameInner::GetPageScrollAmount() const
{
nsSize lineScrollAmount = GetLineScrollAmount();
nsSize effectiveScrollPortSize;
if (mIsRoot) {
// Reduce effective scrollport height by the height of any fixed-pos
// headers or footers
nsIFrame* root = mOuter->PresContext()->PresShell()->GetRootFrame();
effectiveScrollPortSize =
GetScrollPortSizeExcludingHeadersAndFooters(root, mScrollPort);
} else {
effectiveScrollPortSize = mScrollPort.Size();
}
// The page increment is the size of the page, minus the smaller of
// 10% of the size or 2 lines.
return nsSize(
mScrollPort.width - NS_MIN(mScrollPort.width/10, 2*lineScrollAmount.width),
mScrollPort.height - NS_MIN(mScrollPort.height/10, 2*lineScrollAmount.height));
effectiveScrollPortSize.width -
NS_MIN(effectiveScrollPortSize.width/10, 2*lineScrollAmount.width),
effectiveScrollPortSize.height -
NS_MIN(effectiveScrollPortSize.height/10, 2*lineScrollAmount.height));
}
/**

Просмотреть файл

@ -166,6 +166,7 @@ public:
ScrollToWithOrigin(aScrollPosition, aMode, nsGkAtoms::other, aRange);
}
void ScrollToCSSPixels(nsIntPoint aScrollPosition);
nsIntPoint GetScrollPositionCSSPixels();
void ScrollToImpl(nsPoint aScrollPosition, const nsRect& aRange);
void ScrollVisual(nsPoint aOldScrolledFramePosition);
void ScrollBy(nsIntPoint aDelta, nsIScrollableFrame::ScrollUnit aUnit,
@ -480,6 +481,9 @@ public:
virtual void ScrollToCSSPixels(nsIntPoint aScrollPosition) {
mInner.ScrollToCSSPixels(aScrollPosition);
}
virtual nsIntPoint GetScrollPositionCSSPixels() {
return mInner.GetScrollPositionCSSPixels();
}
virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode,
nsIntPoint* aOverflow, nsIAtom *aOrigin = nullptr) {
mInner.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin);
@ -725,6 +729,9 @@ public:
virtual void ScrollToCSSPixels(nsIntPoint aScrollPosition) {
mInner.ScrollToCSSPixels(aScrollPosition);
}
virtual nsIntPoint GetScrollPositionCSSPixels() {
return mInner.GetScrollPositionCSSPixels();
}
virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode,
nsIntPoint* aOverflow, nsIAtom *aOrigin = nullptr) {
mInner.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin);

Просмотреть файл

@ -138,6 +138,11 @@ public:
* The scroll mode is INSTANT.
*/
virtual void ScrollToCSSPixels(nsIntPoint aScrollPosition) = 0;
/**
* Returns the scroll position in integer CSS pixels, rounded to the nearest
* pixel.
*/
virtual nsIntPoint GetScrollPositionCSSPixels() = 0;
/**
* When scrolling by a relative amount, we can choose various units.
*/

Просмотреть файл

@ -65,6 +65,8 @@ MOCHITEST_FILES = \
test_invalidate_during_plugin_paint.html \
test_movement_by_characters.html \
test_movement_by_words.html \
test_page_scroll_with_fixed_pos.html \
page_scroll_with_fixed_pos_window.html \
test_plugin_clipping.xhtml \
test_plugin_clipping2.xhtml \
test_plugin_clipping_transformed.xhtml \

Просмотреть файл

@ -0,0 +1,81 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Scrolling by pages with fixed-pos headers and footers</title>
<style>
.fp { position:fixed; left:0; width:100%; }
</style>
</head>
<body onscroll="didScroll()" onload="test()">
<div class="fp" id="top" style="top:0; height:10px; background:yellow;"></div>
<div class="fp" style="top:50%; height:7px; background:cyan;"></div>
<div class="fp" id="bottom" style="bottom:0; height:13px; background:yellow;"></div>
<p id="target">Something to click on to get focus
<div style="height:3000px;"></div>
<pre id="test">
<script class="testbody">
var SimpleTest = window.opener.SimpleTest;
var SpecialPowers = window.opener.SpecialPowers;
var is = window.opener.is;
function showFixedPosElements(show) {
var elements = document.getElementsByClassName("fp");
for (var i = 0; i < elements.length; ++i) {
elements[i].style.display = show ? '' : 'none';
}
}
var nextCont;
function didScroll() {
var c = nextCont;
nextCont = null;
if (c) {
c();
}
}
function scrollDownOnePageWithContinuation(cont) {
document.documentElement.scrollTop = 0;
nextCont = cont;
window.scrollByPages(1);
}
function test() {
var smoothScrollPref = "general.smoothScroll";
SpecialPowers.setBoolPref(smoothScrollPref, false);
showFixedPosElements(false);
scrollDownOnePageWithContinuation(function() {
var fullPageScrollDown = document.documentElement.scrollTop;
showFixedPosElements(true);
scrollDownOnePageWithContinuation(function() {
var fullPageScrollDownWithHeaderAndFooter = document.documentElement.scrollTop;
is(fullPageScrollDownWithHeaderAndFooter, fullPageScrollDown - (10 + 13),
"Reduce scroll distance by size of small header and footer");
document.getElementById("bottom").style.height = (window.innerHeight - 20) + "px";
scrollDownOnePageWithContinuation(function() {
is(document.documentElement.scrollTop, fullPageScrollDown - 10,
"Ignore really big elements when reducing scroll size");
document.getElementById("bottom").style.height = "13px";
document.getElementById("top").style.width = "100px";
scrollDownOnePageWithContinuation(function() {
is(document.documentElement.scrollTop, fullPageScrollDown - 13,
"Ignore elements that don't span the entire viewport side");
// Scroll back up so test results are visible
document.documentElement.scrollTop = 0;
SpecialPowers.clearUserPref(smoothScrollPref);
SimpleTest.finish();
window.close();
});
});
});
});
}
</script>
</pre>
</body>
</html>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше