Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyImpl.java @ 18408:2c3666f44855
Truffle: initial commit of object API implementation
author | Andreas Woess <andreas.woess@jku.at> |
---|---|
date | Tue, 18 Nov 2014 23:19:43 +0100 |
parents | |
children | de8880bbf2e1 |
comparison
equal
deleted
inserted
replaced
18407:f439fdb137a3 | 18408:2c3666f44855 |
---|---|
1 /* | |
2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.oracle.truffle.object; | |
24 | |
25 import java.util.*; | |
26 | |
27 import com.oracle.truffle.api.object.*; | |
28 import com.oracle.truffle.object.Locations.*; | |
29 | |
30 /** | |
31 * Property objects represent the mapping between low-level stores and high-level data. The simplest | |
32 * Property could be nothing more than a map of one index to one property's value, but abstracting | |
33 * the interface allows for getter/setter methods, type-checked properties, and other such | |
34 * specialized and language-specific behavior. ECMAScript[8.6.1] | |
35 */ | |
36 public class PropertyImpl extends Property { | |
37 private final Object key; | |
38 private final Location location; | |
39 private final int flags; | |
40 private final boolean shadow; | |
41 private final boolean relocatable; | |
42 | |
43 /** | |
44 * Generic, usual-case constructor for properties storing at least a name. | |
45 * | |
46 * @param key the name of the property | |
47 */ | |
48 protected PropertyImpl(Object key, Location location, int flags, boolean shadow, boolean relocatable) { | |
49 this.key = Objects.requireNonNull(key); | |
50 this.location = Objects.requireNonNull(location); | |
51 this.flags = flags; | |
52 this.shadow = shadow; | |
53 this.relocatable = relocatable; | |
54 } | |
55 | |
56 public PropertyImpl(Object name, Location location, int flags) { | |
57 this(name, location, flags, false, true); | |
58 } | |
59 | |
60 @Override | |
61 public final Object getKey() { | |
62 return key; | |
63 } | |
64 | |
65 @Override | |
66 public int getFlags() { | |
67 return flags; | |
68 } | |
69 | |
70 @Override | |
71 public Property relocate(Location newLocation) { | |
72 if ((getLocation() == null || !getLocation().equals(newLocation)) && relocatable) { | |
73 return construct(getKey(), newLocation, getFlags()); | |
74 } | |
75 return this; | |
76 } | |
77 | |
78 @Override | |
79 public final Object get(DynamicObject store, Shape shape) { | |
80 return getLocation().get(store, shape); | |
81 } | |
82 | |
83 @Override | |
84 public final Object get(DynamicObject store, boolean condition) { | |
85 return getLocation().get(store, condition); | |
86 } | |
87 | |
88 @Override | |
89 public final void setInternal(DynamicObject store, Object value) { | |
90 try { | |
91 ((LocationImpl) getLocation()).setInternal(store, value); | |
92 } catch (IncompatibleLocationException e) { | |
93 throw new IllegalStateException(); | |
94 } | |
95 } | |
96 | |
97 @Override | |
98 public final void set(DynamicObject store, Object value, Shape shape) throws IncompatibleLocationException, FinalLocationException { | |
99 assert shape == null || store.getShape() == shape : "wrong shape"; | |
100 getLocation().set(store, value, shape); | |
101 } | |
102 | |
103 @Override | |
104 public final void setSafe(DynamicObject store, Object value, Shape shape) { | |
105 assert shape == null || store.getShape() == shape : "wrong shape"; | |
106 try { | |
107 getLocation().set(store, value, shape); | |
108 } catch (IncompatibleLocationException | FinalLocationException ex) { | |
109 throw new IllegalStateException(); | |
110 } | |
111 } | |
112 | |
113 @Override | |
114 public final void setGeneric(DynamicObject store, Object value, Shape shape) { | |
115 assert shape == null || store.getShape() == shape : "wrong shape"; | |
116 try { | |
117 set(store, value, shape); | |
118 } catch (IncompatibleLocationException | FinalLocationException ex) { | |
119 setSlowCase(store, value); | |
120 } | |
121 } | |
122 | |
123 @Override | |
124 public final void set(DynamicObject store, Object value, Shape oldShape, Shape newShape) throws IncompatibleLocationException { | |
125 assert store.getShape() == oldShape : "wrong shape"; | |
126 assert newShape.isValid(); | |
127 assert getLocation() != null; | |
128 getLocation().set(store, value, oldShape, newShape); | |
129 } | |
130 | |
131 @Override | |
132 public final void setSafe(DynamicObject store, Object value, Shape oldShape, Shape newShape) { | |
133 assert store.getShape() == oldShape : "wrong old shape"; | |
134 assert newShape.isValid(); | |
135 assert getLocation() != null; | |
136 try { | |
137 getLocation().set(store, value, oldShape, newShape); | |
138 } catch (IncompatibleLocationException ex) { | |
139 throw new IllegalStateException(); | |
140 } | |
141 } | |
142 | |
143 @Override | |
144 public final void setGeneric(DynamicObject store, Object value, Shape oldShape, Shape newShape) { | |
145 assert store.getShape() == oldShape : "wrong old shape"; | |
146 assert newShape.isValid(); | |
147 assert getLocation() != null; | |
148 try { | |
149 getLocation().set(store, value, oldShape, newShape); | |
150 } catch (IncompatibleLocationException ex) { | |
151 setWithShapeSlowCase(store, value, oldShape, newShape); | |
152 } | |
153 } | |
154 | |
155 @Override | |
156 public boolean equals(Object obj) { | |
157 if (this == obj) { | |
158 return true; | |
159 } | |
160 if (obj == null) { | |
161 return false; | |
162 } | |
163 if (getClass() != obj.getClass()) { | |
164 return false; | |
165 } | |
166 | |
167 PropertyImpl other = (PropertyImpl) obj; | |
168 return key.equals(other.key) && ((location == null && other.location == null) || (location != null && location.equals(other.location))) && flags == other.flags && shadow == other.shadow && | |
169 relocatable == other.relocatable; | |
170 } | |
171 | |
172 @Override | |
173 public boolean isSame(Property obj) { | |
174 if (this == obj) { | |
175 return true; | |
176 } | |
177 if (obj == null) { | |
178 return false; | |
179 } | |
180 if (getClass() != obj.getClass()) { | |
181 return false; | |
182 } | |
183 | |
184 PropertyImpl other = (PropertyImpl) obj; | |
185 return key.equals(other.key) && flags == other.flags; | |
186 } | |
187 | |
188 @Override | |
189 public int hashCode() { | |
190 final int prime = 31; | |
191 int result = 1; | |
192 result = prime * result + getClass().hashCode(); | |
193 result = prime * result + key.hashCode(); | |
194 result = prime * result + (location != null ? location.hashCode() : 0); | |
195 result = prime * result + flags; | |
196 return result; | |
197 } | |
198 | |
199 @Override | |
200 public String toString() { | |
201 return "\"" + key + "\"" + ":" + location; | |
202 } | |
203 | |
204 @Override | |
205 public final Location getLocation() { | |
206 return location; | |
207 } | |
208 | |
209 private void setSlowCase(DynamicObject store, Object value) { | |
210 if (getLocation() instanceof DeclaredLocation) { | |
211 setDeclaredLocation(store, value); | |
212 } else { | |
213 generalize(store, value); | |
214 } | |
215 } | |
216 | |
217 private void setDeclaredLocation(DynamicObject store, Object value) { | |
218 store.updateShape(); | |
219 Shape oldShape = store.getShape(); | |
220 Shape newShape = oldShape.addProperty(this.relocateShadow(oldShape.allocator().locationForValue(value, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull)))); | |
221 store.updateShape(); | |
222 newShape.getLastProperty().setGeneric(store, value, oldShape, newShape); | |
223 } | |
224 | |
225 private Property generalize(DynamicObject store, Object value) { | |
226 return ((LayoutImpl) store.getShape().getLayout()).getStrategy().generalizeProperty(store, this, value); | |
227 } | |
228 | |
229 private void setWithShapeSlowCase(DynamicObject store, Object value, Shape oldShape, Shape newShape) { | |
230 ((LayoutImpl) store.getShape().getLayout()).getStrategy().generalizeProperty(store, this, value, oldShape, newShape); | |
231 } | |
232 | |
233 @Override | |
234 public final boolean isHidden() { | |
235 return key instanceof HiddenKey; | |
236 } | |
237 | |
238 @Override | |
239 public final boolean isShadow() { | |
240 return shadow; | |
241 } | |
242 | |
243 private Property relocateShadow(Location newLocation) { | |
244 assert !isShadow() && getLocation() instanceof DeclaredLocation && relocatable; | |
245 return new PropertyImpl(getKey(), newLocation, flags, true, relocatable); | |
246 } | |
247 | |
248 @SuppressWarnings("hiding") | |
249 protected Property construct(Object name, Location location, int flags) { | |
250 return new PropertyImpl(name, location, flags, shadow, relocatable); | |
251 } | |
252 | |
253 @Override | |
254 public Property copyWithFlags(int newFlags) { | |
255 return construct(key, location, newFlags); | |
256 } | |
257 | |
258 @Override | |
259 public Property copyWithRelocatable(boolean newRelocatable) { | |
260 if (this.relocatable != newRelocatable) { | |
261 return new PropertyImpl(key, location, flags, shadow, newRelocatable); | |
262 } | |
263 return this; | |
264 } | |
265 } |