execjs-xtrn 1.1.4 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c96df8410557171dfaf3c5943b31f5b098b2f8a8
4
- data.tar.gz: 24ca85d50e1bdf4c7945385849bef1532091ae3e
3
+ metadata.gz: 92eb4b9da9c63cce96b83919a69cfce05124ee02
4
+ data.tar.gz: d9e42c5f04097be48ca41c32a8bcb8a00eb1b1da
5
5
  SHA512:
6
- metadata.gz: ffb757e3b1d4f256916646dfa1139186da502e43ac277fc0b03342bd65dc2ad16c5ccc3367dec0b52d46fe78626e4cf6113eac5049ba7cd375093febdf62da56
7
- data.tar.gz: 12426082a20e85dd543483f50d2535696bbb2ea072217f7b42d12aae45640bd9d647d72886478cca17d22985d54f60c9c9985b14e74b8911ea1f8500c9a629bb
6
+ metadata.gz: f133ee547118f3238f9bba5d3bf6cb2b6756ee5c21e542ebc1bf703ea4cf619f8f18d72069b02113dcbade9c04c312f54e41ab6937c172a7efbed13db668c03e
7
+ data.tar.gz: 85cf9c01a68717bdb29bbf68f8582f8406d8c0632da369b70fdebc7733ec3097fe8975f8493bfbaf0071ec9da3b586458f0ef3903e9726b5e7b297c8bc97f878
@@ -30,11 +30,15 @@ function wrap(s)
30
30
  function compile(s)
31
31
  {
32
32
  s = JSON.parse(s)
33
- if('object'==typeof s)
34
- return vmCmd(s)
35
- if('string'!=typeof s)
36
- throw Error('String expected!')
37
- return ok(new Function(s)())
33
+ switch(typeof s)
34
+ {
35
+ case 'string':
36
+ return ok(new Function(s)())
37
+ case 'object':
38
+ return vmCmd(s)
39
+ default:
40
+ throw Error('String expected!')
41
+ }
38
42
  }
39
43
 
40
44
  function ok(v)
@@ -16,6 +16,7 @@ function split (matcher, mapper, options) {
16
16
  var decoder = new Decoder()
17
17
  var soFar = ''
18
18
  var maxLength = options && options.maxLength;
19
+ var trailing = options && options.trailing === false ? false : true
19
20
  if('function' === typeof matcher)
20
21
  mapper = matcher, matcher = null
21
22
  if (!matcher)
@@ -55,9 +56,8 @@ function split (matcher, mapper, options) {
55
56
  function () {
56
57
  if(decoder.end)
57
58
  next(this, decoder.end())
58
- if(soFar != null)
59
+ if(trailing && soFar != null)
59
60
  emit(this, soFar)
60
61
  this.queue(null)
61
62
  })
62
63
  }
63
-
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "private": true,
3
3
  "dependencies": {
4
- "split": "^0.3.0",
5
- "through": "^2.3.6"
4
+ "split": "^1.0.0"
6
5
  }
7
6
  }
@@ -4,10 +4,42 @@
4
4
  +function (){
5
5
 
6
6
  if(!Object.create)
7
- Object.create = function(proto){
8
- function fn(){}
9
- fn.prototype=proto
10
- return new fn
11
- }
7
+ Object.create = function(proto) {
8
+ function fn() {}
9
+ fn.prototype = proto
10
+ return new fn
11
+ }
12
+
13
+ if(!Object.keys)
14
+ Object.keys = function(obj) {
15
+ var results = []
16
+ for (var k in obj)
17
+ results.push(k)
18
+ return results
19
+ }
20
+
21
+ var base = Array.prototype
22
+ if(!base.indexOf)
23
+ base.indexOf = function(el) {
24
+ for (var i = this.length - 1; i >= 0; i--)
25
+ if (el === this[i])
26
+ return i
27
+ return -1
28
+ }
29
+
30
+ if(!base.forEach)
31
+ base.forEach = function(fn) {
32
+ for (var i = 0, len = this.length; i < len; i++)
33
+ fn(this[i], i, this)
34
+ }
35
+
36
+ if(!base.filter)
37
+ base.filter = function(fn) {
38
+ var z, results = []
39
+ for (var i = 0, len = this.length; i < len; i++)
40
+ if (fn(z = this[i], i, this))
41
+ results.push(z)
42
+ return results
43
+ }
12
44
 
13
45
  }()
