Skip to content

Commit b980c6d

Browse files
committed
[js] Avoid emitting CPS-less versions of blocks that only work in CPS-mode.
1 parent 3cbb936 commit b980c6d

File tree

2 files changed

+51
-33
lines changed

2 files changed

+51
-33
lines changed

src/vm/js/QAST/Compiler.nqp

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2771,8 +2771,15 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
27712771
my $reg := $_.value;
27722772
my $cuid := self.mangled_cuid($_.key);
27732773

2774-
@clone_inners.push("$reg = $cuid.closure");
2775-
@clone_inners.push(%*BLOCKS_DONE{$_.key});
2774+
if %*BLOCKS_DONE{$_.key} {
2775+
@clone_inners.push("$reg = $cuid.closure");
2776+
@clone_inners.push(%*BLOCKS_DONE{$_.key});
2777+
} elsif %*BLOCKS_DONE_CPS{$_.key} {
2778+
@clone_inners.push("$reg = $cuid.onlyCPS()");
2779+
} else {
2780+
say("//Broken block: {$_.key}");
2781+
}
2782+
27762783
if %*BLOCKS_DONE_CPS{$_.key} {
27772784
@clone_inners.push(".CPS");
27782785
@clone_inners.push(%*BLOCKS_DONE_CPS{$_.key});
@@ -2817,21 +2824,41 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
28172824

28182825
my $stmts := self.compile_all_the_statements($node, $body_want);
28192826

2820-
my $sig := self.compile_sig($*BLOCK.params);
2821-
2822-
my @function := [
2823-
"function({$sig.expr}) \{\n",
2824-
self.setup_setting($node),
2825-
self.declare_js_vars($*BLOCK.tmps),
2826-
self.declare_js_vars($*BLOCK.js_lexicals),
2827-
$create_ctx,
2828-
$sig,
2829-
self.clone_inners($*BLOCK),
2830-
self.capture_inners($*BLOCK),
2831-
$stmts,
2832-
"return {$stmts.expr};\n",
2833-
"\}"
2834-
];
2827+
if nqp::istype($stmts, ChunkCPS) {
2828+
say("//can't emit closure version of block");
2829+
} else {
2830+
my $sig := self.compile_sig($*BLOCK.params);
2831+
2832+
my @function := [
2833+
"function({$sig.expr}) \{\n",
2834+
self.setup_setting($node),
2835+
self.declare_js_vars($*BLOCK.tmps),
2836+
self.declare_js_vars($*BLOCK.js_lexicals),
2837+
$create_ctx,
2838+
$sig,
2839+
self.clone_inners($*BLOCK),
2840+
self.capture_inners($*BLOCK),
2841+
$stmts,
2842+
"return {$stmts.expr};\n",
2843+
"\}"
2844+
];
2845+
%*BLOCKS_DONE{$node.cuid} := Chunk.void("(", |@function, ")");
2846+
2847+
if self.is_block_part_of_sc($node) {
2848+
if $node.blocktype eq 'immediate' {
2849+
# TODO think about that, and find a way to test this
2850+
#say("// it's an immediate one");
2851+
} else {
2852+
%!serialized_code_ref_info{$node.cuid} := SerializedCodeRefInfo.new(
2853+
closure_template => Chunk.new($T_OBJ, "", @function).join(),
2854+
ctx => $*CTX,
2855+
outer_ctx => (nqp::defined($*BLOCK.outer) ?? $*BLOCK.outer.ctx !! ""),
2856+
static_info => self.static_info_for_lexicals($*BLOCK)
2857+
);
2858+
}
2859+
}
2860+
}
2861+
28352862

28362863
# The CPS version
28372864

@@ -2847,7 +2874,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
28472874
self.declare_js_vars($*BLOCK.tmps),
28482875
self.declare_js_vars($*BLOCK.js_lexicals),
28492876
$create_ctx,
2850-
$sig,
2877+
$sig_cps,
28512878
self.clone_inners($*BLOCK),
28522879
self.capture_inners($*BLOCK),
28532880
$stmts_cps,
@@ -2860,23 +2887,9 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
28602887
}
28612888

28622889

2863-
%*BLOCKS_DONE{$node.cuid} := Chunk.void("(", |@function, ")");
28642890

28652891

28662892

2867-
if self.is_block_part_of_sc($node) {
2868-
if $node.blocktype eq 'immediate' {
2869-
# TODO think about that, and find a way to test this
2870-
#say("// it's an immediate one");
2871-
} else {
2872-
%!serialized_code_ref_info{$node.cuid} := SerializedCodeRefInfo.new(
2873-
closure_template => Chunk.new($T_OBJ, "", @function).join(),
2874-
ctx => $*CTX,
2875-
outer_ctx => (nqp::defined($*BLOCK.outer) ?? $*BLOCK.outer.ctx !! ""),
2876-
static_info => self.static_info_for_lexicals($*BLOCK)
2877-
);
2878-
}
2879-
}
28802893

28812894
}
28822895

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ CodeRef.prototype.sameCPS = function(block) {
6060
return this;
6161
};
6262

63-
63+
CodeRef.prototype.onlyCPS = function(block) {
64+
this.$call = function() {
65+
throw "this block can be only called in CPS mode";
66+
};
67+
return this;
68+
};
6469

6570
CodeRef.prototype.setCodeObj = function(codeObj) {
6671
this.codeObj = codeObj;

0 commit comments

Comments
 (0)