Skip to content

Commit 3126d69

Browse files
committed
[js] When building Chunks create less empty and one element arrays.
1 parent 1212b7d commit 3126d69

File tree

4 files changed

+77
-52
lines changed

4 files changed

+77
-52
lines changed

src/vm/js/Chunk.nqp

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class Chunk does Joinable {
2424
has $!node; # a QAST::Node that contains info for source maps
2525
has $!setup; # stuff that needs to be executed before the value of $!expr can be used, this contains strings and Chunks.
2626

27-
method new($type, $expr, $setup = [], :$node) {
27+
method new($type, $expr, $setup = nqp::null(), :$node) {
2828
my $obj := nqp::create(self);
2929
$obj.BUILD($type, $expr, $setup, :$node);
3030
$obj
@@ -42,24 +42,38 @@ class Chunk does Joinable {
4242
}
4343

4444
method collect(@strs, :$escape) {
45-
for $!setup -> $part {
46-
if nqp::isstr($part) {
47-
nqp::push_s(@strs, $escape ?? nqp::escape($part) !! $part);
48-
}
49-
else {
50-
$part.collect(@strs, :$escape);
45+
if nqp::isnull($!setup) {
46+
}
47+
elsif nqp::istype($!setup, Chunk) {
48+
$!setup.collect(@strs, :$escape);
49+
}
50+
else {
51+
for $!setup -> $part {
52+
if nqp::isstr($part) {
53+
nqp::push_s(@strs, $escape ?? nqp::escape($part) !! $part);
54+
}
55+
else {
56+
$part.collect(@strs, :$escape);
57+
}
5158
}
5259
}
5360
}
5461

5562
method with_source_map_info() {
5663
my @parts;
57-
for $!setup -> $part {
58-
if nqp::isstr($part) {
59-
nqp::push(@parts,quote_string($part, :json));
60-
}
61-
else {
62-
nqp::push(@parts,$part.with_source_map_info);
64+
if nqp::isnull($!setup) {
65+
}
66+
elsif nqp::istype($!setup, Chunk) {
67+
nqp::push(@parts, $!setup.with_source_map_info);
68+
}
69+
else {
70+
for $!setup -> $part {
71+
if nqp::isstr($part) {
72+
nqp::push(@parts,quote_string($part, :json));
73+
}
74+
else {
75+
nqp::push(@parts,$part.with_source_map_info);
76+
}
6377
}
6478
}
6579
my $parts := '[' ~ nqp::join(',', @parts) ~ ']';
@@ -75,13 +89,20 @@ class Chunk does Joinable {
7589

7690
method source_map_debug() {
7791
my $js := '';
78-
for $!setup -> $part {
79-
if nqp::isstr($part) {
80-
$js := $js ~ $part;
81-
}
82-
else {
83-
$js := $js ~ $part.source_map_debug;
84-
}
92+
if nqp::isnull($!setup) {
93+
}
94+
elsif nqp::istype($!setup, Chunk) {
95+
$js := $js ~ $!setup.source_map_debug;
96+
}
97+
else {
98+
for $!setup -> $part {
99+
if nqp::isstr($part) {
100+
$js := $js ~ $part;
101+
}
102+
else {
103+
$js := $js ~ $part.source_map_debug;
104+
}
105+
}
85106
}
86107

87108
if nqp::defined($!node) && $!node.node {

src/vm/js/Compiler.nqp

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -523,10 +523,10 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
523523
if $desired == $T_NUM {
524524
if $got == $T_INT {
525525
# we store both as a javascript number, and 32bit integers fit into doubles
526-
return Chunk.new($T_NUM, $chunk.expr, [$chunk]);
526+
return Chunk.new($T_NUM, $chunk.expr, $chunk);
527527
}
528528
if $got == $T_BOOL {
529-
return Chunk.new($T_NUM, "({$chunk.expr} ? 1 : 0)", [$chunk]);
529+
return Chunk.new($T_NUM, "({$chunk.expr} ? 1 : 0)", $chunk);
530530
}
531531
if $got == $T_STR {
532532
my $tmp := $*BLOCK.add_tmp();
@@ -536,68 +536,68 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
536536

537537
if $desired == $T_INT {
538538
if $got == $T_STR {
539-
return Chunk.new($T_INT, "parseInt({$chunk.expr})", [$chunk]);
539+
return Chunk.new($T_INT, "parseInt({$chunk.expr})", $chunk);
540540
}
541541
if $got == $T_NUM {
542-
return Chunk.new($T_INT, "({$chunk.expr}|0)", [$chunk]);
542+
return Chunk.new($T_INT, "({$chunk.expr}|0)", $chunk);
543543
}
544544
if $got == $T_BOOL {
545-
return Chunk.new($T_INT, "({$chunk.expr} ? 1 : 0)", [$chunk]);
545+
return Chunk.new($T_INT, "({$chunk.expr} ? 1 : 0)", $chunk);
546546
}
547547
}
548548

549549
if $got == $T_OBJ {
550550
if $desired == $T_BOOL {
551-
return Chunk.new($desired, "{$chunk.expr}.\$\$decont($*CTX).\$\$toBool($*CTX)", [$chunk]);
551+
return Chunk.new($desired, "{$chunk.expr}.\$\$decont($*CTX).\$\$toBool($*CTX)", $chunk);
552552
}
553553
my %convert;
554554
%convert{$T_STR} := 'toStr';
555555
%convert{$T_NUM} := 'toNum';
556556
%convert{$T_INT} := 'toInt';
557-
return Chunk.new($desired, 'nqp.' ~ %convert{$desired} ~ '(' ~ $chunk.expr ~ ", {$*CTX})", [$chunk]);
557+
return Chunk.new($desired, 'nqp.' ~ %convert{$desired} ~ '(' ~ $chunk.expr ~ ", {$*CTX})", $chunk);
558558
}
559559

560560
if $desired == $T_STR {
561561
if $got == $T_INT || $got == $T_NUM {
562-
return Chunk.new($T_STR, $chunk.expr ~ '.toString()', [$chunk]);
562+
return Chunk.new($T_STR, $chunk.expr ~ '.toString()', $chunk);
563563
}
564564
if $got == $T_BOOL {
565-
return Chunk.new($T_STR, "({$chunk.expr} ? '1' : '0')", [$chunk]);
565+
return Chunk.new($T_STR, "({$chunk.expr} ? '1' : '0')", $chunk);
566566
}
567567
}
568568

569569
if $desired == $T_OBJ {
570570
if $got == $T_BOOL {
571-
$chunk := Chunk.new($T_INT, "({$chunk.expr} ? 1 : 0)", [$chunk]);
571+
$chunk := Chunk.new($T_INT, "({$chunk.expr} ? 1 : 0)", $chunk);
572572
$got := $T_INT;
573573
}
574574
elsif $got == $T_VOID {
575575
# TODO think what's the correct thing here
576-
return Chunk.new($T_OBJ, "nqp.Null", [$chunk]);
576+
return Chunk.new($T_OBJ, "nqp.Null", $chunk);
577577
}
578578

579579
if $*HLL eq 'nqp' {
580580
if $got == $T_NUM || $got == $T_STR {
581581
return $chunk;
582582
}
583583
elsif $got == $T_INT {
584-
return Chunk.new($T_OBJ, "new nqp.NQPInt({$chunk.expr})", [$chunk]);
584+
return Chunk.new($T_OBJ, "new nqp.NQPInt({$chunk.expr})", $chunk);
585585
}
586586
}
587587
else {
588588
my %convert;
589589
%convert{$T_INT} := 'intToObj';
590590
%convert{$T_NUM} := 'numToObj';
591591
%convert{$T_STR} := 'strToObj';
592-
return Chunk.new($T_OBJ, "nqp.{%convert{$got}}({quote_string($*HLL)}, {$chunk.expr})", [$chunk]);
592+
return Chunk.new($T_OBJ, "nqp.{%convert{$got}}({quote_string($*HLL)}, {$chunk.expr})", $chunk);
593593
}
594594
}
595595

596596
if $desired == $T_BOOL {
597597
if $got == $T_INT || $got == $T_NUM {
598-
return Chunk.new($T_BOOL, $chunk.expr, [$chunk]);
598+
return Chunk.new($T_BOOL, $chunk.expr, $chunk);
599599
} elsif $got == $T_STR {
600-
return Chunk.new($T_BOOL, "({$chunk.expr} && {$chunk.expr} !== nqp.null_s)", [$chunk]);
600+
return Chunk.new($T_BOOL, "({$chunk.expr} && {$chunk.expr} !== nqp.null_s)", $chunk);
601601
}
602602
}
603603

@@ -805,12 +805,15 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
805805
self.chunk_sequence($want, @chunks, :$result_child, :$node);
806806
}
807807

808-
proto method cpsify_chunk($chunk) { * }
809-
multi method cpsify_chunk(ChunkCPS $chunk) { $chunk }
810-
multi method cpsify_chunk(Chunk $chunk) {
811-
my $ret := self.chunk_sequence($chunk.type, $chunk.setup, :expr($chunk.expr), :node($chunk.node));
812-
$ret;
813-
}
808+
# proto method cpsify_chunk($chunk) { * }
809+
# multi method cpsify_chunk(ChunkCPS $chunk) { $chunk }
810+
# multi method cpsify_chunk(Chunk $chunk) {
811+
# my $ret := self.chunk_sequence($chunk.type, $chunk.setup, :expr($chunk.expr), :node($chunk.node));
812+
# $ret;
813+
# }
814+
815+
method cpsify_chunk($chunk) { $chunk }
816+
# TODO restore CPS
814817

815818
multi method as_js(QAST::Block $node, :$want, :$cps) {
816819
my $outer := try $*BLOCK;
@@ -1710,15 +1713,15 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
17101713
if $*BINDVAL {
17111714
my $bindval := self.as_js_clear_bindval($*BINDVAL, :want($type), :$cps);
17121715
if $var.decl eq 'var' {
1713-
self.stored_result(Chunk.new($type, "({$*CTX}[{quote_string($var.name)}] = {$bindval.expr})", [$bindval]), :$want);
1716+
self.stored_result(Chunk.new($type, "({$*CTX}[{quote_string($var.name)}] = {$bindval.expr})", $bindval), :$want);
17141717
}
17151718
else {
17161719
if $*BLOCK.ctx_for_var($var) -> $ctx {
1717-
self.stored_result(Chunk.new($type, "({$ctx}[{quote_string($var.name)}] = {$bindval.expr})", [$bindval]), :$want);
1720+
self.stored_result(Chunk.new($type, "({$ctx}[{quote_string($var.name)}] = {$bindval.expr})", $bindval), :$want);
17181721
}
17191722
else {
17201723
# nqp::die("we can't find ctx for {$var.name}");
1721-
self.stored_result(Chunk.new($type, "{$*CTX}.bind({quote_string($var.name)}, {$bindval.expr})", [$bindval]), :$want);
1724+
self.stored_result(Chunk.new($type, "{$*CTX}.bind({quote_string($var.name)}, {$bindval.expr})", $bindval), :$want);
17221725
}
17231726
}
17241727
}
@@ -1925,7 +1928,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
19251928
Chunk.new($T_OBJ, $bindval.expr, [$self, $bindval, "{$self.expr}.\$\$bindattr\${$hint}({$bindval.expr});\n"]);
19261929
}
19271930
else {
1928-
Chunk.new($T_OBJ, "{$self.expr}.\$\$getattr\${$hint}()", [$self]);
1931+
Chunk.new($T_OBJ, "{$self.expr}.\$\$getattr\${$hint}()", $self);
19291932
}
19301933
}
19311934
else {
@@ -1935,15 +1938,15 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
19351938
Chunk.new($type, $bindval.expr, [$self, $bindval, "$attr = {$bindval.expr};\n"]);
19361939
}
19371940
else {
1938-
Chunk.new($type, $attr, [$self]);
1941+
Chunk.new($type, $attr, $self);
19391942
}
19401943
}
19411944
}
19421945
}
19431946
elsif $var.scope eq 'contextual' {
19441947
if $*BINDVAL {
19451948
my $bindval := self.as_js_clear_bindval($*BINDVAL, :want($T_OBJ), :$cps);
1946-
self.stored_result(Chunk.new($T_OBJ, "{$*CTX}.bindDynamic({quote_string($var.name)},{$bindval.expr})", [$bindval]), :$want);
1949+
self.stored_result(Chunk.new($T_OBJ, "{$*CTX}.bindDynamic({quote_string($var.name)},{$bindval.expr})", $bindval), :$want);
19471950
}
19481951
else {
19491952
Chunk.new($T_OBJ, "{$*CTX}.lookupDynamic({quote_string($var.name)})");

src/vm/js/Operations.nqp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,10 @@ class QAST::OperationsJS {
316316
my $obj := $comp.as_js(:want($T_OBJ), $node[0]);
317317
if static_hint($node) -> $hint {
318318
if $type == $T_OBJ {
319-
Chunk.new($T_OBJ, "{$obj.expr}\.\$\$getattr\${$hint}()", [$obj]);
319+
Chunk.new($T_OBJ, "{$obj.expr}\.\$\$getattr\${$hint}()", $obj);
320320
}
321321
else {
322-
Chunk.new($type, "{$obj.expr}\.attr\${$hint}", [$obj]);
322+
Chunk.new($type, "{$obj.expr}\.attr\${$hint}", $obj);
323323
}
324324
}
325325
else {
@@ -632,7 +632,8 @@ class QAST::OperationsJS {
632632

633633
my $compiled_args := $comp.args($args, :$cont);
634634

635-
my @setup := nqp::clone($compiled_args.setup);
635+
### setup_as_array NYI
636+
my @setup := nqp::clone($compiled_args.setup_as_array);
636637
@setup.unshift($callee);
637638

638639
my $call := $compiled_args.is_args_array ?? '.$$applyCPS(' !! '.$$callCPS(';

src/vm/js/RegexCompiler.nqp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,12 +335,12 @@ class RegexCompiler {
335335

336336
$call := Chunk.new($T_OBJ,
337337
$!cursor ~ '[' ~ quote_string($method) ~ "]" ~ $invocation ~ $compiled_args.expr ~ ')',
338-
[$compiled_args]);
338+
$compiled_args);
339339
}
340340
else {
341341
#TODO think if arguments are possible, etc.
342342
my $block := $!compiler.as_js($node[0][0], :want($T_OBJ));
343-
$call := Chunk.new($T_OBJ, $block.expr ~ ".\$\$call({$*CTX}, null, $!cursor)", [$block]);
343+
$call := Chunk.new($T_OBJ, $block.expr ~ ".\$\$call({$*CTX}, null, $!cursor)", $block);
344344
}
345345

346346
my $testop := $node.negate ?? '>=' !! '<';

0 commit comments

Comments
 (0)