2222 */
2323package com .oracle .truffle .r .runtime .interop ;
2424
25+ import java .util .ArrayList ;
26+
2527import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
2628import com .oracle .truffle .api .interop .InteropException ;
2729import com .oracle .truffle .api .interop .InteropLibrary ;
3840import com .oracle .truffle .r .runtime .data .RForeignListWrapper ;
3941import com .oracle .truffle .r .runtime .data .RForeignStringWrapper ;
4042import com .oracle .truffle .r .runtime .data .RIntVector ;
41- import com .oracle .truffle .r .runtime .data .RList ;
4243import com .oracle .truffle .r .runtime .data .RStringVector ;
43- import com .oracle .truffle .r .runtime .data .model .RAbstractContainer ;
44- import com .oracle .truffle .r .runtime .data .model .RAbstractListVector ;
45- import com .oracle .truffle .r .runtime .data .nodes .FastPathVectorAccess .FastPathFromListAccess ;
46- import com .oracle .truffle .r .runtime .data .nodes .SlowPathVectorAccess .SlowPathFromListAccess ;
47- import com .oracle .truffle .r .runtime .data .nodes .VectorAccess ;
4844
4945public final class TruffleObjectConverter {
5046
@@ -84,39 +80,18 @@ public static Object convert(TruffleObject obj) {
8480 }
8581
8682 try {
87- TruffleObject classStatic = null ;
88- String [] staticNames = null ;
83+ ArrayList < String > names = new ArrayList <>() ;
84+ ArrayList < Object > values = new ArrayList <>() ;
8985 if (!ConvertForeignObjectNode .isForeignArray (obj , getInterop ())) {
90- try {
91- classStatic = ToJavaStaticNode .getUncached ().execute (obj );
92- staticNames = classStatic != null ? readMembers (classStatic ) : null ;
93- } catch (UnknownIdentifierException | NoSuchFieldError | UnsupportedMessageException e ) {
86+ TruffleObject classStatic = ToJavaStaticNode .getUncached ().execute (obj );
87+ if (classStatic != null ) {
88+ readMembers (classStatic , names , values );
9489 }
9590 }
9691
97- String [] names ;
98- try {
99- names = readMembers (obj );
100- } catch (UnsupportedMessageException e ) {
101- names = null ;
102- }
103-
104- int staticNamesLen ;
105- String [] compoundNames ;
106- if (staticNames == null ) {
107- staticNamesLen = 0 ;
108- compoundNames = (names != null ) ? names : new String [0 ];
109- } else if (names == null ) {
110- staticNamesLen = staticNames .length ;
111- compoundNames = staticNames ;
112- } else {
113- staticNamesLen = staticNames .length ;
114- compoundNames = new String [staticNamesLen + names .length ];
115- System .arraycopy (staticNames , 0 , compoundNames , 0 , staticNamesLen );
116- System .arraycopy (names , 0 , compoundNames , staticNamesLen , names .length );
117- }
118- RStringVector compoundNamesVec = RDataFactory .createStringVector (compoundNames , true );
119- return new CompoundNamedListWrapper (classStatic , obj , staticNamesLen , compoundNamesVec );
92+ readMembers (obj , names , values );
93+ RStringVector namesVec = RDataFactory .createStringVector (names .toArray (new String [0 ]), true );
94+ return RDataFactory .createList (values .toArray (), namesVec );
12095 } catch (InteropException e ) {
12196 throw RInternalError .shouldNotReachHere (e );
12297 }
@@ -127,163 +102,19 @@ public static Object convert(TruffleObject obj) {
127102 return obj ;
128103 }
129104
130- private static String [] readMembers (TruffleObject obj )
131- throws InteropException , UnsupportedMessageException {
105+ private static void readMembers (TruffleObject obj , ArrayList < String > names , ArrayList < Object > values )
106+ throws InteropException {
132107 InteropLibrary interop = getInterop ();
133108 Object members = interop .getMembers (obj );
134- int size = RRuntime .getForeignArraySize (members , getInterop ());
135- String [] names = new String [size ];
109+ int size = RRuntime .getForeignArraySize (members , interop );
136110 for (int i = 0 ; i < size ; i ++) {
137- Object value = interop .readArrayElement (members , i );
138- names [i ] = (String ) value ;
139- }
140- return names ;
141- }
142-
143- private static final class CompoundNamedListWrapper extends RAbstractListVector {
144-
145- private TruffleObject classDelegate ;
146-
147- private TruffleObject delegate ;
148-
149- private int staticNamesLen ;
150-
151- private RStringVector names ;
152-
153- CompoundNamedListWrapper (TruffleObject classDelegate , TruffleObject delegate , int staticNamesLen , RStringVector names ) {
154- super (RDataFactory .INCOMPLETE_VECTOR );
155- this .classDelegate = classDelegate ;
156- this .delegate = delegate ;
157- this .staticNamesLen = staticNamesLen ;
158- this .names = names ;
159- }
160-
161- @ Override
162- public Object getInternalStore () {
163- return this ;
164- }
165-
166- @ Override
167- public int getLength () {
168- return names .getLength ();
169- }
170-
171- @ Override
172- public RStringVector getNames () {
173- return names ;
174- }
175-
176- @ Override
177- public RList materialize () {
178- throw RInternalError .shouldNotReachHere ();
179- }
180-
181- @ Override
182- @ TruffleBoundary
183- public Object getDataAtAsObject (int index ) {
184- return getDataAt (index );
185- }
186-
187- @ Override
188- @ TruffleBoundary
189- public Object getDataAt (int index ) {
190- try {
191- return (index < staticNamesLen ) ? read (getInterop (), classDelegate , names , index ) : read (getInterop (), delegate , names , index );
192- } catch (UnsupportedMessageException | UnknownIdentifierException e ) {
193- throw RInternalError .shouldNotReachHere (e );
194- }
195- }
196-
197- private static final class FastPathAccess extends FastPathFromListAccess {
198-
199- @ Child private InteropLibrary delegateInterop ;
200- @ Child private InteropLibrary classDelegateInterop ;
201- @ Child private Foreign2R foreign2r = Foreign2R .create ();
202-
203- FastPathAccess (RAbstractContainer value ) {
204- super (value );
205- CompoundNamedListWrapper wrapper = (CompoundNamedListWrapper ) value ;
206- delegateInterop = InteropLibrary .getFactory ().create (wrapper .delegate );
207- if (wrapper .classDelegate != null ) {
208- classDelegateInterop = InteropLibrary .getFactory ().create (wrapper .classDelegate );
209- }
210- }
211-
212- @ Override
213- public boolean supports (Object value ) {
214- if (!(value instanceof CompoundNamedListWrapper )) {
215- return false ;
216- }
217- CompoundNamedListWrapper wrapper = (CompoundNamedListWrapper ) value ;
218- if (wrapper .classDelegate == null ) {
219- return super .supports (value ) && delegateInterop .accepts (wrapper .delegate );
220- } else {
221- return super .supports (value ) && delegateInterop .accepts (wrapper .delegate ) && classDelegateInterop .accepts (wrapper .classDelegate );
222- }
223-
224- }
225-
226- @ Override
227- public RType getType () {
228- return RType .List ;
229- }
230-
231- @ Override
232- protected int getLength (RAbstractContainer vector ) {
233- return vector .getLength ();
234- }
235-
236- @ Override
237- protected Object getListElementImpl (AccessIterator accessIter , int index ) {
238- try {
239- CompoundNamedListWrapper wrapper = (CompoundNamedListWrapper ) accessIter .getStore ();
240- return (index < wrapper .staticNamesLen )
241- ? foreign2r .convert (read (classDelegateInterop , wrapper .classDelegate , wrapper .names , index ))
242- : foreign2r .convert (read (delegateInterop , wrapper .delegate , wrapper .names , index ));
243- } catch (UnsupportedMessageException | UnknownIdentifierException e ) {
244- throw RInternalError .shouldNotReachHere (e );
245- }
246- }
247- }
248-
249- @ Override
250- public VectorAccess access () {
251- return new FastPathAccess (this );
252- }
253-
254- private static final SlowPathFromListAccess SLOW_PATH_ACCESS = new SlowPathFromListAccess () {
255-
256- @ Override
257- public RType getType () {
258- return RType .List ;
259- }
260-
261- @ Override
262- protected int getLength (RAbstractContainer vector ) {
263- return ((CompoundNamedListWrapper ) vector ).getLength ();
264- }
265-
266- @ Override
267- protected Object getListElementImpl (AccessIterator accessIter , int index ) {
268- CompoundNamedListWrapper vector = (CompoundNamedListWrapper ) accessIter .getStore ();
269- try {
270- return (index < vector .staticNamesLen )
271- ? read (getInterop (), vector .classDelegate , vector .names , index )
272- : read (getInterop (), vector .delegate , vector .names , index );
273- } catch (UnsupportedMessageException | UnknownIdentifierException e ) {
274- throw RInternalError .shouldNotReachHere (e );
275- }
276- }
277- };
278-
279- @ Override
280- public VectorAccess slowPathAccess () {
281- return SLOW_PATH_ACCESS ;
111+ String memberName = interop .asString (interop .readArrayElement (members , i ));
112+ values .add (read (interop , obj , memberName ));
113+ names .add (memberName );
282114 }
283115 }
284116
285- private static Object read (InteropLibrary interop , TruffleObject obj , RStringVector names , int index ) throws UnsupportedMessageException , UnknownIdentifierException {
286- String memberName = names .getDataAt (index );
117+ private static Object read (InteropLibrary interop , TruffleObject obj , String memberName ) throws UnsupportedMessageException , UnknownIdentifierException {
287118 if (interop .isMemberReadable (obj , memberName )) {
288119 return Foreign2R .getUncached ().convert (interop .readMember (obj , memberName ));
289120 } else {
@@ -294,5 +125,4 @@ private static Object read(InteropLibrary interop, TruffleObject obj, RStringVec
294125 private static InteropLibrary getInterop () {
295126 return InteropLibrary .getFactory ().getUncached ();
296127 }
297-
298128}
0 commit comments