Integration of VariableTable into ScriptOrFnNode to avoid the need to have a separated wrapper class around ObjArray/ObjToIntMap

This commit is contained in:
igor%mir2.org 2003-03-04 15:10:20 +00:00
Родитель 46b7643242
Коммит 39dbbb0550
10 изменённых файлов: 83 добавлений и 56 удалений

Просмотреть файл

@ -107,7 +107,7 @@ public class FunctionNode extends ScriptOrFnNode {
if (fn.getFunctionType() == FUNCTION_EXPRESSION_STATEMENT) { if (fn.getFunctionType() == FUNCTION_EXPRESSION_STATEMENT) {
String name = fn.getFunctionName(); String name = fn.getFunctionName();
if (name != null && name.length() != 0) { if (name != null && name.length() != 0) {
removeParameterOrVar(name); removeParamOrVar(name);
} }
} }
} }
@ -119,7 +119,7 @@ public class FunctionNode extends ScriptOrFnNode {
Node stmts = getLastChild(); Node stmts = getLastChild();
if (getFunctionType() == FUNCTION_EXPRESSION) { if (getFunctionType() == FUNCTION_EXPRESSION) {
String name = getFunctionName(); String name = getFunctionName();
if (name != null && name.length() != 0 && !hasParameterOrVar(name)) if (name != null && name.length() != 0 && !hasParamOrVar(name))
{ {
// A function expression needs to have its name as a // A function expression needs to have its name as a
// variable (if it isn't already allocated as a variable). // variable (if it isn't already allocated as a variable).

Просмотреть файл

@ -218,7 +218,7 @@ public class Interpreter {
itsData.itsDoubleTable = tmp; itsData.itsDoubleTable = tmp;
} }
itsData.itsMaxVars = scriptOrFn.getParameterAndVarCount(); itsData.itsMaxVars = scriptOrFn.getParamAndVarCount();
// itsMaxFrameArray: interpret method needs this amount for its // itsMaxFrameArray: interpret method needs this amount for its
// stack and sDbl arrays // stack and sDbl arrays
itsData.itsMaxFrameArray = itsData.itsMaxVars itsData.itsMaxFrameArray = itsData.itsMaxVars
@ -226,8 +226,8 @@ public class Interpreter {
+ itsData.itsMaxTryDepth + itsData.itsMaxTryDepth
+ itsData.itsMaxStack; + itsData.itsMaxStack;
itsData.argNames = scriptOrFn.getParameterAndVarNames(); itsData.argNames = scriptOrFn.getParamAndVarNames();
itsData.argCount = scriptOrFn.getParameterCount(); itsData.argCount = scriptOrFn.getParamCount();
} }
private int updateLineNumber(Node node, int iCodeTop) { private int updateLineNumber(Node node, int iCodeTop) {
@ -674,7 +674,7 @@ public class Interpreter {
// use typeofname if an activation frame exists // use typeofname if an activation frame exists
// since the vars all exist there instead of in jregs // since the vars all exist there instead of in jregs
if (itsInFunctionFlag && !itsData.itsNeedsActivation) if (itsInFunctionFlag && !itsData.itsNeedsActivation)
index = scriptOrFn.getParameterOrVarIndex(name); index = scriptOrFn.getParamOrVarIndex(name);
if (index == -1) { if (index == -1) {
iCodeTop = addByte(TokenStream.TYPEOFNAME, iCodeTop); iCodeTop = addByte(TokenStream.TYPEOFNAME, iCodeTop);
iCodeTop = addString(name, iCodeTop); iCodeTop = addString(name, iCodeTop);
@ -724,7 +724,7 @@ public class Interpreter {
iCodeTop); iCodeTop);
itsStackDepth--; itsStackDepth--;
} else { } else {
int i = scriptOrFn.getParameterOrVarIndex(name); int i = scriptOrFn.getParamOrVarIndex(name);
iCodeTop = addByte(type == TokenStream.INC iCodeTop = addByte(type == TokenStream.INC
? TokenStream.VARINC ? TokenStream.VARINC
: TokenStream.VARDEC, : TokenStream.VARDEC,
@ -930,7 +930,7 @@ public class Interpreter {
iCodeTop = addByte(TokenStream.GETPROP, iCodeTop); iCodeTop = addByte(TokenStream.GETPROP, iCodeTop);
itsStackDepth--; itsStackDepth--;
} else { } else {
int index = scriptOrFn.getParameterOrVarIndex(name); int index = scriptOrFn.getParamOrVarIndex(name);
iCodeTop = addByte(TokenStream.GETVAR, iCodeTop); iCodeTop = addByte(TokenStream.GETVAR, iCodeTop);
iCodeTop = addByte(index, iCodeTop); iCodeTop = addByte(index, iCodeTop);
itsStackDepth++; itsStackDepth++;
@ -949,7 +949,7 @@ public class Interpreter {
String name = child.getString(); String name = child.getString();
child = child.getNext(); child = child.getNext();
iCodeTop = generateICode(child, iCodeTop); iCodeTop = generateICode(child, iCodeTop);
int index = scriptOrFn.getParameterOrVarIndex(name); int index = scriptOrFn.getParamOrVarIndex(name);
iCodeTop = addByte(TokenStream.SETVAR, iCodeTop); iCodeTop = addByte(TokenStream.SETVAR, iCodeTop);
iCodeTop = addByte(index, iCodeTop); iCodeTop = addByte(index, iCodeTop);
} }

Просмотреть файл

@ -305,7 +305,7 @@ public class JavaAdapter extends ScriptableObject {
ScriptableObject.getProperty(p, "length")); ScriptableObject.getProperty(p, "length"));
} else if (f instanceof FunctionNode) { } else if (f instanceof FunctionNode) {
// This is used only by optimizer/Codegen // This is used only by optimizer/Codegen
length = ((FunctionNode)f).getParameterCount(); length = ((FunctionNode)f).getParamCount();
} else { } else {
continue; continue;
} }

Просмотреть файл

@ -376,7 +376,7 @@ public class NodeTransformer {
// use of "arguments" requires an activation object. // use of "arguments" requires an activation object.
((FunctionNode) tree).setRequiresActivation(true); ((FunctionNode) tree).setRequiresActivation(true);
} }
if (tree.hasParameterOrVar(name)) { if (tree.hasParamOrVar(name)) {
if (type == TokenStream.SETNAME) { if (type == TokenStream.SETNAME) {
node.setType(TokenStream.SETVAR); node.setType(TokenStream.SETVAR);
bind.setType(TokenStream.STRING); bind.setType(TokenStream.STRING);
@ -416,7 +416,7 @@ public class NodeTransformer {
// Use of "arguments" requires an activation object. // Use of "arguments" requires an activation object.
((FunctionNode) tree).setRequiresActivation(true); ((FunctionNode) tree).setRequiresActivation(true);
} }
if (tree.hasParameterOrVar(name)) { if (tree.hasParamOrVar(name)) {
node.setType(TokenStream.GETVAR); node.setType(TokenStream.GETVAR);
} }
break; break;
@ -458,7 +458,7 @@ public class NodeTransformer {
boolean addGetThis = false; boolean addGetThis = false;
if (left.getType() == TokenStream.NAME) { if (left.getType() == TokenStream.NAME) {
String name = left.getString(); String name = left.getString();
if (inFunction && tree.hasParameterOrVar(name) if (inFunction && tree.hasParamOrVar(name)
&& !inWithStatement()) && !inWithStatement())
{ {
// call to a var. Transform to Call(GetVar("a"), b, c) // call to a var. Transform to Call(GetVar("a"), b, c)

Просмотреть файл

@ -261,11 +261,11 @@ class Parser {
first = false; first = false;
mustMatchToken(ts, ts.NAME, "msg.no.parm"); mustMatchToken(ts, ts.NAME, "msg.no.parm");
String s = ts.getString(); String s = ts.getString();
if (fnNode.hasParameterOrVar(s)) { if (fnNode.hasParamOrVar(s)) {
Object[] msgArgs = { s }; Object[] msgArgs = { s };
ts.reportCurrentLineWarning("msg.dup.parms", msgArgs); ts.reportCurrentLineWarning("msg.dup.parms", msgArgs);
} }
fnNode.addParameter(s); fnNode.addParam(s);
sourceAddString(ts.NAME, s); sourceAddString(ts.NAME, s);
} while (ts.matchToken(ts.COMMA)); } while (ts.matchToken(ts.COMMA));

Просмотреть файл

@ -117,48 +117,65 @@ public class ScriptOrFnNode extends Node {
return regexps.size() / 2 - 1; return regexps.size() / 2 - 1;
} }
public final boolean hasParameterOrVar(String name) { public final boolean hasParamOrVar(String name) {
if (variableTable == null) { return false; } return itsVariableNames.has(name);
return variableTable.hasVariable(name);
} }
public final int getParameterOrVarIndex(String name) { public final int getParamOrVarIndex(String name) {
if (variableTable == null) { return -1; } return itsVariableNames.get(name, -1);
return variableTable.getOrdinal(name);
} }
public final String getParameterOrVarName(int index) { public final String getParamOrVarName(int index) {
return variableTable.getVariable(index); return (String)itsVariables.get(index);
} }
public final int getParameterCount() { public final int getParamCount() {
if (variableTable == null) { return 0; } return varStart;
return variableTable.getParameterCount();
} }
public final int getParameterAndVarCount() { public final int getParamAndVarCount() {
if (variableTable == null) { return 0; } return itsVariables.size();
return variableTable.size();
} }
public final String[] getParameterAndVarNames() { public final String[] getParamAndVarNames() {
if (variableTable == null) { return new String[0]; } String[] array = new String[itsVariables.size()];
return variableTable.getAllVariables(); itsVariables.toArray(array);
return array;
} }
public final void addParameter(String name) { public final void addParam(String name) {
if (variableTable == null) { variableTable = new VariableTable(); } // Check addparam is not called after addLocal
variableTable.addParameter(name); if (varStart != itsVariables.size()) Context.codeBug();
// Allow non-unique parameter names: use the last occurrence
int index = varStart++;
itsVariables.add(name);
itsVariableNames.put(name, index);
} }
public final void addVar(String name) { public final void addVar(String name) {
if (variableTable == null) { variableTable = new VariableTable(); } int vIndex = itsVariableNames.get(name, -1);
variableTable.addLocal(name); if (vIndex != -1) {
// There's already a variable or parameter with this name.
return;
}
int index = itsVariables.size();
itsVariables.add(name);
itsVariableNames.put(name, index);
} }
public final void removeParameterOrVar(String name) { public final void removeParamOrVar(String name) {
if (variableTable == null) { return; } int i = itsVariableNames.get(name, -1);
variableTable.removeLocal(name); if (i != -1) {
itsVariables.remove(i);
itsVariableNames.remove(name);
ObjToIntMap.Iterator iter = itsVariableNames.newIterator();
for (iter.start(); !iter.done(); iter.next()) {
int v = iter.getValue();
if (v > i) {
iter.setValue(v - 1);
}
}
}
} }
public final int getLocalCount() { return localCount; } public final int getLocalCount() { return localCount; }
@ -174,9 +191,19 @@ public class ScriptOrFnNode extends Node {
private String sourceName; private String sourceName;
private int baseLineno = -1; private int baseLineno = -1;
private int endLineno = -1; private int endLineno = -1;
private ObjArray functions; private ObjArray functions;
private ObjArray regexps; private ObjArray regexps;
private VariableTable variableTable;
// a list of the formal parameters and local variables
private ObjArray itsVariables = new ObjArray();
// mapping from name to index in list
private ObjToIntMap itsVariableNames = new ObjToIntMap(11);
private int varStart; // index in list of first variable
private int localCount; private int localCount;
} }

Просмотреть файл

Просмотреть файл

@ -333,7 +333,7 @@ public class Codegen extends Interpreter {
+ "Ljava/lang/Object;", + "Ljava/lang/Object;",
flags); flags);
int argCount = fnCurrent.getParameterCount(); int argCount = fnCurrent.getParamCount();
int firstLocal = (4 + argCount * 3) + 1; int firstLocal = (4 + argCount * 3) + 1;
aload((short)0); // this aload((short)0); // this
@ -429,7 +429,7 @@ public class Codegen extends Interpreter {
addByteCode(ByteCode.ALOAD_1); addByteCode(ByteCode.ALOAD_1);
addByteCode(ByteCode.ALOAD_2); addByteCode(ByteCode.ALOAD_2);
addByteCode(ByteCode.ALOAD_3); addByteCode(ByteCode.ALOAD_3);
for (int i = 0; i < scriptOrFn.getParameterCount(); i++) { for (int i = 0; i < scriptOrFn.getParamCount(); i++) {
push(i); push(i);
addByteCode(ByteCode.ALOAD, 4); addByteCode(ByteCode.ALOAD, 4);
addByteCode(ByteCode.ARRAYLENGTH); addByteCode(ByteCode.ARRAYLENGTH);
@ -465,7 +465,7 @@ public class Codegen extends Interpreter {
if (!fnCurrent.getParameterNumberContext()) { if (!fnCurrent.getParameterNumberContext()) {
// make sure that all parameters are objects // make sure that all parameters are objects
itsForcedObjectParameters = true; itsForcedObjectParameters = true;
for (int i = 0; i < fnCurrent.getParameterCount(); i++) { for (int i = 0; i < fnCurrent.getParamCount(); i++) {
OptLocalVariable lVar = fnCurrent.getVar(i); OptLocalVariable lVar = fnCurrent.getVar(i);
aload(lVar.getJRegister()); aload(lVar.getJRegister());
classFile.add(ByteCode.GETSTATIC, classFile.add(ByteCode.GETSTATIC,
@ -482,7 +482,7 @@ public class Codegen extends Interpreter {
markLabel(isObjectLabel); markLabel(isObjectLabel);
} }
} }
generatePrologue(cx, true, scriptOrFn.getParameterCount()); generatePrologue(cx, true, scriptOrFn.getParamCount());
} else { } else {
startNewMethod("call", startNewMethod("call",
"(Lorg/mozilla/javascript/Context;" + "(Lorg/mozilla/javascript/Context;" +
@ -544,7 +544,7 @@ public class Codegen extends Interpreter {
// 2 is reserved for parentScope // 2 is reserved for parentScope
// 3 is reserved for script 'this' // 3 is reserved for script 'this'
short jReg = 4; short jReg = 4;
int parameterCount = fnCurrent.getParameterCount(); int parameterCount = fnCurrent.getParamCount();
for (int i = 0; i < parameterCount; i++) { for (int i = 0; i < parameterCount; i++) {
OptLocalVariable lVar = fnCurrent.getVar(i); OptLocalVariable lVar = fnCurrent.getVar(i);
lVar.assignJRegister(jReg); lVar.assignJRegister(jReg);
@ -1145,7 +1145,7 @@ public class Codegen extends Interpreter {
"functionName", "Ljava/lang/String;"); "functionName", "Ljava/lang/String;");
} }
int N = scriptOrFn.getParameterAndVarCount(); int N = scriptOrFn.getParamAndVarCount();
if (N != 0) { if (N != 0) {
setNonTrivialInit(methodName); setNonTrivialInit(methodName);
push(N); push(N);
@ -1153,7 +1153,7 @@ public class Codegen extends Interpreter {
for (int i = 0; i != N; i++) { for (int i = 0; i != N; i++) {
addByteCode(ByteCode.DUP); addByteCode(ByteCode.DUP);
push(i); push(i);
push(scriptOrFn.getParameterOrVarName(i)); push(scriptOrFn.getParamOrVarName(i));
addByteCode(ByteCode.AASTORE); addByteCode(ByteCode.AASTORE);
} }
addByteCode(ByteCode.ALOAD_0); addByteCode(ByteCode.ALOAD_0);
@ -1163,7 +1163,7 @@ public class Codegen extends Interpreter {
"argNames", "[Ljava/lang/String;"); "argNames", "[Ljava/lang/String;");
} }
int parmCount = scriptOrFn.getParameterCount(); int parmCount = scriptOrFn.getParamCount();
if (parmCount != 0) { if (parmCount != 0) {
setNonTrivialInit(methodName); setNonTrivialInit(methodName);
addByteCode(ByteCode.ALOAD_0); addByteCode(ByteCode.ALOAD_0);
@ -1373,7 +1373,7 @@ public class Codegen extends Interpreter {
!((OptFunctionNode)scriptOrFn).requiresActivation(); !((OptFunctionNode)scriptOrFn).requiresActivation();
if (hasVarsInRegs) { if (hasVarsInRegs) {
// No need to create activation. Pad arguments if need be. // No need to create activation. Pad arguments if need be.
int parmCount = scriptOrFn.getParameterCount(); int parmCount = scriptOrFn.getParamCount();
if (inFunction && parmCount > 0 && directParameterCount < 0) { if (inFunction && parmCount > 0 && directParameterCount < 0) {
// Set up args array // Set up args array
// check length of arguments, pad if need be // check length of arguments, pad if need be

Просмотреть файл

@ -48,17 +48,17 @@ class OptFunctionNode extends FunctionNode {
protected void finishParsing(IRFactory irFactory) { protected void finishParsing(IRFactory irFactory) {
super.finishParsing(irFactory); super.finishParsing(irFactory);
int N = getParameterAndVarCount(); int N = getParamAndVarCount();
int parameterCount = getParameterCount(); int parameterCount = getParamCount();
optVars = new OptLocalVariable[N]; optVars = new OptLocalVariable[N];
for (int i = 0; i != N; ++i) { for (int i = 0; i != N; ++i) {
String name = getParameterOrVarName(i); String name = getParamOrVarName(i);
optVars[i] = new OptLocalVariable(name, i < parameterCount); optVars[i] = new OptLocalVariable(name, i < parameterCount);
} }
} }
String getDirectCallParameterSignature() { String getDirectCallParameterSignature() {
int pCount = getParameterCount(); int pCount = getParamCount();
switch (pCount) { switch (pCount) {
case 0: return ZERO_PARAM_SIG; case 0: return ZERO_PARAM_SIG;
case 1: return ONE_PARAM_SIG; case 1: return ONE_PARAM_SIG;
@ -129,7 +129,7 @@ class OptFunctionNode extends FunctionNode {
} }
OptLocalVariable getVar(String name) { OptLocalVariable getVar(String name) {
int index = getParameterOrVarIndex(name); int index = getParamOrVarIndex(name);
if (index < 0) { return null; } if (index < 0) { return null; }
return optVars[index]; return optVars[index];
} }

Просмотреть файл

@ -129,7 +129,7 @@ class OptTransformer extends NodeTransformer {
OptFunctionNode theFunction OptFunctionNode theFunction
= (OptFunctionNode)theFnClassNameList.get(targetName); = (OptFunctionNode)theFnClassNameList.get(targetName);
if (theFunction != null) { if (theFunction != null) {
int N = theFunction.getParameterCount(); int N = theFunction.getParamCount();
// Refuse to directCall any function with more // Refuse to directCall any function with more
// than 32 parameters - prevent code explosion // than 32 parameters - prevent code explosion
// for wacky test cases // for wacky test cases