Running with Code Like with scissors, only more dangerous


Joining the Jurassic Team

Posted by Rob Paveza

Paul Bartrum graciously just accepted me as a contributor to Jurassic, an open-source JavaScript interpreter written in C#.  I mentioned that I had recently discovered IronJS, but at the time at least, there was no object model – no way of cleanly interfacing .NET code with the script runtime, and frankly, I don’t know F# well enough to meaningfully contribute to that project.  (Please don’t hate on me, functional language junkies).

Jurassic is an exceptionally easy runtime to interface with.  You have to create a script engine, assign it some global variables or functions if you like, and then tell it to execute script.  Very, very easy.  In fact, it took me about an hour to drum up a fairly comprehensive script plugin for JinxBot, which is able to respond to all of BN#’s events (except the clan ones). 

I have several goals and some things I’ve already contributed to the Jurassic source:

  • If you’ve exposed a class to JavaScript using it so far, you’ve probably seen that it’s incredibly easy to expose a method to JavaScript – you decorate it with the [JSFunction] attribute.  Unfortunately, there hadn’t been an analogue for properties, until a commit a couple of days ago.  I added a [JSProperty] attribute, which exposes these properties to JavaScript as accessors.  They are enumerable by default (which means they appear in a for (var … in) loop), and may be opted-in to be configurable.  You can see this functionality in the latest pull, and see it in action in the ScriptEngineTests test class.
  • I also noted that Paul had enabled exposing CLR objects to JavaScript, at least in the source code repository.  In my eyes, this was a security issue, because it could expose the reflection system to the security sandbox.  To account for this, I added the ScriptEngine.EnableExposedClrTypes property, which is false by default.  Attempting to set a global value to a static or instance type while this is false will result in a JavaScriptException being thrown.

Some things that I’ve already started working on and would like to see accomplished:

  • Create a console-based REPL loop.
  • Create a standard library to allow for sandboxed lower-level I/O.  To account for this, I’m planning to add an import(package, [assembly = ‘Jurassic.Library’], [alias]) function to the global object.  For example, import(‘Jurassic.Library.Io’); would import the I/O library, which would enable construction of objects like new io.ByteStream()
  • Create events on ScriptEngine that would allow the engine’s host to intercept, handle, and debug scripting errors.  The biggest use-case I see here is, for example, the debugger statement.  The goal I have here is to be able to create your own debugger, instead of having to launch the system JScript debugger, especially since the JScript debugger is ignorant of the scope and other objects within Jurassic’s engine.
  • Another event I’d like to be able to add is something like EngineAppearsToCycle.  Someone made the point that you could go into the console and type while (true) console.log(‘’) and crash your browser.  The compiler could be refactored somewhat to enable this to be handled.

Eventually, I think it would be cool to refactor the compilation engine to function more like V8 – specifically with its metaclasses.  I’m not particularly adept at building a lexer or parser, but I think Paul has already done a great job, and the engine is still quite fast.  Consequently, this is more of a long-term because-I-can goal than we-need-to-do-it goal, because I honestly don’t think it needs to be done.

I’m excited to be a part of the Jurassic team.  Go check out the project – it’s incredibly easy to add JavaScript scripting to your .NET project!

Filed under: Uncategorized 1 Comment