Skip to content

Commit 9470abb

Browse files
committed
Implement and test nqp::getlexdyn.
1 parent 2635c3b commit 9470abb

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

src/vm/js/QAST/Compiler.nqp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,8 @@ class QAST::OperationsJS {
10791079
} , :sideffects);
10801080
}
10811081

1082+
add_simple_op('getlexdyn', $T_OBJ, [$T_STR], sub ($name) {"{$*BLOCK.ctx}.lookup_dynamic_from_caller($name)"});
1083+
10821084
add_simple_op('captureposelems', $T_INT, [$T_OBJ]);
10831085
add_simple_op('captureposarg', $T_OBJ, [$T_OBJ, $T_INT]);
10841086
add_simple_op('invokewithcapture', $T_OBJ, [$T_OBJ, $T_OBJ], sub ($invokee, $capture) {

src/vm/js/nqp-runtime/runtime.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,19 @@ Ctx.prototype.lookup_dynamic = function(name) {
144144
nqp code usually fallbacks to looking up of global */
145145
};
146146

147+
Ctx.prototype.lookup_dynamic_from_caller = function(name) {
148+
var ctx = this.caller;
149+
while (ctx) {
150+
if (ctx.hasOwnProperty(name)) {
151+
return ctx[name];
152+
}
153+
ctx = ctx.caller;
154+
}
155+
return null;
156+
/* Looking up of a contextual is allowed to fail,
157+
nqp code usually fallbacks to looking up of global */
158+
};
159+
147160
Ctx.prototype.lookup = function(name, value) {
148161
var ctx = this;
149162
while (ctx) {

t/nqp/21-contextual.t

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# Tests for contextual variables
44

5-
plan(7);
5+
plan(10);
66

77
sub foo() { $*VAR }
88

@@ -28,3 +28,27 @@ sub foo() { $*VAR }
2828
}
2929

3030

31+
32+
sub simple_lookup() {
33+
my $foo := nqp::getlexdyn('$*fo' ~ 'o');
34+
ok( $foo eq 'bar', "getting dynamic variable using getlexdyn");
35+
}
36+
37+
{
38+
my $*foo := "bar";
39+
simple_lookup();
40+
}
41+
42+
sub ignore_local() {
43+
my $*foo2;
44+
$*foo2 := "baz";
45+
my $foo := nqp::getlexdyn('$*foo2');
46+
ok( $foo eq 'bar2', "getting dynamic variable using getlexdyn gets the variable from the caller");
47+
ok( nqp::isnull(nqp::getlexdyn("$*no_such")), "nqp::getlexdyn return null for missing variables");
48+
}
49+
50+
{
51+
my $*foo2 := "bar2";
52+
ignore_local();
53+
}
54+

0 commit comments

Comments
 (0)