Bug 1089026 part 5. Eliminate the ability to provide a non-global parent object to JS::CompileFunction and company except via the scopeChain API. r=waldo
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 30 Oct 2014 19:40:29 -0400
changeset 237652 715ded1f9639136c6cbee52b65d78b7898b1ad26
parent 237651 5ccd3c29891cdf7b7cd817ca96c20157b78a8b1f
child 237653 1d752af4a7142753b5a425e7d56b6fb0549012a9
push idunknown
push userunknown
push dateunknown
reviewerswaldo
bugs1089026
milestone36.0a1
Bug 1089026 part 5. Eliminate the ability to provide a non-global parent object to JS::CompileFunction and company except via the scopeChain API. r=waldo
dom/events/EventListenerManager.cpp
dom/xbl/nsXBLProtoImplMethod.cpp
dom/xbl/nsXBLProtoImplProperty.cpp
dom/xbl/nsXBLPrototypeHandler.cpp
js/src/jsapi-tests/testChromeBuffer.cpp
js/src/jsapi-tests/testCloneScript.cpp
js/src/jsapi-tests/testEnclosingFunction.cpp
js/src/jsapi-tests/testPreserveJitCode.cpp
js/src/jsapi-tests/testSourcePolicy.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/xpconnect/src/XPCJSRuntime.cpp
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -903,18 +903,17 @@ EventListenerManager::CompileEventHandle
   if (NS_WARN_IF(!WrapNewBindingObject(cx, target, aElement, &v))) {
     return NS_ERROR_FAILURE;
   }
   JS::CompileOptions options(cx);
   options.setIntroductionType("eventHandler")
          .setFileAndLine(url.get(), lineNo)
          .setVersion(JSVERSION_DEFAULT)
          .setElement(&v.toObject())
-         .setElementAttributeName(jsStr)
-         .setDefineOnScope(false);
+         .setElementAttributeName(jsStr);
 
   JS::Rooted<JSObject*> handler(cx);
   result = nsJSUtils::CompileFunction(jsapi, scopeChain, options,
                                       nsAtomCString(typeAtom),
                                       argCount, argNames, *body, handler.address());
   NS_ENSURE_SUCCESS(result, result);
   NS_ENSURE_TRUE(handler, NS_ERROR_FAILURE);
 
--- a/dom/xbl/nsXBLProtoImplMethod.cpp
+++ b/dom/xbl/nsXBLProtoImplMethod.cpp
@@ -195,18 +195,17 @@ nsXBLProtoImplMethod::CompileMember(Auto
     functionUri.Truncate(hash);
   }
 
   JSContext *cx = jsapi.cx();
   JSAutoCompartment ac(cx, aClassObject);
   JS::CompileOptions options(cx);
   options.setFileAndLine(functionUri.get(),
                          uncompiledMethod->mBodyText.GetLineNumber())
-         .setVersion(JSVERSION_LATEST)
-         .setDefineOnScope(false);
+         .setVersion(JSVERSION_LATEST);
   JS::Rooted<JSObject*> methodObject(cx);
   JS::AutoObjectVector emptyVector(cx);
   nsresult rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options, cname,
                                            paramCount,
                                            const_cast<const char**>(args),
                                            body, methodObject.address());
 
   // Destroy our uncompiled method and delete our arg list.
