minjs 0.4.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cf7918e2d61056e016f1903050b7866612ab4dc0
4
- data.tar.gz: 0576989a9e9705cb43a696d10532d848ee83d27c
3
+ metadata.gz: f2378eb52a7085927e5c4068a9396d656e14dcf0
4
+ data.tar.gz: b3a936cdae1ebc77424d0a2330ee78bdf4b56922
5
5
  SHA512:
6
- metadata.gz: ccf02697889e825b9c5bb7fdb80d91e235980753d3f8aa1c8598cf1512e06b638e8365d23197fa774812d7d5efbcc8c66805872a34072cefc5c81645a2bbbcf9
7
- data.tar.gz: 373dd8eed54811bfae0a1498224fb775e47075d00a5c71087f1644063a2d697241101418cffac5aa028e2829758c429f8acf584c1b33b32ad783aca0a1519cff
6
+ metadata.gz: 86114b8ef9ef2ca9eb0ec5b15b532b49b138f3052b1ef10aaa6fa9433cbbdaa1837905b1b59a816eed0b6ab6182270a165d7aeb8e93c150fc71bc0ab6ae72d96
7
+ data.tar.gz: 458383c20b91c43c8a64c9c70896d54cfdbe34cdeaea3e129393a2ba7a371236cc10ec0cce8d0e7f4d6d537e1c3aa5a3d0ea261c9d2eafa5d9f1b5607c5a54eb
@@ -88,7 +88,7 @@ module Minjs::Compressor
88
88
  # @return self
89
89
  def parse(data)
90
90
  @lex = Minjs::Lex::Parser.new(data, :logger => @logger)
91
- @global_context = ECMA262::Context.new
91
+ @global_var_env = ECMA262::LexEnv.new(outer: nil)
92
92
  @heading_comments = []
93
93
 
94
94
  while a = (@lex.comment || @lex.line_terminator || @lex.white_space)
@@ -98,7 +98,8 @@ module Minjs::Compressor
98
98
  !(@heading_comments[-2].kind_of?(ECMA262::SingleLineComment))
99
99
  @heading_comments.pop
100
100
  end
101
- @prog = @lex.program(@global_context)
101
+ @prog = @lex.program(@global_var_env)
102
+ @prog.exe_context = ECMA262::ExeContext.new
102
103
 
103
104
  remove_empty_statement
104
105
  @lex.clear_cache
