diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7329012..2ac3dde 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,10 @@ jobs: uses: actions/checkout@v3 - name: Install Node run: sudo apt-get install -y nodejs + - name: Install Bun + - uses: oven-sh/setup-bun@v1 + with: + bun-version: latest - name: Set up Ruby uses: ruby/setup-ruby@v1 with: diff --git a/README.md b/README.md index f791177..438f48f 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ ExecJS supports these runtimes: Rhino embedded within JRuby * [Duktape.rb](https://github.com/judofyr/duktape.rb) - Duktape JavaScript interpreter * [Node.js](http://nodejs.org/) +* [Bun.sh](https://bun.sh) - JavaScript runtime & toolkit designed for speed * Apple JavaScriptCore - Included with Mac OS X * [Microsoft Windows Script Host](http://msdn.microsoft.com/en-us/library/9bbdkx3k.aspx) (JScript) * [Google V8](http://code.google.com/p/v8/) diff --git a/lib/execjs/runtimes.rb b/lib/execjs/runtimes.rb index 615ecd6..fd9d5c8 100644 --- a/lib/execjs/runtimes.rb +++ b/lib/execjs/runtimes.rb @@ -25,6 +25,13 @@ module Runtimes encoding: 'UTF-8' ) + Bun = ExternalRuntime.new( + name: "Bun.sh", + command: ["bun"], + runner_path: ExecJS.root + "/support/bun_runner.js", + encoding: 'UTF-8' + ) + JavaScriptCore = ExternalRuntime.new( name: "JavaScriptCore", command: [ @@ -88,6 +95,7 @@ def self.runtimes GraalJS, Duktape, MiniRacer, + Bun, Node, JavaScriptCore, SpiderMonkey, diff --git a/lib/execjs/support/bun_runner.js b/lib/execjs/support/bun_runner.js new file mode 100644 index 0000000..ddbdedf --- /dev/null +++ b/lib/execjs/support/bun_runner.js @@ -0,0 +1,29 @@ +(function(program, execJS) { (function() {execJS(program) }).call({}); })(function(self, global, process, module, exports, require, console, setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate) { #{source} +}, function(program) { + // Force BunJS to use sloppy mode see https://github.com/oven-sh/bun/issues/4527#issuecomment-1709520894 + exports.abc = function(){} + var __process__ = process; + var printFinal = function(string) { + process.stdout.write('' + string, function() { + __process__.exit(0); + }); + }; + try { + delete this.process; + delete this.console; + result = program(); + process = __process__; + if (typeof result == 'undefined' && result !== null) { + printFinal('["ok"]'); + } else { + try { + printFinal(JSON.stringify(['ok', result])); + } catch (err) { + printFinal(JSON.stringify(['err', '' + err, err.stack])); + } + } + } catch (err) { + process = __process__; + printFinal(JSON.stringify(['err', '' + err, err.stack])); + } +}); diff --git a/test/fixtures/uglify.js b/test/fixtures/uglify.js index ca48b66..71ec85c 100644 --- a/test/fixtures/uglify.js +++ b/test/fixtures/uglify.js @@ -307,7 +307,7 @@ if(!String.prototype.trim) { function definePropertyWorks() { try { Object.defineProperty({}, "property", {}); - return "property" in object; + return true; } catch (exception) { return false; } diff --git a/test/test_execjs.rb b/test/test_execjs.rb index f5b25b5..a2b698d 100644 --- a/test/test_execjs.rb +++ b/test/test_execjs.rb @@ -296,6 +296,9 @@ def test_console_is_undefined end def test_timers_are_undefined + # See Bug https://github.com/oven-sh/bun/issues/4806 + skip if ENV["EXECJS_RUNTIME"] == "Bun" + assert ExecJS.eval("typeof setTimeout == 'undefined'") assert ExecJS.eval("typeof setInterval == 'undefined'") assert ExecJS.eval("typeof clearTimeout == 'undefined'") @@ -327,7 +330,7 @@ def test_exec_syntax_error flunk rescue ExecJS::RuntimeError => e assert e - assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n") + assert e.backtrace.join("\n").include?("(execjs):") end end @@ -337,7 +340,7 @@ def test_eval_syntax_error flunk rescue ExecJS::RuntimeError => e assert e - assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n") + assert e.backtrace.join("\n").include?("(execjs):") end end @@ -347,7 +350,7 @@ def test_compile_syntax_error flunk rescue ExecJS::RuntimeError => e assert e - assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n") + assert e.backtrace[0].include?("(execjs):"), e.backtrace.join("\n") end end @@ -357,7 +360,7 @@ def test_exec_thrown_error flunk rescue ExecJS::ProgramError => e assert e - assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n") + assert e.backtrace.join("\n").include?("(execjs):") end end @@ -367,7 +370,7 @@ def test_eval_thrown_error flunk rescue ExecJS::ProgramError => e assert e - assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n") + assert e.backtrace.join("\n").include?("(execjs):") end end @@ -377,7 +380,7 @@ def test_compile_thrown_error flunk rescue ExecJS::ProgramError => e assert e - assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n") + assert e.backtrace.join("\n").include?("(execjs):") end end