--- a/dom/xbl/nsXBLProtoImplProperty.cpp
+++ b/dom/xbl/nsXBLProtoImplProperty.cpp
@@ -193,18 +193,17 @@ nsXBLProtoImplProperty::CompileMember(Au
   bool deletedGetter = false;
   nsXBLTextWithLineNumber *getterText = mGetter.GetUncompiled();
   if (getterText && getterText->GetText()) {
     nsDependentString getter(getterText->GetText());
     if (!getter.IsEmpty()) {
       JSAutoCompartment ac(cx, aClassObject);
       JS::CompileOptions options(cx);
       options.setFileAndLine(functionUri.get(), getterText->GetLineNumber())
-             .setVersion(JSVERSION_LATEST)
-             .setDefineOnScope(false);
+             .setVersion(JSVERSION_LATEST);
       nsCString name = NS_LITERAL_CSTRING("get_") + NS_ConvertUTF16toUTF8(mName);
       JS::Rooted<JSObject*> getterObject(cx);
       JS::AutoObjectVector emptyVector(cx);
       rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options, name, 0,
                                       nullptr, getter, getterObject.address());
 
       delete getterText;
       deletedGetter = true;
@@ -240,18 +239,17 @@ nsXBLProtoImplProperty::CompileMember(Au
   bool deletedSetter = false;
   nsXBLTextWithLineNumber *setterText = mSetter.GetUncompiled();
   if (setterText && setterText->GetText()) {
     nsDependentString setter(setterText->GetText());
     if (!setter.IsEmpty()) {
       JSAutoCompartment ac(cx, aClassObject);
       JS::CompileOptions options(cx);
       options.setFileAndLine(functionUri.get(), setterText->GetLineNumber())
-             .setVersion(JSVERSION_LATEST)
-             .setDefineOnScope(false);
+             .setVersion(JSVERSION_LATEST);
       nsCString name = NS_LITERAL_CSTRING("set_") + NS_ConvertUTF16toUTF8(mName);
       JS::Rooted<JSObject*> setterObject(cx);
       JS::AutoObjectVector emptyVector(cx);
       rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options, name, 1,
                                       gPropertyArgs, setter,
                                       setterObject.address());
 
       delete setterText;
--- a/dom/xbl/nsXBLPrototypeHandler.cpp
+++ b/dom/xbl/nsXBLPrototypeHandler.cpp
@@ -365,18 +365,17 @@ nsXBLPrototypeHandler::EnsureEventHandle
   const char **argNames;
   nsContentUtils::GetEventArgNames(kNameSpaceID_XBL, aName, false, &argCount,
                                    &argNames);
 
   // Compile the event handler in the xbl scope.
   JSAutoCompartment ac(cx, scopeObject);
   JS::CompileOptions options(cx);
   options.setFileAndLine(bindingURI.get(), mLineNumber)
-         .setVersion(JSVERSION_LATEST)
-         .setDefineOnScope(false);
+         .setVersion(JSVERSION_LATEST);
 
   JS::Rooted<JSObject*> handlerFun(cx);
   JS::AutoObjectVector emptyVector(cx);
   nsresult rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options,
                                            nsAtomCString(aName), argCount,
                                            argNames, handlerText,
                                            handlerFun.address());
   NS_ENSURE_SUCCESS(rv, rv);
--- a/js/src/jsapi-tests/testChromeBuffer.cpp
+++ b/js/src/jsapi-tests/testChromeBuffer.cpp
@@ -66,18 +66,20 @@ BEGIN_TEST(testChromeBuffer)
     {
         {
             JSAutoCompartment ac(cx, trusted_glob);
             const char *paramName = "x";
             const char *bytes = "return x ? 1 + trusted(x-1) : 0";
             JS::HandleObject global = JS::HandleObject::fromMarkedLocation(trusted_glob.unsafeGet());
             JS::CompileOptions options(cx);
             options.setFileAndLine("", 0);
-            CHECK(JS_CompileFunction(cx, global, "trusted", 1, &paramName,
-                                     bytes, strlen(bytes), options, &fun));
+            JS::AutoObjectVector emptyScopeChain(cx);
+            CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "trusted",
+                                      1, &paramName, bytes, strlen(bytes), &fun));
+            CHECK(JS_DefineProperty(cx, global, "trusted", fun, JSPROP_ENUMERATE));
             trusted_fun = JS_GetFunctionObject(fun);
             if (!JS::AddNamedObjectRoot(cx, &trusted_fun, "trusted-function"))
                 return false;
         }
 
         JS::RootedValue v(cx, JS::ObjectValue(*trusted_fun));
         CHECK(JS_WrapValue(cx, &v));
 
@@ -88,18 +90,20 @@ BEGIN_TEST(testChromeBuffer)
                             "    try {                                  "
                             "        return trusted(100);               "
                             "    } catch(e) {                           "
                             "        return -1;                         "
                             "    }                                      "
                             "}                                          ";
         JS::CompileOptions options(cx);
         options.setFileAndLine("", 0);
-        CHECK(JS_CompileFunction(cx, global, "untrusted", 1, &paramName,
-                                 bytes, strlen(bytes), options, &fun));
+        JS::AutoObjectVector emptyScopeChain(cx);
+        CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "untrusted", 1,
+                                  &paramName, bytes, strlen(bytes), &fun));
+        CHECK(JS_DefineProperty(cx, global, "untrusted", fun, JSPROP_ENUMERATE));
 
         JS::RootedValue rval(cx);
         CHECK(JS_CallFunction(cx, JS::NullPtr(), fun, JS::HandleValueArray(v), &rval));
         CHECK(rval.toInt32() == 100);
     }
 
     /*
      * Check that content called from chrome in the reserved-buffer space
@@ -117,34 +121,38 @@ BEGIN_TEST(testChromeBuffer)
                                 "   * that might try to push a frame.   "
                                 "   */                                  "
                                 "  return 'From trusted: ' +            "
                                 "         e.name + ': ' + e.message;    "
                                 "}                                      ";
             JS::HandleObject global = JS::HandleObject::fromMarkedLocation(trusted_glob.unsafeGet());
             JS::CompileOptions options(cx);
             options.setFileAndLine("", 0);
