johnson 1.1.2 → 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.
- data/CHANGELOG.rdoc +12 -0
- data/Manifest.txt +6 -4
- data/README.rdoc +2 -8
- data/Rakefile +11 -11
- data/bin/johnson +1 -3
- data/ext/spidermonkey/context.c +3 -2
- data/ext/spidermonkey/conversions.c +61 -27
- data/ext/spidermonkey/conversions.h +13 -0
- data/ext/spidermonkey/debugger.c +13 -5
- data/ext/spidermonkey/debugger.h +1 -0
- data/ext/spidermonkey/extconf.rb +2 -3
- data/ext/spidermonkey/jroot.h +11 -1
- data/ext/spidermonkey/js_land_proxy.c +21 -11
- data/ext/spidermonkey/ruby_land_proxy.c +116 -41
- data/ext/spidermonkey/ruby_land_proxy.h +21 -0
- data/ext/spidermonkey/runtime.c +85 -19
- data/ext/spidermonkey/runtime.h +2 -0
- data/ext/spidermonkey/spidermonkey.c +3 -1
- data/lib/johnson.rb +19 -27
- data/lib/johnson/cli.rb +2 -1
- data/{js/johnson → lib/johnson/js}/cli.js +0 -0
- data/lib/johnson/js/core.js +34 -0
- data/lib/johnson/js/prelude.js +149 -0
- data/lib/johnson/ruby_land_proxy.rb +113 -0
- data/lib/johnson/runtime.rb +92 -33
- data/lib/johnson/spidermonkey.rb +12 -0
- data/lib/johnson/spidermonkey/js_land_proxy.rb +10 -8
- data/lib/johnson/spidermonkey/ruby_land_proxy.rb +10 -47
- data/lib/johnson/spidermonkey/runtime.rb +11 -31
- data/test/johnson/conversions/array_test.rb +41 -3
- data/test/johnson/conversions/string_test.rb +12 -0
- data/test/johnson/custom_conversions_test.rb +50 -0
- data/test/johnson/prelude_test.rb +23 -0
- data/test/johnson/runtime_test.rb +82 -2
- data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +17 -1
- data/test/johnson/spidermonkey/runtime_test.rb +24 -0
- data/vendor/spidermonkey/jsprf.c +2 -0
- metadata +22 -9
- data/js/johnson/prelude.js +0 -80
- data/lib/johnson/version.rb +0 -3
- data/lib/rails/init.rb +0 -37
data/ext/spidermonkey/runtime.h
CHANGED
@@ -6,7 +6,9 @@
|
|
6
6
|
|
7
7
|
void Init_spidermonkey()
|
8
8
|
{
|
9
|
-
|
9
|
+
JS_SetCStringsAreUTF8();
|
10
|
+
|
11
|
+
VALUE johnson = rb_const_get(rb_mKernel, rb_intern("Johnson"));
|
10
12
|
VALUE spidermonkey = rb_define_module_under(johnson, "SpiderMonkey");
|
11
13
|
|
12
14
|
init_Johnson_SpiderMonkey_Context(spidermonkey);
|
data/lib/johnson.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
require "generator"
|
2
|
-
require "johnson/version"
|
3
2
|
|
4
|
-
# the
|
5
|
-
require "johnson/
|
6
|
-
|
7
|
-
|
8
|
-
require "johnson/
|
3
|
+
# the 'public' interface
|
4
|
+
require "johnson/error"
|
5
|
+
require "johnson/runtime"
|
6
|
+
require "johnson/ruby_land_proxy"
|
7
|
+
require "johnson/parser"
|
9
8
|
|
10
9
|
# visitable module and visitors
|
11
10
|
require "johnson/visitable"
|
@@ -14,39 +13,32 @@ require "johnson/visitors"
|
|
14
13
|
# parse tree nodes
|
15
14
|
require "johnson/nodes"
|
16
15
|
|
17
|
-
#
|
18
|
-
require "johnson/spidermonkey
|
19
|
-
require "johnson/spidermonkey/context"
|
20
|
-
require "johnson/spidermonkey/js_land_proxy"
|
21
|
-
require "johnson/spidermonkey/ruby_land_proxy"
|
22
|
-
require "johnson/spidermonkey/mutable_tree_visitor"
|
23
|
-
require "johnson/spidermonkey/debugger"
|
24
|
-
require "johnson/spidermonkey/immutable_node"
|
25
|
-
|
26
|
-
# the 'public' interface
|
27
|
-
require "johnson/error"
|
28
|
-
require "johnson/runtime"
|
29
|
-
require "johnson/parser"
|
30
|
-
|
31
|
-
# make sure all the Johnson JavaScript libs are in the load path
|
32
|
-
$LOAD_PATH.push(File.expand_path("#{File.dirname(__FILE__)}/../js"))
|
16
|
+
# SpiderMonkey, the default JS engine
|
17
|
+
require "johnson/spidermonkey"
|
33
18
|
|
34
19
|
module Johnson
|
35
|
-
|
36
|
-
|
20
|
+
VERSION = "1.2.0"
|
21
|
+
|
22
|
+
###
|
23
|
+
# Evaluate the given JavaScript +expression+ in a new runtime, after
|
24
|
+
# setting the given +vars+ into the global object.
|
25
|
+
#
|
26
|
+
# Returns the result of evaluating the given expression.
|
37
27
|
def self.evaluate(expression, vars={})
|
38
28
|
runtime = Johnson::Runtime.new
|
39
29
|
vars.each { |key, value| runtime[key] = value }
|
40
|
-
|
30
|
+
|
41
31
|
runtime.evaluate(expression)
|
42
32
|
end
|
43
|
-
|
33
|
+
|
44
34
|
def self.parse(js, *args)
|
45
35
|
Johnson::Parser.parse(js, *args)
|
46
36
|
end
|
47
37
|
|
48
38
|
###
|
49
|
-
# Create a new runtime and load all +files+.
|
39
|
+
# Create a new runtime and load all +files+.
|
40
|
+
#
|
41
|
+
# Returns the new Johnson::Runtime.
|
50
42
|
def self.load(*files)
|
51
43
|
rt = Johnson::Runtime.new
|
52
44
|
rt.load(*files)
|
data/lib/johnson/cli.rb
CHANGED
File without changes
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
// Ruby ProxyHelper => JS original
|
3
|
+
Johnson.addConversion(function(v) {
|
4
|
+
return v.javascript_proxy;
|
5
|
+
}, (function(Helper_send) {
|
6
|
+
return function(v) {
|
7
|
+
return Helper_send('===', v);
|
8
|
+
};
|
9
|
+
})(Ruby.Johnson.RubyLandProxy.ProxyHelper.method('send')));
|
10
|
+
|
11
|
+
|
12
|
+
// Ruby Time => JS Date
|
13
|
+
Johnson.addWrapper(function(v) {
|
14
|
+
var d = new Date(v.to_f() * 1000);
|
15
|
+
d.wrappedRuby = v;
|
16
|
+
return d;
|
17
|
+
}, (function(Helper_send, RubyTime_send) {
|
18
|
+
return function(v) {
|
19
|
+
return !Helper_send('===', v) && RubyTime_send('===', v);
|
20
|
+
};
|
21
|
+
})(Ruby.Johnson.RubyLandProxy.ProxyHelper.method('send'), Ruby.Time.method('send')));
|
22
|
+
|
23
|
+
|
24
|
+
// Ruby Date/DateTime => JS Date
|
25
|
+
Johnson.addWrapper(function(v) {
|
26
|
+
var d = new Date(parseFloat(v.strftime('%Q')));
|
27
|
+
d.wrappedRuby = v;
|
28
|
+
return d;
|
29
|
+
}, (function(Helper_send, RubyDate_send) {
|
30
|
+
return function(v) {
|
31
|
+
return !Helper_send('===', v) && RubyDate_send('===', v);
|
32
|
+
};
|
33
|
+
})(Ruby.Johnson.RubyLandProxy.ProxyHelper.method('send'), Ruby.Date.method('send')));
|
34
|
+
|
@@ -0,0 +1,149 @@
|
|
1
|
+
var Johnson = {};
|
2
|
+
|
3
|
+
Johnson.Symbol = function(string) {
|
4
|
+
this.string = string;
|
5
|
+
};
|
6
|
+
|
7
|
+
Johnson.Symbol.prototype = {
|
8
|
+
toString: function() {
|
9
|
+
return this.string;
|
10
|
+
},
|
11
|
+
|
12
|
+
inspect: function() {
|
13
|
+
return ":" + this.toString();
|
14
|
+
}
|
15
|
+
};
|
16
|
+
|
17
|
+
Johnson.symbolCache = {};
|
18
|
+
|
19
|
+
Johnson.symbolize = function(string) {
|
20
|
+
if (!Johnson.symbolCache[string])
|
21
|
+
Johnson.symbolCache[string] = new Johnson.Symbol(string);
|
22
|
+
|
23
|
+
return Johnson.symbolCache[string];
|
24
|
+
};
|
25
|
+
|
26
|
+
Object.defineProperty(String.prototype, "toSymbol", function() {
|
27
|
+
return Johnson.symbolize(this.toString());
|
28
|
+
}, Object.READ_ONLY | Object.NON_DELETABLE);
|
29
|
+
|
30
|
+
(function(origApply) {
|
31
|
+
Object.defineProperty(Function.prototype, "apply", function(thisObj, arrayLike) {
|
32
|
+
var realArray = arrayLike;
|
33
|
+
if (arrayLike != null &&
|
34
|
+
!(arrayLike instanceof Array) &&
|
35
|
+
typeof arrayLike == 'object' &&
|
36
|
+
arrayLike.length != null) {
|
37
|
+
realArray = [];
|
38
|
+
for (var i = arrayLike.length - 1; i >= 0; i--) {
|
39
|
+
realArray[i] = arrayLike[i];
|
40
|
+
}
|
41
|
+
}
|
42
|
+
return origApply.call(this, thisObj, realArray);
|
43
|
+
}, Object.READ_ONLY | Object.NON_DELETABLE);
|
44
|
+
})(Function.prototype.apply);
|
45
|
+
|
46
|
+
(function() {
|
47
|
+
var wrappers = [];
|
48
|
+
var conversions = [];
|
49
|
+
Johnson.addConversion = function(conversion, test) {
|
50
|
+
conversions.push([conversion, test]);
|
51
|
+
};
|
52
|
+
Johnson.applyConversions = function(proxy) {
|
53
|
+
var converted = false;
|
54
|
+
conversions.forEach(function(pair) {
|
55
|
+
if (converted) return;
|
56
|
+
|
57
|
+
var [conversion, test] = pair;
|
58
|
+
|
59
|
+
if (test(proxy)) {
|
60
|
+
proxy = conversion(proxy);
|
61
|
+
converted = true;
|
62
|
+
}
|
63
|
+
});
|
64
|
+
return proxy;
|
65
|
+
};
|
66
|
+
Johnson.addWrapper = function(wrapper, test) {
|
67
|
+
wrappers.push([wrapper, test]);
|
68
|
+
};
|
69
|
+
Johnson.applyWrappers = function(proxy) {
|
70
|
+
wrappers.forEach(function(pair) {
|
71
|
+
var [wrapper, test] = pair;
|
72
|
+
|
73
|
+
if (test && !test(proxy)) return;
|
74
|
+
if (wrapper.test && !wrapper.test(proxy)) return;
|
75
|
+
|
76
|
+
if (typeof wrapper == 'function')
|
77
|
+
proxy = wrapper(proxy);
|
78
|
+
else
|
79
|
+
for (var [m, v] in wrapper)
|
80
|
+
proxy[m] = v;
|
81
|
+
});
|
82
|
+
return proxy;
|
83
|
+
};
|
84
|
+
})();
|
85
|
+
|
86
|
+
Johnson.Generator = function(enumerableProxy, namesOnly) {
|
87
|
+
if (enumerableProxy.js_properties) {
|
88
|
+
this.items = enumerableProxy.js_properties();
|
89
|
+
} else {
|
90
|
+
this.items = (enumerableProxy.keys ? enumerableProxy.keys() : []).concat(enumerableProxy.methods());
|
91
|
+
}
|
92
|
+
this.index = 0;
|
93
|
+
if (!namesOnly)
|
94
|
+
this.obj = enumerableProxy;
|
95
|
+
};
|
96
|
+
|
97
|
+
Johnson.Generator.prototype.__iterator__ = function() {
|
98
|
+
return this;
|
99
|
+
};
|
100
|
+
|
101
|
+
Johnson.Generator.prototype.hasNext = function() {
|
102
|
+
return this.index < this.items.length;
|
103
|
+
}
|
104
|
+
|
105
|
+
Johnson.Generator.prototype.next = function() {
|
106
|
+
if (this.hasNext()) {
|
107
|
+
var name = this.items[this.index++];
|
108
|
+
if (this.obj) {
|
109
|
+
return [name, this.obj[name]];
|
110
|
+
} else {
|
111
|
+
return name;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
throw StopIteration;
|
115
|
+
}
|
116
|
+
|
117
|
+
Johnson.Generator.create = function(namesOnly) {
|
118
|
+
return new Johnson.Generator(this, namesOnly);
|
119
|
+
}
|
120
|
+
|
121
|
+
Johnson.required = {};
|
122
|
+
|
123
|
+
Johnson.require = function(file) {
|
124
|
+
file = Ruby.File.join(Ruby.File.dirname(file),
|
125
|
+
Ruby.File.basename(file, ".js") + ".js");
|
126
|
+
|
127
|
+
if(Johnson.required[file]) return false;
|
128
|
+
|
129
|
+
for(var directory in Ruby["$LOAD_PATH"]) {
|
130
|
+
var path = Ruby.File.join(directory, file);
|
131
|
+
|
132
|
+
if(Ruby.File.send("file?", path)) {
|
133
|
+
Johnson.required[file] = true;
|
134
|
+
Johnson.runtime.load(path);
|
135
|
+
|
136
|
+
return true;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
throw Ruby.LoadError;
|
141
|
+
}
|
142
|
+
|
143
|
+
this.__defineGetter__("__FILE__", function() {
|
144
|
+
try { throw new Error; } catch(e) {
|
145
|
+
return e.stack.split("\n")[2].split("@")[1].split(":").slice(0,-1).join(":");
|
146
|
+
}
|
147
|
+
})
|
148
|
+
|
149
|
+
null; // no need to marshal a result
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Johnson #:nodoc:
|
2
|
+
class RubyLandProxy
|
3
|
+
class << self
|
4
|
+
def apply_wrappers(proxy)
|
5
|
+
wrappers.each do |(wrapper, test)|
|
6
|
+
next if test && !test.call(proxy)
|
7
|
+
next if wrapper.respond_to?(:test?) && !wrapper.test?(proxy)
|
8
|
+
|
9
|
+
if wrapper.respond_to?(:call)
|
10
|
+
proxy = wrapper.call(proxy)
|
11
|
+
break unless Johnson::RubyLandProxy === proxy
|
12
|
+
else
|
13
|
+
proxy.send :extend, wrapper
|
14
|
+
end
|
15
|
+
end
|
16
|
+
proxy
|
17
|
+
end
|
18
|
+
def add_wrapper(wrapper, &test)
|
19
|
+
wrappers.push [wrapper, test]
|
20
|
+
end
|
21
|
+
def insert_wrapper(wrapper, &test)
|
22
|
+
wrappers.unshift [wrapper, test]
|
23
|
+
end
|
24
|
+
def wrappers
|
25
|
+
@wrappers ||= []
|
26
|
+
end
|
27
|
+
|
28
|
+
def apply_conversions(proxy)
|
29
|
+
conversions.each do |(conversion, test)|
|
30
|
+
if test.call(proxy)
|
31
|
+
converted = conversion.call(proxy)
|
32
|
+
return converted unless converted.eql? proxy
|
33
|
+
end
|
34
|
+
end
|
35
|
+
proxy
|
36
|
+
end
|
37
|
+
def add_conversion(conversion, &test)
|
38
|
+
conversions << [conversion, test]
|
39
|
+
end
|
40
|
+
def conversions
|
41
|
+
@conversions ||= []
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module Callable
|
46
|
+
def self.test?(proxy)
|
47
|
+
proxy.respond_to?(:call_using)
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_proc
|
51
|
+
@proc ||= Proc.new { |*args| call(*args) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def call(*args)
|
55
|
+
call_using(runtime.global, *args)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
module ProxyHelper
|
60
|
+
def self.wrap(proxy, result)
|
61
|
+
result.extend self
|
62
|
+
result.javascript_proxy = proxy
|
63
|
+
result
|
64
|
+
end
|
65
|
+
|
66
|
+
attr_accessor :javascript_proxy
|
67
|
+
end
|
68
|
+
|
69
|
+
add_wrapper Callable
|
70
|
+
|
71
|
+
# JS wrapper => Ruby original
|
72
|
+
add_conversion lambda {|o| o.wrappedRuby } do |o| o.respond_to? :wrappedRuby end
|
73
|
+
|
74
|
+
# JS Date => Ruby DateTime
|
75
|
+
add_conversion lambda {|o| ProxyHelper.wrap(o, DateTime.parse(o.toUTCString)) } do |o| o.respond_to? :setUTCMilliseconds end
|
76
|
+
|
77
|
+
include Enumerable
|
78
|
+
|
79
|
+
# FIXME: need to revisit array vs non-array proxy, to_a/to_ary semantics, etc.
|
80
|
+
def size; length; end
|
81
|
+
def to_ary; to_a; end
|
82
|
+
|
83
|
+
def initialize
|
84
|
+
raise Johnson::Error, "#{self.class.name} is an internal support class."
|
85
|
+
end
|
86
|
+
private :initialize
|
87
|
+
|
88
|
+
def inspect
|
89
|
+
toString
|
90
|
+
end
|
91
|
+
|
92
|
+
def method_missing(sym, *args, &block)
|
93
|
+
args << block if block_given?
|
94
|
+
|
95
|
+
name = sym.to_s
|
96
|
+
assignment = "=" == name[-1, 1]
|
97
|
+
|
98
|
+
# default behavior if the slot's not there
|
99
|
+
return super unless assignment || respond_to?(sym)
|
100
|
+
|
101
|
+
unless function_property?(name)
|
102
|
+
# for arity 0, treat it as a get
|
103
|
+
return self[name] if args.empty?
|
104
|
+
|
105
|
+
# arity 1 and quacking like an assignment, treat it as a set
|
106
|
+
return self[name[0..-2]] = args[0] if assignment && 1 == args.size
|
107
|
+
end
|
108
|
+
|
109
|
+
# okay, must really be a function
|
110
|
+
call_function_property(name, *args)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
data/lib/johnson/runtime.rb
CHANGED
@@ -1,36 +1,104 @@
|
|
1
1
|
module Johnson
|
2
|
+
###
|
3
|
+
# An interface to a JavaScript engine.
|
2
4
|
class Runtime
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
|
6
|
+
PRELUDE_PATH = File.expand_path File.dirname(__FILE__) +
|
7
|
+
"/js/prelude.js" # :nodoc:
|
8
|
+
CORE_PATH = File.expand_path File.dirname(__FILE__) +
|
9
|
+
"/js/core.js" # :nodoc:
|
10
|
+
|
11
|
+
PRELUDE = IO.read PRELUDE_PATH # :nodoc:
|
12
|
+
CORE = IO.read CORE_PATH # :nodoc:
|
13
|
+
|
14
|
+
###
|
15
|
+
# Deprecated: Previously, returned the underlying JavaScript engine
|
16
|
+
# instance. Now returns self.
|
17
|
+
def delegate
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
###
|
22
|
+
# Create a new Runtime instance, using the default JavaScript
|
23
|
+
# engine.
|
24
|
+
#
|
25
|
+
# Optionally takes a parameter specifying which engine to use, but
|
26
|
+
# this is deprecated; instead, just create an instance of that
|
27
|
+
# engine's runtime directly.
|
28
|
+
#
|
29
|
+
# :call-seq:
|
30
|
+
# new(runtime_class=nil)
|
31
|
+
#
|
32
|
+
def self.new(*args)
|
33
|
+
return super if self < Johnson::Runtime
|
34
|
+
|
35
|
+
delegate = args.first
|
36
|
+
if delegate.is_a? Class
|
37
|
+
delegate.new
|
38
|
+
elsif delegate
|
39
|
+
delegate
|
40
|
+
else
|
41
|
+
Johnson::SpiderMonkey::Runtime.new
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
###
|
46
|
+
# Install the Johnson prelude into this runtime environment.
|
47
|
+
def initialize # :notnew:
|
48
|
+
evaluate PRELUDE, PRELUDE_PATH, 1
|
8
49
|
global.Johnson.runtime = self
|
50
|
+
global['Ruby'] = Object
|
51
|
+
evaluate CORE, CORE_PATH, 1
|
9
52
|
end
|
10
|
-
|
53
|
+
|
54
|
+
###
|
55
|
+
# Access the +key+ property of the JavaScript +global+ object.
|
11
56
|
def [](key)
|
12
|
-
|
57
|
+
global[key]
|
13
58
|
end
|
14
|
-
|
59
|
+
|
60
|
+
###
|
61
|
+
# Set the +key+ property of the JavaScript +global+ object to
|
62
|
+
# +value+.
|
15
63
|
def []=(key, value)
|
16
|
-
|
64
|
+
global[key] = value
|
17
65
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
66
|
+
|
67
|
+
|
68
|
+
###
|
69
|
+
# Execute the JavaScript source in +script+. If supplied, the script
|
70
|
+
# is marked as starting on line +linenum+ of +filename+.
|
71
|
+
#
|
72
|
+
# Equivalent to calling RubyLandScript#execute on the result of
|
73
|
+
# Runtime#compile.
|
74
|
+
def evaluate(script, filename = nil, linenum = nil)
|
75
|
+
return nil if script.nil?
|
76
|
+
compiled_script = compile(script, filename, linenum)
|
77
|
+
evaluate_compiled_script(compiled_script)
|
22
78
|
end
|
23
|
-
|
79
|
+
|
80
|
+
|
81
|
+
###
|
82
|
+
# The JavaScript unique Global Object.
|
24
83
|
def global
|
25
|
-
|
84
|
+
raise NotImplementedError
|
26
85
|
end
|
27
|
-
|
86
|
+
|
87
|
+
###
|
88
|
+
# Load and execute the named JavaScript +files+.
|
89
|
+
#
|
90
|
+
# Checks for (and skips) a shebang line at the top of any of them.
|
28
91
|
def load(*files)
|
29
|
-
files.map { |f|
|
92
|
+
files.map { |f|
|
93
|
+
evaluate(File.read(f).gsub(/\A#!.*$/, ''), f, 1)
|
94
|
+
}.last
|
30
95
|
end
|
31
96
|
|
32
97
|
###
|
33
|
-
#
|
98
|
+
# Search the Ruby load path for each of the named +files+, and
|
99
|
+
# evaluate them *if they have not yet been loaded*.
|
100
|
+
#
|
101
|
+
# Calls Johnson.require() in JavaScript on each filename in turn.
|
34
102
|
def require(*files)
|
35
103
|
files.each do |file|
|
36
104
|
evaluate("Johnson.require('#{file}');")
|
@@ -38,26 +106,17 @@ module Johnson
|
|
38
106
|
end
|
39
107
|
|
40
108
|
###
|
41
|
-
# Compile +script
|
109
|
+
# Compile the JavaScript source in +script+. If supplied, the script
|
110
|
+
# is marked as starting on line +linenum+ of +filename+.
|
42
111
|
def compile(script, filename=nil, linenum=nil)
|
43
|
-
|
112
|
+
raise NotImplementedError
|
44
113
|
end
|
45
114
|
|
46
115
|
###
|
47
|
-
#
|
48
|
-
|
49
|
-
delegate.break(filename, linenum, &block)
|
50
|
-
end
|
51
|
-
|
116
|
+
# Evaluates the given JS script, that should have been returned by a
|
117
|
+
# previous call to #compile().
|
52
118
|
def evaluate_compiled_script(script)
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
# Called by SpiderMonkey's garbage collector to determine whether or
|
58
|
-
# not it should GC
|
59
|
-
def should_sm_gc?
|
60
|
-
false
|
119
|
+
raise NotImplementedError
|
61
120
|
end
|
62
121
|
end
|
63
122
|
end
|