Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[js] Implement nqp::capturenamedshash.
Also stop declared named parameters from getting into the slurpy named hash.
  • Loading branch information
pmurias committed Jan 13, 2016
1 parent 9cb2383 commit 10218d3
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 7 deletions.
19 changes: 17 additions & 2 deletions src/vm/js/QAST/Compiler.nqp
Expand Up @@ -385,6 +385,15 @@ my class BlockBarrier {
method outer() { $!outer }
}

# TODO benchmark keeping a constant version of this
sub known_named(@known_named) {
my @pairs;
for @known_named -> $named {
@pairs.push($named ~ ": true");
}
'{' ~ nqp::join(',', @pairs) ~ '}'
}

class QAST::OperationsJS {
my %ops;

Expand Down Expand Up @@ -1469,7 +1478,7 @@ class QAST::OperationsJS {

for <savecapture usecapture> -> $op {
add_simple_op($op, $T_OBJ, [], sub () {
"nqp.op.savecapture(Array.prototype.slice.call(arguments))"
"nqp.op.savecapture(Array.prototype.slice.call(arguments), {known_named(@*KNOWN_NAMED)})"
} , :sideffects);
}

Expand All @@ -1480,6 +1489,8 @@ class QAST::OperationsJS {
add_simple_op('capturehasnameds', $T_INT, [$T_OBJ]);
add_simple_op('captureposelems', $T_INT, [$T_OBJ]);
add_simple_op('captureposarg', $T_OBJ, [$T_OBJ, $T_INT]);
add_simple_op('capturenamedshash', $T_OBJ, [$T_OBJ]);

add_simple_op('invokewithcapture', $T_OBJ, [$T_OBJ, $T_OBJ], sub ($invokee, $capture) {
"$invokee.\$apply([{$*CTX}].concat($capture.named, $capture.pos))"
}, :sideffects);
Expand Down Expand Up @@ -2509,6 +2520,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
@sig.push($cps);
}


my $bind_named := '';
for @params {
if $_.slurpy {
Expand All @@ -2521,6 +2533,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
$*BLOCK.add_js_lexical(self.mangle_name($_.name));
} elsif $_.named {
my $quoted := quote_string($_.named);
@*KNOWN_NAMED.push($quoted);
my $value := "_NAMED[$quoted]";
if $_.default {
# TODO types
Expand Down Expand Up @@ -2582,7 +2595,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
@setup.push("{self.mangle_name($slurpy.name)} = Array.prototype.slice.call(arguments,{+@sig});\n");
}
if $slurpy_named {
@setup.push("{self.mangle_name($slurpy_named.name)} = nqp.slurpy_named(_NAMED);\n");
@setup.push("{self.mangle_name($slurpy_named.name)} = nqp.slurpy_named(_NAMED, {known_named(@*KNOWN_NAMED)});\n");
}

Chunk.new($T_NONVAL, nqp::join(',', @sig), @setup);
Expand Down Expand Up @@ -3007,6 +3020,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
} else {
self.register_cuid($node);

my @*KNOWN_NAMED;
my $*BINDVAL := 0;
my $*BLOCK := BlockInfo.new($node, (nqp::defined($outer) ?? $outer !! NQPMu));

Expand Down Expand Up @@ -3059,6 +3073,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
# TODO recreate other things than block

if $!cps ne 'off' {
my @*KNOWN_NAMED;
my $*BLOCK := BlockInfo.new($node, (nqp::defined($outer) ?? $outer !! NQPMu));

my $stmts_cps := self.compile_all_the_statements($node, $body_want, :cps);
Expand Down
23 changes: 18 additions & 5 deletions src/vm/js/nqp-runtime/core.js
Expand Up @@ -163,10 +163,12 @@ exports.hash = function() {
return new Hash();
};

exports.slurpy_named = function(named) {
exports.slurpy_named = function(named, skip) {
var hash = new Hash();
for (key in named) {
hash.content.set(key, named[key]);
if (!skip[key]) {
hash.content.set(key, named[key]);
}
}
return hash;
};
Expand Down Expand Up @@ -231,13 +233,14 @@ op.setboolspec = function(obj, mode, method) {
return obj;
};

function Capture(named, pos) {
function Capture(named, pos, skip) {
this.pos = pos;
this.named = named;
this.skip = skip;
}

op.savecapture = function(args) {
return new Capture(args[1], Array.prototype.slice.call(args, 2));
op.savecapture = function(args, skip) {
return new Capture(args[1], Array.prototype.slice.call(args, 2), skip);
};

op.captureposelems = function(capture) {
Expand All @@ -256,6 +259,16 @@ op.captureexistsnamed = function(capture, arg) {
return capture.named.hasOwnProperty(arg) ? 1 : 0;
};

op.capturenamedshash = function(capture) {
var hash = new Hash();
for (key in capture.named) {
if (!capture.skip[key]) {
hash.content.set(key, capture.named[key]);
}
}
return hash;
};

op.setcodeobj = function(codeRef, codeObj) {
codeRef.codeObj = codeObj;
return codeRef;
Expand Down

0 comments on commit 10218d3

Please sign in to comment.