-            CHECK(JS_CompileFunction(cx, global, "trusted", 1, &paramName,
-                                     bytes, strlen(bytes), options, &fun));
+            JS::AutoObjectVector emptyScopeChain(cx);
+            CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "trusted",
+                                      1, &paramName, bytes, strlen(bytes), &fun));
+            CHECK(JS_DefineProperty(cx, global, "trusted", fun, JSPROP_ENUMERATE));
             trusted_fun = JS_GetFunctionObject(fun);
         }
 
         JS::RootedValue v(cx, JS::ObjectValue(*trusted_fun));
         CHECK(JS_WrapValue(cx, &v));
 
         const char *paramName = "trusted";
         const char *bytes = "try {                                      "
                             "  return untrusted(trusted);               "
                             "} catch (e) {                              "
                             "  return trusted(untrusted);               "
                             "}                                          ";
         JS::CompileOptions options(cx);
         options.setFileAndLine("", 0);
-        CHECK(JS_CompileFunction(cx, global, "untrusted", 1, &paramName,
-                                 bytes, strlen(bytes), options, &fun));
+        JS::AutoObjectVector emptyScopeChain(cx);
+        CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "untrusted", 1,
+                                 &paramName, bytes, strlen(bytes), &fun));
+        CHECK(JS_DefineProperty(cx, global, "untrusted", fun, JSPROP_ENUMERATE));
 
         JS::RootedValue rval(cx);
         CHECK(JS_CallFunction(cx, JS::NullPtr(), fun, JS::HandleValueArray(v), &rval));
         bool match;
         CHECK(JS_StringEqualsAscii(cx, rval.toString(), "From trusted: InternalError: too much recursion", &match));
         CHECK(match);
     }
 
@@ -154,34 +162,38 @@ BEGIN_TEST(testChromeBuffer)
      */
     {
         {
             JSAutoCompartment ac(cx, trusted_glob);
             const char *bytes = "return 42";
             JS::HandleObject global = JS::HandleObject::fromMarkedLocation(trusted_glob.unsafeGet());
             JS::CompileOptions options(cx);
             options.setFileAndLine("", 0);
-            CHECK(JS_CompileFunction(cx, global, "trusted", 0, nullptr,
-                                     bytes, strlen(bytes), options, &fun));
+            JS::AutoObjectVector emptyScopeChain(cx);
+            CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "trusted",
+                                      0, nullptr, bytes, strlen(bytes), &fun));
+            CHECK(JS_DefineProperty(cx, global, "trusted", fun, JSPROP_ENUMERATE));
             trusted_fun = JS_GetFunctionObject(fun);
         }
 
         JS::RootedFunction fun(cx, JS_NewFunction(cx, CallTrusted, 0, 0, global, "callTrusted"));
         JS::RootedObject callTrusted(cx, JS_GetFunctionObject(fun));
 
         const char *paramName = "f";
         const char *bytes = "try {                                      "
                             "  return untrusted(trusted);               "
                             "} catch (e) {                              "
                             "  return f();                              "
                             "}                                          ";
         JS::CompileOptions options(cx);
         options.setFileAndLine("", 0);
