Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistency with "typeof" results #19

Closed
Muchaszewski opened this issue Oct 26, 2017 · 6 comments
Closed

Inconsistency with "typeof" results #19

Muchaszewski opened this issue Oct 26, 2017 · 6 comments
Assignees
Labels

Comments

@Muchaszewski
Copy link

As of now I couldn't find a good way of creating internal JavaScript objects from text to pass them into engine, so I'm using kind of hack

        public static object CreateObject(string document)
        {
            var sb = new StringBuilder();
            sb.Append($"var __obj__ = {document}");
            _engine.ExecuteCommand(sb.ToString());
            return _engine.Script.__obj__;   
        } 

This method produces a mostly valid "object" for most of the purposes but typeof from this object returns function instead of the required type such as array or object etc...

This being mentioned such code is returning false
C#

managed.setScriptData("csharpObjectFromText", JSUtils.CreateObject("[]"));
V8ScriptEngine.Execute(script); 

JS

var array = Managed.getScriptData("csharpObjectFromText");
if(typeof array === typeof []) //expected true

I just hope this is not my misunderstanding of javascript objects using ClearScript.

@ClearScriptLib
Copy link
Collaborator

Hi @Muchaszewski,

First, your CreateObject method could simply be this:

public static object CreateObject(string document)
{
    return _engine.Evaluate(document);
}

Second, how do setScriptData and getScriptData work?

@Muchaszewski
Copy link
Author

Thanks for a tip.

Those methods are pretty straightforward. Just dictionary storage.

        public Dictionary<string, object> ScriptResults = new Dictionary<string, object>();

        public void setScriptData(string name, object value)
        {
            ScriptResults[name] = value;
        }

        public object getScriptData(string name)
        {
            if (ScriptResults.ContainsKey(name))
            {
                return ScriptResults[name];
            }
            return null;
        }

@ClearScriptLib
Copy link
Collaborator

@Muchaszewski, is it possible that, when your script calls getScriptData, it gets an object that was created by a different instance of V8ScriptEngine? That would explain what you're seeing.

A script engine cannot be given direct access to an object created by another script engine, so ClearScript provides a proxy that marshals invocations across script engine boundaries. JavaScript's typeof always returns "function" when applied to a ClearScript proxy.

Note that, although ClearScript supports this setup, it isn't recommended. Invocations across script engines incur heavy overhead, and the full capabilities of the target object may not be accessible.

If the object belongs to the same script engine, ClearScript should hand it off without a proxy, resulting in the expected behavior. Please let us know if that's not the case.

@Muchaszewski
Copy link
Author

I confirm that the case. CreateObject is using a different instance of V8ScriptEngine. This is due to the limitation I have encountered. Settings up Engine.MaxRuntimeStackUsage = 50 and invoking CreateObject always created stack overflow on complicated enough objects, or when reaching stack limit and trying to create anything.

My idea to prevent developers from passing object from different instances of an engine, and making them wonder about errors that can occur from that, simple check and a setting for instantiation of an engine.

Engine = new V8ScriptEngine();
Engine.AllowProxyObjects = true; //Default is false

@ClearScriptLib
Copy link
Collaborator

@Muchaszewski, the runtime stack usage limit is specified in bytes. A value of 50 actually selects an internal minimum, which is currently 16 KiB, and while that may be enough to run simple scripts, it's not surprising that you can easily overflow it by calling into the host and back out to script code.

Consider increasing that limit, or not specifying one at all. A higher limit will let you reign in runaway scripts without having to deal with the overhead of external script objects.

@Muchaszewski
Copy link
Author

Ok. I will close this ticket as the issue with inconsistency is solved.

As mentioned above would be nice to have documentation on that behavior that multiple V8ScriptEngine "talking" to each other may cause an error, this is not so obvious as my example has shown :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants