therubyrhino 1.73.0 → 1.73.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.
data/lib/rhino.rb CHANGED
@@ -1,11 +1,29 @@
1
+ require 'java'
2
+
3
+ require 'rhino/rhino-1.7R3.jar'
1
4
 
2
5
  module Rhino
3
- require 'rhino/java'
4
- require 'rhino/object'
5
- require 'rhino/context'
6
- require 'rhino/wormhole'
7
- require 'rhino/ruby_object'
8
- require 'rhino/ruby_function'
9
- require 'rhino/native_object'
10
- require 'rhino/native_function'
11
- end
6
+
7
+ # This module contains all the native Rhino objects implemented in Java
8
+ # e.g. Rhino::JS::NativeObject # => org.mozilla.javascript.NativeObject
9
+ module JS
10
+ include_package "org.mozilla.javascript"
11
+
12
+ module Regexp
13
+ include_package "org.mozilla.javascript.regexp"
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+
20
+ require 'rhino/wormhole'
21
+ Rhino.extend Rhino::To
22
+
23
+ require 'rhino/object'
24
+ require 'rhino/context'
25
+ require 'rhino/error'
26
+ require 'rhino/rhino_ext'
27
+ require 'rhino/ruby'
28
+ require 'rhino/ruby/access'
29
+ require 'rhino/deprecations'
data/lib/rhino/context.rb CHANGED
@@ -2,40 +2,38 @@ require 'stringio'
2
2
 
3
3
  module Rhino
4
4
 
5
- # ==Overview
6
- # All Javascript must be executed in a context which represents the execution environment in
7
- # which scripts will run. The environment consists of the standard javascript objects
8
- # and functions like Object, String, Array, etc... as well as any objects or functions which
9
- # have been defined in it. e.g.
10
- #
11
- # Context.open do |cxt|
12
- # cxt['num'] = 5
13
- # cxt.eval('num + 5') #=> 10
14
- # end
15
- #
16
- # == Multiple Contexts.
17
- # The same object may appear in any number of contexts, but only one context may be executing javascript code
18
- # in any given thread. If a new context is opened in a thread in which a context is already opened, the second
19
- # context will "mask" the old context e.g.
20
- #
21
- # six = 6
22
- # Context.open do |cxt|
23
- # cxt['num'] = 5
24
- # cxt.eval('num') # => 5
25
- # Context.open do |cxt|
26
- # cxt['num'] = 10
27
- # cxt.eval('num') # => 10
28
- # cxt.eval('++num') # => 11
29
- # end
30
- # cxt.eval('num') # => 5
31
- # end
32
- #
33
- # == Notes
34
- # While there are many similarities between Rhino::Context and Java::org.mozilla.javascript.Context, they are not
35
- # the same thing and should not be confused.
36
-
5
+ # ==Overview
6
+ # All Javascript must be executed in a context which represents the execution environment in
7
+ # which scripts will run. The environment consists of the standard javascript objects
8
+ # and functions like Object, String, Array, etc... as well as any objects or functions which
9
+ # have been defined in it. e.g.
10
+ #
11
+ # Context.open do |cxt|
12
+ # cxt['num'] = 5
13
+ # cxt.eval('num + 5') #=> 10
14
+ # end
15
+ #
16
+ # == Multiple Contexts.
17
+ # The same object may appear in any number of contexts, but only one context may be executing javascript code
18
+ # in any given thread. If a new context is opened in a thread in which a context is already opened, the second
19
+ # context will "mask" the old context e.g.
20
+ #
21
+ # six = 6
22
+ # Context.open do |cxt|
23
+ # cxt['num'] = 5
24
+ # cxt.eval('num') # => 5
25
+ # Context.open do |cxt|
26
+ # cxt['num'] = 10
27
+ # cxt.eval('num') # => 10
28
+ # cxt.eval('++num') # => 11
29
+ # end
30
+ # cxt.eval('num') # => 5
31
+ # end
32
+ #
33
+ # == Notes
34
+ # While there are many similarities between Rhino::Context and Java::org.mozilla.javascript.Context, they are not
35
+ # the same thing and should not be confused.
37
36
  class Context
