Bug 1406957 part 3 - Get rid of some code duplication in jit::CreateThis and MaybeCreateThisForConstructor. r=tcampbell
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 11 Oct 2017 14:55:17 +0200
changeset 428159 cab71dff90c4ab218a2bb008000f550222d419be
parent 428158 817d7ec24cb64275dd3c31ed29307c85407d8acb
child 428160 91bdf32e14f5d190b21ed75aa23cf53754399707
push id97
push userfmarier@mozilla.com
push dateSat, 14 Oct 2017 01:12:59 +0000
reviewerstcampbell
bugs1406957
milestone58.0a1
Bug 1406957 part 3 - Get rid of some code duplication in jit::CreateThis and MaybeCreateThisForConstructor. r=tcampbell
js/src/jit/VMFunctions.cpp
js/src/jsobjinlines.h
js/src/vm/Interpreter.cpp
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -623,24 +623,18 @@ CreateThis(JSContext* cx, HandleObject c
     rval.set(MagicValue(JS_IS_CONSTRUCTING));
 
     if (callee->is<JSFunction>()) {
         RootedFunction fun(cx, &callee->as<JSFunction>());
         if (fun->isInterpreted() && fun->isConstructor()) {
             JSScript* script = JSFunction::getOrCreateScript(cx, fun);
             if (!script || !script->ensureHasTypes(cx))
                 return false;
-            if (fun->isBoundFunction() || script->isDerivedClassConstructor()) {
-                rval.set(MagicValue(JS_UNINITIALIZED_LEXICAL));
-            } else {
-                JSObject* thisObj = CreateThisForFunction(cx, callee, newTarget, GenericObject);
-                if (!thisObj)
-                    return false;
-                rval.set(ObjectValue(*thisObj));
-            }
+            if (!js::CreateThis(cx, fun, script, newTarget, GenericObject, rval))
+                return false;
         }
     }
 
     return true;
 }
 
 void
 GetDynamicName(JSContext* cx, JSObject* envChain, JSString* str, Value* vp)
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -836,16 +836,41 @@ IsCallable(const Value& v)
 
 // ES6 rev 24 (2014 April 27) 7.2.5 IsConstructor
 inline bool
 IsConstructor(const Value& v)
 {
     return v.isObject() && v.toObject().isConstructor();
 }
 
+MOZ_ALWAYS_INLINE bool
+CreateThis(JSContext* cx, HandleObject callee, JSScript* calleeScript, HandleObject newTarget,
+           NewObjectKind newKind, MutableHandleValue thisv)
+{
+    if (callee->isBoundFunction()) {
+        thisv.setMagic(JS_UNINITIALIZED_LEXICAL);
+        return true;
+    }
+
+    if (calleeScript->isDerivedClassConstructor()) {
+        MOZ_ASSERT(callee->as<JSFunction>().isClassConstructor());
+        thisv.setMagic(JS_UNINITIALIZED_LEXICAL);
+        return true;
+    }
+
+    MOZ_ASSERT(thisv.isMagic(JS_IS_CONSTRUCTING));
+
+    JSObject* obj = CreateThisForFunction(cx, callee, newTarget, newKind);
+    if (!obj)
+        return false;
+
+    thisv.setObject(*obj);
+    return true;
+}
+
 } /* namespace js */
 
 MOZ_ALWAYS_INLINE bool
 JSObject::isCallable() const
 {
     if (is<JSFunction>())
         return true;
     return callHook() != nullptr;
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -337,38 +337,20 @@ js::ValueToCallable(JSContext* cx, Handl
 static bool
 MaybeCreateThisForConstructor(JSContext* cx, JSScript* calleeScript, const CallArgs& args,
                               bool createSingleton)
 {
     if (args.thisv().isObject())
         return true;
 
     RootedObject callee(cx, &args.callee());
-    if (callee->isBoundFunction()) {
-        args.setThis(MagicValue(JS_UNINITIALIZED_LEXICAL));
-        return true;
-    }
-
-    if (calleeScript->isDerivedClassConstructor()) {
-        MOZ_ASSERT(callee->as<JSFunction>().isClassConstructor());
-        args.setThis(MagicValue(JS_UNINITIALIZED_LEXICAL));
-        return true;
-    }
-
-    MOZ_ASSERT(args.thisv().isMagic(JS_IS_CONSTRUCTING));
-
     RootedObject newTarget(cx, &args.newTarget().toObject());
     NewObjectKind newKind = createSingleton ? SingletonObject : GenericObject;
 
-    JSObject* obj = CreateThisForFunction(cx, callee, newTarget, newKind);
-    if (!obj)
-        return false;
-
-    args.setThis(ObjectValue(*obj));
-    return true;
+    return CreateThis(cx, callee, calleeScript, newTarget, newKind, args.mutableThisv());
 }
 
 static MOZ_NEVER_INLINE bool
 Interpret(JSContext* cx, RunState& state);
 
 InterpreterFrame*
 InvokeState::pushInterpreterFrame(JSContext* cx)
 {