Merge latest green b2g-inbound changeset and mozilla-central

This commit is contained in:
Ed Morley 2013-09-03 12:11:50 +01:00
commit fec4af2855
103 changed files with 1536 additions and 3578 deletions

View File

@ -223,7 +223,8 @@ if test "$GNU_CC"; then
CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections"
fi
CXXFLAGS="$CXXFLAGS -fno-exceptions"
CFLAGS="$CFLAGS -fno-math-errno"
CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-math-errno"
fi
dnl ========================================================

View File

@ -9227,19 +9227,32 @@ fi
dist=$MOZ_BUILD_ROOT/dist
ac_configure_args="$_SUBDIR_CONFIG_ARGS"
ac_configure_args="$ac_configure_args --enable-threadsafe"
MOZ_ARG_WITH_STRING(intl-api,
[ --with-intl-api, --with-intl-api=build, --without-intl-api
Determine the status of the ECMAScript Internationalization API. The first
(or lack of any of these) builds and exposes the API. The second builds it
but doesn't use ICU or expose the API to script. The third doesn't build
ICU at all.],
WITH_INTL="--with-intl-api=$withval"
])
if test -z "$WITH_INTL"; then
if test "$NIGHTLY_BUILD" = "1" -a "$MOZ_BUILD_APP" = "browser"; then
# In desktop nightlies the Internationalization API is disabled, but all
# code for it is still built. Bug 853301 will remove this so that it's
# built and the API is enabled.
ac_configure_args="$ac_configure_args --with-intl-api=build"
WITH_INTL="--with-intl-api=build"
else
# Internationalization isn't built or exposed by default in non-desktop and
# non-nightly builds. Bugs to enable:
#
# Android: bug 864843
# B2G: bug 866301
ac_configure_args="$ac_configure_args --without-intl-api"
WITH_INTL="--without-intl-api"
fi
fi
ac_configure_args="$ac_configure_args $WITH_INTL"
if test "$BUILD_CTYPES"; then
# Build js-ctypes on the platforms we can.
ac_configure_args="$ac_configure_args --enable-ctypes"

View File

