minjs 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/minjs/compressor.rb +264 -162
- data/lib/minjs/ctype.rb +843 -829
- data/lib/minjs/ecma262/env.rb +1 -1
- data/lib/minjs/ecma262/exp.rb +84 -45
- data/lib/minjs/ecma262/lit.rb +272 -58
- data/lib/minjs/ecma262/st.rb +0 -4
- data/lib/minjs/lex.rb +3 -10
- data/lib/minjs/statement.rb +12 -11
- data/lib/minjs/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a1f04643d50c1beca0d24712ec63604fd2f0cd8
|
4
|
+
data.tar.gz: 95e7f5fe15dcf50dbc08e2428ef4d9b1d7735a06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86c244ba18493772c481a2242758a589634e7799c7da5e545c22b3c2366908c2281dadf16a0f074bcb8c60ecccb2bac5137e379d2f245cf4c8694abb3a23f2c9
|
7
|
+
data.tar.gz: 0e84e49b46819f3991fde8a2821121eead7a29373e4e1dc23c7a41e6a35fb72eaf6a108bf9881256ba36bcb722b58ee91d8feedc25cd833794f89e807f6d9cea
|
data/lib/minjs/compressor.rb
CHANGED
@@ -73,6 +73,7 @@ module Minjs
|
|
73
73
|
:block_to_statement,
|
74
74
|
:if_to_cond,
|
75
75
|
:optimize_if_return2,
|
76
|
+
:optimize_if_return3,
|
76
77
|
:remove_paren,
|
77
78
|
]
|
78
79
|
algo.each do |a|
|
@@ -181,7 +182,12 @@ module Minjs
|
|
181
182
|
}
|
182
183
|
flist.reverse.each do |st, parent|
|
183
184
|
parent.remove(st)
|
184
|
-
parent.statement_list
|
185
|
+
sl = parent.statement_list
|
186
|
+
if sl[0].kind_of? ECMA262::StExp and sl[0].exp.kind_of? ECMA262::ECMA262String and sl[0].exp.val == "use strict"
|
187
|
+
sl[1,0] = st
|
188
|
+
else
|
189
|
+
sl.unshift(st)
|
190
|
+
end
|
185
191
|
end
|
186
192
|
self
|
187
193
|
end
|
@@ -238,10 +244,11 @@ module Minjs
|
|
238
244
|
|
239
245
|
idx = 0
|
240
246
|
elems.each do |e|
|
241
|
-
next if e.kind_of? ECMA262::StFunc and e.decl?
|
242
247
|
found = false
|
243
248
|
if e.kind_of? ECMA262::StFunc and e.decl?
|
244
249
|
;
|
250
|
+
elsif e.kind_of? ECMA262::StExp and e.exp.kind_of? ECMA262::ECMA262String and e.exp.val == "use strict"
|
251
|
+
;
|
245
252
|
else
|
246
253
|
e.traverse(nil){|ee, pp|
|
247
254
|
if ee.kind_of? ECMA262::IdentifierName and var_vars[ee.val.to_sym]
|
@@ -468,187 +475,248 @@ module Minjs
|
|
468
475
|
}
|
469
476
|
self
|
470
477
|
end
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
478
|
+
#
|
479
|
+
# feature
|
480
|
+
#
|
481
|
+
# if(a)b;else return c;
|
482
|
+
# =>
|
483
|
+
# if(!a)return c;b;
|
484
|
+
#
|
485
|
+
def optimize_if_return3(node = @prog)
|
486
|
+
node.traverse(nil) {|st, parent|
|
487
|
+
if st.kind_of? ECMA262::StIf and st.else_st and parent.kind_of? ECMA262::StatementList
|
488
|
+
st.remove_empty_statement
|
489
|
+
if (st.else_st.kind_of? ECMA262::StBlock and st.else_st[-1].kind_of? ECMA262::StReturn) or
|
490
|
+
st.else_st.kind_of? ECMA262::StReturn
|
491
|
+
idx = parent.index(st)
|
492
|
+
parent[idx+1..0] = st.then_st
|
493
|
+
st.instance_eval{
|
494
|
+
@then_st = @else_st
|
495
|
+
@else_st = nil
|
496
|
+
@cond = ECMA262::ExpLogicalNot.new(@cond)
|
497
|
+
}
|
498
|
+
end
|
499
|
+
end
|
500
|
+
}
|
501
|
+
self
|
475
502
|
end
|
476
503
|
|
477
|
-
def
|
478
|
-
|
479
|
-
|
480
|
-
#
|
481
|
-
scopes = []
|
504
|
+
def compress_var(node = @prog, options = {})
|
505
|
+
func_scopes = []
|
506
|
+
catch_scopes = []
|
482
507
|
node.traverse(nil) {|st, parent|
|
483
508
|
if st.kind_of? ECMA262::StFunc
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
509
|
+
func_scopes.push([st, parent])
|
510
|
+
elsif st.kind_of? ECMA262::StTry
|
511
|
+
catch_scopes.push([st, parent])
|
512
|
+
elsif st.kind_of? ECMA262::StWith
|
513
|
+
#TODO
|
488
514
|
end
|
489
515
|
}
|
490
|
-
|
491
|
-
|
516
|
+
#10.2
|
517
|
+
#
|
518
|
+
# Catch clause of a TryStatement and a new Lexical Environment is
|
519
|
+
# created each time such code is evaluated.
|
520
|
+
#
|
521
|
+
catch_scopes.each{|st, parent|
|
522
|
+
catch_context = ECMA262::Context.new
|
523
|
+
catch_context.lex_env = st.context.lex_env.new_declarative_env()
|
524
|
+
catch_context.var_env = st.context.var_env
|
525
|
+
catch_context.lex_env.record.create_mutable_binding(st.catch[0], nil)
|
526
|
+
catch_context.lex_env.record.set_mutable_binding(st.catch[0], :undefined, nil)
|
527
|
+
st.catch[0].context = catch_context
|
528
|
+
|
529
|
+
st.catch[1].traverse(parent){|st2|
|
530
|
+
if st2.kind_of? ECMA262::IdentifierName and st2 == st.catch[0] and
|
531
|
+
st2.binding_env == st.catch[0].binding_env
|
532
|
+
st2.context = catch_context
|
533
|
+
end
|
534
|
+
}
|
535
|
+
func_scopes.unshift([st, parent])
|
536
|
+
}
|
537
|
+
func_scopes.reverse!
|
538
|
+
func_scopes.each {|st, parent|
|
539
|
+
if st.kind_of? ECMA262::StFunc
|
540
|
+
context = st.context
|
541
|
+
elsif st.kind_of? ECMA262::StTry
|
542
|
+
context = st.catch[0].context
|
543
|
+
end
|
492
544
|
var_sym = :a
|
493
|
-
|
545
|
+
#
|
546
|
+
# collect and counting all variables under this function
|
547
|
+
#
|
548
|
+
all_vars = {}
|
549
|
+
var_vars = {}
|
550
|
+
var_vars_list = []
|
551
|
+
outer_vars = {}
|
552
|
+
nesting_vars = {}
|
553
|
+
nesting_vars_list = []
|
554
|
+
|
555
|
+
st.traverse(parent) {|st2|
|
494
556
|
#
|
495
|
-
#
|
496
|
-
#
|
557
|
+
# Next, tring to rename var_vars(see bellow) to
|
558
|
+
# new name.
|
497
559
|
#
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
#
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
#
|
525
|
-
|
526
|
-
var_name
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
end
|
550
|
-
if e.nil?
|
551
|
-
outer_vars[var_name] ||= 0
|
552
|
-
outer_vars[var_name] += 1
|
553
|
-
break
|
554
|
-
end
|
560
|
+
# 1. outer_vars:
|
561
|
+
# Variables which locate out of this function(or global variable)
|
562
|
+
# Them name cannot be renamed
|
563
|
+
# 2. nesting_vars:
|
564
|
+
# Variables which locate in the function of this function.
|
565
|
+
# Them name cannot be renamed
|
566
|
+
# 3. var_vars:
|
567
|
+
# Variables which have same scope in this function.
|
568
|
+
# 4. all_vars:
|
569
|
+
# All variables under this function.
|
570
|
+
#
|
571
|
+
# a. If the new name is not in all_vars, the name can be renamed to it.
|
572
|
+
# b. If the new name belongs to var_vars, the name cannot be renamed.
|
573
|
+
# c. If the new name belongs to outer_vars the name cannot be renamed.
|
574
|
+
# d. If the new name belongs to nesting_vars, the name can be rename
|
575
|
+
# to it after renaming nesting_vars's name to another name.
|
576
|
+
#
|
577
|
+
if st2.kind_of? ECMA262::IdentifierName
|
578
|
+
var_name = st2.val.to_sym
|
579
|
+
#st2_var_env = st2.binding_env
|
580
|
+
st2_lex_env = st2.binding_env(:lex)
|
581
|
+
all_vars[var_name] ||= 0
|
582
|
+
all_vars[var_name] += 1
|
583
|
+
if st2_lex_env == nil #global
|
584
|
+
outer_vars[var_name] ||= 0
|
585
|
+
outer_vars[var_name] += 1
|
586
|
+
elsif st2_lex_env == @global_context.lex_env #global
|
587
|
+
outer_vars[var_name] ||= 0
|
588
|
+
outer_vars[var_name] += 1
|
589
|
+
# elsif st2_lex_env == context.lex_env and st2_lex_env != context.lex_env
|
590
|
+
# nesting_vars[var_name] ||= 0
|
591
|
+
# nesting_vars[var_name] += 1
|
592
|
+
# nesting_vars_list.push(st2)
|
593
|
+
elsif st2_lex_env == context.lex_env
|
594
|
+
var_vars[var_name] ||= 0
|
595
|
+
var_vars[var_name] += 1
|
596
|
+
var_vars_list.push(st2)
|
597
|
+
else
|
598
|
+
e = st2.binding_env(:lex)
|
599
|
+
while e
|
600
|
+
e = e.outer
|
601
|
+
if e == context.lex_env
|
602
|
+
nesting_vars[var_name] ||= 0
|
603
|
+
nesting_vars[var_name] += 1
|
604
|
+
nesting_vars_list.push(st2)
|
605
|
+
break
|
606
|
+
end
|
607
|
+
if e.nil?
|
608
|
+
outer_vars[var_name] ||= 0
|
609
|
+
outer_vars[var_name] += 1
|
610
|
+
break
|
555
611
|
end
|
556
612
|
end
|
557
613
|
end
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
}
|
567
|
-
if eval_flag
|
568
|
-
next
|
614
|
+
end
|
615
|
+
}
|
616
|
+
unless var_vars[:eval]
|
617
|
+
eval_flag = false
|
618
|
+
st.traverse(parent) {|st2|
|
619
|
+
if st2.kind_of? ECMA262::ExpCall and st2.name.to_js({}) == "eval"
|
620
|
+
eval_flag = true
|
621
|
+
break
|
569
622
|
end
|
623
|
+
}
|
624
|
+
if eval_flag
|
625
|
+
next
|
570
626
|
end
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
627
|
+
end
|
628
|
+
#
|
629
|
+
# sort var_vars
|
630
|
+
#
|
631
|
+
var_vars_array = var_vars.sort {|(k1,v1), (k2,v2)| v2 <=> v1}
|
632
|
+
#
|
633
|
+
# create renaming table
|
634
|
+
#
|
635
|
+
rename_table = {}
|
636
|
+
var_vars_array.each {|name, count|
|
637
|
+
if name.nil?
|
638
|
+
next #bug?
|
639
|
+
end
|
640
|
+
#STDERR.puts "trying to rename #{name}"
|
641
|
+
while true
|
642
|
+
#condition b
|
643
|
+
if var_vars[var_sym]
|
644
|
+
#STDERR.puts "var_vars has #{var_sym}"
|
645
|
+
#condigion c
|
646
|
+
elsif outer_vars[var_sym]
|
647
|
+
#STDERR.puts "outer_vars has #{var_sym}"
|
648
|
+
else #condition a&d
|
649
|
+
#STDERR.puts "->#{var_sym}"
|
650
|
+
break
|
582
651
|
end
|
583
|
-
|
584
|
-
|
652
|
+
var_sym = next_sym(var_sym)
|
653
|
+
end
|
654
|
+
#rename nesting_vars
|
655
|
+
if nesting_vars[var_sym]
|
656
|
+
#STDERR.puts "nesting_vars has #{var_sym}"
|
657
|
+
nesting_vars_list.each do |x|
|
658
|
+
#raise 'error' if x.binding_env(:var).nil?
|
659
|
+
raise 'error' if x.binding_env(:lex).nil?
|
585
660
|
end
|
586
|
-
#rename nesting_vars
|
587
|
-
if nesting_vars[var_sym]
|
588
|
-
nesting_vars_list.each do |x|
|
589
|
-
raise 'error' if x.binding_env(:var).nil?
|
590
|
-
raise 'error' if x.binding_env(:lex).nil?
|
591
|
-
end
|
592
661
|
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
662
|
+
var_sym2 = "XXX#{var_sym.to_s}".to_sym
|
663
|
+
while all_vars[var_sym2]
|
664
|
+
var_sym2 = next_sym(var_sym2)
|
665
|
+
end
|
666
|
+
#STDERR.puts "#{var_sym}->#{var_sym2}"
|
667
|
+
rl = {}
|
668
|
+
nesting_vars_list.each do |x|
|
669
|
+
if x.val.to_sym == var_sym
|
670
|
+
_var_env = x.binding_env(:var)
|
671
|
+
_lex_env = x.binding_env(:lex)
|
672
|
+
rl[_var_env] = true
|
673
|
+
rl[_lex_env] = true
|
605
674
|
end
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
675
|
+
end
|
676
|
+
rl.keys.each do |_env|
|
677
|
+
if _env && _env.record.binding[var_sym]
|
678
|
+
_env.record.binding[var_sym2] = _env.record.binding[var_sym]
|
679
|
+
_env.record.binding.delete var_sym
|
611
680
|
end
|
681
|
+
end
|
612
682
|
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
end
|
619
|
-
raise 'error' if x.binding_env(:var).nil?
|
620
|
-
raise 'error' if x.binding_env(:lex).nil?
|
683
|
+
nesting_vars_list.each do |x|
|
684
|
+
if x.val.to_sym == var_sym
|
685
|
+
x.instance_eval{
|
686
|
+
@val = var_sym2
|
687
|
+
}
|
621
688
|
end
|
689
|
+
#raise 'error' if x.binding_env(:var).nil?
|
690
|
+
raise 'error' if x.binding_env(:lex).nil?
|
622
691
|
end
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
692
|
+
end
|
693
|
+
rename_table[name] = var_sym
|
694
|
+
var_sym = next_sym(var_sym)
|
695
|
+
}
|
696
|
+
var_vars_list.each {|st2|
|
697
|
+
raise st2.to_js if st2.binding_env(:lex).nil?
|
698
|
+
}
|
630
699
|
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
end
|
700
|
+
rename_table.each do |name, new_name|
|
701
|
+
if name != new_name
|
702
|
+
if context.var_env.record.binding[name]
|
703
|
+
context.var_env.record.binding[new_name] = context.var_env.record.binding[name]
|
704
|
+
context.var_env.record.binding.delete(name)
|
705
|
+
end
|
706
|
+
if context.lex_env.record.binding[name]
|
707
|
+
context.lex_env.record.binding[new_name] = context.lex_env.record.binding[name]
|
708
|
+
context.lex_env.record.binding.delete(name)
|
641
709
|
end
|
642
710
|
end
|
711
|
+
end
|
643
712
|
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
}
|
648
|
-
raise 'error' if st2.binding_env(:var).nil?
|
649
|
-
raise 'error' if st2.binding_env(:lex).nil?
|
713
|
+
var_vars_list.each {|st2|
|
714
|
+
st2.instance_eval{
|
715
|
+
@val = rename_table[@val]
|
650
716
|
}
|
651
|
-
|
717
|
+
#raise 'error' if st2.binding_env(:var).nil?
|
718
|
+
raise 'error' if st2.binding_env(:lex).nil?
|
719
|
+
}
|
652
720
|
}
|
653
721
|
self
|
654
722
|
end
|
@@ -676,16 +744,19 @@ module Minjs
|
|
676
744
|
parent.replace(st, ECMA262::ExpParen.new(ECMA262::ExpLogicalNot.new(ECMA262::ECMA262Numeric.new(1))))
|
677
745
|
end
|
678
746
|
#
|
679
|
-
#if(true){<then>}else{<else>} => then
|
747
|
+
#if(true){<then>}else{<else>} => <then>
|
748
|
+
#if(false){<then>}else{<else>} => <else>
|
680
749
|
#
|
681
750
|
elsif st.kind_of? ECMA262::StIf
|
682
751
|
if st.cond.respond_to? :to_ecma262_boolean
|
683
|
-
if st.cond.to_ecma262_boolean
|
752
|
+
if st.cond.to_ecma262_boolean.nil?
|
753
|
+
;
|
754
|
+
elsif st.cond.to_ecma262_boolean == true
|
684
755
|
parent.replace(st, st.then_st)
|
685
|
-
elsif st.else_st
|
756
|
+
elsif st.cond.to_ecma262_boolean == false and st.else_st
|
686
757
|
parent.replace(st, st.else_st)
|
687
|
-
|
688
|
-
parent.replace(st, ECMA262::StEmpty.new
|
758
|
+
elsif st.cond.to_ecma262_boolean == false
|
759
|
+
parent.replace(st, ECMA262::StEmpty.new)
|
689
760
|
end
|
690
761
|
end
|
691
762
|
#
|
@@ -693,7 +764,9 @@ module Minjs
|
|
693
764
|
# while(false) => remove
|
694
765
|
#
|
695
766
|
elsif st.kind_of? ECMA262::StWhile and st.exp.respond_to? :to_ecma262_boolean
|
696
|
-
if st.exp.to_ecma262_boolean
|
767
|
+
if st.exp.to_ecma262_boolean.nil?
|
768
|
+
;
|
769
|
+
elsif st.exp.to_ecma262_boolean
|
697
770
|
parent.replace(st, ECMA262::StFor.new(nil,nil,nil, st.statement))
|
698
771
|
else
|
699
772
|
parent.replace(st, ECMA262::StEmpty.new)
|
@@ -756,6 +829,35 @@ module Minjs
|
|
756
829
|
parent.replace(st, ECMA262::StBlock.new([st]))
|
757
830
|
retry_flag = true
|
758
831
|
end
|
832
|
+
=begin
|
833
|
+
#feature
|
834
|
+
#
|
835
|
+
#if(!(a&&b))
|
836
|
+
#=>
|
837
|
+
#if(!a||!b)
|
838
|
+
#
|
839
|
+
#if(!(a||b))
|
840
|
+
#=>
|
841
|
+
#if(!a&&!b)
|
842
|
+
#
|
843
|
+
if st.cond.kind_of? ECMA262::ExpLogicalNot and st.cond.val.kind_of? ECMA262::ExpParen and
|
844
|
+
st.cond.val.val.kind_of? ECMA262::ExpLogicalAnd
|
845
|
+
a = ECMA262::ExpLogicalNot.new(st.cond.val.val.val)
|
846
|
+
b = ECMA262::ExpLogicalNot.new(st.cond.val.val.val2)
|
847
|
+
r = ECMA262::ExpLogicalOr.new(a,b).add_paren.remove_paren
|
848
|
+
if r.to_js.length < st.cond.to_js.length
|
849
|
+
st.replace(st.cond, r)
|
850
|
+
end
|
851
|
+
elsif st.cond.kind_of? ECMA262::ExpLogicalNot and st.cond.val.kind_of? ECMA262::ExpParen and
|
852
|
+
st.cond.val.val.kind_of? ECMA262::ExpLogicalOr
|
853
|
+
a = ECMA262::ExpLogicalNot.new(st.cond.val.val.val)
|
854
|
+
b = ECMA262::ExpLogicalNot.new(st.cond.val.val.val2)
|
855
|
+
r = ECMA262::ExpLogicalAnd.new(a,b).add_paren.remove_paren
|
856
|
+
if r.to_js.length < st.cond.to_js.length
|
857
|
+
st.replace(st.cond, r)
|
858
|
+
end
|
859
|
+
end
|
860
|
+
=end
|
759
861
|
end
|
760
862
|
}
|
761
863
|
block_to_statement if retry_flag
|