annotate graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/RubyBasicObject.java @ 13514:0fbee3eb71f0

Ruby: import project.
author Chris Seaton <chris.seaton@oracle.com>
date Mon, 06 Jan 2014 17:12:09 +0000
parents
children 50c11b9a7fdf
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13514
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
1 /*
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
2 * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
3 * code is released under a tri EPL/GPL/LGPL license. You can use it,
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
4 * redistribute it and/or modify it under the terms of the:
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
5 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
6 * Eclipse Public License version 1.0
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
7 * GNU General Public License version 2
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
8 * GNU Lesser General Public License version 2.1
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
9 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
10 package com.oracle.truffle.ruby.runtime.objects;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
11
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
12 import java.util.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
13 import java.util.Map.Entry;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
14
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
15 import com.oracle.truffle.api.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
16 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
17 import com.oracle.truffle.ruby.runtime.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
18 import com.oracle.truffle.ruby.runtime.control.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
19 import com.oracle.truffle.ruby.runtime.core.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
20 import com.oracle.truffle.ruby.runtime.lookup.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
21 import com.oracle.truffle.ruby.runtime.methods.*;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
22
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
23 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
24 * Represents the Ruby {@code BasicObject} class - the root of the Ruby class hierarchy.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
25 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
26 public class RubyBasicObject {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
27
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
28 @CompilationFinal protected RubyClass rubyClass;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
29 protected RubyClass rubySingletonClass;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
30
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
31 protected LookupNode lookupNode;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
32
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
33 protected long objectID = -1;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
34
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
35 public boolean hasPrivateLayout = false;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
36 private ObjectLayout objectLayout;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
37
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
38 public static final int PRIMITIVE_STORAGE_LOCATIONS_COUNT = 14;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
39 protected int primitiveStorageLocation01;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
40 protected int primitiveStorageLocation02;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
41 protected int primitiveStorageLocation03;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
42 protected int primitiveStorageLocation04;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
43 protected int primitiveStorageLocation05;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
44 protected int primitiveStorageLocation06;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
45 protected int primitiveStorageLocation07;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
46 protected int primitiveStorageLocation08;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
47 protected int primitiveStorageLocation09;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
48 protected int primitiveStorageLocation10;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
49 protected int primitiveStorageLocation11;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
50 protected int primitiveStorageLocation12;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
51 protected int primitiveStorageLocation13;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
52 protected int primitiveStorageLocation14;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
53
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
54 // A bit map to indicate which primitives are set, so that they can be Nil
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
55 protected int primitiveSetMap;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
56
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
57 protected Object[] objectStorageLocations;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
58
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
59 public RubyBasicObject(RubyClass rubyClass) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
60 if (rubyClass != null) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
61 unsafeSetRubyClass(rubyClass);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
62
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
63 if (rubyClass.getContext().getConfiguration().getFullObjectSpace()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
64 rubyClass.getContext().getObjectSpaceManager().add(this);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
65 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
66 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
67 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
68
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
69 public void initialize() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
70 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
71
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
72 public LookupNode getLookupNode() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
73 return lookupNode;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
74 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
75
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
76 public RubyClass getRubyClass() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
77 assert rubyClass != null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
78 return rubyClass;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
79 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
80
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
81 public boolean hasPrivateLayout() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
82 return hasPrivateLayout;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
83 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
84
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
85 public ObjectLayout getObjectLayout() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
86 return objectLayout;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
87 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
88
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
89 public ObjectLayout getUpdatedObjectLayout() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
90 updateLayout();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
91 return objectLayout;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
92 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
93
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
94 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
95 * Does this object have an instance variable defined?
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
96 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
97 public boolean isInstanceVariableDefined(String name) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
98 if (!hasPrivateLayout && objectLayout != rubyClass.getObjectLayoutForInstances()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
99 updateLayout();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
100 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
101
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
102 return objectLayout.findStorageLocation(name) != null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
103 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
104
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
105 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
106 * Set an instance variable to be a value. Slow path.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
107 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
108 public void setInstanceVariable(String name, Object value) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
109 CompilerAsserts.neverPartOfCompilation();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
110
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
111 // If the object's layout doesn't match the class, update
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
112
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
113 if (!hasPrivateLayout && objectLayout != rubyClass.getObjectLayoutForInstances()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
114 updateLayout();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
115 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
116
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
117 // Find the storage location
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
118
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
119 StorageLocation storageLocation = objectLayout.findStorageLocation(name);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
120
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
121 if (storageLocation == null) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
122 /*
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
123 * It doesn't exist, so create a new layout for the class that includes it and update
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
124 * the layout of this object.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
125 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
126
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
127 rubyClass.setObjectLayoutForInstances(rubyClass.getObjectLayoutForInstances().withNewVariable(rubyClass.getContext(), name, value.getClass()));
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
128 updateLayout();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
129
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
130 storageLocation = objectLayout.findStorageLocation(name);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
131 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
132
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
133 // Try to write to that storage location
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
134
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
135 try {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
136 storageLocation.write(this, value);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
137 } catch (GeneralizeStorageLocationException e) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
138 /*
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
139 * It might not be able to store the type that we passed, if not generalize the class's
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
140 * layout and update the layout of this object.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
141 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
142
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
143 rubyClass.setObjectLayoutForInstances(rubyClass.getObjectLayoutForInstances().withGeneralisedVariable(rubyClass.getContext(), name));
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
144 updateLayout();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
145
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
146 storageLocation = objectLayout.findStorageLocation(name);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
147
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
148 // Try to write to the generalized storage location
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
149
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
150 try {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
151 storageLocation.write(this, value);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
152 } catch (GeneralizeStorageLocationException e1) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
153 // We know that we just generalized it, so this should not happen
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
154 throw new RuntimeException("Generalised an instance variable, but it still rejected the value");
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
155 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
156 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
157 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
158
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
159 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
160 * Get the value of an instance variable, or Nil if it isn't defined. Slow path.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
161 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
162 public Object getInstanceVariable(String name) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
163 CompilerAsserts.neverPartOfCompilation();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
164
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
165 // If the object's layout doesn't match the class, update
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
166
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
167 if (!hasPrivateLayout && objectLayout != rubyClass.getObjectLayoutForInstances()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
168 updateLayout();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
169 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
170
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
171 // Find the storage location
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
172
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
173 final StorageLocation storageLocation = objectLayout.findStorageLocation(name);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
174
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
175 // Get the value
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
176
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
177 if (storageLocation == null) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
178 return NilPlaceholder.INSTANCE;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
179 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
180
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
181 return storageLocation.read(this, true);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
182 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
183
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
184 public String[] getInstanceVariableNames() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
185 final Set<String> instanceVariableNames = getInstanceVariables().keySet();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
186 return instanceVariableNames.toArray(new String[instanceVariableNames.size()]);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
187 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
188
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
189 public RubyClass getSingletonClass() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
190 if (rubySingletonClass == null) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
191 /*
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
192 * The object a of class A has a singleton class a' of class Class, with name
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
193 * #<Class:#<A:objectid>>, and with superclass that is A.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
194 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
195 * irb(main):001:0> class A; end
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
196 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
197 * => nil
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
198 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
199 * irb(main):002:0> a = A.new
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
200 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
201 * => #<A:0x007ff612a631e0>
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
202 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
203 * irb(main):003:0> a.singleton_class
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
204 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
205 * => #<Class:#<A:0x007ff612a631e0>>
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
206 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
207 * irb(main):004:0> a.singleton_class.class
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
208 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
209 * => Class
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
210 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
211 * irb(main):005:0> a.singleton_class.superclass
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
212 *
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
213 * => A
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
214 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
215
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
216 rubySingletonClass = new RubyClass(rubyClass.getParentModule(), rubyClass, String.format("#<Class:#<%s:%d>>", rubyClass.getName(), getObjectID()), true);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
217
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
218 lookupNode = new LookupFork(rubySingletonClass, rubyClass);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
219 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
220
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
221 return rubySingletonClass;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
222 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
223
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
224 public long getObjectID() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
225 if (objectID == -1) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
226 objectID = rubyClass.getContext().getNextObjectID();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
227 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
228
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
229 return objectID;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
230 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
231
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
232 public String inspect() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
233 return toString();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
234 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
235
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
236 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
237 * Get a map of all instance variables.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
238 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
239 protected Map<String, Object> getInstanceVariables() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
240 if (objectLayout == null) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
241 return Collections.emptyMap();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
242 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
243
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
244 final Map<String, Object> instanceVariableMap = new HashMap<>();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
245
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
246 for (Entry<String, StorageLocation> entry : objectLayout.getAllStorageLocations().entrySet()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
247 final String name = entry.getKey();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
248 final StorageLocation storageLocation = entry.getValue();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
249
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
250 if (storageLocation.isSet(this)) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
251 instanceVariableMap.put(name, storageLocation.read(this, true));
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
252 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
253 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
254
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
255 return instanceVariableMap;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
256 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
257
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
258 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
259 * Set instance variables from a map.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
260 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
261 protected void setInstanceVariables(Map<String, Object> instanceVariables) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
262 assert instanceVariables != null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
263
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
264 if (objectLayout == null) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
265 updateLayout();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
266 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
267
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
268 for (Entry<String, Object> entry : instanceVariables.entrySet()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
269 final StorageLocation storageLocation = objectLayout.findStorageLocation(entry.getKey());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
270 assert storageLocation != null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
271
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
272 try {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
273 storageLocation.write(this, entry.getValue());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
274 } catch (GeneralizeStorageLocationException e) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
275 throw new RuntimeException("Should not have to be generalising when setting instance variables - " + entry.getValue().getClass().getName() + ", " +
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
276 storageLocation.getStoredClass().getName());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
277 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
278 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
279 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
280
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
281 /**
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
282 * Update the layout of this object to match that of its class.
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
283 */
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
284 @CompilerDirectives.SlowPath
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
285 public void updateLayout() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
286 // Get the current values of instance variables
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
287
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
288 final Map<String, Object> instanceVariableMap = getInstanceVariables();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
289
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
290 // Use the layout of the class
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
291
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
292 objectLayout = rubyClass.getObjectLayoutForInstances();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
293
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
294 // Make all primitives as unset
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
295
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
296 primitiveSetMap = 0;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
297
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
298 // Create a new array for objects
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
299
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
300 allocateObjectStorageLocations();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
301
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
302 // Restore values
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
303
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
304 setInstanceVariables(instanceVariableMap);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
305 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
306
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
307 private void allocateObjectStorageLocations() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
308 final int objectStorageLocationsUsed = objectLayout.getObjectStorageLocationsUsed();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
309
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
310 if (objectStorageLocationsUsed == 0) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
311 objectStorageLocations = null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
312 } else {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
313 objectStorageLocations = new Object[objectStorageLocationsUsed];
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
314 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
315 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
316
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
317 public void switchToPrivateLayout() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
318 final RubyContext context = getRubyClass().getContext();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
319
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
320 final Map<String, Object> instanceVariables = getInstanceVariables();
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
321
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
322 hasPrivateLayout = true;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
323 objectLayout = ObjectLayout.EMPTY;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
324
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
325 for (Entry<String, Object> entry : instanceVariables.entrySet()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
326 objectLayout = objectLayout.withNewVariable(context, entry.getKey(), entry.getValue().getClass());
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
327 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
328
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
329 setInstanceVariables(instanceVariables);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
330 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
331
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
332 public void extend(RubyModule module) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
333 getSingletonClass().include(module);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
334 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
335
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
336 @Override
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
337 public String toString() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
338 return "#<" + rubyClass.getName() + ":0x" + Long.toHexString(getObjectID()) + ">";
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
339 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
340
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
341 public boolean hasSingletonClass() {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
342 return rubySingletonClass != null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
343 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
344
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
345 public Object send(String name, RubyProc block, Object... args) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
346 final RubyMethod method = getLookupNode().lookupMethod(name);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
347
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
348 if (method == null || method.isUndefined()) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
349 throw new RaiseException(getRubyClass().getContext().getCoreLibrary().noMethodError(name, toString()));
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
350 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
351
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
352 return method.call(null, this, block, args);
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
353 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
354
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
355 public void unsafeSetRubyClass(RubyClass newRubyClass) {
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
356 assert rubyClass == null;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
357
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
358 rubyClass = newRubyClass;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
359 lookupNode = rubyClass;
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
360 }
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
361
0fbee3eb71f0 Ruby: import project.
Chris Seaton <chris.seaton@oracle.com>
parents:
diff changeset
362 }