38
- attr_reader :scope
39
37
 
40
38
  class << self
41
39
 
@@ -51,37 +49,40 @@ module Rhino
51
49
 
52
50
  end
53
51
 
52
+ attr_reader :scope
53
+
54
54
  # Create a new javascript environment for executing javascript and ruby code.
55
55
  # * <tt>:sealed</tt> - if this is true, then the standard objects such as Object, Function, Array will not be able to be modified
56
56
  # * <tt>:with</tt> - use this ruby object as the root scope for all javascript that is evaluated
57
57
  # * <tt>:java</tt> - if true, java packages will be accessible from within javascript
58
58
  def initialize(options = {}) #:nodoc:
59
- ContextFactory.new.call do |native|
60
- @native = native
61
- @global = NativeObject.new(@native.initStandardObjects(nil, options[:sealed] == true))
59
+ @factory = ContextFactory.new
60
+ @factory.call do |context|
61
+ @native = context
62
+ @global = @native.initStandardObjects(nil, options[:sealed] == true)
62
63
  if with = options[:with]
63
- @scope = To.javascript(with)
64
- @scope.setParentScope(@global.j)
64
+ @scope = Rhino.to_javascript(with)
65
+ @scope.setParentScope(@global)
65
66
  else
66
67
  @scope = @global
67
68
  end
68
69
  unless options[:java]
69
70
  for package in ["Packages", "java", "javax", "org", "com", "edu", "net"]
70
- @global.j.delete(package)
71
+ @global.delete(package)
71
72
  end
72
73
  end
73
74
  end
74
75
  end
75
76
 
76
77
  # Read a value from the global scope of this context
77
- def [](k)
78
- @scope[k]
78
+ def [](key)
79
+ @scope[key]
79
80
  end
80
81
 
81
82
  # Set a value in the global scope of this context. This value will be visible to all the
82
83
  # javascript that is executed in this context.
83
- def []=(k, v)
84
- @scope[k] = v
84
+ def []=(key, val)
85
+ @scope[key] = val
85
86
  end
86
87
 
87
88
  # Evaluate a string of javascript in this context:
@@ -89,23 +90,18 @@ module Rhino
89
90
  # * <tt>source_name</tt> - associated name for this source code. Mainly useful for backtraces.
90
91
  # * <tt>line_number</tt> - associate this number with the first line of executing source. Mainly useful for backtraces
91
92
  def eval(source, source_name = "<eval>", line_number = 1)
92
- self.open do
93
- begin
94
- scope = To.javascript(@scope)
95
- if IO === source || StringIO === source
96
- result = @native.evaluateReader(scope, IOReader.new(source), source_name, line_number, nil)
97
- else
98
- result = @native.evaluateString(scope, source.to_s, source_name, line_number, nil)
99
- end
100
- To.ruby result
101
- rescue J::RhinoException => e
102
- raise Rhino::JavascriptError, e
93
+ open do
94
+ if IO === source || StringIO === source
95
+ result = @native.evaluateReader(@scope, IOReader.new(source), source_name, line_number, nil)
96
+ else
97
+ result = @native.evaluateString(@scope, source.to_s, source_name, line_number, nil)
103
98
  end
99
+ Rhino.to_ruby(result)
104
100
  end
105
101
  end
106
-
102
+
107
103
  def evaluate(*args) # :nodoc:
108
- self.eval(*args)
104
+ eval(*args) # an alias
109
105
  end
110
106
 
111
107
  # Read the contents of <tt>filename</tt> and evaluate it as javascript. Returns the result of evaluating the
@@ -125,56 +121,102 @@ module Rhino
125
121
  # If this instruction limit is exceeded, then a Rhino::RunawayScriptError
126
122
  # will be raised
127
123
  def instruction_limit=(limit)
128
- @native.setInstructionObserverThreshold(limit);
129
- @native.factory.instruction_limit = limit
124
+ @native.setInstructionObserverThreshold(limit)
125
+ @factory.instruction_limit = limit
130
126
  end
131
127
 
128
+ def optimization_level
129
+ @native.getOptimizationLevel
130
+ end
131
+
132
132
  # Set the optimization level that this context will use. This is sometimes necessary
133
133
  # in Rhino, if the bytecode size of the compiled javascript exceeds the 64KB limit.
134
134
  # By using the -1 optimization level, you tell Rhino to run in interpretative mode,
135
135
  # taking a hit to performance but escaping the Java bytecode limit.
136
136
  def optimization_level=(level)
137
- @native.setOptimizationLevel(level)
137
+ if @native.class.isValidOptimizationLevel(level)
138
+ @native.setOptimizationLevel(level)
139
+ level
140
+ else
141
+ @native.setOptimizationLevel(0)
142
+ nil
143
+ end
138
144
  end
139
145
 
140
- # Enter this context for operations. Some methods such as eval() will
141
- # fail unless this context is open
142
- def open
143
- begin
144
- @native.factory.enterContext(@native)
145
- yield self
146
- ensure
147
- J::Context.exit()
148
- end if block_given?
146
+ # Get the JS interpreter version.
147
+ # Returns a number e.g. 1.7, nil if unknown and 0 for default.
148
+ def version
149
+ case const_value = @native.getLanguageVersion
150
+ when -1 then nil # VERSION_UNKNOWN
151
+ when 0 then 0 # VERSION_DEFAULT
152
+ else const_value / 100.0 # VERSION_1_1 (1.1 = 110 / 100)
153
+ end
149
154
  end
150
-
155
+
156
+ # Sets interpreter mode a.k.a. JS language version e.g. 1.7 (if supported).
157
+ def version=(version)
158
+ const = version.to_s.gsub('.', '_').upcase
159
+ const = "VERSION_#{const}" if const[0, 7] != 'VERSION'
160
+ js_context = @native.class # Context
161
+ if js_context.constants.include?(const)
162
+ const_value = js_context.const_get(const)
163
+ @native.setLanguageVersion(const_value)
164
+ const_value
165
+ else
166
+ @native.setLanguageVersion(js_context::VERSION_DEFAULT)
167
+ nil
168
+ end
169
+ end
170
+
171
+ # Enter this context for operations.
172
+ # Some methods such as eval() will fail unless this context is open !
173
+ def open(&block)
174
+ do_open(&block)
175
+ rescue JS::RhinoException => e
176
+ raise Rhino::JSError.new(e)
177
+ end
178
+
179
+ private
180
+
181
+ def do_open
182
+ begin
183
+ @factory.enterContext(@native)
184
+ yield self
185
+ ensure
186
+ JS::Context.exit
187
+ end
188
+ end
189
+
151
190
  end
152
191
 
153
- class IOReader < java.io.Reader #:nodoc:
192
+ class IOReader < java.io.Reader # :nodoc:
154
193
 
155
194
  def initialize(io)
156
195
  @io = io
157
196
  end
158
197
 
159
- def read(charbuffer, offset, length)
198
+ # implement int Reader#read(char[] buffer, int offset, int length)
199
+ def read(buffer, offset, length)
200
+ str = nil
160
201
  begin
161
202
  str = @io.read(length)
162
- if str.nil?
163
- return -1
164
- else
165
- jstring = java.lang.String.new(str)
166
- for i in 0 .. jstring.length - 1
167
- charbuffer[i + offset] = jstring.charAt(i)
168
- end
169
- return jstring.length
170
- end
171
203
  rescue StandardError => e
172
- raise java.io.IOException.new, "Failed reading from ruby IO object"
204
+ raise java.io.IOException.new("failed reading from ruby IO object")
205
+ end
206
+ if str.nil?
207
+ return -1
208
+ else
209
+ jstr = str.to_java
210
+ for i in 0 .. jstr.length - 1
211
+ buffer[i + offset] = jstr.charAt(i)
212
+ end
213
+ return jstr.length
173
214
  end
174
215
  end
216
+
175
217
  end
176
218
 
177
- class ContextFactory < J::ContextFactory # :nodoc:
219
+ class ContextFactory < JS::ContextFactory # :nodoc:
178
220
 
179
221
  def observeInstructionCount(cxt, count)
