001: /*
002: * $Id: StackFrame.java,v 1.19 2002/09/16 08:05:03 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.script;
011:
012: import anvil.Location;
013: import anvil.core.Any;
014: import anvil.core.AnyClass;
015: import anvil.core.Serializer;
016: import anvil.core.Unserializer;
017: import anvil.core.UnserializationException;
018: import anvil.server.Zone;
019: import java.util.Arrays;
020: import java.io.IOException;
021:
022: /**
023: * class StackFrame
024: * @author Jani Lehtimäki
025: */
026: public class StackFrame {
027:
028: protected Any[] _locals;
029: protected int _maxlocals;
030: protected Module _module;
031: protected AnyClass _self;
032: protected Function _function;
033: protected int _line;
034: protected Any[] _stack = null;
035: protected int _stackptr = 0;
036: protected Zone _zone = null;
037: protected boolean _escaped = false;
038: protected StackFrame _escape = null;
039:
040: private StackFrame() {
041: }
042:
043: public StackFrame(Module module, AnyClass self, Function function,
044: int maxLocals, int line, boolean escaped) {
045: init(module, self, function, maxLocals, line, escaped);
046: }
047:
048: public void init(Module module, AnyClass self, Function function,
049: int maxLocals, int line, boolean escaped) {
050: _module = module;
051: _self = self;
052: _function = function;
053: _line = line;
054: if (maxLocals > 0) {
055: if (_locals == null) {
056: _locals = new Any[maxLocals];
057: } else if (_locals.length < maxLocals) {
058: _locals = new Any[maxLocals];
059: }
060: java.util.Arrays.fill(_locals, 0, maxLocals, Any.UNDEFINED);
061: _maxlocals = maxLocals;
062: }
063: _escaped = escaped;
064: }
065:
066: public void clear() {
067: if (_locals != null) {
068: Arrays.fill(_locals, null);
069: }
070: _module = null;
071: _self = null;
072: _function = null;
073: _zone = null;
074: _stackptr = 0;
075: if (_stack != null) {
076: Arrays.fill(_stack, null);
077: }
078: }
079:
080: public void detach() {
081: _module = null;
082: _self = null;
083: _function = null;
084: _zone = null;
085: if (_stack != null) {
086: Arrays.fill(_stack, null);
087: _stack = null;
088: }
089: }
090:
091: public void destroy() {
092: _locals = null;
093: _module = null;
094: _self = null;
095: _function = null;
096: _zone = null;
097: _stackptr = 0;
098: _stack = null;
099: }
100:
101: public Function getFunction() {
102: return _function;
103: }
104:
105: public Any getLocal(int index) {
106: return _locals[index];
107: }
108:
109: public Any setLocal(int index, Any value) {
110: return _locals[index] = value;
111: }
112:
113: public Any getLocal(int depth, int index) {
114: StackFrame frame = _escape;
115: while (--depth > 0) {
116: frame = frame.getEscape();
117: }
118: return frame.getLocal(index);
119: }
120:
121: public Any setLocal(int depth, int index, Any value) {
122: StackFrame frame = _escape;
123: while (--depth > 0) {
124: frame = frame.getEscape();
125: }
126: return frame.setLocal(index, value);
127: }
128:
129: public Module getModule() {
130: return _module;
131: }
132:
133: public AnyClass getSelf() {
134: return _self;
135: }
136:
137: public String getPathinfo() {
138: return _module.getPathinfo();
139: }
140:
141: public int getLine() {
142: return _line;
143: }
144:
145: public void setLine(int line) {
146: _line = line;
147: }
148:
149: public void push(Any value) {
150: if (_stack == null) {
151: _stack = new Any[4];
152: }
153: if (_stackptr >= _stack.length) {
154: int len = _stack.length;
155: Any[] newstack = new Any[len + 4];
156: System.arraycopy(_stack, 0, newstack, 0, len);
157: _stack = newstack;
158: }
159: _stack[_stackptr++] = value;
160: }
161:
162: public Any pop() {
163: if (_stackptr > 0) {
164: return _stack[--_stackptr];
165: } else {
166: return Any.UNDEFINED;
167: }
168: }
169:
170: public Any peek() {
171: if (_stackptr > 0) {
172: return _stack[_stackptr - 1];
173: } else {
174: return Any.UNDEFINED;
175: }
176: }
177:
178: public Any peek(int pos) {
179: if (_stackptr - pos > 0) {
180: return _stack[_stackptr - 1 - pos];
181: } else {
182: return Any.UNDEFINED;
183: }
184: }
185:
186: public boolean isEscaped() {
187: return _escaped;
188: }
189:
190: public void setEscape(StackFrame escape) {
191: _escape = escape;
192: }
193:
194: public StackFrame getEscape() {
195: return _escape;
196: }
197:
198: public StackFrame getEscape(int depth) {
199: StackFrame frame = _escape;
200: while (--depth > 0) {
201: frame = frame.getEscape();
202: }
203: return frame;
204: }
205:
206: public Zone getZone() {
207: Zone zone = _zone;
208: if (zone == null) {
209: return _zone = _module.getAddress().getZone();
210: } else {
211: return zone;
212: }
213: }
214:
215: public void serialize(Serializer serializer) throws IOException {
216: if (serializer.register(this )) {
217: return;
218: }
219: int n = _maxlocals;
220: serializer.write('[');
221: if (_escape != null) {
222: _escape.serialize(serializer);
223: } else {
224: serializer.write('n');
225: }
226: serializer.write(n);
227: serializer.write(';');
228: for (int i = 0; i < n; i++) {
229: _locals[i].serialize(serializer);
230: }
231: serializer.write(']');
232: }
233:
234: public static final StackFrame unserialize(
235: Unserializer unserializer, Module module, AnyClass self,
236: Function function) throws UnserializationException {
237: Object obj = unserializer.consumeRegisteredIf();
238: if (obj != null) {
239: return (StackFrame) obj;
240: }
241: StackFrame frame = new StackFrame();
242: unserializer.register(frame);
243:
244: unserializer.consume('[');
245: StackFrame parent = null;
246: if (unserializer.peek() == 'n') {
247: unserializer.consume('n');
248: } else {
249: parent = unserialize(unserializer, module, self, function);
250: }
251: int size = (int) unserializer.getLong();
252: frame.init(module, self, function, size, 0, true);
253: frame.setEscape(parent);
254: for (int i = 0; i < size; i++) {
255: frame.setLocal(i, unserializer.unserialize());
256: }
257: unserializer.consume(']');
258: return frame;
259: }
260:
261: }
|