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

This commit is contained in:
Ed Morley 2012-09-12 21:50:56 +01:00
commit e37982cedb
87 changed files with 2854 additions and 791 deletions

View File

@ -440,7 +440,7 @@ pref("app.update.auto", true);
pref("app.update.silent", true);
pref("app.update.mode", 0);
pref("app.update.incompatible.mode", 0);
pref("app.update.stage.enabled", true);
pref("app.update.staging.enabled", true);
pref("app.update.service.enabled", true);
// The URL hosting the update manifest.

View File

@ -245,7 +245,7 @@ var shell = {
case 'keypress':
return;
}
// On my device, the physical hardware buttons (sleep and volume)
// send multiple events (press press release release), but the
// soft home button just sends one. This hack is to manually
@ -421,6 +421,10 @@ Services.obs.addObserver(function(aSubject, aTopic, aData) {
fullscreenorigin: aData });
}, "fullscreen-origin-change", false);
Services.obs.addObserver(function onWebappsReady(subject, topic, data) {
shell.sendChromeEvent({ type: 'webapps-registry-ready' });
}, 'webapps-registry-ready', false);
(function Repl() {
if (!Services.prefs.getBoolPref('b2g.remote-js.enabled')) {
return;

View File

@ -147,7 +147,7 @@ pref("app.update.silent", false);
// If set to true, the Update Service will apply updates in the background
// when it finishes downloading them.
pref("app.update.stage.enabled", true);
pref("app.update.staging.enabled", true);
// Update service URL:
pref("app.update.url", "https://aus3.mozilla.org/update/3/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml");

View File

@ -219,17 +219,14 @@ XPCOMUtils.defineLazyGetter(this, "PageMenu", function() {
* one listener that calls all real handlers.
*/
function pageShowEventHandlers(event) {
// Filter out events that are not about the document load we are interested in
if (event.target == content.document) {
charsetLoadListener();
XULBrowserWindow.asyncUpdateUI();
charsetLoadListener();
XULBrowserWindow.asyncUpdateUI();
// The PluginClickToPlay events are not fired when navigating using the
// BF cache. |event.persisted| is true when the page is loaded from the
// BF cache, so this code reshows the notification if necessary.
if (event.persisted)
gPluginHandler.reshowClickToPlayNotification();
}
// The PluginClickToPlay events are not fired when navigating using the
// BF cache. |event.persisted| is true when the page is loaded from the
// BF cache, so this code reshows the notification if necessary.
if (event.persisted)
gPluginHandler.reshowClickToPlayNotification();
}
function UpdateBackForwardCommands(aWebNavigation) {
@ -1273,7 +1270,11 @@ var gBrowserInit = {
SocialUI.init();
AddonManager.addAddonListener(AddonsMgrListener);
gBrowser.addEventListener("pageshow", function(evt) { setTimeout(pageShowEventHandlers, 0, evt); }, true);
gBrowser.addEventListener("pageshow", function(event) {
// Filter out events that are not about the document load we are interested in
if (event.target == content.document)
setTimeout(pageShowEventHandlers, 0, event);
}, true);
// Ensure login manager is up and running.
Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);

View File

@ -396,7 +396,7 @@ user_pref("network.http.prompt-temp-redirect", false);
user_pref("media.cache_size", 100);
user_pref("security.warn_viewing_mixed", false);
user_pref("app.update.enabled", false);
user_pref("app.update.stage.enabled", false);
user_pref("app.update.staging.enabled", false);
user_pref("browser.panorama.experienced_first_run", true); // Assume experienced
user_pref("dom.w3c_touch_events.enabled", true);
user_pref("toolkit.telemetry.prompted", 2);

View File

@ -160,6 +160,22 @@ void nsOggReader::BuildSerialList(nsTArray<uint32_t>& aTracks)
}
}
static bool IsValidVorbisTagName(nsCString& name)
{
// Tag names must consist of ASCII 0x20 through 0x7D,
// excluding 0x3D '=' which is the separator.
uint32_t length = name.Length();
const char *data = name.Data();
for (uint32_t i = 0; i < length; i++) {
if (data[i] < 0x20 || data[i] > 0x7D || data[i] == '=') {
return false;
}
}
return true;
}
static
nsHTMLMediaElement::MetadataTags* TagsFromVorbisComment(vorbis_comment *vc)
{
@ -172,14 +188,20 @@ nsHTMLMediaElement::MetadataTags* TagsFromVorbisComment(vorbis_comment *vc)
char *comment = vc->user_comments[i];
char *div = (char*)memchr(comment, '=', vc->comment_lengths[i]);
if (!div) {
LOG(PR_LOG_DEBUG, ("Invalid vorbis comment: no separator"));
LOG(PR_LOG_DEBUG, ("Skipping vorbis comment: no separator"));
continue;
}
// This should be ASCII.
nsCString key = nsCString(comment, div-comment);
if (!IsValidVorbisTagName(key)) {
LOG(PR_LOG_DEBUG, ("Skipping vorbis comment: invalid tag name"));
continue;
}
uint32_t value_length = vc->comment_lengths[i] - (div-comment);
// This should be utf-8.
nsCString value = nsCString(div + 1, value_length);
if (!IsUTF8(value)) {
LOG(PR_LOG_DEBUG, ("Skipping vorbis comment: invalid UTF-8 in value"));
continue;
}
tags->Put(key, value);
}

View File

@ -168,6 +168,7 @@ MOCHITEST_FILES += \
448636.ogv \
audio-overhang.ogg \
audio-gaps.ogg \
badtags.ogg \
beta-phrasebook.ogg \
bogus.ogv \
bug495129.ogv \

Binary file not shown.

View File

@ -346,7 +346,22 @@ var gMetadataTests = [
COMMENTS:"Audio Description"
}
},
{ name:"sound.ogg", tags: { } }
{ name:"sound.ogg", tags: { } },
{ name:"badtags.ogg", tags: {
// We list only the valid tags here, and verify
// the invalid ones are filtered out.
title:"Invalid comments test file",
empty:"",
"":"empty",
"{- [(`!@\"#$%^&')] -}":"valid tag name, surprisingly"
// The file also includes the following invalid tags.
// "A description with no separator is a common problem.",
// "雨":"Likely, but an invalid key (non-ascii).",
// "not\nval\x1fid":"invalid tag name",
// "not~valid":"this isn't a valid name either",
// "not-utf-8":"invalid sequences: \xff\xfe\xfa\xfb\0eol"
}
}
];
function checkMetadata(msg, e, test) {

View File

@ -28,7 +28,7 @@ function startTest(test, token) {
var m = a.mozGetMetadata();
} catch (e) {
is(e.name, 'InvalidStateError',
"early mozGetMetadata() threw incorrect exception");
"early mozGetMetadata() should throw InvalidStateError");
exception_fired = true;
}
ok(exception_fired,
@ -38,7 +38,7 @@ function startTest(test, token) {
a.addEventListener('loadedmetadata', function() {
// read decoded tags
tags = a.mozGetMetadata();
ok(tags, "mozGetMetadata() failed");
ok(tags, "mozGetMetadata() should return a truthy value");
// Dump them out.
var d = document.getElementById('output');
var html = '<table>\n';
@ -61,11 +61,11 @@ function startTest(test, token) {
d.appendChild(div);
// Verify decoded tag values.
for (tag in tags) {
is(tags[tag], test.tags[tag], "Tag '"+tag+"' doesn't match");
is(tags[tag], test.tags[tag], "Tag '"+tag+"' should match");
}
// Verify expected tag values
for (tag in test.tags) {
is(tags[tag], test.tags[tag], "Tag '"+tag+"' doesn't match");
is(tags[tag], test.tags[tag], "Tag '"+tag+"' should match");
}
manager.finished(token);
}, false);

View File

@ -77,6 +77,8 @@ let DOMApplicationRegistry = {
dirList.push("coreAppsDir");
#endif
let currentId = 1;
this.dirsToLoad = dirList.length;
this.dirsLoaded = 0;
dirList.forEach((function(dir) {
let curFile;
try {
@ -91,13 +93,16 @@ let DOMApplicationRegistry = {
if (!aData) {
return;
}
#ifdef MOZ_SYS_MSG
let ids = [];
#endif
// Add new apps to the merged list.
for (let id in aData) {
this.webapps[id] = aData[id];
this.webapps[id].basePath = appDir.path;
this.webapps[id].removable = (dir == DIRECTORY_NAME);
#ifdef MOZ_SYS_MSG
this._processManifestForId(id);
ids.push({ id: id });
#endif
// local ids must be stable between restarts.
// We partition the ids in two buckets:
@ -114,7 +119,13 @@ let DOMApplicationRegistry = {
this.webapps[id].appStatus = Ci.nsIPrincipal.APP_STATUS_INSTALLED;
}
};
#ifdef MOZ_SYS_MSG
this._processManifestForIds(ids);
#endif
}).bind(this));
} else {
// The directory we're trying to load from doesn't exist.
this.dirsToLoad--;
}
}).bind(this));
},
@ -175,13 +186,19 @@ let DOMApplicationRegistry = {
}
},
_processManifestForId: function(aId) {
let app = this.webapps[aId];
this._readManifests([{ id: aId }], (function registerManifest(aResult) {
let manifest = aResult[0].manifest;
app.name = manifest.name;
this._registerSystemMessages(manifest, app);
this._registerActivities(manifest, app);
_processManifestForIds: function(aIds) {
this._readManifests(aIds, (function registerManifests(aResults) {
aResults.forEach(function registerManifest(aResult) {
let app = this.webapps[aResult.id];
let manifest = aResult.manifest;
app.name = manifest.name;
this._registerSystemMessages(manifest, app);
this._registerActivities(manifest, app);
}, this);
this.dirsLoaded++;
if (this.dirsLoaded == this.dirsToLoad) {
Services.obs.notifyObservers(this, "webapps-registry-ready", null);
}
}).bind(this));
},
#endif

View File

@ -16,6 +16,8 @@ namespace BluetoothServiceUuid {
static unsigned long long AudioSource = 0x0000110A00000000;
static unsigned long long AdvAudioDist = 0x0000110D00000000;
static unsigned long long Headset = 0x0000110800000000;
static unsigned long long HeadsetAG = 0x0000111200000000;
static unsigned long long Handsfree = 0x0000111E00000000;
static unsigned long long HandsfreeAG = 0x0000111F00000000;
static unsigned long long BaseMSB = 0x0000000000001000;
@ -27,6 +29,7 @@ namespace BluetoothServiceUuidStr {
static const char* AudioSource = "0000110A-0000-1000-8000-00805F9B34FB";
static const char* AdvAudioDist = "0000110D-0000-1000-8000-00805F9B34FB";
static const char* Headset = "00001108-0000-1000-8000-00805F9B34FB";
static const char* HeadsetAG = "00001112-0000-1000-8000-00805F9B34FB";
static const char* Handsfree = "0000111E-0000-1000-8000-00805F9B34FB";
static const char* HandsfreeAG = "0000111F-0000-1000-8000-00805F9B34FB";
}

View File

@ -159,14 +159,15 @@ nsresult
BluetoothGonkService::StopInternal()
{
NS_ASSERTION(!NS_IsMainThread(), "This should not run on the main thread!");
nsresult ret;
ret = StartStopGonkBluetooth(false);
ret = BluetoothDBusService::StopInternal();
if (NS_FAILED(ret)) {
return ret;
}
return BluetoothDBusService::StopInternal();
return StartStopGonkBluetooth(false);
}

View File

@ -18,6 +18,7 @@
#include "base/basictypes.h"
#include "BluetoothDBusService.h"
#include "BluetoothServiceUuid.h"
#include "BluetoothTypes.h"
#include "BluetoothReplyRunnable.h"
@ -140,6 +141,8 @@ static const char* sBluetoothDBusSignals[] =
static nsAutoPtr<RawDBusConnection> gThreadConnection;
static nsDataHashtable<nsStringHashKey, DBusMessage* > sPairingReqTable;
static nsDataHashtable<nsStringHashKey, DBusMessage* > sAuthorizeReqTable;
static nsString sDefaultAdapterPath;
static nsTArray<uint32_t> sServiceHandles;
typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
@ -554,6 +557,28 @@ RegisterAgent(const nsAString& aAdapterPath)
return true;
}
static void
AddReservedServices(const nsAString& aAdapterPath)
{
MOZ_ASSERT(!NS_IsMainThread());
nsTArray<uint32_t> uuids;
uuids.AppendElement((uint32_t)(BluetoothServiceUuid::HandsfreeAG >> 32));
uuids.AppendElement((uint32_t)(BluetoothServiceUuid::HeadsetAG >> 32));
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
NS_WARNING("BluetoothService not available!");
return ;
}
sServiceHandles.Clear();
bs->AddReservedServicesInternal(aAdapterPath, uuids, sServiceHandles);
}
void
RunDBusCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable,
UnpackFunc aFunc)
@ -942,7 +967,8 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, aMsg);
errorStr.AssignLiteral("Cannot parse manager path!");
} else {
v = NS_ConvertUTF8toUTF16(str);
sDefaultAdapterPath = NS_ConvertUTF8toUTF16(str);
v = sDefaultAdapterPath;
}
} else if (dbus_message_is_signal(aMsg, DBUS_MANAGER_IFACE, "PropertyChanged")) {
ParsePropertyChange(aMsg,
@ -1052,6 +1078,8 @@ BluetoothDBusService::StopInternal()
return NS_OK;
}
RemoveReservedServicesInternal(sDefaultAdapterPath, sServiceHandles);
DBusError err;
dbus_error_init(&err);
for (uint32_t i = 0; i < ArrayLength(sBluetoothDBusSignals); ++i) {
@ -1148,6 +1176,7 @@ public:
path));
RegisterAgent(path);
AddReservedServices(path);
DispatchBluetoothReply(mRunnable, v, replyError);

View File

@ -43,6 +43,9 @@ namespace layers {
// affects CrossProcessCompositorParent below.
static CompositorParent* sCurrentCompositor;
static Thread* sCompositorThread = nullptr;
// manual reference count of the compositor thread.
static int sCompositorThreadRefCount = 0;
static MessageLoop* sMainLoop = nullptr;
// When ContentParent::StartUp() is called, we use the Thread global.
// When StartUpWithExistingThread() is used, we have to use the two
// duplicated globals, because there's no API to make a Thread from an
@ -74,6 +77,30 @@ struct PanZoomUserData : public LayerUserData {
*/
static const LayerTreeState* GetIndirectShadowTree(uint64_t aId);
static void DeferredDeleteCompositorParent(CompositorParent* aNowReadyToDie)
{
aNowReadyToDie->Release();
}
static void DeleteCompositorThread()
{
if (NS_IsMainThread()){
delete sCompositorThread;
sCompositorThread = nullptr;
sCompositorLoop = nullptr;
sCompositorThreadID = 0;
} else {
sMainLoop->PostTask(FROM_HERE, NewRunnableFunction(&DeleteCompositorThread));
}
}
static void ReleaseCompositorThread()
{
if(--sCompositorThreadRefCount == 0) {
DeleteCompositorThread();
}
}
void
CompositorParent::StartUpWithExistingThread(MessageLoop* aMsgLoop,
PlatformThreadId aThreadID)
@ -82,6 +109,8 @@ CompositorParent::StartUpWithExistingThread(MessageLoop* aMsgLoop,
CreateCompositorMap();
sCompositorLoop = aMsgLoop;
sCompositorThreadID = aThreadID;
sMainLoop = MessageLoop::current();
sCompositorThreadRefCount = 1;
}
void CompositorParent::StartUp()
@ -89,6 +118,7 @@ void CompositorParent::StartUp()
MOZ_ASSERT(!sCompositorLoop);
CreateCompositorMap();
CreateThread();
sMainLoop = MessageLoop::current();
}
void CompositorParent::ShutDown()
@ -103,6 +133,7 @@ bool CompositorParent::CreateThread()
if (sCompositorThread || sCompositorLoop) {
return true;
}
sCompositorThreadRefCount = 1;
sCompositorThread = new Thread("Compositor");
if (!sCompositorThread->Start()) {
delete sCompositorThread;
@ -115,12 +146,7 @@ bool CompositorParent::CreateThread()
void CompositorParent::DestroyThread()
{
NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
if (sCompositorThread) {
delete sCompositorThread;
sCompositorThread = nullptr;
}
sCompositorLoop = nullptr;
sCompositorThreadID = 0;
ReleaseCompositorThread();
}
MessageLoop* CompositorParent::CompositorLoop()
@ -156,6 +182,7 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
if (!sCurrentCompositor) {
sCurrentCompositor = this;
}
++sCompositorThreadRefCount;
}
PlatformThreadId
@ -171,6 +198,7 @@ CompositorParent::~CompositorParent()
if (this == sCurrentCompositor) {
sCurrentCompositor = NULL;
}
ReleaseCompositorThread();
}
void
@ -199,6 +227,15 @@ bool
CompositorParent::RecvStop()
{
Destroy();
// There are chances that the ref count reaches zero on the main thread shortly
// after this function returns while some ipdl code still needs to run on
// this thread.
// We must keep the compositor parent alive untill the code handling message
// reception is finished on this thread.
this->AddRef(); // Corresponds to DeferredDeleteCompositorParent's Release
CompositorLoop()->PostTask(FROM_HERE,
NewRunnableFunction(&DeferredDeleteCompositorParent,
this));
return true;
}

View File

@ -33,6 +33,24 @@
#include "base/scoped_ptr.h"
#include "base/string_piece.h"
#if defined(OS_NETBSD)
#undef KERN_PROC
#define KERN_PROC KERN_PROC2
#define KINFO_PROC struct kinfo_proc2
#else
#define KINFO_PROC struct kinfo_proc
#endif
#if defined(OS_MACOSX)
#define KP_FLAGS kp_proc.p_flag
#elif defined(OS_DRAGONFLY)
#define KP_FLAGS kp_flags
#elif defined(OS_FREEBSD)
#define KP_FLAGS ki_flag
#else
#define KP_FLAGS p_flag
#endif
// static
bool DebugUtil::SpawnDebuggerOnProcess(unsigned /* process_id */) {
NOTIMPLEMENTED();
@ -60,12 +78,16 @@ bool DebugUtil::BeingDebugged() {
CTL_KERN,
KERN_PROC,
KERN_PROC_PID,
getpid()
getpid(),
#if defined(OS_NETBSD) || defined(OS_OPENBSD)
sizeof(KINFO_PROC),
1,
#endif
};
// Caution: struct kinfo_proc is marked __APPLE_API_UNSTABLE. The source and
// binary interfaces may change.
struct kinfo_proc info;
KINFO_PROC info;
size_t info_size = sizeof(info);
int sysctl_result = sysctl(mib, arraysize(mib), &info, &info_size, NULL, 0);
@ -78,15 +100,7 @@ bool DebugUtil::BeingDebugged() {
// This process is being debugged if the P_TRACED flag is set.
is_set = true;
#if defined(OS_DRAGONFLY)
being_debugged = (info.kp_flags & P_TRACED) != 0;
#elif defined(OS_FREEBSD)
being_debugged = (info.ki_flag & P_TRACED) != 0;
#elif defined(OS_OPENBSD)
being_debugged = (info.p_flag & P_TRACED) != 0;
#else
being_debugged = (info.kp_proc.p_flag & P_TRACED) != 0;
#endif
being_debugged = (info.KP_FLAGS & P_TRACED) != 0;
return being_debugged;
}

View File

@ -100,9 +100,9 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
return NULL;
parser.sct = &sct;
SharedContext sc(cx, scopeChain, /* funbox = */ NULL, StrictModeFromContext(cx));
GlobalSharedContext globalsc(cx, scopeChain, StrictModeFromContext(cx));
ParseContext pc(&parser, &sc, staticLevel, /* bodyid = */ 0);
ParseContext pc(&parser, &globalsc, staticLevel, /* bodyid = */ 0);
if (!pc.init())
return NULL;
@ -123,14 +123,14 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
JS_ASSERT_IF(globalScope, globalScope->isNative());
JS_ASSERT_IF(globalScope, JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(globalScope->getClass()));
BytecodeEmitter bce(/* parent = */ NULL, &parser, &sc, script, callerFrame, !!globalScope,
BytecodeEmitter bce(/* parent = */ NULL, &parser, &globalsc, script, callerFrame, !!globalScope,
options.lineno, options.selfHostingMode);
if (!bce.init())
return NULL;
/* If this is a direct call to eval, inherit the caller's strictness. */
if (callerFrame && callerFrame->script()->strictModeCode)
sc.strictModeState = StrictMode::STRICT;
globalsc.strictModeState = StrictMode::STRICT;
if (options.compileAndGo) {
if (source) {
@ -175,7 +175,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
if (!ok)
return NULL;
}
JS_ASSERT(sc.strictModeState != StrictMode::UNKNOWN);
JS_ASSERT(globalsc.strictModeState != StrictMode::UNKNOWN);
for (;;) {
TokenKind tt = tokenStream.peekToken(TSF_OPERAND);
if (tt <= TOK_EOF) {
@ -277,12 +277,10 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
StrictMode sms = StrictModeFromContext(cx);
FunctionBox *funbox = parser.newFunctionBox(fun, /* outerpc = */ NULL, sms);
SharedContext funsc(cx, /* scopeChain = */ NULL, funbox, sms);
fun->setArgCount(formals.length());
unsigned staticLevel = 0;
ParseContext funpc(&parser, &funsc, staticLevel, /* bodyid = */ 0);
ParseContext funpc(&parser, funbox, staticLevel, /* bodyid = */ 0);
if (!funpc.init())
return false;
@ -332,7 +330,7 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
if (!funpc.generateFunctionBindings(cx, bindings))
return false;
BytecodeEmitter funbce(/* parent = */ NULL, &parser, &funsc, script, /* callerFrame = */ NULL,
BytecodeEmitter funbce(/* parent = */ NULL, &parser, funbox, script, /* callerFrame = */ NULL,
/* hasGlobalScope = */ false, options.lineno);
if (!funbce.init())
return false;

View File

@ -697,12 +697,12 @@ EnclosingStaticScope(BytecodeEmitter *bce)
if (bce->blockChain)
return bce->blockChain;
if (!bce->sc->inFunction()) {
if (!bce->sc->isFunction) {
JS_ASSERT(!bce->parent);
return NULL;
}
return bce->sc->funbox()->fun();
return bce->sc->asFunbox()->fun();
}
// Push a block scope statement and link blockObj into bce->blockChain.
@ -918,9 +918,10 @@ EmitAliasedVarOp(JSContext *cx, JSOp op, ParseNode *pn, BytecodeEmitter *bce)
*/
for (unsigned i = pn->pn_cookie.level(); i; i--) {
skippedScopes += ClonedBlockDepth(bceOfDef);
if (bceOfDef->sc->funbox()->fun()->isHeavyweight()) {
JSFunction *funOfDef = bceOfDef->sc->asFunbox()->fun();
if (funOfDef->isHeavyweight()) {
skippedScopes++;
if (bceOfDef->sc->funbox()->fun()->isNamedLambda())
if (funOfDef->isNamedLambda())
skippedScopes++;
}
bceOfDef = bceOfDef->parent;
@ -1084,7 +1085,7 @@ static int
AdjustBlockSlot(JSContext *cx, BytecodeEmitter *bce, int slot)
{
JS_ASSERT((unsigned) slot < bce->maxStackDepth);
if (bce->sc->inFunction()) {
if (bce->sc->isFunction) {
slot += bce->script->bindings.numVars();
if ((unsigned) slot >= SLOTNO_LIMIT) {
bce->reportError(NULL, JSMSG_TOO_MANY_LOCALS);
@ -1178,7 +1179,7 @@ TryConvertToGname(BytecodeEmitter *bce, ParseNode *pn, JSOp *op)
}
if (bce->script->compileAndGo &&
bce->hasGlobalScope &&
!(bce->sc->inFunction() && bce->sc->funMightAliasLocals()) &&
!(bce->sc->isFunction && bce->sc->asFunbox()->mightAliasLocals()) &&
!pn->isDeoptimized() &&
!bce->sc->inStrictMode())
{
@ -1367,7 +1368,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
}
break;
case Definition::NAMED_LAMBDA:
case Definition::NAMED_LAMBDA: {
JS_ASSERT(dn->isOp(JSOP_CALLEE));
JS_ASSERT(op != JSOP_CALLEE);
@ -1378,8 +1379,9 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (dn->pn_cookie.level() != bce->script->staticLevel)
return true;
JS_ASSERT(bce->sc->funbox()->fun()->flags & JSFUN_LAMBDA);
JS_ASSERT(pn->pn_atom == bce->sc->funbox()->fun()->atom());
RootedFunction fun(cx, bce->sc->asFunbox()->fun());
JS_ASSERT(fun->flags & JSFUN_LAMBDA);
JS_ASSERT(pn->pn_atom == fun->atom());
/*
* Leave pn->isOp(JSOP_NAME) if bce->fun is heavyweight to
@ -1405,7 +1407,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* heavyweight, ensuring that the function name is represented in
* the scope chain so that assignment will throw a TypeError.
*/
if (!bce->sc->funbox()->fun()->isHeavyweight()) {
if (!fun->isHeavyweight()) {
op = JSOP_CALLEE;
pn->pn_dflags |= PND_CONST;
}
@ -1413,6 +1415,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
pn->setOp(op);
pn->pn_dflags |= PND_BOUND;
return true;
}
case Definition::PLACEHOLDER:
return true;
@ -1439,7 +1442,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
BytecodeEmitter *bceSkipped = bce;
for (unsigned i = 0; i < skip; i++)
bceSkipped = bceSkipped->parent;
if (!bceSkipped->sc->inFunction())
if (!bceSkipped->sc->isFunction)
return true;
}
@ -1651,7 +1654,7 @@ CheckSideEffects(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool *answe
bool
BytecodeEmitter::checkSingletonContext()
{
if (!script->compileAndGo || sc->inFunction())
if (!script->compileAndGo || sc->isFunction)
return false;
for (StmtInfoBCE *stmt = topStmt; stmt; stmt = stmt->down) {
if (stmt->isLoop())
@ -1667,11 +1670,11 @@ BytecodeEmitter::needsImplicitThis()
if (!script->compileAndGo)
return true;
if (sc->inFunction()) {
if (sc->funbox()->inWith)
if (sc->isFunction) {
if (sc->asFunbox()->inWith)
return true;
} else {
JSObject *scope = sc->scopeChain();
JSObject *scope = sc->asGlobal()->scopeChain();
while (scope) {
if (scope->isWith())
return true;
@ -2613,7 +2616,8 @@ frontend::EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *bod
* execution starts from script->code, so this has no semantic effect.
*/
if (bce->sc->funArgumentsHasLocalBinding()) {
FunctionBox *funbox = bce->sc->asFunbox();
if (funbox->argumentsHasLocalBinding()) {
JS_ASSERT(bce->next() == bce->base()); /* See JSScript::argumentsBytecode. */
bce->switchToProlog();
if (Emit1(cx, bce, JSOP_ARGUMENTS) < 0)
@ -2634,7 +2638,7 @@ frontend::EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *bod
bce->switchToMain();
}
if (bce->sc->funIsGenerator()) {
if (funbox->isGenerator()) {
bce->switchToProlog();
if (Emit1(cx, bce, JSOP_GENERATOR) < 0)
return false;
@ -2688,7 +2692,7 @@ MaybeEmitVarDecl(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *
}
if (JOF_OPTYPE(pn->getOp()) == JOF_ATOM &&
(!bce->sc->inFunction() || bce->sc->funbox()->fun()->isHeavyweight()))
(!bce->sc->isFunction || bce->sc->asFunbox()->fun()->isHeavyweight()))
{
bce->switchToProlog();
if (!UpdateSourceCoordNotes(cx, bce, pn->pn_pos.begin))
@ -4447,7 +4451,7 @@ EmitLexicalScope(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
(stmtInfo.down
? stmtInfo.down->type == STMT_BLOCK &&
(!stmtInfo.down->down || stmtInfo.down->down->type != STMT_FOR_IN_LOOP)
: !bce->sc->inFunction()))
: !bce->sc->isFunction))
{
/* There must be no source note already output for the next op. */
JS_ASSERT(bce->noteCount() == 0 ||
@ -4839,17 +4843,16 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* comments in EmitStatementList.
*/
JS_ASSERT(pn->functionIsHoisted());
JS_ASSERT(bce->sc->inFunction());
JS_ASSERT(bce->sc->isFunction);
return EmitFunctionDefNop(cx, bce, pn->pn_index);
}
{
SharedContext *outersc = bce->sc;
FunctionBox *funbox = pn->pn_funbox;
SharedContext sc(cx, /* scopeChain = */ NULL, funbox, funbox->strictModeState);
sc.cxFlags = funbox->cxFlags;
if (bce->sc->inFunction() && bce->sc->funMightAliasLocals())
sc.setFunMightAliasLocals(); // inherit funMightAliasLocals from parent
JS_ASSERT_IF(bce->sc->inStrictMode(), sc.inStrictMode());
if (outersc->isFunction && outersc->asFunbox()->mightAliasLocals())
funbox->setMightAliasLocals(); // inherit mightAliasLocals from parent
JS_ASSERT_IF(outersc->inStrictMode(), funbox->inStrictMode());
// Inherit most things (principals, version, etc) from the parent.
Rooted<JSScript*> parent(cx, bce->script);
@ -4869,8 +4872,8 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
script->bindings = funbox->bindings;
BytecodeEmitter bce2(bce, bce->parser, &sc, script, bce->callerFrame, bce->hasGlobalScope,
pn->pn_pos.begin.lineno, bce->selfHostingMode);
BytecodeEmitter bce2(bce, bce->parser, funbox, script, bce->callerFrame,
bce->hasGlobalScope, pn->pn_pos.begin.lineno, bce->selfHostingMode);
if (!bce2.init())
return false;
@ -4880,7 +4883,7 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
}
/* Make the function object a literal in the outer script's pool. */
unsigned index = bce->objectList.add(pn->pn_funbox);
unsigned index = bce->objectList.add(&pn->pn_funbox->objbox);
/* Non-hoisted functions simply emit their respective op. */
if (!pn->functionIsHoisted()) {
@ -4899,7 +4902,7 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* invocation of the emitter and calls to EmitTree for function
* definitions can be scheduled before generating the rest of code.
*/
if (!bce->sc->inFunction()) {
if (!bce->sc->isFunction) {
JS_ASSERT(pn->pn_cookie.isFree());
JS_ASSERT(pn->getOp() == JSOP_NOP);
JS_ASSERT(!bce->topStmt);
@ -5192,7 +5195,7 @@ EmitStatement(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
*/
bool wantval = false;
bool useful = false;
if (bce->sc->inFunction()) {
if (bce->sc->isFunction) {
JS_ASSERT(!bce->script->noScriptRval);
} else {
useful = wantval = !bce->script->noScriptRval;
@ -5958,8 +5961,8 @@ static bool
EmitDefaults(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
JS_ASSERT(pn->isKind(PNK_ARGSBODY));
uint16_t ndefaults = bce->sc->funbox()->ndefaults;
JSFunction *fun = bce->sc->funbox()->fun();
uint16_t ndefaults = bce->sc->asFunbox()->ndefaults;
JSFunction *fun = bce->sc->asFunbox()->fun();
unsigned nformal = fun->nargs - fun->hasRest();
EMIT_UINT16_IMM_OP(JSOP_ACTUALSFILLED, nformal - ndefaults);
ptrdiff_t top = bce->offset();
@ -6049,7 +6052,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
case PNK_ARGSBODY:
{
RootedFunction fun(cx, bce->sc->funbox()->fun());
RootedFunction fun(cx, bce->sc->asFunbox()->fun());
ParseNode *pnlast = pn->last();
// Carefully emit everything in the right order:
@ -6087,7 +6090,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
ParseNode *rest = NULL;
bool restIsDefn = false;
if (fun->hasRest()) {
JS_ASSERT(!bce->sc->funArgumentsHasLocalBinding());
JS_ASSERT(!bce->sc->asFunbox()->argumentsHasLocalBinding());
// Defaults with a rest parameter need special handling. The
// rest parameter needs to be undefined while defaults are being
// processed. To do this, we create the rest argument and let it
@ -6132,7 +6135,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
return false;
if (pn2->pn_next == pnlast && fun->hasRest() && !fun->hasDefaults()) {
// Fill rest parameter. We handled the case with defaults above.
JS_ASSERT(!bce->sc->funArgumentsHasLocalBinding());
JS_ASSERT(!bce->sc->asFunbox()->argumentsHasLocalBinding());
bce->switchToProlog();
if (Emit1(cx, bce, JSOP_REST) < 0)
return false;
@ -6202,7 +6205,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
#if JS_HAS_GENERATORS
case PNK_YIELD:
JS_ASSERT(bce->sc->inFunction());
JS_ASSERT(bce->sc->isFunction);
if (pn->pn_kid) {
if (!EmitTree(cx, bce, pn->pn_kid))
return false;

View File

@ -445,7 +445,7 @@ CloneParseTree(ParseNode *opn, Parser *parser)
case PN_FUNC:
NULLCHECK(pn->pn_funbox =
parser->newFunctionBox(opn->pn_funbox->object, pc, opn->pn_funbox->strictModeState));
parser->newFunctionBox(opn->pn_funbox->fun(), pc, opn->pn_funbox->strictModeState));
NULLCHECK(pn->pn_body = CloneParseTree(opn->pn_body, parser));
pn->pn_cookie = opn->pn_cookie;
pn->pn_dflags = opn->pn_dflags;

View File

@ -1465,9 +1465,14 @@ struct ObjectBox {
ObjectBox *traceLink;
ObjectBox *emitLink;
JSObject *object;
bool isFunctionBox;
// An ObjectBox can hold a JSObject or a JSFunction. In the latter case,
// the ObjectBox will be embedded within a FunctionBox; |funbox| points to
// that FunctionBox.
FunctionBox *const funbox;
ObjectBox(ObjectBox *traceLink, JSObject *obj);
ObjectBox(ObjectBox *traceLink, JSFunction *fun, FunctionBox *funbox);
};
} /* namespace frontend */

View File

@ -167,7 +167,7 @@ ParseContext::define(JSContext *cx, PropertyName *name, ParseNode *pn, Definitio
Definition *dn = (Definition *)pn;
switch (kind) {
case Definition::ARG:
JS_ASSERT(sc->inFunction());
JS_ASSERT(sc->isFunction);
dn->setOp(JSOP_GETARG);
dn->pn_dflags |= PND_BOUND;
if (!dn->pn_cookie.set(cx, staticLevel, args_.length()))
@ -182,7 +182,7 @@ ParseContext::define(JSContext *cx, PropertyName *name, ParseNode *pn, Definitio
case Definition::CONST:
case Definition::VAR:
if (sc->inFunction()) {
if (sc->isFunction) {
dn->setOp(JSOP_GETLOCAL);
dn->pn_dflags |= PND_BOUND;
if (!dn->pn_cookie.set(cx, staticLevel, vars_.length()))
@ -229,7 +229,7 @@ ParseContext::updateDecl(JSAtom *atom, ParseNode *pn)
Definition *newDecl = (Definition *)pn;
decls_.updateFirst(atom, newDecl);
if (!sc->inFunction()) {
if (!sc->isFunction) {
JS_ASSERT(newDecl->isFreeVar());
return;
}
@ -298,7 +298,7 @@ AppendPackedBindings(const ParseContext *pc, const DeclVector &vec, Binding *dst
bool
ParseContext::generateFunctionBindings(JSContext *cx, InternalHandle<Bindings*> bindings) const
{
JS_ASSERT(sc->inFunction());
JS_ASSERT(sc->isFunction);
unsigned count = args_.length() + vars_.length();
Binding *packedBindings = cx->tempLifoAlloc().newArrayUninitialized<Binding>(count);
@ -316,8 +316,9 @@ ParseContext::generateFunctionBindings(JSContext *cx, InternalHandle<Bindings*>
return false;
}
if (bindings->hasAnyAliasedBindings() || sc->funHasExtensibleScope())
sc->funbox()->fun()->flags |= JSFUN_HEAVYWEIGHT;
FunctionBox *funbox = sc->asFunbox();
if (bindings->hasAnyAliasedBindings() || funbox->hasExtensibleScope())
funbox->fun()->flags |= JSFUN_HEAVYWEIGHT;
return true;
}
@ -362,7 +363,15 @@ ObjectBox::ObjectBox(ObjectBox* traceLink, JSObject *obj)
: traceLink(traceLink),
emitLink(NULL),
object(obj),
isFunctionBox(false)
funbox(NULL)
{
}
ObjectBox::ObjectBox(ObjectBox* traceLink, JSFunction *fun, FunctionBox *funbox)
: traceLink(traceLink),
emitLink(NULL),
object(fun),
funbox(funbox)
{
}
@ -390,22 +399,20 @@ Parser::newObjectBox(JSObject *obj)
return objbox;
}
FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseContext *outerpc,
StrictMode sms)
: ObjectBox(traceListHead, obj),
FunctionBox::FunctionBox(JSContext *cx, ObjectBox* traceListHead, JSFunction *fun,
ParseContext *outerpc, StrictMode sms)
: SharedContext(cx, /* isFunction = */ true, sms),
objbox(traceListHead, fun, this),
siblings(outerpc ? outerpc->functionList : NULL),
kids(NULL),
bindings(),
bufStart(0),
bufEnd(0),
ndefaults(0),
strictModeState(sms),
inWith(false), // initialized below
inGenexpLambda(false),
cxFlags() // the cxFlags are set in LeaveFunction
funCxFlags()
{
isFunctionBox = true;
if (!outerpc) {
inWith = false;
@ -418,7 +425,7 @@ FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseContext *
// outerpc->parsingWith is true.
inWith = true;
} else if (!outerpc->sc->inFunction()) {
} else if (!outerpc->sc->isFunction) {
// This covers the case where a function is nested within an eval()
// within a |with| statement.
//
@ -429,7 +436,7 @@ FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseContext *
// ParseContext chain, and |parent| is NULL (again because of the
// eval(), so we have to look at |outerpc|'s scopeChain.
//
JSObject *scope = outerpc->sc->scopeChain();
JSObject *scope = outerpc->sc->asGlobal()->scopeChain();
while (scope) {
if (scope->isWith())
inWith = true;
@ -443,17 +450,16 @@ FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseContext *
//
// In this case, the inner anonymous function needs to inherit the
// setting of |inWith| from the outer one.
FunctionBox *parent = outerpc->sc->funbox();
FunctionBox *parent = outerpc->sc->asFunbox();
if (parent && parent->inWith)
inWith = true;
}
}
FunctionBox *
Parser::newFunctionBox(JSObject *obj, ParseContext *outerpc, StrictMode sms)
Parser::newFunctionBox(JSFunction *fun, ParseContext *outerpc, StrictMode sms)
{
JS_ASSERT(obj && !IsPoisonedPtr(obj));
JS_ASSERT(obj->isFunction());
JS_ASSERT(fun && !IsPoisonedPtr(fun));
/*
* We use JSContext.tempLifoAlloc to allocate parsed objects and place them
@ -463,7 +469,7 @@ Parser::newFunctionBox(JSObject *obj, ParseContext *outerpc, StrictMode sms)
* function.
*/
FunctionBox *funbox =
context->tempLifoAlloc().new_<FunctionBox>(traceListHead, obj, outerpc, sms);
context->tempLifoAlloc().new_<FunctionBox>(context, traceListHead, fun, outerpc, sms);
if (!funbox) {
js_ReportOutOfMemory(context);
return NULL;
@ -471,7 +477,7 @@ Parser::newFunctionBox(JSObject *obj, ParseContext *outerpc, StrictMode sms)
if (outerpc)
outerpc->functionList = funbox;
traceListHead = funbox;
traceListHead = &funbox->objbox;
return funbox;
}
@ -482,8 +488,8 @@ Parser::trace(JSTracer *trc)
ObjectBox *objbox = traceListHead;
while (objbox) {
MarkObjectRoot(trc, &objbox->object, "parser.object");
if (objbox->isFunctionBox)
static_cast<FunctionBox *>(objbox)->bindings.trace(trc);
if (objbox->funbox)
objbox->funbox->bindings.trace(trc);
objbox = objbox->traceLink;
}
}
@ -514,7 +520,7 @@ Parser::parse(JSObject *chain)
* an object lock before it finishes generating bytecode into a script
* protected from the GC by a root or a stack frame reference.
*/
SharedContext globalsc(context, chain, /* funbox = */ NULL, StrictModeFromContext(context));
GlobalSharedContext globalsc(context, chain, StrictModeFromContext(context));
ParseContext globalpc(this, &globalsc, /* staticLevel = */ 0, /* bodyid = */ 0);
if (!globalpc.init())
return NULL;
@ -662,7 +668,7 @@ ReportBadReturn(JSContext *cx, Parser *parser, ParseNode *pn, Parser::Reporter r
unsigned errnum, unsigned anonerrnum)
{
JSAutoByteString name;
JSAtom *atom = parser->pc->sc->funbox()->fun()->atom();
JSAtom *atom = parser->pc->sc->asFunbox()->fun()->atom();
if (atom) {
if (!js_AtomToPrintableString(cx, atom, &name))
return false;
@ -675,7 +681,7 @@ ReportBadReturn(JSContext *cx, Parser *parser, ParseNode *pn, Parser::Reporter r
static bool
CheckFinalReturn(JSContext *cx, Parser *parser, ParseNode *pn)
{
JS_ASSERT(parser->pc->sc->inFunction());
JS_ASSERT(parser->pc->sc->isFunction);
return HasFinalReturn(pn) == ENDS_IN_RETURN ||
ReportBadReturn(cx, parser, pn, &Parser::reportStrictWarning,
JSMSG_NO_RETURN_VALUE, JSMSG_ANON_NO_RETURN_VALUE);
@ -732,7 +738,7 @@ CheckStrictBinding(JSContext *cx, Parser *parser, HandlePropertyName name, Parse
ParseNode *
Parser::functionBody(FunctionBodyType type)
{
JS_ASSERT(pc->sc->inFunction());
JS_ASSERT(pc->sc->isFunction);
StmtInfoPC stmtInfo(context);
PushStatementPC(pc, &stmtInfo, STMT_BLOCK);
@ -757,7 +763,7 @@ Parser::functionBody(FunctionBodyType type)
if (!pn->pn_kid) {
pn = NULL;
} else {
if (pc->sc->funIsGenerator()) {
if (pc->sc->asFunbox()->isGenerator()) {
ReportBadReturn(context, this, pn, &Parser::reportError,
JSMSG_BAD_GENERATOR_RETURN,
JSMSG_BAD_ANON_GENERATOR_RETURN);
@ -827,7 +833,7 @@ Parser::functionBody(FunctionBodyType type)
Definition *maybeArgDef = pc->decls().lookupFirst(arguments);
bool argumentsHasBinding = !!maybeArgDef;
bool argumentsHasLocalBinding = maybeArgDef && maybeArgDef->kind() != Definition::ARG;
bool hasRest = pc->sc->funbox()->fun()->hasRest();
bool hasRest = pc->sc->asFunbox()->fun()->hasRest();
if (hasRest && argumentsHasLocalBinding) {
reportError(NULL, JSMSG_ARGUMENTS_AND_REST);
return NULL;
@ -854,11 +860,12 @@ Parser::functionBody(FunctionBodyType type)
* arguments object. (Also see the flags' comments in ContextFlags.)
*/
if (argumentsHasLocalBinding) {
pc->sc->setFunArgumentsHasLocalBinding();
FunctionBox *funbox = pc->sc->asFunbox();
funbox->setArgumentsHasLocalBinding();
/* Dynamic scope access destroys all hope of optimization. */
if (pc->sc->bindingsAccessedDynamically())
pc->sc->setFunDefinitelyNeedsArgsObj();
funbox->setDefinitelyNeedsArgsObj();
/*
* Check whether any parameters have been assigned within this
@ -873,7 +880,7 @@ Parser::functionBody(FunctionBodyType type)
for (DefinitionList::Range dr = dlist.all(); !dr.empty(); dr.popFront()) {
Definition *dn = dr.front();
if (dn->kind() == Definition::ARG && dn->isAssigned()) {
pc->sc->setFunDefinitelyNeedsArgsObj();
funbox->setDefinitelyNeedsArgsObj();
goto exitLoop;
}
}
@ -1073,15 +1080,15 @@ Parser::newFunction(ParseContext *pc, JSAtom *atom, FunctionSyntaxKind kind)
/*
* Find the global compilation context in order to pre-set the newborn
* function's parent slot to pc->sc->scopeChain. If the global context is a
* compile-and-go one, we leave the pre-set parent intact; otherwise we
* clear parent and proto.
* function's parent slot to pc->sc->asGlobal()->scopeChain. If the global
* context is a compile-and-go one, we leave the pre-set parent intact;
* otherwise we clear parent and proto.
*/
while (pc->parent)
pc = pc->parent;
RootedObject parent(context);
parent = pc->sc->inFunction() ? NULL : pc->sc->scopeChain();
parent = pc->sc->isFunction ? NULL : pc->sc->asGlobal()->scopeChain();
RootedFunction fun(context);
uint32_t flags = JSFUN_INTERPRETED | (kind == Expression ? JSFUN_LAMBDA : 0);
@ -1147,7 +1154,7 @@ LeaveFunction(ParseNode *fn, Parser *parser, PropertyName *funName = NULL,
pc->blockidGen = funpc->blockidGen;
FunctionBox *funbox = fn->pn_funbox;
funbox->cxFlags = funpc->sc->cxFlags; // copy all the flags
JS_ASSERT(funbox == funpc->sc->asFunbox());
funbox->kids = funpc->functionList;
if (!pc->topStmt || pc->topStmt->type == STMT_BLOCK)
@ -1180,7 +1187,7 @@ LeaveFunction(ParseNode *fn, Parser *parser, PropertyName *funName = NULL,
* produce an error (in strict mode).
*/
if (dn->isClosed() || dn->isAssigned())
funpc->sc->funbox()->fun()->flags |= JSFUN_HEAVYWEIGHT;
funbox->fun()->flags |= JSFUN_HEAVYWEIGHT;
continue;
}
@ -1191,7 +1198,7 @@ LeaveFunction(ParseNode *fn, Parser *parser, PropertyName *funName = NULL,
* by eval and function statements (which both flag the function as
* having an extensible scope) or any enclosing 'with'.
*/
if (funpc->sc->funHasExtensibleScope() || pc->parsingWith)
if (funbox->hasExtensibleScope() || pc->parsingWith)
DeoptimizeUsesWithin(dn, fn->pn_pos);
if (!outer_dn) {
@ -1335,7 +1342,7 @@ static bool
BindDestructuringArg(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser)
{
ParseContext *pc = parser->pc;
JS_ASSERT(pc->sc->inFunction());
JS_ASSERT(pc->sc->isFunction);
if (pc->decls().lookupFirst(name)) {
parser->reportError(NULL, JSMSG_BAD_DUP_ARGS);
@ -1357,7 +1364,7 @@ Parser::functionArguments(ParseNode **listp, ParseNode* funcpn, bool &hasRest)
return false;
}
FunctionBox *funbox = pc->sc->funbox();
FunctionBox *funbox = pc->sc->asFunbox();
funbox->bufStart = tokenStream.offsetOfToken(tokenStream.currentToken());
hasRest = false;
@ -1587,14 +1594,15 @@ Parser::functionDef(HandlePropertyName funName, FunctionType type, FunctionSynta
*/
if (bodyLevel) {
JS_ASSERT(pn->functionIsHoisted());
JS_ASSERT_IF(pc->sc->inFunction(), !pn->pn_cookie.isFree());
JS_ASSERT_IF(!pc->sc->inFunction(), pn->pn_cookie.isFree());
JS_ASSERT_IF(pc->sc->isFunction, !pn->pn_cookie.isFree());
JS_ASSERT_IF(!pc->sc->isFunction, pn->pn_cookie.isFree());
} else {
JS_ASSERT(pc->sc->strictModeState != StrictMode::STRICT);
JS_ASSERT(pn->pn_cookie.isFree());
if (pc->sc->inFunction()) {
pc->sc->setFunMightAliasLocals();
pc->sc->setFunHasExtensibleScope();
if (pc->sc->isFunction) {
FunctionBox *funbox = pc->sc->asFunbox();
funbox->setMightAliasLocals();
funbox->setHasExtensibleScope();
}
pn->setOp(JSOP_DEFFUN);
@ -1636,8 +1644,7 @@ Parser::functionDef(HandlePropertyName funName, FunctionType type, FunctionSynta
return NULL;
/* Initialize early for possible flags mutation via destructuringExpr. */
SharedContext funsc(context, /* scopeChain = */ NULL, funbox, sms);
ParseContext funpc(this, &funsc, outerpc->staticLevel + 1, outerpc->blockidGen);
ParseContext funpc(this, funbox, outerpc->staticLevel + 1, outerpc->blockidGen);
if (!funpc.init())
return NULL;
@ -1703,7 +1710,7 @@ Parser::functionDef(HandlePropertyName funName, FunctionType type, FunctionSynta
* that the deoptimizing effects of dynamic name access apply equally to
* parents: any local can be read at runtime.
*/
if (funsc.bindingsAccessedDynamically())
if (funbox->bindingsAccessedDynamically())
outerpc->sc->setBindingsAccessedDynamically();
#if JS_HAS_DESTRUCTURING
@ -1745,7 +1752,7 @@ Parser::functionDef(HandlePropertyName funName, FunctionType type, FunctionSynta
* If any nested function scope does a dynamic scope access, all enclosing
* scopes may be accessed dynamically.
*/
if (funsc.bindingsAccessedDynamically())
if (funbox->bindingsAccessedDynamically())
outerpc->sc->setBindingsAccessedDynamically();
@ -1813,8 +1820,7 @@ Parser::setStrictMode(bool strictMode)
if (pc->sc->strictModeState != StrictMode::UNKNOWN) {
// Strict mode was inherited.
JS_ASSERT(pc->sc->strictModeState == StrictMode::STRICT);
if (pc->sc->inFunction()) {
JS_ASSERT(pc->sc->funbox()->strictModeState == pc->sc->strictModeState);
if (pc->sc->isFunction) {
JS_ASSERT(pc->parent->sc->strictModeState == StrictMode::STRICT);
} else {
JS_ASSERT(StrictModeFromContext(context) == StrictMode::STRICT || pc->staticLevel);
@ -1840,12 +1846,12 @@ Parser::setStrictMode(bool strictMode)
pc->queuedStrictModeError->throwError();
}
}
JS_ASSERT_IF(!pc->sc->inFunction(), !pc->functionList);
if (pc->sc->strictModeState != StrictMode::UNKNOWN && pc->sc->inFunction()) {
JS_ASSERT_IF(!pc->sc->isFunction, !pc->functionList);
if (pc->sc->strictModeState != StrictMode::UNKNOWN && pc->sc->isFunction) {
// We changed the strict mode state. Retroactively recursively set
// strict mode status on all the function children we've seen so far
// children (That is, functions in default expressions).
pc->sc->funbox()->strictModeState = pc->sc->strictModeState;
pc->sc->asFunbox()->strictModeState = pc->sc->strictModeState;
for (FunctionBox *kid = pc->functionList; kid; kid = kid->siblings)
kid->recursivelySetStrictMode(pc->sc->strictModeState);
}
@ -1989,7 +1995,7 @@ Parser::statements(bool *hasFunctionStmt)
* General deoptimization was done in functionDef, here we just
* need to tell TOK_LC in Parser::statement to add braces.
*/
JS_ASSERT_IF(pc->sc->inFunction(), pc->sc->funHasExtensibleScope());
JS_ASSERT_IF(pc->sc->isFunction, pc->sc->asFunbox()->hasExtensibleScope());
if (hasFunctionStmt)
*hasFunctionStmt = true;
}
@ -2189,8 +2195,8 @@ BindVarOrConst(JSContext *cx, BindData *data, HandlePropertyName name, Parser *p
if (stmt && stmt->type == STMT_WITH) {
pn->pn_dflags |= PND_DEOPTIMIZED;
if (pc->sc->inFunction())
pc->sc->setFunMightAliasLocals();
if (pc->sc->isFunction)
pc->sc->asFunbox()->setMightAliasLocals();
return true;
}
@ -2264,7 +2270,7 @@ MakeSetCall(JSContext *cx, ParseNode *pn, Parser *parser, unsigned msg)
}
static void
NoteLValue(JSContext *cx, ParseNode *pn, SharedContext *sc)
NoteLValue(ParseNode *pn)
{
if (pn->isUsed())
pn->pn_lexdef->pn_dflags |= PND_ASSIGNED;
@ -2337,7 +2343,7 @@ BindDestructuringVar(JSContext *cx, BindData *data, ParseNode *pn, Parser *parse
if (data->op == JSOP_DEFCONST)
pn->pn_dflags |= PND_CONST;
NoteLValue(cx, pn, parser->pc->sc);
NoteLValue(pn);
return true;
}
@ -2364,7 +2370,7 @@ BindDestructuringLHS(JSContext *cx, ParseNode *pn, Parser *parser)
{
switch (pn->getKind()) {
case PNK_NAME:
NoteLValue(cx, pn, parser->pc->sc);
NoteLValue(pn);
/* FALL THROUGH */
case PNK_DOT:
@ -2560,7 +2566,7 @@ ParseNode *
Parser::returnOrYield(bool useAssignExpr)
{
TokenKind tt = tokenStream.currentToken().type;
if (!pc->sc->inFunction()) {
if (!pc->sc->isFunction) {
reportError(NULL, JSMSG_BAD_RETURN_OR_YIELD,
(tt == TOK_RETURN) ? js_return_str : js_yield_str);
return NULL;
@ -2577,7 +2583,7 @@ Parser::returnOrYield(bool useAssignExpr)
* a |for| token, so we have to delay flagging the current function.
*/
if (pc->parenDepth == 0) {
pc->sc->setFunIsGenerator();
pc->sc->asFunbox()->setIsGenerator();
} else {
pc->yieldCount++;
pc->yieldNode = pn;
@ -2614,7 +2620,7 @@ Parser::returnOrYield(bool useAssignExpr)
pc->funHasReturnVoid = true;
}
if (pc->funHasReturnExpr && pc->sc->funIsGenerator()) {
if (pc->funHasReturnExpr && pc->sc->asFunbox()->isGenerator()) {
/* As in Python (see PEP-255), disallow return v; in generators. */
ReportBadReturn(context, this, pn, &Parser::reportError, JSMSG_BAD_GENERATOR_RETURN,
JSMSG_BAD_ANON_GENERATOR_RETURN);
@ -3222,7 +3228,7 @@ Parser::forStatement()
switch (pn2->getKind()) {
case PNK_NAME:
/* Beware 'for (arguments in ...)' with or without a 'var'. */
NoteLValue(context, pn2, pc->sc);
NoteLValue(pn2);
break;
#if JS_HAS_DESTRUCTURING
@ -4179,7 +4185,7 @@ Parser::variables(ParseNodeKind kind, StaticBlockObject *blockObj, VarContext va
? JSOP_SETCONST
: JSOP_SETNAME);
NoteLValue(context, pn2, pc->sc);
NoteLValue(pn2);
/* The declarator's position must include the initializer. */
pn2->pn_pos.end = init->pn_pos.end;
@ -4462,7 +4468,7 @@ Parser::setAssignmentLhsOps(ParseNode *pn, JSOp op)
if (!CheckStrictAssignment(context, this, pn))
return false;
pn->setOp(pn->isOp(JSOP_GETLOCAL) ? JSOP_SETLOCAL : JSOP_SETNAME);
NoteLValue(context, pn, pc->sc);
NoteLValue(pn);
break;
case PNK_DOT:
pn->setOp(JSOP_SETPROP);
@ -4581,7 +4587,7 @@ SetIncOpKid(JSContext *cx, Parser *parser, ParseNode *pn, ParseNode *kid,
op = (tt == TOK_INC)
? (preorder ? JSOP_INCNAME : JSOP_NAMEINC)
: (preorder ? JSOP_DECNAME : JSOP_NAMEDEC);
NoteLValue(cx, kid, parser->pc->sc);
NoteLValue(kid);
break;
case PNK_DOT:
@ -4850,13 +4856,13 @@ GenexpGuard::maybeNoteGenerator(ParseNode *pn)
{
ParseContext *pc = parser->pc;
if (pc->yieldCount > 0) {
if (!pc->sc->inFunction()) {
if (!pc->sc->isFunction) {
parser->reportError(NULL, JSMSG_BAD_RETURN_OR_YIELD, js_yield_str);
return false;
}
pc->sc->setFunIsGenerator();
pc->sc->asFunbox()->setIsGenerator();
if (pc->funHasReturnExpr) {
/* At the time we saw the yield, we might not have set funIsGenerator yet. */
/* At the time we saw the yield, we might not have set isGenerator yet. */
ReportBadReturn(pc->sc->context, parser, pn, &Parser::reportError,
JSMSG_BAD_GENERATOR_RETURN, JSMSG_BAD_ANON_GENERATOR_RETURN);
return false;
@ -4948,7 +4954,7 @@ CompExprTransplanter::transplant(ParseNode *pn)
FunctionBox *funbox = pn->pn_funbox;
if (++funcLevel == 1 && genexp) {
FunctionBox *parent = pc->sc->funbox();
FunctionBox *parent = pc->sc->asFunbox();
FunctionBox **funboxp = &pc->parent->functionList;
while (*funboxp != funbox)
@ -5358,12 +5364,11 @@ Parser::generatorExpr(ParseNode *kid)
return NULL;
/* Create box for fun->object early to protect against last-ditch GC. */
FunctionBox *funbox = newFunctionBox(fun, outerpc, outerpc->sc->strictModeState);
if (!funbox)
FunctionBox *genFunbox = newFunctionBox(fun, outerpc, outerpc->sc->strictModeState);
if (!genFunbox)
return NULL;
SharedContext gensc(context, /* scopeChain = */ NULL, funbox, outerpc->sc->strictModeState);
ParseContext genpc(this, &gensc, outerpc->staticLevel + 1, outerpc->blockidGen);
ParseContext genpc(this, genFunbox, outerpc->staticLevel + 1, outerpc->blockidGen);
if (!genpc.init())
return NULL;
@ -5373,11 +5378,13 @@ Parser::generatorExpr(ParseNode *kid)
* simplicity we also do not detect if the flags were only set in the
* kid and could be removed from pc->sc.
*/
gensc.cxFlags = outerpc->sc->cxFlags;
gensc.setFunIsGenerator();
genFunbox->anyCxFlags = outerpc->sc->anyCxFlags;
if (outerpc->sc->isFunction)
genFunbox->funCxFlags = outerpc->sc->asFunbox()->funCxFlags;
funbox->inGenexpLambda = true;
genfn->pn_funbox = funbox;
genFunbox->setIsGenerator();
genFunbox->inGenexpLambda = true;
genfn->pn_funbox = genFunbox;
genfn->pn_blockid = genpc.bodyid;
ParseNode *body = comprehensionTail(pn, outerpc->blockid(), true);
@ -5388,7 +5395,7 @@ Parser::generatorExpr(ParseNode *kid)
genfn->pn_pos.begin = body->pn_pos.begin = kid->pn_pos.begin;
genfn->pn_pos.end = body->pn_pos.end = tokenStream.currentToken().pos.end;
JSAtom *arguments = gensc.context->runtime->atomState.argumentsAtom;
JSAtom *arguments = context->runtime->atomState.argumentsAtom;
if (AtomDefnPtr p = genpc.lexdeps->lookup(arguments)) {
Definition *dn = p.value();
ParseNode *errorNode = dn->dn_uses ? dn->dn_uses : body;
@ -5698,8 +5705,8 @@ Parser::memberExpr(bool allowCallSyntax)
* In non-strict mode code, direct calls to eval can add
* variables to the call object.
*/
if (pc->sc->inFunction() && pc->sc->strictModeState != StrictMode::STRICT)
pc->sc->setFunHasExtensibleScope();
if (pc->sc->isFunction && pc->sc->strictModeState != StrictMode::STRICT)
pc->sc->asFunbox()->setHasExtensibleScope();
}
} else if (lhs->isOp(JSOP_GETPROP)) {
/* Select JSOP_FUNAPPLY given foo.apply(...). */
@ -6340,7 +6347,7 @@ Parser::parseXMLText(JSObject *chain, bool allowList)
* lightweight function activation, or if its scope chain doesn't match
* the one passed to us.
*/
SharedContext xmlsc(context, chain, /* funbox = */ NULL, StrictMode::NOTSTRICT);
GlobalSharedContext xmlsc(context, chain, StrictMode::NOTSTRICT);
ParseContext xmlpc(this, &xmlsc, /* staticLevel = */ 0, /* bodyid = */ 0);
if (!xmlpc.init())
return NULL;

View File

@ -84,12 +84,12 @@ struct ParseContext /* tree context for semantic checks */
}
uint32_t numArgs() const {
JS_ASSERT(sc->inFunction());
JS_ASSERT(sc->isFunction);
return args_.length();
}
uint32_t numVars() const {
JS_ASSERT(sc->inFunction());
JS_ASSERT(sc->isFunction);
return vars_.length();
}
@ -303,7 +303,7 @@ struct Parser : private AutoGCRooter
*/
ObjectBox *newObjectBox(JSObject *obj);
FunctionBox *newFunctionBox(JSObject *obj, ParseContext *pc, StrictMode sms);
FunctionBox *newFunctionBox(JSFunction *fun, ParseContext *pc, StrictMode sms);
/*
* Create a new function object given parse context (pc) and a name (which

View File

@ -15,22 +15,18 @@ namespace js {
namespace frontend {
inline
SharedContext::SharedContext(JSContext *cx, JSObject *scopeChain, FunctionBox *funbox,
StrictMode sms)
SharedContext::SharedContext(JSContext *cx, bool isFun, StrictMode sms)
: context(cx),
funbox_(funbox),
scopeChain_(cx, scopeChain),
cxFlags(),
isFunction(isFun),
anyCxFlags(),
strictModeState(sms)
{
JS_ASSERT((funbox && !scopeChain_) || !funbox);
}
inline bool
SharedContext::inStrictMode()
{
JS_ASSERT(strictModeState != StrictMode::UNKNOWN);
JS_ASSERT_IF(inFunction(), funbox()->strictModeState == strictModeState);
return strictModeState == StrictMode::STRICT;
}
@ -40,6 +36,26 @@ SharedContext::needStrictChecks()
return context->hasStrictOption() || strictModeState != StrictMode::NOTSTRICT;
}
inline GlobalSharedContext *
SharedContext::asGlobal()
{
JS_ASSERT(!isFunction);
return static_cast<GlobalSharedContext*>(this);
}
inline FunctionBox *
SharedContext::asFunbox()
{
JS_ASSERT(isFunction);
return static_cast<FunctionBox*>(this);
}
GlobalSharedContext::GlobalSharedContext(JSContext *cx, JSObject *scopeChain, StrictMode sms)
: SharedContext(cx, /* isFunction = */ false, sms),
scopeChain_(cx, scopeChain)
{
}
} /* namespace frontend */
template <class ContextT>

View File

@ -22,11 +22,11 @@
namespace js {
namespace frontend {
class ContextFlags {
// These flags apply to both global and function contexts.
class AnyContextFlags
{
// This class's data is all private and so only visible to these friends.
friend struct SharedContext;
friend struct FunctionBox;
// True if "use strict"; appears in the body instead of being inherited.
bool hasExplicitUseStrict:1;
@ -54,12 +54,24 @@ class ContextFlags {
//
bool bindingsAccessedDynamically:1;
public:
AnyContextFlags()
: hasExplicitUseStrict(false),
bindingsAccessedDynamically(false)
{ }
};
class FunctionContextFlags
{
// This class's data is all private and so only visible to these friends.
friend struct FunctionBox;
// We parsed a yield statement in the function.
bool funIsGenerator:1;
bool isGenerator:1;
// The function or a function that encloses it may define new local names
// at runtime through means other than calling eval.
bool funMightAliasLocals:1;
bool mightAliasLocals:1;
// This function does something that can extend the set of bindings in its
// call objects --- it does a direct eval in non-strict code, or includes a
@ -68,7 +80,7 @@ class ContextFlags {
// This flag is *not* inherited by enclosed or enclosing functions; it
// applies only to the function in whose flags it appears.
//
bool funHasExtensibleScope:1;
bool hasExtensibleScope:1;
// Technically, every function has a binding named 'arguments'. Internally,
// this binding is only added when 'arguments' is mentioned by the function
@ -91,7 +103,7 @@ class ContextFlags {
// have no special semantics: the initial value is unconditionally the
// actual argument (or undefined if nactual < nformal).
//
bool funArgumentsHasLocalBinding:1;
bool argumentsHasLocalBinding:1;
// In many cases where 'arguments' has a local binding (as described above)
// we do not need to actually create an arguments object in the function
@ -102,39 +114,34 @@ class ContextFlags {
// be unsound in several cases. The frontend filters out such cases by
// setting this flag which eagerly sets script->needsArgsObj to true.
//
bool funDefinitelyNeedsArgsObj:1;
bool definitelyNeedsArgsObj:1;
public:
ContextFlags()
: hasExplicitUseStrict(false),
bindingsAccessedDynamically(false),
funIsGenerator(false),
funMightAliasLocals(false),
funHasExtensibleScope(false),
funArgumentsHasLocalBinding(false),
funDefinitelyNeedsArgsObj(false)
FunctionContextFlags()
: isGenerator(false),
mightAliasLocals(false),
hasExtensibleScope(false),
argumentsHasLocalBinding(false),
definitelyNeedsArgsObj(false)
{ }
};
class GlobalSharedContext;
/*
* The struct SharedContext is part of the current parser context (see
* ParseContext). It stores information that is reused between the parser and
* the bytecode emitter. Note however, that this information is not shared
* between the two; they simply reuse the same data structure.
*/
struct SharedContext {
class SharedContext
{
public:
JSContext *const context;
private:
FunctionBox *const funbox_; /* null or box for function we're compiling
(if inFunction() is true) */
const RootedObject scopeChain_; /* scope chain object for the script
(if inFunction() is false) */
public:
ContextFlags cxFlags;
const bool isFunction; /* true for function code, false for
global code */
AnyContextFlags anyCxFlags;
// strictModeState tracks the strictness of this context. Normally, it
// should be STRICT or NOTSTRICT. However, it can be UNKNOWN when parsing
@ -158,41 +165,71 @@ struct SharedContext {
// If it's function code, funbox must be non-NULL and scopeChain must be NULL.
// If it's global code, funbox must be NULL.
inline SharedContext(JSContext *cx, JSObject *scopeChain, FunctionBox *funbox,
StrictMode sms);
inline SharedContext(JSContext *cx, bool isFun, StrictMode sms);
// The |fun*| flags are only relevant if |inFunction()| is true.
#define INFUNC JS_ASSERT(inFunction())
inline GlobalSharedContext *asGlobal();
inline FunctionBox *asFunbox();
bool hasExplicitUseStrict() const { return cxFlags.hasExplicitUseStrict; }
bool bindingsAccessedDynamically() const { return cxFlags.bindingsAccessedDynamically; }
bool funIsGenerator() const { INFUNC; return cxFlags.funIsGenerator; }
bool funMightAliasLocals() const { INFUNC; return cxFlags.funMightAliasLocals; }
bool funHasExtensibleScope() const { INFUNC; return cxFlags.funHasExtensibleScope; }
bool funArgumentsHasLocalBinding() const { INFUNC; return cxFlags.funArgumentsHasLocalBinding; }
bool funDefinitelyNeedsArgsObj() const { INFUNC; return cxFlags.funDefinitelyNeedsArgsObj; }
bool hasExplicitUseStrict() const { return anyCxFlags.hasExplicitUseStrict; }
bool bindingsAccessedDynamically() const { return anyCxFlags.bindingsAccessedDynamically; }
void setExplicitUseStrict() { cxFlags.hasExplicitUseStrict = true; }
void setBindingsAccessedDynamically() { cxFlags.bindingsAccessedDynamically = true; }
void setFunIsGenerator() { INFUNC; cxFlags.funIsGenerator = true; }
void setFunMightAliasLocals() { INFUNC; cxFlags.funMightAliasLocals = true; }
void setFunHasExtensibleScope() { INFUNC; cxFlags.funHasExtensibleScope = true; }
void setFunArgumentsHasLocalBinding() { INFUNC; cxFlags.funArgumentsHasLocalBinding = true; }
void setFunDefinitelyNeedsArgsObj() { JS_ASSERT(cxFlags.funArgumentsHasLocalBinding);
INFUNC; cxFlags.funDefinitelyNeedsArgsObj = true; }
#undef INFUNC
bool inFunction() const { return !!funbox_; }
FunctionBox *funbox() const { JS_ASSERT(inFunction()); return funbox_; }
JSObject *scopeChain() const { JS_ASSERT(!inFunction()); return scopeChain_; }
void setExplicitUseStrict() { anyCxFlags.hasExplicitUseStrict = true; }
void setBindingsAccessedDynamically() { anyCxFlags.bindingsAccessedDynamically = true; }
// JSOPTION_STRICT warnings or strict mode errors.
inline bool needStrictChecks();
inline bool inStrictMode();
};
class GlobalSharedContext : public SharedContext
{
private:
const RootedObject scopeChain_; /* scope chain object for the script */
public:
inline GlobalSharedContext(JSContext *cx, JSObject *scopeChain, StrictMode sms);
JSObject *scopeChain() const { return scopeChain_; }
};
class FunctionBox : public SharedContext
{
public:
ObjectBox objbox;
FunctionBox *siblings;
FunctionBox *kids;
Bindings bindings; /* bindings for this function */
size_t bufStart;
size_t bufEnd;
uint16_t ndefaults;
bool inWith:1; /* some enclosing scope is a with-statement
or E4X filter-expression */
bool inGenexpLambda:1; /* lambda from generator expression */
FunctionContextFlags funCxFlags;
FunctionBox(JSContext *cx, ObjectBox* traceListHead, JSFunction *fun, ParseContext *pc,
StrictMode sms);
JSFunction *fun() const { return objbox.object->toFunction(); }
void recursivelySetStrictMode(StrictMode strictness);
bool isGenerator() const { return funCxFlags.isGenerator; }
bool mightAliasLocals() const { return funCxFlags.mightAliasLocals; }
bool hasExtensibleScope() const { return funCxFlags.hasExtensibleScope; }
bool argumentsHasLocalBinding() const { return funCxFlags.argumentsHasLocalBinding; }
bool definitelyNeedsArgsObj() const { return funCxFlags.definitelyNeedsArgsObj; }
void setIsGenerator() { funCxFlags.isGenerator = true; }
void setMightAliasLocals() { funCxFlags.mightAliasLocals = true; }
void setHasExtensibleScope() { funCxFlags.hasExtensibleScope = true; }
void setArgumentsHasLocalBinding() { funCxFlags.argumentsHasLocalBinding = true; }
void setDefinitelyNeedsArgsObj() { JS_ASSERT(funCxFlags.argumentsHasLocalBinding);
funCxFlags.definitelyNeedsArgsObj = true; }
};
/*
* NB: If you add a new type of statement that is a scope, add it between
* STMT_WITH and STMT_CATCH, or you will break StmtInfoBase::linksScope. If you
@ -283,31 +320,6 @@ struct StmtInfoBase {
}
};
struct FunctionBox : public ObjectBox
{
FunctionBox *siblings;
FunctionBox *kids;
Bindings bindings; /* bindings for this function */
size_t bufStart;
size_t bufEnd;
uint16_t ndefaults;
StrictMode strictModeState;
bool inWith:1; /* some enclosing scope is a with-statement
or E4X filter-expression */
bool inGenexpLambda:1; /* lambda from generator expression */
ContextFlags cxFlags;
FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseContext *pc,
StrictMode sms);
bool funIsGenerator() const { return cxFlags.funIsGenerator; }
JSFunction *fun() const { return (JSFunction *) object; }
void recursivelySetStrictMode(StrictMode strictness);
};
// Push the C-stack-allocated struct at stmt onto the StmtInfoPC stack.
template <class ContextT>
void

View File

@ -104,7 +104,9 @@ struct Cell
};
/*
* Page size is 4096 by default, except for SPARC, where it is 8192.
* Page size must be static to support our arena pointer optimizations, so we
* are forced to support each platform with non-4096 pages as a special case.
* Note: The freelist supports a maximum arena shift of 15.
* Note: Do not use JS_CPU_SPARC here, this header is used outside JS.
* Bug 692267: Move page size definition to gc/Memory.h and include it
* directly once jsgc.h is no longer an installed header.
@ -112,19 +114,22 @@ struct Cell
#if (defined(SOLARIS) || defined(__FreeBSD__)) && \
(defined(__sparc) || defined(__sparcv9) || defined(__ia64))
const size_t PageShift = 13;
const size_t ArenaShift = PageShift;
#elif defined(__powerpc__)
const size_t PageShift = 16;
const size_t ArenaShift = 12;
#else
const size_t PageShift = 12;
const size_t ArenaShift = PageShift;
#endif
const size_t PageSize = size_t(1) << PageShift;
const size_t ArenaSize = size_t(1) << ArenaShift;
const size_t ArenaMask = ArenaSize - 1;
const size_t ChunkShift = 20;
const size_t ChunkSize = size_t(1) << ChunkShift;
const size_t ChunkMask = ChunkSize - 1;
const size_t ArenaShift = PageShift;
const size_t ArenaSize = PageSize;
const size_t ArenaMask = ArenaSize - 1;
/*
* This is the maximum number of arenas we allow in the FreeCommitted state
* before we trigger a GC_SHRINK to release free arenas to the OS.

View File

@ -15,6 +15,15 @@
namespace js {
namespace gc {
/* Unused memory decommiting requires the arena size match the page size. */
extern const size_t PageSize;
extern const size_t ArenaSize;
static bool
DecommitEnabled()
{
return PageSize == ArenaSize;
}
#if defined(XP_WIN)
#include "jswin.h"
#include <psapi.h>
@ -83,6 +92,9 @@ UnmapPages(void *p, size_t size)
bool
MarkPagesUnused(void *p, size_t size)
{
if (!DecommitEnabled())
return false;
JS_ASSERT(uintptr_t(p) % PageSize == 0);
LPVOID p2 = VirtualAlloc(p, size, MEM_RESET, PAGE_READWRITE);
return p2 == p;
@ -352,6 +364,9 @@ UnmapPages(void *p, size_t size)
bool
MarkPagesUnused(void *p, size_t size)
{
if (!DecommitEnabled())
return false;
JS_ASSERT(uintptr_t(p) % PageSize == 0);
int result = madvise(p, size, MADV_DONTNEED);
return result != -1;

View File

@ -374,14 +374,52 @@ class Rooted : public RootedBase<T>
}
public:
Rooted() : ptr(RootMethods<T>::initial()) { init(JS::TlsRuntime); }
Rooted(const T &initial) : ptr(initial) { init(JS::TlsRuntime); }
Rooted(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
: ptr(RootMethods<T>::initial())
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
init(JS::TlsRuntime);
}
Rooted(JSRuntime *rt) : ptr(RootMethods<T>::initial()) { init(rt); }
Rooted(JSRuntime *rt, T initial) : ptr(initial) { init(rt); }
Rooted(const T &initial
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: ptr(initial)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
init(JS::TlsRuntime);
}
Rooted(JSContext *cx) : ptr(RootMethods<T>::initial()) { init(cx); }
Rooted(JSContext *cx, T initial) : ptr(initial) { init(cx); }
Rooted(JSRuntime *rt
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: ptr(RootMethods<T>::initial())
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
init(rt);
}
Rooted(JSRuntime *rt, T initial
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: ptr(initial)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
init(rt);
}
Rooted(JSContext *cx
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: ptr(RootMethods<T>::initial())
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
init(cx);
}
Rooted(JSContext *cx, T initial
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: ptr(initial)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
init(cx);
}
~Rooted()
{
@ -420,6 +458,7 @@ class Rooted : public RootedBase<T>
Rooted<T> **stack, *prev;
#endif
T ptr;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
Rooted(const Rooted &) MOZ_DELETE;
};

View File

@ -0,0 +1,22 @@
var g = true;
function getown(name)
{
if (g)
return { value: 8, enumerable: true, writable: false, configurable: true };
}
var p = Proxy.create( { getPropertyDescriptor: getown } );
var o2 = Object.create(p);
function test(x, expected) {
for (var i=0; i<3; i++) {
var v = x.hello;
if (g) assertEq(v, 8);
}
}
g = false
test(o2);
g = true;
test(o2);

View File

@ -3100,11 +3100,11 @@ ASTSerializer::identifier(ParseNode *pn, Value *dst)
bool
ASTSerializer::function(ParseNode *pn, ASTType type, Value *dst)
{
JSFunction *func = (JSFunction *)pn->pn_funbox->object;
JSFunction *func = pn->pn_funbox->fun();
bool isGenerator =
#if JS_HAS_GENERATORS
pn->pn_funbox->funIsGenerator();
pn->pn_funbox->isGenerator();
#else
false;
#endif

View File

@ -1638,7 +1638,7 @@ JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, Bytecode
script->mainOffset = prologLength;
PodCopy<jsbytecode>(script->code, bce->prologBase(), prologLength);
PodCopy<jsbytecode>(script->main(), bce->base(), mainLength);
uint32_t nfixed = bce->sc->inFunction() ? script->bindings.numVars() : 0;
uint32_t nfixed = bce->sc->isFunction ? script->bindings.numVars() : 0;
JS_ASSERT(nfixed < SLOTNO_LIMIT);
script->nfixed = uint16_t(nfixed);
InitAtomMap(cx, bce->atomIndices.getMap(), script->atoms);
@ -1656,6 +1656,8 @@ JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, Bytecode
}
script->nslots = script->nfixed + bce->maxStackDepth;
FunctionBox *funbox = bce->sc->isFunction ? bce->sc->asFunbox() : NULL;
if (!FinishTakingSrcNotes(cx, bce, script->notes()))
return false;
if (bce->tryNoteList.length() != 0)
@ -1669,31 +1671,30 @@ JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, Bytecode
script->strictModeCode = bce->sc->inStrictMode();
script->explicitUseStrict = bce->sc->hasExplicitUseStrict();
script->bindingsAccessedDynamically = bce->sc->bindingsAccessedDynamically();
script->funHasExtensibleScope =
bce->sc->inFunction() ? bce->sc->funHasExtensibleScope() : false;
script->funHasExtensibleScope = funbox ? funbox->hasExtensibleScope() : false;
script->hasSingletons = bce->hasSingletons;
#ifdef JS_METHODJIT
if (cx->compartment->debugMode())
script->debugMode = true;
#endif
if (bce->sc->inFunction()) {
if (bce->sc->funArgumentsHasLocalBinding()) {
if (funbox) {
if (funbox->argumentsHasLocalBinding()) {
// This must precede the script->bindings.transfer() call below
script->setArgumentsHasVarBinding();
if (bce->sc->funDefinitelyNeedsArgsObj())
if (funbox->definitelyNeedsArgsObj())
script->setNeedsArgsObj(true);
} else {
JS_ASSERT(!bce->sc->funDefinitelyNeedsArgsObj());
JS_ASSERT(!funbox->definitelyNeedsArgsObj());
}
}
RootedFunction fun(cx, NULL);
if (bce->sc->inFunction()) {
if (funbox) {
JS_ASSERT(!bce->script->noScriptRval);
script->isGenerator = bce->sc->funIsGenerator();
script->isGeneratorExp = bce->sc->funbox()->inGenexpLambda;
script->setFunction(bce->sc->funbox()->fun());
script->isGenerator = funbox->isGenerator();
script->isGeneratorExp = funbox->inGenexpLambda;
script->setFunction(funbox->fun());
}
/*

View File

@ -702,8 +702,12 @@ struct GetPropHelper {
* object, as lookups may extend beyond the prototype chain (e.g.
* for ListBase proxies).
*/
if (!obj->isNative())
return Lookup_Uncacheable;
JSObject *obj2 = obj;
while (obj2) {
if (!obj2->isNative())
return Lookup_Uncacheable;
obj2 = obj2->getProto();
}
#if JS_HAS_NO_SUCH_METHOD
/*

View File

@ -119,6 +119,7 @@
#include "nsRefreshDriver.h"
#include "nsRuleProcessorData.h"
#include "sampler.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -8012,6 +8013,8 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
if (!count)
return NS_OK;
SAMPLE_LABEL("CSS", "ProcessRestyledFrames");
// Make sure to not rebuild quote or counter lists while we're
// processing restyles
BeginUpdate();

View File

@ -61,6 +61,7 @@
#include "nsFrameManager.h"
#include "nsRuleProcessorData.h"
#include "sampler.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
@ -1646,6 +1647,8 @@ nsFrameManager::ComputeStyleChangeFor(nsIFrame *aFrame,
RestyleTracker& aRestyleTracker,
bool aRestyleDescendants)
{
SAMPLE_LABEL("CSS", "ComputeStyleChangeFor");
nsIContent *content = aFrame->GetContent();
if (aMinChange) {
aChangeList->AppendChange(aFrame, content, aMinChange);

View File

@ -0,0 +1,54 @@
<!DOCTYPE HTML>
<html><head>
<meta charset="utf-8">
<title>Testcase for bug 789824</title>
<style type="text/css">
html,body {
color:black; background-color:white; font-size:24px; padding:0; margin:0;
}
div { padding:5px; }
hbox {
display:-moz-box;
border-top:3px solid;
border-bottom:2px solid;
padding-bottom:4px;
background:lime;
box-sizing:content-box;
-moz-box-sizing:content-box;
}
.cb {
background:pink;
box-sizing:border-box;
-moz-box-sizing:border-box;
}
.pb {
background:cyan;
}
</style>
</head>
<body>
<div><hbox style="height:11px;">border-box 20px</hbox></div>
<div><hbox style="height:41px;">border-box 50px</hbox></div>
<div><hbox style="height:11px;">border-box 20px</hbox></div>
<div><hbox class="cb" style="height:29px;">content-box 20px</hbox></div>
<div><hbox class="cb" style="height:59px;">content-box 50px</hbox></div>
<div><hbox class="cb" style="height:29px;">content-box 20px</hbox></div>
<div><hbox class="pb" style="height:16px;">padding-box 20px</hbox></div>
<div><hbox class="pb" style="height:46px;">padding-box 50px</hbox></div>
<div><hbox class="pb" style="height:16px;">padding-box 20px</hbox></div>
</body>
</html>

View File

@ -0,0 +1,56 @@
<!DOCTYPE HTML>
<html><head>
<meta charset="utf-8">
<title>Testcase for bug 789824</title>
<style type="text/css">
html,body {
color:black; background-color:white; font-size:24px; padding:0; margin:0;
}
div { padding:5px; }
hbox {
display:-moz-box;
border-top:3px solid;
border-bottom:2px solid;
padding-bottom:4px;
height:auto;
box-sizing:border-box;
-moz-box-sizing:border-box;
background:lime;
}
.cb {
box-sizing:content-box;
-moz-box-sizing:content-box;
background:pink;
}
.pb {
box-sizing:padding-box;
-moz-box-sizing:padding-box;
background:cyan;
}
</style>
</head>
<body>
<div><hbox style="height:20px;">border-box 20px</hbox></div>
<div><hbox style="min-height:50px;">border-box 50px</hbox></div>
<div><hbox style="max-height:20px;">border-box 20px</hbox></div>
<div><hbox class="cb" style="height:20px;">content-box 20px</hbox></div>
<div><hbox class="cb" style="min-height:50px;">content-box 50px</hbox></div>
<div><hbox class="cb" style="max-height:20px;">content-box 20px</hbox></div>
<div><hbox class="pb" style="height:20px;">padding-box 20px</hbox></div>
<div><hbox class="pb" style="min-height:50px;">padding-box 50px</hbox></div>
<div><hbox class="pb" style="max-height:20px;">padding-box 20px</hbox></div>
</body>
</html>

View File

@ -18,6 +18,7 @@
== box-sizing-4.html box-sizing-4-ref.html
== box-sizing-minmax-height.html box-sizing-minmax-height-ref.html
== box-sizing-minmax-width.html box-sizing-minmax-width-ref.html
== box-sizing-mozbox-minmax-height.html box-sizing-mozbox-minmax-height-ref.html
== abspos-non-replaced-width-offset-margin.html abspos-non-replaced-width-offset-margin-ref.html
== abspos-replaced-width-offset-margin.html abspos-replaced-width-offset-margin-ref.html
HTTP(..) == CSS21-t100301.xhtml CSS21-t100301-ref.xhtml

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<table width="250" cellpadding="0" border="0" cellspacing="0">
<tr>
<td width="50" bgcolor=yellow>50
<td width="180" bgcolor=aqua>This is a cell with enough text in it to wrap.
<td width="20" bgcolor=lime><span style="display:inline-block"></span>
</table>
<table width="250" cellpadding="0" border="0" cellspacing="0">
<tr>
<td width="180" bgcolor=fuchsia>This is a cell with enough text in it to wrap.
<td width="50" bgcolor=yellow>50
<td width="20" bgcolor=lime><span style="display:inline-block"></span>
</table>

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<table width="250" cellpadding="0" border="0" cellspacing="0">
<tr>
<td width="50" bgcolor=yellow>50
<td colspan="2" bgcolor=aqua>This is a cell with enough text in it to wrap.
<td bgcolor=lime><span style="display:inline-block; width: 20px"></span>
<tr>
<td colspan="2" bgcolor=fuchsia>This is a cell with enough text in it to wrap.
<td width="50" bgcolor=yellow>50
<td bgcolor=lime><span style="display:inline-block; width: 20px"></span>
</table>

View File

@ -62,3 +62,4 @@ fails == default-box-sizing-collapse-quirks.html default-box-sizing-collapse-qui
== cell-pref-width-border-box.html cell-pref-width-border-box-ref.html
== colspan-distribute-to-empty-1a.html colspan-distribute-to-empty-1-ref.html
== colspan-distribute-to-empty-1b.html colspan-distribute-to-empty-1-ref.html
== colspan-distribute-to-empty-2.html colspan-distribute-to-empty-2-ref.html

View File

@ -0,0 +1,3 @@
<style>@\</style>
<style>@\
</style>

View File

@ -77,3 +77,4 @@ load 696188-1.html
load 700116.html
load 729126-1.html
load 729126-2.html
load 788836.html

View File

@ -728,13 +728,7 @@ nsCSSScanner::Next(nsCSSToken& aToken)
// AT_KEYWORD
if (ch == '@') {
int32_t nextChar = Read();
if (nextChar >= 0) {
int32_t followingChar = Peek();
Pushback(nextChar);
if (StartsIdent(nextChar, followingChar))
return ParseAtKeyword(ch, aToken);
}
return ParseAtKeyword(aToken);
}
// NUMBER or DIM
@ -1028,8 +1022,8 @@ nsCSSScanner::GatherIdent(int32_t aChar, nsString& aIdent)
if (!ParseAndAppendEscape(aIdent, false)) {
return false;
}
}
else if (0 < aChar) {
} else {
MOZ_ASSERT(aChar > 0);
aIdent.Append(aChar);
}
for (;;) {
@ -1065,6 +1059,7 @@ nsCSSScanner::GatherIdent(int32_t aChar, nsString& aIdent)
break;
}
}
MOZ_ASSERT(aIdent.Length() > 0);
return true;
}
@ -1124,14 +1119,21 @@ nsCSSScanner::ParseIdent(int32_t aChar, nsCSSToken& aToken)
}
bool
nsCSSScanner::ParseAtKeyword(int32_t aChar, nsCSSToken& aToken)
nsCSSScanner::ParseAtKeyword(nsCSSToken& aToken)
{
aToken.mIdent.SetLength(0);
aToken.mType = eCSSToken_AtKeyword;
if (!GatherIdent(0, aToken.mIdent)) {
aToken.mType = eCSSToken_Symbol;
aToken.mSymbol = PRUnichar('@');
int32_t ch = Read();
if (StartsIdent(ch, Peek())) {
aToken.mIdent.SetLength(0);
aToken.mType = eCSSToken_AtKeyword;
if (GatherIdent(ch, aToken.mIdent)) {
return true;
}
}
if (ch >= 0) {
Pushback(ch);
}
aToken.mType = eCSSToken_Symbol;
aToken.mSymbol = PRUnichar('@');
return true;
}

View File

@ -187,7 +187,7 @@ protected:
bool ParseAndAppendEscape(nsString& aOutput, bool aInString);
bool ParseIdent(int32_t aChar, nsCSSToken& aResult);
bool ParseAtKeyword(int32_t aChar, nsCSSToken& aResult);
bool ParseAtKeyword(nsCSSToken& aResult);
bool ParseNumber(int32_t aChar, nsCSSToken& aResult);
bool ParseRef(int32_t aChar, nsCSSToken& aResult);
bool ParseString(int32_t aChar, nsCSSToken& aResult);

View File

@ -20,10 +20,15 @@
* be explicitly specified for this property.
*
* To allow these testcases to be re-used in both horizontal and vertical
* flex containers, we specify "width"/"min-width"/etc. as "_main-size",
* "_min-main-size", etc. The test code can map these placeholder names to
* their corresponding property-names using the maps defined below --
* gHorizontalPropertyMapping and gVerticalPropertyMapping.
* flex containers, we specify "width"/"min-width"/etc. using the aliases
* "_main-size", "_min-main-size", etc. The test code can map these
* placeholder names to their corresponding property-names using the maps
* defined below -- gRowPropertyMapping, gColumnPropertyMapping, etc.
*
* If the testcase needs to customize its flex container at all (e.g. by
* specifying a custom container-size), it can do so by including a hash
* called "container_properties", with propertyName:propertyValue mappings.
* (This hash can use aliased property-names like "_main-size" as well.)
*/
// The standard main-size we'll use for our flex container when setting up
@ -296,6 +301,179 @@ var gFlexboxTestcases =
]
},
// And now, some testcases to check that we handle float accumulation error
// gracefully.
// First, a testcase with just a custom-sized huge container, to be sure we'll
// be able to handle content on that scale, in the subsequent more-complex
// testcases:
{
container_properties:
{
"_main-size": "9000000px"
},
items:
[
{
"-moz-flex": "1",
"_main-size": [ null, "9000000px" ]
},
]
},
// ...and now with two flex items dividing up that container's huge size:
{
container_properties:
{
"_main-size": "9000000px"
},
items:
[
{
"-moz-flex": "2",
"_main-size": [ null, "6000000px" ]
},
{
"-moz-flex": "1",
"_main-size": [ null, "3000000px" ]
},
]
},
// OK, now to actually test accumulation error. Below, we have six flex items
// splitting up the container's size, with huge differences between flex
// weights. For simplicity, I've set up the weights so that they sum exactly
// to the container's size in px. So 1 unit of flex *should* get you 1px.
//
// NOTE: The expected computed "_main-size" values for the flex items below
// appear to add up to more than their container's size, which would suggest
// that they overflow their container unnecessarily. But they don't actually
// overflow -- this discrepancy is simply because Gecko's code for reporting
// computed-sizes rounds to 6 significant figures (in particular, the method
// (nsTSubstring_CharT::AppendFloat() does this). Internally, in app-units,
// the child frames' main-sizes add up exactly to the container's main-size,
// as you'd hope & expect.
{
container_properties:
{
"_main-size": "9000000px"
},
items:
[
{
"-moz-flex": "3000000",
"_main-size": [ null, "3000000px" ]
},
{
"-moz-flex": "1",
"_main-size": [ null, "1px" ]
},
{
"-moz-flex": "1",
"_main-size": [ null, "1px" ]
},
{
"-moz-flex": "2999999",
// NOTE: Expected value is off slightly, from float error when
// resolving flexible lengths & when generating computed value string:
"_main-size": [ null, "3000000px" ]
},
{
"-moz-flex": "2999998",
// NOTE: Expected value is off slightly, from float error when
// resolving flexible lengths & when generating computed value string:
"_main-size": [ null, "3000000px" ]
},
{
"-moz-flex": "1",
"_main-size": [ null, "1px" ]
},
]
},
// Same flex items as previous testcase, but now reordered such that the items
// with tiny flex weights are all listed last:
{
container_properties:
{
"_main-size": "9000000px"
},
items:
[
{
"-moz-flex": "3000000",
"_main-size": [ null, "3000000px" ]
},
{
"-moz-flex": "2999999",
// NOTE: Expected value is off slightly, from float error when
// resolving flexible lengths & when generating computed value string:
"_main-size": [ null, "3000000px" ]
},
{
"-moz-flex": "2999998",
// NOTE: Expected value is off slightly, from float error when
// resolving flexible lengths & when generating computed value string:
"_main-size": [ null, "3000000px" ]
},
{
"-moz-flex": "1",
"_main-size": [ null, "1px" ]
},
{
"-moz-flex": "1",
"_main-size": [ null, "1px" ]
},
{
"-moz-flex": "1",
"_main-size": [ null, "1px" ]
},
]
},
// Same flex items as previous testcase, but now reordered such that the items
// with tiny flex weights are all listed first:
{
container_properties:
{
"_main-size": "9000000px"
},
items:
[
{
"-moz-flex": "1",
// NOTE: Expected value is off slightly, from float error when
// resolving flexible lengths:
"_main-size": [ null, "0.966667px" ]
},
{
"-moz-flex": "1",
// NOTE: Expected value is off slightly, from float error when
// resolving flexible lengths:
"_main-size": [ null, "0.983333px" ]
},
{
"-moz-flex": "1",
// NOTE: Expected value is off slightly, from float error when
// resolving flexible lengths:
"_main-size": [ null, "0.983333px" ]
},
{
"-moz-flex": "3000000",
"_main-size": [ null, "3000000px" ]
},
{
"-moz-flex": "2999999",
// NOTE: Expected value is off slightly, from float error when
// resolving flexible lengths & when generating computed value string:
"_main-size": [ null, "3000000px" ]
},
{
"-moz-flex": "2999998",
// NOTE: Expected value is off slightly, from float error when
// resolving flexible lengths & when generating computed value string:
"_main-size": [ null, "3000000px" ]
},
]
},
// Trying "flex: auto" (== "1 1 auto") w/ a mix of flex-grow/flex-basis values
{
items:

View File

@ -37,6 +37,21 @@ function getComputedStyleWrapper(elem, prop)
return window.getComputedStyle(elem, null).getPropertyValue(prop);
}
function setPossiblyAliasedProperty(aElem, aPropertyName, aPropertyValue,
aPropertyMapping)
{
let actualPropertyName = (aPropertyName in aPropertyMapping ?
aPropertyMapping[aPropertyName] : aPropertyName);
if (!gCSSProperties[actualPropertyName]) {
ok(false, "Bug in test: property '" + actualPropertyName +
"' doesn't exist in gCSSProperties");
} else {
let domPropertyName = gCSSProperties[actualPropertyName].domProp;
aElem.style[domPropertyName] = aPropertyValue;
}
}
// The main test function.
// aFlexboxTestcase is an entry from the list in flexbox_layout_testcases.js
function testFlexboxTestcase(aFlexboxTestcase, aFlexDirection, aPropertyMapping)
@ -46,10 +61,17 @@ function testFlexboxTestcase(aFlexboxTestcase, aFlexDirection, aPropertyMapping)
// Create flex container
let flexContainer = document.createElement("div");
flexContainer.style.display = "-moz-flex";
flexContainer.style[aPropertyMapping["_main-size"]] = gDefaultFlexContainerSize;
flexContainer.style.MozFlexDirection = aFlexDirection;
setPossiblyAliasedProperty(flexContainer, "_main-size", gDefaultFlexContainerSize, aPropertyMapping);
// Apply testcase's customizations for flex container (if any).
if (aFlexboxTestcase.container_properties) {
for (let propName in aFlexboxTestcase.container_properties) {
let propValue = aFlexboxTestcase.container_properties[propName];
setPossiblyAliasedProperty(flexContainer, propName, propValue,
aPropertyMapping);
}
}
// Create & append flex items
aFlexboxTestcase.items.forEach(function(aChildSpec) {
@ -70,14 +92,9 @@ function testFlexboxTestcase(aFlexboxTestcase, aFlexDirection, aPropertyMapping)
"unexpected number of elements in array within child spec");
}
let actualPropName = (propName in aPropertyMapping ?
aPropertyMapping[propName] : propName);
if (!gCSSProperties[actualPropName]) {
ok(false, "Bug in test: property '" + actualPropName +
"' doesn't exist in gCSSProperties");
} else if (specifiedValue !== null) {
let domPropName = gCSSProperties[actualPropName].domProp;
child.style[domPropName] = specifiedValue;
if (specifiedValue !== null) {
setPossiblyAliasedProperty(child, propName, specifiedValue,
aPropertyMapping);
}
}

View File

@ -675,22 +675,14 @@ nsBoxFrame::Reflow(nsPresContext* aPresContext,
if (aReflowState.ComputedHeight() == NS_INTRINSICSIZE) {
computedSize.height = prefSize.height;
// prefSize is border-box, so we need to figure out the right
// length to apply our min/max constraints to.
nscoord outsideBoxSizing = 0;
switch (GetStylePosition()->mBoxSizing) {
case NS_STYLE_BOX_SIZING_CONTENT:
outsideBoxSizing = aReflowState.mComputedBorderPadding.TopBottom();
// fall through
case NS_STYLE_BOX_SIZING_PADDING:
outsideBoxSizing -= aReflowState.mComputedPadding.TopBottom();
break;
}
computedSize.height -= outsideBoxSizing;
// Note: might be negative now, but that's OK because min-width is
// never negative.
computedSize.height = aReflowState.ApplyMinMaxHeight(computedSize.height);
computedSize.height += outsideBoxSizing;
// prefSize is border-box but min/max constraints are content-box.
nscoord verticalBorderPadding =
aReflowState.mComputedBorderPadding.TopBottom();
nscoord contentHeight = computedSize.height - verticalBorderPadding;
// Note: contentHeight might be negative, but that's OK because min-height
// is never negative.
computedSize.height = aReflowState.ApplyMinMaxHeight(contentHeight) +
verticalBorderPadding;
} else {
computedSize.height += m.top + m.bottom;
}

19
python/mozboot/README.rst Normal file
View File

@ -0,0 +1,19 @@
mozboot - Bootstrap your system to build Mozilla projects
=========================================================
This package contains code used for bootstrapping a system to build
mozilla-central.
This code is not part of the build system per se. Instead, it is related
to everything up to invoking the actual build system.
If you have a copy of the source tree, you run:
python bin/bootstrap.py
If you don't have a copy of the source tree, you can run:
curl https://hg.mozilla.org/mozilla-central/raw-file/default/python/mozboot/bin/bootstrap.py | python -
The bootstrap script will download everything it needs from hg.mozilla.org
automatically!

134
python/mozboot/bin/bootstrap.py Executable file
View File

@ -0,0 +1,134 @@
#!/usr/bin/env python
# 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/.
# This script provides one-line bootstrap support to configure systems to build
# the tree.
#
# The role of this script is to load the Python modules containing actual
# bootstrap support. It does this through various means, including fetching
# content from the upstream source repository.
from __future__ import print_function, unicode_literals
import os
import shutil
import sys
import tempfile
import urllib2
from optparse import OptionParser
# The next two variables define where in the repository the Python files
# reside. This is used to remotely download file content when it isn't
# available locally.
REPOSITORY_PATH_PREFIX = 'python/mozboot'
REPOSITORY_PATHS = [
'mozboot/__init__.py',
'mozboot/base.py',
'mozboot/bootstrap.py',
'mozboot/centos.py',
'mozboot/fedora.py',
'mozboot/mint.py',
'mozboot/osx.py',
'mozboot/ubuntu.py',
]
TEMPDIR = None
def fetch_files(repo_url, repo_type):
repo_url = repo_url.rstrip('/')
files = {}
if repo_type == 'hgweb':
for path in REPOSITORY_PATHS:
url = repo_url + '/raw-file/default/python/mozboot/' + path
req = urllib2.urlopen(url=url, timeout=30)
files[path] = req.read()
else:
raise NotImplementedError('Not sure how to handle repo type.', repo_type)
return files
def ensure_environment(repo_url=None, repo_type=None):
"""Ensure we can load the Python modules necessary to perform bootstrap."""
try:
from mozboot.bootstrap import Bootstrapper
return Bootstrapper
except ImportError:
# The first fallback is to assume we are running from a tree checkout
# and have the files in a sibling directory.
pardir = os.path.join(os.path.dirname(__file__), os.path.pardir)
include = os.path.normpath(pardir)
sys.path.append(include)
try:
from mozboot.bootstrap import Bootstrapper
return Bootstrapper
except ImportError:
sys.path.pop()
# The next fallback is to download the files from the source
# repository.
files = fetch_files(repo_url, repo_type)
# Install them into a temporary location. They will be deleted
# after this script has finished executing.
global TEMPDIR
TEMPDIR = tempfile.mkdtemp()
for relpath in files.keys():
destpath = os.path.join(TEMPDIR, relpath)
destdir = os.path.dirname(destpath)
if not os.path.exists(destdir):
os.makedirs(destdir)
with open(destpath, 'wb') as fh:
fh.write(files[relpath])
# This should always work.
sys.path.append(TEMPDIR)
from mozboot.bootstrap import Bootstrapper
return Bootstrapper
def main(args):
parser = OptionParser()
parser.add_option('-r', '--repo-url', dest='repo_url',
default='https://hg.mozilla.org/mozilla-central/',
help='Base URL of source control repository where bootstrap files can '
'be downloaded.')
parser.add_option('--repo-type', dest='repo_type',
default='hgweb',
help='The type of the repository. This defines how we fetch file '
'content. Like --repo, you should not need to set this.')
options, leftover = parser.parse_args(args)
try:
try:
cls = ensure_environment(options.repo_url, options.repo_type)
except Exception as e:
print('Could not load the bootstrap Python environment.\n')
print('This should never happen. Consider filing a bug.\n')
print('\n')
print(e)
return 1
dasboot = cls()
dasboot.bootstrap()
return 0
finally:
if TEMPDIR is not None:
shutil.rmtree(TEMPDIR)
if __name__ == '__main__':
sys.exit(main(sys.argv))

View File

View File

@ -0,0 +1,12 @@
# 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/.
class BaseBootstrapper(object):
"""Base class for system bootstrappers."""
def __init__(self):
pass
def install_system_packages(self):
raise NotImplemented('%s must implement install_system_packages()' %
__name__)

View File

@ -0,0 +1,54 @@
# 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/.
import platform
import sys
from mozboot.centos import CentOSBootstrapper
from mozboot.fedora import FedoraBootstrapper
from mozboot.mint import MintBootstrapper
from mozboot.osx import OSXBootstrapper
from mozboot.ubuntu import UbuntuBootstrapper
class Bootstrapper(object):
"""Main class that performs system bootstrap."""
def bootstrap(self):
cls = None
args = {}
if sys.platform.startswith('linux'):
distro, version, dist_id = platform.linux_distribution()
if distro == 'CentOS':
cls = CentOSBootstrapper
elif distro == 'Fedora':
cls = FedoraBootstrapper
elif distro == 'Mint':
cls = MintBootstrapper
elif distro == 'Ubuntu':
cls = UbuntuBootstrapper
else:
raise NotImplementedError('Bootstrap support for this Linux '
'distro not yet available.')
args['version'] = version
args['dist_id'] = dist_id
elif sys.platform.startswith('darwin'):
# TODO Support Darwin platforms that aren't OS X.
major, minor, point = map(int, platform.mac_ver()[0].split('.'))
cls = OSXBootstrapper
args['major'] = major
args['minor'] = minor
args['point'] = point
if cls is None:
raise NotImplementedError('Bootstrap support is not yet available '
'for your OS.')
instance = cls(**args)
instance.install_system_packages()

View File

@ -0,0 +1,30 @@
# 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/.
import os
import platform
from mozboot.base import BaseBootstrapper
class CentOSBootstrapper(BaseBootstrapper):
def __init__(self, version, dist_id):
BaseBootstrapper.__init__(self)
self.version = version
self.dist_id = dist_id
def install_system_packages(self):
kern = platform.uname()
os.system("sudo yum groupinstall 'Development Tools' 'Development Libraries' 'GNOME Software Development'")
os.system("sudo yum install mercurial autoconf213 glibc-static libstdc++-static yasm wireless-tools-devel mesa-libGL-devel alsa-lib-devel libXt-devel")
os.system("sudo yum install gtk2-devel")
os.system("sudo yum install dbus-glib-devel")
if ('x86_64' in kern[2]):
os.system("sudo rpm -ivh http://pkgs.repoforge.org/yasm/yasm-1.1.0-1.el6.rf.x86_64.rpm")
else:
os.system("sudo rpm -ivh http://pkgs.repoforge.org/yasm/yasm-1.1.0-1.el6.rf.i686.rpm")
os.system("sudo yum install curl-devel")

View File

@ -0,0 +1,18 @@
# 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/.
import os
from mozboot.base import BaseBootstrapper
class FedoraBootstrapper(BaseBootstrapper):
def __init__(self, version, dist_id):
BaseBootstrapper.__init__(self)
self.version = version
self.dist_id = dist_id
def install_system_packages(self):
os.system("sudo yum groupinstall 'Development Tools' 'Development Libraries' 'GNOME Software Development'")
os.system("sudo yum install mercurial autoconf213 glibc-static libstdc++-static yasm wireless-tools-devel mesa-libGL-devel alsa-lib-devel libXt-devel")

View File

@ -0,0 +1,18 @@
# 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/.
import os
from mozboot.base import BaseBootstrapper
class MintBootstrapper(BaseBootstrapper):
def __init__(self, version, dist_id):
BaseBootstrapper.__init__(self)
self.version = version
self.dist_id = dist_id
def install_system_packages(self):
os.system("sudo apt-get build-dep firefox")
os.system("sudo apt-get install mercurial libasound2-dev libcurl4-openssl-dev libnotify-dev libxt-dev libiw-dev mesa-common-dev autoconf2.13 yasm uuid")

View File

@ -0,0 +1,17 @@
# 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/.
from mozboot.base import BaseBootstrapper
class OSXBootstrapper(BaseBootstrapper):
def __init__(self, major, minor, point):
BaseBootstrapper.__init__(self)
if major == 10 and minor < 6:
raise Exception('OS X 10.6 or above is required.')
def install_system_packages(self):
raise NotImplementedError('OS X bootstrap not yet implemented.')

View File

@ -0,0 +1,18 @@
# 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/.
import os
from mozboot.base import BaseBootstrapper
class UbuntuBootstrapper(BaseBootstrapper):
def __init__(self, version, dist_id):
BaseBootstrapper.__init__(self)
self.version = version
self.dist_id = dist_id
def install_system_packages(self):
os.system("sudo apt-get build-dep firefox")
os.system("sudo apt-get install mercurial libasound2-dev libcurl4-openssl-dev libnotify-dev libxt-dev libiw-dev mesa-common-dev autoconf2.13 yasm uuid")

16
python/mozboot/setup.py Normal file
View File

@ -0,0 +1,16 @@
# 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/.
from distutils.core import setup
VERSION = '0.1'
setup(
name='mozboot',
description='System bootstrap for building Mozilla projects.',
license='MPL 2.0',
packages=['mozboot'],
version=VERSION,
scripts=['bin/bootstrap.py'],
)

View File

@ -8,9 +8,6 @@
Mozilla universal manifest parser
"""
# this file lives at
# http://hg.mozilla.org/automation/ManifestDestiny/raw-file/tip/manifestparser.py
__all__ = ['read_ini', # .ini reader
'ManifestParser', 'TestManifest', 'convert', # manifest handling
'parse', 'ParseError', 'ExpressionParser'] # conditional expression parser
@ -436,15 +433,15 @@ class ManifestParser(object):
# determine the path
path = test.get('path', section)
relpath = path
_relpath = path
if '://' not in path: # don't futz with URLs
path = normalize_path(path)
if not os.path.isabs(path):
path = os.path.join(here, path)
relpath = os.path.relpath(path, self.rootdir)
_relpath = relpath(path, self.rootdir)
test['path'] = path
test['relpath'] = relpath
test['relpath'] = _relpath
# append the item
self.tests.append(test)

View File

@ -14,7 +14,7 @@ except:
description = ''
PACKAGE_NAME = "ManifestDestiny"
PACKAGE_VERSION = '0.5.5'
PACKAGE_VERSION = '0.5.6'
setup(name=PACKAGE_NAME,
version=PACKAGE_VERSION,

View File

View File

View File

@ -1,60 +0,0 @@
# 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/.
import os
import posixpath
from dmunit import DeviceManagerTestCase
class UnzipTestCase(DeviceManagerTestCase):
def runTest(self):
""" This tests unzipping a file on the device.
"""
testroot = posixpath.join(self.dm.getDeviceRoot(), 'infratest')
self.dm.removeDir(testroot)
self.dm.mkDir(testroot)
self.assert_(self.dm.pushFile(
os.path.join('test-files', 'mybinary.zip'),
posixpath.join(testroot, 'mybinary.zip')))
self.assertNotEqual(self.dm.unpackFile(
posixpath.join(testroot, 'mybinary.zip')), None)
# the mybinary.zip file has the zipped up contents of test-files/push2
# so we validate it the same as test_push2.
self.assert_(self.dm.dirExists(
posixpath.join(testroot, 'push2', 'sub1')))
self.assert_(self.dm.validateFile(
posixpath.join(testroot, 'push2', 'sub1', 'file1.txt'),
os.path.join('test-files', 'push2', 'sub1', 'file1.txt')))
self.assert_(self.dm.validateFile(
posixpath.join(testroot, 'push2', 'sub1', 'sub1.1', 'file2.txt'),
os.path.join('test-files', 'push2', 'sub1', 'sub1.1', 'file2.txt')))
self.assert_(self.dm.validateFile(
posixpath.join(testroot, 'push2', 'sub2', 'file3.txt'),
os.path.join('test-files', 'push2', 'sub2', 'file3.txt')))
self.assert_(self.dm.validateFile(
posixpath.join(testroot, 'push2', 'file4.bin'),
os.path.join('test-files', 'push2', 'file4.bin')))
# test dest_dir param
newdir = posixpath.join(testroot, 'newDir')
self.dm.mkDir(newdir)
self.assertNotEqual(self.dm.unpackFile(
posixpath.join(testroot, 'mybinary.zip'), newdir), None)
self.assert_(self.dm.dirExists(posixpath.join(newdir, 'push2', 'sub1')))
self.assert_(self.dm.validateFile(
posixpath.join(newdir, 'push2', 'sub1', 'file1.txt'),
os.path.join('test-files', 'push2', 'sub1', 'file1.txt')))
self.assert_(self.dm.validateFile(
posixpath.join(newdir, 'push2', 'sub1', 'sub1.1', 'file2.txt'),
os.path.join('test-files', 'push2', 'sub1', 'sub1.1', 'file2.txt')))
self.assert_(self.dm.validateFile(
posixpath.join(newdir, 'push2', 'sub2', 'file3.txt'),
os.path.join('test-files', 'push2', 'sub2', 'file3.txt')))
self.assert_(self.dm.validateFile(
posixpath.join(newdir, 'push2', 'file4.bin'),
os.path.join('test-files', 'push2', 'file4.bin')))

0
testing/mozbase/mozinstall/mozinstall/mozinstall.py Normal file → Executable file
View File

0
testing/mozbase/mozprocess/tests/mozprocess1.py Normal file → Executable file
View File

0
testing/mozbase/mozprocess/tests/mozprocess2.py Normal file → Executable file
View File

0
testing/mozbase/mozprofile/mozprofile/cli.py Normal file → Executable file
View File

0
testing/mozbase/mozprofile/tests/addonid.py Normal file → Executable file
View File

0
testing/mozbase/mozprofile/tests/bug758250.py Normal file → Executable file
View File

0
testing/mozbase/mozprofile/tests/test_nonce.py Normal file → Executable file
View File

0
testing/mozbase/mozprofile/tests/test_preferences.py Normal file → Executable file
View File

0
testing/mozbase/mozrunner/mozrunner/runner.py Normal file → Executable file
View File

0
testing/mozbase/test.py Normal file → Executable file
View File

View File

@ -328,6 +328,7 @@ else
#building tests.jar (bug 543800) fails on unify, so we build tests.jar after unify is run
$(MAKE) -C $(DEPTH)/testing/mochitest stage-chromejar PKG_STAGE=$(DIST)/universal
endif
find $(PKG_STAGE) -name "*.pyc" -exec rm {} \;
cd $(PKG_STAGE) && \
zip -rq9D "$(call core_abspath,$(DIST)/$(PKG_PATH)$(TEST_PACKAGE))" \
* -x \*/.mkdir.done

View File

@ -130,6 +130,13 @@ FrameWorker.prototype = {
};
sandbox.navigator = navigator;
// Our importScripts function needs to 'eval' the script code from inside
// a function, but using eval() directly means functions in the script
// don't end up in the global scope.
sandbox._evalInSandbox = function(s) {
Cu.evalInSandbox(s, sandbox);
};
// and we delegate ononline and onoffline events to the worker.
// See http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workerglobalscope
this.frame.addEventListener('offline', function fw_onoffline(event) {

View File

@ -32,7 +32,7 @@ function importScripts() {
xhr.onreadystatechange = function(aEvt) {
if (xhr.readyState == 4) {
if (xhr.status == 200 || xhr.status == 0) {
eval(xhr.responseText);
_evalInSandbox(xhr.responseText);
}
else {
throw new Error("Unable to importScripts ["+scriptURL+"], status " + xhr.status)

View File

@ -1 +1,6 @@
dump("relative_import file\n");
testVar = "oh hai";
function testFunc() {
return "oh hai";
}

View File

@ -4,7 +4,12 @@ onconnect = function(e) {
let req;
try {
importScripts("relative_import.js");
port.postMessage({topic: "done", result: "ok"});
// the import should have exposed "testVar" and "testFunc" from the module.
if (testVar == "oh hai" && testFunc() == "oh hai") {
port.postMessage({topic: "done", result: "ok"});
} else {
port.postMessage({topic: "done", result: "import worked but global is not available"});
}
} catch(e) {
port.postMessage({topic: "done", result: "FAILED to importScripts, " + e.toString() });
return;

View File

@ -50,18 +50,41 @@
#include <sys/syscall.h>
#endif
#ifdef XP_MACOSX
#include <sys/sysctl.h>
#endif
#ifdef __OpenBSD__
#if defined(XP_MACOSX) || defined(__DragonFly__) || defined(__FreeBSD__) \
|| defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/param.h>
#include <sys/sysctl.h>
#endif
#if defined(__DragonFly__) || defined(__FreeBSD__)
#include <sys/user.h>
#endif
#include "mozilla/Telemetry.h"
#include "mozilla/StartupTimeline.h"
#if defined(__NetBSD__)
#undef KERN_PROC
#define KERN_PROC KERN_PROC2
#define KINFO_PROC struct kinfo_proc2
#else
#define KINFO_PROC struct kinfo_proc
#endif
#if defined(XP_MACOSX)
#define KP_START_SEC kp_proc.p_un.__p_starttime.tv_sec
#define KP_START_USEC kp_proc.p_un.__p_starttime.tv_usec
#elif defined(__DragonFly__)
#define KP_START_SEC kp_start.tv_sec
#define KP_START_USEC kp_start.tv_usec
#elif defined(__FreeBSD__)
#define KP_START_SEC ki_start.tv_sec
#define KP_START_USEC ki_start.tv_usec
#else
#define KP_START_SEC p_ustart_sec
#define KP_START_USEC p_ustart_usec
#endif
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
#define kPrefLastSuccess "toolkit.startup.last_success"
@ -836,42 +859,30 @@ CalculateProcessCreationTimestamp()
#endif
return timestamp;
}
#elif defined(XP_MACOSX)
#elif defined(XP_MACOSX) || defined(__DragonFly__) || defined(__FreeBSD__) \
|| defined(__NetBSD__) || defined(__OpenBSD__)
static PRTime
CalculateProcessCreationTimestamp()
{
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() };
size_t buffer_size;
if (sysctl(mib, 4, NULL, &buffer_size, NULL, 0))
int mib[] = {
CTL_KERN,
KERN_PROC,
KERN_PROC_PID,
getpid(),
#if defined(__NetBSD__) || defined(__OpenBSD__)
sizeof(KINFO_PROC),
1,
#endif
};
u_int miblen = sizeof(mib) / sizeof(mib[0]);
KINFO_PROC proc;
size_t buffer_size = sizeof(proc);
if (sysctl(mib, miblen, &proc, &buffer_size, NULL, 0))
return 0;
struct kinfo_proc *proc = (kinfo_proc*) malloc(buffer_size);
if (sysctl(mib, 4, proc, &buffer_size, NULL, 0)) {
free(proc);
return 0;
}
PRTime starttime = static_cast<PRTime>(proc->kp_proc.p_un.__p_starttime.tv_sec) * PR_USEC_PER_SEC;
starttime += proc->kp_proc.p_un.__p_starttime.tv_usec;
free(proc);
return starttime;
}
#elif defined(__OpenBSD__)
static PRTime
CalculateProcessCreationTimestamp()
{
int mib[6] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid(), sizeof(struct kinfo_proc), 1 };
size_t buffer_size;
if (sysctl(mib, 6, NULL, &buffer_size, NULL, 0))
return 0;
struct kinfo_proc *proc = (struct kinfo_proc*) malloc(buffer_size);
if (sysctl(mib, 6, proc, &buffer_size, NULL, 0)) {
free(proc);
return 0;
}
PRTime starttime = static_cast<PRTime>(proc->p_ustart_sec) * PR_USEC_PER_SEC;
starttime += proc->p_ustart_usec;
free(proc);
PRTime starttime = static_cast<PRTime>(proc.KP_START_SEC) * PR_USEC_PER_SEC;
starttime += proc.KP_START_USEC;
return starttime;
}
#else

View File

@ -42,7 +42,7 @@ const PREF_APP_UPDATE_POSTUPDATE = "app.update.postupdate";
const PREF_APP_UPDATE_PROMPTWAITTIME = "app.update.promptWaitTime";
const PREF_APP_UPDATE_SHOW_INSTALLED_UI = "app.update.showInstalledUI";
const PREF_APP_UPDATE_SILENT = "app.update.silent";
const PREF_APP_UPDATE_STAGE_ENABLED = "app.update.stage.enabled";
const PREF_APP_UPDATE_STAGE_ENABLED = "app.update.staging.enabled";
const PREF_APP_UPDATE_URL = "app.update.url";
const PREF_APP_UPDATE_URL_DETAILS = "app.update.url.details";
const PREF_APP_UPDATE_URL_OVERRIDE = "app.update.url.override";

View File

@ -12,7 +12,7 @@ const AUS_Cr = Components.results;
const AUS_Cu = Components.utils;
const PREF_APP_UPDATE_AUTO = "app.update.auto";
const PREF_APP_UPDATE_STAGE_ENABLED = "app.update.stage.enabled";
const PREF_APP_UPDATE_STAGE_ENABLED = "app.update.staging.enabled";
const PREF_APP_UPDATE_BACKGROUNDERRORS = "app.update.backgroundErrors";
const PREF_APP_UPDATE_BACKGROUNDMAXERRORS = "app.update.backgroundMaxErrors";
const PREF_APP_UPDATE_CERTS_BRANCH = "app.update.certs.";

View File

@ -1089,8 +1089,9 @@ void mozilla_sampler_start(int aProfileEntries, int aInterval,
mozilla_sampler_stop();
TableTicker *t = new TableTicker(aInterval, aProfileEntries, stack,
aFeatures, aFeatureCount);
TableTicker *t = new TableTicker(aInterval ? aInterval : PROFILE_DEFAULT_INTERVAL,
aProfileEntries ? aProfileEntries : PROFILE_DEFAULT_ENTRY,
stack, aFeatures, aFeatureCount);
tlsTicker.set(t);
t->Start();
if (t->ProfileJS())

View File

@ -476,6 +476,9 @@ static nsExtraMimeTypeEntry extraMimeEntries [] =
{ AUDIO_OGG, "opus", "Opus Audio" },
{ VIDEO_WEBM, "webm", "Web Media Video" },
{ AUDIO_WEBM, "webm", "Web Media Audio" },
#ifdef MOZ_MEDIA_PLUGINS
{ AUDIO_MP3, "mp3", "MPEG Audio" },
#endif
{ VIDEO_MP4, "mp4", "MPEG-4 Video" },
{ VIDEO_RAW, "yuv", "Raw YUV Video" },
{ AUDIO_WAV, "wav", "Waveform Audio" }

File diff suppressed because it is too large Load Diff

View File

@ -155,6 +155,19 @@ protected:
bool Create(nsWindow*, IMEState::Enabled);
bool Destroy(void);
bool IsReadLock(DWORD aLock) const
{
return (TS_LF_READ == (aLock & TS_LF_READ));
}
bool IsReadWriteLock(DWORD aLock) const
{
return (TS_LF_READWRITE == (aLock & TS_LF_READWRITE));
}
bool IsReadLocked() const { return IsReadLock(mLock); }
bool IsReadWriteLocked() const { return IsReadWriteLock(mLock); }
bool GetScreenExtInternal(RECT &aScreenExt);
bool GetSelectionInternal(TS_SELECTION_ACP &aSelectionACP);
// If aDispatchTextEvent is true, this method will dispatch text event if
// this is called during IME composing. aDispatchTextEvent should be true
// only when this is called from SetSelection. Because otherwise, the text

View File

@ -475,10 +475,17 @@ PuppetWidget::OnIMESelectionChange(void)
NS_IMETHODIMP
PuppetWidget::SetCursor(nsCursor aCursor)
{
if (mCursor == aCursor) {
return NS_OK;
}
if (!mTabChild ||
!mTabChild->SendSetCursor(aCursor)) {
return NS_ERROR_FAILURE;
}
mCursor = aCursor;
return NS_OK;
}