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

Public method overriden in internal class: call from JS error #112

Closed
ezolotko opened this issue May 9, 2019 · 6 comments
Closed

Public method overriden in internal class: call from JS error #112

ezolotko opened this issue May 9, 2019 · 6 comments
Assignees

Comments

@ezolotko
Copy link

ezolotko commented May 9, 2019

The code below produces Microsoft.ClearScript.ScriptEngineException: 'TypeError: myobj.MyMethod() is not a function', while the MyMethod method is public and is defined in a public class.

    public abstract class MyBase
    {
        public abstract void MyMethod();
    }
    internal class MyDerived : MyBase
    {
        public override void MyMethod()
        {
            Console.WriteLine("MyMethod");
        }
    }

    var engine = new V8ScriptEngine();
    var myobj = new MyDerived();

    myobj.MyMethod();

    engine.AddHostObject("myobj", myobj);

    // Microsoft.ClearScript.ScriptEngineException: 'TypeError: myobj.MyMethod() is not a function'
    engine.Execute("myobj.MyMethod();");

If I change internal class MyDerived to public, the method is called as expected. Here is a project that reproduces the problem:
ClearScriptTypeError.zip
It also includes the WpfTest() method, which reproduces what seems to be the same problem, but with a real-world class from WPF (System.Windows.Media.VisualDrawingContext). This is how we encountered this issue in the first place.

@ClearScriptLib
Copy link
Collaborator

Hi @ezolotko,

This looks like a bug. Here's a workaround. Instead of this:

engine.AddHostObject("myobj", myobj);

do this:

engine.AddRestrictedHostObject<MyBase>("myobj", myobj);

Thank you!

@ezolotko
Copy link
Author

ezolotko commented May 9, 2019

@ClearScriptLib Thank you for your reply.

We are experiencing this issue in a scenario like this:

            var engine = new V8ScriptEngine();
            engine.Execute("function f(o) { o.MyMethod(); }");
            engine.Invoke("f", new MyDerived());

As I understand, the workaround with AddRestrictedHostObject is not applicable here. Do you have any advice on this scenario?
Thank you.

@ClearScriptLib
Copy link
Collaborator

Hi @ezolotko,

You can do this:

var host = engine.Script.host = new HostFunctions();
engine.Invoke("f", host.cast<MyBase>(new MyDerived()));

Cheers!

@ezolotko
Copy link
Author

@ClearScriptLib the workaround works, thank you very much!

@ClearScriptLib
Copy link
Collaborator

@ezolotko Thanks for reporting this issue. The next release will include a fix as well as an easier way to pass a type-bound ("restricted") object to script code.

ClearScriptLib added a commit that referenced this issue Aug 1, 2019
…y, GitHub Issue #114); added initial support for CommonJS modules (V8 and JScript); added ScriptEngine.ExecuteDocument and ScriptEngine.EvaluateDocument; added V8ScriptEngine.CompileDocument and V8Runtime.CompileDocument; added support for machine-level deployment (GitHub Issue #117); added Extensions and JavaScriptExtensions to facilitate specific scenarios; added implicit conversion of host method arguments via user-defined operators (GitHub Issue #115); patched a V8 issue that causes occasional script execution failure in 32-bit processes (GitHub Issue #111); fixed accessibility of public methods overriden by internal classes (GitHub Issue #112); updated deployment and API documentation. Tested with V8 7.6.303.28.
@ClearScriptLib
Copy link
Collaborator

ClearScript 5.6 includes a fix for this issue.

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

No branches or pull requests

2 participants