@@ -1,12 +1,16 @@
1
1
  //
2
2
  // Communicate with cscript via stdin/stderr
3
3
  //
4
+ // For using vm-commands must be run from 32-bit cscript (true if Ruby is 32-bit)
5
+ //
4
6
  +function(){
5
7
 
6
8
  var
7
9
  w = WScript,
8
10
  i = w.StdIn,
9
- o = w.StdErr
11
+ o = w.StdErr,
12
+ vms = {},
13
+ lastShim
10
14
 
11
15
  loadShivs('json2 es5')
12
16
 
@@ -25,9 +29,15 @@ function wrap(s)
25
29
  function compile(s)
26
30
  {
27
31
  s = JSON.parse(s)
28
- if('string'!=typeof s)
29
- throw Error('String expected!')
30
- return ok(new Function(s)())
32
+ switch(typeof s)
33
+ {
34
+ case 'string':
35
+ return ok(new Function(s)())
36
+ case 'object':
37
+ return vmCmd(s)
38
+ default:
39
+ throw Error('String expected!')
40
+ }
31
41
  }
32
42
 
33
43
  function ok(v)
@@ -35,28 +45,55 @@ function ok(v)
35
45
  return 'undefined'==typeof v ? {} : {ok: v}
36
46
  }
37
47
 
38
- // Load JSON2
39
- function json2()
40
- {
41
- var
42
- fso = new ActiveXObject("Scripting.FileSystemObject"),
43
- j2 = fso.GetParentFolderName(w.ScriptFullName)+"/json2.js"
44
- new Function(fso.OpenTextFile(j2).ReadAll())()
45
- }
46
-
47
- function loadJS(name)
48
+ function jsText(name)
48
49
  {
49
50
  var
50
51
  fso = new ActiveXObject("Scripting.FileSystemObject")
51
52
  name = fso.GetParentFolderName(w.ScriptFullName)+"/"+name+".js"
52
- new Function(fso.OpenTextFile(name).ReadAll())()
53
+ return fso.OpenTextFile(name).ReadAll()
53
54
  }
54
55
 
55
56
  function loadShivs(names)
56
57
  {
57
58
  names = names.split(' ')
58
59
  for(var i in names)
59
- loadJS(names[i])
60
+ new Function(lastShim = jsText(names[i]))()
61
+ }
62
+
63
+ function vmCmd(s)
64
+ {
65
+ if(!('vm' in s))
66
+ throw Error('VM command expected!')
67
+ if('js' in s)
68
+ return vmEval(s)
69
+ if(!s.vm)
70
+ return {vm: vmNew()}
71
+ delete vms[s.vm]
72
+ return {}
73
+ }
74
+
75
+ function vmNew()
76
+ {
77
+ var i, r
78
+ for(i = 10; i>0; i--)
79
+ if((r = /\d{3,}/.exec(Math.random())) && !vms[r = r[0]])
80
+ {
81
+ vms[r] = i = new ActiveXObject('ScriptControl')
82
+ i.Language = 'JScript'
83
+ i.addCode(lastShim)
84
+ return r
85
+ }
86
+ throw Error('Cannot generate random number')
87
+ }
88
+
89
+ function vmEval(s)
90
+ {
91
+ var z = vms[s.vm]
92
+ if(!z)
93
+ throw Error('VM not found')
94
+ if('string'!=typeof s.js)
95
+ throw Error('String expected!')
96
+ return ok(z.eval('new Function('+JSON.stringify(s.js)+')()'))
60
97
  }
61
98
 
62
99
  }()
data/lib/execjs/xtrn.rb CHANGED
@@ -2,7 +2,7 @@ require_relative "xtrn/rails"
2
2
 
3
3
  module ExecJS::Xtrn
4
4
 
5
- Engines=[Nvm, Node, Wsh]
5
+ Engines=[Nvm, Node, Wsh, Wvm, Ole]
6
6
 
7
7
  class << self
8
8
  attr_accessor :engine
@@ -9,11 +9,9 @@ class ExecJS::Xtrn::Engine
9
9
 
10
10
  Run=nil # Abstract class
11
11
 
12
- @stats=@@stats={c: 0}
13
-
14
12
  def exec(code)
15
13
  return if (code=code.to_s.strip).length==0
16
- result=child.say code
14
+ result=say code
17
15
  result={'err'=>'Invalid JS result'} unless Hash===result
18
16
  raise Error, result['err'] if result['err']
19
17
  result['ok']
@@ -61,14 +59,30 @@ class ExecJS::Xtrn::Engine
61
59
 
62
60
  private
63
61
 
62
+ def self.class_stats increment = 1
63
+ s = @stats ||= {c: 0}
64
+ s[:c] += increment
65
+ s
66
+ end
67
+
68
+ def self.bear
69
+ raise NotImplementedError, self unless self::Run
70
+ ExecJS::Xtrn::Child.new self::Run
71
+ end
72
+
73
+ def self.child
74
+ bear.tap {|c| c.stats self.class_stats, ExecJS::Xtrn::Engine.class_stats}
75
+ end
76
+
64
77
  def child
65
78
  return @child if @child
66
- raise NotImplementedError, self.class unless self.class::Run
67
- @child=child=ExecJS::Xtrn::Child.new(self.class::Run)
68
- child.stats @stats={}, @@stats, classStats=self.class.class_eval{@stats||={c: 0}}
69
- @@stats[:c]+=1
70
- classStats[:c]+=1
71
- child
79
+ c = self.class.child
80
+ c.stats @stats = {}
81
+ @child = c
82
+ end
83
+
84
+ def say code
85
+ child.say code
72
86
  end
73
87
 
74
88
  def initialize
@@ -1,4 +1,4 @@
1
- require_relative 'engine'
1
+ require_relative 'vm'
2
2
 
3
3
  class ExecJS::Xtrn::Node < ExecJS::Xtrn::Engine
4
4
 
@@ -7,15 +7,15 @@ class ExecJS::Xtrn::Node < ExecJS::Xtrn::Engine
7
7
  path: 'node',
8
8
  }
9
9
 
10
- Names=%w(nodejs node)
10
+ Names=%w(nodejs node iojs)
11
11
 
12
12
  def self.valid?
13
- i=Names.index do |n|
14
- Run[:args][0]=n
15
- {"ok"=>42}==ExecJS::Xtrn::Child.new(Run).say('return 7*6') rescue nil
13
+ Names.each do |n|
14
+ Run[:args][0] = n
15
+ return true if {"ok"=>42} === bear.say('return 7*6') rescue nil
16
16
  end
17
- Run[:args][0]='!' unless i
18
- !!i
17
+ Run[:args][0]='!'
18
+ false
19
19
  end
20
20
 
21
21
  Valid=valid?
@@ -4,44 +4,5 @@
4
4
  require_relative 'node'
5
5
 
6
6
  class ExecJS::Xtrn::Nvm < ExecJS::Xtrn::Node
7
-
8
- def exec(code)
9
- return if (code=code.to_s.strip).length==0
10
- result=say vm: vm, js: code
11
- result={'err'=>'Invalid JS result'} unless Hash===result
12
- raise Error, result['err'] if result['err']
13
- result['ok']
14
- end
15
-
16
- private
17
-
18
- def child
19
- @@child||=super
20
- end
21
-
22
- def say(code)
23
- ch=@@child
24
- @stats[:once]=1
25
- ch.stats @stats
26
- ch.say code
27
- end
28
-
29
- def vm
30
- return @vm if @vm
31
- c=child
32
- @stats[:once]=1 if @stats # Remove @stats, added by Engine
33
- @stats={} # Our new stats
34
- vm=say({vm: 0})['vm']
35
- raise Error, 'Cannot create VM' unless vm
36
- cs=self.class.class_eval{@stats}
37
- cs[:m]||=0
38
- cs[:m]+=1
39
- ObjectSpace.define_finalizer(self)do
40
- cs[:x]||=0
41
- cs[:x]+=1
42
- c.say vm: vm rescue nil
43
- end
44
- @vm=vm
45
- end
46
-
7
+ include ExecJS::Xtrn::VM
47
8
  end
@@ -0,0 +1,85 @@
1
+ require_relative 'wvm'
2
+
3
+ class ExecJS::Xtrn::Ole < ExecJS::Xtrn::Wsh
4
+
5
+ class Error < ExecJS::Xtrn::Error
6
+ def initialize error
7
+ # In addition, say: $stdout.set_encoding Encoding.default_external
8
+ super error.message.force_encoding Encoding.default_external
9
+ end
10
+ end
11
+
12
+ def self.valid?
13
+ return unless Gem.win_platform?
14
+ require 'win32ole'
15
+ WIN32OLE.codepage = WIN32OLE::CP_UTF8
16
+ WIN32OLE.new 'ScriptControl'
17
+ true
18
+ rescue
19
+ false
20
+ end
21
+
22
+ Valid = valid?
23
+
24
+ def exec code
25
+ return if (code=code.to_s.strip).length==0
26
+ result = nil
27
+ delta={
28
+ n: 1, # calls
29
+ o: 0, # out bytes
30
+ i: 0, # in bytes
31
+ t: Time.now # time spent
32
+ }
33
+ begin
34
+ result = parse vm.eval "new Function(#{JSON.dump code})()"
35
+ rescue WIN32OLERuntimeError=>e
36
+ raise Error.new e
37
+ ensure
38
+ delta[:t]=Time.now-delta[:t]
39
+ delta[:o]=code.length
40
+ delta[:i]=JSON.dump(result).length if result
41
+ @statz.each{|var| delta.each{|k, v| var[k]||=0; var[k]+=v}}
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ Json2 = File.expand_path('../../wsh/json2.js', __FILE__)
48
+
49
+ def vm
50
+ return @vm if @vm
51
+ @statz = [
52
+ @stats||={},
53
+ self.class.class_stats,
54
+ ExecJS::Xtrn::Engine.class_stats(0)
55
+ ]
56
+ vm = WIN32OLE.new 'ScriptControl'
57
+ vm.Language = 'JScript'
58
+ vm.addCode File.read ES5
59
+ @vm = vm
60
+ end
61
+
62
+ @@json = nil
63
+
64
+ def json
65
+ return @@json if @@json
66
+ j = WIN32OLE.new 'ScriptControl'
67
+ j.Language = 'JScript'
68
+ j.addCode File.read Json2
69
+ j.addCode <<-EOJ
70
+ function jsonDump(o)
71
+ {
72
+ return JSON.stringify(o)
73
+ }
74
+ EOJ
75
+ @@json = j
76
+ end
77
+
78
+ def parse result
79
+ WIN32OLE===result ?
80
+ JSON.parse(json.run 'jsonDump', result)
81
+ :
82
+ result
83
+ end
84
+
85
+ end
@@ -1,2 +1,2 @@
1
- require_relative 'wsh'
1
+ require_relative 'ole'
2
2
  require_relative 'routing' if defined? Rails::Application
