mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge last PGO-green changeset of mozilla-inbound to mozilla-central
This commit is contained in:
commit
4161cb07c2
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -168,6 +168,7 @@ MOCHITEST_FILES += \
|
||||
448636.ogv \
|
||||
audio-overhang.ogg \
|
||||
audio-gaps.ogg \
|
||||
badtags.ogg \
|
||||
beta-phrasebook.ogg \
|
||||
bogus.ogv \
|
||||
bug495129.ogv \
|
||||
|
BIN
content/media/test/badtags.ogg
Normal file
BIN
content/media/test/badtags.ogg
Normal file
Binary file not shown.
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
22
js/src/jit-test/tests/basic/bug787847.js
Normal file
22
js/src/jit-test/tests/basic/bug787847.js
Normal 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);
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
/*
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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>
|
@ -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>
|
@ -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
|
||||
|
@ -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>
|
@ -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>
|
@ -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
|
||||
|
3
layout/style/crashtests/788836.html
Normal file
3
layout/style/crashtests/788836.html
Normal file
@ -0,0 +1,3 @@
|
||||
<style>@\</style>
|
||||
<style>@\
|
||||
</style>
|
@ -77,3 +77,4 @@ load 696188-1.html
|
||||
load 700116.html
|
||||
load 729126-1.html
|
||||
load 729126-2.html
|
||||
load 788836.html
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
19
python/mozboot/README.rst
Normal 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
134
python/mozboot/bin/bootstrap.py
Executable 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))
|
0
python/mozboot/mozboot/__init__.py
Normal file
0
python/mozboot/mozboot/__init__.py
Normal file
12
python/mozboot/mozboot/base.py
Normal file
12
python/mozboot/mozboot/base.py
Normal 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__)
|
54
python/mozboot/mozboot/bootstrap.py
Normal file
54
python/mozboot/mozboot/bootstrap.py
Normal 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()
|
30
python/mozboot/mozboot/centos.py
Normal file
30
python/mozboot/mozboot/centos.py
Normal 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")
|
||||
|
18
python/mozboot/mozboot/fedora.py
Normal file
18
python/mozboot/mozboot/fedora.py
Normal 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")
|
18
python/mozboot/mozboot/mint.py
Normal file
18
python/mozboot/mozboot/mint.py
Normal 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")
|
17
python/mozboot/mozboot/osx.py
Normal file
17
python/mozboot/mozboot/osx.py
Normal 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.')
|
||||
|
||||
|
18
python/mozboot/mozboot/ubuntu.py
Normal file
18
python/mozboot/mozboot/ubuntu.py
Normal 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
16
python/mozboot/setup.py
Normal 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'],
|
||||
)
|
@ -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)
|
||||
|
@ -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,
|
||||
|
0
testing/mozbase/manifestdestiny/tests/test_expressionparser.py
Normal file → Executable file
0
testing/mozbase/manifestdestiny/tests/test_expressionparser.py
Normal file → Executable file
0
testing/mozbase/manifestdestiny/tests/test_manifestparser.py
Normal file → Executable file
0
testing/mozbase/manifestdestiny/tests/test_manifestparser.py
Normal file → Executable 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
0
testing/mozbase/mozinstall/mozinstall/mozinstall.py
Normal file → Executable file
0
testing/mozbase/mozprocess/tests/mozprocess1.py
Normal file → Executable file
0
testing/mozbase/mozprocess/tests/mozprocess1.py
Normal file → Executable file
0
testing/mozbase/mozprocess/tests/mozprocess2.py
Normal file → Executable file
0
testing/mozbase/mozprocess/tests/mozprocess2.py
Normal file → Executable file
0
testing/mozbase/mozprofile/mozprofile/cli.py
Normal file → Executable file
0
testing/mozbase/mozprofile/mozprofile/cli.py
Normal file → Executable file
0
testing/mozbase/mozprofile/tests/addonid.py
Normal file → Executable file
0
testing/mozbase/mozprofile/tests/addonid.py
Normal file → Executable file
0
testing/mozbase/mozprofile/tests/bug758250.py
Normal file → Executable file
0
testing/mozbase/mozprofile/tests/bug758250.py
Normal file → Executable file
0
testing/mozbase/mozprofile/tests/test_nonce.py
Normal file → Executable file
0
testing/mozbase/mozprofile/tests/test_nonce.py
Normal file → Executable file
0
testing/mozbase/mozprofile/tests/test_preferences.py
Normal file → Executable file
0
testing/mozbase/mozprofile/tests/test_preferences.py
Normal file → Executable file
0
testing/mozbase/mozrunner/mozrunner/runner.py
Normal file → Executable file
0
testing/mozbase/mozrunner/mozrunner/runner.py
Normal file → Executable file
0
testing/mozbase/moztest/moztest/__init__.py
Normal file
0
testing/mozbase/moztest/moztest/__init__.py
Normal file
0
testing/mozbase/moztest/moztest/output/__init__.py
Normal file
0
testing/mozbase/moztest/moztest/output/__init__.py
Normal file
0
testing/mozbase/test.py
Normal file → Executable file
0
testing/mozbase/test.py
Normal file → Executable 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
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -1 +1,6 @@
|
||||
dump("relative_import file\n");
|
||||
|
||||
testVar = "oh hai";
|
||||
function testFunc() {
|
||||
return "oh hai";
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
@ -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.";
|
||||
|
@ -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())
|
||||
|
@ -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
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user