-        CHECK(JS_CompileFunction(cx, global, "untrusted", 1, &paramName,
-                                 bytes, strlen(bytes), options, &fun));
+        JS::AutoObjectVector emptyScopeChain(cx);
+        CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "untrusted", 1,
+                                  &paramName, bytes, strlen(bytes), &fun));
+        CHECK(JS_DefineProperty(cx, global, "untrusted", fun, JSPROP_ENUMERATE));
 
         JS::RootedValue arg(cx, JS::ObjectValue(*callTrusted));
         JS::RootedValue rval(cx);
         CHECK(JS_CallFunction(cx, JS::NullPtr(), fun, JS::HandleValueArray(arg), &rval));
         CHECK(rval.toInt32() == 42);
     }
 
     return true;
--- a/js/src/jsapi-tests/testCloneScript.cpp
+++ b/js/src/jsapi-tests/testCloneScript.cpp
@@ -30,18 +30,19 @@ BEGIN_TEST(test_cloneScript)
     JS::RootedObject obj(cx);
 
     // compile for A
     {
         JSAutoCompartment a(cx, A);
         JS::RootedFunction fun(cx);
         JS::CompileOptions options(cx);
         options.setFileAndLine(__FILE__, 1);
-        CHECK(JS_CompileFunction(cx, A, "f", 0, nullptr, source,
-                                 strlen(source), options, &fun));
+        JS::AutoObjectVector emptyScopeChain(cx);
+        CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "f", 0, nullptr,
+                                  source, strlen(source), &fun));
         CHECK(obj = JS_GetFunctionObject(fun));
     }
 
     // clone into B
     {
         JSAutoCompartment b(cx, B);
         CHECK(JS::CloneFunctionObject(cx, obj));
     }
@@ -104,19 +105,20 @@ BEGIN_TEST(test_cloneScriptWithPrincipal
     JS::RootedObject obj(cx);
 
     // Compile in A
     {
         JSAutoCompartment a(cx, A);
         JS::CompileOptions options(cx);
         options.setFileAndLine(__FILE__, 1);
         JS::RootedFunction fun(cx);
-        JS_CompileFunction(cx, A, "f",
+        JS::AutoObjectVector emptyScopeChain(cx);
+        JS::CompileFunction(cx, emptyScopeChain, options, "f",
                            mozilla::ArrayLength(argnames), argnames, source,
-                           strlen(source), options, &fun);
+                           strlen(source), &fun);
         CHECK(fun);
 
         JSScript *script;
         CHECK(script = JS_GetFunctionScript(cx, fun));
 
         CHECK(JS_GetScriptPrincipals(script) == principalsA);
         CHECK(obj = JS_GetFunctionObject(fun));
     }
--- a/js/src/jsapi-tests/testEnclosingFunction.cpp
+++ b/js/src/jsapi-tests/testEnclosingFunction.cpp
@@ -34,31 +34,35 @@ BEGIN_TEST(test_enclosingFunction)
     CHECK(foundFun == nullptr);
 
     RootedFunction fun(cx);
 
     JS::CompileOptions options(cx);
     options.setFileAndLine(__FILE__, __LINE__);
 
     const char s1chars[] = "checkEnclosing()";
-    JS_CompileFunction(cx, global, "s1", 0, nullptr, s1chars,
-                       strlen(s1chars), options, &fun);
+    JS::AutoObjectVector emptyScopeChain(cx);
+    CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "s1", 0, nullptr, s1chars,
+                              strlen(s1chars), &fun));
     CHECK(fun);
+    CHECK(JS_DefineProperty(cx, global, "s1", fun, JSPROP_ENUMERATE));
     EXEC("s1()");
     CHECK(foundFun == fun);
 
     const char s2chars[] = "return function() { checkEnclosing() }";
-    JS_CompileFunction(cx, global, "s2", 0, nullptr, s2chars,
-                       strlen(s2chars), options, &fun);
+    CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "s2", 0, nullptr, s2chars,
+                              strlen(s2chars), &fun));
     CHECK(fun);
