diff --git a/ipc/chromium/moz.build b/ipc/chromium/moz.build index f44b7517e1..790d3916cf 100644 --- a/ipc/chromium/moz.build +++ b/ipc/chromium/moz.build @@ -50,7 +50,6 @@ UNIFIED_SOURCES += [ 'src/base/pickle.cc', 'src/base/rand_util.cc', 'src/base/revocable_store.cc', - 'src/base/scoped_temp_dir.cc', 'src/base/string_piece.cc', 'src/base/string_util.cc', 'src/base/thread.cc', diff --git a/ipc/chromium/src/base/file_util.cc b/ipc/chromium/src/base/file_util.cc index a0da63f6f4..bf121c685c 100644 --- a/ipc/chromium/src/base/file_util.cc +++ b/ipc/chromium/src/base/file_util.cc @@ -139,12 +139,6 @@ void AppendToPath(std::wstring* path, const std::wstring& new_ending) { path->push_back(FilePath::kSeparators[0]); path->append(new_ending); } -bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path, - bool recursive) { - return CopyDirectory(FilePath::FromWStringHack(from_path), - FilePath::FromWStringHack(to_path), - recursive); -} bool CopyFile(const std::wstring& from_path, const std::wstring& to_path) { return CopyFile(FilePath::FromWStringHack(from_path), FilePath::FromWStringHack(to_path)); @@ -172,8 +166,8 @@ bool CreateTemporaryFileName(std::wstring* temp_file) { *temp_file = temp_file_path.ToWStringHack(); return true; } -bool Delete(const std::wstring& path, bool recursive) { - return Delete(FilePath::FromWStringHack(path), recursive); +bool Delete(const std::wstring& path) { + return Delete(FilePath::FromWStringHack(path)); } bool DirectoryExists(const std::wstring& path) { return DirectoryExists(FilePath::FromWStringHack(path)); diff --git a/ipc/chromium/src/base/file_util.h b/ipc/chromium/src/base/file_util.h index 0461503faf..4374d32602 100644 --- a/ipc/chromium/src/base/file_util.h +++ b/ipc/chromium/src/base/file_util.h @@ -16,7 +16,6 @@ #include #elif defined(OS_POSIX) #include -#include #include #endif @@ -87,34 +86,17 @@ void ReplaceExtension(std::wstring* file_name, const std::wstring& extension); // Deletes the given path, whether it's a file or a directory. // If it's a directory, it's perfectly happy to delete all of the -// directory's contents. Passing true to recursive deletes -// subdirectories and their contents as well. +// directory's contents. // Returns true if successful, false otherwise. -// -// WARNING: USING THIS WITH recursive==true IS EQUIVALENT -// TO "rm -rf", SO USE WITH CAUTION. -bool Delete(const FilePath& path, bool recursive); +bool Delete(const FilePath& path); // Deprecated temporary compatibility function. -bool Delete(const std::wstring& path, bool recursive); +bool Delete(const std::wstring& path); // Copies a single file. Use CopyDirectory to copy directories. bool CopyFile(const FilePath& from_path, const FilePath& to_path); // Deprecated temporary compatibility function. bool CopyFile(const std::wstring& from_path, const std::wstring& to_path); -// Copies the given path, and optionally all subdirectories and their contents -// as well. -// If there are files existing under to_path, always overwrite. -// Returns true if successful, false otherwise. -// Dont't use wildcards on the names, it may stop working without notice. -// -// If you only need to copy a file use CopyFile, it's faster. -bool CopyDirectory(const FilePath& from_path, const FilePath& to_path, - bool recursive); -// Deprecated temporary compatibility function. -bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path, - bool recursive); - // Returns true if the given path exists on the local filesystem, // false otherwise. bool PathExists(const FilePath& path); diff --git a/ipc/chromium/src/base/file_util_posix.cc b/ipc/chromium/src/base/file_util_posix.cc index b91d20d3ce..b716a5dd46 100644 --- a/ipc/chromium/src/base/file_util_posix.cc +++ b/ipc/chromium/src/base/file_util_posix.cc @@ -8,13 +8,10 @@ #include #include #include -#ifndef ANDROID -#include -#endif #include #include #include -#include +#include #include #define _DARWIN_USE_64_BIT_INODE // Use 64-bit inode data structures #include @@ -53,7 +50,7 @@ bool AbsolutePath(FilePath* path) { // which works both with and without the recursive flag. I'm not sure we need // that functionality. If not, remove from file_util_win.cc, otherwise add it // here. -bool Delete(const FilePath& path, bool recursive) { +bool Delete(const FilePath& path) { const char* path_str = path.value().c_str(); struct stat file_info; int test = stat(path_str, &file_info); @@ -64,174 +61,8 @@ bool Delete(const FilePath& path, bool recursive) { } if (!S_ISDIR(file_info.st_mode)) return (unlink(path_str) == 0); - if (!recursive) - return (rmdir(path_str) == 0); -#ifdef ANDROID - // XXX Need ftsless impl for bionic - return false; -#else - bool success = true; - int ftsflags = FTS_PHYSICAL | FTS_NOSTAT; - char top_dir[PATH_MAX]; - if (base::strlcpy(top_dir, path_str, - arraysize(top_dir)) >= arraysize(top_dir)) { - return false; - } - char* dir_list[2] = { top_dir, NULL }; - FTS* fts = fts_open(dir_list, ftsflags, NULL); - if (fts) { - FTSENT* fts_ent = fts_read(fts); - while (success && fts_ent != NULL) { - switch (fts_ent->fts_info) { - case FTS_DNR: - case FTS_ERR: - // log error - success = false; - continue; - break; - case FTS_DP: - success = (rmdir(fts_ent->fts_accpath) == 0); - break; - case FTS_D: - break; - case FTS_NSOK: - case FTS_F: - case FTS_SL: - case FTS_SLNONE: - success = (unlink(fts_ent->fts_accpath) == 0); - break; - default: - DCHECK(false); - break; - } - fts_ent = fts_read(fts); - } - fts_close(fts); - } - return success; -#endif -} - -bool Move(const FilePath& from_path, const FilePath& to_path) { - if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0) - return true; - - if (!CopyDirectory(from_path, to_path, true)) - return false; - - Delete(from_path, true); - return true; -} - -bool CopyDirectory(const FilePath& from_path, - const FilePath& to_path, - bool recursive) { - // Some old callers of CopyDirectory want it to support wildcards. - // After some discussion, we decided to fix those callers. - // Break loudly here if anyone tries to do this. - // TODO(evanm): remove this once we're sure it's ok. - DCHECK(to_path.value().find('*') == std::string::npos); - DCHECK(from_path.value().find('*') == std::string::npos); - - char top_dir[PATH_MAX]; - if (base::strlcpy(top_dir, from_path.value().c_str(), - arraysize(top_dir)) >= arraysize(top_dir)) { - return false; - } - -#ifdef ANDROID - // XXX Need ftsless impl for bionic - return false; -#else - char* dir_list[] = { top_dir, NULL }; - FTS* fts = fts_open(dir_list, FTS_PHYSICAL | FTS_NOSTAT, NULL); - if (!fts) { - CHROMIUM_LOG(ERROR) << "fts_open failed: " << strerror(errno); - return false; - } - - int error = 0; - FTSENT* ent; - while (!error && (ent = fts_read(fts)) != NULL) { - // ent->fts_path is the source path, including from_path, so paste - // the suffix after from_path onto to_path to create the target_path. - std::string suffix(&ent->fts_path[from_path.value().size()]); - // Strip the leading '/' (if any). - if (!suffix.empty()) { - DCHECK_EQ('/', suffix[0]); - suffix.erase(0, 1); - } - const FilePath target_path = to_path.Append(suffix); - switch (ent->fts_info) { - case FTS_D: // Preorder directory. - // If we encounter a subdirectory in a non-recursive copy, prune it - // from the traversal. - if (!recursive && ent->fts_level > 0) { - if (fts_set(fts, ent, FTS_SKIP) != 0) - error = errno; - continue; - } - - // Try creating the target dir, continuing on it if it exists already. - // Rely on the user's umask to produce correct permissions. - if (mkdir(target_path.value().c_str(), 0777) != 0) { - if (errno != EEXIST) - error = errno; - } - break; - case FTS_F: // Regular file. - case FTS_NSOK: // File, no stat info requested. - errno = 0; - if (!CopyFile(FilePath(ent->fts_path), target_path)) - error = errno ? errno : EINVAL; - break; - case FTS_DP: // Postorder directory. - case FTS_DOT: // "." or ".." - // Skip it. - continue; - case FTS_DC: // Directory causing a cycle. - // Skip this branch. - if (fts_set(fts, ent, FTS_SKIP) != 0) - error = errno; - break; - case FTS_DNR: // Directory cannot be read. - case FTS_ERR: // Error. - case FTS_NS: // Stat failed. - // Abort with the error. - error = ent->fts_errno; - break; - case FTS_SL: // Symlink. - case FTS_SLNONE: // Symlink with broken target. - CHROMIUM_LOG(WARNING) << "CopyDirectory() skipping symbolic link: " << - ent->fts_path; - continue; - case FTS_DEFAULT: // Some other sort of file. - CHROMIUM_LOG(WARNING) << "CopyDirectory() skipping file of unknown type: " << - ent->fts_path; - continue; - default: - NOTREACHED(); - continue; // Hope for the best! - } - } - // fts_read may have returned NULL and set errno to indicate an error. - if (!error && errno != 0) - error = errno; - - if (!fts_close(fts)) { - // If we already have an error, let's use that error instead of the error - // fts_close set. - if (!error) - error = errno; - } - - if (error) { - CHROMIUM_LOG(ERROR) << "CopyDirectory(): " << strerror(error); - return false; - } - return true; -#endif + return (rmdir(path_str) == 0); } bool PathExists(const FilePath& path) { diff --git a/ipc/chromium/src/base/file_util_win.cc b/ipc/chromium/src/base/file_util_win.cc index 8a59a74911..4568e02969 100644 --- a/ipc/chromium/src/base/file_util_win.cc +++ b/ipc/chromium/src/base/file_util_win.cc @@ -27,14 +27,14 @@ bool AbsolutePath(FilePath* path) { return true; } -bool Delete(const FilePath& path, bool recursive) { +bool Delete(const FilePath& path) { if (path.value().length() >= MAX_PATH) return false; - // If we're not recursing use DeleteFile; it should be faster. DeleteFile + // Use DeleteFile; it should be faster. DeleteFile // fails if passed a directory though, which is why we fall through on // failure to the SHFileOperation. - if (!recursive && DeleteFile(path.value().c_str()) != 0) + if (DeleteFile(path.value().c_str()) != 0) return true; // SHFILEOPSTRUCT wants the path to be terminated with two NULLs, @@ -48,8 +48,7 @@ bool Delete(const FilePath& path, bool recursive) { file_operation.wFunc = FO_DELETE; file_operation.pFrom = double_terminated_path; file_operation.fFlags = FOF_NOERRORUI | FOF_SILENT | FOF_NOCONFIRMATION; - if (!recursive) - file_operation.fFlags |= FOF_NORECURSION | FOF_FILESONLY; + file_operation.fFlags |= FOF_NORECURSION | FOF_FILESONLY; int err = SHFileOperation(&file_operation); // Some versions of Windows return ERROR_FILE_NOT_FOUND when // deleting an empty directory. @@ -98,26 +97,6 @@ bool ShellCopy(const FilePath& from_path, const FilePath& to_path, return (SHFileOperation(&file_operation) == 0); } -bool CopyDirectory(const FilePath& from_path, const FilePath& to_path, - bool recursive) { - if (recursive) - return ShellCopy(from_path, to_path, true); - - // Instead of creating a new directory, we copy the old one to include the - // security information of the folder as part of the copy. - if (!PathExists(to_path)) { - // Except that Vista fails to do that, and instead do a recursive copy if - // the target directory doesn't exist. - if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) - CreateDirectory(to_path); - else - ShellCopy(from_path, to_path, false); - } - - FilePath directory = from_path.Append(L"*.*"); - return ShellCopy(directory, to_path, false); -} - bool PathExists(const FilePath& path) { return (GetFileAttributes(path.value().c_str()) != INVALID_FILE_ATTRIBUTES); } diff --git a/ipc/chromium/src/base/scoped_temp_dir.cc b/ipc/chromium/src/base/scoped_temp_dir.cc deleted file mode 100644 index 363e4fe4b8..0000000000 --- a/ipc/chromium/src/base/scoped_temp_dir.cc +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/scoped_temp_dir.h" - -#include "base/file_util.h" -#include "base/logging.h" -#include "base/string_util.h" - -ScopedTempDir::ScopedTempDir() { -} - -ScopedTempDir::~ScopedTempDir() { - if (!path_.empty() && !file_util::Delete(path_, true)) - CHROMIUM_LOG(ERROR) << "ScopedTempDir unable to delete " << path_.value(); -} - -bool ScopedTempDir::CreateUniqueTempDir() { - // This "scoped_dir" prefix is only used on Windows and serves as a template - // for the unique name. - if (!file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("scoped_dir"), - &path_)) - return false; - - return true; -} - -bool ScopedTempDir::Set(const FilePath& path) { - DCHECK(path_.empty()); - if (!file_util::DirectoryExists(path) && - !file_util::CreateDirectory(path)) { - return false; - } - path_ = path; - return true; -} - -FilePath ScopedTempDir::Take() { - FilePath ret = path_; - path_ = FilePath(); - return ret; -} - -bool ScopedTempDir::IsValid() const { - return !path_.empty() && file_util::DirectoryExists(path_); -} diff --git a/ipc/chromium/src/base/scoped_temp_dir.h b/ipc/chromium/src/base/scoped_temp_dir.h deleted file mode 100644 index e9d45b9a99..0000000000 --- a/ipc/chromium/src/base/scoped_temp_dir.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_SCOPED_TEMP_DIR_H_ -#define BASE_SCOPED_TEMP_DIR_H_ - -// An object representing a temporary / scratch directory that should be cleaned -// up (recursively) when this object goes out of scope. Note that since -// deletion occurs during the destructor, no further error handling is possible -// if the directory fails to be deleted. As a result, deletion is not -// guaranteed by this class. - -#include "base/file_path.h" - -class ScopedTempDir { - public: - // No directory is owned/created initially. - ScopedTempDir(); - - // Recursively delete path_ - ~ScopedTempDir(); - - // Creates a unique directory in TempPath, and takes ownership of it. - // See file_util::CreateNewTemporaryDirectory. - bool CreateUniqueTempDir(); - - // Takes ownership of directory at |path|, creating it if necessary. - // Don't call multiple times unless Take() has been called first. - bool Set(const FilePath& path); - - // Caller takes ownership of the temporary directory so it won't be destroyed - // when this object goes out of scope. - FilePath Take(); - - const FilePath& path() const { return path_; } - - // Returns true if path_ is non-empty and exists. - bool IsValid() const; - - private: - FilePath path_; - - DISALLOW_COPY_AND_ASSIGN(ScopedTempDir); -}; - -#endif // BASE_SCOPED_TEMP_DIR_H_ diff --git a/ipc/chromium/src/base/shared_memory_posix.cc b/ipc/chromium/src/base/shared_memory_posix.cc index 669b81d662..dc87320173 100644 --- a/ipc/chromium/src/base/shared_memory_posix.cc +++ b/ipc/chromium/src/base/shared_memory_posix.cc @@ -93,7 +93,7 @@ bool SharedMemory::Delete(const std::wstring& name) { FilePath path(WideToUTF8(mem_filename)); if (file_util::PathExists(path)) { - return file_util::Delete(path, false); + return file_util::Delete(path); } // Doesn't exist, so success. @@ -170,7 +170,7 @@ bool SharedMemory::CreateOrOpen(const std::wstring &name, // Deleting the file prevents anyone else from mapping it in // (making it private), and prevents the need for cleanup (once // the last fd is closed, it is truly freed). - file_util::Delete(path, false); + file_util::Delete(path); } else { std::wstring mem_filename; if (FilenameForMemoryName(name, &mem_filename) == false) diff --git a/js/src/asmjs/AsmJSLink.cpp b/js/src/asmjs/AsmJSLink.cpp index b8d3e18d10..6b77945a12 100644 --- a/js/src/asmjs/AsmJSLink.cpp +++ b/js/src/asmjs/AsmJSLink.cpp @@ -824,6 +824,16 @@ HandleDynamicLinkFailure(JSContext* cx, const CallArgs& args, AsmJSModule& modul if (cx->isExceptionPending()) return false; + // Source discarding is allowed to affect JS semantics because it is never + // enabled for normal JS content. + bool haveSource = module.scriptSource()->hasSourceData(); + if (!haveSource && !JSScript::loadSource(cx, module.scriptSource(), &haveSource)) + return false; + if (!haveSource) { + JS_ReportError(cx, "asm.js link failure with source discarding enabled"); + return false; + } + uint32_t begin = module.srcBodyStart(); // starts right after 'use asm' uint32_t end = module.srcEndBeforeCurly(); Rooted src(cx, module.scriptSource()->substringDontDeflate(cx, begin, end)); @@ -1174,9 +1184,6 @@ js::AsmJSModuleToString(JSContext* cx, HandleFunction fun, bool addParenToLambda ScriptSource* source = module.scriptSource(); StringBuffer out(cx); - // Whether the function has been created with a Function ctor - bool funCtor = begin == 0 && end == source->length() && source->argumentsNotIncluded(); - if (addParenToLambda && fun->isLambda() && !out.append("(")) return nullptr; @@ -1186,43 +1193,54 @@ js::AsmJSModuleToString(JSContext* cx, HandleFunction fun, bool addParenToLambda if (fun->atom() && !out.append(fun->atom())) return nullptr; - if (funCtor) { - // Functions created with the function constructor don't have arguments in their source. - if (!out.append("(")) - return nullptr; - - if (PropertyName* argName = module.globalArgumentName()) { - if (!out.append(argName)) - return nullptr; - } - if (PropertyName* argName = module.importArgumentName()) { - if (!out.append(", ") || !out.append(argName)) - return nullptr; - } - if (PropertyName* argName = module.bufferArgumentName()) { - if (!out.append(", ") || !out.append(argName)) - return nullptr; - } - - if (!out.append(") {\n")) - return nullptr; - } - - Rooted src(cx, source->substring(cx, begin, end)); - if (!src) + bool haveSource = source->hasSourceData(); + if (!haveSource && !JSScript::loadSource(cx, source, &haveSource)) return nullptr; - if (module.strict()) { - if (!AppendUseStrictSource(cx, fun, src, out)) + if (!haveSource) { + if (!out.append("() {\n [sourceless code]\n}")) return nullptr; } else { - if (!out.append(src)) + // Whether the function has been created with a Function ctor + bool funCtor = begin == 0 && end == source->length() && source->argumentsNotIncluded(); + if (funCtor) { + // Functions created with the function constructor don't have arguments in their source. + if (!out.append("(")) + return nullptr; + + if (PropertyName* argName = module.globalArgumentName()) { + if (!out.append(argName)) + return nullptr; + } + if (PropertyName* argName = module.importArgumentName()) { + if (!out.append(", ") || !out.append(argName)) + return nullptr; + } + if (PropertyName* argName = module.bufferArgumentName()) { + if (!out.append(", ") || !out.append(argName)) + return nullptr; + } + + if (!out.append(") {\n")) + return nullptr; + } + + Rooted src(cx, source->substring(cx, begin, end)); + if (!src) + return nullptr; + + if (module.strict()) { + if (!AppendUseStrictSource(cx, fun, src, out)) + return nullptr; + } else { + if (!out.append(src)) + return nullptr; + } + + if (funCtor && !out.append("\n}")) return nullptr; } - if (funCtor && !out.append("\n}")) - return nullptr; - if (addParenToLambda && fun->isLambda() && !out.append(")")) return nullptr; @@ -1274,33 +1292,46 @@ js::AsmJSFunctionToString(JSContext* cx, HandleFunction fun) ScriptSource* source = module.scriptSource(); StringBuffer out(cx); - // asm.js functions cannot have been created with a Function constructor - // as they belong within a module. - MOZ_ASSERT(!(begin == 0 && end == source->length() && source->argumentsNotIncluded())); - if (!out.append("function ")) return nullptr; - if (module.strict()) { - // AppendUseStrictSource expects its input to start right after the - // function name, so split the source chars from the src into two parts: - // the function name and the rest (arguments + body). + bool haveSource = source->hasSourceData(); + if (!haveSource && !JSScript::loadSource(cx, source, &haveSource)) + return nullptr; + if (!haveSource) { // asm.js functions can't be anonymous MOZ_ASSERT(fun->atom()); if (!out.append(fun->atom())) return nullptr; - - size_t nameEnd = begin + fun->atom()->length(); - Rooted src(cx, source->substring(cx, nameEnd, end)); - if (!AppendUseStrictSource(cx, fun, src, out)) + if (!out.append("() {\n [sourceless code]\n}")) return nullptr; } else { - Rooted src(cx, source->substring(cx, begin, end)); - if (!src) - return nullptr; - if (!out.append(src)) - return nullptr; + // asm.js functions cannot have been created with a Function constructor + // as they belong within a module. + MOZ_ASSERT(!(begin == 0 && end == source->length() && source->argumentsNotIncluded())); + + if (module.strict()) { + // AppendUseStrictSource expects its input to start right after the + // function name, so split the source chars from the src into two parts: + // the function name and the rest (arguments + body). + + // asm.js functions can't be anonymous + MOZ_ASSERT(fun->atom()); + if (!out.append(fun->atom())) + return nullptr; + + size_t nameEnd = begin + fun->atom()->length(); + Rooted src(cx, source->substring(cx, nameEnd, end)); + if (!src || !AppendUseStrictSource(cx, fun, src, out)) + return nullptr; + } else { + Rooted src(cx, source->substring(cx, begin, end)); + if (!src) + return nullptr; + if (!out.append(src)) + return nullptr; + } } return out.finishString(); diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 28f5ce8e37..7bf02b1d1a 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -2509,7 +2509,7 @@ SetImmutablePrototype(JSContext* cx, unsigned argc, Value* vp) } static bool -SetLazyParsingEnabled(JSContext *cx, unsigned argc, Value *vp) +SetLazyParsingEnabled(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 2232e1d292..fa81d566a3 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -637,6 +637,15 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunct FunctionBox* parent = outerpc->sc->asFunctionBox(); if (parent && parent->inWith) inWith = true; + } else { + // This is like the above case, but when inside eval. + // + // For example: + // + // with(o) { eval("(function() { g(); })();"); } + // + // In this case, the static scope chain tells us the presence of with. + inWith = outerpc->sc->asGlobalSharedContext()->inWith(); } } @@ -4398,13 +4407,6 @@ Parser::exportDeclaration() return handler.newExportDefaultDeclaration(kid, TokenPos(begin, pos().end)); } - case TOK_NAME: - // Handle the form |export a| in the same way as |export let a|, by - // acting as if we've just seen the let keyword. Simply unget the token - // and fall through. - // - // XXX This |export foo = 5| syntax is *not* in ES6! Remove it! - tokenStream.ungetToken(); case TOK_LET: case TOK_CONST: kid = lexicalDeclaration(YieldIsName, tt == TOK_CONST); diff --git a/js/src/frontend/SharedContext.h b/js/src/frontend/SharedContext.h index 2fcd04239d..4f06df253a 100644 --- a/js/src/frontend/SharedContext.h +++ b/js/src/frontend/SharedContext.h @@ -290,6 +290,14 @@ class GlobalSharedContext : public SharedContext } return false; } + + bool inWith() const { + for (StaticScopeIter it(context, topStaticScope_); !it.done(); it++) { + if (it.type() == StaticScopeIter::With) + return true; + } + return false; + } }; class FunctionBox : public ObjectBox, public SharedContext diff --git a/js/src/jit-test/tests/asm.js/bug1219954.js b/js/src/jit-test/tests/asm.js/bug1219954.js new file mode 100644 index 0000000000..17069e7dc3 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1219954.js @@ -0,0 +1,12 @@ +"use strict"; + +if (!('oomTest' in this)) + quit(); + +let g = (function() { + "use asm"; + function f() {} + return f; +})(); + +oomTest(() => "" + g); diff --git a/js/src/jit-test/tests/asm.js/testBug1147144.js b/js/src/jit-test/tests/asm.js/testBug1147144.js new file mode 100644 index 0000000000..894535e420 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1147144.js @@ -0,0 +1,20 @@ +load(libdir + 'asm.js'); +load(libdir + 'asserts.js'); + +if (!isAsmJSCompilationAvailable()) + quit(); + +setLazyParsingEnabled(false) +assertEq(eval(`(function asmModule() { "use asm"; function asmFun() {} return asmFun })`).toString(), "function asmModule() {\n [sourceless code]\n}"); +assertEq(eval(`(function asmModule() { "use asm"; function asmFun() {} return asmFun })`).toSource(), "(function asmModule() {\n [sourceless code]\n})"); +assertEq(eval(`(function asmModule() { "use asm"; function asmFun() {} return asmFun })`)().toString(), "function asmFun() {\n [sourceless code]\n}"); +assertEq(eval(`(function asmModule() { "use asm"; function asmFun() {} return asmFun })`)().toSource(), "function asmFun() {\n [sourceless code]\n}"); +assertEq((evaluate(`function asmModule1() { "use asm"; function asmFun() {} return asmFun }`), asmModule1).toString(), "function asmModule1() {\n [sourceless code]\n}"); +assertEq((evaluate(`function asmModule2() { "use asm"; function asmFun() {} return asmFun }`), asmModule2).toSource(), "function asmModule2() {\n [sourceless code]\n}"); +assertEq((evaluate(`function asmModule3() { "use asm"; function asmFun() {} return asmFun }`), asmModule3)().toString(), "function asmFun() {\n [sourceless code]\n}"); +assertEq((evaluate(`function asmModule4() { "use asm"; function asmFun() {} return asmFun }`), asmModule4)().toSource(), "function asmFun() {\n [sourceless code]\n}"); +assertEq(asmCompile(USE_ASM + `function asmFun() {} return asmFun`).toString(), "function anonymous() {\n [sourceless code]\n}"); +assertEq(asmCompile(USE_ASM + `function asmFun() {} return asmFun`).toSource(), "(function anonymous() {\n [sourceless code]\n})"); +assertEq(asmCompile(USE_ASM + `function asmFun() {} return asmFun`)().toString(), "function asmFun() {\n [sourceless code]\n}"); +assertEq(asmCompile(USE_ASM + `function asmFun() {} return asmFun`)().toSource(), "function asmFun() {\n [sourceless code]\n}"); +assertThrowsInstanceOf(()=>asmCompile('stdlib',USE_ASM + "var sin=stdlib.Math.sin;return {}")({Math:{}}), Error); diff --git a/js/src/jit-test/tests/basic/syntax-error-illegal-character.js b/js/src/jit-test/tests/basic/syntax-error-illegal-character.js index a231963aac..2823f0084e 100644 --- a/js/src/jit-test/tests/basic/syntax-error-illegal-character.js +++ b/js/src/jit-test/tests/basic/syntax-error-illegal-character.js @@ -414,11 +414,6 @@ test("debugger; @"); // export test_no_fun_no_eval("export @"); -test_no_fun_no_eval("export x @"); -test_no_fun_no_eval("export x, @"); -test_no_fun_no_eval("export x, y @"); -test_no_fun_no_eval("export x, y; @"); - test_no_fun_no_eval("export { @"); test_no_fun_no_eval("export { x @"); test_no_fun_no_eval("export { x, @"); @@ -473,6 +468,54 @@ test_no_fun_no_eval("export const a = 1, b = @"); test_no_fun_no_eval("export const a = 1, b = 2 @"); test_no_fun_no_eval("export const a = 1, b = 2; @"); +test_no_fun_no_eval("export class @"); +test_no_fun_no_eval("export class Foo @"); +test_no_fun_no_eval("export class Foo { @"); +test_no_fun_no_eval("export class Foo { constructor @"); +test_no_fun_no_eval("export class Foo { constructor( @"); +test_no_fun_no_eval("export class Foo { constructor() @"); +test_no_fun_no_eval("export class Foo { constructor() { @"); +test_no_fun_no_eval("export class Foo { constructor() {} @"); +test_no_fun_no_eval("export class Foo { constructor() {} } @"); +test_no_fun_no_eval("export class Foo { constructor() {} }; @"); + +test_no_fun_no_eval("export default @"); +test_no_fun_no_eval("export default 1 @"); +test_no_fun_no_eval("export default 1; @"); + +test_no_fun_no_eval("export default function @"); +test_no_fun_no_eval("export default function() @"); +test_no_fun_no_eval("export default function() { @"); +test_no_fun_no_eval("export default function() {} @"); +test_no_fun_no_eval("export default function() {}; @"); + +test_no_fun_no_eval("export default function foo @"); +test_no_fun_no_eval("export default function foo( @"); +test_no_fun_no_eval("export default function foo() @"); +test_no_fun_no_eval("export default function foo() { @"); +test_no_fun_no_eval("export default function foo() {} @"); +test_no_fun_no_eval("export default function foo() {}; @"); + +test_no_fun_no_eval("export default class @"); +test_no_fun_no_eval("export default class { @"); +test_no_fun_no_eval("export default class { constructor @"); +test_no_fun_no_eval("export default class { constructor( @"); +test_no_fun_no_eval("export default class { constructor() @"); +test_no_fun_no_eval("export default class { constructor() { @"); +test_no_fun_no_eval("export default class { constructor() {} @"); +test_no_fun_no_eval("export default class { constructor() {} } @"); +test_no_fun_no_eval("export default class { constructor() {} }; @"); + +test_no_fun_no_eval("export default class Foo @"); +test_no_fun_no_eval("export default class Foo { @"); +test_no_fun_no_eval("export default class Foo { constructor @"); +test_no_fun_no_eval("export default class Foo { constructor( @"); +test_no_fun_no_eval("export default class Foo { constructor() @"); +test_no_fun_no_eval("export default class Foo { constructor() { @"); +test_no_fun_no_eval("export default class Foo { constructor() {} @"); +test_no_fun_no_eval("export default class Foo { constructor() {} } @"); +test_no_fun_no_eval("export default class Foo { constructor() {} }; @"); + // import test_no_fun_no_eval("import @"); @@ -500,6 +543,29 @@ test_no_fun_no_eval("import { x as y } from 'a'; @"); test_no_fun_no_eval("import 'a' @"); test_no_fun_no_eval("import 'a'; @"); +test_no_fun_no_eval("import * @"); +test_no_fun_no_eval("import * as @"); +test_no_fun_no_eval("import * as a @"); +test_no_fun_no_eval("import * as a from @"); +test_no_fun_no_eval("import * as a from 'a' @"); +test_no_fun_no_eval("import * as a from 'a'; @"); + +test_no_fun_no_eval("import a @"); +test_no_fun_no_eval("import a, @"); +test_no_fun_no_eval("import a, * @"); +test_no_fun_no_eval("import a, * as @"); +test_no_fun_no_eval("import a, * as b @"); +test_no_fun_no_eval("import a, * as b from @"); +test_no_fun_no_eval("import a, * as b from 'c' @"); +test_no_fun_no_eval("import a, * as b from 'c'; @"); + +test_no_fun_no_eval("import a, { @"); +test_no_fun_no_eval("import a, { b @"); +test_no_fun_no_eval("import a, { b } @"); +test_no_fun_no_eval("import a, { b } from @"); +test_no_fun_no_eval("import a, { b } from 'c' @"); +test_no_fun_no_eval("import a, { b } from 'c'; @"); + // label test("a @"); diff --git a/js/src/jit-test/tests/modules/export-declaration.js b/js/src/jit-test/tests/modules/export-declaration.js index 9d3245aa58..e65ae49f71 100644 --- a/js/src/jit-test/tests/modules/export-declaration.js +++ b/js/src/jit-test/tests/modules/export-declaration.js @@ -266,25 +266,6 @@ program([ ) ]).assert(Reflect.parse("export let a = 1, b = 2;")); -// NOTE: binding lists are treated as if they were let declarations by esprima, -// so we follow that convention. -program([ - exportDeclaration( - variableDeclaration([ - { - id: ident("a"), - init: lit(1) - }, { - id: ident("b"), - init: lit(2) - } - ]), - null, - null, - false - ) -]).assert(Reflect.parse("export a = 1, b = 2;")); - program([ exportDeclaration( functionDeclaration( @@ -398,3 +379,11 @@ assertThrowsInstanceOf(function() { assertThrowsInstanceOf(function() { Reflect.parse("class() { constructor() {} }"); }, SyntaxError); + +assertThrowsInstanceOf(function() { + Reflect.parse("export x"); +}, SyntaxError); + +assertThrowsInstanceOf(function() { + Reflect.parse("export foo = 5"); +}, SyntaxError); diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index dff205df4d..93b1d03fc3 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -1807,14 +1807,14 @@ const DebugScopeProxy DebugScopeProxy::singleton; DebugScopeObject::create(JSContext* cx, ScopeObject& scope, HandleObject enclosing) { MOZ_ASSERT(scope.compartment() == cx->compartment()); + MOZ_ASSERT(!IsSyntacticScope(enclosing)); + RootedValue priv(cx, ObjectValue(scope)); JSObject* obj = NewProxyObject(cx, &DebugScopeProxy::singleton, priv, nullptr /* proto */); if (!obj) return nullptr; - MOZ_ASSERT(!enclosing->is()); - DebugScopeObject* debugScope = &obj->as(); debugScope->setExtra(ENCLOSING_EXTRA, ObjectValue(*enclosing)); debugScope->setExtra(SNAPSHOT_EXTRA, NullValue()); diff --git a/testing/docker/b2g-build/Dockerfile b/testing/docker/b2g-build/Dockerfile index cba1f4a3bd..ac97329069 100644 --- a/testing/docker/b2g-build/Dockerfile +++ b/testing/docker/b2g-build/Dockerfile @@ -14,7 +14,8 @@ RUN yum install -y epel-release && \ bison \ bzip2 \ ccache \ - cmake \ + # cmake: is disabled intentionally to work around: bug 1141417 + # cmake \ curl \ curl-devel \ dbus-devel \ diff --git a/testing/docker/b2g-build/VERSION b/testing/docker/b2g-build/VERSION index 3a4036fb45..53a75d6735 100644 --- a/testing/docker/b2g-build/VERSION +++ b/testing/docker/b2g-build/VERSION @@ -1 +1 @@ -0.2.5 +0.2.6 diff --git a/testing/docker/builder/Dockerfile b/testing/docker/builder/Dockerfile index d70364a662..441a5e601a 100644 --- a/testing/docker/builder/Dockerfile +++ b/testing/docker/builder/Dockerfile @@ -1,4 +1,4 @@ -FROM quay.io/mozilla/b2g-build:0.2.5 +FROM quay.io/mozilla/b2g-build:0.2.6 MAINTAINER Dustin J. Mitchell ENV PYTHONPATH /tools/tools/lib/python:$PYTHONPATH @@ -21,7 +21,7 @@ RUN git config --global user.email "mozilla@example.com" && \ git config --global user.name "mozilla" # VCS Tools -RUN npm install -g taskcluster-vcs@2.3.0 +RUN npm install -g taskcluster-vcs@2.3.1 # TODO enable worker # TODO volume mount permissions will be an issue diff --git a/testing/docker/builder/VERSION b/testing/docker/builder/VERSION index 8f0916f768..cb0c939a93 100644 --- a/testing/docker/builder/VERSION +++ b/testing/docker/builder/VERSION @@ -1 +1 @@ -0.5.0 +0.5.2 diff --git a/testing/docker/decision/Dockerfile b/testing/docker/decision/Dockerfile index 178d8841bb..42aa6b3b2a 100644 --- a/testing/docker/decision/Dockerfile +++ b/testing/docker/decision/Dockerfile @@ -4,5 +4,5 @@ MAINTAINER Jonas Finnemann Jensen ENV PATH /home/worker/bin/:$PATH # Add utilities and configuration -RUN npm install -g taskcluster-vcs@0.0.2 +RUN npm install -g taskcluster-vcs@2.3.1 ADD bin /home/worker/bin diff --git a/testing/docker/decision/VERSION b/testing/docker/decision/VERSION index bcab45af15..81340c7e72 100644 --- a/testing/docker/decision/VERSION +++ b/testing/docker/decision/VERSION @@ -1 +1 @@ -0.0.3 +0.0.4 diff --git a/testing/docker/phone-builder/Dockerfile b/testing/docker/phone-builder/Dockerfile index b872ca27c7..98792e4e19 100644 --- a/testing/docker/phone-builder/Dockerfile +++ b/testing/docker/phone-builder/Dockerfile @@ -1,4 +1,4 @@ -FROM quay.io/mozilla/builder:0.5.0 +FROM quay.io/mozilla/builder:0.5.2 MAINTAINER Wander Lairson Costa # Add utilities and configuration diff --git a/testing/docker/phone-builder/VERSION b/testing/docker/phone-builder/VERSION index c5d54ec326..2cfabea2f1 100644 --- a/testing/docker/phone-builder/VERSION +++ b/testing/docker/phone-builder/VERSION @@ -1 +1 @@ -0.0.9 +0.0.11 diff --git a/testing/docker/phone-builder/bin/validate_task.py b/testing/docker/phone-builder/bin/validate_task.py index 2b660c3abe..978cd73d7e 100755 --- a/testing/docker/phone-builder/bin/validate_task.py +++ b/testing/docker/phone-builder/bin/validate_task.py @@ -36,12 +36,11 @@ def check_task(task): print('Invalid base repository', repo, file=sys.stderr) return -1 - if 'artifacts' in payload: - artifacts = payload['artifacts'] - # If any of the artifacts makes reference to 'public', - # abort the task - if any(map(lambda a: 'public' in a, artifacts)): - print('Cannot upload to public', file=sys.stderr) + locations = task["extra"]["locations"] + if "img" in locations: + img = locations["img"] + if img.startswith("public"): + print('Cannot upload images to public', file=sys.stderr) return -1 return 0 diff --git a/testing/docker/tester/Dockerfile b/testing/docker/tester/Dockerfile index ba07f8f116..b3d0dbfe5b 100644 --- a/testing/docker/tester/Dockerfile +++ b/testing/docker/tester/Dockerfile @@ -16,7 +16,7 @@ RUN chmod u+x /home/worker/bin/buildbot_step RUN pip install virtualenv; RUN mkdir Documents; mkdir Pictures; mkdir Music; mkdir Videos; mkdir artifacts RUN chown -R worker:worker /home/worker/* /home/worker/.* -RUN npm install -g taskcluster-vcs@2.2.0 +RUN npm install -g taskcluster-vcs@2.3.1 ENV PATH $PATH:/home/worker/bin # TODO Re-enable worker when bug 1093833 lands diff --git a/testing/docker/tester/VERSION b/testing/docker/tester/VERSION index 9789c4ccb0..ceddfb28f4 100644 --- a/testing/docker/tester/VERSION +++ b/testing/docker/tester/VERSION @@ -1 +1 @@ -0.0.14 +0.0.15 diff --git a/testing/taskcluster/mach_commands.py b/testing/taskcluster/mach_commands.py index 1835c067ba..ec75e7c8d7 100644 --- a/testing/taskcluster/mach_commands.py +++ b/testing/taskcluster/mach_commands.py @@ -327,6 +327,8 @@ class Graph(object): graph['scopes'].append(define_task) graph['scopes'].extend(build_task['task'].get('scopes', [])) + route_scopes = map(lambda route: 'queue:route:' + route, build_task['task'].get('routes', [])) + graph['scopes'].extend(route_scopes) # Treeherder symbol configuration for the graph required for each # build so tests know which platform they belong to.