Controlling what's Marshalled

May 24, 2012 at 6:45 PM

Is there any possibility of the very clever developers adding the ability to control which parts of the CLR are marshalled?  Perhaps via an event that is thrown for each one when creating the cache?

May 24, 2012 at 10:03 PM

Jint doesn't have an explicit method to control the marshaling, but it's not hard to make some customization. Actually marshalling consists of several simple steps:

1. Creating a regular object

2. Setting the internal value to the CLR instance

3. Propagating CLR properties to the js object

3. Specify a proper prototype which is also a regular object which contains a wrappers around CLR methods

 

Steps 2 and 3 can be made by applying a CLR constructor, i.e. My.Namespace.Foo.apply(jsobject,...). A new CLR instance will be created an assigned to jsobject and all public native properties will be propagated.

Here more complete example

function CustomFoo() {
    My.Namespace.Foo.apply(this);
};

CustomFoo.prototype.testMe = My.Namespace.Foo.TestMethod;

var o = new CustomFoo();
o.testMe(); // will call  My.Namespace.Foo.TestMethod

Same results may be achieved in the CLR:

1. You need to create JsObject with two parameters: a CLR instance which you are marshalling, and a desired prototype which will define available methods

2. Use NativeConstrutor.SetupNativeProperties on the created JsObject to populate a native properties (use Marshaller.MarshalType(type) to get a corresponding NativeConstructor)

May 25, 2012 at 8:46 AM

Thank you very much for your reply.

I fear, however, either I'm not understanding fully or have not communicated my desire for the requested functionality.

I wish to control what parts of the framework the engine has access to, so that only my namespace is available.

I tried what you suggested, but believe (perhaps wrongly) that it requires the AllowClr property to be true, which exposes everything anyway?

I also tried using the SetFunction that then returns a constructed object - this works with the AllowClr property set to false, however the user would construct by simply calling the function rather than using the new keyword, which is at odds with the natural way of programming in javascript.

I hope I'm explaining myself properly - and thank you in advance for your assistance.

May 25, 2012 at 11:24 PM

I'm planning to remove AllowClr in the future and replace it with custom code permissions, currently this parameter affects  implicit type resolution, i.e. when you wrote fully qualified type name and there is no such object in the current scope it will try to find an appropriate CLR type.

Unfortunately without this parameter you will loose indexers (for CLR objects) and maybe something more.

Returning to your question: import only a particular type to the js runtime,  use NativeConstructor, to create a js constructor for you CLR type, then use JintEngine.SetParameter to pass it to the script or assign it to a property of an existing your object, something like below

((JsObject)engine.Run("my.lib",false))["importedType"] = nativeConstructor;

then you can use it from your script:

var obj = new my.lib.importedType();

In the future I'm planning to introduce some methods to JintEngine to import a specified set of CLR types before a script will be executed and a set of permissions that will control the level of isolation of the executing script from the CLR (for example how dependencies are resolved and what types can be imported to the runtime).

Also there will be a built-in function to allow scripts to import native types.

May 26, 2012 at 6:57 AM

Thank you very much for taking the time to help me - it's very much appreciated.