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 +4 -4
- data/lib/execjs/node/index.js +9 -5
- data/lib/execjs/node/node_modules/split/index.js +2 -2
- data/lib/execjs/node/package.json +1 -2
- data/lib/execjs/wsh/es5.js +37 -5
- data/lib/execjs/wsh/repl.js +53 -16
- data/lib/execjs/xtrn.rb +1 -1
- data/lib/execjs/xtrn/engine.rb +23 -9
- data/lib/execjs/xtrn/node.rb +7 -7
- data/lib/execjs/xtrn/nvm.rb +1 -40
- data/lib/execjs/xtrn/ole.rb +85 -0
- data/lib/execjs/xtrn/rails.rb +1 -1
- data/lib/execjs/xtrn/version.rb +1 -1
- data/lib/execjs/xtrn/vm.rb +46 -0
- data/lib/execjs/xtrn/wsh.rb +1 -1
- data/lib/execjs/xtrn/wvm.rb +19 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92eb4b9da9c63cce96b83919a69cfce05124ee02
|
4
|
+
data.tar.gz: d9e42c5f04097be48ca41c32a8bcb8a00eb1b1da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f133ee547118f3238f9bba5d3bf6cb2b6756ee5c21e542ebc1bf703ea4cf619f8f18d72069b02113dcbade9c04c312f54e41ab6937c172a7efbed13db668c03e
|
7
|
+
data.tar.gz: 85cf9c01a68717bdb29bbf68f8582f8406d8c0632da369b70fdebc7733ec3097fe8975f8493bfbaf0071ec9da3b586458f0ef3903e9726b5e7b297c8bc97f878
|
data/lib/execjs/node/index.js
CHANGED
@@ -30,11 +30,15 @@ function wrap(s)
|
|
30
30
|
function compile(s)
|
31
31
|
{
|
32
32
|
s = JSON.parse(s)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
data/lib/execjs/wsh/es5.js
CHANGED
@@ -4,10 +4,42 @@
|
|
4
4
|
+function (){
|
5
5
|
|
6
6
|
if(!Object.create)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
}()
|
data/lib/execjs/wsh/repl.js
CHANGED
@@ -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
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
data/lib/execjs/xtrn/engine.rb
CHANGED
@@ -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=
|
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
|
-
|
67
|
-
@
|
68
|
-
child
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
data/lib/execjs/xtrn/node.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative '
|
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
|
-
|
14
|
-
Run[:args][0]=n
|
15
|
-
{"ok"=>42}
|
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]='!'
|
18
|
-
|
17
|
+
Run[:args][0]='!'
|
18
|
+
false
|
19
19
|
end
|
20
20
|
|
21
21
|
Valid=valid?
|
data/lib/execjs/xtrn/nvm.rb
CHANGED
@@ -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
|
data/lib/execjs/xtrn/rails.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'ole'
|
2
2
|
require_relative 'routing' if defined? Rails::Application
|
data/lib/execjs/xtrn/version.rb
CHANGED
@@ -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
|
data/lib/execjs/xtrn/wsh.rb
CHANGED
@@ -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.
|
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-
|
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.
|
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'
|