@@ -203,12 +204,12 @@ module Minjs::Compressor
203
204
  node.traverse(nil) {|parent, st|
204
205
  if st.kind_of? ECMA262::Prog
205
206
  vars = nil
206
- context = st.context
207
+ var_env = st.var_env
207
208
  #
208
209
  # collect all of var variable in this function
209
210
  #
210
211
  var_vars = {}
211
- context.var_env.record.binding.each do|k, v|
212
+ var_env.record.binding.each do|k, v|
212
213
  if v and v[:_parameter_list].nil? and !v[:value].kind_of?(ECMA262::StFunc)
213
214
  var_vars[k] = true
214
215
  end
@@ -218,7 +219,7 @@ module Minjs::Compressor
218
219
  # if variable has initializer
219
220
  #
220
221
  st.traverse(parent){|parent2, st2|
221
- if st2.kind_of? ECMA262::StVar and st2.context.var_env == context.var_env
222
+ if st2.kind_of? ECMA262::StVar and st2.var_env == var_env
222
223
  exp = nil
223
224
  st2.vars.each do |name, initializer|
224
225
  if initializer
@@ -234,18 +235,18 @@ module Minjs::Compressor
234
235
  else
235
236
  parent2.replace(st2, ECMA262::StEmpty.new())
236
237
  end
237
- elsif st2.kind_of? ECMA262::StForVar and st2.context.var_env == context.var_env
238
+ elsif st2.kind_of? ECMA262::StForVar and st2.var_env == var_env
238
239
  parent2.replace(st2, st2.to_st_for)
239
- elsif st2.kind_of? ECMA262::StForInVar and st2.context.var_env == context.var_env
240
+ elsif st2.kind_of? ECMA262::StForInVar and st2.var_env == var_env
240
241
  parent2.replace(st2, st2.to_st_for_in)
241
242
  end
242
243
  }
243
244
  if var_vars.length > 0
244
245
  elems = st.source_elements.source_elements
245
246
  v = ECMA262::StVar.new(
246
- context,
247
+ var_env,
247
248
  var_vars.collect do |k, v|
248
- [ECMA262::IdentifierName.get(context, k)]
249
+ [ECMA262::IdentifierName.get(k)]
249
250
  end
250
251
  )
251
252
 
@@ -341,7 +342,7 @@ module Minjs::Compressor
341
342
  remove_empty_statement
342
343
  then_to_block
343
344
  node.traverse(nil) {|parent, st|
344
- if st.kind_of? ECMA262::StBlock and !parent.kind_of?(ECMA262::StTry) and !parent.kind_of?(ECMA262::StIf)
345
+ if st.kind_of? ECMA262::StBlock and !parent.kind_of?(ECMA262::StTry) and !parent.kind_of?(ECMA262::StIf) and !parent.kind_of?(ECMA262::StTryCatch)
345
346
  if st.to_statement?
346
347
  parent.replace(st, st.to_statement)
347
348
  end
@@ -569,20 +570,20 @@ module Minjs::Compressor
569
570
 
570
571
  # Compresses variable name as short as possible.
571
572
  #
572
- # This method collects and counts all variables under this function,
573
+ # This method collects and counts all variables under the function/catch,
573
574
  # then trying to rename var_vars(see bellow) to
574
575
  # new name.
575
576
  #
576
577
  # outer_vars::
577
- # Variables which locate out of this function(or global variable)
578
+ # Variables which locate out of this function/catch(or global variable)
578
579
  # Them name cannot be renamed
579
580
  # nesting_vars::
580
- # Variables which locate in the function of this function.
581
+ # Variables which locate in the function/catch of this function/catch.
581
582
  # Them name cannot be renamed
582
583
  # var_vars::
583
- # Variables which have same scope in this function.
584
+ # Variables which have same scope in this function/catch.
584
585
  # all_vars::
585
- # All variables under this function.
586
+ # All variables under this function/catch.
586
587
  #
587
588
  # 1. If the new name is not in all_vars, the name can be renamed to it.
588
589
  # 2. If the new name belongs to var_vars, the name cannot be renamed.
@@ -592,9 +593,15 @@ module Minjs::Compressor
592
593
  #
593
594
  #
594
595
  def compress_var(node = @prog)
596
+ scopes = []
595
597
  func_scopes = []
596
598
  catch_scopes = []
597
599
  with_scopes = []
600
+
601
+ node.traverse(nil) {|parent, st|
602
+ st.parent = parent
603
+ }
604
+
598
605
  #
599
606
  # ECMA262 10.2:
600
607
  #
@@ -607,8 +614,10 @@ module Minjs::Compressor
607
614
  node.traverse(nil) {|parent, st|
608
615
  if st.kind_of? ECMA262::StFunc
609
616
  func_scopes.push([parent, st])
610
- elsif st.kind_of? ECMA262::StTry
617
+ scopes.push([parent, st])
618
+ elsif st.kind_of? ECMA262::StTryCatch
611
619
  catch_scopes.push([parent, st])
620
+ scopes.push([parent, st])
612
621
  elsif st.kind_of? ECMA262::StWith
613
622
  with_scopes.push([parent, st])
614
623
  end
@@ -653,42 +662,53 @@ module Minjs::Compressor
653
662
  #console.log(eee); //=>global
654
663
  #test();
655
664
  #
656
- catch_scopes.each{|parent, st|
657
- if st.catch
658
- catch_context = ECMA262::Context.new
659
- catch_context.lex_env = st.context.lex_env.new_declarative_env()
660
- catch_context.var_env = st.context.var_env
661
- catch_context.lex_env.record.create_mutable_binding(st.catch[0], nil)
662
- catch_context.lex_env.record.set_mutable_binding(st.catch[0], :undefined, nil)
663
- st.catch[0].context = catch_context
665
+ scopes.reverse!
664
666
 
665
- st.catch[1].traverse(parent){|parent2, st2|
666
- if st2.kind_of? ECMA262::IdentifierName and st2 == st.catch[0] and st2.binding_env == st.catch[0].binding_env
667
- st2.context = catch_context
667
+ # outer
668
+ scopes = scopes.collect {|parent, st|
669
+ if st.kind_of? ECMA262::StFunc or st.kind_of? ECMA262::StTryCatch
670
+ outer = st.parent
671
+ while outer
672
+ if outer.kind_of? ECMA262::StFunc or outer.kind_of? ECMA262::StTryCatch
673
+ break
668
674
  end
669
- }
670
- func_scopes.unshift([parent, st])
675
+ outer = outer.parent
676
+ end
671
677
  end
678
+ if outer.nil?
679
+ outer = @prog
680
+ end
681
+ [parent, st, outer]
672
682
  }
673
- # with_scopes.each{|st, parent|
674
- # with_context = ECMA262::Context.new
675
- # with_context.lex_env = st.context.lex_env.new_declarative_env()
676
- # with_context.var_env = st.context.var_env
677
- # st.statement.traverse(st) {|st2|
678
- # if st2.kind_of? ECMA262::IdentifierName and st2.binding_env == st.context.var_env
679
- # st2.context = with_context
680
- # with_context.lex_env.record.create_mutable_binding(st2, nil)
681
- # with_context.lex_env.record.set_mutable_binding(st2, :undefined, nil)
682
- # end
683
- # }
684
- # }
685
- func_scopes.reverse!
686
- func_scopes.each {|parent, st|
683
+
684
+ # exe_context
685
+ scopes.each {|parent, st, outer|
687
686
  if st.kind_of? ECMA262::StFunc
688
- context = st.context
689
- elsif st.kind_of? ECMA262::StTry
690
- context = st.catch[0].context
687
+ st.exe_context = st.enter(outer.exe_context)
688
+ st.traverse(nil) {|parent2, st2|
689
+ if st2.kind_of? ECMA262::IdentifierName
690
+ if st.decl? and st2 .eql? st.name
691
+ ;
692
+ elsif st.var_env.record.binding[st2.to_s.to_sym]
693
+ st2.exe_context = st.exe_context
694
+ end
695
+ end
696
+ }
697
+ elsif st.kind_of? ECMA262::StTryCatch
698
+ st.exe_context = st.enter(outer.exe_context)
699
+ st.traverse(nil) {|parent2, st2|
700
+ if st2.kind_of? ECMA262::IdentifierName
701
+ if st2 == st.arg
702
+ st2.exe_context = st.exe_context
703
+ end
704
+ end
705
+ }
691
706
  end
707
+ }
708
+
709
+ scopes.each {|parent, st|
710
+ exe_context = st.exe_context
711
+
692
712
  var_sym = :a
693
713
  all_vars = {}
694
714
  var_vars = {}
@@ -700,30 +720,28 @@ module Minjs::Compressor
700
720
  st.traverse(parent) {|parent2, st2|
701
721
  if st2.kind_of? ECMA262::IdentifierName
702
722
  var_name = st2.val.to_sym
703
- #st2_var_env = st2.binding_env
704
- st2_lex_env = st2.binding_env(:lex)
705
723
  all_vars[var_name] ||= 0
706
724
  all_vars[var_name] += 1
707
- if st2_lex_env == nil #global
725
+ if st2.exe_context == nil #global
708
726
  outer_vars[var_name] ||= 0
709
727
  outer_vars[var_name] += 1
710
- elsif st2_lex_env == @global_context.lex_env #global
728
+ elsif st2.exe_context.lex_env == @prog.exe_context.lex_env
711
729
  outer_vars[var_name] ||= 0
712
730
  outer_vars[var_name] += 1
713
- elsif st2_lex_env == context.lex_env
731
+ elsif st2.exe_context.lex_env == exe_context.lex_env
714
732
  var_vars[var_name] ||= 0
715
733
  var_vars[var_name] += 1
716
734
  var_vars_list.push(st2)
717
735
  else
718
- e = st2.binding_env(:lex)
736
+ e = st2.exe_context.lex_env
719
737
  while e
720
- e = e.outer
721
- if e == context.lex_env
738
+ if e == exe_context.lex_env
722
739
  nesting_vars[var_name] ||= 0
723
740
  nesting_vars[var_name] += 1
724
741
  nesting_vars_list.push(st2)
725
742
  break
726
743
  end
744
+ e = e.outer
727
745
  if e.nil?
728
746
  outer_vars[var_name] ||= 0
729
747
  outer_vars[var_name] += 1
@@ -733,6 +751,19 @@ module Minjs::Compressor
733
751
  end
734
752
  end
735
753
  }
754
+
755
+ # puts "*" * 30
756
+ # puts st.to_js
757
+ # puts "*" * 30
758
+ # puts "all_vars"
759
+ # puts all_vars
760
+ # puts "outer_vars"
761
+ # puts outer_vars
762
+ # puts "var_vars"
763
+ # puts var_vars
764
+ # puts "nesting_vars"
765
+ # puts nesting_vars
766
+
736
767
  unless var_vars[:eval]
737
768
  eval_flag = false
738
769
  st.traverse(parent) {|parent2, st2|
@@ -769,7 +800,7 @@ module Minjs::Compressor
769
800
  while true
770
801
  #condition b
771
802
  if outer_vars[var_sym]
772
- #STDERR.puts "outer_vars has #{var_sym}"
803
+ #STDERR.puts "outer_vars has #{var_sym}"
773
804
  elsif var_vars[var_sym]
774
805
  #STDERR.puts "var_vars has #{var_sym}(#{var_vars[var_sym]})"
775
806
  #condigion c
@@ -783,8 +814,7 @@ module Minjs::Compressor
783
814
  if nesting_vars[var_sym]
784
815
  #STDERR.puts "nesting_vars has #{var_sym}"
785
816
  nesting_vars_list.each do |x|
786
- #raise 'error' if x.binding_env(:var).nil?
787
- raise 'error' if x.binding_env(:lex).nil?
817
+ #raise 'error' if x.binding_env(x.exe_context.var_env).nil?
788
818
  end
789
819
 
790
820
  var_sym2 = "XXX#{var_sym.to_s}".to_sym
@@ -792,13 +822,12 @@ module Minjs::Compressor
792
822
  var_sym2 = next_sym(var_sym2)
793
823
  end
794
824
  #STDERR.puts "#{var_sym}->#{var_sym2}"
825
+
795
826
  rl = {}
796
827
  nesting_vars_list.each do |x|
797
828
  if x.val.to_sym == var_sym
798
- _var_env = x.binding_env(:var)
799
- _lex_env = x.binding_env(:lex)
829
+ _var_env = x.binding_env(x.exe_context.var_env)
800
830
  rl[_var_env] = true
801
- rl[_lex_env] = true
802
831
  end
803
832
  end
804
833
  rl.keys.each do |_env|
@@ -814,26 +843,24 @@ module Minjs::Compressor
814
843
  @val = var_sym2
815
844
  }
816
845
  end
817
- #raise 'error' if x.binding_env(:var).nil?
818
- raise x.to_js if x.binding_env(:lex).nil?
819
846
  end
820
847
  end
821
848
  rename_table[name] = var_sym
822
849
  var_sym = next_sym(var_sym)
823
850
  }
824
851
  var_vars_list.each {|st2|
825
- raise st2.to_js if st2.binding_env(:lex).nil?
852
+ #raise 'error' if st2.binding_env(st2.exe_context.var_env).nil?
826
853
  }
827
854
 
828
855
  rename_table.each do |name, new_name|
829
856
  if name != new_name
830
- if context.var_env.record.binding[name]
831
- context.var_env.record.binding[new_name] = context.var_env.record.binding[name]
832
- context.var_env.record.binding.delete(name)
857
+ if exe_context.var_env.record.binding[name]
858
+ exe_context.var_env.record.binding[new_name] = exe_context.var_env.record.binding[name]
859
+ exe_context.var_env.record.binding.delete(name)
833
860
  end
834
- if context.lex_env.record.binding[name]
835
- context.lex_env.record.binding[new_name] = context.lex_env.record.binding[name]
836
- context.lex_env.record.binding.delete(name)
861
+ if exe_context.lex_env.record.binding[name]
862
+ exe_context.lex_env.record.binding[new_name] = exe_context.lex_env.record.binding[name]
863
+ exe_context.lex_env.record.binding.delete(name)
837
864
  end
838
865
  end
839
866
  end
@@ -843,11 +870,14 @@ module Minjs::Compressor
843
870
  if rename_table[@val]
844
871
  @val = rename_table[@val]
845
872
  #raise 'error' if st2.binding_env(:var).nil?
846
- raise st2.to_js if st2.binding_env(:lex).nil?
873
+ #raise st2.to_js if st2.binding_env(:lex).nil?
847
874
  end
848
875
  }
849
876
  }
850
877
  }
878
+ node.traverse(nil) {|parent, st|
879
+ st.parent = nil
880
+ }
851
881
  self
852
882
  end
853
883
 
@@ -2,6 +2,8 @@ module Minjs
2
2
  module ECMA262
3
3
  #ECMA262 Elements
4
4
  class Base
5
+ attr_accessor :parent
6
+
5
7
  # Returns a ECMAScript string containg the representation of element.
6
8
  # @param options [Hash] options for Base#concat
7
9
  # @return [String] ECMAScript string.
@@ -9,11 +11,6 @@ module Minjs
9
11
  self.class.to_s + "??"
10
12
  end
11
13
 
12
- # to string
13
- def to_s
14
- to_js({})
15
- end
16
-
17
14
  # concatenate some of ECMA262 elements and convert it to ECMAScript
18
15
  #
19
16
  # @param args ECMA262 element
@@ -321,17 +318,18 @@ module Minjs
321
318
  # @see http://www.ecma-international.org/ecma-262 ECMA262 14
322
319
  class Prog < Base
323
320
  attr_reader :source_elements
324
- attr_reader :context
321
+ attr_reader :var_env
322
+ attr_accessor :exe_context
325
323
 
326
- def initialize(context, source_elements)
324
+ def initialize(var_env, source_elements)
327
325
  @source_elements = source_elements
328
- @context = context
326
+ @var_env = var_env
329
327
  end
330
328
 
331
329
  # duplicate object
332
330
  # @see Base#deep_dup
333
331
  def deep_dup
334
- self.class.new(context, source_elements.deep_dup)
332
+ self.class.new(var_env, source_elements.deep_dup)
335
333
  end
336
334
 
337
335
  # Replaces children object
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  module Minjs
2
3
  module ECMA262
3
4
  # class of Environment Record
@@ -30,7 +31,7 @@ module Minjs
30
31
  n = n.val
31
32
  end
32
33
  @binding[n][:value] = v
33
- @binding[n].merge!(options)
34
+ @binding[n].merge!(options || {})
34
35
  end
35
36
  end
36
37
 
@@ -50,16 +51,19 @@ module Minjs
50
51
  #
51
52
  # @see http://www.ecma-international.org/ecma-262 ECMA262 10.2
52
53
  class LexEnv
53
- attr_reader :record
54
+ attr_accessor :record
54
55
  attr_reader :outer
55
56
  attr_reader :type
56
57
 
57
58
  def initialize(options = {})
58
59
  @outer = options[:outer]
59
- if options[:type] == :object
60
+ @type = (options[:type] || :declarative)
61
+ if options[:record]
60
62
  @record = ObjectEnvRecord.new
61
- else #if options[:type] == :declarative
63
+ elsif options[:type] == :declarative
62
64
  @record = DeclarativeEnvRecord.new
65
+ elsif options[:type] == :object or true
66
+ @record = ObjectEnvRecord.new
63
67
  end
64
68
  end
65
69
 
@@ -70,6 +74,13 @@ module Minjs
70
74
  e = LexEnv.new(outer: (outer || self), type: :declarative)
71
75
  end
72
76
 
77
+ # NewDeclarativeEnvironment(E)
78
+ #
79
+ # @see http://www.ecma-international.org/ecma-262 ECMA262 10.2.2.2
80
+ def self.new_declarative_env(e)
81
+ env = LexEnv.new(outer: e, type: :declarative)
82
+ end
83
+
73
84
  # NewObjectEnvironment(O, E)
74
85
  #
75
86
  # @see http://www.ecma-international.org/ecma-262 ECMA262 10.2.2.3
@@ -93,32 +104,15 @@ module Minjs
93
104
  # Class of Execution Contexts
94
105
  #
95
106
  # @see http://www.ecma-international.org/ecma-262 ECMA262 10.3
96
- class Context
107
+ class ExeContext
97
108
  attr_accessor :lex_env
98
109
  attr_accessor :var_env
99
110
  attr_accessor :this_binding
100
-
101
111
  def initialize(options = {})
102
112
  @var_env = LexEnv.new(options)
103
113
  @lex_env = LexEnv.new(options)
104
- #TODO
105
114
  @this_binding = nil
106
- # ExObject.new(
107
- # {
108
- # attr: {
109
- # writable: true,
110
- # enumerable: false,
111
- # configurable: true
112
- # }
113
- # }
114
- # )
115
- end
116
-
117
- # debug
118
- def debug
119
- @var_env.debug
120
115
  end
121
-
122
116
  end
123
117
  end
124
118
  end