@ -149,6 +149,7 @@ protected:
nsString mContentType;
nsString mName;
nsString mPath; // The path relative to a directory chosen by the user
uint64_t mStart;
uint64_t mLength;
@ -300,6 +301,8 @@ public:
NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
NS_IMETHOD GetInternalStream(nsIInputStream**) MOZ_OVERRIDE;
void SetPath(const nsAString& aFullPath);
protected:
// Create slice
nsDOMFileFile(const nsDOMFileFile* aOther, uint64_t aStart, uint64_t aLength,

View File

@ -59,11 +59,13 @@ interface nsIDOMBlob : nsISupports
[notxpcom] FileInfo getFileInfo(in FileManager aFileManager);
};
[scriptable, builtinclass, uuid(6928584d-7d87-4d56-9ce1-1c89c24f2c6a)]
[scriptable, builtinclass, uuid(0acb4135-9f79-4516-ba92-b5fba5203620)]
interface nsIDOMFile : nsIDOMBlob
{
readonly attribute DOMString name;
readonly attribute DOMString path;
[implicit_jscontext]
readonly attribute jsval lastModifiedDate;

View File

@ -299,6 +299,16 @@ public:
mMatchNameSpaceId == aKey.mMatchNameSpaceId;
}
/**
* Sets the state to LIST_DIRTY and clears mElements array.
* @note This is the only acceptable way to set state to LIST_DIRTY.
*/
void SetDirty()
{
mState = LIST_DIRTY;
Reset();
}
protected:
/**
* Returns whether the element matches our criterion
@ -350,16 +360,6 @@ protected:
*/
inline void BringSelfUpToDate(bool aDoFlush);
/**
* Sets the state to LIST_DIRTY and clears mElements array.
* @note This is the only acceptable way to set state to LIST_DIRTY.
*/
void SetDirty()
{
mState = LIST_DIRTY;
Reset();
}
/**
* To be called from non-destructor locations that want to remove from caches.
* Needed because if subclasses want to have cache behavior they can't just

View File

@ -126,6 +126,14 @@ nsDOMFileBase::GetName(nsAString &aFileName)
return NS_OK;
}
NS_IMETHODIMP
nsDOMFileBase::GetPath(nsAString &aPath)
{
NS_ASSERTION(mIsFile, "Should only be called on files");
aPath = mPath;
return NS_OK;
}
NS_IMETHODIMP
nsDOMFileBase::GetLastModifiedDate(JSContext* cx, JS::Value *aLastModifiedDate)
{
@ -591,6 +599,12 @@ nsDOMFileFile::GetInternalStream(nsIInputStream **aStream)
-1, -1, sFileStreamFlags);
}
void
nsDOMFileFile::SetPath(const nsAString& aPath)
{
mPath = aPath;
}
////////////////////////////////////////////////////////////////////////////
// nsDOMMemoryFile implementation

View File

@ -289,7 +289,7 @@ nsXMLHttpRequest::nsXMLHttpRequest()
mProgressSinceLastProgressEvent(false),
mRequestSentTime(0), mTimeoutMilliseconds(0),
mErrorLoad(false), mWaitingForOnStopRequest(false),
mProgressTimerIsActive(false), mProgressEventWasDelayed(false),
mProgressTimerIsActive(false),
mIsHtml(false),
mWarnAboutSyncHtml(false),
mLoadLengthComputable(false), mLoadTotal(0),
@ -3752,7 +3752,6 @@ nsXMLHttpRequest::StartProgressEventTimer()
mProgressNotifier = do_CreateInstance(NS_TIMER_CONTRACTID);
}
if (mProgressNotifier) {
mProgressEventWasDelayed = false;
mProgressTimerIsActive = true;
mProgressNotifier->Cancel();
mProgressNotifier->InitWithCallback(this, NS_PROGRESS_EVENT_INTERVAL,

View File

@ -673,7 +673,6 @@ protected:
bool mErrorLoad;
bool mWaitingForOnStopRequest;
bool mProgressTimerIsActive;
bool mProgressEventWasDelayed;
bool mIsHtml;
bool mWarnAboutMultipartHtml;
bool mWarnAboutSyncHtml;

View File

@ -240,13 +240,13 @@ class HTMLInputElementState MOZ_FINAL : public nsISupports
mValue = aValue;
}
const nsCOMArray<nsIDOMFile>& GetFiles() {
const nsTArray<nsCOMPtr<nsIDOMFile> >& GetFiles() {
return mFiles;
}
void SetFiles(const nsCOMArray<nsIDOMFile>& aFiles) {
void SetFiles(const nsTArray<nsCOMPtr<nsIDOMFile> >& aFiles) {
mFiles.Clear();
mFiles.AppendObjects(aFiles);
mFiles.AppendElements(aFiles);
}
HTMLInputElementState()
@ -257,7 +257,7 @@ class HTMLInputElementState MOZ_FINAL : public nsISupports
protected:
nsString mValue;
nsCOMArray<nsIDOMFile> mFiles;
nsTArray<nsCOMPtr<nsIDOMFile> > mFiles;
bool mChecked;
bool mCheckedSet;
};
@ -314,6 +314,221 @@ UploadLastDir::ContentPrefCallback::HandleError(nsresult error)
return NS_OK;
}
namespace {
/**
* This enumerator returns nsDOMFileFile objects after wrapping a single
* nsIFile representing a directory. It enumerates the files under that
* directory and its subdirectories as a flat list of files, ignoring/skipping
* over symbolic links.
*
* The enumeration involves I/O, so this class must NOT be used on the main
* thread or else the main thread could be blocked for a very long time.
*
* This enumerator does not walk the directory tree breadth-first, but it also
* is not guaranteed to walk it depth-first either (since it uses
* nsIFile::GetDirectoryEntries, which is not guaranteed to group a directory's
* subdirectories at the beginning of the list that it returns).
*/
class DirPickerRecursiveFileEnumerator MOZ_FINAL
: public nsISimpleEnumerator
{
public:
NS_DECL_ISUPPORTS
DirPickerRecursiveFileEnumerator(nsIFile* aTopDir)
: mTopDir(aTopDir)
{
MOZ_ASSERT(!NS_IsMainThread(), "This class blocks on I/O!");
#ifdef DEBUG
{
bool isDir;
aTopDir->IsDirectory(&isDir);
MOZ_ASSERT(isDir);
}
#endif
nsCOMPtr<nsISimpleEnumerator> entries;
if (NS_SUCCEEDED(mTopDir->GetDirectoryEntries(getter_AddRefs(entries))) &&
entries) {
mDirEnumeratorStack.AppendElement(entries);
LookupAndCacheNext();
}
}
NS_IMETHOD
GetNext(nsISupports** aResult)
{
MOZ_ASSERT(!NS_IsMainThread(),
"Walking the directory tree involves I/O, so using this "
"enumerator can block a thread for a long time!");
if (!mNextFile) {
return NS_ERROR_FAILURE;
}
nsRefPtr<nsDOMFileFile> domFile = new nsDOMFileFile(mNextFile);
nsCString relDescriptor;
nsresult rv = mNextFile->GetRelativeDescriptor(mTopDir, relDescriptor);
NS_ENSURE_SUCCESS(rv, rv);
NS_ConvertUTF8toUTF16 path(relDescriptor);
nsAutoString leafName;
mNextFile->GetLeafName(leafName);
MOZ_ASSERT(leafName.Length() <= path.Length());
int32_t length = path.Length() - leafName.Length() - 1; // -1 for "/"
MOZ_ASSERT(length >= -1);
if (length > 0) {
domFile->SetPath(Substring(path, 0, uint32_t(length)));
}
*aResult = static_cast<nsIDOMFile*>(domFile.forget().get());
LookupAndCacheNext();
return NS_OK;
}
NS_IMETHOD
HasMoreElements(bool* aResult)
{
*aResult = !!mNextFile;
return NS_OK;
}
private:
void
LookupAndCacheNext()
{
for (;;) {
if (mDirEnumeratorStack.IsEmpty()) {
mNextFile = nullptr;
break;
}
nsISimpleEnumerator* currentDirEntries =
mDirEnumeratorStack.LastElement();
bool hasMore;
DebugOnly<nsresult> rv = currentDirEntries->HasMoreElements(&hasMore);
MOZ_ASSERT(NS_SUCCEEDED(rv));
if (!hasMore) {
mDirEnumeratorStack.RemoveElementAt(mDirEnumeratorStack.Length() - 1);
continue;
}
nsCOMPtr<nsISupports> entry;
rv = currentDirEntries->GetNext(getter_AddRefs(entry));
MOZ_ASSERT(NS_SUCCEEDED(rv));
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
MOZ_ASSERT(file);
bool isLink, isSpecial;
file->IsSymlink(&isLink);
file->IsSpecial(&isSpecial);
if (isLink || isSpecial) {
continue;
}
bool isDir;
file->IsDirectory(&isDir);
if (isDir) {
nsCOMPtr<nsISimpleEnumerator> subDirEntries;
rv = file->GetDirectoryEntries(getter_AddRefs(subDirEntries));
MOZ_ASSERT(NS_SUCCEEDED(rv) && subDirEntries);
mDirEnumeratorStack.AppendElement(subDirEntries);
continue;
}
#ifdef DEBUG
{
bool isFile;
file->IsFile(&isFile);
MOZ_ASSERT(isFile);
}
#endif
mNextFile.swap(file);
return;
}
}
private:
nsCOMPtr<nsIFile> mTopDir;
nsCOMPtr<nsIFile> mNextFile;
nsTArray<nsCOMPtr<nsISimpleEnumerator> > mDirEnumeratorStack;
};
NS_IMPL_ISUPPORTS1(DirPickerRecursiveFileEnumerator, nsISimpleEnumerator)
class DirPickerBuildFileListTask MOZ_FINAL
: public nsRunnable
{
public:
DirPickerBuildFileListTask(HTMLInputElement* aInput, nsIFile* aTopDir)
: mInput(aInput)
, mTopDir(aTopDir)
{}
NS_IMETHOD Run() {
if (!NS_IsMainThread()) {
// Build up list of nsDOMFileFile objects on this dedicated thread:
nsCOMPtr<nsISimpleEnumerator> iter =
new DirPickerRecursiveFileEnumerator(mTopDir);
bool hasMore = true;
nsCOMPtr<nsISupports> tmp;
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
iter->GetNext(getter_AddRefs(tmp));
nsCOMPtr<nsIDOMFile> domFile = do_QueryInterface(tmp);
MOZ_ASSERT(domFile);
mFileList.AppendElement(domFile);
}
return NS_DispatchToMainThread(this);
}
// Now back on the main thread, set the list on our HTMLInputElement:
if (mFileList.IsEmpty()) {
return NS_OK;
}
// The text control frame (if there is one) isn't going to send a change
// event because it will think this is done by a script.
// So, we can safely send one by ourself.
mInput->SetFiles(mFileList, true);
nsresult rv =
nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
NS_LITERAL_STRING("change"), true,
false);
// Clear mInput to make sure that it can't lose its last strong ref off the
// main thread (which may happen if our dtor runs off the main thread)!
mInput = nullptr;
return rv;
}
private:
nsRefPtr<HTMLInputElement> mInput;
nsCOMPtr<nsIFile> mTopDir;
nsTArray<nsCOMPtr<nsIDOMFile> > mFileList;
};
static already_AddRefed<nsIFile>
DOMFileToLocalFile(nsIDOMFile* aDomFile)
{
nsString path;
nsresult rv = aDomFile->GetMozFullPathInternal(path);
if (NS_FAILED(rv) || path.IsEmpty()) {
return nullptr;
}
nsCOMPtr<nsIFile> localFile;
rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(path), true,
getter_AddRefs(localFile));
NS_ENSURE_SUCCESS(rv, nullptr);
return localFile.forget();
}
} // anonymous namespace
NS_IMETHODIMP
HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
{
@ -323,11 +538,43 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
int16_t mode;
mFilePicker->GetMode(&mode);
bool multi = mode == static_cast<int16_t>(nsIFilePicker::modeOpenMultiple);
if (mode == static_cast<int16_t>(nsIFilePicker::modeGetFolder)) {
// Directory picking is different, since we still need to do more I/O to
// build up the list of nsDOMFileFile objects. Since this may block for a
// long time, we need to build the list off on another dedicated thread to
// avoid blocking any other activities that the browser is carrying out.
// The user selected this directory, so we always save this dir, even if
// no files are found under it.
nsCOMPtr<nsIFile> pickedDir;
mFilePicker->GetFile(getter_AddRefs(pickedDir));
#ifdef DEBUG
{
bool isDir;
pickedDir->IsDirectory(&isDir);
MOZ_ASSERT(isDir);
}
#endif
HTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
mInput->OwnerDoc(), pickedDir);
nsCOMPtr<nsIEventTarget> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
NS_ASSERTION(target, "Must have stream transport service");
// DirPickerBuildFileListTask takes care of calling SetFiles() and
// dispatching the "change" event.
nsRefPtr<DirPickerBuildFileListTask> event =
new DirPickerBuildFileListTask(mInput.get(), pickedDir.get());
return target->Dispatch(event, NS_DISPATCH_NORMAL);
}
// Collect new selected filenames
nsCOMArray<nsIDOMFile> newFiles;
if (multi) {
nsTArray<nsCOMPtr<nsIDOMFile> > newFiles;
if (mode == static_cast<int16_t>(nsIFilePicker::modeOpenMultiple)) {
nsCOMPtr<nsISimpleEnumerator> iter;
nsresult rv = mFilePicker->GetDomfiles(getter_AddRefs(iter));
NS_ENSURE_SUCCESS(rv, rv);
@ -337,41 +584,35 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
}
nsCOMPtr<nsISupports> tmp;
bool prefSaved = false;
bool loop = true;
bool hasMore = true;
while (NS_SUCCEEDED(iter->HasMoreElements(&loop)) && loop) {
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
iter->GetNext(getter_AddRefs(tmp));
nsCOMPtr<nsIDOMFile> domFile = do_QueryInterface(tmp);
MOZ_ASSERT(domFile);
newFiles.AppendObject(domFile);
if (!prefSaved) {
// Store the last used directory using the content pref service
HTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
mInput->OwnerDoc(), domFile);
prefSaved = true;
newFiles.AppendElement(domFile);
}
}
}
else {
} else {
MOZ_ASSERT(mode == static_cast<int16_t>(nsIFilePicker::modeOpen));
nsCOMPtr<nsIDOMFile> domFile;
nsresult rv = mFilePicker->GetDomfile(getter_AddRefs(domFile));
NS_ENSURE_SUCCESS(rv, rv);
if (domFile) {
newFiles.AppendObject(domFile);
// Store the last used directory using the content pref service
HTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
mInput->OwnerDoc(), domFile);
newFiles.AppendElement(domFile);
}
}
if (!newFiles.Count()) {
if (newFiles.IsEmpty()) {
return NS_OK;
}
// Store the last used directory using the content pref service:
nsCOMPtr<nsIFile> file = DOMFileToLocalFile(newFiles[0]);
nsCOMPtr<nsIFile> lastUsedDir;
file->GetParent(getter_AddRefs(lastUsedDir));
HTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
mInput->OwnerDoc(), lastUsedDir);
// The text control frame (if there is one) isn't going to send a change
// event because it will think this is done by a script.
// So, we can safely send one by ourself.
@ -543,7 +784,7 @@ HTMLInputElement::InitColorPicker()
}
nsresult
HTMLInputElement::InitFilePicker()
HTMLInputElement::InitFilePicker(FilePickerType aType)
{
// Get parent nsPIDOMWindow object.
nsCOMPtr<nsIDocument> doc = OwnerDoc();
@ -567,15 +808,23 @@ HTMLInputElement::InitFilePicker()
if (!filePicker)
return NS_ERROR_FAILURE;
bool multi = HasAttr(kNameSpaceID_None, nsGkAtoms::multiple);
int16_t mode;
nsresult rv = filePicker->Init(win, title,
multi
? static_cast<int16_t>(nsIFilePicker::modeOpenMultiple)
: static_cast<int16_t>(nsIFilePicker::modeOpen));
if (aType == FILE_PICKER_DIRECTORY) {
mode = static_cast<int16_t>(nsIFilePicker::modeGetFolder);
} else if (HasAttr(kNameSpaceID_None, nsGkAtoms::multiple)) {
mode = static_cast<int16_t>(nsIFilePicker::modeOpenMultiple);
} else {
mode = static_cast<int16_t>(nsIFilePicker::modeOpen);
}
nsresult rv = filePicker->Init(win, title, mode);
NS_ENSURE_SUCCESS(rv, rv);
if (HasAttr(kNameSpaceID_None, nsGkAtoms::accept)) {
// Native directory pickers ignore file type filters, so we don't spend
// cycles adding them for FILE_PICKER_DIRECTORY.
if (HasAttr(kNameSpaceID_None, nsGkAtoms::accept) &&
aType != FILE_PICKER_DIRECTORY) {
SetFilePickerFiltersFromAccept(filePicker);
} else {
filePicker->AppendFilters(nsIFilePicker::filterAll);
@ -584,12 +833,13 @@ HTMLInputElement::InitFilePicker()
// Set default directry and filename
nsAutoString defaultName;
const nsCOMArray<nsIDOMFile>& oldFiles = GetFilesInternal();
const nsTArray<nsCOMPtr<nsIDOMFile> >& oldFiles = GetFilesInternal();
nsCOMPtr<nsIFilePickerShownCallback> callback =
new HTMLInputElement::nsFilePickerShownCallback(this, filePicker);
if (oldFiles.Count()) {
if (!oldFiles.IsEmpty() &&
aType != FILE_PICKER_DIRECTORY) {
nsString path;
oldFiles[0]->GetMozFullPathInternal(path);
@ -608,7 +858,7 @@ HTMLInputElement::InitFilePicker()
// Unfortunately nsIFilePicker doesn't allow multiple files to be
// default-selected, so only select something by default if exactly
// one file was selected before.
if (oldFiles.Count() == 1) {
if (oldFiles.Length() == 1) {
nsAutoString leafName;
oldFiles[0]->GetName(leafName);
if (!leafName.IsEmpty()) {
@ -621,7 +871,6 @@ HTMLInputElement::InitFilePicker()
HTMLInputElement::gUploadLastDir->FetchDirectoryAndDisplayPicker(doc, filePicker, callback);
return NS_OK;
}
#define CPS_PREF_NAME NS_LITERAL_STRING("browser.upload.lastDir")
@ -680,31 +929,16 @@ UploadLastDir::FetchDirectoryAndDisplayPicker(nsIDocument* aDoc,
}
nsresult
UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIDOMFile* aDomFile)
UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aDir)
{
NS_PRECONDITION(aDoc, "aDoc is null");
NS_PRECONDITION(aDomFile, "aDomFile is null");
nsString path;
nsresult rv = aDomFile->GetMozFullPathInternal(path);
if (NS_FAILED(rv) || path.IsEmpty()) {
if (!aDir) {
return NS_OK;
}
nsCOMPtr<nsIFile> localFile;
rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(path), true,
getter_AddRefs(localFile));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> docURI = aDoc->GetDocumentURI();
NS_PRECONDITION(docURI, "docURI is null");
nsCOMPtr<nsIFile> parentFile;
localFile->GetParent(getter_AddRefs(parentFile));
if (!parentFile) {
return NS_OK;
}
// Attempt to get the CPS, if it's not present we'll just return
nsCOMPtr<nsIContentPrefService2> contentPrefService =
do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
@ -717,7 +951,7 @@ UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIDOMFile* aDomFile)
// Find the parent of aFile, and store it
nsString unicodePath;
parentFile->GetPath(unicodePath);
aDir->GetPath(unicodePath);
if (unicodePath.IsEmpty()) // nothing to do
return NS_OK;
nsCOMPtr<nsIWritableVariant> prefValue = do_CreateInstance(NS_VARIANT_CONTRACTID);
@ -906,7 +1140,7 @@ HTMLInputElement::Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const
GetDisplayFileName(it->mStaticDocFileList);
} else {
it->mFiles.Clear();
it->mFiles.AppendObjects(mFiles);
it->mFiles.AppendElements(mFiles);
}
break;
case VALUE_MODE_DEFAULT_ON:
@ -1264,7 +1498,7 @@ HTMLInputElement::GetValueInternal(nsAString& aValue) const
case VALUE_MODE_FILENAME:
if (nsContentUtils::IsCallerChrome()) {
if (mFiles.Count()) {
if (!mFiles.IsEmpty()) {
return mFiles[0]->GetMozFullPath(aValue);
}
else {
@ -1272,7 +1506,7 @@ HTMLInputElement::GetValueInternal(nsAString& aValue) const
}
} else {
// Just return the leaf name
if (mFiles.Count() == 0 || NS_FAILED(mFiles[0]->GetName(aValue))) {
if (mFiles.IsEmpty() || NS_FAILED(mFiles[0]->GetName(aValue))) {
aValue.Truncate();
}
}
@ -1818,7 +2052,7 @@ HTMLInputElement::StepUp(int32_t n, uint8_t optional_argc)
void
HTMLInputElement::MozGetFileNameArray(nsTArray< nsString >& aArray)
{
for (int32_t i = 0; i < mFiles.Count(); i++) {
for (uint32_t i = 0; i < mFiles.Length(); i++) {
nsString str;
mFiles[i]->GetMozFullPathInternal(str);
aArray.AppendElement(str);
@ -1857,7 +2091,7 @@ HTMLInputElement::MozGetFileNameArray(uint32_t* aLength, PRUnichar*** aFileNames
void
HTMLInputElement::MozSetFileNameArray(const Sequence< nsString >& aFileNames)
{
nsCOMArray<nsIDOMFile> files;
nsTArray<nsCOMPtr<nsIDOMFile> > files;
for (uint32_t i = 0; i < aFileNames.Length(); ++i) {
nsCOMPtr<nsIFile> file;
@ -1876,7 +2110,7 @@ HTMLInputElement::MozSetFileNameArray(const Sequence< nsString >& aFileNames)
if (file) {
nsCOMPtr<nsIDOMFile> domFile = new nsDOMFileFile(file);
files.AppendObject(domFile);
files.AppendElement(domFile);
} else {
continue; // Not much we can do if the file doesn't exist
}
@ -2068,14 +2302,14 @@ HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
return;
}
if (mFiles.Count() == 1) {
if (mFiles.Length() == 1) {
mFiles[0]->GetName(aValue);
return;
}
nsXPIDLString value;
if (mFiles.Count() == 0) {
if (mFiles.IsEmpty()) {
if (HasAttr(kNameSpaceID_None, nsGkAtoms::multiple)) {
nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"NoFilesSelected", value);
@ -2085,7 +2319,7 @@ HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
}
} else {
nsString count;
count.AppendInt(mFiles.Count());
count.AppendInt(mFiles.Length());
const PRUnichar* params[] = { count.get() };
nsContentUtils::FormatLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
@ -2096,11 +2330,11 @@ HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
}
void
HTMLInputElement::SetFiles(const nsCOMArray<nsIDOMFile>& aFiles,
HTMLInputElement::SetFiles(const nsTArray<nsCOMPtr<nsIDOMFile> >& aFiles,
bool aSetValueChanged)
{
mFiles.Clear();
mFiles.AppendObjects(aFiles);
mFiles.AppendElements(aFiles);
AfterSetFiles(aSetValueChanged);
}
@ -2117,7 +2351,7 @@ HTMLInputElement::SetFiles(nsIDOMFileList* aFiles,
for (uint32_t i = 0; i < listLength; i++) {
nsCOMPtr<nsIDOMFile> file;
aFiles->Item(i, getter_AddRefs(file));
mFiles.AppendObject(file);
mFiles.AppendElement(file);
}
}
@ -2179,14 +2413,23 @@ HTMLInputElement::GetFiles()
return mFileList;
}
void
HTMLInputElement::OpenDirectoryPicker(ErrorResult& aRv)
{
if (mType != NS_FORM_INPUT_FILE) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
}
InitFilePicker(FILE_PICKER_DIRECTORY);
}
nsresult
HTMLInputElement::UpdateFileList()
{
if (mFileList) {
mFileList->Clear();
const nsCOMArray<nsIDOMFile>& files = GetFilesInternal();
for (int32_t i = 0; i < files.Count(); ++i) {
const nsTArray<nsCOMPtr<nsIDOMFile> >& files = GetFilesInternal();
for (uint32_t i = 0; i < files.Length(); ++i) {
if (!mFileList->Append(files[i])) {
return NS_ERROR_FAILURE;
}
@ -2890,7 +3133,7 @@ HTMLInputElement::MaybeInitPickers(nsEventChainPostVisitor& aVisitor)
if (NS_IS_MOUSE_LEFT_CLICK(aVisitor.mEvent) &&
!aVisitor.mEvent->mFlags.mDefaultPrevented) {
if (mType == NS_FORM_INPUT_FILE) {
return InitFilePicker();
return InitFilePicker(FILE_PICKER_FILE);
}
if (mType == NS_FORM_INPUT_COLOR) {
return InitColorPicker();
@ -4574,13 +4817,13 @@ HTMLInputElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
if (mType == NS_FORM_INPUT_FILE) {
// Submit files
const nsCOMArray<nsIDOMFile>& files = GetFilesInternal();
const nsTArray<nsCOMPtr<nsIDOMFile> >& files = GetFilesInternal();
for (int32_t i = 0; i < files.Count(); ++i) {
for (uint32_t i = 0; i < files.Length(); ++i) {
aFormSubmission->AddNameFilePair(name, files[i], NullString());
}
if (files.Count() == 0) {
if (files.IsEmpty()) {
// If no file was selected, pretend we had an empty file with an
// empty filename.
aFormSubmission->AddNameFilePair(name, nullptr, NullString());
@ -4617,7 +4860,7 @@ HTMLInputElement::SaveState()
}
break;
case VALUE_MODE_FILENAME:
if (mFiles.Count()) {
if (!mFiles.IsEmpty()) {
inputState = new HTMLInputElementState();
inputState->SetFiles(mFiles);
}
@ -4790,7 +5033,7 @@ HTMLInputElement::RestoreState(nsPresState* aState)
break;
case VALUE_MODE_FILENAME:
{
const nsCOMArray<nsIDOMFile>& files = inputState->GetFiles();
const nsTArray<nsCOMPtr<nsIDOMFile> >& files = inputState->GetFiles();
SetFiles(files, true);
}
break;
@ -5257,8 +5500,8 @@ HTMLInputElement::IsValueMissing() const
return IsValueEmpty();
case VALUE_MODE_FILENAME:
{
const nsCOMArray<nsIDOMFile>& files = GetFilesInternal();
return !files.Count();
const nsTArray<nsCOMPtr<nsIDOMFile> >& files = GetFilesInternal();
return files.IsEmpty();
}
case VALUE_MODE_DEFAULT_ON:
// This should not be used for type radio.

View File

@ -54,10 +54,9 @@ public:
* Store the last used directory for this location using the
* content pref service, if it is available
* @param aURI URI of the current page
* @param aDomFile file chosen by the user - the path to the parent of this
* file will be stored
* @param aDir Parent directory of the file(s)/directory chosen by the user
*/
nsresult StoreLastUsedDirectory(nsIDocument* aDoc, nsIDOMFile* aDomFile);
nsresult StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aDir);
class ContentPrefCallback MOZ_FINAL : public nsIContentPrefCallback2
{
@ -191,12 +190,12 @@ public:
void GetDisplayFileName(nsAString& aFileName) const;
const nsCOMArray<nsIDOMFile>& GetFilesInternal() const
const nsTArray<nsCOMPtr<nsIDOMFile> >& GetFilesInternal() const
{
return mFiles;
}
void SetFiles(const nsCOMArray<nsIDOMFile>& aFiles, bool aSetValueChanged);
void SetFiles(const nsTArray<nsCOMPtr<nsIDOMFile> >& aFiles, bool aSetValueChanged);
void SetFiles(nsIDOMFileList* aFiles, bool aSetValueChanged);
void SetCheckedChangedInternal(bool aCheckedChanged);
@ -393,6 +392,8 @@ public:
nsDOMFileList* GetFiles();
void OpenDirectoryPicker(ErrorResult& aRv);
// XPCOM GetFormAction() is OK
void SetFormAction(const nsAString& aValue, ErrorResult& aRv)
{
@ -734,7 +735,7 @@ protected:
bool IsValueEmpty() const;
void ClearFiles(bool aSetValueChanged) {
nsCOMArray<nsIDOMFile> files;
nsTArray<nsCOMPtr<nsIDOMFile> > files;
SetFiles(files, aSetValueChanged);
}
@ -1080,7 +1081,11 @@ protected:
*/
nsresult MaybeInitPickers(nsEventChainPostVisitor& aVisitor);
nsresult InitFilePicker();
enum FilePickerType {
FILE_PICKER_FILE,
FILE_PICKER_DIRECTORY
};
nsresult InitFilePicker(FilePickerType aType);
nsresult InitColorPicker();
/**
@ -1122,7 +1127,7 @@ protected:
* the frame. Whenever the frame wants to change the filename it has to call
* SetFileNames to update this member.
*/
nsCOMArray<nsIDOMFile> mFiles;
nsTArray<nsCOMPtr<nsIDOMFile> > mFiles;
nsRefPtr<nsDOMFileList> mFileList;

View File

@ -13,6 +13,7 @@
#include "mozilla/dom/HTMLSelectElementBinding.h"
#include "mozilla/Util.h"
#include "nsContentCreatorFunctions.h"
#include "nsContentList.h"
#include "nsError.h"
#include "nsEventDispatcher.h"
#include "nsEventStates.h"
@ -139,10 +140,12 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLSelectElement,
nsGenericHTMLFormElementWithState)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOptions)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelectedOptions)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLSelectElement,
nsGenericHTMLFormElementWithState)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelectedOptions)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_ADDREF_INHERITED(HTMLSelectElement, Element)
@ -769,6 +772,34 @@ HTMLSelectElement::SetLength(uint32_t aLength, ErrorResult& aRv)
}
}
/* static */
bool
HTMLSelectElement::MatchSelectedOptions(nsIContent* aContent,
int32_t /* unused */,
nsIAtom* /* unused */,
void* /* unused*/)
{
HTMLOptionElement* option = HTMLOptionElement::FromContent(aContent);
return option && option->Selected();
}
nsIHTMLCollection*
HTMLSelectElement::SelectedOptions()
{
if (!mSelectedOptions) {
mSelectedOptions = new nsContentList(this, MatchSelectedOptions, nullptr,
nullptr, /* deep */ true);
}
return mSelectedOptions;
}
NS_IMETHODIMP
HTMLSelectElement::GetSelectedOptions(nsIDOMHTMLCollection** aSelectedOptions)
{
NS_ADDREF(*aSelectedOptions = SelectedOptions());
return NS_OK;
}
//NS_IMPL_INT_ATTR(HTMLSelectElement, SelectedIndex, selectedindex)
NS_IMETHODIMP
@ -847,6 +878,7 @@ HTMLSelectElement::OnOptionSelected(nsISelectControlFrame* aSelectFrame,
aSelectFrame->OnOptionSelected(aIndex, aSelected);
}
UpdateSelectedOptions();
UpdateValueMissingValidityState();
UpdateState(aNotify);
}
@ -1848,6 +1880,8 @@ HTMLSelectElement::SetSelectionChanged(bool aValue, bool aNotify)
return;
}
UpdateSelectedOptions();
bool previousSelectionChangedValue = mSelectionHasChanged;
mSelectionHasChanged = aValue;
@ -1856,6 +1890,14 @@ HTMLSelectElement::SetSelectionChanged(bool aValue, bool aNotify)
}
}
void
HTMLSelectElement::UpdateSelectedOptions()
{
if (mSelectedOptions) {
mSelectedOptions->SetDirty();
}
}
JSObject*
HTMLSelectElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{

View File

@ -18,7 +18,9 @@
#include "nsError.h"
#include "mozilla/dom/HTMLFormElement.h"
class nsContentList;
class nsIDOMHTMLOptionElement;
class nsIHTMLCollection;
class nsISelectControlFrame;
class nsPresState;
@ -208,6 +210,11 @@ public:
mOptions->IndexedSetter(aIndex, aOption, aRv);
}
static bool MatchSelectedOptions(nsIContent* aContent, int32_t, nsIAtom*,
void*);
nsIHTMLCollection* SelectedOptions();
int32_t SelectedIndex() const
{
return mSelectedIndex;
@ -553,6 +560,12 @@ protected:
void SetSelectionChanged(bool aValue, bool aNotify);
/**
* Marks the selectedOptions list as dirty, so that it'll populate itself
* again.
*/
void UpdateSelectedOptions();
/**
* Return whether an element should have a validity UI.
* (with :-moz-ui-invalid and :-moz-ui-valid pseudo-classes).
@ -618,6 +631,11 @@ protected:
* done adding options
*/
nsCOMPtr<SelectState> mRestoreState;
/**
* The live list of selected options.
*/
nsRefPtr<nsContentList> mSelectedOptions;
};
} // namespace dom

View File

@ -470,6 +470,13 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
if (filename16.IsEmpty()) {
filename16.AssignLiteral("blob");
} else {
nsAutoString filepath16;
rv = file->GetPath(filepath16);
NS_ENSURE_SUCCESS(rv, rv);
if (!filepath16.IsEmpty()) {
filename16 = filepath16 + NS_LITERAL_STRING("/") + filename16;
}
}
rv = EncodeVal(filename16, filename, true);

View File

@ -67,6 +67,7 @@ MOCHITEST_FILES = \
test_input_color_picker_popup.html \
test_input_color_input_change_events.html \
test_restore_form_elements.html \
test_select_selectedOptions.html \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,120 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=596681
-->
<head>
<title>Test for HTMLSelectElement.selectedOptions</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=596681">Mozilla Bug 596681</a>
<p id="display"></p>
<pre id="test">
<script type="application/javascript;version=1.7">
/** Test for HTMLSelectElement's selectedOptions attribute.
*
* selectedOptions is a live list of the options that have selectedness of true
* (not the selected content attribute).
*
* See http://www.whatwg.org/html/#dom-select-selectedoptions
**/
function checkSelectedOptions(size, elements)
{
is(selectedOptions.length, size,
"select should have " + size + " selected options");
for (let i = 0; i < size; ++i) {
ok(selectedOptions[i], "selected option is valid");
if (selectedOptions[i]) {
is(selectedOptions[i].value, elements[i].value, "selected options are correct");
}
}
}
let select = document.createElement("select");
document.body.appendChild(select);
let selectedOptions = select.selectedOptions;
ok("selectedOptions" in select,
"select element should have a selectedOptions IDL attribute");
ok(select.selectedOptions instanceof HTMLCollection,
"selectedOptions should be an HTMLCollection instance");
let option1 = document.createElement("option");
let option2 = document.createElement("option");
let option3 = document.createElement("option");
option1.id = "option1";
option1.value = "option1";
option2.value = "option2";
option3.value = "option3";
checkSelectedOptions(0, null);
select.add(option1, null);
is(selectedOptions.namedItem("option1").value, "option1", "named getter works");
checkSelectedOptions(1, [option1]);
select.add(option2, null);
checkSelectedOptions(1, [option1]);
select.options[1].selected = true;
checkSelectedOptions(1, [option2]);
select.multiple = true;
checkSelectedOptions(1, [option2]);
select.options[0].selected = true;
checkSelectedOptions(2, [option1, option2]);
option1.selected = false;
// Usinig selected directly on the option should work.
checkSelectedOptions(1, [option2]);
select.remove(1);
select.add(option2, 0);
select.options[0].selected = true;
select.options[1].selected = true;
// Should be in tree order.
checkSelectedOptions(2, [option2, option1]);
select.add(option3, null);
checkSelectedOptions(2, [option2, option1]);
select.options[2].selected = true;
checkSelectedOptions(3, [option2, option1, option3]);
select.length = 0;
option1.selected = false;
option2.selected = false;
option3.selected = false;
var optgroup1 = document.createElement("optgroup");
optgroup1.appendChild(option1);
optgroup1.appendChild(option2);
select.add(optgroup1)
var optgroup2 = document.createElement("optgroup");
optgroup2.appendChild(option3);
select.add(optgroup2);
checkSelectedOptions(0, null);
option2.selected = true;
checkSelectedOptions(1, [option2]);
option3.selected = true;
checkSelectedOptions(2, [option2, option3]);
optgroup1.removeChild(option2);
checkSelectedOptions(1, [option3]);
document.body.removeChild(select);
option1.selected = true;
checkSelectedOptions(2, [option1, option3]);
</script>
</pre>
</body>
</html>

View File

@ -107,9 +107,6 @@ static bool IsOmxSupported()
// nullptr is returned if Omx decoding is not supported on the device,
static const char* GetOmxLibraryName()
{
if (!IsOmxSupported())
return nullptr;
#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1");
NS_ASSERTION(infoService, "Could not find a system info service");
@ -138,19 +135,18 @@ static const char* GetOmxLibraryName()
ALOG("Android Manufacturer is: %s", NS_LossyConvertUTF16toASCII(manufacturer).get());
}
if (version >= 16 && manufacturer.Find("HTC") == 0) {
return "libomxpluginjb-htc.so";
nsAutoString hardware;
rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("hardware"), hardware);
if (NS_SUCCEEDED(rv)) {
ALOG("Android Hardware is: %s", NS_LossyConvertUTF16toASCII(hardware).get());
}
else if (version == 15 &&
(device.Find("LT28", false) == 0 ||
device.Find("LT26", false) == 0 ||
device.Find("LT22", false) == 0 ||
device.Find("IS12", false) == 0 ||
device.Find("MT27", false) == 0)) {
// Sony Ericsson devices running ICS
return "libomxpluginsony.so";
}
else if (version == 13 || version == 12 || version == 11) {
#endif
if (!IsOmxSupported())
return nullptr;
#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
if (version == 13 || version == 12 || version == 11) {
return "libomxpluginhc.so";
}
else if (version == 10 && release_version >= NS_LITERAL_STRING("2.3.6")) {

View File

@ -61,7 +61,6 @@ MOCHITEST_FILES := \
test_convolverNode_mono_mono.html \
test_currentTime.html \
test_delayNode.html \
test_delayNodeAtMax.html \
test_delayNodeSmallMaxDelay.html \
test_delayNodeWithGain.html \
test_dynamicsCompressorNode.html \
@ -113,4 +112,10 @@ MOCHITEST_FILES := \
audio-quad.wav \
$(NULL)
ifneq ($(MOZ_DEBUG)+$(MOZ_WIDGET_TOOLKIT),+gtk2) # bug 911777
MOCHITEST_FILES += \
test_delayNodeAtMax.html \
$(NULL)
endif
include $(topsrcdir)/config/rules.mk

View File

@ -19,7 +19,7 @@
interface nsIDOMValidityState;
[scriptable, uuid(846578b2-6d4f-4399-86cc-2c05f19469d0)]
[scriptable, uuid(d8914a2d-3556-4b66-911c-a84c4394e7fa)]
interface nsIDOMHTMLSelectElement : nsISupports
{
attribute boolean autofocus;
@ -44,6 +44,7 @@ interface nsIDOMHTMLSelectElement : nsISupports
raises(DOMException);
void remove(in long index);
readonly attribute nsIDOMHTMLCollection selectedOptions;
attribute long selectedIndex;
attribute DOMString value;

View File

@ -33,6 +33,8 @@ interface HTMLInputElement : HTMLElement {
readonly attribute HTMLFormElement? form;
[Pure]
readonly attribute FileList? files;
[Throws, Pref="dom.input.dirpicker"]
void openDirectoryPicker();
[Pure, SetterThrows]
attribute DOMString formAction;
[Pure, SetterThrows]

View File

@ -38,7 +38,7 @@ interface HTMLSelectElement : HTMLElement {
[Throws]
setter creator void (unsigned long index, HTMLOptionElement? option);
// NYI: readonly attribute HTMLCollection selectedOptions;
readonly attribute HTMLCollection selectedOptions;
[SetterThrows, Pure]
attribute long selectedIndex;
[Pure]

View File

@ -353,6 +353,29 @@ private:
return true;
}
static bool
GetPath(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
JS::MutableHandle<JS::Value> aVp)
{
nsIDOMFile* file = GetInstancePrivate(aCx, aObj, "path");
if (!file) {
return false;
}
nsString path;
if (NS_FAILED(file->GetPath(path))) {
path.Truncate();
}
JSString* jsPath = JS_NewUCStringCopyN(aCx, path.get(), path.Length());
if (!jsPath) {
return false;
}
aVp.set(STRING_TO_JSVAL(jsPath));
return true;
}
static bool
GetLastModifiedDate(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
JS::MutableHandle<JS::Value> aVp)
@ -382,6 +405,8 @@ JSClass File::sClass = {
const JSPropertySpec File::sProperties[] = {
{ "name", 0, PROPERTY_FLAGS, JSOP_WRAPPER(GetName),
JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
{ "path", 0, PROPERTY_FLAGS, JSOP_WRAPPER(GetPath),
JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
{ "lastModifiedDate", 0, PROPERTY_FLAGS, JSOP_WRAPPER(GetLastModifiedDate),
JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
{ "mozFullPath", 0, PROPERTY_FLAGS, JSOP_WRAPPER(GetMozFullPath),

View File

@ -514,13 +514,13 @@ LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */)
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX
"gc_allocation_threshold_mb");
if (memPrefName == matchName || (!rts && index == 9)) {
if (memPrefName == matchName || (!rts && index == 8)) {
UpdateCommonJSGCMemoryOption(rts, matchName, JSGC_ALLOCATION_THRESHOLD);
continue;
}
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX "gc_incremental_slice_ms");
if (memPrefName == matchName || (!rts && index == 10)) {
if (memPrefName == matchName || (!rts && index == 9)) {
int32_t prefValue = GetWorkerPref(matchName, -1);
uint32_t value =
(prefValue <= 0 || prefValue >= 100000) ? 0 : uint32_t(prefValue);
@ -529,7 +529,7 @@ LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */)
}
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX "gc_dynamic_heap_growth");
if (memPrefName == matchName || (!rts && index == 11)) {
if (memPrefName == matchName || (!rts && index == 10)) {
bool prefValue = GetWorkerPref(matchName, false);
UpdatOtherJSGCMemoryOption(rts, JSGC_DYNAMIC_HEAP_GROWTH,
prefValue ? 0 : 1);
@ -537,7 +537,7 @@ LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */)
}
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX "gc_dynamic_mark_slice");
if (memPrefName == matchName || (!rts && index == 12)) {
if (memPrefName == matchName || (!rts && index == 11)) {
bool prefValue = GetWorkerPref(matchName, false);
UpdatOtherJSGCMemoryOption(rts, JSGC_DYNAMIC_MARK_SLICE,
prefValue ? 0 : 1);

View File

@ -9,6 +9,7 @@ onmessage = function(event) {
rtnObj.size = file.size;
rtnObj.type = file.type;
rtnObj.name = file.name;
rtnObj.path = file.path;
rtnObj.lastModifiedDate = file.lastModifiedDate;
rtnObj.mozFullPath = file.mozFullPath;

View File

@ -69,6 +69,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=123456
is(event.data.size, expectedSize, "size proproperty accessed from worker is not the same as on main thread.");
is(event.data.type, expectedType, "type proproperty accessed from worker is incorrect.");
is(event.data.name, file.name, "name proproperty accessed from worker is incorrect.");
is(event.data.path, file.path, "path proproperty accessed from worker is incorrect.");
is(event.data.lastModifiedDate.toString(), file.lastModifiedDate.toString(), "lastModifiedDate proproperty accessed from worker is incorrect.");
is(event.data.mozFullPath, file.mozFullPath, "mozFullPath proproperty accessed from worker is not the same as on main thread.");
finish();

View File

@ -256,7 +256,8 @@ ImageClientSingle::CreateBufferTextureClient(gfx::SurfaceFormat aFormat, Texture
TemporaryRef<BufferTextureClient>
ImageClientSingle::CreateBufferTextureClient(gfx::SurfaceFormat aFormat)
{
return CompositableClient::CreateBufferTextureClient(aFormat, mTextureFlags);
return CompositableClient::CreateBufferTextureClient(aFormat,
mTextureFlags | TEXTURE_FLAGS_DEFAULT);
}
void

View File

@ -4383,7 +4383,36 @@ gfxFontGroup::InitTextRun(gfxContext *aContext,
}
}
#ifdef PR_LOGGING
PRLogModuleInfo *log = (mStyle.systemFont ?
gfxPlatform::GetLog(eGfxLog_textrunui) :
gfxPlatform::GetLog(eGfxLog_textrun));
#endif
if (sizeof(T) == sizeof(uint8_t) && !transformedString) {
#ifdef PR_LOGGING
if (MOZ_UNLIKELY(log)) {
nsAutoCString lang;
mStyle.language->ToUTF8String(lang);
nsAutoCString str((const char*)aString, aLength);
PR_LOG(log, PR_LOG_WARNING,\
("(%s) fontgroup: [%s] lang: %s script: %d len %d "
"weight: %d width: %d style: %s size: %6.2f %d-byte "
"TEXTRUN [%s] ENDTEXTRUN\n",
(mStyle.systemFont ? "textrunui" : "textrun"),
NS_ConvertUTF16toUTF8(mFamilies).get(),
lang.get(), MOZ_SCRIPT_LATIN, aLength,
uint32_t(mStyle.weight), uint32_t(mStyle.stretch),
(mStyle.style & NS_FONT_STYLE_ITALIC ? "italic" :
(mStyle.style & NS_FONT_STYLE_OBLIQUE ? "oblique" :
"normal")),
mStyle.size,
sizeof(T),
str.get()));
}
#endif
// the text is still purely 8-bit; bypass the script-run itemizer
// and treat it as a single Latin run
InitScriptRun(aContext, aTextRun, aString,
@ -4402,12 +4431,6 @@ gfxFontGroup::InitTextRun(gfxContext *aContext,
// the font matching process below
gfxScriptItemizer scriptRuns(textPtr, aLength);
#ifdef PR_LOGGING
PRLogModuleInfo *log = (mStyle.systemFont ?
gfxPlatform::GetLog(eGfxLog_textrunui) :
gfxPlatform::GetLog(eGfxLog_textrun));
#endif
uint32_t runStart = 0, runLimit = aLength;
int32_t runScript = MOZ_SCRIPT_LATIN;
while (scriptRuns.Next(runStart, runLimit, runScript)) {
@ -4419,7 +4442,7 @@ gfxFontGroup::InitTextRun(gfxContext *aContext,
uint32_t runLen = runLimit - runStart;
PR_LOG(log, PR_LOG_WARNING,\
("(%s) fontgroup: [%s] lang: %s script: %d len %d "
"weight: %d width: %d style: %s "
"weight: %d width: %d style: %s size: %6.2f %d-byte "
"TEXTRUN [%s] ENDTEXTRUN\n",
(mStyle.systemFont ? "textrunui" : "textrun"),
NS_ConvertUTF16toUTF8(mFamilies).get(),
@ -4428,6 +4451,8 @@ gfxFontGroup::InitTextRun(gfxContext *aContext,
(mStyle.style & NS_FONT_STYLE_ITALIC ? "italic" :
(mStyle.style & NS_FONT_STYLE_OBLIQUE ? "oblique" :
"normal")),
mStyle.size,
sizeof(T),
NS_ConvertUTF16toUTF8(textPtr + runStart, runLen).get()));
}
#endif

View File

@ -39,9 +39,9 @@ class JavaScriptParent
JS::MutableHandle<JSPropertyDescriptor> desc, unsigned flags);
bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
bool getOwnPropertyNames(JSContext *cx, JS::HandleObject proxy, js::AutoIdVector &props);
bool getOwnPropertyNames(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool enumerate(JSContext *cx, JS::HandleObject proxy, js::AutoIdVector &props);
bool enumerate(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
// Derived proxy traps. Implementing these is useful for perfomance.
bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
@ -50,7 +50,7 @@ class JavaScriptParent
JS::HandleId id, JS::MutableHandleValue vp);
bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, bool strict, JS::MutableHandleValue vp);
bool keys(JSContext *cx, JS::HandleObject proxy, js::AutoIdVector &props);
bool keys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
// We use "iterate" provided by the base class here.
// SpiderMonkey Extensions.
@ -82,7 +82,8 @@ class JavaScriptParent
private:
bool makeId(JSContext *cx, JSObject *obj, ObjectId *idp);
bool getPropertyNames(JSContext *cx, JS::HandleObject proxy, uint32_t flags, js::AutoIdVector &props);
bool getPropertyNames(JSContext *cx, JS::HandleObject proxy, uint32_t flags,
JS::AutoIdVector &props);
ObjectId idOf(JSObject *obj);
// Catastrophic IPC failure.

116
js/src/NamespaceImports.h Normal file
View File

@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 file imports some common JS:: names into the js namespace so we can
// make unqualified references to them.
#ifndef NamespaceImports_h
#define NamespaceImports_h
// These includes are needed these for some typedefs (e.g. HandleValue) and
// functions (e.g. NullValue())...
#include "js/CallNonGenericMethod.h"
#include "js/TypeDecls.h"
#include "js/Value.h"
// ... but we do forward declarations of the structs and classes not pulled in
// by the headers included above.
namespace JS {
class Latin1CharsZ;
class StableCharPtr;
class TwoByteChars;
class AutoFunctionVector;
class AutoIdVector;
class AutoObjectVector;
class AutoScriptVector;
class AutoValueVector;
class AutoIdArray;
class AutoGCRooter;
class AutoArrayRooter;
template <typename T> class AutoVectorRooter;
template<typename K, typename V> class AutoHashMapRooter;
template<typename T> class AutoHashSetRooter;
}
// Do the importing.
namespace js {
using JS::Value;
using JS::BooleanValue;
using JS::DoubleValue;
using JS::Int32Value;
using JS::IsPoisonedValue;
using JS::MagicValue;
using JS::NullValue;
using JS::NumberValue;
using JS::ObjectOrNullValue;
using JS::ObjectValue;
using JS::PrivateUint32Value;
using JS::PrivateValue;
using JS::StringValue;
using JS::UndefinedValue;
using JS::IsPoisonedPtr;
using JS::Latin1CharsZ;
using JS::StableCharPtr;
using JS::TwoByteChars;
using JS::AutoFunctionVector;
using JS::AutoIdVector;
using JS::AutoObjectVector;
using JS::AutoScriptVector;
using JS::AutoValueVector;
using JS::AutoIdArray;
using JS::AutoGCRooter;
using JS::AutoArrayRooter;
using JS::AutoHashMapRooter;
using JS::AutoHashSetRooter;
using JS::AutoVectorRooter;
using JS::CallArgs;
using JS::CallNonGenericMethod;
using JS::CallReceiver;
using JS::CompileOptions;
using JS::IsAcceptableThis;
using JS::NativeImpl;
using JS::Rooted;
using JS::RootedFunction;
using JS::RootedId;
using JS::RootedObject;
using JS::RootedScript;
using JS::RootedString;
using JS::RootedValue;
using JS::Handle;
using JS::HandleFunction;
using JS::HandleId;
using JS::HandleObject;
using JS::HandleScript;
using JS::HandleString;
using JS::HandleValue;
using JS::MutableHandle;
using JS::MutableHandleFunction;
using JS::MutableHandleId;
using JS::MutableHandleObject;
using JS::MutableHandleScript;
using JS::MutableHandleString;
using JS::MutableHandleValue;
using JS::Zone;
} /* namespace js */
#endif /* NamespaceImports_h */

View File

@ -223,7 +223,8 @@ if test "$GNU_CC"; then
CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections"
fi
CXXFLAGS="$CXXFLAGS -fno-exceptions"
CFLAGS="$CFLAGS -fno-math-errno"
CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-math-errno"
fi
dnl ========================================================

View File

@ -7,7 +7,6 @@
#ifndef builtin_BinaryData_h
#define builtin_BinaryData_h
#include "jsapi.h"
#include "jsobj.h"
#include "builtin/TypeRepresentation.h"

View File

@ -7,8 +7,8 @@
#ifndef builtin_Eval_h
#define builtin_Eval_h
#include "jsapi.h"
#include "jsbytecode.h"
#include "NamespaceImports.h"
namespace js {

View File

@ -7,7 +7,7 @@
#ifndef builtin_Intl_h
#define builtin_Intl_h
#include "jsapi.h"
#include "NamespaceImports.h"
#include "js/RootingAPI.h"

View File

@ -7,7 +7,7 @@
#ifndef builtin_TestingFunctions_h
#define builtin_TestingFunctions_h
#include "jsapi.h"
#include "NamespaceImports.h"
namespace js {
@ -15,10 +15,10 @@ bool
DefineTestingFunctions(JSContext *cx, HandleObject obj);
bool
testingFunc_inParallelSection(JSContext *cx, unsigned argc, jsval *vp);
testingFunc_inParallelSection(JSContext *cx, unsigned argc, Value *vp);
bool
testingFunc_bailout(JSContext *cx, unsigned argc, jsval *vp);
testingFunc_bailout(JSContext *cx, unsigned argc, Value *vp);
} /* namespace js */

View File

@ -232,7 +232,7 @@ changequote(,)
MOZJS_MAJOR_VERSION=`echo $MOZILLA_VERSION | sed "s|\(^[0-9]*\)\.[0-9]*.*|\1|"`
MOZJS_MINOR_VERSION=`echo $MOZILLA_VERSION | sed "s|^[0-9]*\.\([0-9]*\).*|\1|"`
MOZJS_PATCH_VERSION=`echo $MOZILLA_VERSION | sed "s|^[0-9]*\.[0-9]*[^0-9]*||"`
IS_ALPHA=`echo $MOZILLA_VERSION | grep [ab]`
IS_ALPHA=`echo $MOZILLA_VERSION | grep '[ab]'`
dnl XXX in a temporary bid to avoid developer anger at renaming files
dnl XXX before "js" symlinks exist, don't change names.

View File

@ -7,7 +7,7 @@
#ifndef ds_IdValuePair_h
#define ds_IdValuePair_h
#include "jsapi.h"
#include "NamespaceImports.h"
namespace js {

View File

@ -7,7 +7,7 @@
#ifndef frontend_BytecodeCompiler_h
#define frontend_BytecodeCompiler_h
#include "jsapi.h"
#include "NamespaceImports.h"
class JSLinearString;

View File

@ -317,6 +317,12 @@ struct CompileError {
}
~CompileError();
void throwError(JSContext *cx);
private:
// CompileError owns raw allocated memory, so disable assignment and copying
// for safety.
void operator=(const CompileError &) MOZ_DELETE;
CompileError(const CompileError &) MOZ_DELETE;
};
// Ideally, tokenizing would be entirely independent of context. But the

View File

@ -8,6 +8,7 @@
#define gc_Barrier_h
#include "jsapi.h"
#include "NamespaceImports.h"
#include "gc/Heap.h"
#include "js/HashTable.h"

View File

@ -10,10 +10,11 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/PodOperations.h"
#include "jsapi.h"
#include "jsalloc.h"
#include "jspubtd.h"
#include "js/GCAPI.h"
#include "js/Vector.h"
struct JSCompartment;

View File

@ -21,6 +21,7 @@
// actually run.)
#include "jsapi.h"
#include "NamespaceImports.h"
void breakpoint();

View File

@ -5223,7 +5223,7 @@ StackDecrementForCall(MacroAssembler &masm, const VectorT &argTypes, unsigned ex
static const unsigned FramePushedAfterSave = NonVolatileRegs.gprs().size() * STACK_SLOT_SIZE +
NonVolatileRegs.fpus().size() * sizeof(double);
#ifndef JS_CPU_ARM
static bool
GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFunc)
{
@ -5237,72 +5237,85 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
// PushRegsInMask(NonVolatileRegs).
masm.setFramePushed(0);
masm.PushRegsInMask(NonVolatileRegs);
JS_ASSERT(masm.framePushed() == FramePushedAfterSave);
// Remember the stack pointer in the current AsmJSActivation. This will be
// used by error exit paths to set the stack pointer back to what it was
// right after the (C++) caller's non-volatile registers were saved so that
// they can be restored.
JS_ASSERT(masm.framePushed() == FramePushedAfterSave);
Register activation = ABIArgGenerator::NonArgReturnVolatileReg0;
LoadAsmJSActivationIntoRegister(masm, activation);
masm.movePtr(StackPointer, Operand(activation, AsmJSActivation::offsetOfErrorRejoinSP()));
masm.storePtr(StackPointer, Address(activation, AsmJSActivation::offsetOfErrorRejoinSP()));
#if defined(JS_CPU_X64)
// Install the heap pointer into the globally-pinned HeapReg. The heap
// pointer is stored in the global data section and is patched at dynamic
// link time.
CodeOffsetLabel label = masm.loadRipRelativeInt64(HeapReg);
m.addGlobalAccess(AsmJSGlobalAccess(label.offset(), m.module().heapOffset()));
// ARM has a globally-pinned GlobalReg (x64 uses RIP-relative addressing,
// x86 uses immediates in effective addresses) and NaN register (used as
// part of the out-of-bounds handling in heap loads/stores).
#if defined(JS_CPU_ARM)
masm.movePtr(IntArgReg1, GlobalReg);
masm.ma_vimm(js_NaN, NANReg);
#endif
// ARM and x64 have a globally-pinned HeapReg (x86 uses immediates in
// effective addresses).
#if defined(JS_CPU_X64) || defined(JS_CPU_ARM)
masm.loadPtr(Address(IntArgReg1, m.module().heapOffset()), HeapReg);
#endif
// Get 'argv' into a non-arg register and save it on the stack.
Register argv = ABIArgGenerator::NonArgReturnVolatileReg0;
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg1;
#if defined(JS_CPU_X86)
masm.movl(Operand(StackPointer, NativeFrameSize + masm.framePushed()), argv);
#elif defined(JS_CPU_X64)
masm.movq(IntArgReg0, argv);
masm.Push(argv);
masm.loadPtr(Address(StackPointer, NativeFrameSize + masm.framePushed()), argv);
#else
masm.movePtr(IntArgReg0, argv);
#endif
masm.Push(argv);
// Bump the stack for the call.
const ModuleCompiler::Func &func = *m.lookupFunction(exportedFunc.name());
unsigned stackDec = StackDecrementForCall(masm, func.sig().args());
masm.reserveStack(stackDec);
// Copy parameters out of argv and into the registers/stack-slots specified by
// the system ABI.
for (ABIArgTypeIter iter(func.sig().args()); !iter.done(); iter++) {
Operand src(argv, iter.index() * sizeof(uint64_t));
unsigned argOffset = iter.index() * sizeof(uint64_t);
Address src(argv, argOffset);
switch (iter->kind()) {
case ABIArg::GPR:
masm.load32(src, iter->gpr());
break;
case ABIArg::FPU:
#if defined(JS_CPU_ARM) and !defined(JS_CPU_ARM_HARDFP)
masm.ma_dataTransferN(IsLoad, 64, true, argv, Imm32(argOffset),
Register::FromCode(iter->fpu().code()*2));
#else
masm.loadDouble(src, iter->fpu());
#endif
break;
case ABIArg::Stack:
if (iter.mirType() == MIRType_Int32) {
masm.load32(src, scratch);
masm.storePtr(scratch, Operand(StackPointer, iter->offsetFromArgBase()));
masm.storePtr(scratch, Address(StackPointer, iter->offsetFromArgBase()));
} else {
JS_ASSERT(iter.mirType() == MIRType_Double);
masm.loadDouble(src, ScratchFloatReg);
masm.storeDouble(ScratchFloatReg, Operand(StackPointer, iter->offsetFromArgBase()));
masm.storeDouble(ScratchFloatReg, Address(StackPointer, iter->offsetFromArgBase()));
}
break;
}
}
// Call into the real function.
AssertStackAlignment(masm);
masm.call(func.code());
// Pop the stack and recover the original 'argv' argument passed to the
// trampoline (which was pushed on the stack).
masm.freeStack(stackDec);
#if defined(JS_CPU_X86)
masm.movl(Operand(StackPointer, NativeFrameSize + masm.framePushed()), argv);
#elif defined(JS_CPU_X64)
masm.Pop(argv);
#endif
// Store return value in argv[0]
// Store the return value in argv[0]
switch (func.sig().retType().which()) {
case RetType::Void:
break;
@ -5310,119 +5323,7 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
masm.storeValue(JSVAL_TYPE_INT32, ReturnReg, Address(argv, 0));
break;
case RetType::Double:
masm.canonicalizeDouble(ReturnFloatReg);
masm.storeDouble(ReturnFloatReg, Address(argv, 0));
break;
}
// Restore clobbered registers.
masm.PopRegsInMask(NonVolatileRegs);
JS_ASSERT(masm.framePushed() == 0);
masm.move32(Imm32(true), ReturnReg);
masm.ret();
return true;
}
#else
static bool
GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFunc)
{
const ModuleCompiler::Func &func = *m.lookupFunction(exportedFunc.name());
MacroAssembler &masm = m.masm();
// In constrast to the X64 system ABI, the Ion convention is that all
// registers are clobbered by calls. Thus, we must save the caller's
// non-volatile registers.
//
// NB: GenerateExits assumes that masm.framePushed() == 0 before
// PushRegsInMask(NonVolatileRegs).
masm.setFramePushed(0);
masm.PushRegsInMask(NonVolatileRegs);
JS_ASSERT(masm.framePushed() == FramePushedAfterSave);
JS_ASSERT(masm.framePushed() % 8 == 0);
// Remember the stack pointer in the current AsmJSActivation. This will be
// used by error exit paths to set the stack pointer back to what it was
// right after the (C++) caller's non-volatile registers were saved so that
// they can be restored.
LoadAsmJSActivationIntoRegister(masm, r9);
masm.ma_str(StackPointer, Address(r9, AsmJSActivation::offsetOfErrorRejoinSP()));
// masm.storeErrorRejoinSp();
// Move the parameters into non-argument registers since we are about to
// clobber these registers with the contents of argv.
Register argv = r9;
masm.movePtr(IntArgReg1, GlobalReg); // globalData
masm.movePtr(IntArgReg0, argv); // argv
masm.ma_ldr(Operand(GlobalReg, Imm32(m.module().heapOffset())), HeapReg);
// Remember argv so that we can load argv[0] after the call.
JS_ASSERT(masm.framePushed() % 8 == 0);
masm.Push(argv);
JS_ASSERT(masm.framePushed() % 8 == 4);
// Determine how many stack slots we need to hold arguments that don't fit
// in registers.
unsigned numStackArgs = 0;
for (ABIArgTypeIter iter(func.sig().args()); !iter.done(); iter++) {
if (iter->kind() == ABIArg::Stack)
numStackArgs++;
}
// Before calling, we must ensure sp % 16 == 0. Since (sp % 16) = 8 on
// entry, we need to push 8 (mod 16) bytes.
//JS_ASSERT(AlignmentAtPrologue == 8);
JS_ASSERT(masm.framePushed() % 8 == 4);
unsigned stackDec = numStackArgs * sizeof(double) + (masm.framePushed() >> 2) % 2 * sizeof(uint32_t);
masm.reserveStack(stackDec);
//JS_ASSERT(masm.framePushed() % 8 == 0);
if(getenv("GDB_BREAK")) {
masm.breakpoint(js::jit::Assembler::Always);
}
// Copy parameters out of argv into the registers/stack-slots specified by
// the system ABI.
for (ABIArgTypeIter iter(func.sig().args()); !iter.done(); iter++) {
unsigned argOffset = iter.index() * sizeof(uint64_t);
switch (iter->kind()) {
case ABIArg::GPR:
masm.ma_ldr(Operand(argv, argOffset), iter->gpr());
break;
case ABIArg::FPU:
#if defined(JS_CPU_ARM_HARDFP)
masm.ma_vldr(Operand(argv, argOffset), iter->fpu());
#else
// The ABI is expecting a double value in a pair of gpr's. Figure out which gprs it is,
// and use them explicityl.
masm.ma_dataTransferN(IsLoad, 64, true, argv, Imm32(argOffset), Register::FromCode(iter->fpu().code()*2));
#endif
break;
case ABIArg::Stack:
if (iter.mirType() == MIRType_Int32) {
masm.memMove32(Address(argv, argOffset), Address(StackPointer, iter->offsetFromArgBase()));
} else {
masm.memMove64(Address(argv, argOffset), Address(StackPointer, iter->offsetFromArgBase()));
}
break;
}
}
masm.ma_vimm(js_NaN, NANReg);
masm.call(func.code());
// Recover argv.
masm.freeStack(stackDec);
masm.Pop(argv);
// Store the result in argv[0].
switch (func.sig().retType().which()) {
case RetType::Void:
break;
case RetType::Signed:
masm.storeValue(JSVAL_TYPE_INT32, ReturnReg, Address(argv, 0));
break;
case RetType::Double:
#ifndef JS_CPU_ARM_HARDFP
#if defined(JS_CPU_ARM) and !defined(JS_CPU_ARM_HARDFP)
masm.ma_vxfer(r0, r1, d0);
#endif
masm.canonicalizeDouble(ReturnFloatReg);
@ -5430,13 +5331,15 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
break;
}
// Restore clobbered non-volatile registers of the caller.
masm.PopRegsInMask(NonVolatileRegs);
masm.ma_mov(Imm32(true), ReturnReg);
JS_ASSERT(masm.framePushed() == 0);
masm.move32(Imm32(true), ReturnReg);
masm.abiret();
return true;
}
#endif
static inline bool
TryEnablingIon(JSContext *cx, AsmJSModule &module, HandleFunction fun, uint32_t exitIndex,
@ -6029,16 +5932,9 @@ GenerateStackOverflowExit(ModuleCompiler &m, Label *throwLabel)
LoadAsmJSActivationIntoRegister(masm, eax);
LoadJSContextFromActivation(masm, eax, eax);
masm.storePtr(eax, Address(StackPointer, 0));
#elif defined(JS_CPU_X64)
LoadAsmJSActivationIntoRegister(masm, IntArgReg0);
LoadJSContextFromActivation(masm, IntArgReg0, IntArgReg0);
#else
// on ARM, we should always be aligned, just do the context manipulation
// and make the call.
LoadAsmJSActivationIntoRegister(masm, IntArgReg0);
LoadJSContextFromActivation(masm, IntArgReg0, IntArgReg0);
#endif
void (*pf)(JSContext*) = js_ReportOverRecursed;
masm.call(ImmWord(JS_FUNC_TO_DATA_PTR(void*, pf)));

View File

@ -7,7 +7,9 @@
#ifndef jit_AsmJS_h
#define jit_AsmJS_h
#include "jsapi.h"
#include <stddef.h>
#include "js/TypeDecls.h"
namespace js {

View File

@ -362,13 +362,8 @@ CallAsmJS(JSContext *cx, unsigned argc, Value *vp)
JitActivation jitActivation(cx, /* firstFrameIsConstructing = */ false, /* active */ false);
// Call the per-exported-function trampoline created by GenerateEntry.
#ifdef JS_CPU_ARM
if (!module.entryTrampoline(func)(coercedArgs.begin(), module.globalData()))
return false;
#else
if (!module.entryTrampoline(func)(coercedArgs.begin()))
return false;
#endif
}
switch (func.returnType()) {

View File

@ -7,7 +7,7 @@
#ifndef jit_AsmJSLink_h
#define jit_AsmJSLink_h
#include "jsapi.h"
#include "NamespaceImports.h"
namespace js {

View File

@ -183,11 +183,7 @@ class AsmJSModule
ionCodeOffset_ = off;
}
};
#ifdef JS_CPU_ARM
typedef int32_t (*CodePtr)(uint64_t *args, uint8_t *global);
#else
typedef int32_t (*CodePtr)(uint64_t *args);
#endif
typedef Vector<AsmJSCoercion, 0, SystemAllocPolicy> ArgCoercionVector;

View File

@ -9,7 +9,7 @@
#ifdef DEBUG
#include "jsapi.h"
#include "NamespaceImports.h"
#include "js/RootingAPI.h"

View File

@ -1786,6 +1786,9 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call)
if (!emitCallToUncompiledScriptPar(call, calleereg))
return false;
break;
default:
MOZ_ASSUME_UNREACHABLE("No such execution mode");
}
masm.bind(&end);
@ -1911,6 +1914,9 @@ CodeGenerator::visitCallKnown(LCallKnown *call)
if (!emitCallToUncompiledScriptPar(call, calleereg))
return false;
break;
default:
MOZ_ASSUME_UNREACHABLE("No such execution mode");
}
masm.bind(&end);
@ -4800,7 +4806,7 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole *ool)
masm.jump(ool->rejoin());
return true;
case ParallelExecution:
case ParallelExecution: {
//////////////////////////////////////////////////////////////
// If the problem is that we do not have sufficient capacity,
// try to reallocate the elements array and then branch back
@ -4857,6 +4863,10 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole *ool)
return true;
}
default:
MOZ_ASSUME_UNREACHABLE("No such execution mode");
}
JS_ASSERT(false);
return false;
}

View File

@ -30,11 +30,15 @@ CountArgSlots(JSScript *script, JSFunction *fun)
enum ExecutionMode {
// Normal JavaScript execution
SequentialExecution = 0,
SequentialExecution,
// JavaScript code to be executed in parallel worker threads,
// e.g. by ParallelArray
ParallelExecution
ParallelExecution,
// MIR analysis performed when invoking 'new' on a script, to determine
// definite properties
DefinitePropertiesAnalysis
};
// Not as part of the enum so we don't get warnings about unhandled enum

View File

@ -22,6 +22,7 @@ HasIonScript(JSScript *script, ExecutionMode cmode)
switch (cmode) {
case SequentialExecution: return script->hasIonScript();
case ParallelExecution: return script->hasParallelIonScript();
default:;
}
MOZ_ASSUME_UNREACHABLE("No such execution mode");
}
@ -32,6 +33,7 @@ GetIonScript(JSScript *script, ExecutionMode cmode)
switch (cmode) {
case SequentialExecution: return script->maybeIonScript();
case ParallelExecution: return script->maybeParallelIonScript();
default:;
}
MOZ_ASSUME_UNREACHABLE("No such execution mode");
}
@ -42,6 +44,7 @@ SetIonScript(JSScript *script, ExecutionMode cmode, IonScript *ionScript)
switch (cmode) {
case SequentialExecution: script->setIonScript(ionScript); return;
case ParallelExecution: script->setParallelIonScript(ionScript); return;
default:;
}
MOZ_ASSUME_UNREACHABLE("No such execution mode");
}
@ -52,6 +55,7 @@ OffsetOfIonInJSScript(ExecutionMode cmode)
switch (cmode) {
case SequentialExecution: return JSScript::offsetOfIonScript();
case ParallelExecution: return JSScript::offsetOfParallelIonScript();
default:;
}
MOZ_ASSUME_UNREACHABLE("No such execution mode");
}
@ -62,6 +66,8 @@ CanIonCompile(JSScript *script, ExecutionMode cmode)
switch (cmode) {
case SequentialExecution: return script->canIonCompile();
case ParallelExecution: return script->canParallelIonCompile();
case DefinitePropertiesAnalysis: return true;
default:;
}
MOZ_ASSUME_UNREACHABLE("No such execution mode");
return false;
@ -79,6 +85,7 @@ CompilingOffThread(JSScript *script, ExecutionMode cmode)
switch (cmode) {
case SequentialExecution: return script->isIonCompilingOffThread();
case ParallelExecution: return script->isParallelIonCompilingOffThread();
default:;
}
MOZ_ASSUME_UNREACHABLE("No such execution mode");
}
@ -89,6 +96,7 @@ CompilingOffThread(HandleScript script, ExecutionMode cmode)
switch (cmode) {
case SequentialExecution: return script->isIonCompilingOffThread();
case ParallelExecution: return script->isParallelIonCompilingOffThread();
default:;
}
MOZ_ASSUME_UNREACHABLE("No such execution mode");
}
@ -99,6 +107,7 @@ CompilerOutputKind(ExecutionMode cmode)
switch (cmode) {
case SequentialExecution: return types::CompilerOutput::Ion;
case ParallelExecution: return types::CompilerOutput::ParallelIon;
default:;
}
MOZ_ASSUME_UNREACHABLE("No such execution mode");
}

View File

@ -2451,6 +2451,8 @@ jit::Invalidate(JSContext *cx, JSScript *script, ExecutionMode mode, bool resetU
if (!scripts.append(script->parallelIonScript()->recompileInfo()))
return false;
break;
default:
MOZ_ASSUME_UNREACHABLE("No such execution mode");
}
Invalidate(cx, scripts, resetUses);
@ -2542,6 +2544,9 @@ jit::ForbidCompilation(JSContext *cx, JSScript *script, ExecutionMode mode)
script->setParallelIonScript(ION_DISABLED_SCRIPT);
return;
default:
MOZ_ASSUME_UNREACHABLE("No such execution mode");
}
MOZ_ASSUME_UNREACHABLE("No such execution mode");

View File

@ -8,14 +8,20 @@
#include "jsanalyze.h"
#include "jit/BaselineInspector.h"
#include "jit/Ion.h"
#include "jit/IonBuilder.h"
#include "jit/LIR.h"
#include "jit/MIRGraph.h"
#include "jsinferinlines.h"
#include "jsscriptinlines.h"
using namespace js;
using namespace js::jit;
using mozilla::DebugOnly;
// A critical edge is an edge which is neither its successor's only predecessor
// nor its predecessor's only successor. Critical edges must be split to
// prevent copy-insertion and code motion from affecting other edges.
@ -1605,3 +1611,263 @@ LinearSum::print(Sprinter &sp) const
else if (constant_ < 0)
sp.printf("%d", constant_);
}
static bool
AnalyzePoppedThis(JSContext *cx, types::TypeObject *type,
MDefinition *thisValue, MInstruction *ins, bool definitelyExecuted,
HandleObject baseobj,
Vector<types::TypeNewScript::Initializer> *initializerList,
Vector<jsid> *accessedProperties,
bool *phandled)
{
// Determine the effect that a use of the |this| value when calling |new|
// on a script has on the properties definitely held by the new object.
if (ins->isCallSetProperty()) {
MCallSetProperty *setprop = ins->toCallSetProperty();
if (setprop->obj() != thisValue)
return true;
// Don't use GetAtomId here, we need to watch for SETPROP on
// integer properties and bail out. We can't mark the aggregate
// JSID_VOID type property as being in a definite slot.
RootedId id(cx, NameToId(setprop->name()));
if (types::IdToTypeId(id) != id ||
id == NameToId(cx->names().classPrototype) ||
id == NameToId(cx->names().proto) ||
id == NameToId(cx->names().constructor))
{
return true;
}
// Ignore assignments to properties that were already written to.
if (baseobj->nativeLookup(cx, id)) {
*phandled = true;
return true;
}
// Don't add definite properties for properties that were already
// read in the constructor.
for (size_t i = 0; i < accessedProperties->length(); i++) {
if ((*accessedProperties)[i] == id)
return true;
}
if (baseobj->slotSpan() >= (types::TYPE_FLAG_DEFINITE_MASK >> types::TYPE_FLAG_DEFINITE_SHIFT)) {
// Maximum number of definite properties added.
return true;
}
// Assignments to new properties must always execute.
if (!definitelyExecuted)
return true;
if (!types::AddClearDefiniteGetterSetterForPrototypeChain(cx, type, id)) {
// The prototype chain already contains a getter/setter for this
// property, or type information is too imprecise.
return true;
}
DebugOnly<unsigned> slotSpan = baseobj->slotSpan();
RootedValue value(cx, UndefinedValue());
if (!DefineNativeProperty(cx, baseobj, id, value, NULL, NULL,
JSPROP_ENUMERATE, 0, 0, DNP_SKIP_TYPE))
{
return false;
}
JS_ASSERT(baseobj->slotSpan() != slotSpan);
JS_ASSERT(!baseobj->inDictionaryMode());
Vector<MResumePoint *> callerResumePoints(cx);
MBasicBlock *block = ins->block();
for (MResumePoint *rp = block->callerResumePoint();
rp;
block = rp->block(), rp = block->callerResumePoint())
{
JSScript *script = rp->block()->info().script();
types::AddClearDefiniteFunctionUsesInScript(cx, type, script, block->info().script());
if (!callerResumePoints.append(rp))
return false;
}
for (int i = callerResumePoints.length() - 1; i >= 0; i--) {
MResumePoint *rp = callerResumePoints[i];
JSScript *script = rp->block()->info().script();
types::TypeNewScript::Initializer entry(types::TypeNewScript::Initializer::SETPROP_FRAME,
rp->pc() - script->code);
if (!initializerList->append(entry))
return false;
}
JSScript *script = ins->block()->info().script();
types::TypeNewScript::Initializer entry(types::TypeNewScript::Initializer::SETPROP,
setprop->resumePoint()->pc() - script->code);
if (!initializerList->append(entry))
return false;
*phandled = true;
return true;
}
if (ins->isCallGetProperty()) {
MCallGetProperty *get = ins->toCallGetProperty();
/*
* Properties can be read from the 'this' object if the following hold:
*
* - The read is not on a getter along the prototype chain, which
* could cause 'this' to escape.
*
* - The accessed property is either already a definite property or
* is not later added as one. Since the definite properties are
* added to the object at the point of its creation, reading a
* definite property before it is assigned could incorrectly hit.
*/
RootedId id(cx, NameToId(get->name()));
if (types::IdToTypeId(id) != id)
return true;
if (!baseobj->nativeLookup(cx, id) && !accessedProperties->append(id.get()))
return false;
if (!types::AddClearDefiniteGetterSetterForPrototypeChain(cx, type, id)) {
// The |this| value can escape if any property reads it does go
// through a getter.
return true;
}
*phandled = true;
return true;
}
if (ins->isPostWriteBarrier()) {
*phandled = true;
return true;
}
return true;
}
static int
CmpInstructions(const void *a, const void *b)
{
return (*static_cast<MInstruction * const *>(a))->id() -
(*static_cast<MInstruction * const *>(b))->id();
}
bool
jit::AnalyzeNewScriptProperties(JSContext *cx, JSFunction *fun,
types::TypeObject *type, HandleObject baseobj,
Vector<types::TypeNewScript::Initializer> *initializerList)
{
// When invoking 'new' on the specified script, try to find some properties
// which will definitely be added to the created object before it has a
// chance to escape and be accessed elsewhere.
if (!fun->nonLazyScript()->compileAndGo)
return true;
if (!fun->nonLazyScript()->ensureHasTypes(cx))
return false;
types::TypeScript::SetThis(cx, fun->nonLazyScript(), types::Type::ObjectType(type));
Vector<jsid> accessedProperties(cx);
LifoAlloc alloc(JSCompartment::ANALYSIS_LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
TempAllocator temp(&alloc);
IonContext ictx(cx, &temp);
types::AutoEnterAnalysis enter(cx);
if (!fun->nonLazyScript()->ensureRanAnalysis(cx))
return false;
MIRGraph graph(&temp);
CompileInfo info(fun->nonLazyScript(), fun,
/* osrPc = */ NULL, /* constructing = */ false,
DefinitePropertiesAnalysis);
AutoTempAllocatorRooter root(cx, &temp);
BaselineInspector inspector(cx, fun->nonLazyScript());
IonBuilder builder(cx, &temp, &graph, &inspector, &info, /* baselineFrame = */ NULL);
if (!builder.build()) {
if (builder.abortReason() == AbortReason_Alloc)
return false;
return true;
}
if (!SplitCriticalEdges(graph))
return false;
if (!RenumberBlocks(graph))
return false;
if (!BuildDominatorTree(graph))
return false;
if (!EliminatePhis(&builder, graph, AggressiveObservability))
return false;
MDefinition *thisValue = graph.begin()->getSlot(info.thisSlot());
// Get a list of instructions using the |this| value in the order they
// appear in the graph.
Vector<MInstruction *> instructions(cx);
Vector<MDefinition *> useWorklist(cx);
for (MUseDefIterator uses(thisValue); uses; uses++) {
MDefinition *use = uses.def();
// Don't track |this| through assignments to phis.
if (!use->isInstruction())
return true;
if (!instructions.append(use->toInstruction()))
return false;
}
// Sort the instructions to visit in increasing order.
qsort(instructions.begin(), instructions.length(),
sizeof(MInstruction *), CmpInstructions);
// Find all exit blocks in the graph.
Vector<MBasicBlock *> exitBlocks(cx);
for (MBasicBlockIterator block(graph.begin()); block != graph.end(); block++) {
if (!block->numSuccessors() && !exitBlocks.append(*block))
return false;
}
for (size_t i = 0; i < instructions.length(); i++) {
MInstruction *ins = instructions[i];
// Track whether the use of |this| is in unconditional code, i.e.
// the block dominates all graph exits.
bool definitelyExecuted = true;
for (size_t i = 0; i < exitBlocks.length(); i++) {
for (MBasicBlock *exit = exitBlocks[i];
exit != ins->block();
exit = exit->immediateDominator())
{
if (exit == exit->immediateDominator()) {
definitelyExecuted = false;
break;
}
}
}
bool handled = false;
if (!AnalyzePoppedThis(cx, type, thisValue, ins, definitelyExecuted,
baseobj, initializerList, &accessedProperties, &handled))
{
return false;
}
if (!handled)
return true;
}
return true;
}

View File

@ -124,6 +124,11 @@ class LinearSum
int32_t constant_;
};
bool
AnalyzeNewScriptProperties(JSContext *cx, JSFunction *fun,
types::TypeObject *type, HandleObject baseobj,
Vector<types::TypeNewScript::Initializer> *initializerList);
} // namespace jit
} // namespace js

View File

@ -3929,16 +3929,21 @@ IonBuilder::makeInliningDecision(JSFunction *target, CallInfo &callInfo)
return false;
}
// Caller must be... somewhat hot.
// Caller must be... somewhat hot. Ignore use counts when inlining for
// the definite properties analysis, as the caller has not run yet.
uint32_t callerUses = script()->getUseCount();
if (callerUses < js_IonOptions.usesBeforeInlining()) {
if (callerUses < js_IonOptions.usesBeforeInlining() &&
info().executionMode() != DefinitePropertiesAnalysis)
{
IonSpew(IonSpew_Inlining, "%s:%d - Vetoed: caller is insufficiently hot.",
targetScript->filename(), targetScript->lineno);
return false;
}
// Callee must be hot relative to the caller.
if (targetScript->getUseCount() * js_IonOptions.inlineUseCountRatio < callerUses) {
if (targetScript->getUseCount() * js_IonOptions.inlineUseCountRatio < callerUses &&
info().executionMode() != DefinitePropertiesAnalysis)
{
IonSpew(IonSpew_Inlining, "%s:%d - Vetoed: callee is not hot.",
targetScript->filename(), targetScript->lineno);
return false;
@ -4803,7 +4808,7 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc)
// When this script isn't inlined, use MApplyArgs,
// to copy the arguments from the stack and call the function
if (inliningDepth_ == 0) {
if (inliningDepth_ == 0 && info().executionMode() != DefinitePropertiesAnalysis) {
// Vp
MPassArg *passVp = current->pop()->toPassArg();
@ -4841,7 +4846,9 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc)
// When inlining we have the arguments the function gets called with
// and can optimize even more, by just calling the functions with the args.
JS_ASSERT(inliningDepth_ > 0);
// We also try this path when doing the definite properties analysis, as we
// can inline the apply() target and don't care about the actual arguments
// that were passed in.
CallInfo callInfo(cx, false);
@ -4853,8 +4860,10 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc)
// Arguments
Vector<MDefinition *> args(cx);
if (inliningDepth_) {
if (!args.append(inlineCallInfo_->argv().begin(), inlineCallInfo_->argv().end()))
return false;
}
callInfo.setArgs(&args);
// This
@ -5570,6 +5579,7 @@ IonBuilder::jsop_initprop(HandlePropertyName name)
// forkjoin.cpp for more information.
switch (info().executionMode()) {
case SequentialExecution:
case DefinitePropertiesAnalysis:
break;
case ParallelExecution:
needsBarrier = false;
@ -8019,11 +8029,22 @@ IonBuilder::jsop_getprop(HandlePropertyName name)
if (!getPropTryArgumentsLength(&emitted) || emitted)
return emitted;
bool barrier = PropertyReadNeedsTypeBarrier(cx, current->peek(-1), name, types);
// Try to hardcode known constants.
if (!getPropTryConstant(&emitted, id, types) || emitted)
return emitted;
bool barrier = PropertyReadNeedsTypeBarrier(cx, current->peek(-1), name, types);
// Except when loading constants above, always use a call if we are doing
// the definite properties analysis and not actually emitting code, to
// simplify later analysis.
if (info().executionMode() == DefinitePropertiesAnalysis) {
MDefinition *obj = current->pop();
MCallGetProperty *call = MCallGetProperty::New(obj, name);
current->add(call);
current->push(call);
return resumeAfter(call);
}
// Try to emit loads from definite slots.
if (!getPropTryDefiniteSlot(&emitted, name, barrier, types) || emitted)
@ -8370,6 +8391,15 @@ IonBuilder::jsop_setprop(HandlePropertyName name)
RootedId id(cx, NameToId(name));
bool emitted = false;
// Always use a call if we are doing the definite properties analysis and
// not actually emitting code, to simplify later analysis.
if (info().executionMode() == DefinitePropertiesAnalysis) {
MInstruction *ins = MCallSetProperty::New(obj, value, name, script()->strict);
current->add(ins);
current->push(value);
return resumeAfter(ins);
}
// Add post barrier if needed.
if (NeedsPostBarrier(info(), value))
current->add(MPostWriteBarrier::New(obj, value));
@ -8759,6 +8789,15 @@ IonBuilder::jsop_this()
return true;
}
// If we are doing a definite properties analysis, we don't yet know the
// |this| type as its type object is being created right now. Instead of
// bailing out just push the |this| slot, as this code won't actually
// execute and it does not matter whether |this| is primitive.
if (info().executionMode() == DefinitePropertiesAnalysis) {
current->pushSlot(info().thisSlot());
return true;
}
return abort("JSOP_THIS hard case not yet handled");
}

View File

@ -1102,7 +1102,7 @@ IonBuilder::inlineForceSequentialOrInParallelSection(CallInfo &callInfo)
// access the "in warmup" flag of the runtime.
return InliningStatus_NotInlined;
case ParallelExecution:
case ParallelExecution: {
// During Parallel Exec, we always force sequential, so
// replace with true. This permits UCE to eliminate the
// entire path as dead, which is important.
@ -1113,6 +1113,9 @@ IonBuilder::inlineForceSequentialOrInParallelSection(CallInfo &callInfo)
return InliningStatus_Inlined;
}
default:;
}
MOZ_ASSUME_UNREACHABLE("Invalid execution mode");
}
@ -1285,6 +1288,7 @@ IonBuilder::inlineNewDenseArray(CallInfo &callInfo)
return inlineNewDenseArrayForSequentialExecution(callInfo);
case ParallelExecution:
return inlineNewDenseArrayForParallelExecution(callInfo);
default:;
}
MOZ_ASSUME_UNREACHABLE("unknown ExecutionMode");

View File

@ -147,7 +147,7 @@ PerfSpewer::writeProfile(JSScript *script,
if (size > 0) {
fprintf(fp_,
"%lx %lx %s:%d: Func%02d\n",
reinterpret_cast<unsigned long>(code->raw()),
reinterpret_cast<uintptr_t>(code->raw()),
size,
script->filename(),
script->lineno,

View File

@ -1787,88 +1787,6 @@ ScriptAnalysis::needsArgsObj(JSContext *cx)
return needsArgsObj(cx, seen, SSAValue::PushedValue(pcOff, 0));
}
CrossSSAValue
CrossScriptSSA::foldValue(const CrossSSAValue &cv)
{
const Frame &frame = getFrame(cv.frame);
const SSAValue &v = cv.v;
JSScript *parentScript = NULL;
ScriptAnalysis *parentAnalysis = NULL;
if (frame.parent != INVALID_FRAME) {
parentScript = getFrame(frame.parent).script;
parentAnalysis = parentScript->analysis();
}
if (v.kind() == SSAValue::VAR && v.varInitial() && parentScript) {
uint32_t slot = v.varSlot();
if (slot >= ArgSlot(0) && slot < LocalSlot(frame.script, 0)) {
uint32_t argc = GET_ARGC(frame.parentpc);
SSAValue argv = parentAnalysis->poppedValue(frame.parentpc, argc - 1 - (slot - ArgSlot(0)));
return foldValue(CrossSSAValue(frame.parent, argv));
}
}
if (v.kind() == SSAValue::PUSHED) {
jsbytecode *pc = frame.script->code + v.pushedOffset();
switch (JSOp(*pc)) {
case JSOP_THIS:
if (parentScript) {
uint32_t argc = GET_ARGC(frame.parentpc);
SSAValue thisv = parentAnalysis->poppedValue(frame.parentpc, argc);
return foldValue(CrossSSAValue(frame.parent, thisv));
}
break;
case JSOP_CALL: {
/*
* If there is a single inline callee with a single return site,
* propagate back to that.
*/
JSScript *callee = NULL;
uint32_t calleeFrame = INVALID_FRAME;
for (unsigned i = 0; i < numFrames(); i++) {
if (iterFrame(i).parent == cv.frame && iterFrame(i).parentpc == pc) {
if (callee)
return cv; /* Multiple callees */
callee = iterFrame(i).script;
calleeFrame = iterFrame(i).index;
}
}
if (callee && callee->analysis()->numReturnSites() == 1) {
ScriptAnalysis *analysis = callee->analysis();
uint32_t offset = 0;
while (offset < callee->length) {
jsbytecode *pc = callee->code + offset;
if (analysis->maybeCode(pc) && JSOp(*pc) == JSOP_RETURN)
return foldValue(CrossSSAValue(calleeFrame, analysis->poppedValue(pc, 0)));
offset += GetBytecodeLength(pc);
}
}
break;
}
case JSOP_TOID: {
/*
* TOID acts as identity for integers, so to get better precision
* we should propagate its popped values forward if it acted as
* identity.
*/
ScriptAnalysis *analysis = frame.script->analysis();
SSAValue toidv = analysis->poppedValue(pc, 0);
if (analysis->getValueTypes(toidv)->getKnownTypeTag() == JSVAL_TYPE_INT32)
return foldValue(CrossSSAValue(cv.frame, toidv));
break;
}
default:;
}
}
return cv;
}
#ifdef DEBUG
void

View File

@ -78,15 +78,6 @@ class Bytecode
/* Whether this is a catch/finally entry point. */
bool exceptionEntry : 1;
/*
* Side effects of this bytecode were not determined by type inference.
* Either a property set with unknown lvalue, or call with unknown callee.
*/
bool monitoredTypes : 1;
/* Call whose result should be monitored. */
bool monitoredTypesReturn : 1;
/*
* Dynamically observed state about the execution of this opcode. These are
* hints about the script for use during compilation.
@ -129,14 +120,6 @@ class Bytecode
*/
Vector<SlotValue> *pendingValues;
};
/* --------- Type inference --------- */
/* Types for all values pushed by this bytecode. */
types::StackTypeSet *pushedTypes;
/* Any type barriers in place at this bytecode. */
types::TypeBarrier *typeBarriers;
};
/*
@ -471,7 +454,6 @@ class SSAValue
uint32_t phiSlot() const;
uint32_t phiLength() const;
const SSAValue &phiValue(uint32_t i) const;
types::TypeSet *phiTypes() const;
/* Offset at which this phi node was created. */
uint32_t phiOffset() const {
@ -571,7 +553,6 @@ class SSAValue
*/
struct SSAPhiNode
{
types::StackTypeSet types;
uint32_t slot;
uint32_t length;
SSAValue *options;
@ -599,13 +580,6 @@ SSAValue::phiValue(uint32_t i) const
return u.phi.node->options[i];
}
inline types::TypeSet *
SSAValue::phiTypes() const
{
JS_ASSERT(kind() == PHI);
return &u.phi.node->types;
}
class SSAUseChain
{
public:
@ -654,7 +628,6 @@ class ScriptAnalysis
bool ranBytecode_;
bool ranSSA_;
bool ranLifetimes_;
bool ranInference_;
#ifdef DEBUG
/* Whether the compartment was in debug mode when we performed the analysis. */
@ -689,15 +662,10 @@ class ScriptAnalysis
bool ranBytecode() { return ranBytecode_; }
bool ranSSA() { return ranSSA_; }
bool ranLifetimes() { return ranLifetimes_; }
bool ranInference() { return ranInference_; }
void analyzeBytecode(JSContext *cx);
void analyzeSSA(JSContext *cx);
void analyzeLifetimes(JSContext *cx);
void analyzeTypes(JSContext *cx);
/* Analyze the effect of invoking 'new' on script. */
void analyzeTypesNew(JSContext *cx);
bool OOM() const { return outOfMemory; }
bool failed() const { return hadFailure; }
@ -760,45 +728,6 @@ class ScriptAnalysis
}
const SlotValue *newValues(const jsbytecode *pc) { return newValues(pc - script_->code); }
inline types::StackTypeSet *pushedTypes(uint32_t offset, uint32_t which = 0);
inline types::StackTypeSet *pushedTypes(const jsbytecode *pc, uint32_t which);
bool hasPushedTypes(const jsbytecode *pc) { return getCode(pc).pushedTypes != NULL; }
types::TypeBarrier *typeBarriers(JSContext *cx, uint32_t offset) {
if (getCode(offset).typeBarriers)
pruneTypeBarriers(cx, offset);
return getCode(offset).typeBarriers;
}
types::TypeBarrier *typeBarriers(JSContext *cx, const jsbytecode *pc) {
return typeBarriers(cx, pc - script_->code);
}
void addTypeBarrier(JSContext *cx, const jsbytecode *pc,
types::TypeSet *target, types::Type type);
void addSingletonTypeBarrier(JSContext *cx, const jsbytecode *pc,
types::TypeSet *target,
HandleObject singleton, HandleId singletonId);
/* Remove obsolete type barriers at the given offset. */
void pruneTypeBarriers(JSContext *cx, uint32_t offset);
/*
* Remove still-active type barriers at the given offset. If 'all' is set,
* then all barriers are removed, otherwise only those deemed excessive
* are removed.
*/
void breakTypeBarriers(JSContext *cx, uint32_t offset, bool all);
/* Break all type barriers used in computing v. */
void breakTypeBarriersSSA(JSContext *cx, const SSAValue &v);
inline void addPushedType(JSContext *cx, uint32_t offset, uint32_t which, types::Type type);
inline types::StackTypeSet *getValueTypes(const SSAValue &v);
inline types::StackTypeSet *poppedTypes(uint32_t offset, uint32_t which);
inline types::StackTypeSet *poppedTypes(const jsbytecode *pc, uint32_t which);
bool trackUseChain(const SSAValue &v) {
JS_ASSERT_IF(v.kind() == SSAValue::VAR, trackSlot(v.varSlot()));
return v.kind() != SSAValue::EMPTY &&
@ -912,9 +841,6 @@ class ScriptAnalysis
{}
};
/* Type inference helpers */
bool analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferenceState &state);
typedef Vector<SSAValue, 16> SeenVector;
bool needsArgsObj(JSContext *cx, SeenVector &seen, const SSAValue &v);
bool needsArgsObj(JSContext *cx, SeenVector &seen, SSAUseChain *use);
@ -928,84 +854,6 @@ class ScriptAnalysis
#endif
};
/* SSA value as used by CrossScriptSSA, identifies the frame it came from. */
struct CrossSSAValue
{
unsigned frame;
SSAValue v;
CrossSSAValue(unsigned frame, const SSAValue &v) : frame(frame), v(v) {}
};
/*
* Analysis for managing SSA values from multiple call stack frames. These are
* created by the backend compiler when inlining functions, and allow for
* values to be tracked as they flow into or out of the inlined frames.
*/
class CrossScriptSSA
{
public:
static const uint32_t OUTER_FRAME = UINT32_MAX;
static const unsigned INVALID_FRAME = uint32_t(-2);
struct Frame {
uint32_t index;
JSScript *script;
uint32_t depth; /* Distance from outer frame to this frame, in sizeof(Value) */
uint32_t parent;
jsbytecode *parentpc;
Frame(uint32_t index, JSScript *script, uint32_t depth, uint32_t parent,
jsbytecode *parentpc)
: index(index), script(script), depth(depth), parent(parent), parentpc(parentpc)
{}
};
const Frame &getFrame(uint32_t index) {
if (index == OUTER_FRAME)
return outerFrame;
return inlineFrames[index];
}
unsigned numFrames() { return 1 + inlineFrames.length(); }
const Frame &iterFrame(unsigned i) {
if (i == 0)
return outerFrame;
return inlineFrames[i - 1];
}
JSScript *outerScript() { return outerFrame.script; }
/* Total length of scripts preceding a frame. */
size_t frameLength(uint32_t index) {
if (index == OUTER_FRAME)
return 0;
size_t res = outerFrame.script->length;
for (unsigned i = 0; i < index; i++)
res += inlineFrames[i].script->length;
return res;
}
inline types::StackTypeSet *getValueTypes(const CrossSSAValue &cv);
bool addInlineFrame(JSScript *script, uint32_t depth, uint32_t parent,
jsbytecode *parentpc)
{
uint32_t index = inlineFrames.length();
return inlineFrames.append(Frame(index, script, depth, parent, parentpc));
}
CrossScriptSSA(JSContext *cx, JSScript *outer)
: outerFrame(OUTER_FRAME, outer, 0, INVALID_FRAME, NULL), inlineFrames(cx)
{}
CrossSSAValue foldValue(const CrossSSAValue &cv);
private:
Frame outerFrame;
Vector<Frame> inlineFrames;
};
#ifdef DEBUG
void PrintBytecode(JSContext *cx, HandleScript script, jsbytecode *pc);
#endif

View File

@ -29,64 +29,6 @@ ScriptAnalysis::poppedValue(const jsbytecode *pc, uint32_t which)
return poppedValue(pc - script_->code, which);
}
inline types::StackTypeSet *
ScriptAnalysis::pushedTypes(uint32_t offset, uint32_t which)
{
JS_ASSERT(offset < script_->length);
JS_ASSERT(which < GetDefCount(script_, offset) +
(ExtendedDef(script_->code + offset) ? 1 : 0));
types::StackTypeSet *array = getCode(offset).pushedTypes;
JS_ASSERT(array);
return array + which;
}
inline types::StackTypeSet *
ScriptAnalysis::pushedTypes(const jsbytecode *pc, uint32_t which)
{
return pushedTypes(pc - script_->code, which);
}
inline types::StackTypeSet *
ScriptAnalysis::getValueTypes(const SSAValue &v)
{
switch (v.kind()) {
case SSAValue::PUSHED:
return pushedTypes(v.pushedOffset(), v.pushedIndex());
case SSAValue::VAR:
JS_ASSERT(!slotEscapes(v.varSlot()));
if (v.varInitial()) {
if (v.varSlot() < LocalSlot(script_, 0))
return types::TypeScript::SlotTypes(script_, v.varSlot());
return undefinedTypeSet;
} else {
/*
* Results of intermediate assignments have the same type as
* the first type pushed by the assignment op. Note that this
* may not be the exact same value as was pushed, due to
* post-inc/dec ops.
*/
return pushedTypes(v.varOffset(), 0);
}
case SSAValue::PHI:
return &v.phiNode()->types;
default:
/* Cannot compute types for empty SSA values. */
MOZ_ASSUME_UNREACHABLE("Bad SSA value");
}
}
inline types::StackTypeSet *
ScriptAnalysis::poppedTypes(uint32_t offset, uint32_t which)
{
return getValueTypes(poppedValue(offset, which));
}
inline types::StackTypeSet *
ScriptAnalysis::poppedTypes(const jsbytecode *pc, uint32_t which)
{
return getValueTypes(poppedValue(pc, which));
}
inline SSAUseChain *&
ScriptAnalysis::useChain(const SSAValue &v)
{
@ -107,12 +49,6 @@ ScriptAnalysis::getCallPC(jsbytecode *pc)
return script_->code + uses->offset;
}
inline types::StackTypeSet *
CrossScriptSSA::getValueTypes(const CrossSSAValue &cv)
{
return getFrame(cv.frame).script->analysis()->getValueTypes(cv.v);
}
} /* namespace analyze */
} /* namespace js */

