22
22
package trufflesom .interpreter .nodes ;
23
23
24
24
import com .oracle .truffle .api .CompilerDirectives ;
25
+ import com .oracle .truffle .api .dsl .Cached ;
25
26
import com .oracle .truffle .api .dsl .NodeChild ;
26
27
import com .oracle .truffle .api .dsl .Specialization ;
27
28
import com .oracle .truffle .api .frame .VirtualFrame ;
31
32
import bd .primitives .nodes .PreevaluatedExpression ;
32
33
import trufflesom .compiler .Variable .Argument ;
33
34
import trufflesom .interpreter .nodes .ArgumentReadNode .LocalArgumentReadNode ;
35
+ import trufflesom .interpreter .nodes .FieldNodeFactory .FieldReadNodeGen ;
34
36
import trufflesom .interpreter .nodes .FieldNodeFactory .FieldWriteNodeGen ;
35
37
import trufflesom .interpreter .objectstorage .FieldAccessorNode ;
36
- import trufflesom .interpreter .objectstorage .FieldAccessorNode .AbstractReadFieldNode ;
37
38
import trufflesom .interpreter .objectstorage .FieldAccessorNode .AbstractWriteFieldNode ;
38
39
import trufflesom .interpreter .objectstorage .FieldAccessorNode .IncrementLongFieldNode ;
40
+ import trufflesom .interpreter .objectstorage .ObjectLayout ;
41
+ import trufflesom .interpreter .objectstorage .StorageLocation ;
42
+ import trufflesom .interpreter .objectstorage .StorageLocation .DoubleStorageLocation ;
43
+ import trufflesom .interpreter .objectstorage .StorageLocation .LongStorageLocation ;
39
44
import trufflesom .vm .NotYetImplementedException ;
45
+ import trufflesom .vm .constants .Nil ;
40
46
import trufflesom .vmobjects .SObject ;
41
47
42
48
43
49
public abstract class FieldNode extends ExpressionNode {
44
50
45
51
protected abstract ExpressionNode getSelf ();
46
52
47
- public static final class FieldReadNode extends FieldNode
53
+ @ NodeChild (value = "self" , type = ExpressionNode .class )
54
+ public abstract static class FieldReadNode extends FieldNode
48
55
implements PreevaluatedExpression {
49
- @ Child private ExpressionNode self ;
50
- @ Child private AbstractReadFieldNode read ;
51
-
52
- public FieldReadNode (final ExpressionNode self , final int fieldIndex ) {
53
- this .self = self ;
54
- read = FieldAccessorNode .createRead (fieldIndex );
55
- }
56
+ protected final int fieldIndex ;
56
57
57
- public int getFieldIndex ( ) {
58
- return read . getFieldIndex () ;
58
+ public FieldReadNode ( final int fieldIndex ) {
59
+ this . fieldIndex = fieldIndex ;
59
60
}
60
61
61
- @ Override
62
- protected ExpressionNode getSelf () {
63
- return self ;
64
- }
62
+ public abstract Object executeEvaluated (SObject obj );
65
63
66
- public Object executeEvaluated ( final SObject obj ) {
67
- return read . read ( obj ) ;
64
+ public int getFieldIndex ( ) {
65
+ return fieldIndex ;
68
66
}
69
67
70
68
@ Override
@@ -73,28 +71,64 @@ public Object doPreEvaluated(final VirtualFrame frame,
73
71
return executeEvaluated ((SObject ) arguments [0 ]);
74
72
}
75
73
76
- @ Override
77
- public long executeLong (final VirtualFrame frame ) throws UnexpectedResultException {
78
- SObject obj = self .executeSObject (frame );
79
- return read .readLong (obj );
80
- }
81
-
82
- @ Override
83
- public double executeDouble (final VirtualFrame frame ) throws UnexpectedResultException {
84
- SObject obj = self .executeSObject (frame );
85
- return read .readDouble (obj );
74
+ @ Specialization (
75
+ assumptions = "layout.getAssumption()" ,
76
+ guards = {
77
+ "obj.getObjectLayout() == layout" ,
78
+ "layout.isLongLocation(fieldIndex)" },
79
+ rewriteOn = UnexpectedResultException .class )
80
+ public long readLong (final SObject obj ,
81
+ @ Cached ("obj.getObjectLayout()" ) final ObjectLayout layout ,
82
+ @ Cached ("layout.getLongLocation(fieldIndex)" ) final LongStorageLocation storage )
83
+ throws UnexpectedResultException {
84
+ return storage .readLong (obj );
85
+ }
86
+
87
+ @ Specialization (
88
+ assumptions = "layout.getAssumption()" ,
89
+ guards = {
90
+ "obj.getObjectLayout() == layout" ,
91
+ "layout.isDoubleLocation(fieldIndex)" },
92
+ rewriteOn = UnexpectedResultException .class )
93
+ public double readDouble (final SObject obj ,
94
+ @ Cached ("obj.getObjectLayout()" ) final ObjectLayout layout ,
95
+ @ Cached ("layout.getDoubleLocation(fieldIndex)" ) final DoubleStorageLocation storage )
96
+ throws UnexpectedResultException {
97
+ return storage .readDouble (obj );
98
+ }
99
+
100
+ @ Specialization (
101
+ assumptions = "layout.getAssumption()" ,
102
+ guards = {
103
+ "obj.getObjectLayout() == layout" ,
104
+ "layout.isUnwrittenLocation(fieldIndex)" },
105
+ rewriteOn = UnexpectedResultException .class )
106
+ public SObject readNil (final SObject obj ,
107
+ @ Cached ("obj.getObjectLayout()" ) final ObjectLayout layout )
108
+ throws UnexpectedResultException {
109
+ return Nil .nilObject ;
110
+ }
111
+
112
+ @ Specialization (
113
+ assumptions = "layout.getAssumption()" ,
114
+ guards = {
115
+ "obj.getObjectLayout() == layout" ,
116
+ "layout.isObjectLocation(fieldIndex)" })
117
+ public Object readObject (final SObject obj ,
118
+ @ Cached ("obj.getObjectLayout()" ) final ObjectLayout layout ,
119
+ @ Cached ("layout.getObjectLocation(fieldIndex)" ) final StorageLocation storage ) {
120
+ return storage .read (obj );
121
+ }
122
+
123
+ @ Specialization (guards = "!obj.getObjectLayout().isValid()" )
124
+ public Object updateObject (final SObject obj ) {
125
+ obj .updateLayoutToMatchClass ();
126
+ return executeEvaluated (obj );
86
127
}
87
128
88
- @ Override
89
- public Object executeGeneric (final VirtualFrame frame ) {
90
- SObject obj ;
91
- try {
92
- obj = self .executeSObject (frame );
93
- } catch (UnexpectedResultException e ) {
94
- CompilerDirectives .transferToInterpreter ();
95
- throw new RuntimeException ("This should never happen by construction" );
96
- }
97
- return executeEvaluated (obj );
129
+ @ Specialization
130
+ public Object readObject (final SObject obj ) {
131
+ return obj .getObjectLayout ().getStorageLocation (fieldIndex ).read (obj );
98
132
}
99
133
100
134
@ Override
@@ -104,10 +138,7 @@ public boolean isTrivial() {
104
138
105
139
@ Override
106
140
public PreevaluatedExpression copyTrivialNode () {
107
- FieldReadNode node = (FieldReadNode ) copy ();
108
- node .self = null ;
109
- node .read = (AbstractReadFieldNode ) node .read .deepCopy ();
110
- return node ;
141
+ return FieldReadNodeGen .create (fieldIndex , getSelf ());
111
142
}
112
143
}
113
144
0 commit comments