Skip to content

Instantly share code, notes, and snippets.

@peschwa
Created May 13, 2016 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peschwa/e82fac05cb2382a044bddb6687a15aa1 to your computer and use it in GitHub Desktop.
Save peschwa/e82fac05cb2382a044bddb6687a15aa1 to your computer and use it in GitHub Desktop.
diff --git a/src/core/Iterable.pm b/src/core/Iterable.pm
index b8f070a..c123e3a 100644
--- a/src/core/Iterable.pm
+++ b/src/core/Iterable.pm
@@ -151,4 +151,8 @@ my role Iterable {
}
}
+#?if jvm
+nqp::p6setitertype(Iterable);
+#?endif
+
# vim: ft=perl6 expandtab sw=4
diff --git a/src/vm/jvm/Perl6/Ops.nqp b/src/vm/jvm/Perl6/Ops.nqp
index 26a8cec..7674a7d 100644
--- a/src/vm/jvm/Perl6/Ops.nqp
+++ b/src/vm/jvm/Perl6/Ops.nqp
@@ -90,6 +90,7 @@ $ops.add_hll_op('nqp', 'p6setbinder', -> $qastcomp, $op {
});
$ops.add_hll_op('perl6', 'p6trialbind', :!inlinable, $trial_bind);
$ops.add_hll_op('nqp', 'p6trialbind', :!inlinable, $trial_bind);
+$ops.map_classlib_hll_op('perl6', 'p6setitertype', $TYPE_P6OPS, 'p6setitertype', [$RT_OBJ], $RT_OBJ, :tc);
$ops.map_classlib_hll_op('perl6', 'p6isbindable', $TYPE_P6OPS, 'p6isbindable', [$RT_OBJ, $RT_OBJ], $RT_INT, :tc);
$ops.map_classlib_hll_op('perl6', 'p6bindcaptosig', $TYPE_P6OPS, 'p6bindcaptosig', [$RT_OBJ, $RT_OBJ], $RT_OBJ, :tc);
$ops.map_classlib_hll_op('perl6', 'p6typecheckrv', $TYPE_P6OPS, 'p6typecheckrv', [$RT_OBJ, $RT_OBJ, $RT_OBJ], $RT_OBJ, :tc);
@@ -217,6 +218,7 @@ $ops.add_hll_op('perl6', 'p6sink', -> $qastcomp, $past {
$ops.add_hll_op('nqp', 'p6bool', $p6bool);
$ops.map_classlib_hll_op('nqp', 'p6init', $TYPE_P6OPS, 'p6init', [], $RT_OBJ, :tc);
$ops.map_classlib_hll_op('nqp', 'p6settypes', $TYPE_P6OPS, 'p6settypes', [$RT_OBJ], $RT_OBJ, :tc);
+$ops.map_classlib_hll_op('nqp', 'p6setitertype', $TYPE_P6OPS, 'p6setitertype', [$RT_OBJ], $RT_OBJ, :tc);
$ops.map_classlib_hll_op('nqp', 'p6var', $TYPE_P6OPS, 'p6var', [$RT_OBJ], $RT_OBJ, :tc);
$ops.map_classlib_hll_op('nqp', 'p6isbindable', $TYPE_P6OPS, 'p6isbindable', [$RT_OBJ, $RT_OBJ], $RT_INT, :tc);
$ops.map_classlib_hll_op('nqp', 'p6inpre', $TYPE_P6OPS, 'p6inpre', [], $RT_INT, :tc);
diff --git a/src/vm/jvm/runtime/org/perl6/rakudo/Binder.java b/src/vm/jvm/runtime/org/perl6/rakudo/Binder.java
index 31d15d1..d8a0561 100644
--- a/src/vm/jvm/runtime/org/perl6/rakudo/Binder.java
+++ b/src/vm/jvm/runtime/org/perl6/rakudo/Binder.java
@@ -324,6 +324,7 @@ public final class Binder {
* further checking. */
SixModelObject decontValue = null;
boolean didHLLTransform = false;
+ SixModelObject nomType = null;
if (flag == CallSiteDescriptor.ARG_OBJ && !(is_rw && desiredNative != 0)) {
/* We need to work on the decontainerized value. */
decontValue = Ops.decont(arg_o, tc);
@@ -339,7 +340,7 @@ public final class Binder {
/* Is the nominal type generic and in need of instantiation? (This
* can happen in (::T, T) where we didn't learn about the type until
* during the signature bind). */
- SixModelObject nomType = param.get_attribute_boxed(tc, gcx.Parameter,
+ nomType = param.get_attribute_boxed(tc, gcx.Parameter,
"$!nominal_type", HINT_nominal_type);
if ((paramFlags & SIG_ELEM_NOMINAL_GENERIC) != 0) {
SixModelObject HOW = nomType.st.HOW;
@@ -524,15 +525,25 @@ public final class Binder {
* container and store it, for copy or ro case (the rw bit
* in the container descriptor takes care of the rest). */
else {
- STable stScalar = gcx.Scalar.st;
- SixModelObject new_cont = stScalar.REPR.allocate(tc, stScalar);
- SixModelObject desc = param.get_attribute_boxed(tc, gcx.Parameter,
- "$!container_descriptor", HINT_container_descriptor);
- new_cont.bind_attribute_boxed(tc, gcx.Scalar, "$!descriptor",
- RakudoContainerSpec.HINT_descriptor, desc);
- new_cont.bind_attribute_boxed(tc, gcx.Scalar, "$!value",
- RakudoContainerSpec.HINT_value, decontValue);
- cf.oLex[sci.oTryGetLexicalIdx(varName)] = new_cont;
+ boolean wrap = (paramFlags & SIG_ELEM_IS_COPY) != 0;
+ if (!wrap && nomType != null && gcx.Iterable != null) {
+ wrap = Ops.istype(gcx.Iterable, nomType, tc) != 0
+ || Ops.istype(nomType, gcx.Iterable, tc) != 0;
+ }
+ if (wrap || varName.equals("$_")) {
+ STable stScalar = gcx.Scalar.st;
+ SixModelObject new_cont = stScalar.REPR.allocate(tc, stScalar);
+ SixModelObject desc = param.get_attribute_boxed(tc, gcx.Parameter,
+ "$!container_descriptor", HINT_container_descriptor);
+ new_cont.bind_attribute_boxed(tc, gcx.Scalar, "$!descriptor",
+ RakudoContainerSpec.HINT_descriptor, desc);
+ new_cont.bind_attribute_boxed(tc, gcx.Scalar, "$!value",
+ RakudoContainerSpec.HINT_value, decontValue);
+ cf.oLex[sci.oTryGetLexicalIdx(varName)] = new_cont;
+ }
+ else {
+ cf.oLex[sci.oTryGetLexicalIdx(varName)] = decontValue;
+ }
}
}
}
diff --git a/src/vm/jvm/runtime/org/perl6/rakudo/RakOps.java b/src/vm/jvm/runtime/org/perl6/rakudo/RakOps.java
index 5fe919f..902ec30 100644
--- a/src/vm/jvm/runtime/org/perl6/rakudo/RakOps.java
+++ b/src/vm/jvm/runtime/org/perl6/rakudo/RakOps.java
@@ -37,6 +37,7 @@ public final class RakOps {
public SixModelObject Str;
public SixModelObject List;
public SixModelObject ListIter;
+ public SixModelObject Iterable;
public SixModelObject Array;
public SixModelObject Nil;
public SixModelObject Map;
@@ -87,6 +88,12 @@ public final class RakOps {
}
return null;
}
+
+ public static SixModelObject p6setitertype(SixModelObject type, ThreadContext tc) {
+ GlobalExt gcx = key.getGC(tc);
+ gcx.Iterable = type;
+ return type;
+ }
public static SixModelObject p6settypes(SixModelObject conf, ThreadContext tc) {
GlobalExt gcx = key.getGC(tc);
@@ -101,6 +108,7 @@ public final class RakOps {
gcx.Str = conf.at_key_boxed(tc, "Str");
gcx.List = conf.at_key_boxed(tc, "List");
gcx.ListIter = conf.at_key_boxed(tc, "ListIter");
+ gcx.Iterable = conf.at_key_boxed(tc, "Iterable");
gcx.Array = conf.at_key_boxed(tc, "Array");
gcx.Nil = conf.at_key_boxed(tc, "Nil");
gcx.Map = conf.at_key_boxed(tc, "Map");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment