зеркало из https://github.com/mozilla/pjs.git
Changes for try/catch handling
This commit is contained in:
Родитель
66078d249d
Коммит
f5deb2638e
|
@ -1,31 +0,0 @@
|
|||
public class Interpreter {
|
||||
|
||||
|
||||
void executeScript(Node node)
|
||||
{
|
||||
Node child = node.getFirstChild();
|
||||
while (child != null) {
|
||||
if (child.getType() != TokenStream.FUNCTION)
|
||||
executeCode(child);
|
||||
child = child.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
void executeCode(Node top)
|
||||
{
|
||||
PostorderNodeIterator ni = new PostorderNodeIterator(top);
|
||||
|
||||
JSStack theStack = new JSStack();
|
||||
|
||||
Node n = ni.nextNode();
|
||||
while (n != null) {
|
||||
ni = n.execute(theStack, ni);
|
||||
n = ni.nextNode();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -2,12 +2,33 @@
|
|||
import java.util.Stack;
|
||||
|
||||
class JSStack {
|
||||
|
||||
|
||||
Stack stack = new Stack();
|
||||
|
||||
void push(StackValue value)
|
||||
int frameTop;
|
||||
|
||||
void newFrame(StackValue returnAddress)
|
||||
{
|
||||
stack.push(value);
|
||||
stack.push(returnAddress);
|
||||
stack.push(new StackValue(frameTop));
|
||||
frameTop = stack.size();
|
||||
}
|
||||
|
||||
StackValue popFrame()
|
||||
{
|
||||
stack.setSize(frameTop);
|
||||
StackValue oldFrame = (StackValue)(stack.pop());
|
||||
frameTop = oldFrame.i;
|
||||
return (StackValue)stack.pop();
|
||||
}
|
||||
|
||||
void push(StackValue v)
|
||||
{
|
||||
stack.push(v);
|
||||
}
|
||||
|
||||
boolean isEmpty()
|
||||
{
|
||||
return stack.isEmpty();
|
||||
}
|
||||
|
||||
StackValue pop()
|
||||
|
|
|
@ -1,473 +0,0 @@
|
|||
/* -*- Mode: java; tab-width: 8 -*-
|
||||
* Copyright © 1997, 1998 Netscape Communications Corporation,
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This class implements the root of the intermediate representation.
|
||||
*
|
||||
* @author Norris Boyd
|
||||
* @author Mike McCabe
|
||||
*/
|
||||
|
||||
public class Node implements Cloneable {
|
||||
|
||||
public Node(int nodeType) {
|
||||
type = nodeType;
|
||||
}
|
||||
|
||||
public Node(int nodeType, Node child) {
|
||||
type = nodeType;
|
||||
first = last = child;
|
||||
child.next = null;
|
||||
}
|
||||
|
||||
public Node(int nodeType, Node left, Node right) {
|
||||
type = nodeType;
|
||||
first = left;
|
||||
last = right;
|
||||
left.next = right;
|
||||
right.next = null;
|
||||
}
|
||||
|
||||
public Node(int nodeType, Node left, Node mid, Node right) {
|
||||
type = nodeType;
|
||||
first = left;
|
||||
last = right;
|
||||
left.next = mid;
|
||||
mid.next = right;
|
||||
right.next = null;
|
||||
}
|
||||
|
||||
public Node(int nodeType, Object datum) {
|
||||
type = nodeType;
|
||||
this.datum = datum;
|
||||
}
|
||||
|
||||
public Node(int nodeType, Node child, Object datum) {
|
||||
this(nodeType, child);
|
||||
this.datum = datum;
|
||||
}
|
||||
|
||||
public Node(int nodeType, Node left, Node right, Object datum) {
|
||||
this(nodeType, left, right);
|
||||
this.datum = datum;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public boolean hasChildren() {
|
||||
return first != null;
|
||||
}
|
||||
|
||||
public Node getFirstChild() {
|
||||
return first;
|
||||
}
|
||||
|
||||
public Node getLastChild() {
|
||||
return last;
|
||||
}
|
||||
|
||||
public Node getNextSibling() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public Node getChildBefore(Node child) {
|
||||
if (child == first)
|
||||
return null;
|
||||
Node n = first;
|
||||
while (n.next != child) {
|
||||
n = n.next;
|
||||
if (n == null)
|
||||
throw new RuntimeException("node is not a child");
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public Node getLastSibling() {
|
||||
Node n = this;
|
||||
while (n.next != null) {
|
||||
n = n.next;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public ShallowNodeIterator getChildIterator() {
|
||||
return new ShallowNodeIterator(first);
|
||||
}
|
||||
|
||||
public PreorderNodeIterator getPreorderIterator() {
|
||||
return new PreorderNodeIterator(this);
|
||||
}
|
||||
|
||||
public void addChildToFront(Node child) {
|
||||
child.next = first;
|
||||
first = child;
|
||||
if (last == null) {
|
||||
last = child;
|
||||
}
|
||||
}
|
||||
|
||||
public void addChildToBack(Node child) {
|
||||
child.next = null;
|
||||
if (last == null) {
|
||||
first = last = child;
|
||||
return;
|
||||
}
|
||||
last.next = child;
|
||||
last = child;
|
||||
}
|
||||
|
||||
public void addChildrenToFront(Node children) {
|
||||
Node lastSib = children.getLastSibling();
|
||||
lastSib.next = first;
|
||||
first = children;
|
||||
if (last == null) {
|
||||
last = lastSib;
|
||||
}
|
||||
}
|
||||
|
||||
public void addChildrenToBack(Node children) {
|
||||
if (last != null) {
|
||||
last.next = children;
|
||||
}
|
||||
last = children.getLastSibling();
|
||||
if (first == null) {
|
||||
first = children;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'child' before 'node'.
|
||||
*/
|
||||
public void addChildBefore(Node newChild, Node node) {
|
||||
if (newChild.next != null)
|
||||
throw new RuntimeException(
|
||||
"newChild had siblings in addChildBefore");
|
||||
if (first == node) {
|
||||
newChild.next = first;
|
||||
first = newChild;
|
||||
return;
|
||||
}
|
||||
Node prev = getChildBefore(node);
|
||||
addChildAfter(newChild, prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'child' after 'node'.
|
||||
*/
|
||||
public void addChildAfter(Node newChild, Node node) {
|
||||
if (newChild.next != null)
|
||||
throw new RuntimeException(
|
||||
"newChild had siblings in addChildAfter");
|
||||
newChild.next = node.next;
|
||||
node.next = newChild;
|
||||
if (last == node)
|
||||
last = newChild;
|
||||
}
|
||||
|
||||
public void removeChild(Node child) {
|
||||
Node prev = getChildBefore(child);
|
||||
if (prev == null)
|
||||
first = first.next;
|
||||
else
|
||||
prev.next = child.next;
|
||||
if (child == last) last = prev;
|
||||
child.next = null;
|
||||
}
|
||||
|
||||
public void replaceChild(Node child, Node newChild) {
|
||||
newChild.next = child.next;
|
||||
if (child == first) {
|
||||
first = newChild;
|
||||
} else {
|
||||
Node prev = getChildBefore(child);
|
||||
prev.next = newChild;
|
||||
}
|
||||
if (child == last)
|
||||
last = newChild;
|
||||
child.next = null;
|
||||
}
|
||||
|
||||
public static final int
|
||||
TARGET_PROP = 1,
|
||||
BREAK_PROP = 2,
|
||||
CONTINUE_PROP = 3,
|
||||
ENUM_PROP = 4,
|
||||
FUNCTION_PROP = 5,
|
||||
TEMP_PROP = 6,
|
||||
LOCAL_PROP = 7,
|
||||
CODEOFFSET_PROP = 8,
|
||||
FIXUPS_PROP = 9,
|
||||
VARS_PROP = 10,
|
||||
USES_PROP = 11,
|
||||
REGEXP_PROP = 12,
|
||||
CASES_PROP = 13,
|
||||
DEFAULT_PROP = 14,
|
||||
CASEARRAY_PROP = 15,
|
||||
SOURCENAME_PROP = 16,
|
||||
SOURCE_PROP = 17,
|
||||
TYPE_PROP = 18,
|
||||
SPECIAL_PROP_PROP = 19,
|
||||
LABEL_PROP = 20,
|
||||
FINALLY_PROP = 21,
|
||||
LOCALCOUNT_PROP = 22,
|
||||
/*
|
||||
the following properties are defined and manipulated by the
|
||||
optimizer -
|
||||
TARGETBLOCK_PROP - the block referenced by a branch node
|
||||
VARIABLE_PROP - the variable referenced by a BIND or NAME node
|
||||
LASTUSE_PROP - that variable node is the last reference before
|
||||
a new def or the end of the block
|
||||
ISNUMBER_PROP - this node generates code on Number children and
|
||||
delivers a Number result (as opposed to Objects)
|
||||
DIRECTCALL_PROP - this call node should emit code to test the function
|
||||
object against the known class and call diret if it
|
||||
matches.
|
||||
*/
|
||||
|
||||
TARGETBLOCK_PROP = 23,
|
||||
VARIABLE_PROP = 24,
|
||||
LASTUSE_PROP = 25,
|
||||
ISNUMBER_PROP = 26,
|
||||
DIRECTCALL_PROP = 27,
|
||||
|
||||
BASE_LINENO_PROP = 28,
|
||||
END_LINENO_PROP = 29,
|
||||
SPECIALCALL_PROP = 30;
|
||||
|
||||
public static final int // this value of the ISNUMBER_PROP specifies
|
||||
BOTH = 0, // which of the children are Number types
|
||||
LEFT = 1,
|
||||
RIGHT = 2;
|
||||
|
||||
private static String propNames[];
|
||||
|
||||
private static final String propToString(int propType) {
|
||||
if (Context.printTrees && propNames == null) {
|
||||
// If Context.printTrees is false, the compiler
|
||||
// can remove all these strings.
|
||||
String[] a = {
|
||||
"TARGET",
|
||||
"BREAK",
|
||||
"CONTINUE",
|
||||
"ENUM",
|
||||
"FUNCTION",
|
||||
"TEMP",
|
||||
"LOCAL",
|
||||
"CODEOFFSET",
|
||||
"FIXUPS",
|
||||
"VARS",
|
||||
"USES",
|
||||
"REGEXP",
|
||||
"SWITCHES",
|
||||
"CASES",
|
||||
"DEFAULT",
|
||||
"CASEARRAY",
|
||||
"SOURCENAME",
|
||||
"SOURCE",
|
||||
"TYPE",
|
||||
"SPECIAL_PROP",
|
||||
"LABEL",
|
||||
"FINALLY",
|
||||
"LOCALCOUNT",
|
||||
"TARGETBLOCK",
|
||||
"VARIABLE",
|
||||
"LASTUSE",
|
||||
"ISNUMBER",
|
||||
"DIRECTCALL",
|
||||
"BASE_LINENO",
|
||||
"END_LINENO",
|
||||
"SPECIALCALL"
|
||||
};
|
||||
propNames = a;
|
||||
}
|
||||
return propNames[propType];
|
||||
}
|
||||
|
||||
public Object getProp(int propType) {
|
||||
if (props == null)
|
||||
return null;
|
||||
return props.get(new Integer(propType));
|
||||
}
|
||||
|
||||
public void putProp(int propType, Object prop) {
|
||||
if (props == null)
|
||||
props = new Hashtable(2);
|
||||
if (prop == null)
|
||||
props.remove(new Integer(propType));
|
||||
else
|
||||
props.put(new Integer(propType), prop);
|
||||
}
|
||||
|
||||
public Object getDatum() {
|
||||
return datum;
|
||||
}
|
||||
|
||||
public void setDatum(Object datum) {
|
||||
this.datum = datum;
|
||||
}
|
||||
|
||||
public int getInt() {
|
||||
return ((Number) datum).intValue();
|
||||
}
|
||||
|
||||
public double getDouble() {
|
||||
return ((Number) datum).doubleValue();
|
||||
}
|
||||
|
||||
public long getLong() {
|
||||
return ((Number) datum).longValue();
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
return (String) datum;
|
||||
}
|
||||
|
||||
public Node cloneNode() {
|
||||
Node result;
|
||||
try {
|
||||
result = (Node) super.clone();
|
||||
result.next = null;
|
||||
result.first = null;
|
||||
result.last = null;
|
||||
}
|
||||
catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (Context.printTrees) {
|
||||
StringBuffer sb = new StringBuffer(TokenStream.tokenToName(type));
|
||||
if (type == TokenStream.TARGET) {
|
||||
sb.append(" ");
|
||||
sb.append(hashCode());
|
||||
}
|
||||
if (datum != null) {
|
||||
sb.append(' ');
|
||||
sb.append(datum.toString());
|
||||
}
|
||||
if (props == null)
|
||||
return sb.toString();
|
||||
|
||||
Enumeration keys = props.keys();
|
||||
Enumeration elems = props.elements();
|
||||
while (keys.hasMoreElements()) {
|
||||
Integer key = (Integer) keys.nextElement();
|
||||
Object elem = elems.nextElement();
|
||||
sb.append(" [");
|
||||
sb.append(propToString(key.intValue()));
|
||||
sb.append(": ");
|
||||
switch (key.intValue()) {
|
||||
case FIXUPS_PROP : // can't add this as it recurses
|
||||
sb.append("fixups property");
|
||||
break;
|
||||
case SOURCE_PROP : // can't add this as it has unprintables
|
||||
sb.append("source property");
|
||||
break;
|
||||
case TARGETBLOCK_PROP : // can't add this as it recurses
|
||||
sb.append("target block property");
|
||||
break;
|
||||
case LASTUSE_PROP : // can't add this as it is dull
|
||||
sb.append("last use property");
|
||||
break;
|
||||
default :
|
||||
sb.append(elem.toString());
|
||||
break;
|
||||
}
|
||||
sb.append("]");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toStringTree() {
|
||||
return toStringTreeHelper(0);
|
||||
}
|
||||
|
||||
|
||||
private String toStringTreeHelper(int level) {
|
||||
if (Context.printTrees) {
|
||||
StringBuffer s = new StringBuffer();
|
||||
for (int i=0; i < level; i++) {
|
||||
s.append(" ");
|
||||
}
|
||||
s.append(toString());
|
||||
s.append('\n');
|
||||
ShallowNodeIterator iterator = getChildIterator();
|
||||
if (iterator != null) {
|
||||
while (iterator.hasMoreElements()) {
|
||||
Node n = (Node) iterator.nextElement();
|
||||
if (n.getType() == TokenStream.FUNCTION) {
|
||||
Node p = (Node) n.getProp(Node.FUNCTION_PROP);
|
||||
if (p != null)
|
||||
n = p;
|
||||
}
|
||||
s.append(n.toStringTreeHelper(level+1));
|
||||
}
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
PostorderNodeIterator execute(JSStack theStack, PostorderNodeIterator ni)
|
||||
{
|
||||
StackValue lhs;
|
||||
StackValue rhs;
|
||||
Number num;
|
||||
|
||||
switch (type) {
|
||||
|
||||
case TokenStream.NUMBER :
|
||||
num = (Number)getDatum();
|
||||
System.out.println("number " + num.doubleValue());
|
||||
return ni;
|
||||
|
||||
case TokenStream.SETNAME :
|
||||
System.out.println("setname");
|
||||
return ni;
|
||||
|
||||
case TokenStream.BINDNAME :
|
||||
System.out.println("name " + getString());
|
||||
return ni;
|
||||
|
||||
case TokenStream.ADD :
|
||||
rhs = theStack.pop();
|
||||
lhs = theStack.pop();
|
||||
theStack.push(new StackValue(lhs.dbl + rhs.dbl));
|
||||
return ni;
|
||||
|
||||
}
|
||||
|
||||
return ni;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************/
|
||||
|
||||
|
||||
public Node getFirst() { return first; }
|
||||
public Node getNext() { return next; }
|
||||
|
||||
protected int type; // type of the node; TokenStream.NAME for example
|
||||
protected Node next; // next sibling
|
||||
protected Node first; // first element of a linked list of children
|
||||
protected Node last; // last element of a linked list of children
|
||||
protected Hashtable props;
|
||||
protected Object datum; // encapsulated data; depends on type
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
|
||||
import java.util.Stack;
|
||||
|
||||
class PostorderNodeIterator {
|
||||
|
||||
PostorderNodeIterator(Node n)
|
||||
{
|
||||
stack = new Stack();
|
||||
while (n.first != null) {
|
||||
stack.push(n);
|
||||
n = n.first;
|
||||
}
|
||||
start = n;
|
||||
}
|
||||
|
||||
Node nextNode()
|
||||
{
|
||||
if (current == null)
|
||||
return current = start;
|
||||
|
||||
if (stack.isEmpty())
|
||||
return null;
|
||||
else {
|
||||
current = current.next;
|
||||
if (current != null) {
|
||||
while (current.first != null) {
|
||||
stack.push(current);
|
||||
current = current.first;
|
||||
}
|
||||
}
|
||||
else
|
||||
current = (Node)stack.pop();
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
Node start;
|
||||
Node current;
|
||||
Stack stack;
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
class StackValue {
|
||||
|
||||
StackValue(double d)
|
||||
{
|
||||
dbl = d;
|
||||
}
|
||||
|
||||
double dbl;
|
||||
|
||||
|
||||
}
|
Загрузка…
Ссылка в новой задаче