+    CHECK(JS_DefineProperty(cx, global, "s2", fun, JSPROP_ENUMERATE));
     EXEC("s2()()");
     CHECK(foundFun == fun);
 
     const char s3chars[] = "return function() { let (x) { function g() { checkEnclosing() } return g() } }";
-    JS_CompileFunction(cx, global, "s3", 0, nullptr, s3chars,
-                       strlen(s3chars), options, &fun);
+    CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "s3", 0, nullptr, s3chars,
+                              strlen(s3chars), &fun));
     CHECK(fun);
+    CHECK(JS_DefineProperty(cx, global, "s3", fun, JSPROP_ENUMERATE));
     EXEC("s3()()");
     CHECK(foundFun == fun);
 
     return true;
 }
 END_TEST(test_enclosingFunction)
--- a/js/src/jsapi-tests/testPreserveJitCode.cpp
+++ b/js/src/jsapi-tests/testPreserveJitCode.cpp
@@ -50,17 +50,19 @@ testPreserveJitCode(bool preserveJitCode
         "    ++i;\n"
         "}\n"
         "return sum;\n";
     unsigned length = strlen(source);
 
     JS::RootedFunction fun(cx);
     JS::CompileOptions options(cx);
     options.setFileAndLine(__FILE__, 1);
-    CHECK(JS_CompileFunction(cx, global, "f", 0, nullptr, source, length, options, &fun));
+    JS::AutoObjectVector emptyScopeChain(cx);
+    CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "f", 0, nullptr,
+			      source, length, &fun));
 
     RootedValue value(cx);
     for (unsigned i = 0; i < 1500; ++i)
         CHECK(JS_CallFunction(cx, global, fun, JS::HandleValueArray::empty(), &value));
     CHECK_EQUAL(value.toInt32(), 45);
     CHECK_EQUAL(countIonScripts(global), 1u);
 
     GCForReason(rt, gcreason::API);
--- a/js/src/jsapi-tests/testSourcePolicy.cpp
+++ b/js/src/jsapi-tests/testSourcePolicy.cpp
@@ -13,15 +13,16 @@ BEGIN_TEST(testBug795104)
     const size_t strLen = 60002;
     char *s = static_cast<char *>(JS_malloc(cx, strLen));
     CHECK(s);
     s[0] = '"';
     memset(s + 1, 'x', strLen - 2);
     s[strLen - 1] = '"';
     CHECK(JS::Evaluate(cx, global, opts, s, strLen));
     JS::RootedFunction fun(cx);
-    CHECK(JS::CompileFunction(cx, global, opts, "f", 0, nullptr, s, strLen, &fun));
+    JS::AutoObjectVector emptyScopeChain(cx);
+    CHECK(JS::CompileFunction(cx, emptyScopeChain, opts, "f", 0, nullptr, s, strLen, &fun));
     CHECK(fun);
     JS_free(cx, s);
 
     return true;
 }
 END_TEST(testBug795104)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4588,32 +4588,28 @@ JS_GetFunctionScript(JSContext *cx, Hand
 }
 
 /*
  * enclosingStaticScope is a static enclosing scope, if any (e.g. a
  * StaticWithObject).  If the enclosing scope is the global scope, this must be
  * null.
  *
  * enclosingDynamicScope is a dynamic scope to use, if it's not the global.
- *
- * The function will be defined as a property on objToDefineOn if the caller
- * requested that.
  */
 static bool
