Hello, first time poster here. I’m looking at SpiderMoney for embedding in an audio application, and I have some things I’d like to clarify before I get started. I’ve been using a much smaller JavaScript parser JUCE::JavascriptEngine, but it is quite limited and so I need to replace it. I’ve been doing a lot of research over the past couple of weeks (V8, ChakraCore, etc.), and SpiderMonkey has the API that makes most sense to me and seems to be generally well suited to my project. I’m fairly competent at C++ and the JUCE library, but I’ve never worked with a package as heavy as SpiderMonkey before, so it’s quite possible that I’ll be making some basic mistakes. Please correct me if I do.
I will first give some context about my program. I’m building an audio application which lets the user sequence events by writing code. For instance, the user might write
play(50);
wait(1);
start(next());
which would play Midi note 50, wait for one second, and then start the next bit of code. Rather than write my own DSL, I’m using a Javascript for the parsing. (From the example I’ve given here this seem that this is not a good decision, but for reasons I won’t go into here, Javascript is a actually great fit). The user will also be able to write their own functions, store variables, etc, just like in regular code. The situation here is that the code I’ll be executing will mostly be quite short, but it will be executing frequently, and I really want the process to be as light as possible, since the application will have a lot of other heavy audio processing to deal with.
Now for my questions.
-
One of the reasons why I wanted to use SpiderMonkey is because of the JIT compiler and other optimizers. In some of the documentation, I read that SpiderMonkey first parses code to an Abstract Syntax Tree which can later be executed much more efficiently. My question is: is it possible to parse the code once and then store the AST somehow for execution later? What I’m thinking of here is that you pass in some code as a string and the AST could be created only once. Then the AST could be executed many times, without the expensive parsing. It might be, though, that in SpiderMonkey the AST only exists under the hood, and that the user never has access to it. If that is the case, is there some other way that I can achieve this “parse once, execute many times” model?
-
In JUCE::JavascriptEngine, code can be run in two different ways: “execute” (which can set new variables, and returns success / failure status), and “evauate” (which basically just runs a function and returns the result). Are there similarly two different modes in SpiderMonkey? If not, what is the simplest way of running a line of Javascript code and returning the result in C++?
-
Related to the last question, I want to know if it is possible to define a global JS function which returns custom C++ types. I see that
JS::Value
is the object that deals with JS values. This can hold basic types, but can this hold a pointer to a custom type also? for example, in JUCE::JavascriptEngine, I can define a global functionplay
which returns in C++ a pointer to a classPlayExecution
, which my C++ app can then deal with accordingly. Is this possible in SpiderMonkey also? -
Building SpiderMonkey is the thing that scares me most about it. I’ve found two different guides for building SpiderMoney:
1: https://github.com/mozilla-spidermonkey/spidermonkey-embedding-examples/blob/esr91/docs/Building%20SpiderMonkey.md2: https://firefox-source-docs.mozilla.org/js/build.html
The two seem to differ quite a lot. Which one should I be using? Are there any other resources I’m missing? (I’m using Windows, btw). Also, a simple question: how large is it once its built?
Thanks for taking the time to read my post. If you can answer just one of these questions, or set me straight on why they are misguided, I’ll be very grateful.