Are you the publisher? Claim or contact us about this channel


Embed this content in your HTML

Search

Report adult content:

click to rate:

Account: (login)

More Channels


Showcase


Channel Catalog


Channel Description:

ClearScript is a library that makes it easy to add scripting to your .NET applications. It currently supports JavaScript (via V8 and JScript) and VBScript.

older | 1 | .... | 81 | 82 | (Page 83) | 84 | 85 | .... | 115 | newer

    0 0

    When cached V8 objects are explicitly disposed during V8 context destruction, the weak states of their handles must be cleared and the associated weak callback contexts deleted.
    Comments: Fixed in [Version 5.4.3](https://clearscript.codeplex.com/SourceControl/changeset/ba8bf459e44aab693d58c6df4a80bb481319e04f).

    0 0

    I've been testing some of the ClearScript functionality based on following versions and an ability to invoke DynamicObject methods with various parameters. My testing didn't go far, I immediately started to see issues with Int based arguments for the methods I invoked. Here is a code I used:

    ```
    Module Module1

    Sub Main()
    Using engine As New V8ScriptEngine(V8ScriptEngineFlags.DisableGlobalMembers, V8ScriptEngineFlags.EnableDebugging, 9222)
    With engine
    ' test dynamic object
    .AddHostObject("testDynamicObj", New TestDynamicObject)
    .Execute("testDynamicObj.Run(111);")
    End With
    End Using
    End Sub

    End Module

    Public Class TestDynamicObject
    Inherits DynamicObject

    Public Overrides Function GetDynamicMemberNames() As IEnumerable(Of String)
    Return New List(Of String) From {"Run"}
    End Function

    Public Overrides Function TryGetMember(binder As GetMemberBinder, ByRef result As Object) As Boolean
    Return False
    End Function

    Public Overrides Function TryInvokeMember(binder As InvokeMemberBinder, args() As Object, ByRef result As Object) As Boolean
    result = binder.Name
    Return True
    End Function
    End Class

    ```
    Here is a test results:
    * ClearScript 5.3.10 - worked as expected, I've been able to reach TryInvokeMember an execute it.
    * ClearScript 5.4/5.4.2.1 - error, unable to reach TryInvokeMember. Error details as following:

    ```
    Microsoft.ClearScript.ScriptEngineException was unhandled
    _HResult=-2146233079
    _message=Error: An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    HResult=-2146233079
    IsTransient=false
    Message=Error: An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    Source=ClearScriptV8-64
    EngineName=2
    ErrorDetails=Error: An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    at Script Document:1:16 -> testDynamicObj.Run(111);
    IsFatal=false
    StackTrace:
    at V8Exception.ThrowScriptEngineException(V8Exception* )
    at Microsoft.ClearScript.V8.V8ContextProxyImpl.Execute(String gcDocumentName, String gcCode, Boolean evaluate, Boolean discard)
    at Microsoft.ClearScript.V8.V8ScriptEngine.<>c__DisplayClass1b.<Execute>b__19()
    at Microsoft.ClearScript.ScriptEngine.ScriptInvoke[T](Func`1 func)
    at Microsoft.ClearScript.V8.V8ScriptEngine.BaseScriptInvoke[T](Func`1 func)
    at Microsoft.ClearScript.V8.V8ScriptEngine.<>c__DisplayClass25`1.<ScriptInvoke>b__24()
    at Microsoft.ClearScript.V8.?A0x361e23e8.InvokeAction(Void* pvActionRef)
    at Microsoft.ClearScript.V8.V8ContextProxyImpl.InvokeWithLock(Action gcAction)
    at Microsoft.ClearScript.V8.V8ScriptEngine.ScriptInvoke[T](Func`1 func)
    at Microsoft.ClearScript.V8.V8ScriptEngine.Execute(String documentName, String code, Boolean evaluate, Boolean discard)
    at Microsoft.ClearScript.ScriptEngine.Execute(String documentName, Boolean discard, String code)
    at Microsoft.ClearScript.ScriptEngine.Execute(String documentName, String code)
    at Microsoft.ClearScript.ScriptEngine.Execute(String code)
    at ClearScript_5._3._9Test.EngineWrapper.RunScriptsExperimental(ScriptToRun scriptToRun, Int32 operationTimeout) in C:\Users\mshakirov\Documents\Visual Studio 2012\Projects\ClearScript-5.3.9Test\ClearScript-5.3.9Test\Module1.vb:line 113
    at ClearScript_5._3._9Test.Module1.Main() in C:\Users\mshakirov\Documents\Visual Studio 2012\Projects\ClearScript-5.3.9Test\ClearScript-5.3.9Test\Module1.vb:line 16
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Threading.ThreadHelper.ThreadStart()
    InnerException: System.InvalidOperationException
    _HResult=-2146233079
    _message=An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    HResult=-2146233079
    IsTransient=false
    Message=An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    Source=System.Core
    StackTrace:
    at System.Linq.Expressions.Expression.NewArrayInit(Type type, IEnumerable`1 initializers)
    at Microsoft.ClearScript.Util.DynamicHelpers.DynamicInvokeMemberBinder.FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
    at System.Dynamic.DynamicObject.MetaDynamic.BuildCallMethodWithResult(String methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke)
    at System.Dynamic.DynamicObject.MetaDynamic.BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
    at Microsoft.ClearScript.Util.DynamicHelpers.InvokeMember(DynamicMetaObject target, IHostInvokeContext context, String name, BindingFlags invokeFlags, Object[] args)
    at Microsoft.ClearScript.Util.DynamicHelpers.<>c__DisplayClass7.<TryInvokeMember>b__6()
    at Microsoft.ClearScript.Util.DynamicHelpers.TryDynamicOperation[T](Func`1 operation, T& result)
    at Microsoft.ClearScript.Util.DynamicHelpers.TryInvokeMember(DynamicMetaObject target, IHostInvokeContext context, String name, BindingFlags invokeFlags, Object[] args, Object& result)
    at Microsoft.ClearScript.HostItem.InvokeHostMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling)
    at Microsoft.ClearScript.HostMethod.TryInvoke(IHostInvokeContext context, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, Object& result)
    at Microsoft.ClearScript.Util.InvokeHelpers.TryInvokeObject(IHostInvokeContext context, Object target, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, Boolean tryDynamic, Object& result)
    at Microsoft.ClearScript.HostItem.InvokeHostMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.<>c__DisplayClass4b.<InvokeReflectMember>b__4a()
    at Microsoft.ClearScript.ScriptEngine.HostInvoke[T](Func`1 func)
    at Microsoft.ClearScript.HostItem.HostInvoke[T](Func`1 func)
    at Microsoft.ClearScript.HostItem.InvokeReflectMember(String name, BindingFlags invokeFlags, Object[] wrappedArgs, CultureInfo culture, String[] namedParams, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeReflectMember(String name, BindingFlags invokeFlags, Object[] wrappedArgs, CultureInfo culture, String[] namedParams)
    at Microsoft.ClearScript.HostItem.System.Reflection.IReflect.InvokeMember(String name, BindingFlags invokeFlags, Binder binder, Object invokeTarget, Object[] wrappedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
    at Microsoft.ClearScript.HostItem.Microsoft.ClearScript.Util.IDynamic.Invoke(Object[] args, Boolean asConstructor)
    at Microsoft.ClearScript.V8.V8ProxyHelpers.InvokeHostObject(Object obj, Object[] args, Boolean asConstructor)
    at Microsoft.ClearScript.V8.V8ProxyHelpers.InvokeHostObject(Void* pObject, Object[] args, Boolean asConstructor)
    at HostObjectHelpers.Invoke(V8Value* , Void* pvObject, vector<V8Value\,std::allocator<V8Value> >* args, Boolean asConstructor)
    InnerException:
    ```
    Just out of curiosity I've tested this with string argument, or non of it at all and it worked just as expected. I didn't test with any other argument type from that point and decided to share this with ClearScript team. Could someone elaborate on this and either point out at problem in the test code or confirm that there is a deeper issue at the ClearScript/V8 levels?

    Thanks in advance,
    Max


    0 0

    I've been testing some of the ClearScript functionality based on following versions and an ability to invoke DynamicObject methods with various parameters. My testing didn't go far, I immediately started to see issues with Int based arguments for the methods I invoked. Here is a code I used:

    ```
    Module Module1

    Sub Main()
    Using engine As New V8ScriptEngine(V8ScriptEngineFlags.DisableGlobalMembers, V8ScriptEngineFlags.EnableDebugging, 9222)
    With engine
    ' test dynamic object
    .AddHostObject("testDynamicObj", New TestDynamicObject)
    .Execute("testDynamicObj.Run(111);")
    End With
    End Using
    End Sub

    End Module

    Public Class TestDynamicObject
    Inherits DynamicObject

    Public Overrides Function GetDynamicMemberNames() As IEnumerable(Of String)
    Return New List(Of String) From {"Run"}
    End Function

    Public Overrides Function TryGetMember(binder As GetMemberBinder, ByRef result As Object) As Boolean
    Return False
    End Function

    Public Overrides Function TryInvokeMember(binder As InvokeMemberBinder, args() As Object, ByRef result As Object) As Boolean
    result = binder.Name
    Return True
    End Function
    End Class

    ```
    Here is a test results:
    * ClearScript 5.3.10 - worked as expected, I've been able to reach TryInvokeMember an execute it.
    * ClearScript 5.4/5.4.2.1 - error, unable to reach TryInvokeMember. Error details as following:

    ```
    Microsoft.ClearScript.ScriptEngineException was unhandled
    _HResult=-2146233079
    _message=Error: An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    HResult=-2146233079
    IsTransient=false
    Message=Error: An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    Source=ClearScriptV8-64
    EngineName=2
    ErrorDetails=Error: An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    at Script Document:1:16 -> testDynamicObj.Run(111);
    IsFatal=false
    StackTrace:
    at V8Exception.ThrowScriptEngineException(V8Exception* )
    at Microsoft.ClearScript.V8.V8ContextProxyImpl.Execute(String gcDocumentName, String gcCode, Boolean evaluate, Boolean discard)
    at Microsoft.ClearScript.V8.V8ScriptEngine.<>c__DisplayClass1b.<Execute>b__19()
    at Microsoft.ClearScript.ScriptEngine.ScriptInvoke[T](Func`1 func)
    at Microsoft.ClearScript.V8.V8ScriptEngine.BaseScriptInvoke[T](Func`1 func)
    at Microsoft.ClearScript.V8.V8ScriptEngine.<>c__DisplayClass25`1.<ScriptInvoke>b__24()
    at Microsoft.ClearScript.V8.?A0x361e23e8.InvokeAction(Void* pvActionRef)
    at Microsoft.ClearScript.V8.V8ContextProxyImpl.InvokeWithLock(Action gcAction)
    at Microsoft.ClearScript.V8.V8ScriptEngine.ScriptInvoke[T](Func`1 func)
    at Microsoft.ClearScript.V8.V8ScriptEngine.Execute(String documentName, String code, Boolean evaluate, Boolean discard)
    at Microsoft.ClearScript.ScriptEngine.Execute(String documentName, Boolean discard, String code)
    at Microsoft.ClearScript.ScriptEngine.Execute(String documentName, String code)
    at Microsoft.ClearScript.ScriptEngine.Execute(String code)
    at ClearScript_5._3._9Test.EngineWrapper.RunScriptsExperimental(ScriptToRun scriptToRun, Int32 operationTimeout) in C:\Users\mshakirov\Documents\Visual Studio 2012\Projects\ClearScript-5.3.9Test\ClearScript-5.3.9Test\Module1.vb:line 113
    at ClearScript_5._3._9Test.Module1.Main() in C:\Users\mshakirov\Documents\Visual Studio 2012\Projects\ClearScript-5.3.9Test\ClearScript-5.3.9Test\Module1.vb:line 16
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Threading.ThreadHelper.ThreadStart()
    InnerException: System.InvalidOperationException
    _HResult=-2146233079
    _message=An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    HResult=-2146233079
    IsTransient=false
    Message=An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    Source=System.Core
    StackTrace:
    at System.Linq.Expressions.Expression.NewArrayInit(Type type, IEnumerable`1 initializers)
    at Microsoft.ClearScript.Util.DynamicHelpers.DynamicInvokeMemberBinder.FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
    at System.Dynamic.DynamicObject.MetaDynamic.BuildCallMethodWithResult(String methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke)
    at System.Dynamic.DynamicObject.MetaDynamic.BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
    at Microsoft.ClearScript.Util.DynamicHelpers.InvokeMember(DynamicMetaObject target, IHostInvokeContext context, String name, BindingFlags invokeFlags, Object[] args)
    at Microsoft.ClearScript.Util.DynamicHelpers.<>c__DisplayClass7.<TryInvokeMember>b__6()
    at Microsoft.ClearScript.Util.DynamicHelpers.TryDynamicOperation[T](Func`1 operation, T& result)
    at Microsoft.ClearScript.Util.DynamicHelpers.TryInvokeMember(DynamicMetaObject target, IHostInvokeContext context, String name, BindingFlags invokeFlags, Object[] args, Object& result)
    at Microsoft.ClearScript.HostItem.InvokeHostMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling)
    at Microsoft.ClearScript.HostMethod.TryInvoke(IHostInvokeContext context, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, Object& result)
    at Microsoft.ClearScript.Util.InvokeHelpers.TryInvokeObject(IHostInvokeContext context, Object target, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, Boolean tryDynamic, Object& result)
    at Microsoft.ClearScript.HostItem.InvokeHostMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.<>c__DisplayClass4b.<InvokeReflectMember>b__4a()
    at Microsoft.ClearScript.ScriptEngine.HostInvoke[T](Func`1 func)
    at Microsoft.ClearScript.HostItem.HostInvoke[T](Func`1 func)
    at Microsoft.ClearScript.HostItem.InvokeReflectMember(String name, BindingFlags invokeFlags, Object[] wrappedArgs, CultureInfo culture, String[] namedParams, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeReflectMember(String name, BindingFlags invokeFlags, Object[] wrappedArgs, CultureInfo culture, String[] namedParams)
    at Microsoft.ClearScript.HostItem.System.Reflection.IReflect.InvokeMember(String name, BindingFlags invokeFlags, Binder binder, Object invokeTarget, Object[] wrappedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
    at Microsoft.ClearScript.HostItem.Microsoft.ClearScript.Util.IDynamic.Invoke(Object[] args, Boolean asConstructor)
    at Microsoft.ClearScript.V8.V8ProxyHelpers.InvokeHostObject(Object obj, Object[] args, Boolean asConstructor)
    at Microsoft.ClearScript.V8.V8ProxyHelpers.InvokeHostObject(Void* pObject, Object[] args, Boolean asConstructor)
    at HostObjectHelpers.Invoke(V8Value* , Void* pvObject, vector<V8Value\,std::allocator<V8Value> >* args, Boolean asConstructor)
    InnerException:
    ```
    Just out of curiosity I've tested this with string argument, or non of it at all and it worked just as expected. I didn't test with any other argument type from that point and decided to share this with ClearScript team. Could someone elaborate on this and either point out at problem in the test code or confirm that there is a deeper issue at the ClearScript/V8 levels?

    Thanks in advance,
    Max

    Comments: Fixed in [Version 5.4.3](https://clearscript.codeplex.com/SourceControl/changeset/ba8bf459e44aab693d58c6df4a80bb481319e04f).

    0 0

    I am running into a very strange issue where I cannot use the indexer of an IReadOnlyCollection when it is exposed via an interface property. Below is a code example of the problem. The second line of the script results in TypeError: Cannot read property 'SystemName' of undefined. E.g. the indexer is returning undefined. It seems like the indexer should work regardless of if I am accessing the host object directly or via an interface.

    >
    public interface IDataObject
    {
    Guid Id { get; set; }

    string SystemName { get; set; }

    string DisplayName { get; set; }

    string Description { get; set; }

    IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get; }
    }

    public class DataObject : IDataObject
    {
    public DataObject()
    {
    Children = new List<SubDataObject>();
    }

    public Guid Id { get; set; }

    public string SystemName { get; set; }

    public string DisplayName { get; set; }

    public string Description { get; set; }

    public IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get { return Children; } }

    public Char CharTest { get; set; }

    public int IntTest { get; set; }

    public decimal DecimalTest { get; set; }

    public byte ByteTest { get; set; }

    public bool? BoolTest { get; set; }

    public List<SubDataObject> Children { get; set; }

    public string IntTestToString()
    {
    return IntTest.ToString();
    }

    public Func<string> DoSomething { get; set; }
    }

    public class SubDataObject
    {
    public DataObject Parent { get; set; }

    public Guid Id { get; set; }

    public string SystemName { get; set; }

    public string DisplayName { get; set; }

    public string Description { get; set; }
    }

    private static void ReproduceIReadOnlyCollectionIssue()
    {
    var dataObj = new DataObject
    {
    Id = Guid.NewGuid(),
    SystemName = "Root Object System Name",
    DisplayName = "Root Object Display Name",
    Description = "Root Description",
    };

    dataObj.Children = new List<SubDataObject>
    {
    new SubDataObject
    {
    Parent = dataObj,
    Id = Guid.NewGuid(),
    SystemName = "Sub System Name 0",
    DisplayName = "Sub Display Name 0",
    Description = "Sub Description 0"
    }
    };

    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("Console", typeof(Console));
    engine.AddHostObject("dataObj", dataObj);
    engine.AddHostObject("readOnlyCollection", dataObj.ChildrenReadOnly);

    const string script = @"
    Console.WriteLine(readOnlyCollection[0].SystemName); //works fine
    Console.WriteLine(dataObj.ChildrenReadOnly[0].SystemName); //indexer returns undefined.
    ";
    engine.Execute(script);
    }
    }




    0 0

    I am running into a very strange issue where I cannot use the indexer of an IReadOnlyCollection when it is exposed via an interface property. Below is a code example of the problem. The second line of the script results in TypeError: Cannot read property 'SystemName' of undefined. E.g. the indexer is returning undefined. It seems like the indexer should work regardless of if I am accessing the host object directly or via an interface.

    >
    public interface IDataObject
    {
    Guid Id { get; set; }

    string SystemName { get; set; }

    string DisplayName { get; set; }

    string Description { get; set; }

    IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get; }
    }

    public class DataObject : IDataObject
    {
    public DataObject()
    {
    Children = new List<SubDataObject>();
    }

    public Guid Id { get; set; }

    public string SystemName { get; set; }

    public string DisplayName { get; set; }

    public string Description { get; set; }

    public IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get { return Children; } }

    public Char CharTest { get; set; }

    public int IntTest { get; set; }

    public decimal DecimalTest { get; set; }

    public byte ByteTest { get; set; }

    public bool? BoolTest { get; set; }

    public List<SubDataObject> Children { get; set; }

    public string IntTestToString()
    {
    return IntTest.ToString();
    }

    public Func<string> DoSomething { get; set; }
    }

    public class SubDataObject
    {
    public DataObject Parent { get; set; }

    public Guid Id { get; set; }

    public string SystemName { get; set; }

    public string DisplayName { get; set; }

    public string Description { get; set; }
    }

    private static void ReproduceIReadOnlyCollectionIssue()
    {
    var dataObj = new DataObject
    {
    Id = Guid.NewGuid(),
    SystemName = "Root Object System Name",
    DisplayName = "Root Object Display Name",
    Description = "Root Description",
    };

    dataObj.Children = new List<SubDataObject>
    {
    new SubDataObject
    {
    Parent = dataObj,
    Id = Guid.NewGuid(),
    SystemName = "Sub System Name 0",
    DisplayName = "Sub Display Name 0",
    Description = "Sub Description 0"
    }
    };

    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("Console", typeof(Console));
    engine.AddHostObject("dataObj", dataObj);
    engine.AddHostObject("readOnlyCollection", dataObj.ChildrenReadOnly);

    const string script = @"
    Console.WriteLine(readOnlyCollection[0].SystemName); //works fine
    Console.WriteLine(dataObj.ChildrenReadOnly[0].SystemName); //indexer returns undefined.
    ";
    engine.Execute(script);
    }
    }




    0 0

    I am running into a very strange issue where I cannot use the indexer of an IReadOnlyCollection when it is exposed via an interface property. Below is a code example of the problem. The second line of the script results in TypeError: Cannot read property 'SystemName' of undefined. E.g. the indexer is returning undefined. It seems like the indexer should work regardless of if I am accessing the host object directly or via an interface.

    >
    public interface IDataObject
    {
    Guid Id { get; set; }

    string SystemName { get; set; }

    string DisplayName { get; set; }

    string Description { get; set; }

    IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get; }
    }

    public class DataObject : IDataObject
    {
    public DataObject()
    {
    Children = new List<SubDataObject>();
    }

    public Guid Id { get; set; }

    public string SystemName { get; set; }

    public string DisplayName { get; set; }

    public string Description { get; set; }

    public IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get { return Children; } }

    public Char CharTest { get; set; }

    public int IntTest { get; set; }

    public decimal DecimalTest { get; set; }

    public byte ByteTest { get; set; }

    public bool? BoolTest { get; set; }

    public List<SubDataObject> Children { get; set; }

    public string IntTestToString()
    {
    return IntTest.ToString();
    }

    public Func<string> DoSomething { get; set; }
    }

    public class SubDataObject
    {
    public DataObject Parent { get; set; }

    public Guid Id { get; set; }

    public string SystemName { get; set; }

    public string DisplayName { get; set; }

    public string Description { get; set; }
    }

    private static void ReproduceIReadOnlyCollectionIssue()
    {
    var dataObj = new DataObject
    {
    Id = Guid.NewGuid(),
    SystemName = "Root Object System Name",
    DisplayName = "Root Object Display Name",
    Description = "Root Description",
    };

    dataObj.Children = new List<SubDataObject>
    {
    new SubDataObject
    {
    Parent = dataObj,
    Id = Guid.NewGuid(),
    SystemName = "Sub System Name 0",
    DisplayName = "Sub Display Name 0",
    Description = "Sub Description 0"
    }
    };

    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("Console", typeof(Console));
    engine.AddHostObject("dataObj", dataObj);
    engine.AddHostObject("readOnlyCollection", dataObj.ChildrenReadOnly);

    const string script = @"
    Console.WriteLine(readOnlyCollection[0].SystemName); //works fine
    Console.WriteLine(dataObj.ChildrenReadOnly[0].SystemName); //indexer returns undefined.
    ";
    engine.Execute(script);
    }
    }



    Comments: Hello! This behavior is by design. Consider this line from your sample: ``` C# engine.AddHostObject("dataObj", dataObj); ``` With this setup, the expression `dataObj.ChildrenReadOnly` is of type `IReadOnlyCollection<SubDataObject>`. This type doesn't have an indexer, so applying indexing syntax to the result yields `undefined` in JavaScript and a compilation error in C#. To understand why it works in the other case, consider this line: ``` C# engine.AddHostObject("readOnlyCollection", dataObj.ChildrenReadOnly); ``` When you use `AddHostObject()`, you expose the given object's _runtime_ type, which in this case is `List<SubDataObject>` — a type that does have an indexer. Therefore `readOnlyCollection[0]` works as you expect. You may be wondering why ClearScript doesn't always expose the runtime types of managed objects. The reason has to do with C#-style method binding, which relies heavily on static typing. Most script languages don't support static typing, so ClearScript simulates it with a feature called type restriction. Type restriction is the default behavior in ClearScript, although `AddHostObject()` predates it and retains its original behavior for compatibility. A newer method, `AddRestrictedHostObject()`, serves a similar purpose but supports type restriction. In any case, you can use `ScriptMemberAttribute` to disable type restriction for an individual class member, or `ScriptEngine.DisableTypeRestriction` to turn it off globally. Keep in mind however that doing so may break certain method binding scenarios. Good luck!

    0 0

    I've been testing some of the ClearScript functionality based on following versions and an ability to invoke DynamicObject methods with various parameters. My testing didn't go far, I immediately started to see issues with Int based arguments for the methods I invoked. Here is a code I used:

    ```
    Module Module1

    Sub Main()
    Using engine As New V8ScriptEngine(V8ScriptEngineFlags.DisableGlobalMembers, V8ScriptEngineFlags.EnableDebugging, 9222)
    With engine
    ' test dynamic object
    .AddHostObject("testDynamicObj", New TestDynamicObject)
    .Execute("testDynamicObj.Run(111);")
    End With
    End Using
    End Sub

    End Module

    Public Class TestDynamicObject
    Inherits DynamicObject

    Public Overrides Function GetDynamicMemberNames() As IEnumerable(Of String)
    Return New List(Of String) From {"Run"}
    End Function

    Public Overrides Function TryGetMember(binder As GetMemberBinder, ByRef result As Object) As Boolean
    Return False
    End Function

    Public Overrides Function TryInvokeMember(binder As InvokeMemberBinder, args() As Object, ByRef result As Object) As Boolean
    result = binder.Name
    Return True
    End Function
    End Class

    ```
    Here is a test results:
    * ClearScript 5.3.10 - worked as expected, I've been able to reach TryInvokeMember an execute it.
    * ClearScript 5.4/5.4.2.1 - error, unable to reach TryInvokeMember. Error details as following:

    ```
    Microsoft.ClearScript.ScriptEngineException was unhandled
    _HResult=-2146233079
    _message=Error: An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    HResult=-2146233079
    IsTransient=false
    Message=Error: An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    Source=ClearScriptV8-64
    EngineName=2
    ErrorDetails=Error: An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    at Script Document:1:16 -> testDynamicObj.Run(111);
    IsFatal=false
    StackTrace:
    at V8Exception.ThrowScriptEngineException(V8Exception* )
    at Microsoft.ClearScript.V8.V8ContextProxyImpl.Execute(String gcDocumentName, String gcCode, Boolean evaluate, Boolean discard)
    at Microsoft.ClearScript.V8.V8ScriptEngine.<>c__DisplayClass1b.<Execute>b__19()
    at Microsoft.ClearScript.ScriptEngine.ScriptInvoke[T](Func`1 func)
    at Microsoft.ClearScript.V8.V8ScriptEngine.BaseScriptInvoke[T](Func`1 func)
    at Microsoft.ClearScript.V8.V8ScriptEngine.<>c__DisplayClass25`1.<ScriptInvoke>b__24()
    at Microsoft.ClearScript.V8.?A0x361e23e8.InvokeAction(Void* pvActionRef)
    at Microsoft.ClearScript.V8.V8ContextProxyImpl.InvokeWithLock(Action gcAction)
    at Microsoft.ClearScript.V8.V8ScriptEngine.ScriptInvoke[T](Func`1 func)
    at Microsoft.ClearScript.V8.V8ScriptEngine.Execute(String documentName, String code, Boolean evaluate, Boolean discard)
    at Microsoft.ClearScript.ScriptEngine.Execute(String documentName, Boolean discard, String code)
    at Microsoft.ClearScript.ScriptEngine.Execute(String documentName, String code)
    at Microsoft.ClearScript.ScriptEngine.Execute(String code)
    at ClearScript_5._3._9Test.EngineWrapper.RunScriptsExperimental(ScriptToRun scriptToRun, Int32 operationTimeout) in C:\Users\mshakirov\Documents\Visual Studio 2012\Projects\ClearScript-5.3.9Test\ClearScript-5.3.9Test\Module1.vb:line 113
    at ClearScript_5._3._9Test.Module1.Main() in C:\Users\mshakirov\Documents\Visual Studio 2012\Projects\ClearScript-5.3.9Test\ClearScript-5.3.9Test\Module1.vb:line 16
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Threading.ThreadHelper.ThreadStart()
    InnerException: System.InvalidOperationException
    _HResult=-2146233079
    _message=An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    HResult=-2146233079
    IsTransient=false
    Message=An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    Source=System.Core
    StackTrace:
    at System.Linq.Expressions.Expression.NewArrayInit(Type type, IEnumerable`1 initializers)
    at Microsoft.ClearScript.Util.DynamicHelpers.DynamicInvokeMemberBinder.FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
    at System.Dynamic.DynamicObject.MetaDynamic.BuildCallMethodWithResult(String methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke)
    at System.Dynamic.DynamicObject.MetaDynamic.BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
    at Microsoft.ClearScript.Util.DynamicHelpers.InvokeMember(DynamicMetaObject target, IHostInvokeContext context, String name, BindingFlags invokeFlags, Object[] args)
    at Microsoft.ClearScript.Util.DynamicHelpers.<>c__DisplayClass7.<TryInvokeMember>b__6()
    at Microsoft.ClearScript.Util.DynamicHelpers.TryDynamicOperation[T](Func`1 operation, T& result)
    at Microsoft.ClearScript.Util.DynamicHelpers.TryInvokeMember(DynamicMetaObject target, IHostInvokeContext context, String name, BindingFlags invokeFlags, Object[] args, Object& result)
    at Microsoft.ClearScript.HostItem.InvokeHostMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling)
    at Microsoft.ClearScript.HostMethod.TryInvoke(IHostInvokeContext context, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, Object& result)
    at Microsoft.ClearScript.Util.InvokeHelpers.TryInvokeObject(IHostInvokeContext context, Object target, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, Boolean tryDynamic, Object& result)
    at Microsoft.ClearScript.HostItem.InvokeHostMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.<>c__DisplayClass4b.<InvokeReflectMember>b__4a()
    at Microsoft.ClearScript.ScriptEngine.HostInvoke[T](Func`1 func)
    at Microsoft.ClearScript.HostItem.HostInvoke[T](Func`1 func)
    at Microsoft.ClearScript.HostItem.InvokeReflectMember(String name, BindingFlags invokeFlags, Object[] wrappedArgs, CultureInfo culture, String[] namedParams, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeReflectMember(String name, BindingFlags invokeFlags, Object[] wrappedArgs, CultureInfo culture, String[] namedParams)
    at Microsoft.ClearScript.HostItem.System.Reflection.IReflect.InvokeMember(String name, BindingFlags invokeFlags, Binder binder, Object invokeTarget, Object[] wrappedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
    at Microsoft.ClearScript.HostItem.Microsoft.ClearScript.Util.IDynamic.Invoke(Object[] args, Boolean asConstructor)
    at Microsoft.ClearScript.V8.V8ProxyHelpers.InvokeHostObject(Object obj, Object[] args, Boolean asConstructor)
    at Microsoft.ClearScript.V8.V8ProxyHelpers.InvokeHostObject(Void* pObject, Object[] args, Boolean asConstructor)
    at HostObjectHelpers.Invoke(V8Value* , Void* pvObject, vector<V8Value\,std::allocator<V8Value> >* args, Boolean asConstructor)
    InnerException:
    ```
    Just out of curiosity I've tested this with string argument, or non of it at all and it worked just as expected. I didn't test with any other argument type from that point and decided to share this with ClearScript team. Could someone elaborate on this and either point out at problem in the test code or confirm that there is a deeper issue at the ClearScript/V8 levels?

    Thanks in advance,
    Max

    Comments: You guys rock! I'll test it first thing on Monday.

    0 0

    I've been testing some of the ClearScript functionality based on following versions and an ability to invoke DynamicObject methods with various parameters. My testing didn't go far, I immediately started to see issues with Int based arguments for the methods I invoked. Here is a code I used:

    ```
    Module Module1

    Sub Main()
    Using engine As New V8ScriptEngine(V8ScriptEngineFlags.DisableGlobalMembers, V8ScriptEngineFlags.EnableDebugging, 9222)
    With engine
    ' test dynamic object
    .AddHostObject("testDynamicObj", New TestDynamicObject)
    .Execute("testDynamicObj.Run(111);")
    End With
    End Using
    End Sub

    End Module

    Public Class TestDynamicObject
    Inherits DynamicObject

    Public Overrides Function GetDynamicMemberNames() As IEnumerable(Of String)
    Return New List(Of String) From {"Run"}
    End Function

    Public Overrides Function TryGetMember(binder As GetMemberBinder, ByRef result As Object) As Boolean
    Return False
    End Function

    Public Overrides Function TryInvokeMember(binder As InvokeMemberBinder, args() As Object, ByRef result As Object) As Boolean
    result = binder.Name
    Return True
    End Function
    End Class

    ```
    Here is a test results:
    * ClearScript 5.3.10 - worked as expected, I've been able to reach TryInvokeMember an execute it.
    * ClearScript 5.4/5.4.2.1 - error, unable to reach TryInvokeMember. Error details as following:

    ```
    Microsoft.ClearScript.ScriptEngineException was unhandled
    _HResult=-2146233079
    _message=Error: An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    HResult=-2146233079
    IsTransient=false
    Message=Error: An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    Source=ClearScriptV8-64
    EngineName=2
    ErrorDetails=Error: An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    at Script Document:1:16 -> testDynamicObj.Run(111);
    IsFatal=false
    StackTrace:
    at V8Exception.ThrowScriptEngineException(V8Exception* )
    at Microsoft.ClearScript.V8.V8ContextProxyImpl.Execute(String gcDocumentName, String gcCode, Boolean evaluate, Boolean discard)
    at Microsoft.ClearScript.V8.V8ScriptEngine.<>c__DisplayClass1b.<Execute>b__19()
    at Microsoft.ClearScript.ScriptEngine.ScriptInvoke[T](Func`1 func)
    at Microsoft.ClearScript.V8.V8ScriptEngine.BaseScriptInvoke[T](Func`1 func)
    at Microsoft.ClearScript.V8.V8ScriptEngine.<>c__DisplayClass25`1.<ScriptInvoke>b__24()
    at Microsoft.ClearScript.V8.?A0x361e23e8.InvokeAction(Void* pvActionRef)
    at Microsoft.ClearScript.V8.V8ContextProxyImpl.InvokeWithLock(Action gcAction)
    at Microsoft.ClearScript.V8.V8ScriptEngine.ScriptInvoke[T](Func`1 func)
    at Microsoft.ClearScript.V8.V8ScriptEngine.Execute(String documentName, String code, Boolean evaluate, Boolean discard)
    at Microsoft.ClearScript.ScriptEngine.Execute(String documentName, Boolean discard, String code)
    at Microsoft.ClearScript.ScriptEngine.Execute(String documentName, String code)
    at Microsoft.ClearScript.ScriptEngine.Execute(String code)
    at ClearScript_5._3._9Test.EngineWrapper.RunScriptsExperimental(ScriptToRun scriptToRun, Int32 operationTimeout) in C:\Users\mshakirov\Documents\Visual Studio 2012\Projects\ClearScript-5.3.9Test\ClearScript-5.3.9Test\Module1.vb:line 113
    at ClearScript_5._3._9Test.Module1.Main() in C:\Users\mshakirov\Documents\Visual Studio 2012\Projects\ClearScript-5.3.9Test\ClearScript-5.3.9Test\Module1.vb:line 16
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Threading.ThreadHelper.ThreadStart()
    InnerException: System.InvalidOperationException
    _HResult=-2146233079
    _message=An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    HResult=-2146233079
    IsTransient=false
    Message=An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'
    Source=System.Core
    StackTrace:
    at System.Linq.Expressions.Expression.NewArrayInit(Type type, IEnumerable`1 initializers)
    at Microsoft.ClearScript.Util.DynamicHelpers.DynamicInvokeMemberBinder.FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
    at System.Dynamic.DynamicObject.MetaDynamic.BuildCallMethodWithResult(String methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke)
    at System.Dynamic.DynamicObject.MetaDynamic.BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
    at Microsoft.ClearScript.Util.DynamicHelpers.InvokeMember(DynamicMetaObject target, IHostInvokeContext context, String name, BindingFlags invokeFlags, Object[] args)
    at Microsoft.ClearScript.Util.DynamicHelpers.<>c__DisplayClass7.<TryInvokeMember>b__6()
    at Microsoft.ClearScript.Util.DynamicHelpers.TryDynamicOperation[T](Func`1 operation, T& result)
    at Microsoft.ClearScript.Util.DynamicHelpers.TryInvokeMember(DynamicMetaObject target, IHostInvokeContext context, String name, BindingFlags invokeFlags, Object[] args, Object& result)
    at Microsoft.ClearScript.HostItem.InvokeHostMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling)
    at Microsoft.ClearScript.HostMethod.TryInvoke(IHostInvokeContext context, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, Object& result)
    at Microsoft.ClearScript.Util.InvokeHelpers.TryInvokeObject(IHostInvokeContext context, Object target, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, Boolean tryDynamic, Object& result)
    at Microsoft.ClearScript.HostItem.InvokeHostMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.<>c__DisplayClass4b.<InvokeReflectMember>b__4a()
    at Microsoft.ClearScript.ScriptEngine.HostInvoke[T](Func`1 func)
    at Microsoft.ClearScript.HostItem.HostInvoke[T](Func`1 func)
    at Microsoft.ClearScript.HostItem.InvokeReflectMember(String name, BindingFlags invokeFlags, Object[] wrappedArgs, CultureInfo culture, String[] namedParams, Boolean& isCacheable)
    at Microsoft.ClearScript.HostItem.InvokeReflectMember(String name, BindingFlags invokeFlags, Object[] wrappedArgs, CultureInfo culture, String[] namedParams)
    at Microsoft.ClearScript.HostItem.System.Reflection.IReflect.InvokeMember(String name, BindingFlags invokeFlags, Binder binder, Object invokeTarget, Object[] wrappedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
    at Microsoft.ClearScript.HostItem.Microsoft.ClearScript.Util.IDynamic.Invoke(Object[] args, Boolean asConstructor)
    at Microsoft.ClearScript.V8.V8ProxyHelpers.InvokeHostObject(Object obj, Object[] args, Boolean asConstructor)
    at Microsoft.ClearScript.V8.V8ProxyHelpers.InvokeHostObject(Void* pObject, Object[] args, Boolean asConstructor)
    at HostObjectHelpers.Invoke(V8Value* , Void* pvObject, vector<V8Value\,std::allocator<V8Value> >* args, Boolean asConstructor)
    InnerException:
    ```
    Just out of curiosity I've tested this with string argument, or non of it at all and it worked just as expected. I didn't test with any other argument type from that point and decided to share this with ClearScript team. Could someone elaborate on this and either point out at problem in the test code or confirm that there is a deeper issue at the ClearScript/V8 levels?

    Thanks in advance,
    Max

    Comments: Closing fixed bugs.

    0 0

    When cached V8 objects are explicitly disposed during V8 context destruction, the weak states of their handles must be cleared and the associated weak callback contexts deleted.
    Comments: Closing fixed bugs.

    0 0

    The V8 script item finalizer currently requires a V8 runtime lock. If the runtime is executing a long-running script, it can block the finalization thread and cause out-of-control memory consumption and frequent garbage collection.
    Comments: Closing fixed bugs.

    0 0

    I am running into a very strange issue where I cannot use the indexer of an IReadOnlyCollection when it is exposed via an interface property. Below is a code example of the problem. The second line of the script results in TypeError: Cannot read property 'SystemName' of undefined. E.g. the indexer is returning undefined. It seems like the indexer should work regardless of if I am accessing the host object directly or via an interface.

    >
    public interface IDataObject
    {
    Guid Id { get; set; }

    string SystemName { get; set; }

    string DisplayName { get; set; }

    string Description { get; set; }

    IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get; }
    }

    public class DataObject : IDataObject
    {
    public DataObject()
    {
    Children = new List<SubDataObject>();
    }

    public Guid Id { get; set; }

    public string SystemName { get; set; }

    public string DisplayName { get; set; }

    public string Description { get; set; }

    public IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get { return Children; } }

    public Char CharTest { get; set; }

    public int IntTest { get; set; }

    public decimal DecimalTest { get; set; }

    public byte ByteTest { get; set; }

    public bool? BoolTest { get; set; }

    public List<SubDataObject> Children { get; set; }

    public string IntTestToString()
    {
    return IntTest.ToString();
    }

    public Func<string> DoSomething { get; set; }
    }

    public class SubDataObject
    {
    public DataObject Parent { get; set; }

    public Guid Id { get; set; }

    public string SystemName { get; set; }

    public string DisplayName { get; set; }

    public string Description { get; set; }
    }

    private static void ReproduceIReadOnlyCollectionIssue()
    {
    var dataObj = new DataObject
    {
    Id = Guid.NewGuid(),
    SystemName = "Root Object System Name",
    DisplayName = "Root Object Display Name",
    Description = "Root Description",
    };

    dataObj.Children = new List<SubDataObject>
    {
    new SubDataObject
    {
    Parent = dataObj,
    Id = Guid.NewGuid(),
    SystemName = "Sub System Name 0",
    DisplayName = "Sub Display Name 0",
    Description = "Sub Description 0"
    }
    };

    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("Console", typeof(Console));
    engine.AddHostObject("dataObj", dataObj);
    engine.AddHostObject("readOnlyCollection", dataObj.ChildrenReadOnly);

    const string script = @"
    Console.WriteLine(readOnlyCollection[0].SystemName); //works fine
    Console.WriteLine(dataObj.ChildrenReadOnly[0].SystemName); //indexer returns undefined.
    ";
    engine.Execute(script);
    }
    }




    0 0

    I am running into a very strange issue where I cannot use the indexer of an IReadOnlyCollection when it is exposed via an interface property. Below is a code example of the problem. The second line of the script results in TypeError: Cannot read property 'SystemName' of undefined. E.g. the indexer is returning undefined. It seems like the indexer should work regardless of if I am accessing the host object directly or via an interface.

    >
    public interface IDataObject
    {
    Guid Id { get; set; }

    string SystemName { get; set; }

    string DisplayName { get; set; }

    string Description { get; set; }

    IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get; }
    }

    public class DataObject : IDataObject
    {
    public DataObject()
    {
    Children = new List<SubDataObject>();
    }

    public Guid Id { get; set; }

    public string SystemName { get; set; }

    public string DisplayName { get; set; }

    public string Description { get; set; }

    public IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get { return Children; } }

    public Char CharTest { get; set; }

    public int IntTest { get; set; }

    public decimal DecimalTest { get; set; }

    public byte ByteTest { get; set; }

    public bool? BoolTest { get; set; }

    public List<SubDataObject> Children { get; set; }

    public string IntTestToString()
    {
    return IntTest.ToString();
    }

    public Func<string> DoSomething { get; set; }
    }

    public class SubDataObject
    {
    public DataObject Parent { get; set; }

    public Guid Id { get; set; }

    public string SystemName { get; set; }

    public string DisplayName { get; set; }

    public string Description { get; set; }
    }

    private static void ReproduceIReadOnlyCollectionIssue()
    {
    var dataObj = new DataObject
    {
    Id = Guid.NewGuid(),
    SystemName = "Root Object System Name",
    DisplayName = "Root Object Display Name",
    Description = "Root Description",
    };

    dataObj.Children = new List<SubDataObject>
    {
    new SubDataObject
    {
    Parent = dataObj,
    Id = Guid.NewGuid(),
    SystemName = "Sub System Name 0",
    DisplayName = "Sub Display Name 0",
    Description = "Sub Description 0"
    }
    };

    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("Console", typeof(Console));
    engine.AddHostObject("dataObj", dataObj);
    engine.AddHostObject("readOnlyCollection", dataObj.ChildrenReadOnly);

    const string script = @"
    Console.WriteLine(readOnlyCollection[0].SystemName); //works fine
    Console.WriteLine(dataObj.ChildrenReadOnly[0].SystemName); //indexer returns undefined.
    ";
    engine.Execute(script);
    }
    }




    0 0
  • 09/04/15--13:11: Updated Wiki: Home
  • Description

    ClearScript is a library that makes it easy to add scripting to your .NET applications. It currently supports JavaScript (via V8 and JScript) and VBScript.

    Features

    • Simple usage; create a script engine, add your objects and/or types, run scripts
    • Support for several script engines: Google's V8, Microsoft's JScript and VBScript
    • Exposed resources require no modification, decoration, or special coding of any kind
    • Scripts get simple access to most of the features of exposed objects and types:
      • Methods, properties, fields, events
      • (Objects) Indexers, extension methods, conversion operators, explicitly implemented interfaces
      • (Types) Constructors, nested types
    • Full support for generic types and methods, including C#-like type inference and explicit type arguments
    • Scripts can invoke methods with output parameters, optional parameters, and parameter arrays
    • Script delegates enable callbacks into script code
    • Support for exposing all the types defined in one or more assemblies in one step
    • Optional support for importing types and assemblies from script code
    • The host can invoke script functions and access script objects directly
    • Full support for script debugging

    Examples

    using System;
    using Microsoft.ClearScript;
    using Microsoft.ClearScript.V8;
    
    // create a script engineusing (var engine = new V8ScriptEngine())
    {
        // expose a host type
        engine.AddHostType("Console", typeof(Console));
        engine.Execute("Console.WriteLine('{0} is an interesting number.', Math.PI)");
    
        // expose a host object
        engine.AddHostObject("random", new Random());
        engine.Execute("Console.WriteLine(random.NextDouble())");
    
        // expose entire assemblies
        engine.AddHostObject("lib", new HostTypeCollection("mscorlib", "System.Core"));
        engine.Execute("Console.WriteLine(lib.System.DateTime.Now)");
    
        // create a host object from script
        engine.Execute(@"
            birthday = new lib.System.DateTime(2007, 5, 22);
            Console.WriteLine(birthday.ToLongDateString());
        ");
    
        // use a generic class from script
        engine.Execute(@"
            Dictionary = lib.System.Collections.Generic.Dictionary;
            dict = new Dictionary(lib.System.String, lib.System.Int32);
            dict.Add('foo', 123);
        ");
    
        // call a host method with an output parameter
        engine.AddHostObject("host", new HostFunctions());
        engine.Execute(@"
            intVar = host.newVar(lib.System.Int32);
            found = dict.TryGetValue('foo', intVar.out);
            Console.WriteLine('{0} {1}', found, intVar);
        ");
    
        // create and populate a host array
        engine.Execute(@"
            numbers = host.newArr(lib.System.Int32, 20);
            for (var i = 0; i < numbers.Length; i++) { numbers[i] = i; }
            Console.WriteLine(lib.System.String.Join(', ', numbers));
        ");
    
        // create a script delegate
        engine.Execute(@"
            Filter = lib.System.Func(lib.System.Int32, lib.System.Boolean);
            oddFilter = new Filter(function(value) {
                return (value & 1) ? true : false;
            });
        ");
    
        // use LINQ from script
        engine.Execute(@"
            oddNumbers = numbers.Where(oddFilter);
            Console.WriteLine(lib.System.String.Join(', ', oddNumbers));
        ");
    
        // use a dynamic host object
        engine.Execute(@"
            expando = new lib.System.Dynamic.ExpandoObject();
            expando.foo = 123;
            expando.bar = 'qux';
            delete expando.foo;
        ");
    
        // call a script function
        engine.Execute("function print(x) { Console.WriteLine(x); }");
        engine.Script.print(DateTime.Now.DayOfWeek);
    
        // examine a script object
        engine.Execute("person = { name: 'Fred', age: 5 }");
        Console.WriteLine(engine.Script.person.name);
    }

    0 0

    Hi

    Why the following code crashs :
    using (var engine = new Microsoft.ClearScript.Windows.JScriptEngine())
    {
                    engine.Execute("alert('hello world')");
    }
    Is there is a way to display messagebox like alert call ?

    Thanks for advance.
    Sybaris

    0 0

    Hello Sybaris,

    The alert method is part of the Web API, which is usually provided by web browsers and is not part of the JavaScript standard. However, you can easily expose a similar method based on WPF:
    engine.Script.alert = new Action<string>(msg => MessageBox.Show(msg));
    engine.Execute("alert('Hello, world!')");
    Good luck!

    0 0

    Hi,

    Thanks for your answer.
    Is there is a way to declare same API alert (an action and not a function), but without using Script (dynamic) property ?

    Something like that :
    engine.AddHostType("alert", new Action<string>(msg => MessageBox.Show(msg)));
    Note that previous code does not compile...
    Thanks for advance

    Sybaris

    0 0

    Hi,

    I have the following code with a class that expose an interface. I would like to expose my interface to javascript engine, but not using "objects".
    
        public interface ITest
        {
            void foo(string s);
            //... many other methods
            int bar { get; set; }
        }
    
        public class Test : ITest
        {
            public void foo(string s)
            {
                MessageBox.Show(s);
            }
    
            public int bar {get;set;}
        }
    The code I would write is this :
                    engine.Execute("foo('hello')");
                    engine.Execute("bar=6");
    But NOT something like
                    engine.Execute("myObject.foo('hello')");
                    engine.Execute("myObject.bar=6");
    So how can I expose all my interface as an API ?
    I would like to do something like that :
                    ITest t = new Test();
                    engine.AddHostObject("", t);
    And I would not have to "wrap" each method and property, or if you have generic code that wrap all an interface, I am interested please...

    Thanks for advance for your answer
    Sybaris

    0 0

    Hi again,

    Sure, you can do it this way:
    engine.AddHostObject("alert", new Action<string>(msg => MessageBox.Show(msg)));
    engine.Execute("alert('Hello, world!')");
    Cheers!

    0 0

    Hi Sybaris,

    You can use the "global members" feature to achieve the desired effect:
    ITest t = new Test();
    engine.AddRestrictedHostObject("test", HostItemFlags.GlobalMembers, t);
    engine.Execute("foo('hello')");
    Note that using AddRestrictedHostObject() in this manner ensures that only the ITest interface members are exposed for scripting. Other members of the object remain inaccessible. Use AddHostObject() if that is not the desired behavior.

    Thanks for your question!

    0 0

    Hi,

    Thanks. this is exactly the solution I was looking for.
    I was not very far :-)

    AddHostType instead of AddHostObject ...

    Regards,

    Sybaris

older | 1 | .... | 81 | 82 | (Page 83) | 84 | 85 | .... | 115 | newer