Rhino: deal with all Throwables in Interpreter.interpret
        Date:
             Thu, 12 Jul 2001 14:27:34 +0200
       From:
             Igor Bukanov <igor@icesoft.no>
 Organization:
             Wind River
         To:
             Norris Boyd <nboyd@atg.com>




The attached patch modifies the catch code in Interpreter.interpret to
catch general Throwable exceptions to allow cleanup after throwing an
Error instance from Context.observeInstructionCount.
===================
Subject:
             Rhino: change of InterpreterData.itsLineNumberTable from Hahstable to
             UintHash
        Date:
             Thu, 12 Jul 2001 15:51:38 +0200
       From:
             Igor Bukanov <igor@icesoft.no>
 Organization:
             Wind River
         To:
             Norris Boyd <nboyd@atg.com>




The patch linetable_patch changes InterpreterData.itsLineNumberTable
from Hahstable to UintHash and debug/DebuggableScript.java to return
int[] array instead of Enumeration. It was run produced via
diff -ru javascript.0 javascript

The patch debugger_patch contains update for
toolsrc/org/mozilla/javascript/tools/debugger/Main.java to reflect above
api changes.
===============================
Subject:
             Rhino: patch not to store VariableTable in InterpreterData
        Date:
             Thu, 12 Jul 2001 16:34:18 +0200
       From:
             Igor Bukanov <igor@icesoft.no>
 Organization:
             Wind River
         To:
             Norris Boyd <nboyd@atg.com>




The patch removes the "VariableTable itsVariableTable" field from
InterpreterData so it would not be stored in
InterpretedFunction/InterpretedScript and could be garbage collected
after interpreter byte code generation is finished. The usage of
theData.itsVariableTable it Interpreter.interpret is replaced by
accessing argNames/argCount fields from the passed NativeFunction.
This commit is contained in:
nboyd%atg.com 2001-07-13 13:53:40 +00:00
Родитель 6d0b3baa55
Коммит c97a786c6e
7 изменённых файлов: 85 добавлений и 71 удалений

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

