1 package org.metricshub.jawk.backend;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import java.util.ArrayDeque;
26 import java.util.Arrays;
27 import java.util.Deque;
28 import java.util.LinkedList;
29
30 import org.metricshub.jawk.intermediate.UninitializedObject;
31 import org.metricshub.jawk.jrt.AssocArray;
32
33
34
35
36 class RuntimeStack {
37
38 static final UninitializedObject BLANK = new UninitializedObject();
39
40 private Object[] globals = null;
41 private Object[] locals = null;
42 private Deque<Object[]> localsStack = new LinkedList<Object[]>();
43 private Deque<Integer> returnIndexes = new ArrayDeque<Integer>();
44
45 @SuppressWarnings("unused")
46 public void dump() {
47 System.out.println("globals = " + Arrays.toString(globals));
48 System.out.println("locals = " + Arrays.toString(locals));
49 System.out.println("localsStack = " + localsStack);
50 System.out.println("returnIndexes = " + returnIndexes);
51 }
52
53 Object[] getNumGlobals() {
54 return globals;
55 }
56
57
58 void setNumGlobals(long l) {
59 assert l >= 0;
60 assert globals == null;
61 globals = new Object[(int) l];
62 for (int i = 0; i < l; i++) {
63 globals[i] = null;
64 }
65
66
67 }
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 Object getVariable(long offset, boolean isGlobal) {
84 assert globals != null;
85 assert offset != AVM.NULL_OFFSET;
86 if (isGlobal) {
87 return globals[(int) offset];
88 } else {
89 return locals[(int) offset];
90 }
91 }
92
93 Object setVariable(long offset, Object val, boolean isGlobal) {
94 assert globals != null;
95 assert offset != AVM.NULL_OFFSET;
96 if (isGlobal) {
97 globals[(int) offset] = val;
98 return val;
99 } else {
100 locals[(int) offset] = val;
101 return val;
102 }
103 }
104
105
106 void removeVariable(long offset, boolean isGlobal) {
107 assert globals != null;
108 assert offset != AVM.NULL_OFFSET;
109 if (isGlobal) {
110 assert globals[(int) offset] == null || globals[(int) offset] instanceof AssocArray;
111 globals[(int) offset] = null;
112 } else {
113 assert locals[(int) offset] == null || locals[(int) offset] instanceof AssocArray;
114 locals[(int) offset] = null;
115 }
116 }
117
118 void setFilelistVariable(int offset, Object value) {
119 assert globals != null;
120 assert offset != AVM.NULL_OFFSET;
121 globals[offset] = value;
122 }
123
124 void pushFrame(long numFormalParams, int positionIdx) {
125 localsStack.push(locals);
126 locals = new Object[(int) numFormalParams];
127 returnIndexes.push(positionIdx);
128 }
129
130
131 int popFrame() {
132 locals = localsStack.pop();
133 return returnIndexes.pop();
134 }
135
136 void popAllFrames() {
137 for (int i = localsStack.size(); i > 0; i--) {
138 locals = localsStack.pop();
139 returnIndexes.pop();
140 }
141 }
142
143 private Object returnValue;
144
145 void setReturnValue(Object obj) {
146 assert returnValue == null;
147 returnValue = obj;
148 }
149
150 Object getReturnValue() {
151 Object retval;
152 if (returnValue == null) {
153 retval = BLANK;
154 } else {
155 retval = returnValue;
156 }
157 returnValue = null;
158 return retval;
159 }
160 }