diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 79482681a..197763852 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -2270,6 +2270,26 @@ BaselineCompiler::emit_JSOP_BINDGNAME() return emit_JSOP_BINDNAME(); } +typedef JSObject* (*BindVarFn)(JSContext*, HandleObject); +static const VMFunction BindVarInfo = FunctionInfo(jit::BindVar); + +bool +BaselineCompiler::emit_JSOP_BINDVAR() +{ + frame.syncStack(0); + masm.loadPtr(frame.addressOfScopeChain(), R0.scratchReg()); + + prepareVMCall(); + pushArg(R0.scratchReg()); + + if (!callVM(BindVarInfo)) + return false; + + masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0); + frame.push(R0); + return true; +} + bool BaselineCompiler::emit_JSOP_SETPROP() { diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h index 43d88a20c..bbb6e27c6 100644 --- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -143,6 +143,7 @@ namespace jit { _(JSOP_DELNAME) \ _(JSOP_GETIMPORT) \ _(JSOP_GETINTRINSIC) \ + _(JSOP_BINDVAR) \ _(JSOP_DEFVAR) \ _(JSOP_DEFCONST) \ _(JSOP_DEFLET) \ diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 1296b52fe..5a0b7e593 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -167,14 +167,20 @@ CheckOverRecursedWithExtra(JSContext* cx, BaselineFrame* frame, return cx->runtime()->handleInterrupt(cx); } +JSObject* +BindVar(JSContext* cx, HandleObject scopeChain) +{ + JSObject* obj = scopeChain; + while (!obj->isQualifiedVarObj()) + obj = obj->enclosingScope(); + return obj; +} + bool DefVar(JSContext* cx, HandlePropertyName dn, unsigned attrs, HandleObject scopeChain) { // Given the ScopeChain, extract the VarObj. - RootedObject obj(cx, scopeChain); - while (!obj->isQualifiedVarObj()) - obj = obj->enclosingScope(); - + RootedObject obj(cx, BindVar(cx, scopeChain)); return DefVarOperation(cx, obj, dn, attrs); } @@ -185,10 +191,7 @@ DefLexical(JSContext* cx, HandlePropertyName dn, unsigned attrs, HandleObject sc Rooted lexical(cx, &NearestEnclosingExtensibleLexicalScope(scopeChain)); // Find the variables object. - RootedObject varObj(cx, scopeChain); - while (!varObj->isQualifiedVarObj()) - varObj = varObj->enclosingScope(); - + RootedObject varObj(cx, BindVar(cx, scopeChain)); return DefLexicalOperation(cx, lexical, varObj, dn, attrs); } @@ -853,9 +856,8 @@ bool InitGlobalOrEvalScopeObjects(JSContext* cx, BaselineFrame* frame) { RootedScript script(cx, frame->script()); - RootedObject varObj(cx, frame->scopeChain()); - while (!varObj->isQualifiedVarObj()) - varObj = varObj->enclosingScope(); + RootedObject scopeChain(cx, frame->scopeChain()); + RootedObject varObj(cx, BindVar(cx, scopeChain)); if (script->isForEval()) { // Strict eval needs its own call object. @@ -866,13 +868,12 @@ InitGlobalOrEvalScopeObjects(JSContext* cx, BaselineFrame* frame) if (!frame->initStrictEvalScopeObjects(cx)) return false; } else { - RootedObject scopeChain(cx, frame->scopeChain()); if (!CheckEvalDeclarationConflicts(cx, script, scopeChain, varObj)) return false; } } else { Rooted lexicalScope(cx, - &NearestEnclosingExtensibleLexicalScope(frame->scopeChain())); + &NearestEnclosingExtensibleLexicalScope(scopeChain)); if (!CheckGlobalDeclarationConflicts(cx, script, lexicalScope, varObj)) return false; } diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 2ea3f8aab..67177905d 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -588,6 +588,7 @@ bool CheckOverRecursed(JSContext* cx); bool CheckOverRecursedWithExtra(JSContext* cx, BaselineFrame* frame, uint32_t extra, uint32_t earlyCheck); +JSObject* BindVar(JSContext* cx, HandleObject scopeChain); bool DefVar(JSContext* cx, HandlePropertyName dn, unsigned attrs, HandleObject scopeChain); bool DefLexical(JSContext* cx, HandlePropertyName dn, unsigned attrs, HandleObject scopeChain); bool DefGlobalLexical(JSContext* cx, HandlePropertyName dn, unsigned attrs);