180
222
  raise RunawayScriptError, "script exceeded allowable instruction count" if count > @limit
@@ -183,28 +225,13 @@ module Rhino
183
225
  def instruction_limit=(count)
184
226
  @limit = count
185
227
  end
228
+
186
229
  end
187
230
 
188
231
  class ContextError < StandardError # :nodoc:
189
-
190
232
  end
191
233
 
192
- class JavascriptError < StandardError # :nodoc:
193
- def initialize(native)
194
- @native = native
195
- end
196
-
197
- def message
198
- @native.cause.details
199
- end
200
-
201
- def javascript_backtrace
202
- @native.getScriptStackTrace()
203
- end
204
- end
205
-
206
- JSError = JavascriptError
207
-
208
- class RunawayScriptError < StandardError # :nodoc:
234
+ class RunawayScriptError < ContextError # :nodoc:
209
235
  end
236
+
210
237
  end
@@ -0,0 +1,52 @@
1
+
2
+ module Rhino
3
+
4
+ @@stub_class = Class.new(Object)
5
+
6
+ def self.const_missing(name)
7
+ case name.to_s
8
+ when 'J' then
9
+ warn "[DEPRECATION] `Rhino::J` is deprecated, use `Rhino::JS` instead."
10
+ return JS
11
+ when 'JavascriptError' then
12
+ warn "[DEPRECATION] `Rhino::JavascriptError` is deprecated, use `Rhino::JSError` instead."
13
+ return JSError
14
+ when 'NativeObject' then
15
+ warn "[DEPRECATION] `Rhino::NativeObject` is no longer used, returning a stub."
16
+ return @@stub_class
17
+ when 'NativeFunction' then
18
+ warn "[DEPRECATION] `Rhino::NativeFunction` is no longer used, returning a stub."
19
+ return @@stub_class
20
+ else super
21
+ end
22
+ end
23
+
24
+ @@warnings = {}
25
+
26
+ def self.warn(msg)
27
+ # only print out deprecation warnings once
28
+ if msg[0, 13] == '[DEPRECATION]'
29
+ return nil if @@warnings[msg]
30
+ @@warnings[msg] = true
31
+ end
32
+ super # Kernel.warn
33
+ end
34
+
35
+ module To
36
+
37
+ extend self
38
+
39
+ # @deprecated use {#to_ruby} instead
40
+ def self.ruby(object)
41
+ Rhino.warn "[DEPRECATION] `Rhino::To.ruby` is deprecated, use `Rhino.to_ruby` instead."
42
+ to_ruby(object)
43
+ end
44
+
45
+ # @deprecated use {#to_javascript} instead
46
+ def self.javascript(object, scope = nil)
47
+ Rhino.warn "[DEPRECATION] `Rhino::To.javascript` is deprecated, use `Rhino.to_javascript` instead."
48
+ to_javascript(object, scope)
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,44 @@
1
+
2
+ module Rhino
3
+
4
+ class JSError < StandardError
5
+
6
+ def initialize(native)
7
+ @native = native # NativeException wrapping a Java Throwable
8
+ end
9
+
10
+ def message
11
+ cause ? cause.details : @native.to_s
12
+ end
13
+
14
+ def to_s
15
+ super
16
+ end
17
+
18
+ # most likely a Rhino::JS::JavaScriptException
19
+ def cause
20
+ @native.respond_to?(:cause) ? @native.cause : nil
21
+ end
22
+
23
+ def unwrap
24
+ return @unwrap if defined?(@unwrap)
25
+ cause = self.cause
26
+ if cause && cause.is_a?(JS::WrappedException)
27
+ e = cause.getWrappedException
28
+ if e && e.is_a?(Java::OrgJrubyExceptions::RaiseException)
29
+ @unwrap = e.getException
30
+ else
31
+ @unwrap = e
32
+ end
33
+ else
34
+ @unwrap = nil
35
+ end
36
+ end
37
+
38
+ def javascript_backtrace
39
+ cause.is_a?(JS::RhinoException) ? cause.getScriptStackTrace : nil
40
+ end
41
+
42
+ end
43
+
44
+ end