therubyrhino 1.73.0 → 1.73.1

Sign up to get free protection for your applications and to get access to all the features.
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