Repository navigation
Expand file tree
/
Copy pathExecutionFrame.java
More file actions
181 lines (156 loc) · 6.16 KB
/
Copy pathExecutionFrame.java
File metadata and controls
181 lines (156 loc) · 6.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
* Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
*
* Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
* that is described in this document. In particular, and without limitation, these intellectual property
* rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
* more additional patents or pending patent applications in the U.S. and in other countries.
*
* U.S. Government Rights - Commercial software. Government users are subject to the Sun
* Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
* supplements.
*
* Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
* registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
* are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
* U.S. and other countries.
*
* UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
* Company, Ltd.
*/
package com.sun.max.tele.interpreter;
import java.util.*;
import com.sun.max.vm.actor.holder.*;
import com.sun.max.vm.actor.member.*;
import com.sun.max.vm.classfile.*;
import com.sun.max.vm.classfile.constant.*;
import com.sun.max.vm.value.*;
/**
* Instances of this class represent individual execution frame entries on a given ExecutionThread's execution stack.
*
* @author Athul Acharya
*/
class ExecutionFrame {
private final ClassMethodActor method;
private int currentOpcodePosition;
private int currentBytePosition;
private final Value[] locals;
private final Stack<Value> operands;
private final ExecutionFrame callersFrame;
private final byte[] code;
private final int depth;
public ExecutionFrame(ExecutionFrame callersFrame, ClassMethodActor method) {
this.method = method;
this.locals = new Value[method.codeAttribute().maxLocals];
this.operands = new Stack<Value>();
this.callersFrame = callersFrame;
this.code = method.codeAttribute().code();
this.depth = callersFrame == null ? 1 : callersFrame.depth + 1;
}
/**
* Computes the number of frames on the call stack up to and including this frame.
*/
public int depth() {
return depth;
}
public ExecutionFrame callersFrame() {
return callersFrame;
}
public void setLocal(int index, Value value) {
locals[index] = value;
}
public int readOpcode() {
currentOpcodePosition = currentBytePosition;
return readByte() & 0xff;
}
public byte readByte() {
try {
return code[currentBytePosition++];
} catch (ArrayIndexOutOfBoundsException arrayIndexOutOfBoundsException) {
throw new VerifyError("Ran off end of code");
}
}
public short readShort() {
final int high = readByte();
final int low = readByte() & 0xff;
return (short) ((high << 8) | low);
}
public int readInt() {
final int b3 = readByte() << 24;
final int b2 = (readByte() & 0xff) << 16;
final int b1 = (readByte() & 0xff) << 8;
final int b0 = readByte() & 0xff;
return b3 | b2 | b1 | b0;
}
public void skipBytes(int n) {
currentBytePosition += n;
}
public void alignInstructionPosition() {
final int remainder = currentBytePosition % 4;
if (remainder != 0) {
currentBytePosition += 4 - remainder;
}
}
public void jump(int offset) {
currentBytePosition = currentOpcodePosition + offset;
}
public int currentOpcodePosition() {
return currentOpcodePosition;
}
public int currentBytePosition() {
return currentBytePosition;
}
public void setBytecodePosition(int bcp) {
currentBytePosition = bcp;
}
public byte[] code() {
return code;
}
public Value getLocal(int index) {
return locals[index];
}
public Stack<Value> stack() {
return operands;
}
public ConstantPool constantPool() {
return method.codeAttribute().constantPool;
}
public ClassMethodActor method() {
return method;
}
@Override
public String toString() {
return method.format("%H.%n(%p) @ " + currentBytePosition);
}
/**
* Handles an exception at the current execution point in this frame by updating the {@linkplain #setBytecodePosition(int)
* instruction pointer} to the matching exception handler in this frame. If no matching exception handler is found
* for the current execution point and the given exception type, then the instruction pointer in this frame is left
* unmodified.
* <p>
* The current execution point is derived from the value of {@link ExecutionFrame#currentBytePosition()} which is now at the first
* byte passed the instruction currently being executed. That is, an instruction is completely decoded before any
* exceptions are thrown while executing it.
*
* @param throwableClassActor the type of the exception being thrown
* @return {@code true} if an exception handler was found, {@code false} otherwise
*/
public boolean handleException(ClassActor throwableClassActor) {
final int bcp = currentOpcodePosition;
final ExceptionHandlerEntry[] handlers = method().codeAttribute().exceptionHandlerTable();
for (ExceptionHandlerEntry handler : handlers) {
if (bcp >= handler.startPosition() && bcp < handler.endPosition()) {
if (handler.catchTypeIndex() == 0) {
currentBytePosition = handler.handlerPosition();
return true;
}
final ClassActor catchType = constantPool().classAt(handler.catchTypeIndex()).resolve(constantPool(), handler.catchTypeIndex());
if (catchType.isAssignableFrom(throwableClassActor)) {
currentBytePosition = handler.handlerPosition();
return true;
}
}
}
return false;
}
}