Quantcast
Channel: ClearScript
Viewing all 2297 articles
Browse latest View live

Commented Issue: [BUG] Weak handle contexts are leaked during explicit disposal of cached V8 objects [90]

$
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).

Edited Issue: [BUG] DynamicObject: Unable to invoke method with Int argument [89]

$
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

Commented Issue: [BUG] DynamicObject: Unable to invoke method with Int argument [89]

$
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).

Created Unassigned: Cannot Access IReadOnlyCollection via interface Property [91]

$
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);
}
}



Edited Unassigned: Cannot Access IReadOnlyCollection via interface Property [91]

$
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);
}
}



Commented Unassigned: Cannot Access IReadOnlyCollection via interface Property [91]

$
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!

Commented Issue: [BUG] DynamicObject: Unable to invoke method with Int argument [89]

$
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.

Closed Issue: [BUG] DynamicObject: Unable to invoke method with Int argument [89]

$
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.

Closed Issue: [BUG] Weak handle contexts are leaked during explicit disposal of cached V8 objects [90]

$
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.

Closed Issue: [BUG] Script execution blocks V8 script item finalization [86]

$
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.

Edited Issue: Cannot Access IReadOnlyCollection via interface Property [91]

$
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);
}
}



Closed Issue: Cannot Access IReadOnlyCollection via interface Property [91]

$
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);
}
}



Updated Wiki: Home

$
0
0

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);
}

New Post: alert does not work ?

$
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

New Post: alert does not work ?

$
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!

New Post: alert does not work ?

$
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

New Post: Add functions and property from an Interface to a new API of the engine

$
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

New Post: alert does not work ?

$
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!

New Post: Add functions and property from an Interface to a new API of the engine

$
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!

New Post: alert does not work ?

$
0
0
Hi,

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

AddHostType instead of AddHostObject ...

Regards,

Sybaris
Viewing all 2297 articles
Browse latest View live


Latest Images