comparison graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyCacheNode.java @ 18412:997bc9764a9a

SL: use the truffle object storage model to represent SL objects
author Andreas Woess <andreas.woess@jku.at>
date Tue, 18 Nov 2014 12:08:51 +0100
parents
children ccb97347d874
comparison
equal deleted inserted replaced
18411:dc2e000bed40 18412:997bc9764a9a
1 /*
2 * Copyright (c) 2013, 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.sl.nodes.access;
24
25 import com.oracle.truffle.api.*;
26 import com.oracle.truffle.api.nodes.*;
27 import com.oracle.truffle.api.object.*;
28 import com.oracle.truffle.sl.nodes.*;
29 import com.oracle.truffle.sl.runtime.*;
30
31 /**
32 * The node for accessing a property of an object. When executed, this node first evaluates the
33 * object expression on the left side of the dot operator and then reads the named property.
34 */
35 public abstract class SLReadPropertyCacheNode extends Node {
36
37 public static SLReadPropertyCacheNode create(String propertyName) {
38 return new SLUninitializedReadObjectPropertyNode(propertyName);
39 }
40
41 public abstract Object executeObject(DynamicObject receiver);
42
43 public abstract long executeLong(DynamicObject receiver) throws UnexpectedResultException;
44
45 protected abstract static class SLReadPropertyCacheChainNode extends SLReadPropertyCacheNode {
46 protected final Shape shape;
47 @Child protected SLReadPropertyCacheNode next;
48
49 public SLReadPropertyCacheChainNode(Shape shape, SLReadPropertyCacheNode next) {
50 this.shape = shape;
51 this.next = next;
52 }
53
54 @Override
55 public final Object executeObject(DynamicObject receiver) {
56 try {
57 // if this assumption fails, the object needs to be updated to a valid shape
58 shape.getValidAssumption().check();
59 } catch (InvalidAssumptionException e) {
60 return this.replace(next).executeObject(receiver);
61 }
62
63 boolean condition = shape.check(receiver);
64
65 if (condition) {
66 return executeObjectUnchecked(receiver, condition);
67 } else {
68 return next.executeObject(receiver);
69 }
70 }
71
72 @Override
73 public final long executeLong(DynamicObject receiver) throws UnexpectedResultException {
74 try {
75 // if this assumption fails, the object needs to be updated to a valid shape
76 shape.getValidAssumption().check();
77 } catch (InvalidAssumptionException e) {
78 return this.replace(next).executeLong(receiver);
79 }
80
81 boolean condition = shape.check(receiver);
82
83 if (condition) {
84 return executeLongUnchecked(receiver, condition);
85 } else {
86 return next.executeLong(receiver);
87 }
88 }
89
90 protected abstract Object executeObjectUnchecked(DynamicObject receiver, boolean condition);
91
92 protected long executeLongUnchecked(DynamicObject receiver, boolean condition) throws UnexpectedResultException {
93 return SLTypesGen.SLTYPES.expectLong(executeObjectUnchecked(receiver, condition));
94 }
95 }
96
97 protected static class SLReadObjectPropertyNode extends SLReadPropertyCacheChainNode {
98 private final Location location;
99
100 protected SLReadObjectPropertyNode(Shape shape, Location location, SLReadPropertyCacheNode next) {
101 super(shape, next);
102 this.location = location;
103 }
104
105 @Override
106 protected Object executeObjectUnchecked(DynamicObject receiver, boolean condition) {
107 return location.get(receiver, condition);
108 }
109 }
110
111 protected static class SLReadBooleanPropertyNode extends SLReadPropertyCacheChainNode {
112 private final BooleanLocation location;
113
114 protected SLReadBooleanPropertyNode(Shape shape, BooleanLocation location, SLReadPropertyCacheNode next) {
115 super(shape, next);
116 this.location = location;
117 }
118
119 @Override
120 protected Object executeObjectUnchecked(DynamicObject receiver, boolean condition) {
121 return location.getBoolean(receiver, condition);
122 }
123 }
124
125 protected static class SLReadLongPropertyNode extends SLReadPropertyCacheChainNode {
126 private final LongLocation location;
127
128 protected SLReadLongPropertyNode(Shape shape, LongLocation location, SLReadPropertyCacheNode next) {
129 super(shape, next);
130 this.location = location;
131 }
132
133 @Override
134 protected Object executeObjectUnchecked(DynamicObject receiver, boolean condition) {
135 return location.getLong(receiver, condition);
136 }
137
138 @Override
139 protected long executeLongUnchecked(DynamicObject receiver, boolean condition) throws UnexpectedResultException {
140 return location.getLong(receiver, condition);
141 }
142 }
143
144 protected static class SLReadMissingPropertyNode extends SLReadPropertyCacheChainNode {
145 protected SLReadMissingPropertyNode(Shape shape, SLReadPropertyCacheNode next) {
146 super(shape, next);
147 }
148
149 @Override
150 protected Object executeObjectUnchecked(DynamicObject receiver, boolean condition) {
151 // The property was not found in the object, return null
152 return SLNull.SINGLETON;
153 }
154 }
155
156 protected static class SLUninitializedReadObjectPropertyNode extends SLReadPropertyCacheNode {
157 protected final String propertyName;
158
159 protected SLUninitializedReadObjectPropertyNode(String propertyName) {
160 this.propertyName = propertyName;
161 }
162
163 @Override
164 public Object executeObject(DynamicObject receiver) {
165 CompilerDirectives.transferToInterpreterAndInvalidate();
166
167 receiver.updateShape();
168
169 Shape shape = receiver.getShape();
170 Property property = shape.getProperty(propertyName);
171
172 final SLReadPropertyCacheNode resolvedNode;
173 if (property == null) {
174 resolvedNode = new SLReadMissingPropertyNode(shape, this);
175 } else if (property.getLocation() instanceof LongLocation) {
176 resolvedNode = new SLReadLongPropertyNode(shape, (LongLocation) property.getLocation(), this);
177 } else if (property.getLocation() instanceof BooleanLocation) {
178 resolvedNode = new SLReadBooleanPropertyNode(shape, (BooleanLocation) property.getLocation(), this);
179 } else {
180 resolvedNode = new SLReadObjectPropertyNode(shape, property.getLocation(), this);
181 }
182
183 return this.replace(resolvedNode, "resolved '" + propertyName + "'").executeObject(receiver);
184 }
185
186 @Override
187 public long executeLong(DynamicObject receiver) throws UnexpectedResultException {
188 return SLTypesGen.SLTYPES.expectLong(executeObject(receiver));
189 }
190 }
191 }