Bug 1070131 - Switch originPrincipals to a mutedError flags. r=luke,r=bz
authorBobby Holley <bobbyholley@gmail.com>
Mon, 29 Sep 2014 10:44:30 +0200
changeset 207625 ee03a0b3b0375e344abb72d775350a97529408a6
parent 207624 b9bfd9b37fe82071ac5da7360608fd301f98e57e
child 207626 7fde2c699ac3ff40e1e9ca77918541aceb8ce212
push id49738
push userbobbyholley@gmail.com
push dateMon, 29 Sep 2014 08:44:52 +0000
treeherdermozilla-inbound@ee03a0b3b037 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke, bz
bugs1070131
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1070131 - Switch originPrincipals to a mutedError flags. r=luke,r=bz
content/base/src/nsScriptLoader.cpp
dom/base/nsJSEnvironment.cpp
js/src/asmjs/AsmJSLink.cpp
js/src/builtin/Eval.cpp
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/TokenStream.cpp
js/src/frontend/TokenStream.h
js/src/jsapi-tests/moz.build
js/src/jsapi-tests/testMutedErrors.cpp
js/src/jsapi-tests/testOriginPrincipals.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jscntxt.cpp
js/src/jsexn.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/vm/ErrorObject.cpp
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/vm/Xdr.h
js/xpconnect/loader/mozJSLoaderUtils.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcpublic.h
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -1053,17 +1053,19 @@ nsScriptLoader::FillCompileOptionsForReq
   aOptions->setIntroductionType("scriptElement");
   aOptions->setFileAndLine(aRequest->mURL.get(), aRequest->mLineNo);
   aOptions->setVersion(JSVersion(aRequest->mJSVersion));
   aOptions->setCompileAndGo(JS_IsGlobalObject(aScopeChain));
   if (aRequest->mHasSourceMapURL) {
     aOptions->setSourceMapURL(aRequest->mSourceMapURL.get());
   }
   if (aRequest->mOriginPrincipal) {
-    aOptions->setOriginPrincipals(nsJSPrincipals::get(aRequest->mOriginPrincipal));
+    nsIPrincipal* scriptPrin = nsContentUtils::ObjectPrincipal(aScopeChain);
+    bool subsumes = scriptPrin->Subsumes(aRequest->mOriginPrincipal);
+    aOptions->setMutedErrors(!subsumes);
   }
 
   JSContext* cx = jsapi.cx();
   JS::Rooted<JS::Value> elementVal(cx);
   MOZ_ASSERT(aRequest->mElement);
   if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, aRequest->mElement,
                                               &elementVal,
                                               /* aAllowWrapping = */ true))) {
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -348,20 +348,18 @@ NS_HandleScriptError(nsIScriptGlobalObje
   return called;
 }
 
 class ScriptErrorEvent : public nsRunnable
 {
 public:
   ScriptErrorEvent(JSRuntime* aRuntime,
                    xpc::ErrorReport* aReport,
-                   nsIPrincipal* aScriptOriginPrincipal,
                    JS::Handle<JS::Value> aError)
     : mReport(aReport)
-    , mOriginPrincipal(aScriptOriginPrincipal)
     , mError(aRuntime, aError)
   {}
 
   NS_IMETHOD Run()
   {
     nsEventStatus status = nsEventStatus_eIgnore;
     nsPIDOMWindow* win = mReport->mWindow;
     MOZ_ASSERT(win);
@@ -375,31 +373,18 @@ public:
       win->GetDocShell()->GetPresContext(getter_AddRefs(presContext));
 
       ThreadsafeAutoJSContext cx;
       RootedDictionary<ErrorEventInit> init(cx);
       init.mCancelable = true;
       init.mFilename = mReport->mFileName;
       init.mBubbles = true;
 
-      nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(win));
-      NS_ENSURE_STATE(sop);
-      nsIPrincipal* p = sop->GetPrincipal();
-      NS_ENSURE_STATE(p);
-
-      bool sameOrigin = !mOriginPrincipal;
-
-      if (p && !sameOrigin) {
-        if (NS_FAILED(p->Subsumes(mOriginPrincipal, &sameOrigin))) {
-          sameOrigin = false;
-        }
-      }
-
       NS_NAMED_LITERAL_STRING(xoriginMsg, "Script error.");
-      if (sameOrigin) {
+      if (!mReport->mIsMuted) {
         init.mMessage = mReport->mErrorMsg;
         init.mLineno = mReport->mLineNumber;
         init.mColno = mReport->mColumn;
         init.mError = mError;
       } else {
         NS_WARNING("Not same origin error!");
         init.mMessage = xoriginMsg;
         init.mLineno = 0;
@@ -418,17 +403,16 @@ public:
       mReport->LogToConsole();
     }
 
     return NS_OK;
   }
 
 private:
   nsRefPtr<xpc::ErrorReport>      mReport;
-  nsCOMPtr<nsIPrincipal>          mOriginPrincipal;
   JS::PersistentRootedValue       mError;
 
   static bool sHandlingScriptError;
 };
 
 bool ScriptErrorEvent::sHandlingScriptError = false;
 
 // This temporarily lives here to avoid code churn. It will go away entirely
@@ -492,21 +476,17 @@ SystemErrorReporter(JSContext *cx, const
         report->errorNumber == JSMSG_OUT_OF_MEMORY)
     {
       xpcReport->LogToConsole();
       return;
     }
 
     // Otherwise, we need to asynchronously invoke onerror before we can decide
     // whether or not to report the error to the console.
-    nsContentUtils::AddScriptRunner(
-      new ScriptErrorEvent(JS_GetRuntime(cx),
-                           xpcReport,
-                           nsJSPrincipals::get(report->originPrincipals),
-                           exception));
+    nsContentUtils::AddScriptRunner(new ScriptErrorEvent(JS_GetRuntime(cx), xpcReport, exception));
   }
 }
 
 } /* namespace xpc */
 
 #ifdef DEBUG
 // A couple of useful functions to call when you're debugging.
 nsGlobalWindow *
