зеркало из https://github.com/mozilla/pjs.git
Subject:
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:
Родитель
6d0b3baa55
Коммит
c97a786c6e
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче