execjs-xtrn 1.1.4 → 1.2.0

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: 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'