--- a/js/src/asmjs/AsmJSLink.cpp
+++ b/js/src/asmjs/AsmJSLink.cpp
@@ -771,17 +771,17 @@ HandleDynamicLinkFailure(JSContext *cx, 
     if (module.globalArgumentName())
         formals.infallibleAppend(module.globalArgumentName());
     if (module.importArgumentName())
         formals.infallibleAppend(module.importArgumentName());
     if (module.bufferArgumentName())
         formals.infallibleAppend(module.bufferArgumentName());
 
     CompileOptions options(cx);
-    options.setOriginPrincipals(module.scriptSource()->originPrincipals())
+    options.setMutedErrors(module.scriptSource()->mutedErrors())
            .setFile(module.scriptSource()->filename())
            .setCompileAndGo(false)
            .setNoScriptRval(false);
 
     // The exported function inherits an implicit strict context if the module
     // also inherited it somehow.
     if (module.strict())
         options.strictOption = true;
--- a/js/src/builtin/Eval.cpp
+++ b/js/src/builtin/Eval.cpp
@@ -307,34 +307,34 @@ EvalKernel(JSContext *cx, const CallArgs
 
     if (evalType == DIRECT_EVAL && caller.isNonEvalFunctionFrame())
         esg.lookupInEvalCache(flatStr, callerScript, pc);
 
     if (!esg.foundScript()) {
         RootedScript maybeScript(cx);
         unsigned lineno;
         const char *filename;
-        JSPrincipals *originPrincipals;
+        bool mutedErrors;
         uint32_t pcOffset;
         DescribeScriptedCallerForCompilation(cx, &maybeScript, &filename, &lineno, &pcOffset,
-                                             &originPrincipals,
+                                             &mutedErrors,
                                              evalType == DIRECT_EVAL
                                              ? CALLED_FROM_JSOP_EVAL
                                              : NOT_CALLED_FROM_JSOP_EVAL);
 
         const char *introducerFilename = filename;
         if (maybeScript && maybeScript->scriptSource()->introducerFilename())
             introducerFilename = maybeScript->scriptSource()->introducerFilename();
 
         CompileOptions options(cx);
         options.setFileAndLine(filename, 1)
                .setCompileAndGo(true)
                .setForEval(true)
                .setNoScriptRval(false)
-               .setOriginPrincipals(originPrincipals)
+               .setMutedErrors(mutedErrors)
                .setIntroductionInfo(introducerFilename, "eval", lineno, maybeScript, pcOffset);
 
         AutoStableStringChars flatChars(cx);
         if (!flatChars.initTwoByte(cx, flatStr))
             return false;
 
         const char16_t *chars = flatChars.twoByteRange().start().get();
         SourceBufferHolder::Ownership ownership = flatChars.maybeGiveOwnershipToCaller()
@@ -383,31 +383,31 @@ js::DirectEvalStringFromIon(JSContext *c
     EvalScriptGuard esg(cx);
 
     esg.lookupInEvalCache(flatStr, callerScript, pc);
 
     if (!esg.foundScript()) {
         RootedScript maybeScript(cx);
         const char *filename;
         unsigned lineno;
-        JSPrincipals *originPrincipals;
+        bool mutedErrors;
         uint32_t pcOffset;
         DescribeScriptedCallerForCompilation(cx, &maybeScript, &filename, &lineno, &pcOffset,
-                                              &originPrincipals, CALLED_FROM_JSOP_EVAL);
+                                              &mutedErrors, CALLED_FROM_JSOP_EVAL);
 
         const char *introducerFilename = filename;
         if (maybeScript && maybeScript->scriptSource()->introducerFilename())
             introducerFilename = maybeScript->scriptSource()->introducerFilename();
 
         CompileOptions options(cx);
         options.setFileAndLine(filename, 1)
                .setCompileAndGo(true)
                .setForEval(true)
                .setNoScriptRval(false)
-               .setOriginPrincipals(originPrincipals)
+               .setMutedErrors(mutedErrors)
                .setIntroductionInfo(introducerFilename, "eval", lineno, maybeScript, pcOffset);
 
         AutoStableStringChars flatChars(cx);
         if (!flatChars.initTwoByte(cx, flatStr))
             return false;
 
         const char16_t *chars = flatChars.twoByteRange().start().get();
         SourceBufferHolder::Ownership ownership = flatChars.maybeGiveOwnershipToCaller()
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -461,17 +461,17 @@ frontend::CompileScript(ExclusiveContext
 }
 
 bool
 frontend::CompileLazyFunction(JSContext *cx, Handle<LazyScript*> lazy, const char16_t *chars, size_t length)
 {
     JS_ASSERT(cx->compartment() == lazy->functionNonDelazifying()->compartment());
 
     CompileOptions options(cx, lazy->version());
-    options.setOriginPrincipals(lazy->originPrincipals())
+    options.setMutedErrors(lazy->mutedErrors())
            .setFileAndLine(lazy->source()->filename(), lazy->lineno())
            .setColumn(lazy->column())
            .setCompileAndGo(true)
            .setNoScriptRval(false)
            .setSelfHostingMode(false);
 
     js::TraceLogger *logger = js::TraceLoggerForMainThread(cx->runtime());
     uint32_t logId = js::TraceLogCreateTextId(logger, options);
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -5170,17 +5170,17 @@ EmitFunc(ExclusiveContext *cx, BytecodeE
 
             if (outersc->isFunctionBox() && outersc->asFunctionBox()->mightAliasLocals())
                 funbox->setMightAliasLocals();      // inherit mightAliasLocals from parent
             JS_ASSERT_IF(outersc->strict, funbox->strict);
 
             // Inherit most things (principals, version, etc) from the parent.
             Rooted<JSScript*> parent(cx, bce->script);
             CompileOptions options(cx, bce->parser->options());
-            options.setOriginPrincipals(parent->originPrincipals())
+            options.setMutedErrors(parent->mutedErrors())
                    .setCompileAndGo(parent->compileAndGo())
                    .setSelfHostingMode(parent->selfHosted())
                    .setNoScriptRval(false)
                    .setForEval(false)
                    .setVersion(parent->getVersion());
 
             Rooted<JSObject*> enclosingScope(cx, EnclosingStaticScope(bce));
             Rooted<JSObject*> sourceObject(cx, bce->script->sourceObject());
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -296,23 +296,19 @@ TokenStream::TokenStream(ExclusiveContex
     linebase(base - options.column),
     prevLinebase(nullptr),
     userbuf(cx, base - options.column, length + options.column), // See comment below
     filename(options.filename()),
     displayURL_(nullptr),
     sourceMapURL_(nullptr),
     tokenbuf(cx),
     cx(cx),
-    originPrincipals(options.originPrincipals(cx)),
+    mutedErrors(options.mutedErrors()),
     strictModeGetter(smg)
 {
-    // The caller must ensure that a reference is held on the supplied principals
-    // throughout compilation.
-    JS_ASSERT_IF(originPrincipals, originPrincipals->refcount > 0);
-
     // Column numbers are computed as offsets from the current line's base, so the
     // initial line's base must be included in the buffer. linebase and userbuf
     // were adjusted above, and if we are starting tokenization part way through
     // this line then adjust the next character.
     userbuf.setAddressOfNextRawChar(base, /* allowPoisoned = */ true);
 
     // Nb: the following tables could be static, but initializing them here is
     // much easier.  Don't worry, the time to initialize them for each
@@ -349,17 +345,16 @@ TokenStream::TokenStream(ExclusiveContex
 }
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 TokenStream::~TokenStream()
 {
-    JS_ASSERT_IF(originPrincipals, originPrincipals->refcount);
 }
 
 // Use the fastest available getc.
 #if defined(HAVE_GETC_UNLOCKED)
 # define fast_getc getc_unlocked
 #elif defined(HAVE__GETC_NOLOCK)
 # define fast_getc _getc_nolock
 #else
@@ -637,17 +632,17 @@ TokenStream::reportCompileErrorNumberVA(
     // On the main thread, report the error immediately. When compiling off
     // thread, save the error so that the main thread can report it later.
     CompileError tempErr;
     CompileError &err = cx->isJSContext() ? tempErr : cx->addPendingCompileError();
 
     err.report.flags = flags;
     err.report.errorNumber = errorNumber;
     err.report.filename = filename;
-    err.report.originPrincipals = originPrincipals;
+    err.report.isMuted = mutedErrors;
     if (offset == NoOffset) {
         err.report.lineno = 0;
         err.report.column = 0;
     } else {
         err.report.lineno = srcCoords.lineNum(offset);
         err.report.column = srcCoords.columnIndex(offset);
     }
 
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -265,17 +265,17 @@ class MOZ_STACK_CLASS TokenStream
     const Token &currentToken() const { return tokens[cursor]; }
     bool isCurrentTokenType(TokenKind type) const {
         return currentToken().type == type;
     }
     const CharBuffer &getTokenbuf() const { return tokenbuf; }
     const char *getFilename() const { return filename; }
     unsigned getLineno() const { return lineno; }
     unsigned getColumn() const { return userbuf.addressOfNextRawChar() - linebase - 1; }
-    JSPrincipals *getOriginPrincipals() const { return originPrincipals; }
+    bool getMutedErrors() const { return mutedErrors; }
     JSVersion versionNumber() const { return VersionNumber(options().version); }
     JSVersion versionWithFlags() const { return options().version; }
 
     PropertyName *currentName() const {
         if (isCurrentTokenType(TOK_YIELD))
             return cx->names().yield;
         JS_ASSERT(isCurrentTokenType(TOK_NAME));
         return currentToken().name();
@@ -765,17 +765,17 @@ class MOZ_STACK_CLASS TokenStream
     const char          *filename;          // input filename or null
     mozilla::UniquePtr<char16_t[], JS::FreePolicy> displayURL_; // the user's requested source URL or null
     mozilla::UniquePtr<char16_t[], JS::FreePolicy> sourceMapURL_; // source map's filename or null
     CharBuffer          tokenbuf;           // current token string buffer
     bool                maybeEOL[256];      // probabilistic EOL lookup table
     bool                maybeStrSpecial[256];   // speeds up string scanning
     uint8_t             isExprEnding[TOK_LIMIT];// which tokens definitely terminate exprs?
     ExclusiveContext    *const cx;
-    JSPrincipals        *const originPrincipals;
+    bool                mutedErrors;
     StrictModeGetter    *strictModeGetter;  // used to test for strict mode
 };
 
 // Steal one JSREPORT_* bit (see jsapi.h) to tell that arguments to the error
 // message have const char16_t* type, not const char*.
 #define JSREPORT_UC 0x100
 
 extern const char *
--- a/js/src/jsapi-tests/moz.build
+++ b/js/src/jsapi-tests/moz.build
@@ -44,22 +44,22 @@ UNIFIED_SOURCES += [
     'testIntern.cpp',
     'testIntString.cpp',
     'testIntTypesABI.cpp',
     'testIsInsideNursery.cpp',
     'testJSEvaluateScript.cpp',
     'testLookup.cpp',
     'testLooselyEqual.cpp',
     'testMappedArrayBuffer.cpp',
+    'testMutedErrors.cpp',
     'testNewObject.cpp',
     'testNullRoot.cpp',
     'testObjectEmulatingUndefined.cpp',
     'testOOM.cpp',
     'testOps.cpp',
-    'testOriginPrincipals.cpp',
     'testParseJSON.cpp',
     'testPersistentRooted.cpp',
     'testPreserveJitCode.cpp',
     'testProfileStrings.cpp',
     'testPropCache.cpp',
     'testRegExp.cpp',
     'testResolveRecursion.cpp',
     'tests.cpp',
rename from js/src/jsapi-tests/testOriginPrincipals.cpp
rename to js/src/jsapi-tests/testMutedErrors.cpp
--- a/js/src/jsapi-tests/testOriginPrincipals.cpp
+++ b/js/src/jsapi-tests/testMutedErrors.cpp
@@ -1,28 +1,19 @@
 /* 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/. */
 
 #include "jsfriendapi.h"
 #include "js/OldDebugAPI.h"
 #include "jsapi-tests/tests.h"
 
-static JSPrincipals *sOriginPrincipalsInErrorReporter = nullptr;
-static TestJSPrincipals prin1(1);
-static TestJSPrincipals prin2(1);
-
-BEGIN_TEST(testOriginPrincipals)
+static bool sErrorReportMuted = false;
+BEGIN_TEST(testMutedErrors)
 {
-    /*
-     * Currently, the only way to set a non-trivial originPrincipal is to use
-     * JS_EvaluateUCScriptForPrincipalsVersionOrigin. This does not expose the
-     * compiled script, so we can only test nested scripts.
-     */
-
     CHECK(testOuter("function f() {return 1}; f;"));
     CHECK(testOuter("function outer() { return (function () {return 2}); }; outer();"));
     CHECK(testOuter("eval('(function() {return 3})');"));
     CHECK(testOuter("(function (){ return eval('(function() {return 4})'); })()"));
     CHECK(testOuter("(function (){ return eval('(function() { return eval(\"(function(){return 5})\") })()'); })()"));
     CHECK(testOuter("new Function('return 6')"));
     CHECK(testOuter("function f() { return new Function('return 7') }; f();"));
     CHECK(testOuter("eval('new Function(\"return 8\")')"));
@@ -33,78 +24,77 @@ BEGIN_TEST(testOriginPrincipals)
     JS_SetErrorReporter(rt, ErrorReporter);
     CHECK(testError("eval(-)"));
     CHECK(testError("-"));
     CHECK(testError("new Function('x', '-')"));
     CHECK(testError("eval('new Function(\"x\", \"-\")')"));
 
     /*
      * NB: uncaught exceptions, when reported, have nothing on the stack so
-     * both the filename and originPrincipals are null. E.g., this would fail:
+     * both the filename and mutedErrors are empty. E.g., this would fail:
      *
      *   CHECK(testError("throw 3"));
      */
     return true;
 }
 
 static void
 ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
 {
-    sOriginPrincipalsInErrorReporter = report->originPrincipals;
+    sErrorReportMuted = report->isMuted;
 }
 
 bool
-eval(const char *asciiChars, JSPrincipals *principals, JSPrincipals *originPrincipals, JS::MutableHandleValue rval)
+eval(const char *asciiChars, bool mutedErrors, JS::MutableHandleValue rval)
 {
     size_t len = strlen(asciiChars);
     char16_t *chars = new char16_t[len+1];
     for (size_t i = 0; i < len; ++i)
         chars[i] = asciiChars[i];
     chars[len] = 0;
 
-    JS::RootedObject global(cx, JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook));
+    JS::RootedObject global(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook));
     CHECK(global);
     JSAutoCompartment ac(cx, global);
     CHECK(JS_InitStandardClasses(cx, global));
 
 
     JS::CompileOptions options(cx);
-    options.setOriginPrincipals(originPrincipals)
+    options.setMutedErrors(mutedErrors)
            .setFileAndLine("", 0);
 
     bool ok = JS::Evaluate(cx, global, options, chars, len, rval);
 
     delete[] chars;
     return ok;
 }
 
 bool
 testOuter(const char *asciiChars)
 {
-    CHECK(testInner(asciiChars, &prin1, &prin1));
-    CHECK(testInner(asciiChars, &prin1, &prin2));
+    CHECK(testInner(asciiChars, false));
+    CHECK(testInner(asciiChars, true));
     return true;
 }
 
 bool
-testInner(const char *asciiChars, JSPrincipals *principal, JSPrincipals *originPrincipal)
+testInner(const char *asciiChars, bool mutedErrors)
 {
     JS::RootedValue rval(cx);
-    CHECK(eval(asciiChars, principal, originPrincipal, &rval));
+    CHECK(eval(asciiChars, mutedErrors, &rval));
 
     JS::RootedFunction fun(cx, &rval.toObject().as<JSFunction>());
     JSScript *script = JS_GetFunctionScript(cx, fun);
-    CHECK(JS_GetScriptPrincipals(script) == principal);
-    CHECK(JS_GetScriptOriginPrincipals(script) == originPrincipal);
+    CHECK(JS_ScriptHasMutedErrors(script) == mutedErrors);
 
     return true;
 }
 
 bool
 testError(const char *asciiChars)
 {
     JS::RootedValue rval(cx);
-    CHECK(!eval(asciiChars, &prin1, &prin2 /* = originPrincipals */, &rval));
+    CHECK(!eval(asciiChars, true, &rval));
     CHECK(JS_ReportPendingException(cx));
-    CHECK(sOriginPrincipalsInErrorReporter == &prin2);
+    CHECK(sErrorReportMuted == true);
     return true;
 }
-END_TEST(testOriginPrincipals)
+END_TEST(testMutedErrors)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4330,48 +4330,39 @@ JS::ReadOnlyCompileOptions::copyPODOptio
     installedFile = rhs.installedFile;
     sourceIsLazy = rhs.sourceIsLazy;
     introductionType = rhs.introductionType;
     introductionLineno = rhs.introductionLineno;
     introductionOffset = rhs.introductionOffset;
     hasIntroductionInfo = rhs.hasIntroductionInfo;
 }
 
-JSPrincipals *
-JS::ReadOnlyCompileOptions::originPrincipals(ExclusiveContext *cx) const
-{
-    return NormalizeOriginPrincipals(cx->compartment()->principals, originPrincipals_);
-}
-
 JS::OwningCompileOptions::OwningCompileOptions(JSContext *cx)
     : ReadOnlyCompileOptions(),
       runtime(GetRuntime(cx)),
       elementRoot(cx),
       elementAttributeNameRoot(cx),
       introductionScriptRoot(cx)
 {
 }
 
 JS::OwningCompileOptions::~OwningCompileOptions()
 {
-    if (originPrincipals_)
-        JS_DropPrincipals(runtime, originPrincipals_);
-
     // OwningCompileOptions always owns these, so these casts are okay.
     js_free(const_cast<char *>(filename_));
     js_free(const_cast<char16_t *>(sourceMapURL_));
     js_free(const_cast<char *>(introducerFilename_));
 }
 
 bool
 JS::OwningCompileOptions::copy(JSContext *cx, const ReadOnlyCompileOptions &rhs)
 {
     copyPODOptions(rhs);
 
-    setOriginPrincipals(rhs.originPrincipals(cx));
+    setMutedErrors(rhs.mutedErrors());
     setElement(rhs.element());
     setElementAttributeName(rhs.elementAttributeName());
     setIntroductionScript(rhs.introductionScript());
 
     return setFileAndLine(cx, rhs.filename(), rhs.lineno) &&
            setSourceMapURL(cx, rhs.sourceMapURL()) &&
            setIntroducerFilename(cx, rhs.introducerFilename());
 }
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3539,27 +3539,38 @@ namespace JS {
  * is protected anyway); instead, create instances only of the derived classes:
  * CompileOptions and OwningCompileOptions.
  */
 class JS_FRIEND_API(ReadOnlyCompileOptions)
 {
     friend class CompileOptions;
 
   protected:
-    JSPrincipals *originPrincipals_;
+    // The Web Platform allows scripts to be loaded from arbitrary cross-origin
+    // sources. This allows an attack by which a malicious website loads a
+    // sensitive file (say, a bank statement) cross-origin (using the user's
+    // cookies), and sniffs the generated syntax errors (via a window.onerror
+    // handler) for juicy morsels of its contents.
+    //
+    // To counter this attack, HTML5 specifies that script errors should be
+    // sanitized ("muted") when the script is not same-origin with the global
+    // for which it is loaded. Callers should set this flag for cross-origin
+    // scripts, and it will be propagated appropriately to child scripts and
+    // passed back in JSErrorReports.
+    bool mutedErrors_;
     const char *filename_;
     const char *introducerFilename_;
     const char16_t *sourceMapURL_;
 
     // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure
     // is unusable until that's set to something more specific; the derived
     // classes' constructors take care of that, in ways appropriate to their
     // purpose.
     ReadOnlyCompileOptions()
-      : originPrincipals_(nullptr),
+      : mutedErrors_(false),
         filename_(nullptr),
         introducerFilename_(nullptr),
         sourceMapURL_(nullptr),
         version(JSVERSION_UNKNOWN),
         versionSet(false),
         utf8(false),
         lineno(1),
         column(0),
@@ -3584,17 +3595,17 @@ class JS_FRIEND_API(ReadOnlyCompileOptio
 
     // Set all POD options (those not requiring reference counts, copies,
     // rooting, or other hand-holding) to their values in |rhs|.
     void copyPODOptions(const ReadOnlyCompileOptions &rhs);
 
   public:
     // Read-only accessors for non-POD options. The proper way to set these
     // depends on the derived type.
-    JSPrincipals *originPrincipals(js::ExclusiveContext *cx) const;
+    bool mutedErrors() const { return mutedErrors_; }
     const char *filename() const { return filename_; }
     const char *introducerFilename() const { return introducerFilename_; }
     const char16_t *sourceMapURL() const { return sourceMapURL_; }
     virtual JSObject *element() const = 0;
     virtual JSString *elementAttributeName() const = 0;
     virtual JSScript *introductionScript() const = 0;
 
     // POD options.
@@ -3679,20 +3690,18 @@ class JS_FRIEND_API(OwningCompileOptions
     OwningCompileOptions &setElementAttributeName(JSString *p) {
         elementAttributeNameRoot = p;
         return *this;
     }
     OwningCompileOptions &setIntroductionScript(JSScript *s) {
         introductionScriptRoot = s;
         return *this;
     }
-    OwningCompileOptions &setOriginPrincipals(JSPrincipals *p) {
-        if (p) JS_HoldPrincipals(p);
-        if (originPrincipals_) JS_DropPrincipals(runtime, originPrincipals_);
-        originPrincipals_ = p;
+    OwningCompileOptions &setMutedErrors(bool mute) {
+        mutedErrors_ = mute;
         return *this;
     }
     OwningCompileOptions &setVersion(JSVersion v) {
         version = v;
         versionSet = true;
         return *this;
     }
     OwningCompileOptions &setUTF8(bool u) { utf8 = u; return *this; }
@@ -3738,17 +3747,17 @@ class MOZ_STACK_CLASS JS_FRIEND_API(Comp
   public:
     explicit CompileOptions(JSContext *cx, JSVersion version = JSVERSION_UNKNOWN);
     CompileOptions(js::ContextFriendFields *cx, const ReadOnlyCompileOptions &rhs)
       : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx),
         introductionScriptRoot(cx)
     {
         copyPODOptions(rhs);
 
-        originPrincipals_ = rhs.originPrincipals_;
+        mutedErrors_ = rhs.mutedErrors_;
         filename_ = rhs.filename();
         sourceMapURL_ = rhs.sourceMapURL();
         elementRoot = rhs.element();
         elementAttributeNameRoot = rhs.elementAttributeName();
         introductionScriptRoot = rhs.introductionScript();
     }
 
     JSObject *element() const MOZ_OVERRIDE { return elementRoot; }
@@ -3765,18 +3774,18 @@ class MOZ_STACK_CLASS JS_FRIEND_API(Comp
     CompileOptions &setElementAttributeName(JSString *p) {
         elementAttributeNameRoot = p;
         return *this;
     }
     CompileOptions &setIntroductionScript(JSScript *s) {
         introductionScriptRoot = s;
         return *this;
     }
-    CompileOptions &setOriginPrincipals(JSPrincipals *p) {
-        originPrincipals_ = p;
+    CompileOptions &setMutedErrors(bool mute) {
+        mutedErrors_ = mute;
         return *this;
     }
     CompileOptions &setVersion(JSVersion v) {
         version = v;
         versionSet = true;
         return *this;
     }
     CompileOptions &setUTF8(bool u) { utf8 = u; return *this; }
@@ -4633,17 +4642,17 @@ JS_ReportOutOfMemory(JSContext *cx);
 /*
  * Complain when an allocation size overflows the maximum supported limit.
  */
 extern JS_PUBLIC_API(void)
 JS_ReportAllocationOverflow(JSContext *cx);
 
 struct JSErrorReport {
     const char      *filename;      /* source file name, URL, etc., or null */
-    JSPrincipals    *originPrincipals; /* see 'originPrincipals' comment above */
+    bool            isMuted;        /* See the comment in ReadOnlyCompileOptions. */
     unsigned        lineno;         /* source line number */
     const char      *linebuf;       /* offending source line without final \n */
     const char      *tokenptr;      /* pointer to error token in linebuf */
     const char16_t  *uclinebuf;     /* unicode (original) line buffer */
     const char16_t  *uctokenptr;    /* unicode (original) token pointer */
     unsigned        flags;          /* error/warning, etc. */
     unsigned        errorNumber;    /* the error number, e.g. see js.msg */
     const char16_t  *ucmessage;     /* the (default) error message */
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -309,32 +309,32 @@ ReportError(JSContext *cx, const char *m
     if (!JS_IsRunning(cx) || !js_ErrorToException(cx, message, reportp, callback, userRef)) {
         if (message)
             CallErrorReporter(cx, message, reportp);
     }
 }
 
 /*
  * The given JSErrorReport object have been zeroed and must not outlive
- * cx->fp() (otherwise report->originPrincipals may become invalid).
+ * cx->fp() (otherwise owned fields may become invalid).
  */
 static void
 PopulateReportBlame(JSContext *cx, JSErrorReport *report)
 {
     /*
      * Walk stack until we find a frame that is associated with a non-builtin
      * rather than a builtin frame.
      */
     NonBuiltinFrameIter iter(cx);
     if (iter.done())
         return;
 
     report->filename = iter.scriptFilename();
     report->lineno = iter.computeLine(&report->column);
-    report->originPrincipals = iter.originPrincipals();
+    report->isMuted = iter.mutedErrors();
 }
 
 /*
  * Since memory has been exhausted, avoid the normal error-handling path which
  * allocates an error object, report and callstack. If code is running, simply
  * throw the static atom "out of memory". If code is not running, call the
  * error reporter directly.
  *
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -226,20 +226,18 @@ js::CopyErrorReport(JSContext *cx, JSErr
     }
 
     if (report->filename) {
         copy->filename = (const char *)cursor;
         js_memcpy(cursor, report->filename, filenameSize);
     }
     JS_ASSERT(cursor + filenameSize == (uint8_t *)copy + mallocSize);
 
-    /* HOLD called by the destination error object. */
-    copy->originPrincipals = report->originPrincipals;
-
     /* Copy non-pointer members. */
+    copy->isMuted = report->isMuted;
     copy->lineno = report->lineno;
     copy->column = report->column;
     copy->errorNumber = report->errorNumber;
     copy->exnType = report->exnType;
 
     /* Note that this is before it gets flagged with JSREPORT_EXCEPTION */
     copy->flags = report->flags;
 
@@ -322,22 +320,18 @@ js::ComputeStackString(JSContext *cx)
     }
 
     return sb.finishString();
 }
 
 static void
 exn_finalize(FreeOp *fop, JSObject *obj)
 {
-    if (JSErrorReport *report = obj->as<ErrorObject>().getErrorReport()) {
-        /* These were held by ErrorObject::init. */
-        if (JSPrincipals *prin = report->originPrincipals)
-            JS_DropPrincipals(fop->runtime(), prin);
+    if (JSErrorReport *report = obj->as<ErrorObject>().getErrorReport())
         fop->free_(report);
-    }
 }
 
 JSErrorReport *
 js_ErrorFromException(JSContext *cx, HandleObject objArg)
 {
     // It's ok to UncheckedUnwrap here, since all we do is get the
     // JSErrorReport, and consumers are careful with the information they get
     // from that anyway.  Anyone doing things that would expose anything in the
@@ -870,17 +864,17 @@ ErrorReport::populateUncaughtExceptionRe
     ownedReport.errorNumber = JSMSG_UNCAUGHT_EXCEPTION;
     // XXXbz this assumes the stack we have right now is still
     // related to our exception object.  It would be better if we
     // could accept a passed-in stack of some sort instead.
     NonBuiltinFrameIter iter(cx);
     if (!iter.done()) {
         ownedReport.filename = iter.scriptFilename();
         ownedReport.lineno = iter.computeLine(&ownedReport.column);
-        ownedReport.originPrincipals = iter.originPrincipals();
+        ownedReport.isMuted = iter.mutedErrors();
     }
 
     if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, nullptr,
                                  JSMSG_UNCAUGHT_EXCEPTION, &ownedMessage,
                                  &ownedReport, ArgumentsAreASCII, ap)) {
         return;
     }
 
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -259,20 +259,20 @@ JS_SetCompartmentPrincipals(JSCompartmen
 }
 
 JS_FRIEND_API(JSPrincipals *)
 JS_GetScriptPrincipals(JSScript *script)
 {
     return script->principals();
 }
 
-JS_FRIEND_API(JSPrincipals *)
-JS_GetScriptOriginPrincipals(JSScript *script)
+JS_FRIEND_API(bool)
+JS_ScriptHasMutedErrors(JSScript *script)
 {
-    return script->originPrincipals();
+    return script->mutedErrors();
 }
 
 JS_FRIEND_API(bool)
 JS_WrapPropertyDescriptor(JSContext *cx, JS::MutableHandle<js::PropertyDescriptor> desc)
 {
     return cx->compartment()->wrap(cx, desc);
 }
 
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -138,18 +138,19 @@ extern JS_FRIEND_API(JSPrincipals *)
 JS_GetCompartmentPrincipals(JSCompartment *compartment);
 
 extern JS_FRIEND_API(void)
 JS_SetCompartmentPrincipals(JSCompartment *compartment, JSPrincipals *principals);
 
 extern JS_FRIEND_API(JSPrincipals *)
 JS_GetScriptPrincipals(JSScript *script);
 
-extern JS_FRIEND_API(JSPrincipals *)
-JS_GetScriptOriginPrincipals(JSScript *script);
+extern JS_FRIEND_API(bool)
+JS_ScriptHasMutedErrors(JSScript *script);
+
 
 /* Safe to call with input obj == nullptr. Returns non-nullptr iff obj != nullptr. */
 extern JS_FRIEND_API(JSObject *)
 JS_ObjectToInnerObject(JSContext *cx, JS::HandleObject obj);
 
 /* Requires obj != nullptr. */
 extern JS_FRIEND_API(JSObject *)
 JS_ObjectToOuterObject(JSContext *cx, JS::HandleObject obj);
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1693,31 +1693,31 @@ FunctionConstructor(JSContext *cx, unsig
     bool hasRest = false;
 
     bool isStarGenerator = generatorKind == StarGenerator;
     JS_ASSERT(generatorKind != LegacyGenerator);
 
     RootedScript maybeScript(cx);
     const char *filename;
     unsigned lineno;
-    JSPrincipals *originPrincipals;
+    bool mutedErrors;
     uint32_t pcOffset;
     DescribeScriptedCallerForCompilation(cx, &maybeScript, &filename, &lineno, &pcOffset,
-                                         &originPrincipals);
+                                         &mutedErrors);
 
     const char *introductionType = "Function";
     if (generatorKind != NotGenerator)
         introductionType = "GeneratorFunction";
 
     const char *introducerFilename = filename;
     if (maybeScript && maybeScript->scriptSource()->introducerFilename())
         introducerFilename = maybeScript->scriptSource()->introducerFilename();
 
     CompileOptions options(cx);
-    options.setOriginPrincipals(originPrincipals)
+    options.setMutedErrors(mutedErrors)
            .setFileAndLine(filename, 1)
            .setNoScriptRval(false)
            .setCompileAndGo(true)
            .setIntroductionInfo(introducerFilename, introductionType, lineno, maybeScript, pcOffset);
 
     unsigned n = args.length() ? args.length() - 1 : 0;
     if (n > 0) {
         /*
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1790,19 +1790,16 @@ ScriptSource::~ScriptSource()
 
       case DataParent:
         parent()->decref();
         break;
 
       default:
         break;
     }
-
-    if (originPrincipals_)
-        JS_DropPrincipals(TlsPerThreadData.get()->runtimeFromMainThread(), originPrincipals_);
 }
 
 void
 ScriptSource::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
                                      JS::ScriptSourceInfo *info) const
 {
     if (dataType == DataUncompressed && ownsUncompressedChars())
         info->uncompressed += mallocSizeOf(uncompressedChars());
@@ -1988,19 +1985,17 @@ FormatIntroducedFilename(ExclusiveContex
 }
 
 bool
 ScriptSource::initFromOptions(ExclusiveContext *cx, const ReadOnlyCompileOptions &options)
 {
     JS_ASSERT(!filename_);
     JS_ASSERT(!introducerFilename_);
 
-    originPrincipals_ = options.originPrincipals(cx);
-    if (originPrincipals_)
-        JS_HoldPrincipals(originPrincipals_);
+    mutedErrors_ = options.mutedErrors();
 
     introductionType_ = options.introductionType;
     setIntroductionOffset(options.introductionOffset);
 
     if (options.hasIntroductionInfo) {
         JS_ASSERT(options.introductionType != nullptr);
         const char *filename = options.filename() ? options.filename() : "<unknown>";
         char *formatted = FormatIntroducedFilename(cx, filename, options.introductionLineno,
@@ -2858,47 +2853,47 @@ js_GetScriptLineExtent(JSScript *script)
     }
 
     return 1 + maxLineNo - script->lineno();
 }
 
 void
 js::DescribeScriptedCallerForCompilation(JSContext *cx, MutableHandleScript maybeScript,
                                          const char **file, unsigned *linenop,
-                                         uint32_t *pcOffset, JSPrincipals **origin,
+                                         uint32_t *pcOffset, bool *mutedErrors,
                                          LineOption opt)
 {
     if (opt == CALLED_FROM_JSOP_EVAL) {
         jsbytecode *pc = nullptr;
         maybeScript.set(cx->currentScript(&pc));
         JS_ASSERT(JSOp(*pc) == JSOP_EVAL || JSOp(*pc) == JSOP_SPREADEVAL);
         JS_ASSERT(*(pc + (JSOp(*pc) == JSOP_EVAL ? JSOP_EVAL_LENGTH
                                                  : JSOP_SPREADEVAL_LENGTH)) == JSOP_LINENO);
         *file = maybeScript->filename();
         *linenop = GET_UINT16(pc + (JSOp(*pc) == JSOP_EVAL ? JSOP_EVAL_LENGTH
                                                            : JSOP_SPREADEVAL_LENGTH));
         *pcOffset = pc - maybeScript->code();
-        *origin = maybeScript->originPrincipals();
+        *mutedErrors = maybeScript->mutedErrors();
         return;
     }
 
     NonBuiltinFrameIter iter(cx);
 
     if (iter.done()) {
         maybeScript.set(nullptr);
         *file = nullptr;
         *linenop = 0;
         *pcOffset = 0;
-        *origin = cx->compartment()->principals;
+        *mutedErrors = false;
         return;
     }
 
     *file = iter.scriptFilename();
     *linenop = iter.computeLine();
-    *origin = iter.originPrincipals();
+    *mutedErrors = iter.mutedErrors();
 
     // These values are only used for introducer fields which are debugging
     // information and can be safely left null for asm.js frames.
     if (iter.hasScript()) {
         maybeScript.set(iter.script());
         *pcOffset = iter.pc() - maybeScript->code();
     } else {
         maybeScript.set(nullptr);
@@ -3032,17 +3027,17 @@ js::CloneScript(JSContext *cx, HandleObj
         sourceObject = src->sourceObject();
         if (!cx->compartment()->wrap(cx, &sourceObject))
             return nullptr;
     }
 
     /* Now that all fallible allocation is complete, create the GC thing. */
 
     CompileOptions options(cx);
-    options.setOriginPrincipals(src->originPrincipals())
+    options.setMutedErrors(src->mutedErrors())
            .setCompileAndGo(src->compileAndGo())
            .setSelfHostingMode(src->selfHosted())
            .setNoScriptRval(src->noScriptRval())
            .setVersion(src->getVersion());
 
     RootedScript dst(cx, JSScript::Create(cx, enclosingScope, src->savedCallerFun(),
                                           options, src->staticLevel(),
                                           sourceObject, src->sourceStart(), src->sourceEnd()));
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -432,17 +432,17 @@ class ScriptSource
 
     uint32_t length_;
 
     // The filename of this script.
     mozilla::UniquePtr<char[], JS::FreePolicy> filename_;
 
     mozilla::UniquePtr<char16_t[], JS::FreePolicy> displayURL_;
     mozilla::UniquePtr<char16_t[], JS::FreePolicy> sourceMapURL_;
-    JSPrincipals *originPrincipals_;
+    bool mutedErrors_;
 
     // bytecode offset in caller script that generated this code.
     // This is present for eval-ed code, as well as "new Function(...)"-introduced
     // scripts.
     uint32_t introductionOffset_;
 
     // If this ScriptSource was generated by a code-introduction mechanism such
     // as |eval| or |new Function|, the debugger needs access to the "raw"
@@ -482,17 +482,17 @@ class ScriptSource
   public:
     explicit ScriptSource()
       : refs(0),
         dataType(DataMissing),
         length_(0),
         filename_(nullptr),
         displayURL_(nullptr),
         sourceMapURL_(nullptr),
-        originPrincipals_(nullptr),
+        mutedErrors_(false),
         introductionOffset_(0),
         introducerFilename_(nullptr),
         introductionType_(nullptr),
         sourceRetrievable_(false),
         argumentsNotIncluded_(false),
         hasIntroductionOffset_(false),
         inCompressedSourceSet(false)
     {
@@ -592,17 +592,17 @@ class ScriptSource
     // Source maps
     bool setSourceMapURL(ExclusiveContext *cx, const char16_t *sourceMapURL);
     bool hasSourceMapURL() const { return sourceMapURL_ != nullptr; }
     const char16_t * sourceMapURL() {
         MOZ_ASSERT(hasSourceMapURL());
         return sourceMapURL_.get();
     }
 
-    JSPrincipals *originPrincipals() const { return originPrincipals_; }
+    bool mutedErrors() const { return mutedErrors_; }
 
     bool hasIntroductionOffset() const { return hasIntroductionOffset_; }
     uint32_t introductionOffset() const {
         JS_ASSERT(hasIntroductionOffset());
         return introductionOffset_;
     }
     void setIntroductionOffset(uint32_t offset) {
         JS_ASSERT(!hasIntroductionOffset());
@@ -1405,17 +1405,17 @@ class JSScript : public js::gc::TenuredC
     static bool loadSource(JSContext *cx, js::ScriptSource *ss, bool *worked);
 
     void setSourceObject(JSObject *object);
     JSObject *sourceObject() const {
         return sourceObject_;
     }
     js::ScriptSourceObject &scriptSourceUnwrap() const;
     js::ScriptSource *scriptSource() const;
-    JSPrincipals *originPrincipals() const { return scriptSource()->originPrincipals(); }
+    bool mutedErrors() const { return scriptSource()->mutedErrors(); }
     const char *filename() const { return scriptSource()->filename(); }
 
   public:
 
     /* Return whether this script was compiled for 'eval' */
     bool isForEval() { return isCachedEval() || isActiveEval(); }
 
 #ifdef DEBUG
@@ -1847,18 +1847,18 @@ class LazyScript : public gc::TenuredCel
 
     JSObject *enclosingScope() const {
         return enclosingScope_;
     }
     ScriptSourceObject *sourceObject() const;
     ScriptSource *scriptSource() const {
         return sourceObject()->source();
     }
-    JSPrincipals *originPrincipals() const {
-        return scriptSource()->originPrincipals();
+    bool mutedErrors() const {
+        return scriptSource()->mutedErrors();
     }
     JSVersion version() const {
         JS_STATIC_ASSERT(JSVERSION_UNKNOWN == -1);
         return (p_.version == JS_BIT(8) - 1) ? JSVERSION_UNKNOWN : JSVersion(p_.version);
     }
 
     void setParent(JSObject *enclosingScope, ScriptSourceObject *sourceObject);
 
@@ -2086,36 +2086,23 @@ PCToLineNumber(unsigned startLine, jssrc
 enum LineOption {
     CALLED_FROM_JSOP_EVAL,
     NOT_CALLED_FROM_JSOP_EVAL
 };
 
 extern void
 DescribeScriptedCallerForCompilation(JSContext *cx, MutableHandleScript maybeScript,
                                      const char **file, unsigned *linenop,
-                                     uint32_t *pcOffset, JSPrincipals **origin,
+                                     uint32_t *pcOffset, bool *mutedErrors,
                                      LineOption opt = NOT_CALLED_FROM_JSOP_EVAL);
 
 bool
 CloneFunctionScript(JSContext *cx, HandleFunction original, HandleFunction clone,
                     NewObjectKind newKind = GenericObject);
 
-/*
- * JSAPI clients are allowed to leave CompileOptions.originPrincipals nullptr in
- * which case the JS engine sets options.originPrincipals = origin.principals.
- * This normalization step must occur before the originPrincipals get stored in
- * the JSScript/ScriptSource.
- */
-
-static inline JSPrincipals *
-NormalizeOriginPrincipals(JSPrincipals *principals, JSPrincipals *originPrincipals)
-{
-    return originPrincipals ? originPrincipals : principals;
-}
-
 } /* namespace js */
 
 // JS::ubi::Nodes can point to js::LazyScripts; they're js::gc::Cell instances
 // with no associated compartment.
 namespace JS {
 namespace ubi {
 template<> struct Concrete<js::LazyScript> : TracerConcrete<js::LazyScript> { };
 }
--- a/js/src/vm/ErrorObject.cpp
+++ b/js/src/vm/ErrorObject.cpp
@@ -71,19 +71,16 @@ js::ErrorObject::init(JSContext *cx, Han
     obj->setReservedSlot(ERROR_REPORT_SLOT, PrivateValue(report));
     obj->initReservedSlot(FILENAME_SLOT, StringValue(fileName));
     obj->initReservedSlot(LINENUMBER_SLOT, Int32Value(lineNumber));
     obj->initReservedSlot(COLUMNNUMBER_SLOT, Int32Value(columnNumber));
     obj->initReservedSlot(STACK_SLOT, StringValue(stack));
     if (message)
         obj->nativeSetSlotWithType(cx, messageShape, StringValue(message));
 
-    if (report && report->originPrincipals)
-        JS_HoldPrincipals(report->originPrincipals);
-
     return true;
 }
 
 /* static */ ErrorObject *
 js::ErrorObject::create(JSContext *cx, JSExnType errorType, HandleString stack,
                         HandleString fileName, uint32_t lineNumber, uint32_t columnNumber,
                         ScopedJSFreePtr<JSErrorReport> *report, HandleString message)
 {
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -968,27 +968,27 @@ FrameIter::computeLine(uint32_t *column)
         return PCToLineNumber(script(), pc(), column);
       case ASMJS:
         return data_.asmJSFrames_.computeLine(column);
     }
 
     MOZ_CRASH("Unexpected state");
 }
 
-JSPrincipals *
-FrameIter::originPrincipals() const
+bool
+FrameIter::mutedErrors() const
 {
     switch (data_.state_) {
       case DONE:
         break;
       case INTERP:
       case JIT:
-        return script()->originPrincipals();
+        return script()->mutedErrors();
       case ASMJS:
-        return data_.activations_->asAsmJS()->module().scriptSource()->originPrincipals();
+        return data_.activations_->asAsmJS()->module().scriptSource()->mutedErrors();
     }
 
     MOZ_CRASH("Unexpected state");
 }
 
 bool
 FrameIter::isConstructing() const
 {
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -1633,17 +1633,17 @@ class FrameIter
     /*
      * Get an abstract frame pointer dispatching to either an interpreter,
      * baseline, or rematerialized optimized frame.
      */
     ScriptSource *scriptSource() const;
     const char *scriptFilename() const;
     unsigned computeLine(uint32_t *column = nullptr) const;
     JSAtom *functionDisplayAtom() const;
-    JSPrincipals *originPrincipals() const;
+    bool mutedErrors() const;
 
     bool hasScript() const { return !isAsmJS(); }
 
     // -----------------------------------------------------------
     // The following functions can only be called when hasScript()
     // -----------------------------------------------------------
 
     inline JSScript *script() const;
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -96,18 +96,17 @@ class XDRBuffer {
  */
 template <XDRMode mode>
 class XDRState {
   public:
     XDRBuffer buf;
 
   protected:
     explicit XDRState(JSContext *cx)
-      : buf(cx) {
-    }
+      : buf(cx) { }
 
   public:
     JSContext *cx() const {
         return buf.cx();
     }
 
     bool codeUint8(uint8_t *n) {
         if (mode == XDR_ENCODE) {
--- a/js/xpconnect/loader/mozJSLoaderUtils.cpp
+++ b/js/xpconnect/loader/mozJSLoaderUtils.cpp
@@ -58,17 +58,16 @@ ReadCachedFunction(StartupCache* cache, 
     return NS_OK;*/
 }
 
 nsresult
 WriteCachedScript(StartupCache* cache, nsACString &uri, JSContext *cx,
                   nsIPrincipal *systemPrincipal, HandleScript script)
 {
     MOZ_ASSERT(JS_GetScriptPrincipals(script) == nsJSPrincipals::get(systemPrincipal));
-    MOZ_ASSERT(JS_GetScriptOriginPrincipals(script) == nsJSPrincipals::get(systemPrincipal));
 
     uint32_t size;
     void *data = JS_EncodeScript(cx, script, &size);
     if (!data)
         return NS_ERROR_OUT_OF_MEMORY;
 
     MOZ_ASSERT(size);
     nsresult rv = cache->PutBuffer(PromiseFlatCString(uri).get(), static_cast<char *>(data), size);
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -239,16 +239,17 @@ xpc::ErrorReport::InitInternal(JSErrorRe
         mFileName.AssignWithConversion(aReport->filename);
     }
 
     mSourceLine = static_cast<const char16_t*>(aReport->uclinebuf);
 
     mLineNumber = aReport->lineno;
     mColumn = aReport->column;
     mFlags = aReport->flags;
+    mIsMuted = aReport->isMuted;
 }
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gJSDiagnostics;
 #endif
 
 void
 xpc::ErrorReport::LogToConsole()
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -504,16 +504,17 @@ ExtraWarningsForSystemJS();
 class ErrorReport {
   public:
     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ErrorReport);
 
     ErrorReport() : mIsChrome(false)
                   , mLineNumber(0)
                   , mColumn(0)
                   , mFlags(0)
+                  , mIsMuted(false)
     {}
 
     void Init(JSErrorReport *aReport, const char *aFallbackMessage,
               nsIGlobalObject *aGlobal);
     void InitOnWorkerThread(JSErrorReport *aReport, const char *aFallbackMessage,
                             bool aIsChrome);
 
     void LogToConsole();
@@ -529,16 +530,17 @@ class ErrorReport {
     }
 
     nsString mErrorMsg;
     nsString mFileName;
     nsString mSourceLine;
     uint32_t mLineNumber;
     uint32_t mColumn;
     uint32_t mFlags;
+    bool mIsMuted;
 
     // These are both null for ErrorReports initialized on a worker thread.
     nsCOMPtr<nsIGlobalObject> mGlobal;
     nsCOMPtr<nsPIDOMWindow> mWindow;
 
   private:
     ~ErrorReport() {}
 };