@ -40,25 +40,19 @@ import org.mozilla.javascript.debug.DebuggableScript;
class InterpretedFunction extends NativeFunction implements DebuggableScript {
InterpretedFunction(InterpreterData theData, Context cx) {
InterpretedFunction(Context cx,
InterpreterData theData,
String[] argNames, short argCount)
{
itsData = theData;
this.argNames = argNames;
this.argCount = argCount;
init(cx);
}
void init(Context cx)
{
// probably too much copying going on from theData to the InterpretedFunction object
// should pass them as parameters - unless we need them in the data block anyway?
functionName = itsData.itsName;
int N = itsData.itsVariableTable.size();
if (N != 0) {
argNames = new String[N];
for (int i = 0; i != N; i++) {
argNames[i] = itsData.itsVariableTable.getName(i);
}
}
argCount = (short)itsData.itsVariableTable.getParameterCount();
source = itsData.itsSource;
nestedFunctions = itsData.itsNestedFunctions;
if (cx != null)
@ -69,6 +63,8 @@ class InterpretedFunction extends NativeFunction implements DebuggableScript {
Scriptable theScope, Context cx)
{
itsData = theOther.itsData;
this.argNames = theOther.argNames;
this.argCount = theOther.argCount;
itsClosure = theScope;
init(cx);
}
@ -111,8 +107,8 @@ class InterpretedFunction extends NativeFunction implements DebuggableScript {
return itsData.itsSourceFile;
}
public Enumeration getLineNumbers() {
return itsData.itsLineNumberTable.keys();
public int[] getLineNumbers() {
return itsData.itsLineNumberTable.getKeys();
}
public boolean placeBreakpoint(int line) { // XXX throw exn?

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

@ -41,17 +41,14 @@ import java.util.*;
public class InterpretedScript extends NativeScript implements DebuggableScript {
InterpretedScript(InterpreterData theData, Context cx)
InterpretedScript(Context cx,
InterpreterData theData,
String[] argNames, short argCount)
{
itsData = theData;
this.argNames = argNames;
this.argCount = argCount;
functionName = "";
int N = itsData.itsVariableTable.size();
if (N != 0) {
argNames = new String[N];
for (int i = 0; i != N; i++) {
argNames[i] = itsData.itsVariableTable.getName(i);
}
}
nestedFunctions = itsData.itsNestedFunctions;
version = (short)cx.getLanguageVersion();
}
@ -83,8 +80,8 @@ public class InterpretedScript extends NativeScript implements DebuggableScript
return itsData.itsSourceFile;
}
public Enumeration getLineNumbers() {
return itsData.itsLineNumberTable.keys();
public int[] getLineNumbers() {
return itsData.itsLineNumberTable.getKeys();
}
public boolean placeBreakpoint(int line) { // XXX throw exn?

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

@ -84,7 +84,7 @@ public class Interpreter extends LabelTable {
Object securityDomain)
{
int theICodeTop = 0;
itsData.itsVariableTable = varTable;
itsVariableTable = varTable;
itsData.itsNeedsActivation = needsActivation;
theICodeTop = generateICode(tree, theICodeTop);
itsData.itsICodeTop = theICodeTop;
@ -136,7 +136,10 @@ public class Interpreter extends LabelTable {
itsData.itsRegExpLiterals = regExpLiterals;
if (printICode) dumpICode(itsData);
InterpretedScript result = new InterpretedScript(itsData, cx);
String[] argNames = itsVariableTable.getAllNames();
short argCount = (short)itsVariableTable.getParameterCount();
InterpretedScript
result = new InterpretedScript(cx, itsData, argNames, argCount);
if (cx.debugger != null) {
cx.debugger.handleCompilationDone(cx, result, debugSource);
}
@ -192,7 +195,10 @@ public class Interpreter extends LabelTable {
itsData.itsRegExpLiterals = regExpLiterals;
if (printICode) dumpICode(itsData);
InterpretedFunction result = new InterpretedFunction(itsData, cx);
String[] argNames = itsVariableTable.getAllNames();
short argCount = (short)itsVariableTable.getParameterCount();
InterpretedFunction
result = new InterpretedFunction(cx, itsData, argNames, argCount);
if (cx.debugger != null) {
cx.debugger.handleCompilationDone(cx, result, debugSource);
}
@ -203,6 +209,7 @@ public class Interpreter extends LabelTable {
Vector itsFunctionList;
InterpreterData itsData;
VariableTable itsVariableTable;
int itsTryDepth = 0;
int itsStackDepth = 0;
int itsEpilogLabel = -1;
@ -221,11 +228,10 @@ public class Interpreter extends LabelTable {
if (itsData.itsLineNumberTable == null &&
Context.getCurrentContext().isGeneratingDebug())
{
itsData.itsLineNumberTable = new java.util.Hashtable();
itsData.itsLineNumberTable = new UintMap();
}
if (itsData.itsLineNumberTable != null) {
itsData.itsLineNumberTable.put(new Integer(lineNumber),
new Integer(iCodeTop));
itsData.itsLineNumberTable.put(lineNumber, iCodeTop);
}
iCodeTop = addByte((byte) TokenStream.LINE, iCodeTop);
iCodeTop = addByte((byte)(lineNumber >> 8), iCodeTop);
@ -673,7 +679,7 @@ public class Interpreter extends LabelTable {
// use typeofname if an activation frame exists
// since the vars all exist there instead of in jregs
if (itsInFunctionFlag && !itsData.itsNeedsActivation)
index = itsData.itsVariableTable.getOrdinal(name);
index = itsVariableTable.getOrdinal(name);
if (index == -1) {
iCodeTop = addByte((byte) TokenStream.TYPEOFNAME, iCodeTop);
iCodeTop = addString(name, iCodeTop);
@ -731,8 +737,7 @@ public class Interpreter extends LabelTable {
? TokenStream.VARINC
: TokenStream.VARDEC),
iCodeTop);
int i = itsData.itsVariableTable.
getOrdinal(name);
int i = itsVariableTable.getOrdinal(name);
iCodeTop = addByte((byte)i, iCodeTop);
itsStackDepth++;
if (itsStackDepth > itsData.itsMaxStack)
@ -946,7 +951,7 @@ public class Interpreter extends LabelTable {
itsStackDepth--;
}
else {
int index = itsData.itsVariableTable.getOrdinal(name);
int index = itsVariableTable.getOrdinal(name);
iCodeTop = addByte((byte) TokenStream.GETVAR, iCodeTop);
iCodeTop = addByte((byte)index, iCodeTop);
itsStackDepth++;
@ -966,7 +971,7 @@ public class Interpreter extends LabelTable {
String name = child.getString();
child = child.getNextSibling();
iCodeTop = generateICode(child, iCodeTop);
int index = itsData.itsVariableTable.getOrdinal(name);
int index = itsVariableTable.getOrdinal(name);
iCodeTop = addByte((byte) TokenStream.SETVAR, iCodeTop);
iCodeTop = addByte((byte)index, iCodeTop);
}
@ -1350,7 +1355,7 @@ public class Interpreter extends LabelTable {
public static Object interpret(Context cx, Scriptable scope,
Scriptable thisObj, Object[] args,
Scriptable fnOrScript,
NativeFunction fnOrScript,
InterpreterData theData)
throws JavaScriptException
{
@ -1358,7 +1363,8 @@ public class Interpreter extends LabelTable {
Object lhs;
final int maxStack = theData.itsMaxStack;
final int maxVars = theData.itsVariableTable.size();
final int maxVars = (fnOrScript.argNames == null)
? 0 : fnOrScript.argNames.length;
final int maxLocals = theData.itsMaxLocals;
final int maxTryDepth = theData.itsMaxTryDepth;
@ -1384,7 +1390,7 @@ public class Interpreter extends LabelTable {
final Scriptable undefined = Undefined.instance;
if (maxVars != 0) {
int definedArgs = theData.itsVariableTable.getParameterCount();
int definedArgs = fnOrScript.argCount;
if (definedArgs != 0) {
if (definedArgs > args.length) { definedArgs = args.length; }
for (i = 0; i != definedArgs; ++i) {
@ -2190,7 +2196,7 @@ public class Interpreter extends LabelTable {
}
pc++;
}
catch (Exception ex) {
catch (Throwable ex) {
cx.interpreterSecurityDomain = null;
if (instructionThreshold != 0) {
@ -2203,9 +2209,9 @@ public class Interpreter extends LabelTable {
instructionCount += pc - pcPrevBranch;
cx.instructionCount = instructionCount;
}
}
}
final int SCRIPT_THROW = 0, ECMA = 1, OTHER = 2;
final int SCRIPT_THROW = 0, ECMA = 1, RUNTIME = 2, OTHER = 3;
int exType;
Object errObj; // Object seen by catch
@ -2219,20 +2225,25 @@ public class Interpreter extends LabelTable {
errObj = ((EcmaError)ex).getErrorObject();
exType = ECMA;
}
else {
else if (ex instanceof RuntimeException) {
errObj = ex;
exType = RUNTIME;
}
else {
errObj = ex; // Error instance
exType = OTHER;
}
if (cx.debugger != null) {
if (exType != OTHER && cx.debugger != null) {
cx.debugger.handleExceptionThrown(cx, errObj);
}
boolean rethrow = true;
if (tryStackTop > 0) {
if (exType != OTHER && tryStackTop > 0) {
--tryStackTop;
scope = (Scriptable)stack[TRY_SCOPE_SHFT + tryStackTop];
if (exType == SCRIPT_THROW || exType == ECMA) {
// Check for catch only for
// JavaScriptException and EcmaError
pc = catchStack[tryStackTop * 2];
if (pc != 0) {
// Has catch block
@ -2241,34 +2252,40 @@ public class Interpreter extends LabelTable {
}
if (rethrow) {
pc = catchStack[tryStackTop * 2 + 1];
if (pc != 0) {
if (pc != 0) {
// has finally block
rethrow = false;
rethrow = false;
errObj = ex;
}
}
}
}
if (rethrow) {
if (frame != null)
cx.popFrame();
if (exType == SCRIPT_THROW) throw (JavaScriptException)ex;
else throw (RuntimeException)ex;
if (exType == SCRIPT_THROW)
throw (JavaScriptException)ex;
if (exType == ECMA || exType == RUNTIME)
throw (RuntimeException)ex;
throw (Error)ex;
}
// We caught an exception,
// We caught an exception,
// Notify instruction observer if necessary
// and point pcPrevBranch to start of catch/finally block
if (instructionThreshold != 0) {
if (instructionCount > instructionThreshold) {
// Note: this can throw Error
cx.observeInstructionCount(instructionCount);
instructionCount = 0;
}
}
pcPrevBranch = pc;
pcPrevBranch = pc;
// prepare stack and restore this function's security domain.
scope = (Scriptable)stack[TRY_SCOPE_SHFT + tryStackTop];
stackTop = 0;
stack[0] = errObj;
cx.interpreterSecurityDomain = theData.securityDomain;

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

@ -90,19 +90,13 @@ class InterpreterData {
}
private int getOffset(int line) {
Object offset = itsLineNumberTable.get(new Integer(line));
if (offset != null && offset instanceof Integer) {
int i = ((Integer)offset).intValue();
if (i >= 0 && i < itsICode.length)
{
return i;
}
int offset = itsLineNumberTable.getInt(line, -1);
if (0 <= offset && offset <= itsICode.length) {
return offset;
}
return -1;
}
VariableTable itsVariableTable;
String itsName;
String itsSource;
String itsSourceFile;
@ -130,7 +124,7 @@ class InterpreterData {
int itsMaxStack;
int itsMaxTryDepth;
java.util.Hashtable itsLineNumberTable;
UintMap itsLineNumberTable;
Object securityDomain;
}

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

@ -77,6 +77,18 @@ public class VariableTable {
return ((LocalVariable)(itsVariables.elementAt(index))).getName();
}
public String[] getAllNames() {
int N = size();
String[] result = null;
if (N != 0) {
result = new String[N];
for (int i = 0; i != N; i++) {
result[i] = getName(i);
}
}
return result;
}
public void establishIndices() {
for (int i = 0; i < itsVariables.size(); i++) {
LocalVariable lVar = (LocalVariable)(itsVariables.elementAt(i));

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

@ -65,11 +65,10 @@ public interface DebuggableScript {
public String getSourceName();
/**
* Get an enumeration containing the line numbers that
* Get array containing the line numbers that
* can have breakpoints placed on them.
* XXX - array?
*/
public Enumeration getLineNumbers();
public int[] getLineNumbers();
/**
* Place a breakpoint at the given line.

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

@ -631,14 +631,13 @@ class FindFunction extends JDialog implements ActionListener {
DebuggableScript script = sourceEntry.fnOrScript;
if(script != null) {
String sourceName = script.getSourceName();
Enumeration ee = script.getLineNumbers();
int[] lns = script.getLineNumbers();
int lineNumber = -1;
while(ee.hasMoreElements()) {
Integer ival = (Integer)ee.nextElement();
for (int i = 0; i != lns.length; ++i) {
if(lineNumber == -1) {
lineNumber = ival.intValue();
} else if(ival.intValue() < lineNumber) {
lineNumber = ival.intValue();
lineNumber = lns[i];
} else if(lns[i] < lineNumber) {
lineNumber = lns[i];
}
}