Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are native functions created in Rhino?

I've been looking at the Rhino documentation and source code for a clue as to how to implement my own global native function. This task is however more complicated than I expected it to be.

After reading the code of the implementation of the require function in RingoJS I believe I need to do something along the following lines:

import org.mozilla.javascript.BaseFunction;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.Context;

public class MyGlobalNativeFunction extends BaseFunction {
    public MyGlobalNativeFunction() {}

    public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
        // implementation of my function
    }

    public int getArity() {
        return 1;
    }
}

Am I on the correct track? A step by step walkthrough on how to achieve this would be great.

Also it would be great if I could use Rhino's defineClass function to create my global native function. I'm not too keen on rolling out my own modified version of Rhino just because I want to implement one native function.

like image 546
Aadit M Shah Avatar asked Feb 18 '23 18:02

Aadit M Shah


2 Answers

I think this should work, and if you only want to implement a single global function it's a good approach. If you want to implement multiple functions or a host object, there are other approaches.

You'd then use something like this to instantiate your function:

scope.defineProperty("myNativeFunction",
                     new MyGlobalNativeFunction(),
                     ScriptableObject.DONTENUM);

Check out RingoGlobal for how this is done (it also shows how to define multiple functions in one sweep without having to creating a class for each). The Rhino examples directory contains some examples of how to create proper host objects with Rhino.

like image 61
Hannes Wallnöfer Avatar answered Feb 27 '23 06:02

Hannes Wallnöfer


First of all You need to init your global scope (init all javascript standard object, functions, etc), next to add your function to this scope as Hannes Wallnöfer wrote.

Context cx = Context.enter();  //enter rhino context - bind context with current thread
Scriptable globalScope= cx.initStandardObjects();  //init js standard object in global scope
globalScope.defineProperty("myNativeFunction",
                     new MyGlobalNativeFunction(),
                     ScriptableObject.DONTENUM);

and that's it.

Now to call this function invoke:

Object result = cx.evaluateString(globalScope, "myNativeFunction()", "<cmd>", 1, null);

For more information see: rhino embedding tutorial

like image 22
Dominik Kunicki Avatar answered Feb 27 '23 05:02

Dominik Kunicki