-CompileFunction(JSContext *cx, HandleObject objToDefineOn, const ReadOnlyCompileOptions &options,
+CompileFunction(JSContext *cx, const ReadOnlyCompileOptions &options,
                 const char *name, unsigned nargs, const char *const *argnames,
                 SourceBufferHolder &srcBuf,
                 HandleObject enclosingDynamicScope,
                 HandleObject enclosingStaticScope,
                 MutableHandleFunction fun)
 {
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
-    assertSameCompartment(cx, objToDefineOn);
     assertSameCompartment(cx, enclosingDynamicScope);
     assertSameCompartment(cx, enclosingStaticScope);
     RootedAtom funAtom(cx);
     AutoLastFrameCheck lfc(cx);
 
     if (name) {
         funAtom = Atomize(cx, name, strlen(name));
         if (!funAtom)
@@ -4631,97 +4627,46 @@ CompileFunction(JSContext *cx, HandleObj
                         funAtom, JSFunction::FinalizeKind, TenuredObject));
     if (!fun)
         return false;
 
     if (!frontend::CompileFunctionBody(cx, fun, options, formals, srcBuf,
                                        enclosingStaticScope))
         return false;
 
-    if (objToDefineOn && funAtom && options.defineOnScope) {
-        Rooted<jsid> id(cx, AtomToId(funAtom));
-        RootedValue value(cx, ObjectValue(*fun));
-        if (!JSObject::defineGeneric(cx, objToDefineOn, id, value, nullptr,
-                                     nullptr, JSPROP_ENUMERATE))
-            return false;
-    }
-
     return true;
 }
 
 JS_PUBLIC_API(bool)
-JS::CompileFunction(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
-                    const char *name, unsigned nargs, const char *const *argnames,
-                    SourceBufferHolder &srcBuf, MutableHandleFunction fun)
-{
-    return CompileFunction(cx, obj, options, name, nargs, argnames, srcBuf,
-                           obj, NullPtr(), fun);
-}
-
-JS_PUBLIC_API(bool)
-JS::CompileFunction(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
-                    const char *name, unsigned nargs, const char *const *argnames,
-                    const char16_t *chars, size_t length, MutableHandleFunction fun)
-{
-    SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
-    return JS::CompileFunction(cx, obj, options, name, nargs, argnames, srcBuf, fun);
-}
-
-JS_PUBLIC_API(bool)
-JS::CompileFunction(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
-                    const char *name, unsigned nargs, const char *const *argnames,
-                    const char *bytes, size_t length, MutableHandleFunction fun)
-{
-    mozilla::UniquePtr<char16_t, JS::FreePolicy> chars;
-    if (options.utf8)
-        chars.reset(UTF8CharsToNewTwoByteCharsZ(cx, UTF8Chars(bytes, length), &length).get());
-    else
-        chars.reset(InflateString(cx, bytes, &length));
-    if (!chars)
-        return false;
-
-    return CompileFunction(cx, obj, options, name, nargs, argnames, chars.get(), length, fun);
-}
-
-JS_PUBLIC_API(bool)
 JS::CompileFunction(JSContext *cx, AutoObjectVector &scopeChain,
                     const ReadOnlyCompileOptions &options,
                     const char *name, unsigned nargs, const char *const *argnames,
                     SourceBufferHolder &srcBuf, MutableHandleFunction fun)
 {
     RootedObject dynamicScopeObj(cx);
     RootedObject staticScopeObj(cx);
     if (!CreateScopeObjectsForScopeChain(cx, scopeChain, &dynamicScopeObj, &staticScopeObj))
         return false;
 
-    return CompileFunction(cx, /* objToDefineOn = */ JS::NullPtr(), options, name, nargs, argnames,
+    return CompileFunction(cx, options, name, nargs, argnames,
                            srcBuf, dynamicScopeObj, staticScopeObj, fun);
 }
 
 JS_PUBLIC_API(bool)
 JS::CompileFunction(JSContext *cx, AutoObjectVector &scopeChain,
                     const ReadOnlyCompileOptions &options,
                     const char *name, unsigned nargs, const char *const *argnames,
                     const char16_t *chars, size_t length, MutableHandleFunction fun)
 {
     SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
     return CompileFunction(cx, scopeChain, options, name, nargs, argnames,
                            srcBuf, fun);
 }
 
 JS_PUBLIC_API(bool)
-JS_CompileUCFunction(JSContext *cx, JS::HandleObject obj, const char *name,
-                     unsigned nargs, const char *const *argnames,
-                     const char16_t *chars, size_t length,
-                     const CompileOptions &options, MutableHandleFunction fun)
-{
-    return CompileFunction(cx, obj, options, name, nargs, argnames, chars, length, fun);
-}
-
-JS_PUBLIC_API(bool)
 JS::CompileFunction(JSContext *cx, AutoObjectVector &scopeChain,
                     const ReadOnlyCompileOptions &options,
                     const char *name, unsigned nargs, const char *const *argnames,
                     const char *bytes, size_t length, MutableHandleFunction fun)
 {
     mozilla::UniquePtr<char16_t, JS::FreePolicy> chars;
     if (options.utf8)
         chars.reset(UTF8CharsToNewTwoByteCharsZ(cx, UTF8Chars(bytes, length), &length).get());
@@ -4729,25 +4674,16 @@ JS::CompileFunction(JSContext *cx, AutoO
         chars.reset(InflateString(cx, bytes, &length));
     if (!chars)
         return false;
 
     return CompileFunction(cx, scopeChain, options, name, nargs, argnames,
                            chars.get(), length, fun);
 }
 
-JS_PUBLIC_API(bool)
-JS_CompileFunction(JSContext *cx, JS::HandleObject obj, const char *name,
-                   unsigned nargs, const char *const *argnames,
-                   const char *ascii, size_t length,
-                   const JS::CompileOptions &options, MutableHandleFunction fun)
-{
-    return CompileFunction(cx, obj, options, name, nargs, argnames, ascii, length, fun);
-}
-
 JS_PUBLIC_API(JSString *)
 JS_DecompileScript(JSContext *cx, HandleScript script, const char *name, unsigned indent)
 {
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
 
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     script->ensureNonLazyCanonicalFunction(cx);
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3582,36 +3582,16 @@ extern JS_PUBLIC_API(const char *)
 JS_GetScriptFilename(JSScript *script);
 
 extern JS_PUBLIC_API(unsigned)
 JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script);
 
 extern JS_PUBLIC_API(JSScript *)
 JS_GetFunctionScript(JSContext *cx, JS::HandleFunction fun);
 
-/*
- * |fun| will always be set. On failure, it will be set to nullptr.
- */
-extern JS_PUBLIC_API(bool)
-JS_CompileFunction(JSContext *cx, JS::HandleObject obj, const char *name,
-                   unsigned nargs, const char *const *argnames,
-                   const char *bytes, size_t length,
-                   const JS::CompileOptions &options,
-                   JS::MutableHandleFunction fun);
-
-/*
- * |fun| will always be set. On failure, it will be set to nullptr.
- */
-extern JS_PUBLIC_API(bool)
-JS_CompileUCFunction(JSContext *cx, JS::HandleObject obj, const char *name,
-                     unsigned nargs, const char *const *argnames,
-                     const char16_t *chars, size_t length,
-                     const JS::CompileOptions &options,
-                     JS::MutableHandleFunction fun);
-
 namespace JS {
 
 /* Options for JavaScript compilation. */
 
 /*
  * In the most common use case, a CompileOptions instance is allocated on the
  * stack, and holds non-owning references to non-POD option values: strings;
  * principals; objects; and so on. The code declaring the instance guarantees
@@ -3685,17 +3665,16 @@ class JS_FRIEND_API(ReadOnlyCompileOptio
         sourceMapURL_(nullptr),
         version(JSVERSION_UNKNOWN),
         versionSet(false),
         utf8(false),
         lineno(1),
         column(0),
         compileAndGo(false),
         forEval(false),
-        defineOnScope(true),
         noScriptRval(false),
         selfHostingMode(false),
         canLazilyParse(true),
         strictOption(false),
         extraWarningsOption(false),
         werrorOption(false),
         asmJSOption(false),
         forceAsync(false),
@@ -3725,17 +3704,16 @@ class JS_FRIEND_API(ReadOnlyCompileOptio
     // POD options.
     JSVersion version;
     bool versionSet;
     bool utf8;
     unsigned lineno;
     unsigned column;
     bool compileAndGo;
     bool forEval;
-    bool defineOnScope;
     bool noScriptRval;
     bool selfHostingMode;
     bool canLazilyParse;
     bool strictOption;
     bool extraWarningsOption;
     bool werrorOption;
     bool asmJSOption;
     bool forceAsync;
@@ -3817,17 +3795,16 @@ class JS_FRIEND_API(OwningCompileOptions
         version = v;
         versionSet = true;
         return *this;
     }
     OwningCompileOptions &setUTF8(bool u) { utf8 = u; return *this; }
     OwningCompileOptions &setColumn(unsigned c) { column = c; return *this; }
     OwningCompileOptions &setCompileAndGo(bool cng) { compileAndGo = cng; return *this; }
     OwningCompileOptions &setForEval(bool eval) { forEval = eval; return *this; }
-    OwningCompileOptions &setDefineOnScope(bool define) { defineOnScope = define; return *this; }
     OwningCompileOptions &setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
     OwningCompileOptions &setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
     OwningCompileOptions &setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
     OwningCompileOptions &setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
     OwningCompileOptions &setIntroductionType(const char *t) { introductionType = t; return *this; }
     bool setIntroductionInfo(JSContext *cx, const char *introducerFn, const char *intro,
                              unsigned line, JSScript *script, uint32_t offset)
     {
@@ -3901,17 +3878,16 @@ class MOZ_STACK_CLASS JS_FRIEND_API(Comp
         version = v;
         versionSet = true;
         return *this;
     }
     CompileOptions &setUTF8(bool u) { utf8 = u; return *this; }
     CompileOptions &setColumn(unsigned c) { column = c; return *this; }
     CompileOptions &setCompileAndGo(bool cng) { compileAndGo = cng; return *this; }
     CompileOptions &setForEval(bool eval) { forEval = eval; return *this; }
-    CompileOptions &setDefineOnScope(bool define) { defineOnScope = define; return *this; }
     CompileOptions &setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
     CompileOptions &setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
     CompileOptions &setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
     CompileOptions &setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
     CompileOptions &setIntroductionType(const char *t) { introductionType = t; return *this; }
     CompileOptions &setIntroductionInfo(const char *introducerFn, const char *intro,
                                         unsigned line, JSScript *script, uint32_t offset)
     {
@@ -3973,31 +3949,16 @@ CanCompileOffThread(JSContext *cx, const
 extern JS_PUBLIC_API(bool)
 CompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options,
                  const char16_t *chars, size_t length,
                  OffThreadCompileCallback callback, void *callbackData);
 
 extern JS_PUBLIC_API(JSScript *)
 FinishOffThreadScript(JSContext *maybecx, JSRuntime *rt, void *token);
 
-extern JS_PUBLIC_API(bool)
-CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
-                const char *name, unsigned nargs, const char *const *argnames,
-                SourceBufferHolder &srcBuf, JS::MutableHandleFunction fun);
-
-extern JS_PUBLIC_API(bool)
-CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
-                const char *name, unsigned nargs, const char *const *argnames,
-                const char *bytes, size_t length, JS::MutableHandleFunction fun);
-
-extern JS_PUBLIC_API(bool)
-CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
-                const char *name, unsigned nargs, const char *const *argnames,
-                const char16_t *chars, size_t length, JS::MutableHandleFunction fun);
-
 /**
  * Compile a function with scopeChain plus the global as its scope chain.
  * scopeChain must contain objects in the current compartment of cx.  The actual
  * scope chain used for the function will consist of With wrappers for those
  * objects, followed by the current global of the compartment cx is in.  This
  * global must not be explicitly included in the scope chain.
  */
 extern JS_PUBLIC_API(bool)
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -3274,17 +3274,17 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
     // and using regular expressions to modify them. We avoid keeping most browser
     // JS source code in memory by setting LAZY_SOURCE on JS::CompileOptions when
     // compiling some chrome code. This causes the JS engine not save the source
     // code in memory. When the JS engine is asked to provide the source for a
     // function compiled with LAZY_SOURCE, it calls SourceHook to load it.
     ///
     // Note we do have to retain the source code in memory for scripts compiled in
     // compileAndGo mode and compiled function bodies (from
-    // JS_CompileFunction*). In practice, this means content scripts and event
+    // JS::CompileFunction). In practice, this means content scripts and event
     // handlers.
     UniquePtr<XPCJSSourceHook> hook(new XPCJSSourceHook);
     js::SetSourceHook(runtime, Move(hook));
 
     // Set up locale information and callbacks for the newly-created runtime so
     // that the various toLocaleString() methods, localeCompare(), and other
     // internationalization APIs work as desired.
     if (!xpc_LocalizeRuntime(runtime))