mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 08:12:05 +00:00
Removal of 64K limit of total number of strings per script/function: now
string operands are preloaded with special LOAD_STR opcodes that handles full int indexes
This commit is contained in:
parent
9a6e1fe15d
commit
696129bcb0
@ -111,8 +111,13 @@ public class Interpreter
|
||||
Icode_LITERAL_NEW = BASE_ICODE + 30,
|
||||
Icode_LITERAL_SET = BASE_ICODE + 31,
|
||||
|
||||
// Load string register to prepare for the following string operation
|
||||
Icode_LOAD_STR1 = BASE_ICODE + 32,
|
||||
Icode_LOAD_STR2 = BASE_ICODE + 33,
|
||||
Icode_LOAD_STR4 = BASE_ICODE + 34,
|
||||
|
||||
// Last icode
|
||||
MAX_ICODE = BASE_ICODE + 31;
|
||||
MAX_ICODE = BASE_ICODE + 34;
|
||||
|
||||
public Object compile(Scriptable scope,
|
||||
CompilerEnvirons compilerEnv,
|
||||
@ -523,13 +528,6 @@ public class Interpreter
|
||||
if (itsStackDepth - savedStackDepth != 2)
|
||||
Kit.codeBug();
|
||||
}
|
||||
String functionName = null;
|
||||
int childType = child.getType();
|
||||
if (childType == Token.NAME || childType == Token.GETPROP
|
||||
|| childType == Token.GETVAR)
|
||||
{
|
||||
functionName = lastAddString;
|
||||
}
|
||||
int argCount = 0;
|
||||
while ((child = child.getNext()) != null) {
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
@ -544,7 +542,7 @@ public class Interpreter
|
||||
iCodeTop = addByte(type == Token.NEW ? 1 : 0, iCodeTop);
|
||||
iCodeTop = addShort(itsLineNumber, iCodeTop);
|
||||
} else {
|
||||
iCodeTop = addString(type, functionName, iCodeTop);
|
||||
iCodeTop = addToken(type, iCodeTop);
|
||||
}
|
||||
// adjust stack
|
||||
if (type == Token.NEW) {
|
||||
@ -773,7 +771,7 @@ public class Interpreter
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
child = child.getNext();
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
iCodeTop = addString(Token.SETNAME, firstChild.getString(), iCodeTop);
|
||||
iCodeTop = addStringOp(Token.SETNAME, firstChild.getString(), iCodeTop);
|
||||
itsStackDepth--;
|
||||
break;
|
||||
|
||||
@ -786,15 +784,14 @@ public class Interpreter
|
||||
if (itsInFunctionFlag && !itsData.itsNeedsActivation)
|
||||
index = scriptOrFn.getParamOrVarIndex(name);
|
||||
if (index == -1) {
|
||||
iCodeTop = addString(Icode_TYPEOFNAME, name, iCodeTop);
|
||||
iCodeTop = addStringOp(Icode_TYPEOFNAME, name, iCodeTop);
|
||||
stackChange(1);
|
||||
} else {
|
||||
iCodeTop = addToken(Token.GETVAR, iCodeTop);
|
||||
iCodeTop = addByte(index, iCodeTop);
|
||||
stackChange(1);
|
||||
iCodeTop = addToken(Token.TYPEOF, iCodeTop);
|
||||
}
|
||||
itsStackDepth++;
|
||||
if (itsStackDepth > itsData.itsMaxStack)
|
||||
itsData.itsMaxStack = itsStackDepth;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -802,10 +799,8 @@ public class Interpreter
|
||||
case Token.NAME :
|
||||
case Token.STRING :
|
||||
stackDelta = 1;
|
||||
iCodeTop = addString(type, node.getString(), iCodeTop);
|
||||
itsStackDepth++;
|
||||
if (itsStackDepth > itsData.itsMaxStack)
|
||||
itsData.itsMaxStack = itsStackDepth;
|
||||
iCodeTop = addStringOp(type, node.getString(), iCodeTop);
|
||||
stackChange(1);
|
||||
break;
|
||||
|
||||
case Token.INC :
|
||||
@ -817,7 +812,7 @@ public class Interpreter
|
||||
String name = child.getString();
|
||||
if (itsData.itsNeedsActivation) {
|
||||
iCodeTop = addIcode(Icode_SCOPE, iCodeTop);
|
||||
iCodeTop = addString(Token.STRING, name, iCodeTop);
|
||||
iCodeTop = addStringOp(Token.STRING, name, iCodeTop);
|
||||
itsStackDepth += 2;
|
||||
if (itsStackDepth > itsData.itsMaxStack)
|
||||
itsData.itsMaxStack = itsStackDepth;
|
||||
@ -858,10 +853,10 @@ public class Interpreter
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
iCodeTop = addString(type == Token.INC
|
||||
? Icode_NAMEINC
|
||||
: Icode_NAMEDEC,
|
||||
child.getString(), iCodeTop);
|
||||
iCodeTop = addStringOp(type == Token.INC
|
||||
? Icode_NAMEINC
|
||||
: Icode_NAMEDEC,
|
||||
child.getString(), iCodeTop);
|
||||
itsStackDepth++;
|
||||
if (itsStackDepth > itsData.itsMaxStack)
|
||||
itsData.itsMaxStack = itsStackDepth;
|
||||
@ -921,7 +916,7 @@ public class Interpreter
|
||||
case Token.CATCH_SCOPE :
|
||||
stackDelta = 1;
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
iCodeTop = addString(Token.CATCH_SCOPE, node.getString(), iCodeTop);
|
||||
iCodeTop = addStringOp(Token.CATCH_SCOPE, node.getString(), iCodeTop);
|
||||
break;
|
||||
|
||||
case Token.LEAVEWITH :
|
||||
@ -1018,7 +1013,7 @@ public class Interpreter
|
||||
// bogus children. Instead we use a special op to
|
||||
// push the current scope.
|
||||
iCodeTop = addIcode(Icode_SCOPE, iCodeTop);
|
||||
iCodeTop = addString(Token.STRING, name, iCodeTop);
|
||||
iCodeTop = addStringOp(Token.STRING, name, iCodeTop);
|
||||
itsStackDepth += 2;
|
||||
if (itsStackDepth > itsData.itsMaxStack)
|
||||
itsData.itsMaxStack = itsStackDepth;
|
||||
@ -1133,7 +1128,7 @@ public class Interpreter
|
||||
boolean skipGetThis = (itsWithDepth == 0
|
||||
&& (itsInFunctionFlag
|
||||
|| !itsData.itsFromEvalCode));
|
||||
iCodeTop = addString(Icode_NAME_AND_THIS, name, iCodeTop);
|
||||
iCodeTop = addStringOp(Icode_NAME_AND_THIS, name, iCodeTop);
|
||||
iCodeTop = addByte(skipGetThis ? 1 : 0, iCodeTop);
|
||||
stackChange(2);
|
||||
break;
|
||||
@ -1446,20 +1441,28 @@ public class Interpreter
|
||||
return iCodeTop;
|
||||
}
|
||||
|
||||
private int addString(int op, String str, int iCodeTop)
|
||||
private int addStringOp(int op, String str, int iCodeTop)
|
||||
{
|
||||
if (op > BASE_ICODE) {
|
||||
iCodeTop = addIcode(op, iCodeTop);
|
||||
} else {
|
||||
iCodeTop = addToken(op, iCodeTop);
|
||||
}
|
||||
int index = itsStrings.get(str, -1);
|
||||
if (index == -1) {
|
||||
index = itsStrings.size();
|
||||
itsStrings.put(str, index);
|
||||
}
|
||||
iCodeTop = addIndex(index, iCodeTop);
|
||||
lastAddString = str;
|
||||
if (index <= 0xFF) {
|
||||
iCodeTop = addIcode(Icode_LOAD_STR1, iCodeTop);
|
||||
iCodeTop = addByte(index, iCodeTop);
|
||||
} else if (index <= 0xFFFF) {
|
||||
iCodeTop = addIcode(Icode_LOAD_STR2, iCodeTop);
|
||||
iCodeTop = addIndex(index, iCodeTop);
|
||||
} else {
|
||||
iCodeTop = addIcode(Icode_LOAD_STR4, iCodeTop);
|
||||
iCodeTop = addInt(index, iCodeTop);
|
||||
}
|
||||
if (op > BASE_ICODE) {
|
||||
iCodeTop = addIcode(op, iCodeTop);
|
||||
} else {
|
||||
iCodeTop = addToken(op, iCodeTop);
|
||||
}
|
||||
return iCodeTop;
|
||||
}
|
||||
|
||||
@ -1588,6 +1591,9 @@ public class Interpreter
|
||||
case Icode_INTNUMBER: return "INTNUMBER";
|
||||
case Icode_LITERAL_NEW: return "LITERAL_NEW";
|
||||
case Icode_LITERAL_SET: return "LITERAL_SET";
|
||||
case Icode_LOAD_STR1: return "LOAD_STR1";
|
||||
case Icode_LOAD_STR2: return "LOAD_STR2";
|
||||
case Icode_LOAD_STR4: return "LOAD_STR4";
|
||||
}
|
||||
}
|
||||
return "<UNKNOWN ICODE: "+icode+">";
|
||||
@ -1685,10 +1691,9 @@ public class Interpreter
|
||||
}
|
||||
case Token.NEW :
|
||||
case Token.CALL : {
|
||||
int count = getIndex(iCode, pc + 2);
|
||||
String name = strings[getIndex(iCode, pc)];
|
||||
out.println(tname+' '+count+" \""+name+'"');
|
||||
pc += 4;
|
||||
int count = getIndex(iCode, pc);
|
||||
out.println(tname+' '+count);
|
||||
pc += 2;
|
||||
break;
|
||||
}
|
||||
case Token.THROW : {
|
||||
@ -1716,24 +1721,10 @@ public class Interpreter
|
||||
pc += 2;
|
||||
break;
|
||||
}
|
||||
case Token.CATCH_SCOPE :
|
||||
case Icode_TYPEOFNAME :
|
||||
case Token.BINDNAME :
|
||||
case Token.SETNAME :
|
||||
case Token.NAME :
|
||||
case Icode_NAMEINC :
|
||||
case Icode_NAMEDEC :
|
||||
case Token.STRING : {
|
||||
String str = strings[getIndex(iCode, pc)];
|
||||
out.println(tname + " \"" + str + '"');
|
||||
pc += 2;
|
||||
break;
|
||||
}
|
||||
case Icode_NAME_AND_THIS : {
|
||||
String str = strings[getIndex(iCode, pc)];
|
||||
boolean skipGetThis = (0 != iCode[pc + 2]);
|
||||
out.println(tname + " \"" + str + '"'+" "+skipGetThis);
|
||||
pc += 3;
|
||||
boolean skipGetThis = (0 != iCode[pc]);
|
||||
out.println(tname+" "+skipGetThis);
|
||||
++pc;
|
||||
break;
|
||||
}
|
||||
case Icode_LINE : {
|
||||
@ -1748,6 +1739,21 @@ public class Interpreter
|
||||
pc += 4;
|
||||
break;
|
||||
}
|
||||
case Icode_LOAD_STR1: {
|
||||
String str = strings[0xFF & iCode[pc]];
|
||||
out.println(tname + " \"" + str + '"');
|
||||
++pc;
|
||||
}
|
||||
case Icode_LOAD_STR2: {
|
||||
String str = strings[getIndex(iCode, pc)];
|
||||
out.println(tname + " \"" + str + '"');
|
||||
pc += 2;
|
||||
}
|
||||
case Icode_LOAD_STR4: {
|
||||
String str = strings[getInt(iCode, pc)];
|
||||
out.println(tname + " \"" + str + '"');
|
||||
pc += 4;
|
||||
}
|
||||
}
|
||||
if (old_pc + icodeLength != pc) Kit.codeBug();
|
||||
}
|
||||
@ -1841,6 +1847,14 @@ public class Interpreter
|
||||
case Icode_CATCH:
|
||||
case Icode_RETUNDEF:
|
||||
case Icode_LITERAL_SET:
|
||||
case Token.STRING :
|
||||
case Token.NAME :
|
||||
case Token.SETNAME :
|
||||
case Icode_TYPEOFNAME :
|
||||
case Token.BINDNAME :
|
||||
case Icode_NAMEINC :
|
||||
case Icode_NAMEDEC :
|
||||
case Token.CATCH_SCOPE :
|
||||
return 1;
|
||||
|
||||
case Token.THROW :
|
||||
@ -1885,9 +1899,8 @@ public class Interpreter
|
||||
|
||||
case Token.NEW :
|
||||
case Token.CALL :
|
||||
// name string index
|
||||
// arg count
|
||||
return 1 + 2 + 2;
|
||||
return 1 + 2;
|
||||
|
||||
case Icode_SHORTNUMBER :
|
||||
// short number
|
||||
@ -1901,20 +1914,21 @@ public class Interpreter
|
||||
// index of double number
|
||||
return 1 + 2;
|
||||
|
||||
case Token.CATCH_SCOPE :
|
||||
case Icode_TYPEOFNAME :
|
||||
case Token.BINDNAME :
|
||||
case Token.SETNAME :
|
||||
case Token.NAME :
|
||||
case Icode_NAMEINC :
|
||||
case Icode_NAMEDEC :
|
||||
case Token.STRING :
|
||||
// string index
|
||||
case Icode_LOAD_STR1:
|
||||
// ubyte string index
|
||||
return 1 + 1;
|
||||
|
||||
case Icode_LOAD_STR2:
|
||||
// ushort string index
|
||||
return 1 + 2;
|
||||
|
||||
case Icode_LOAD_STR4:
|
||||
// int string index
|
||||
return 1 + 4;
|
||||
|
||||
case Icode_NAME_AND_THIS :
|
||||
// string index skipGetThis
|
||||
return 1 + 2 + 1;
|
||||
// skipGetThis flag
|
||||
return 1 + 1;
|
||||
|
||||
case Icode_LINE :
|
||||
// line number
|
||||
@ -2129,9 +2143,7 @@ public class Interpreter
|
||||
int exceptionPC = -1;
|
||||
|
||||
byte[] iCode = idata.itsICode;
|
||||
String[] strings = idata.itsStringTable;
|
||||
int pc = 0;
|
||||
|
||||
int pcPrevBranch = 0;
|
||||
final int instructionThreshold = cx.instructionThreshold;
|
||||
// During function call this will be set to -1 so catch can properly
|
||||
@ -2141,6 +2153,9 @@ public class Interpreter
|
||||
// other functions
|
||||
final int INVOCATION_COST = 100;
|
||||
|
||||
String[] strings = idata.itsStringTable;
|
||||
String stringReg = null;
|
||||
|
||||
Loop: for (;;) {
|
||||
int pcJump;
|
||||
try {
|
||||
@ -2552,20 +2567,27 @@ public class Interpreter
|
||||
? Boolean.FALSE : Boolean.TRUE;
|
||||
continue Loop;
|
||||
}
|
||||
case Token.BINDNAME : {
|
||||
String name = strings[getIndex(iCode, pc)];
|
||||
stack[++stackTop] = ScriptRuntime.bind(scope, name);
|
||||
case Icode_LOAD_STR1:
|
||||
stringReg = strings[0xFF & iCode[pc]];
|
||||
++pc;
|
||||
continue Loop;
|
||||
case Icode_LOAD_STR2:
|
||||
stringReg = strings[getIndex(iCode, pc)];
|
||||
pc += 2;
|
||||
continue Loop;
|
||||
}
|
||||
case Icode_LOAD_STR4:
|
||||
stringReg = strings[getInt(iCode, pc)];
|
||||
pc += 4;
|
||||
continue Loop;
|
||||
case Token.BINDNAME :
|
||||
stack[++stackTop] = ScriptRuntime.bind(scope, stringReg);
|
||||
continue Loop;
|
||||
case Token.SETNAME : {
|
||||
String name = strings[getIndex(iCode, pc)];
|
||||
Object rhs = stack[stackTop];
|
||||
if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
|
||||
--stackTop;
|
||||
Scriptable lhs = (Scriptable)stack[stackTop];
|
||||
stack[stackTop] = ScriptRuntime.setName(lhs, rhs, scope, name);
|
||||
pc += 2;
|
||||
stack[stackTop] = ScriptRuntime.setName(lhs, rhs, scope, stringReg);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.DELPROP : {
|
||||
@ -2677,7 +2699,7 @@ public class Interpreter
|
||||
cx.instructionCount = instructionCount;
|
||||
instructionCount = -1;
|
||||
}
|
||||
int count = getIndex(iCode, pc + 2);
|
||||
int count = getIndex(iCode, pc);
|
||||
stackTop -= count;
|
||||
int calleeArgShft = stackTop + 1;
|
||||
Object rhs = stack[stackTop];
|
||||
@ -2712,15 +2734,14 @@ public class Interpreter
|
||||
else if (lhs == undefined) {
|
||||
// special code for better error message for call
|
||||
// to undefined
|
||||
lhs = strings[getIndex(iCode, pc)];
|
||||
if (lhs == null) lhs = undefined;
|
||||
lhs = stringReg;
|
||||
}
|
||||
throw ScriptRuntime.typeError1("msg.isnt.function",
|
||||
ScriptRuntime.toString(lhs));
|
||||
}
|
||||
|
||||
instructionCount = cx.instructionCount;
|
||||
pc += 4;
|
||||
pc += 2;
|
||||
continue Loop;
|
||||
}
|
||||
case Token.NEW : {
|
||||
@ -2729,7 +2750,7 @@ public class Interpreter
|
||||
cx.instructionCount = instructionCount;
|
||||
instructionCount = -1;
|
||||
}
|
||||
int count = getIndex(iCode, pc + 2);
|
||||
int count = getIndex(iCode, pc);
|
||||
stackTop -= count;
|
||||
int calleeArgShft = stackTop + 1;
|
||||
Object lhs = stack[stackTop];
|
||||
@ -2756,15 +2777,14 @@ public class Interpreter
|
||||
else if (lhs == undefined) {
|
||||
// special code for better error message for call
|
||||
// to undefined
|
||||
lhs = strings[getIndex(iCode, pc)];
|
||||
if (lhs == null) lhs = undefined;
|
||||
lhs = stringReg;
|
||||
}
|
||||
throw ScriptRuntime.typeError1("msg.isnt.function",
|
||||
ScriptRuntime.toString(lhs));
|
||||
|
||||
}
|
||||
instructionCount = cx.instructionCount;
|
||||
pc += 4;
|
||||
pc += 2;
|
||||
continue Loop;
|
||||
}
|
||||
case Token.TYPEOF : {
|
||||
@ -2773,22 +2793,17 @@ public class Interpreter
|
||||
stack[stackTop] = ScriptRuntime.typeof(lhs);
|
||||
continue Loop;
|
||||
}
|
||||
case Icode_TYPEOFNAME : {
|
||||
String name = strings[getIndex(iCode, pc)];
|
||||
stack[++stackTop] = ScriptRuntime.typeofName(scope, name);
|
||||
pc += 2;
|
||||
case Icode_TYPEOFNAME :
|
||||
stack[++stackTop] = ScriptRuntime.typeofName(scope, stringReg);
|
||||
continue Loop;
|
||||
}
|
||||
case Icode_NAME_AND_THIS : {
|
||||
String name = strings[getIndex(iCode, pc)];
|
||||
boolean skipGetThis = (0 != iCode[pc + 2]);
|
||||
stackTop = do_nameAndThis(stack, stackTop, scope, name, skipGetThis);
|
||||
pc += 3;
|
||||
boolean skipGetThis = (0 != iCode[pc]);
|
||||
stackTop = do_nameAndThis(stack, stackTop, scope, stringReg, skipGetThis);
|
||||
++pc;
|
||||
continue Loop;
|
||||
}
|
||||
case Token.STRING :
|
||||
stack[++stackTop] = strings[getIndex(iCode, pc)];
|
||||
pc += 2;
|
||||
stack[++stackTop] = stringReg;
|
||||
continue Loop;
|
||||
case Icode_SHORTNUMBER :
|
||||
++stackTop;
|
||||
@ -2808,19 +2823,13 @@ public class Interpreter
|
||||
sDbl[stackTop] = idata.itsDoubleTable[getIndex(iCode, pc)];
|
||||
pc += 2;
|
||||
continue Loop;
|
||||
case Token.NAME : {
|
||||
String name = strings[getIndex(iCode, pc)];
|
||||
stack[++stackTop] = ScriptRuntime.name(scope, name);
|
||||
pc += 2;
|
||||
case Token.NAME :
|
||||
stack[++stackTop] = ScriptRuntime.name(scope, stringReg);
|
||||
continue Loop;
|
||||
}
|
||||
case Icode_NAMEINC :
|
||||
case Icode_NAMEDEC : {
|
||||
String name = strings[getIndex(iCode, pc)];
|
||||
stack[++stackTop] = ScriptRuntime.postIncrDecr(scope, name, op == Icode_NAMEINC);
|
||||
pc += 2;
|
||||
case Icode_NAMEDEC :
|
||||
stack[++stackTop] = ScriptRuntime.postIncrDecr(scope, stringReg, op == Icode_NAMEINC);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.SETVAR : {
|
||||
int slot = (iCode[pc] & 0xFF);
|
||||
if (!useActivationVars) {
|
||||
@ -2912,12 +2921,9 @@ public class Interpreter
|
||||
scope = ScriptRuntime.leaveWith(scope);
|
||||
--withDepth;
|
||||
continue Loop;
|
||||
case Token.CATCH_SCOPE : {
|
||||
String name = strings[getIndex(iCode, pc)];
|
||||
stack[stackTop] = ScriptRuntime.newCatchScope(name, stack[stackTop]);
|
||||
pc += 2;
|
||||
case Token.CATCH_SCOPE :
|
||||
stack[stackTop] = ScriptRuntime.newCatchScope(stringReg, stack[stackTop]);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.ENUM_INIT : {
|
||||
int slot = (iCode[pc] & 0xFF);
|
||||
Object lhs = stack[stackTop];
|
||||
@ -3418,7 +3424,6 @@ public class Interpreter
|
||||
private int itsLineNumber = 0;
|
||||
private int itsDoubleTableTop;
|
||||
private ObjToIntMap itsStrings = new ObjToIntMap(20);
|
||||
private String lastAddString;
|
||||
private int itsLocalTop;
|
||||
|
||||
private static final int MIN_LABEL_TABLE_SIZE = 32;
|
||||
|
Loading…
Reference in New Issue
Block a user