@@ -1,5 +1,5 @@
1
1
  module ExecJS
2
2
  module Xtrn
3
- VERSION = "1.1.4"
3
+ VERSION = "1.2.0"
4
4
  end
5
5
  end
@@ -0,0 +1,46 @@
1
+ #
2
+ # Using VM with Engine
3
+ #
4
+
5
+ require_relative 'engine'
6
+
7
+ module ExecJS::Xtrn::VM
8
+ private
9
+
10
+ Error = ExecJS::Xtrn::Error
11
+
12
+ def self.included base
13
+ def base.child # override class.child
14
+ @child ||= super # Single child for engine
15
+ end
16
+ end
17
+
18
+ def child
19
+ @child ||= self.class.child
20
+ end
21
+
22
+ def say code
23
+ @stats ||= {}
24
+ @stats[:once] = 1
25
+ c = child
26
+ c.stats @stats
27
+ c.say vm: vm, js: code
28
+ end
29
+
30
+ def vm
31
+ return @vm if @vm
32
+ c = child
33
+ vm = c.say({vm: 0})['vm']
34
+ raise Error, 'Cannot create VM' unless vm
35
+ cs = self.class.class_stats 0
36
+ cs[:m] ||= 0
37
+ cs[:m] += 1
38
+ ObjectSpace.define_finalizer self do
39
+ cs[:x] ||= 0
40
+ cs[:x] += 1
41
+ c.say vm: vm rescue nil
42
+ end
43
+ @vm = vm
44
+ end
45
+
46
+ end
@@ -12,5 +12,5 @@ class ExecJS::Xtrn::Wsh < ExecJS::Xtrn::Engine
12
12
 
13
13
  Valid=Gem.win_platform?
14
14
 
15
- exec '//' rescue nil if Valid # Warm up
15
+ bear.say '//' rescue nil if Valid # Warm up
16
16
  end
@@ -0,0 +1,19 @@
1
+ #
2
+ # Virtual machine interface to Windows Script Host
3
+ #
4
+ require_relative 'wsh'
5
+
6
+ class ExecJS::Xtrn::Wvm < ExecJS::Xtrn::Wsh
7
+ include ExecJS::Xtrn::VM
8
+
9
+ # Force 32-bit cscript
10
+ def self.patch64
11
+ return unless Gem.win_platform?
12
+ return unless File.exist? exe =
13
+ File.join(ENV['windir'], 'syswow64/cscript.exe')
14
+ args = Run[:args].dup
15
+ args[0] = exe
16
+ @run32 = Run.merge args: args
17
+ end
18
+ Run = @run32 if self.patch64
19
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: execjs-xtrn
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.4
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stas Ukolov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-20 00:00:00.000000000 Z
11
+ date: 2016-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -127,11 +127,14 @@ files:
127
127
  - lib/execjs/xtrn/engine.rb
128
128
  - lib/execjs/xtrn/node.rb
129
129
  - lib/execjs/xtrn/nvm.rb
130
+ - lib/execjs/xtrn/ole.rb
130
131
  - lib/execjs/xtrn/rails.rb
131
132
  - lib/execjs/xtrn/routes.rb
132
133
  - lib/execjs/xtrn/routing.rb
133
134
  - lib/execjs/xtrn/version.rb
135
+ - lib/execjs/xtrn/vm.rb
134
136
  - lib/execjs/xtrn/wsh.rb
137
+ - lib/execjs/xtrn/wvm.rb
135
138
  homepage: https://github.com/ukoloff/execjs-xtrn
136
139
  licenses:
137
140
  - MIT
@@ -152,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
155
  version: '0'
153
156
  requirements: []
154
157
  rubyforge_project:
155
- rubygems_version: 2.2.3
158
+ rubygems_version: 2.4.5.1
156
159
  signing_key:
157
160
  specification_version: 4
158
161
  summary: 'Proof-of-concept: make ExecJS fast even without therubyracer'