View File

@ -9,11 +9,9 @@
#ifndef jsapi_h
#define jsapi_h
#include "mozilla/Compiler.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/RangedPtr.h"
#include "mozilla/TypeTraits.h"
#include <stdarg.h>
#include <stddef.h>
@ -24,7 +22,6 @@
#include "jspubtd.h"
#include "js/CallArgs.h"
#include "js/CallNonGenericMethod.h"
#include "js/Class.h"
#include "js/HashTable.h"
#include "js/Id.h"
@ -1358,7 +1355,7 @@ JS_EndRequest(JSContext *cx);
extern JS_PUBLIC_API(bool)
JS_IsInRequest(JSRuntime *rt);
namespace JS {
namespace js {
inline bool
IsPoisonedId(jsid iden)
@ -1370,15 +1367,11 @@ IsPoisonedId(jsid iden)
return false;
}
} /* namespace JS */
namespace js {
template <> struct GCMethods<jsid>
{
static jsid initial() { return JSID_VOID; }
static ThingRootKind kind() { return THING_ROOT_ID; }
static bool poisoned(jsid id) { return JS::IsPoisonedId(id); }
static bool poisoned(jsid id) { return IsPoisonedId(id); }
static bool needsPostBarrier(jsid id) { return false; }
#ifdef JSGC_GENERATIONAL
static void postBarrier(jsid *idp) {}
@ -4586,81 +4579,4 @@ extern JS_PUBLIC_DATA(const Handle<jsid>) JSID_EMPTYHANDLE;
} /* namespace JS */
namespace js {
/*
* Import some JS:: names into the js namespace so we can make unqualified
* references to them.
*/
using JS::Value;
using JS::IsPoisonedValue;
using JS::NullValue;
using JS::UndefinedValue;
using JS::Int32Value;
using JS::DoubleValue;
using JS::StringValue;
using JS::BooleanValue;
using JS::ObjectValue;
using JS::MagicValue;
using JS::NumberValue;
using JS::ObjectOrNullValue;
using JS::PrivateValue;
using JS::PrivateUint32Value;
using JS::IsPoisonedPtr;
using JS::IsPoisonedId;
using JS::StableCharPtr;
using JS::TwoByteChars;
using JS::Latin1CharsZ;
using JS::AutoIdVector;
using JS::AutoValueVector;
using JS::AutoObjectVector;
using JS::AutoFunctionVector;
using JS::AutoScriptVector;
using JS::AutoIdArray;
using JS::AutoGCRooter;
using JS::AutoArrayRooter;
using JS::AutoVectorRooter;
using JS::AutoHashMapRooter;
using JS::AutoHashSetRooter;
using JS::CallArgs;
using JS::IsAcceptableThis;
using JS::NativeImpl;
using JS::CallReceiver;
using JS::CompileOptions;
using JS::CallNonGenericMethod;
using JS::Rooted;
using JS::RootedObject;
using JS::RootedFunction;
using JS::RootedScript;
using JS::RootedString;
using JS::RootedId;
using JS::RootedValue;
using JS::Handle;
using JS::HandleObject;
using JS::HandleFunction;
using JS::HandleScript;
using JS::HandleString;
using JS::HandleId;
using JS::HandleValue;
using JS::MutableHandle;
using JS::MutableHandleObject;
using JS::MutableHandleFunction;
using JS::MutableHandleScript;
using JS::MutableHandleString;
using JS::MutableHandleId;
using JS::MutableHandleValue;
using JS::Zone;
} /* namespace js */
#endif /* jsapi_h */

View File

@ -6,11 +6,13 @@
#ifndef jsbool_h
#define jsbool_h
/*
* JS boolean interface.
*/
#include "jsapi.h"
#include "NamespaceImports.h"
extern JSObject *
js_InitBooleanClass(JSContext *cx, js::HandleObject obj);

View File

@ -12,6 +12,7 @@
#define jsexn_h
#include "jsapi.h"
#include "NamespaceImports.h"
/*
* Initialize the exception constructor/prototype hierarchy.

File diff suppressed because it is too large Load Diff

View File

@ -571,22 +571,8 @@ class StackTypeSet : public TypeSet
*/
static StackTypeSet *make(JSContext *cx, const char *name);
/* Constraints for type inference. */
void addSubset(JSContext *cx, TypeSet *target);
void addGetProperty(JSContext *cx, JSScript *script, jsbytecode *pc,
StackTypeSet *target, jsid id);
void addSetProperty(JSContext *cx, JSScript *script, jsbytecode *pc,
StackTypeSet *target, jsid id);
void addSetElement(JSContext *cx, JSScript *script, jsbytecode *pc,
StackTypeSet *objectTypes, StackTypeSet *valueTypes);
void addCall(JSContext *cx, TypeCallsite *site);
void addArith(JSContext *cx, JSScript *script, jsbytecode *pc,
TypeSet *target, TypeSet *other = NULL);
void addTransformThis(JSContext *cx, JSScript *script, TypeSet *target);
void addPropagateThis(JSContext *cx, JSScript *script, jsbytecode *pc,
Type type, StackTypeSet *types = NULL);
void addSubsetBarrier(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target);
/* Propagate any types from this set into target. */
void addSubset(JSContext *cx, StackTypeSet *target);
/*
* Constraints for JIT compilation.
@ -679,16 +665,8 @@ class HeapTypeSet : public TypeSet
{
public:
/* Constraints for type inference. */
void addSubset(JSContext *cx, TypeSet *target);
void addGetProperty(JSContext *cx, JSScript *script, jsbytecode *pc,
StackTypeSet *target, jsid id);
void addCallProperty(JSContext *cx, JSScript *script, jsbytecode *pc, jsid id);
void addFilterPrimitives(JSContext *cx, TypeSet *target);
void addSubsetBarrier(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target);
/* Constraints for JIT compilation. */
/* Propagate any types from this set into target. */
void addSubset(JSContext *cx, HeapTypeSet *target);
/* Completely freeze the contents of this type set. */
void addFreeze(JSContext *cx);
@ -745,6 +723,13 @@ TypeSet::toHeapTypeSet()
return (HeapTypeSet *) this;
}
bool
AddClearDefiniteGetterSetterForPrototypeChain(JSContext *cx, TypeObject *type, jsid id);
void
AddClearDefiniteFunctionUsesInScript(JSContext *cx, TypeObject *type,
JSScript *script, JSScript *calleeScript);
/*
* Handler which persists information about dynamic types pushed within a
* script which can affect its behavior and are not covered by JOF_TYPESET ops,
@ -932,14 +917,14 @@ struct TypeNewScript : public TypeObjectAddendum
* scripted setter is added to one of the object's prototypes while it is
* in the middle of being initialized, so we can walk the stack and fixup
* any objects which look for in-progress objects which were prematurely
* set with their final shape. Initialization can traverse stack frames,
* in which case FRAME_PUSH/FRAME_POP are used.
* set with their final shape. Property assignments in inner frames are
* preceded by a series of SETPROP_FRAME entries specifying the stack down
* to the frame containing the write.
*/
struct Initializer {
enum Kind {
SETPROP,
FRAME_PUSH,
FRAME_POP,
SETPROP_FRAME,
DONE
} kind;
uint32_t offset;
@ -1145,7 +1130,7 @@ struct TypeObject : gc::Cell
void clearAddendum(ExclusiveContext *cx);
void clearNewScriptAddendum(ExclusiveContext *cx);
void clearBinaryDataAddendum(ExclusiveContext *cx);
void getFromPrototypes(JSContext *cx, jsid id, TypeSet *types, bool force = false);
void getFromPrototypes(JSContext *cx, jsid id, HeapTypeSet *types, bool force = false);
void print();
@ -1493,10 +1478,6 @@ struct TypeCompartment
void addPendingRecompile(JSContext *cx, const RecompileInfo &info);
void addPendingRecompile(JSContext *cx, JSScript *script);
/* Monitor future effects on a bytecode. */
void monitorBytecode(JSContext *cx, JSScript *script, uint32_t offset,
bool returnOnly = false);
/* Mark any type set containing obj as having a generic object type. */
void markSetsUnknown(JSContext *cx, TypeObject *obj);

View File

@ -1682,18 +1682,6 @@ JSScript::ensureRanAnalysis(JSContext *cx)
return true;
}
inline bool
JSScript::ensureRanInference(JSContext *cx)
{
if (!ensureRanAnalysis(cx))
return false;
if (!analysis()->ranInference()) {
js::types::AutoEnterAnalysis enter(cx);
analysis()->analyzeTypes(cx);
}
return !analysis()->OOM() && !cx->zone()->types.pendingNukeTypes;
}
inline bool
JSScript::hasAnalysis()
{
@ -1723,14 +1711,6 @@ JSScript::clearPropertyReadTypes()
types->propertyReadTypes = NULL;
}
inline void
js::analyze::ScriptAnalysis::addPushedType(JSContext *cx, uint32_t offset, uint32_t which,
js::types::Type type)
{
js::types::TypeSet *pushed = pushedTypes(offset, which);
pushed->addType(cx, type);
}
namespace js {
template <>

View File

@ -9,7 +9,7 @@
#include "mozilla/MemoryReporting.h"
#include "jsapi.h"
#include "NamespaceImports.h"
namespace js {

View File

@ -9,7 +9,7 @@
#include "mozilla/FloatingPoint.h"
#include "jsapi.h"
#include "NamespaceImports.h"
#include "vm/NumericConversions.h"

View File

@ -8,6 +8,7 @@
#define json_h
#include "jsapi.h"
#include "NamespaceImports.h"
#include "js/RootingAPI.h"

View File

@ -13,6 +13,7 @@
#include "jsapi.h"
#include "jsbytecode.h"
#include "NamespaceImports.h"
#include "frontend/SourceNotes.h"

View File

@ -6,7 +6,6 @@
#include "jspropertytree.h"
#include "jsapi.h"
#include "jscntxt.h"
#include "jsgc.h"
#include "jstypes.h"

View File

@ -2834,11 +2834,6 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, HandleScript script)
}
}
if (script->hasAnalysis() && script->analysis()->ranInference()) {
types::AutoEnterAnalysis enter(cx);
types::TypeScript::MonitorUnknown(cx, script, script->argumentsBytecode());
}
return true;
}

