Bug 1234702 - Part 4: Self-host default base class constructor. (r=till)
authorEric Faust <efaustbmo@gmail.com>
Wed, 06 Jan 2016 14:26:14 -0800
changeset 278881 8c69c6036831f6126e64734af669f5c27d47b07f
parent 278880 10d23a474969b04776bb6200895dc8e64a0dd85e
child 278882 c4f7c14dfe4546456a9351853bbb45117340703f
push id29860
push usercbook@mozilla.com
push dateThu, 07 Jan 2016 10:51:20 +0000
treeherdermozilla-central@e0bcd16e1d4b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs1234702
milestone46.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 1234702 - Part 4: Self-host default base class constructor. (r=till)
js/src/builtin/Classes.js
js/src/jsfun.cpp
js/src/vm/CommonPropertyNames.h
js/src/vm/Interpreter.cpp
--- a/js/src/builtin/Classes.js
+++ b/js/src/builtin/Classes.js
@@ -4,8 +4,14 @@
 
 var DefaultDerivedClassConstructor =
     class extends null {
         constructor(...args) {
             super(...allowContentSpread(args));
         }
     };
 MakeDefaultConstructor(DefaultDerivedClassConstructor);
+
+var DefaultBaseClassConstructor =
+    class {
+        constructor() { }
+    };
+MakeDefaultConstructor(DefaultBaseClassConstructor);
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1077,27 +1077,28 @@ js::FunctionToString(JSContext* cx, Hand
         {
             return nullptr;
         }
         if (!lambdaParen && fun->isLambda() && !fun->isArrow() && !out.append(")"))
             return nullptr;
     } else {
         MOZ_ASSERT(!fun->isExprBody());
 
-        if (fun->infallibleIsDefaultClassConstructor(cx) && fun->isDerivedClassConstructor()) {
+        bool derived = fun->infallibleIsDefaultClassConstructor(cx);
+        if (derived && fun->isDerivedClassConstructor()) {
             if (!out.append("(...args) {\n    ") ||
                 !out.append("super(...args);\n}"))
             {
                 return nullptr;
             }
         } else {
             if (!out.append("() {\n    "))
                 return nullptr;
 
-            if (!fun->isNative() || fun->native() != js::DefaultClassConstructor) {
+            if (!derived) {
                 if (!out.append("[native code]"))
                     return nullptr;
             }
 
             if (!out.append("\n}"))
                 return nullptr;
         }
     }
@@ -1272,17 +1273,18 @@ bool
 JSFunction::infallibleIsDefaultClassConstructor(JSContext* cx) const
 {
     if (!isSelfHostedBuiltin())
         return false;
 
     bool isDefault = false;
     if (isInterpretedLazy()) {
         JSAtom* name = &getExtendedSlot(LAZY_FUNCTION_NAME_SLOT).toString()->asAtom();
-        isDefault = name == cx->names().DefaultDerivedClassConstructor;
+        isDefault = name == cx->names().DefaultDerivedClassConstructor ||
+                    name == cx->names().DefaultBaseClassConstructor;
     } else {
         isDefault = nonLazyScript()->isDefaultClassConstructor();
     }
 
     MOZ_ASSERT_IF(isDefault, isConstructor());
     MOZ_ASSERT_IF(isDefault, isClassConstructor());
     return isDefault;
 }
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -61,16 +61,17 @@
     macro(DateTimeFormat, DateTimeFormat, "DateTimeFormat") \
     macro(DateTimeFormatFormatGet, DateTimeFormatFormatGet, "Intl_DateTimeFormat_format_get") \
     macro(DateTimeFormatFormatToPartsGet, DateTimeFormatFormatToPartsGet, "Intl_DateTimeFormat_formatToParts_get") \
     macro(day, day, "day") \
     macro(dayperiod, dayperiod, "dayperiod") \
     macro(decodeURI, decodeURI, "decodeURI") \
     macro(decodeURIComponent, decodeURIComponent, "decodeURIComponent") \
     macro(default_, default_, "default") \
+    macro(DefaultBaseClassConstructor, DefaultBaseClassConstructor, "DefaultBaseClassConstructor") \
     macro(DefaultDerivedClassConstructor, DefaultDerivedClassConstructor, "DefaultDerivedClassConstructor") \
     macro(defineProperty, defineProperty, "defineProperty") \
     macro(defineGetter, defineGetter, "__defineGetter__") \
     macro(defineSetter, defineSetter, "__defineSetter__") \
     macro(delete, delete_, "delete") \
     macro(deleteProperty, deleteProperty, "deleteProperty") \
     macro(displayURL, displayURL, "displayURL") \
     macro(done, done, "done") \
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -286,31 +286,30 @@ SetPropertyOperation(JSContext* cx, JSOp
     // to obj's [[Set]] internal method. See bug 603201.
     RootedValue receiver(cx, ObjectValue(*obj));
     ObjectOpResult result;
     return SetProperty(cx, obj, id, rval, receiver, result) &&
            result.checkStrictErrorOrWarning(cx, obj, id, op == JSOP_STRICTSETPROP);
 }
 
 static JSFunction*
-MakeDefaultConstructor(JSContext* cx, JSOp op, JSAtom* atom)
-{
-    RootedAtom name(cx, atom == cx->names().empty ? nullptr : atom);
-    JSNative native = DefaultClassConstructor;
-    return NewFunctionWithProto(cx, native, 0, JSFunction::NATIVE_CLASS_CTOR, nullptr, name, nullptr);
-}
-
-static JSFunction*
-MakeDerivedDefaultConstructor(JSContext* cx, JSAtom* atom, HandleObject proto)
-{
-    RootedPropertyName selfHostedName(cx, cx->names().DefaultDerivedClassConstructor);
+MakeDefaultConstructor(JSContext* cx, JSOp op, JSAtom* atom, HandleObject proto)
+{
+    bool derived = op == JSOP_DERIVEDCONSTRUCTOR;
+    MOZ_ASSERT(derived == !!proto);
+
+    PropertyName* lookup = derived ? cx->names().DefaultDerivedClassConstructor
+                                   : cx->names().DefaultBaseClassConstructor;
+
+    RootedPropertyName selfHostedName(cx, lookup);
     RootedAtom name(cx, atom == cx->names().empty ? nullptr : atom);
 
     RootedFunction ctor(cx);
-    if (!cx->runtime()->createLazySelfHostedFunctionClone(cx, selfHostedName, name, /* nargs = */ 1,
+    if (!cx->runtime()->createLazySelfHostedFunctionClone(cx, selfHostedName, name,
+                                                          /* nargs = */ !!derived,
                                                           proto, TenuredObject, &ctor))
     {
         return nullptr;
     }
 
     ctor->setIsConstructor();
     ctor->setIsClassConstructor();
 
@@ -3897,27 +3896,29 @@ CASE(JSOP_SUPERFUN)
 }
 END_CASE(JSOP_SUPERFUN)
 
 CASE(JSOP_DERIVEDCONSTRUCTOR)
 {
     MOZ_ASSERT(REGS.sp[-1].isObject());
     ReservedRooted<JSObject*> proto(&rootObject0, &REGS.sp[-1].toObject());
 
-    JSFunction* constructor = MakeDerivedDefaultConstructor(cx, script->getAtom(REGS.pc), proto);
+    JSFunction* constructor = MakeDefaultConstructor(cx, JSOp(*REGS.pc), script->getAtom(REGS.pc),
+                                                     proto);
     if (!constructor)
         goto error;
 
     REGS.sp[-1].setObject(*constructor);
 }
 END_CASE(JSOP_DERIVEDCONSTRUCTOR)
 
 CASE(JSOP_CLASSCONSTRUCTOR)
 {
-    JSFunction* constructor = MakeDefaultConstructor(cx, JSOp(*REGS.pc), script->getAtom(REGS.pc));
+    JSFunction* constructor = MakeDefaultConstructor(cx, JSOp(*REGS.pc), script->getAtom(REGS.pc),
+                                                     nullptr);
     if (!constructor)
         goto error;
     PUSH_OBJECT(*constructor);
 }
 END_CASE(JSOP_CLASSCONSTRUCTOR)
 
 CASE(JSOP_CHECKOBJCOERCIBLE)
 {
@@ -4808,34 +4809,16 @@ js::ReportRuntimeLexicalError(JSContext*
     } else {
         MOZ_ASSERT(IsAliasedVarOp(op));
         name = ScopeCoordinateName(cx->runtime()->scopeCoordinateNameCache, script, pc);
     }
 
     ReportRuntimeLexicalError(cx, errorNumber, name);
 }
 
-bool
-js::DefaultClassConstructor(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (!args.isConstructing()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_CALL_CLASS_CONSTRUCTOR);
-        return false;
-    }
-
-    RootedObject newTarget(cx, &args.newTarget().toObject());
-    JSObject* obj = CreateThis(cx, &PlainObject::class_, newTarget);
-    if (!obj)
-        return false;
-
-    args.rval().set(ObjectValue(*obj));
-    return true;
-}
-
 void
 js::ReportRuntimeRedeclaration(JSContext* cx, HandlePropertyName name,
                                frontend::Definition::Kind declKind)
 {
     JSAutoByteString printable;
     if (AtomToPrintableString(cx, name, &printable)) {
         // We cannot distinguish 'var' declarations from manually defined,
         // non-configurable global properties.