Making interpreter bytecode independent from Context.isGeneratingDebug so debugger can handle scripts compiled without Context.isGeneratingDebug: if itsNeedsActivation is false with debugger present, Interpreter.interpret creates activation scope and check in variable queries/assignments if they should be made against activation object and not stack[VAR_SHIFT+...] array.

This commit is contained in:
igor%mir2.org 2002-04-19 07:19:07 +00:00
Родитель 2d24521089
Коммит 77589e0e41
1 изменённых файлов: 76 добавлений и 29 удалений

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

@ -213,11 +213,8 @@ public class Interpreter extends LabelTable {
regExpLiterals = generateRegExpLiterals(cx, scope, regexps);
VariableTable varTable = theFunction.getVariableTable();
boolean needsActivation = theFunction.requiresActivation() ||
(cx.isGeneratingDebugChanged() &&
cx.isGeneratingDebug());
generateICodeFromTree(theFunction.getLastChild(),
varTable, needsActivation,
varTable, theFunction.requiresActivation(),
securityDomain);
itsData.itsName = theFunction.getFunctionName();
@ -1513,10 +1510,16 @@ public class Interpreter extends LabelTable {
theData.itsFromEvalCode);
}
DebugFrame frame = null;
DebugFrame debuggerFrame = null;
boolean useActivationVars = false;
if (cx.debugger != null) {
frame = cx.debugger.enterFrame(cx, scope, thisObj, args,
(DebuggableScript)fnOrScript);
if (!theData.itsNeedsActivation) {
useActivationVars = true;
scope = ScriptRuntime.initVarObj(cx, scope, fnOrScript,
thisObj, args);
}
debuggerFrame = cx.debugger.enterFrame
(cx, scope, thisObj, args, (DebuggableScript)fnOrScript);
}
Object result = undefined;
@ -2126,35 +2129,60 @@ public class Interpreter extends LabelTable {
break;
case TokenStream.SETVAR : {
int slot = (iCode[++pc] & 0xFF);
stack[VAR_SHFT + slot] = stack[stackTop];
sDbl[VAR_SHFT + slot] = sDbl[stackTop];
if (!useActivationVars) {
stack[VAR_SHFT + slot] = stack[stackTop];
sDbl[VAR_SHFT + slot] = sDbl[stackTop];
}else {
Object val = stack[stackTop];
if (val == DBL_MRK) val = doubleWrap(sDbl[stackTop]);
activationPut(fnOrScript, scope, slot, val);
}
break;
}
case TokenStream.GETVAR : {
int slot = (iCode[++pc] & 0xFF);
++stackTop;
stack[stackTop] = stack[VAR_SHFT + slot];
sDbl[stackTop] = sDbl[VAR_SHFT + slot];
if (!useActivationVars) {
stack[stackTop] = stack[VAR_SHFT + slot];
sDbl[stackTop] = sDbl[VAR_SHFT + slot];
}else {
stack[stackTop]
= activationGet(fnOrScript, scope, slot);
}
break;
}
case TokenStream.VARINC : {
int slot = (iCode[++pc] & 0xFF);
++stackTop;
stack[stackTop] = stack[VAR_SHFT + slot];
sDbl[stackTop] = sDbl[VAR_SHFT + slot];
stack[VAR_SHFT + slot] = DBL_MRK;
sDbl[VAR_SHFT + slot]
= stack_double(stack, sDbl, stackTop) + 1.0;
if (!useActivationVars) {
stack[stackTop] = stack[VAR_SHFT + slot];
sDbl[stackTop] = sDbl[VAR_SHFT + slot];
stack[VAR_SHFT + slot] = DBL_MRK;
sDbl[VAR_SHFT + slot]
= stack_double(stack, sDbl, stackTop) + 1.0;
}else {
Object val = activationGet(fnOrScript, scope, slot);
stack[stackTop] = val;
val = doubleWrap(ScriptRuntime.toNumber(val) + 1.0);
activationPut(fnOrScript, scope, slot, val);
}
break;
}
case TokenStream.VARDEC : {
int slot = (iCode[++pc] & 0xFF);
++stackTop;
stack[stackTop] = stack[VAR_SHFT + slot];
sDbl[stackTop] = sDbl[VAR_SHFT + slot];
stack[VAR_SHFT + slot] = DBL_MRK;
sDbl[VAR_SHFT + slot]
= stack_double(stack, sDbl, stackTop) - 1.0;
if (!useActivationVars) {
stack[stackTop] = stack[VAR_SHFT + slot];
sDbl[stackTop] = sDbl[VAR_SHFT + slot];
stack[VAR_SHFT + slot] = DBL_MRK;
sDbl[VAR_SHFT + slot]
= stack_double(stack, sDbl, stackTop) - 1.0;
}else {
Object val = activationGet(fnOrScript, scope, slot);
stack[stackTop] = val;
val = doubleWrap(ScriptRuntime.toNumber(val) - 1.0);
activationPut(fnOrScript, scope, slot, val);
}
break;
}
case TokenStream.ZERO :
@ -2297,10 +2325,10 @@ public class Interpreter extends LabelTable {
case BREAKPOINT_ICODE : {
int line = getShort(iCode, pc + 1);
cx.interpreterLine = line;
if (frame != null) {
if (debuggerFrame != null) {
boolean breakpoint
= ((iCode[pc] & 0xff) == BREAKPOINT_ICODE);
frame.onLineChange(cx, line, breakpoint);
debuggerFrame.onLineChange(cx, line, breakpoint);
}
pc += 2;
break;
@ -2359,8 +2387,8 @@ public class Interpreter extends LabelTable {
break;
}
if (exType != OTHER && frame != null) {
frame.onExceptionThrown(cx, ex);
if (exType != OTHER && debuggerFrame != null) {
debuggerFrame.onExceptionThrown(cx, ex);
}
boolean rethrow = true;
@ -2397,8 +2425,8 @@ public class Interpreter extends LabelTable {
}
if (rethrow) {
if (frame != null) {
frame.onExit(cx, true, ex);
if (debuggerFrame != null) {
debuggerFrame.onExit(cx, true, ex);
}
if (theData.itsNeedsActivation) {
ScriptRuntime.popActivation(cx);
@ -2428,8 +2456,8 @@ public class Interpreter extends LabelTable {
scope = (Scriptable)stack[TRY_STACK_SHFT + tryStackTop];
}
}
if (frame != null) {
frame.onExit(cx, false, result);
if (debuggerFrame != null) {
debuggerFrame.onExit(cx, false, result);
}
if (theData.itsNeedsActivation) {
ScriptRuntime.popActivation(cx);
@ -2688,6 +2716,25 @@ public class Interpreter extends LabelTable {
return args;
}
private static Object activationGet(NativeFunction f,
Scriptable activation, int slot)
{
String name = f.argNames[slot];
Object val = activation.get(name, activation);
// Activation parameter or var is permanent
if (val == Scriptable.NOT_FOUND) Context.codeBug();
return val;
}
private static void activationPut(NativeFunction f,
Scriptable activation, int slot,
Object value)
{
String name = f.argNames[slot];
activation.put(name, activation, value);
}
private int version;
private boolean inLineStepMode;
private StringBuffer debugSource;