View File

@ -10,12 +10,13 @@
#include "mozilla/HashFunctions.h"
#include "mozilla/PodOperations.h"
#include "jsapi.h"
#include "jsutil.h"
#include "NamespaceImports.h"
#include "js/RootingAPI.h"
#include "vm/Unicode.h"
class JSAutoByteString;
class JSFlatString;
class JSLinearString;
class JSStableString;

View File

@ -8,7 +8,6 @@
#define jswatchpoint_h
#include "jsalloc.h"
#include "jsapi.h"
#include "gc/Barrier.h"
#include "js/HashTable.h"

View File

@ -202,6 +202,9 @@ ParseTask::~ParseTask()
// ParseTask takes over ownership of its input exclusive context.
js_delete(cx);
for (size_t i = 0; i < errors.length(); i++)
js_delete(errors[i]);
}
bool
@ -550,7 +553,7 @@ WorkerThreadState::finishParseTask(JSContext *maybecx, JSRuntime *rt, void *toke
if (maybecx) {
AutoCompartment ac(maybecx, parseTask->scopeChain);
for (size_t i = 0; i < parseTask->errors.length(); i++)
parseTask->errors[i].throwError(maybecx);
parseTask->errors[i]->throwError(maybecx);
}
JSScript *script = parseTask->script;
@ -677,9 +680,12 @@ ExclusiveContext::setWorkerThread(WorkerThread *workerThread)
frontend::CompileError &
ExclusiveContext::addPendingCompileError()
{
if (!workerThread->parseTask->errors.append(frontend::CompileError()))
frontend::CompileError *error = js_new<frontend::CompileError>();
if (!error)
MOZ_CRASH();
return workerThread->parseTask->errors.back();
if (!workerThread->parseTask->errors.append(error))
MOZ_CRASH();
return *error;
}
void

View File

@ -389,7 +389,7 @@ struct ParseTask
// Any errors or warnings produced during compilation. These are reported
// when finishing the script.
Vector<frontend::CompileError> errors;
Vector<frontend::CompileError *> errors;
ParseTask(ExclusiveContext *cx, const CompileOptions &options,
const jschar *chars, size_t length, JSObject *scopeChain,

View File

@ -6,7 +6,10 @@
#ifndef perf_jsperf_h
#define perf_jsperf_h
#include "jsapi.h"
#include "jstypes.h"
#include "js/TypeDecls.h"
#include "js/Utility.h"
namespace JS {
@ -118,12 +121,12 @@ extern JS_FRIEND_API(JSObject*)
RegisterPerfMeasurement(JSContext *cx, JSObject *global);
/*
* Given a jsval which contains an instance of the aforementioned
* Given a Value which contains an instance of the aforementioned
* wrapper class, extract the C++ object. Returns NULL if the
* jsval is not an instance of the wrapper.
* Value is not an instance of the wrapper.
*/
extern JS_FRIEND_API(PerfMeasurement*)
ExtractPerfMeasurement(jsval wrapper);
ExtractPerfMeasurement(Value wrapper);
} // namespace JS

View File

@ -953,8 +953,8 @@ TryNoteIter::settle()
}
}
#define PUSH_COPY(v) do { *regs.sp++ = v; assertSameCompartmentDebugOnly(cx, regs.sp[-1]); } while (0)
#define PUSH_COPY_SKIP_CHECK(v) *regs.sp++ = v
#define PUSH_COPY(v) do { *regs.sp++ = (v); assertSameCompartmentDebugOnly(cx, regs.sp[-1]); } while (0)
#define PUSH_COPY_SKIP_CHECK(v) *regs.sp++ = (v)
#define PUSH_NULL() regs.sp++->setNull()
#define PUSH_UNDEFINED() regs.sp++->setUndefined()
#define PUSH_BOOLEAN(b) regs.sp++->setBoolean(b)
@ -964,13 +964,13 @@ TryNoteIter::settle()
#define PUSH_OBJECT(obj) do { regs.sp++->setObject(obj); assertSameCompartmentDebugOnly(cx, regs.sp[-1]); } while (0)
#define PUSH_OBJECT_OR_NULL(obj) do { regs.sp++->setObjectOrNull(obj); assertSameCompartmentDebugOnly(cx, regs.sp[-1]); } while (0)
#define PUSH_HOLE() regs.sp++->setMagic(JS_ELEMENTS_HOLE)
#define POP_COPY_TO(v) v = *--regs.sp
#define POP_COPY_TO(v) (v) = *--regs.sp
#define POP_RETURN_VALUE() regs.fp()->setReturnValue(*--regs.sp)
#define FETCH_OBJECT(cx, n, obj) \
JS_BEGIN_MACRO \
HandleValue val = regs.stackHandleAt(n); \
obj = ToObjectFromStack(cx, (val)); \
obj = ToObjectFromStack((cx), (val)); \
if (!obj) \
goto error; \
JS_END_MACRO
@ -1277,35 +1277,19 @@ Interpret(JSContext *cx, RunState &state)
register int switchMask = 0;
int switchOp;
# define DO_OP() goto do_op
#define DO_OP() goto do_op
# define BEGIN_CASE(OP) case OP:
# define END_CASE(OP) END_CASE_LEN(OP##_LENGTH)
# define END_CASE_LEN(n) END_CASE_LENX(n)
# define END_CASE_LENX(n) END_CASE_LEN##n
#define BEGIN_CASE(OP) case OP:
#define END_CASE(OP) \
JS_BEGIN_MACRO \
len = OP##_LENGTH; \
goto advanceAndDoOp; \
JS_END_MACRO;
/*
* To share the code for all len == 1 cases we use the specialized label with
* code that falls through to advanceAndDoOp: .
*/
# define END_CASE_LEN1 goto advance_pc_by_one;
# define END_CASE_LEN2 len = 2; goto advanceAndDoOp;
# define END_CASE_LEN3 len = 3; goto advanceAndDoOp;
# define END_CASE_LEN4 len = 4; goto advanceAndDoOp;
# define END_CASE_LEN5 len = 5; goto advanceAndDoOp;
# define END_CASE_LEN6 len = 6; goto advanceAndDoOp;
# define END_CASE_LEN7 len = 7; goto advanceAndDoOp;
# define END_CASE_LEN8 len = 8; goto advanceAndDoOp;
# define END_CASE_LEN9 len = 9; goto advanceAndDoOp;
# define END_CASE_LEN10 len = 10; goto advanceAndDoOp;
# define END_CASE_LEN11 len = 11; goto advanceAndDoOp;
# define END_CASE_LEN12 len = 12; goto advanceAndDoOp;
# define END_VARLEN_CASE goto advanceAndDoOp;
# define ADD_EMPTY_CASE(OP) BEGIN_CASE(OP)
# define END_EMPTY_CASES goto advance_pc_by_one;
#define END_VARLEN_CASE goto advanceAndDoOp;
#define LOAD_DOUBLE(PCOFF, dbl) \
(dbl = script->getConst(GET_UINT32_INDEX(regs.pc + (PCOFF))).toDouble())
((dbl) = script->getConst(GET_UINT32_INDEX(regs.pc + (PCOFF))).toDouble())
/*
* Prepare to call a user-supplied branch handler, and abort the script
@ -1431,12 +1415,7 @@ Interpret(JSContext *cx, RunState &state)
if (rt->profilingScripts || cx->runtime()->debugHooks.interruptHook)
switchMask = -1; /* Enable interrupts. */
goto advanceAndDoOp;
for (;;) {
advance_pc_by_one:
JS_ASSERT(js_CodeSpec[op].length == 1);
len = 1;
advanceAndDoOp:
js::gc::MaybeVerifyBarriers(cx);
regs.pc += len;
@ -1518,51 +1497,55 @@ Interpret(JSContext *cx, RunState &state)
goto do_switch;
}
/* No-ops for ease of decompilation. */
ADD_EMPTY_CASE(JSOP_NOP)
ADD_EMPTY_CASE(JSOP_UNUSED125)
ADD_EMPTY_CASE(JSOP_UNUSED126)
ADD_EMPTY_CASE(JSOP_UNUSED132)
ADD_EMPTY_CASE(JSOP_UNUSED148)
ADD_EMPTY_CASE(JSOP_UNUSED161)
ADD_EMPTY_CASE(JSOP_UNUSED162)
ADD_EMPTY_CASE(JSOP_UNUSED163)
ADD_EMPTY_CASE(JSOP_UNUSED164)
ADD_EMPTY_CASE(JSOP_UNUSED165)
ADD_EMPTY_CASE(JSOP_UNUSED166)
ADD_EMPTY_CASE(JSOP_UNUSED167)
ADD_EMPTY_CASE(JSOP_UNUSED168)
ADD_EMPTY_CASE(JSOP_UNUSED169)
ADD_EMPTY_CASE(JSOP_UNUSED170)
ADD_EMPTY_CASE(JSOP_UNUSED171)
ADD_EMPTY_CASE(JSOP_UNUSED172)
ADD_EMPTY_CASE(JSOP_UNUSED173)
ADD_EMPTY_CASE(JSOP_UNUSED174)
ADD_EMPTY_CASE(JSOP_UNUSED175)
ADD_EMPTY_CASE(JSOP_UNUSED176)
ADD_EMPTY_CASE(JSOP_UNUSED177)
ADD_EMPTY_CASE(JSOP_UNUSED178)
ADD_EMPTY_CASE(JSOP_UNUSED179)
ADD_EMPTY_CASE(JSOP_UNUSED180)
ADD_EMPTY_CASE(JSOP_UNUSED181)
ADD_EMPTY_CASE(JSOP_UNUSED182)
ADD_EMPTY_CASE(JSOP_UNUSED183)
ADD_EMPTY_CASE(JSOP_UNUSED188)
ADD_EMPTY_CASE(JSOP_UNUSED189)
ADD_EMPTY_CASE(JSOP_UNUSED190)
ADD_EMPTY_CASE(JSOP_UNUSED200)
ADD_EMPTY_CASE(JSOP_UNUSED201)
ADD_EMPTY_CASE(JSOP_UNUSED208)
ADD_EMPTY_CASE(JSOP_UNUSED209)
ADD_EMPTY_CASE(JSOP_UNUSED210)
ADD_EMPTY_CASE(JSOP_UNUSED219)
ADD_EMPTY_CASE(JSOP_UNUSED220)
ADD_EMPTY_CASE(JSOP_UNUSED221)
ADD_EMPTY_CASE(JSOP_UNUSED222)
ADD_EMPTY_CASE(JSOP_UNUSED223)
ADD_EMPTY_CASE(JSOP_CONDSWITCH)
ADD_EMPTY_CASE(JSOP_TRY)
END_EMPTY_CASES
/* Various 1-byte no-ops. */
BEGIN_CASE(JSOP_NOP)
BEGIN_CASE(JSOP_UNUSED125)
BEGIN_CASE(JSOP_UNUSED126)
BEGIN_CASE(JSOP_UNUSED132)
BEGIN_CASE(JSOP_UNUSED148)
BEGIN_CASE(JSOP_UNUSED161)
BEGIN_CASE(JSOP_UNUSED162)
BEGIN_CASE(JSOP_UNUSED163)
BEGIN_CASE(JSOP_UNUSED164)
BEGIN_CASE(JSOP_UNUSED165)
BEGIN_CASE(JSOP_UNUSED166)
BEGIN_CASE(JSOP_UNUSED167)
BEGIN_CASE(JSOP_UNUSED168)
BEGIN_CASE(JSOP_UNUSED169)
BEGIN_CASE(JSOP_UNUSED170)
BEGIN_CASE(JSOP_UNUSED171)
BEGIN_CASE(JSOP_UNUSED172)
BEGIN_CASE(JSOP_UNUSED173)
BEGIN_CASE(JSOP_UNUSED174)
BEGIN_CASE(JSOP_UNUSED175)
BEGIN_CASE(JSOP_UNUSED176)
BEGIN_CASE(JSOP_UNUSED177)
BEGIN_CASE(JSOP_UNUSED178)
BEGIN_CASE(JSOP_UNUSED179)
BEGIN_CASE(JSOP_UNUSED180)
BEGIN_CASE(JSOP_UNUSED181)
BEGIN_CASE(JSOP_UNUSED182)
BEGIN_CASE(JSOP_UNUSED183)
BEGIN_CASE(JSOP_UNUSED188)
BEGIN_CASE(JSOP_UNUSED189)
BEGIN_CASE(JSOP_UNUSED190)
BEGIN_CASE(JSOP_UNUSED200)
BEGIN_CASE(JSOP_UNUSED201)
BEGIN_CASE(JSOP_UNUSED208)
BEGIN_CASE(JSOP_UNUSED209)
BEGIN_CASE(JSOP_UNUSED210)
BEGIN_CASE(JSOP_UNUSED219)
BEGIN_CASE(JSOP_UNUSED220)
BEGIN_CASE(JSOP_UNUSED221)
BEGIN_CASE(JSOP_UNUSED222)
BEGIN_CASE(JSOP_UNUSED223)
BEGIN_CASE(JSOP_CONDSWITCH)
BEGIN_CASE(JSOP_TRY)
{
JS_ASSERT(js_CodeSpec[op].length == 1);
len = 1;
goto advanceAndDoOp;
}
BEGIN_CASE(JSOP_LOOPHEAD)
END_CASE(JSOP_LOOPHEAD)
@ -1605,7 +1588,6 @@ END_CASE(JSOP_LOOPENTRY)
BEGIN_CASE(JSOP_NOTEARG)
END_CASE(JSOP_NOTEARG)
/* ADD_EMPTY_CASE is not used here as JSOP_LINENO_LENGTH == 3. */
BEGIN_CASE(JSOP_LINENO)
END_CASE(JSOP_LINENO)
@ -1772,17 +1754,17 @@ END_CASE(JSOP_AND)
#define FETCH_ELEMENT_ID(n, id) \
JS_BEGIN_MACRO \
if (!ValueToId<CanGC>(cx, regs.stackHandleAt(n), &id)) \
if (!ValueToId<CanGC>(cx, regs.stackHandleAt(n), &(id))) \
goto error; \
JS_END_MACRO
#define TRY_BRANCH_AFTER_COND(cond,spdec) \
JS_BEGIN_MACRO \
JS_ASSERT(js_CodeSpec[op].length == 1); \
unsigned diff_ = (unsigned) GET_UINT8(regs.pc) - (unsigned) JSOP_IFEQ; \
unsigned diff_ = (unsigned) GET_UINT8(regs.pc) - (unsigned) JSOP_IFEQ;\
if (diff_ <= 1) { \
regs.sp -= spdec; \
if (cond == (diff_ != 0)) { \
regs.sp -= (spdec); \
if ((cond) == (diff_ != 0)) { \
++regs.pc; \
len = GET_JUMP_OFFSET(regs.pc); \
BRANCH(len); \
@ -2004,7 +1986,7 @@ END_CASE(JSOP_NE)
bool equal; \
if (!StrictlyEqual(cx, lref, rref, &equal)) \
goto error; \
COND = equal OP true; \
(COND) = equal OP true; \
regs.sp--; \
JS_END_MACRO

View File

@ -14,6 +14,7 @@
#include "jsfriendapi.h"
#include "jsinfer.h"
#include "NamespaceImports.h"
#include "gc/Barrier.h"
#include "gc/Heap.h"

View File

@ -9,7 +9,6 @@
#include "mozilla/Endian.h"
#include "jsapi.h"
#include "jsatom.h"
namespace js {

View File

@ -36,6 +36,7 @@
#include "mozilla/dom/BindingUtils.h"
using namespace mozilla;
using namespace JS;
using namespace js;
using namespace xpc;

View File

@ -41,6 +41,7 @@
#include "nsGlobalWindow.h"
using namespace mozilla;
using namespace JS;
using namespace js;
using namespace xpc;
@ -3714,7 +3715,7 @@ nsXPCComponents::AttachComponentsObject(JSContext* aCx,
MOZ_ASSERT(js::IsObjectInContextCompartment(global, aCx));
RootedId id(aCx, XPCJSRuntime::Get()->GetStringID(XPCJSRuntime::IDX_COMPONENTS));
return JS_DefinePropertyById(aCx, global, id, js::ObjectValue(*components),
return JS_DefinePropertyById(aCx, global, id, JS::ObjectValue(*components),
nullptr, nullptr, JSPROP_PERMANENT | JSPROP_READONLY);
}

View File

@ -24,6 +24,7 @@
#include "mozilla/dom/BindingUtils.h"
using namespace mozilla;
using namespace JS;
using namespace js;
namespace xpc {

View File

@ -15,6 +15,7 @@
#include "jsapi.h"
using namespace JS;
using namespace js;
namespace xpc {

View File

@ -20,6 +20,7 @@
#include "mozilla/Likely.h"
#include "nsContentUtils.h"
using namespace JS;
using namespace js;
using namespace mozilla;

View File

@ -66,17 +66,6 @@ public:
return 0;
}
#if defined(MOZ_ANDROID_SONY_WORKAROUND)
private:
// Sony ICS devices have extra virtual methods in DataSource.
// The dummy methods below fill these vtable positions.
virtual void foo1() { abort(); }
virtual void foo2() { abort(); }
virtual void foo3() { abort(); }
virtual void foo4() { abort(); }
public:
#endif
virtual status_t reconnectAtOffset(off64_t offset) {
return ERROR_UNSUPPORTED;
}

View File

@ -20,22 +20,4 @@ index 81ef632..713af92 100644
public:
enum Flags {
kWantsPrefetching = 1,
@@ -66,17 +62,6 @@ public:
return 0;
}
-#if defined(MOZ_ANDROID_SONY_WORKAROUND)
-private:
- // Sony ICS devices have extra virtual methods in DataSource.
- // The dummy methods below fill these vtable positions.
- virtual void foo1() { abort(); }
- virtual void foo2() { abort(); }
- virtual void foo3() { abort(); }
- virtual void foo4() { abort(); }
-public:
-#endif
-
virtual status_t reconnectAtOffset(off64_t offset) {
return ERROR_UNSUPPORTED;
}

View File

@ -1,60 +0,0 @@
# Copyright 2012 Mozilla Foundation and Mozilla contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE_NAME = omxpluginjb-htc
FORCE_SHARED_LIB = 1
# Don't use STL wrappers; this isn't Gecko code
STL_FLAGS =
# must link statically with the CRT; this isn't Gecko code
USE_STATIC_LIBS = 1
# Need to custom install OMX media plugin
NO_INSTALL = 1
include $(topsrcdir)/config/rules.mk
ifdef GNU_CXX
# Turn off C++ 11 features due to conflicts with Android OS headers and char16_t definition
CXXFLAGS += -std=gnu++98
endif
INCLUDES += \
-I$(srcdir)/../../../content/media/plugins \
$(NULL)
EXTRA_DSO_LDOPTS += \
-L$(DEPTH)/media/omx-plugin/lib/ics/libutils \
-lutils \
-L$(DEPTH)/media/omx-plugin/lib/ics/libstagefright \
-lstagefright \
$(NULL)
INCLUDES += \
-I$(srcdir)/../include/ics \
-I$(srcdir)/../include/ics/media/stagefright/openmax \
$(NULL)
libs:: $(DLL_PREFIX)$(LIBRARY_NAME)$(DLL_SUFFIX)
$(INSTALL) $< $(DEPTH)/dist/bin
libs:: $(PROGRAMS)

View File

@ -1,9 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#define MOZ_STAGEFRIGHT_OFF_T off64_t
#define MOZ_ANDROID_ICS
#define MOZ_ANDROID_HTC_WORKAROUND
#include "../OmxPlugin.cpp"

View File

@ -1,15 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=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/.
MODULE = 'omxpluginjb-htc'
NO_DIST_INSTALL = True
CPP_SOURCES += [
'OmxPluginJB-HTC.cpp',
]
LIBRARY_NAME = 'omxpluginjb-htc'

View File

@ -1,60 +0,0 @@
# Copyright 2012 Mozilla Foundation and Mozilla contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE_NAME = omxpluginsony
FORCE_SHARED_LIB = 1
# Don't use STL wrappers; this isn't Gecko code
STL_FLAGS =
# must link statically with the CRT; this isn't Gecko code
USE_STATIC_LIBS = 1
# Need to custom install OMX media plugin
NO_INSTALL = 1
include $(topsrcdir)/config/rules.mk
ifdef GNU_CXX
# Turn off C++ 11 features due to conflicts with Android OS headers and char16_t definition
CXXFLAGS += -std=gnu++98
endif
INCLUDES += \
-I$(srcdir)/../../../content/media/plugins \
$(NULL)
EXTRA_DSO_LDOPTS += \
-L$(DEPTH)/media/omx-plugin/lib/ics/libutils \
-lutils \
-L$(DEPTH)/media/omx-plugin/lib/ics/libstagefright \
-lstagefright \
$(NULL)
INCLUDES += \
-I$(srcdir)/../include/ics \
-I$(srcdir)/../include/ics/media/stagefright/openmax \
$(NULL)
libs:: $(DLL_PREFIX)$(LIBRARY_NAME)$(DLL_SUFFIX)
$(INSTALL) $< $(DEPTH)/dist/bin
libs:: $(PROGRAMS)

View File

@ -1,10 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#define MOZ_STAGEFRIGHT_OFF_T off64_t
#define MOZ_ANDROID_GB
#define MOZ_ANDROID_HC
#include <ui/egl/android_natives.h>
#include "../OmxPlugin.cpp"

View File

@ -1,9 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#define MOZ_STAGEFRIGHT_OFF_T off64_t
#define MOZ_ANDROID_ICS
#define MOZ_ANDROID_SONY_WORKAROUND
#include "../OmxPlugin.cpp"

View File

@ -1,15 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=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/.
MODULE = 'omxpluginsony'
NO_DIST_INSTALL = True
CPP_SOURCES += [
'OmxPluginSony.cpp',
]
LIBRARY_NAME = 'omxpluginsony'

View File

@ -8,6 +8,11 @@
#include <math.h>
using mozilla::DoublesAreIdentical;
using mozilla::IsFinite;
using mozilla::IsInfinite;
using mozilla::IsNaN;
using mozilla::IsNegative;
using mozilla::IsNegativeZero;
using mozilla::NegativeInfinity;
using mozilla::PositiveInfinity;
using mozilla::SpecificNaN;
@ -97,8 +102,54 @@ TestDoublesAreIdentical()
ShouldNotBeIdentical(UnspecifiedNaN(), NegativeInfinity());
}
static void
TestPredicates()
{
MOZ_ASSERT(IsNaN(UnspecifiedNaN()));
MOZ_ASSERT(IsNaN(SpecificNaN(1, 17)));;
MOZ_ASSERT(IsNaN(SpecificNaN(0, 0xfffffffffff0fULL)));
MOZ_ASSERT(!IsNaN(0));
MOZ_ASSERT(!IsNaN(-0.0));
MOZ_ASSERT(!IsNaN(1.0));
MOZ_ASSERT(!IsNaN(PositiveInfinity()));
MOZ_ASSERT(!IsNaN(NegativeInfinity()));
MOZ_ASSERT(IsInfinite(PositiveInfinity()));
MOZ_ASSERT(IsInfinite(NegativeInfinity()));
MOZ_ASSERT(!IsInfinite(UnspecifiedNaN()));
MOZ_ASSERT(!IsInfinite(0));
MOZ_ASSERT(!IsInfinite(-0.0));
MOZ_ASSERT(!IsInfinite(1.0));
MOZ_ASSERT(!IsFinite(PositiveInfinity()));
MOZ_ASSERT(!IsFinite(NegativeInfinity()));
MOZ_ASSERT(!IsFinite(UnspecifiedNaN()));
MOZ_ASSERT(IsFinite(0));
MOZ_ASSERT(IsFinite(-0.0));
MOZ_ASSERT(IsFinite(1.0));
MOZ_ASSERT(!IsNegative(PositiveInfinity()));
MOZ_ASSERT(IsNegative(NegativeInfinity()));
MOZ_ASSERT(IsNegative(-0.0));
MOZ_ASSERT(!IsNegative(0.0));
MOZ_ASSERT(IsNegative(-1.0));
MOZ_ASSERT(!IsNegative(1.0));
MOZ_ASSERT(!IsNegativeZero(PositiveInfinity()));
MOZ_ASSERT(!IsNegativeZero(NegativeInfinity()));
MOZ_ASSERT(!IsNegativeZero(SpecificNaN(1, 17)));;
MOZ_ASSERT(!IsNegativeZero(SpecificNaN(1, 0xfffffffffff0fULL)));
MOZ_ASSERT(!IsNegativeZero(SpecificNaN(0, 17)));;
MOZ_ASSERT(!IsNegativeZero(SpecificNaN(0, 0xfffffffffff0fULL)));
MOZ_ASSERT(IsNegativeZero(-0.0));
MOZ_ASSERT(!IsNegativeZero(0.0));
MOZ_ASSERT(!IsNegativeZero(-1.0));
MOZ_ASSERT(!IsNegativeZero(1.0));
}
int
main()
{
TestDoublesAreIdentical();
TestPredicates();
}

View File

@ -44,8 +44,6 @@
@BINPATH@/@DLL_PREFIX@omxplugingb@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxplugingb235@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginhc@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginjb-htc@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginsony@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginfroyo@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@

View File

@ -118,17 +118,21 @@ class TreeMetadataEmitter(LoggingMixin):
CPP_UNIT_TESTS='CPP_UNIT_TESTS',
CSRCS='CSRCS',
DEFINES='DEFINES',
EXPORT_LIBRARY='EXPORT_LIBRARY',
EXTRA_COMPONENTS='EXTRA_COMPONENTS',
EXTRA_JS_MODULES='EXTRA_JS_MODULES',
EXTRA_PP_COMPONENTS='EXTRA_PP_COMPONENTS',
EXTRA_PP_JS_MODULES='EXTRA_PP_JS_MODULES',
FAIL_ON_WARNINGS='FAIL_ON_WARNINGS',
FORCE_SHARED_LIB='FORCE_SHARED_LIB',
FORCE_STATIC_LIB='FORCE_STATIC_LIB',
GTEST_CMMSRCS='GTEST_CMM_SOURCES',
GTEST_CPPSRCS='GTEST_CPP_SOURCES',
GTEST_CSRCS='GTEST_C_SOURCES',
HOST_CPPSRCS='HOST_CPPSRCS',
HOST_CSRCS='HOST_CSRCS',
HOST_LIBRARY_NAME='HOST_LIBRARY_NAME',
IS_COMPONENT='IS_COMPONENT',
JS_MODULES_PATH='JS_MODULES_PATH',
LIBRARY_NAME='LIBRARY_NAME',
LIBS='LIBS',

View File

@ -98,6 +98,10 @@ VARIABLES = {
delimiters.
"""),
'EXPORT_LIBRARY': (bool, bool, False,
"""Install the library to the static libraries folder.
"""),
'EXTRA_COMPONENTS': (StrictOrderingOnAppendList, list, [],
"""Additional component files to distribute.
@ -138,6 +142,14 @@ VARIABLES = {
"""Whether to treat warnings as errors.
"""),
'FORCE_SHARED_LIB': (bool, bool, False,
"""Whether the library in this directory is a shared library.
"""),
'FORCE_STATIC_LIB': (bool, bool, False,
"""Whether the library in this directory is a static library.
"""),
'GTEST_C_SOURCES': (StrictOrderingOnAppendList, list, [],
"""C code source files for GTest unit tests.
@ -171,6 +183,10 @@ VARIABLES = {
This variable contains a list of C source files to compile.
"""),
'IS_COMPONENT': (bool, bool, False,
"""Whether the library contains a binary XPCOM component manifest.
"""),
'PARALLEL_DIRS': (list, list, [],
"""A parallel version of DIRS.
@ -212,7 +228,7 @@ VARIABLES = {
'LIBXUL_LIBRARY': (bool, bool, False,
"""Whether the library in this directory is linked into libxul.
Implies MOZILLA_INTERNAL_API.
Implies MOZILLA_INTERNAL_API and FORCE_STATIC_LIB.
"""),
'MSVC_ENABLE_PGO': (bool, bool, False,

View File

@ -45,3 +45,8 @@ LIBXUL_LIBRARY = True
MSVC_ENABLE_PGO = True
NO_DIST_INSTALL = True
FORCE_SHARED_LIB = True
FORCE_STATIC_LIB = True
EXPORT_LIBRARY = True
IS_COMPONENT = True

View File

@ -132,17 +132,21 @@ class TestEmitterBasic(unittest.TestCase):
CSRCS=['fans.c', 'tans.c'],
CPP_UNIT_TESTS=['foo.cpp'],
DEFINES=['-Dfans', '-Dtans'],
EXPORT_LIBRARY=True,
EXTRA_COMPONENTS=['fans.js', 'tans.js'],
EXTRA_PP_COMPONENTS=['fans.pp.js', 'tans.pp.js'],
EXTRA_JS_MODULES=['bar.jsm', 'foo.jsm'],
EXTRA_PP_JS_MODULES=['bar.pp.jsm', 'foo.pp.jsm'],
FAIL_ON_WARNINGS=True,
FORCE_SHARED_LIB=True,
FORCE_STATIC_LIB=True,
GTEST_CSRCS=['test1.c', 'test2.c'],
GTEST_CMMSRCS=['test1.mm', 'test2.mm'],
GTEST_CPPSRCS=['test1.cpp', 'test2.cpp'],
HOST_CPPSRCS=['fans.cpp', 'tans.cpp'],
HOST_CSRCS=['fans.c', 'tans.c'],
HOST_LIBRARY_NAME='host_fans',
IS_COMPONENT=True,
LIBRARY_NAME='lib_name',
LIBS=['fans.lib', 'tans.lib'],
LIBXUL_LIBRARY=True,

View File

@ -184,15 +184,15 @@ function _do_quit() {
}
function _format_exception_stack(stack) {
// frame is of the form "fname(args)@file:line"
let frame_regexp = new RegExp("(.*)\\(.*\\)@(.*):(\\d*)", "g");
// frame is of the form "fname@file:line"
let frame_regexp = new RegExp("(.*)@(.*):(\\d*)", "g");
return stack.split("\n").reduce(function(stack_msg, frame) {
if (frame) {
let parts = frame_regexp.exec(frame);
if (parts) {
return stack_msg + "JS frame :: " + parts[2] + " :: " +
(parts[1] ? parts[1] : "anonymous") +
" :: line " + parts[3] + "\n";
let [ _, func, file, line ] = parts;
return stack_msg + "JS frame :: " + file + " :: " +
(func || "anonymous") + " :: line " + line + "\n";
}
else { /* Could be a -e (command line string) style location. */
return stack_msg + "JS frame :: " + frame + "\n";

View File

@ -345,7 +345,7 @@ INNER_ROBOCOP_PACKAGE=echo 'Testing is disabled - No Robocop for you'
endif
ifdef MOZ_OMX_PLUGIN
DIST_FILES += libomxplugin.so libomxplugingb.so libomxplugingb235.so libomxpluginhc.so libomxpluginsony.so libomxpluginfroyo.so libomxpluginjb-htc.so
DIST_FILES += libomxplugin.so libomxplugingb.so libomxplugingb235.so libomxpluginhc.so libomxpluginfroyo.so
endif
SO_LIBRARIES := $(filter %.so,$(DIST_FILES))

Some files were not shown because too many files have changed in this diff Show More