Created
May 13, 2016 19:11
-
-
Save peschwa/e82fac05cb2382a044bddb6687a15aa1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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