Skip to content

Commit 04bcb40

Browse files
committed
CArray of strings on JVM.
1 parent 84b433f commit 04bcb40

File tree

3 files changed

+103
-2
lines changed

3 files changed

+103
-2
lines changed

src/vm/jvm/runtime/org/perl6/nqp/runtime/NativeCallOps.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ private static Class javaType(ThreadContext tc, ArgType target) {
129129
return null;
130130
}
131131

132-
private static Object toJNAType(ThreadContext tc, SixModelObject o, ArgType target) {
132+
public static Object toJNAType(ThreadContext tc, SixModelObject o, ArgType target) {
133133
o = Ops.decont(o, tc);
134134
switch (target) {
135135
case CHAR:
@@ -170,7 +170,7 @@ private static Object toJNAType(ThreadContext tc, SixModelObject o, ArgType targ
170170
return null;
171171
}
172172

173-
private static SixModelObject toNQPType(ThreadContext tc, ArgType target, SixModelObject type, Object o) {
173+
public static SixModelObject toNQPType(ThreadContext tc, ArgType target, SixModelObject type, Object o) {
174174
SixModelObject nqpobj = null;
175175
if (target != ArgType.VOID)
176176
nqpobj = type.st.REPR.allocate(tc, type.st);

src/vm/jvm/runtime/org/perl6/nqp/sixmodel/reprs/CArray.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ else if (ss.bits == 64) {
8383
}
8484
data.elem_kind = ElemKind.NUMERIC;
8585
}
86+
else if ((ss.can_box & StorageSpec.CAN_BOX_STR) != 0) {
87+
data.jna_size = Native.POINTER_SIZE;
88+
data.elem_kind = ElemKind.STRING;
89+
}
8690
else {
8791
/* TODO: Remaining cases. */
8892
ExceptionHandling.dieInternal(tc, "CArray only handles ints and nums so far.");

src/vm/jvm/runtime/org/perl6/nqp/sixmodel/reprs/CArrayInstance.java

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
package org.perl6.nqp.sixmodel.reprs;
22

3+
import java.util.Arrays;
4+
35
import com.sun.jna.Memory;
46
import com.sun.jna.Native;
57
import com.sun.jna.Pointer;
68

79
import org.perl6.nqp.runtime.ExceptionHandling;
10+
import org.perl6.nqp.runtime.NativeCallOps;
11+
import org.perl6.nqp.runtime.Ops;
812
import org.perl6.nqp.runtime.ThreadContext;
913

1014
import org.perl6.nqp.sixmodel.SixModelObject;
1115

1216
import org.perl6.nqp.sixmodel.reprs.CArrayREPRData.ElemKind;
17+
import org.perl6.nqp.sixmodel.reprs.NativeCallBody.ArgType;
1318

1419
public class CArrayInstance extends SixModelObject {
1520
public Pointer storage;
21+
public SixModelObject[] child_objs;
1622
public boolean managed;
1723
public long allocated;
1824
public long elems;
@@ -64,6 +70,45 @@ else if (repr_data.elem_size == 64) {
6470
}
6571
}
6672

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+
67112
public void bind_pos_native(ThreadContext tc, long index) {
68113
CArrayREPRData repr_data = (CArrayREPRData) st.REPRData;
69114

@@ -100,6 +145,31 @@ else if (repr_data.elem_size == 64) {
100145
}
101146
}
102147

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+
103173
private void expand(ThreadContext tc, long new_size) {
104174
CArrayREPRData repr_data = (CArrayREPRData) st.REPRData;
105175

@@ -111,6 +181,33 @@ private void expand(ThreadContext tc, long new_size) {
111181
}
112182
storage = new_storage;
113183
}
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+
114196
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;
115212
}
116213
}

0 commit comments

Comments
 (0)