1
1
package org .perl6 .nqp .sixmodel .reprs ;
2
2
3
+ import java .util .Arrays ;
4
+
3
5
import com .sun .jna .Memory ;
4
6
import com .sun .jna .Native ;
5
7
import com .sun .jna .Pointer ;
6
8
7
9
import org .perl6 .nqp .runtime .ExceptionHandling ;
10
+ import org .perl6 .nqp .runtime .NativeCallOps ;
11
+ import org .perl6 .nqp .runtime .Ops ;
8
12
import org .perl6 .nqp .runtime .ThreadContext ;
9
13
10
14
import org .perl6 .nqp .sixmodel .SixModelObject ;
11
15
12
16
import org .perl6 .nqp .sixmodel .reprs .CArrayREPRData .ElemKind ;
17
+ import org .perl6 .nqp .sixmodel .reprs .NativeCallBody .ArgType ;
13
18
14
19
public class CArrayInstance extends SixModelObject {
15
20
public Pointer storage ;
21
+ public SixModelObject [] child_objs ;
16
22
public boolean managed ;
17
23
public long allocated ;
18
24
public long elems ;
@@ -64,6 +70,45 @@ else if (repr_data.elem_size == 64) {
64
70
}
65
71
}
66
72
73
+ public SixModelObject at_pos_boxed (ThreadContext tc , long index ) {
74
+ CArrayREPRData repr_data = (CArrayREPRData ) st .REPRData ;
75
+ int intidx = (int ) index ;
76
+
77
+ /* TODO: Die if this is a NUMERIC/INTEGER CArray. */
78
+
79
+ if (managed ) {
80
+ if (index >= elems )
81
+ return repr_data .elem_type ;
82
+
83
+ if (child_objs [intidx ] != null ) {
84
+ return child_objs [intidx ];
85
+ }
86
+ else {
87
+ SixModelObject obj = makeObject (tc , storage .getPointer (index *repr_data .jna_size ));
88
+ child_objs [intidx ] = obj ;
89
+ return obj ;
90
+ }
91
+ }
92
+ else {
93
+ if (index >= allocated )
94
+ expand (tc , index +1 );
95
+
96
+ if (child_objs [intidx ] != null )
97
+ return child_objs [intidx ];
98
+ else {
99
+ Pointer ptr = storage .getPointer (index *repr_data .jna_size );
100
+ if (ptr != null ) {
101
+ SixModelObject obj = makeObject (tc , ptr );
102
+ child_objs [intidx ] = obj ;
103
+ return obj ;
104
+ }
105
+ else {
106
+ return repr_data .elem_type ;
107
+ }
108
+ }
109
+ }
110
+ }
111
+
67
112
public void bind_pos_native (ThreadContext tc , long index ) {
68
113
CArrayREPRData repr_data = (CArrayREPRData ) st .REPRData ;
69
114
@@ -100,6 +145,31 @@ else if (repr_data.elem_size == 64) {
100
145
}
101
146
}
102
147
148
+ public void bind_pos_boxed (ThreadContext tc , long index , SixModelObject value ) {
149
+ CArrayREPRData repr_data = (CArrayREPRData ) st .REPRData ;
150
+ int intidx = (int ) index ;
151
+
152
+ /* TODO: Die if this is a NUMERIC/INTEGER CArray. */
153
+ if (index >= allocated )
154
+ expand (tc , index +1 );
155
+
156
+ Pointer ptr = null ;
157
+ if (Ops .isconcrete (value , tc ) != 0 ) {
158
+ switch (repr_data .elem_kind ) {
159
+ case STRING :
160
+ byte [] bytes = Native .toByteArray (value .get_str (tc ));
161
+ ptr = new Memory (bytes .length );
162
+ ptr .write (0 , bytes , 0 , bytes .length );
163
+ break ;
164
+ default :
165
+ ExceptionHandling .dieInternal (tc , "CArray.bind_pos_boxed reached its default case. This should never happen." );
166
+ }
167
+ }
168
+
169
+ child_objs [intidx ] = value ;
170
+ storage .setPointer (index *repr_data .jna_size , ptr );
171
+ }
172
+
103
173
private void expand (ThreadContext tc , long new_size ) {
104
174
CArrayREPRData repr_data = (CArrayREPRData ) st .REPRData ;
105
175
@@ -111,6 +181,33 @@ private void expand(ThreadContext tc, long new_size) {
111
181
}
112
182
storage = new_storage ;
113
183
}
184
+
185
+ boolean complex = repr_data .elem_kind == ElemKind .CARRAY
186
+ || repr_data .elem_kind == ElemKind .CPOINTER
187
+ || repr_data .elem_kind == ElemKind .CSTRUCT
188
+ || repr_data .elem_kind == ElemKind .STRING ;
189
+
190
+ if (complex ) {
191
+ child_objs = child_objs == null ?
192
+ new SixModelObject [(int ) new_size ]:
193
+ Arrays .copyOf (child_objs , (int ) new_size );
194
+ }
195
+
114
196
elems = new_size ;
197
+ allocated = new_size ;
198
+ }
199
+
200
+ private SixModelObject makeObject (ThreadContext tc , Pointer ptr ) {
201
+ CArrayREPRData repr_data = (CArrayREPRData ) st .REPRData ;
202
+
203
+ switch (repr_data .elem_kind ) {
204
+ case STRING :
205
+ return NativeCallOps .toNQPType (tc , ArgType .UTF8STR , repr_data .elem_type , ptr .getString (0 ));
206
+ default :
207
+ ExceptionHandling .dieInternal (tc , "CArray can only makeObject strings" );
208
+ }
209
+
210
+ /* And a dummy return statement to placate Java's flow analysis. */
211
+ return null ;
115
212
}
116
213
}
0 commit comments