Class: RustyRacer::ExecJSRuntime::Context
- Inherits:
-
ExecJS::Runtime::Context
- Object
- ExecJS::Runtime::Context
- RustyRacer::ExecJSRuntime::Context
- Defined in:
- lib/rusty_racer/execjs.rb
Constant Summary collapse
- LOCATION =
‘filename` for every JS run, so a thrown error’s stack (which rusty_racer surfaces as the Ruby backtrace) reads “(execjs):line:col” — ExecJS’s test suite asserts the backtrace mentions “(execjs):”.
'(execjs)'
Instance Method Summary collapse
-
#call(identifier, *args) ⇒ Object
Evaluate ‘identifier` to a function and call it with the global object as `this` and the (JSON-marshalled) args.
-
#eval(source, _options = {}) ⇒ Object
Evaluate an expression and return its (JSON-projected) value.
-
#exec(source, _options = {}) ⇒ Object
Run statements in a function body and return what they ‘return` (nil when nothing is returned), per ExecJS.
-
#initialize(_runtime, source = '', _options = {}) ⇒ Context
constructor
A new instance of Context.
Constructor Details
#initialize(_runtime, source = '', _options = {}) ⇒ Context
Returns a new instance of Context.
32 33 34 35 36 37 38 39 40 41 |
# File 'lib/rusty_racer/execjs.rb', line 32 def initialize(_runtime, source = '', = {}) @isolate = RustyRacer::Isolate.new @context = @isolate.context # ExecJS guarantees a bare global (no browser/Node ambient): V8 installs a # default `console`, so drop it to match the contract (consumers attach # their own if needed), exactly as the mini_racer runtime does. @context.eval('delete globalThis.console') source = encode(source) translate { @context.eval(source, filename: LOCATION) } if /\S/.match?(source) end |
Instance Method Details
#call(identifier, *args) ⇒ Object
Evaluate ‘identifier` to a function and call it with the global object as `this` and the (JSON-marshalled) args. `identifier` is arbitrary JS — a name path (“a.b.fn”), a member expression, or a function literal — so it is applied rather than looked up. The newline guards a trailing comment as in eval/exec.
71 72 73 |
# File 'lib/rusty_racer/execjs.rb', line 71 def call(identifier, *args) eval("(#{encode(identifier)}\n).apply(this, #{JSON.generate(args)})") end |
#eval(source, _options = {}) ⇒ Object
Evaluate an expression and return its (JSON-projected) value. Blank source is nil. The expression is parenthesised so a leading ‘{` reads as an object literal (and a trailing `//` comment can’t swallow the closing parens — hence the newline), then routed through JSON.stringify for ExecJS semantics.
56 57 58 59 60 61 62 63 64 |
# File 'lib/rusty_racer/execjs.rb', line 56 def eval(source, = {}) source = encode(source) return unless /\S/.match?(source) json = translate { @context.eval("JSON.stringify((#{source}\n))", filename: LOCATION) } # JSON.stringify yields `undefined` (-> nil here) for a function/undefined # result; otherwise a JSON string to parse back. json.nil? ? nil : JSON.parse(json) end |
#exec(source, _options = {}) ⇒ Object
Run statements in a function body and return what they ‘return` (nil when nothing is returned), per ExecJS. The trailing newline before `}` ends any `//` line comment the source closes with, so it can’t eat the wrapper.
46 47 48 49 |
# File 'lib/rusty_racer/execjs.rb', line 46 def exec(source, = {}) source = encode(source) eval("(function(){#{source}\n})()") if /\S/.match?(source) end |