зеркало из https://github.com/mozilla/pjs.git
Removal of ScriptRuntime.getThis() : it was used by nested functions or
functions declared inside with statements to ensure that their thisObj is not with or call scope as required by ECMA-262. But due the changes to support E4X extensions such situation can only happen when function is accessed as expression like in var f = function() { } ... f() and typically it is exactly nested the functions that are accessed in this way. So the patch adds optimized code that always check for proper thisObj to ScriptRuntime.getValueFunctionAndThis and removes getThis and corresponding parsing/code generation code. In this way when nested functions are accessed as name or property no checks are done for them and Rhino code slightly shrinks.
This commit is contained in:
Родитель
41a93646b9
Коммит
5f2437939f
|
@ -57,14 +57,6 @@ public class FunctionNode extends ScriptOrFnNode {
|
|||
itsNeedsActivation = true;
|
||||
}
|
||||
|
||||
public boolean getCheckThis() {
|
||||
return itsCheckThis;
|
||||
}
|
||||
|
||||
void setCheckThis() {
|
||||
itsCheckThis = true;
|
||||
}
|
||||
|
||||
public boolean getIgnoreDynamicScope() {
|
||||
return itsIgnoreDynamicScope;
|
||||
}
|
||||
|
@ -102,7 +94,6 @@ public class FunctionNode extends ScriptOrFnNode {
|
|||
|
||||
private String functionName;
|
||||
private boolean itsNeedsActivation;
|
||||
private boolean itsCheckThis;
|
||||
private int itsFunctionType;
|
||||
private boolean itsIgnoreDynamicScope;
|
||||
}
|
||||
|
|
|
@ -480,7 +480,6 @@ public class Interpreter
|
|||
jsi.compilerEnv = compilerEnv;
|
||||
jsi.scriptOrFn = def;
|
||||
jsi.itsData = new InterpreterData(itsData);
|
||||
jsi.itsData.itsCheckThis = def.getCheckThis();
|
||||
jsi.generateFunctionICode();
|
||||
array[i] = jsi.itsData;
|
||||
}
|
||||
|
@ -3112,7 +3111,7 @@ switch (op) {
|
|||
}
|
||||
|
||||
private static void initState(Context cx, Scriptable callerScope,
|
||||
Scriptable origThisObj,
|
||||
Scriptable thisObj,
|
||||
Object[] args, double[] argsDbl,
|
||||
int argShift, int argCount,
|
||||
InterpretedFunction fnOrScript,
|
||||
|
@ -3159,7 +3158,6 @@ switch (op) {
|
|||
}
|
||||
|
||||
Scriptable scope;
|
||||
Scriptable thisObj = origThisObj;
|
||||
if (idata.itsFunctionType != 0) {
|
||||
if (!idata.useDynamicScope) {
|
||||
scope = fnOrScript.getParentScope();
|
||||
|
@ -3167,10 +3165,6 @@ switch (op) {
|
|||
scope = callerScope;
|
||||
}
|
||||
|
||||
if (idata.itsCheckThis) {
|
||||
thisObj = ScriptRuntime.getThis(thisObj);
|
||||
}
|
||||
|
||||
if (state.useActivation) {
|
||||
scope = ScriptRuntime.enterActivationFunction(cx, scope,
|
||||
fnOrScript,
|
||||
|
|
|
@ -78,7 +78,6 @@ final class InterpreterData implements Serializable, DebuggableScript
|
|||
String itsName;
|
||||
String itsSourceFile;
|
||||
boolean itsNeedsActivation;
|
||||
boolean itsCheckThis;
|
||||
int itsFunctionType;
|
||||
|
||||
String[] itsStringTable;
|
||||
|
|
|
@ -107,11 +107,6 @@ public final class NativeCall extends IdScriptableObject
|
|||
return originalArgs;
|
||||
}
|
||||
|
||||
Scriptable getThisObj()
|
||||
{
|
||||
return thisObj;
|
||||
}
|
||||
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
return s.equals("constructor") ? Id_constructor : 0;
|
||||
|
|
|
@ -462,11 +462,6 @@ public class Parser
|
|||
boolean nested = insideFunction();
|
||||
|
||||
FunctionNode fnNode = nf.createFunction(name);
|
||||
if (nested) {
|
||||
// Nested functions must check their 'this' value to insure
|
||||
// it is not an activation object: see 10.1.6 Activation Object
|
||||
fnNode.setCheckThis();
|
||||
}
|
||||
if (nested || nestingOfWith > 0) {
|
||||
// 1. Nested functions are not affected by the dynamic scope flag
|
||||
// as dynamic scope is already a parent of their scope.
|
||||
|
|
|
@ -1824,14 +1824,6 @@ public class ScriptRuntime {
|
|||
return firstXMLObject;
|
||||
}
|
||||
|
||||
public static Scriptable getThis(Scriptable base) {
|
||||
while (base instanceof NativeWith)
|
||||
base = base.getPrototype();
|
||||
if (base instanceof NativeCall)
|
||||
base = ScriptableObject.getTopLevelScope(base);
|
||||
return base;
|
||||
}
|
||||
|
||||
public static Object setName(Scriptable bound, Object value,
|
||||
Context cx, Scriptable scope, String id)
|
||||
{
|
||||
|
@ -2094,6 +2086,15 @@ public class ScriptRuntime {
|
|||
|
||||
Function f = (Function)value;
|
||||
Scriptable thisObj = f.getParentScope();
|
||||
if (thisObj.getParentScope() != null) {
|
||||
if (thisObj instanceof NativeWith) {
|
||||
// functions defined inside with should have with target
|
||||
// as their thisObj
|
||||
} else if (thisObj instanceof NativeCall) {
|
||||
// nested functions should have top scope as their thisObj
|
||||
thisObj = ScriptableObject.getTopLevelScope(thisObj);
|
||||
}
|
||||
}
|
||||
storeScriptable(cx, thisObj);
|
||||
return f;
|
||||
}
|
||||
|
|
|
@ -1201,17 +1201,6 @@ class BodyCodegen
|
|||
}
|
||||
}
|
||||
|
||||
if (fnCurrent != null && fnCurrent.fnode.getCheckThis()) {
|
||||
// Nested functions must check their 'this' value to
|
||||
// insure it is not an activation object:
|
||||
// see 10.1.6 Activation Object
|
||||
cfw.addALoad(thisObjLocal);
|
||||
addScriptRuntimeInvoke("getThis",
|
||||
"(Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Lorg/mozilla/javascript/Scriptable;");
|
||||
cfw.addAStore(thisObjLocal);
|
||||
}
|
||||
|
||||
if (hasVarsInRegs) {
|
||||
// No need to create activation. Pad arguments if need be.
|
||||
int parmCount = scriptOrFn.getParamCount();
|
||||
|
|
Загрузка…
Ссылка в новой задаче