comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java @ 9258:07f8d136a05e

Truffle API changes for the Frame API. Introduction of Assumptions class.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 23 Apr 2013 15:34:06 +0200
parents 645f216a00c4
children 8cf939b349dd
comparison
equal deleted inserted replaced
9257:542712a4732a 9258:07f8d136a05e
27 import com.oracle.truffle.api.*; 27 import com.oracle.truffle.api.*;
28 import com.oracle.truffle.api.frame.*; 28 import com.oracle.truffle.api.frame.*;
29 29
30 public final class DefaultVirtualFrame implements VirtualFrame { 30 public final class DefaultVirtualFrame implements VirtualFrame {
31 31
32 private static final Object UNDEFINED_OBJECT = null;
33 private static final Boolean UNDEFINED_BOOLEAN = false;
34 private static final Integer UNDEFINED_INTEGER = 0;
35 private static final Float UNDEFINED_FLOAT = 0.0f;
36 private static final Long UNDEFINED_LONG = 0L;
37 private static final Double UNDEFINED_DOUBLE = 0.0d;
38
39 private final FrameDescriptor descriptor; 32 private final FrameDescriptor descriptor;
40 private final PackedFrame caller; 33 private final PackedFrame caller;
41 private final Arguments arguments; 34 private final Arguments arguments;
42 private FrameVersion currentVersion; 35 private Object[] locals;
43 protected Object[] locals; 36 private Class[] tags;
44 protected Class[] tags;
45 37
46 public DefaultVirtualFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments arguments) { 38 public DefaultVirtualFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments arguments) {
47 this.descriptor = descriptor; 39 this.descriptor = descriptor;
48 this.caller = caller; 40 this.caller = caller;
49 this.arguments = arguments; 41 this.arguments = arguments;
50 this.currentVersion = descriptor.getCurrentVersion();
51 this.locals = new Object[descriptor.getSize()]; 42 this.locals = new Object[descriptor.getSize()];
52 // The tags are only needed for assertion checking, so initialize the field only when 43 this.tags = new Class[descriptor.getSize()];
53 // assertions are enabled
54 assert (this.tags = new Class[descriptor.getSize()]) != null;
55 } 44 }
56 45
57 @Override 46 @Override
58 public Arguments getArguments() { 47 public Arguments getArguments() {
59 return arguments; 48 return arguments;
73 public MaterializedFrame materialize() { 62 public MaterializedFrame materialize() {
74 return new DefaultMaterializedFrame(this); 63 return new DefaultMaterializedFrame(this);
75 } 64 }
76 65
77 @Override 66 @Override
78 public Object getObject(FrameSlot slot) { 67 public Object getObject(FrameSlot slot) throws FrameSlotTypeException {
79 return get(slot, Object.class, UNDEFINED_OBJECT); 68 verifyGet(slot, Object.class);
80 } 69 return locals[slot.getIndex()];
81 70 }
82 @Override 71
83 public void setObject(FrameSlot slot, Object value) { 72 @Override
84 set(slot, Object.class, value); 73 public void setObject(FrameSlot slot, Object value) throws FrameSlotTypeException {
85 } 74 verifySet(slot, Object.class);
86 75 locals[slot.getIndex()] = value;
87 @Override 76 }
88 public boolean getBoolean(FrameSlot slot) { 77
89 return (Boolean) get(slot, Boolean.class, UNDEFINED_BOOLEAN); 78 @Override
90 } 79 public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException {
91 80 verifyGet(slot, boolean.class);
92 @Override 81 return (boolean) locals[slot.getIndex()];
93 public void setBoolean(FrameSlot slot, boolean value) { 82 }
94 set(slot, Boolean.class, value); 83
95 } 84 @Override
96 85 public void setBoolean(FrameSlot slot, boolean value) throws FrameSlotTypeException {
97 @Override 86 verifySet(slot, boolean.class);
98 public int getInt(FrameSlot slot) { 87 locals[slot.getIndex()] = value;
99 return (Integer) get(slot, Integer.class, UNDEFINED_INTEGER); 88 }
100 } 89
101 90 @Override
102 @Override 91 public int getInt(FrameSlot slot) throws FrameSlotTypeException {
103 public void setInt(FrameSlot slot, int value) { 92 verifyGet(slot, int.class);
104 set(slot, Integer.class, value); 93 return (int) locals[slot.getIndex()];
105 } 94 }
106 95
107 @Override 96 @Override
108 public long getLong(FrameSlot slot) { 97 public void setInt(FrameSlot slot, int value) throws FrameSlotTypeException {
109 return (Long) get(slot, Long.class, UNDEFINED_LONG); 98 verifySet(slot, int.class);
110 } 99 locals[slot.getIndex()] = value;
111 100 }
112 @Override 101
113 public void setLong(FrameSlot slot, long value) { 102 @Override
114 set(slot, Long.class, value); 103 public long getLong(FrameSlot slot) throws FrameSlotTypeException {
115 } 104 verifyGet(slot, long.class);
116 105 return (long) locals[slot.getIndex()];
117 @Override 106 }
118 public float getFloat(FrameSlot slot) { 107
119 return (Float) get(slot, Float.class, UNDEFINED_FLOAT); 108 @Override
120 } 109 public void setLong(FrameSlot slot, long value) throws FrameSlotTypeException {
121 110 verifySet(slot, long.class);
122 @Override 111 locals[slot.getIndex()] = value;
123 public void setFloat(FrameSlot slot, float value) { 112 }
124 set(slot, Float.class, value); 113
125 } 114 @Override
126 115 public float getFloat(FrameSlot slot) throws FrameSlotTypeException {
127 @Override 116 verifyGet(slot, float.class);
128 public double getDouble(FrameSlot slot) { 117 return (float) locals[slot.getIndex()];
129 return (Double) get(slot, Double.class, UNDEFINED_DOUBLE); 118 }
130 } 119
131 120 @Override
132 @Override 121 public void setFloat(FrameSlot slot, float value) throws FrameSlotTypeException {
133 public void setDouble(FrameSlot slot, double value) { 122 verifySet(slot, float.class);
134 set(slot, Double.class, value); 123 locals[slot.getIndex()] = value;
135 } 124 }
136 125
137 private Object get(FrameSlot slot, Class<?> accessType, Object defaultValue) { 126 @Override
138 Object value = locals[slot.getIndex()]; 127 public double getDouble(FrameSlot slot) throws FrameSlotTypeException {
139 assert verifyGet(slot, accessType, value); 128 verifyGet(slot, double.class);
140 if (value == null) { 129 return (double) locals[slot.getIndex()];
141 return defaultValue; 130 }
142 } else { 131
143 return value; 132 @Override
144 } 133 public void setDouble(FrameSlot slot, double value) throws FrameSlotTypeException {
145 } 134 verifySet(slot, double.class);
146 135 locals[slot.getIndex()] = value;
147 private boolean verifyGet(FrameSlot slot, Class<?> accessType, Object value) {
148 assert descriptor.getSlots().get(slot.getIndex()) == slot;
149 Class<?> tag = tags[slot.getIndex()];
150 if (value == null) {
151 assert tag == null || tag == Object.class;
152 } else {
153 assert tag == accessType : "Local variable " + slot + " was written with set" + tag.getSimpleName() + ", but is read with get" + accessType.getSimpleName();
154 }
155 return true;
156 }
157
158 private void set(FrameSlot slot, Class<?> accessType, Object value) {
159 assert verifySet(slot, accessType, value);
160 locals[slot.getIndex()] = value;
161 }
162
163 private boolean verifySet(FrameSlot slot, Class<?> accessType, Object value) {
164 assert descriptor.getSlots().get(slot.getIndex()) == slot;
165 tags[slot.getIndex()] = accessType;
166 assert accessType.isAssignableFrom(slot.getType()) : "Local variable " + slot + ": " + accessType + " is not assignable from " + slot.getType();
167 if (value == null) {
168 assert accessType == Object.class;
169 } else {
170 assert slot.getType().isAssignableFrom(value.getClass()) : "Local variable " + slot + ": " + slot.getType() + " is not assignable from " + value.getClass();
171 }
172 return true;
173 }
174
175 @Override
176 public void updateToLatestVersion() {
177 if (currentVersion.getNext() != null) {
178 doUpdateToLatestVersion();
179 }
180 }
181
182 private void doUpdateToLatestVersion() {
183 FrameVersion version = currentVersion;
184 while (version.getNext() != null) {
185 version = version.getNext();
186 if (version instanceof FrameVersion.TypeChange) {
187 ((FrameVersion.TypeChange) version).applyTransformation(this);
188 } else if (version instanceof FrameVersion.Resize) {
189 int newSize = ((FrameVersion.Resize) version).getNewSize();
190 locals = Arrays.copyOf(locals, newSize);
191 }
192 }
193 currentVersion = version;
194 } 136 }
195 137
196 @Override 138 @Override
197 public FrameDescriptor getFrameDescriptor() { 139 public FrameDescriptor getFrameDescriptor() {
198 return this.descriptor; 140 return this.descriptor;
199 } 141 }
142
143 @Override
144 public Object getValue(FrameSlot slot) {
145 int index = slot.getIndex();
146 if (index >= tags.length) {
147 assert index >= 0 && index < descriptor.getSize();
148 return descriptor.getTypeConversion().getDefaultValue();
149 }
150 Class tag = tags[index];
151 if (tag == null) {
152 return descriptor.getTypeConversion().getDefaultValue();
153 } else {
154 return locals[index];
155 }
156 }
157
158 private void verifySet(FrameSlot slot, Class accessType) throws FrameSlotTypeException {
159 if (slot.getType() != accessType) {
160 throw new FrameSlotTypeException();
161 }
162 int slotIndex = slot.getIndex();
163 if (slotIndex >= tags.length) {
164 resize();
165 }
166 tags[slotIndex] = accessType;
167 }
168
169 private void verifyGet(FrameSlot slot, Class accessType) throws FrameSlotTypeException {
170 Class<?> slotType = slot.getType();
171 int slotIndex = slot.getIndex();
172 if (slotType != accessType) {
173 if (slotType == null) {
174 slot.setType(Object.class);
175 this.setObject(slot, descriptor.getTypeConversion().getDefaultValue());
176 if (accessType != Object.class) {
177 throw new FrameSlotTypeException();
178 }
179 } else {
180 throw new FrameSlotTypeException();
181 }
182 }
183 if (slotIndex >= tags.length) {
184 resize();
185 }
186 Class tag = tags[slotIndex];
187 if (tag != slotType) {
188 descriptor.getTypeConversion().updateFrameSlot(this, slot, getValue(slot));
189 if (tags[slotIndex] != slotType) {
190 throw new FrameSlotTypeException();
191 }
192 }
193 }
194
195 private void resize() {
196 int newSize = descriptor.getSize();
197 if (newSize > tags.length) {
198 locals = Arrays.copyOf(locals, newSize);
199 tags = Arrays.copyOf(tags, newSize);
200 }
201 }
200 } 202 }