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

Edited Feature: V8ScriptEngine does not support stack limits [26]

0
0
Hi there,

I'm trying to evaluate how ClearScript's V8 implementation works when it comes to scripts that could contain issues of any kind. One particular case led me to running a script that contains circular reference, such as this one:
```
var cnt=0;
var addCounter=function(){
++cnt;
console.WriteLine('Counter: #'+(cnt));
addCounter();
}
addCounter();
```
When I execute this script via ClearScript.Execute method, I end up with "An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll" (InvokeHelpers.cs, line 144 --> var result = method.Invoke(target, finalArgs);) and there is no way to recover from it. Is there anything that could be done to recover from this error without changing a script section above?

Thanks,
Max

Commented Feature: V8ScriptEngine does not support stack limits [26]

0
0
Hi there,

I'm trying to evaluate how ClearScript's V8 implementation works when it comes to scripts that could contain issues of any kind. One particular case led me to running a script that contains circular reference, such as this one:
```
var cnt=0;
var addCounter=function(){
++cnt;
console.WriteLine('Counter: #'+(cnt));
addCounter();
}
addCounter();
```
When I execute this script via ClearScript.Execute method, I end up with "An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll" (InvokeHelpers.cs, line 144 --> var result = method.Invoke(target, finalArgs);) and there is no way to recover from it. Is there anything that could be done to recover from this error without changing a script section above?

Thanks,
Max
Comments: Stack limit support added in [Version 5.3.10](https://clearscript.codeplex.com/SourceControl/changeset/133980c335b05a07025111150f9cc2f8bc25a7fd).

Edited Unassigned: Overload resolution not working with indexed property [25]

0
0
When an class have overloaded indexed property,
overload resolution with the property does not work.

class definition (C#)
```
public class MyDictionary
{
public Object this[Int32 index]
{
get { return this.GetItemByIndex(index); }
}
public String this[String name]
{
get { return this.GetItemByName(name); }
}
// ...
}
```

Code execution
```
var engine = new V8ScriptEngine();
var dic = new MyDictionary();
engine.AddHostObject("dic", dic);

engine.Execute("dic.Item.get(0);"); // works
engine.Execute("dic.Item.get('name');"); // throws ScriptEngineException
```

Commented Unassigned: Overload resolution not working with indexed property [25]

0
0
When an class have overloaded indexed property,
overload resolution with the property does not work.

class definition (C#)
```
public class MyDictionary
{
public Object this[Int32 index]
{
get { return this.GetItemByIndex(index); }
}
public String this[String name]
{
get { return this.GetItemByName(name); }
}
// ...
}
```

Code execution
```
var engine = new V8ScriptEngine();
var dic = new MyDictionary();
engine.AddHostObject("dic", dic);

engine.Execute("dic.Item.get(0);"); // works
engine.Execute("dic.Item.get('name');"); // throws ScriptEngineException
```
Comments: We can't reproduce the issue with ClearScript 5.3.8 and up, and AtsushiSuzuki hasn't sent an update in 10 days. Marking as resolved.

New Post: access private fields of base class

0
0
Is it possible to get & set private fields of base class. Currently unable to get the fields of base class even after casting the object to base. But able to get private fields of derived class using the HostFlag privateaccess.

New Post: access private fields of base class

0
0
Greetings jnair, and thanks for your question!

Unfortunately ClearScript doesn't have a complete solution for private member access. As you've discovered, PrivateAccess only goes so far, and casting doesn't propagate it.

Here's one thing you can do. Let's say your classes look like this:
publicclass FooBase {
    privateint PrivateBaseField;
}
publicclass Foo : FooBase {
    privatestring PrivateField;
}
You can expose the base portion of your object separately, with its own PrivateAccess flag:
var foo = new Foo();
engine.AddHostObject("foo", HostItemFlags.PrivateAccess, foo);
engine.AddRestrictedHostObject("fooBase", HostItemFlags.PrivateAccess, (FooBase)foo);
engine.Execute(@"
    foo.PrivateField = 'bar';
    fooBase.PrivateBaseField = 123;
");
It's a bit ugly, but it works :)

Cheers!

New Post: How to add the ClearScript.V8 assemblies into GAC

0
0
Hello!

Tell me how to add the ClearScript.V8 assemblies into Global Assembly Cache?

New Post: How to add the ClearScript.V8 assemblies into GAC

0
0
Greetings!

ClearScript currently does not support the GAC. Its assemblies don't have keys or strong names, and its V8 assembly loading algorithm (see here) is incompatible with GAC deployment. Given that a full ClearScript installation includes normal, mixed-mode, and native assemblies, some combination of GAC and SxS deployment may be possible, but we haven't looked into it.

Cheers!

New Post: How to add the ClearScript.V8 assemblies into GAC

0
0
I have two questions:
  1. It possible in the future make loading of V8 assemblies like NSass?
  2. It possible embed v8-ia32.dll into ClearScriptV8-32.dll, and v8-x64.dll into ClearScriptV8-64.dll (like Noesis Javascript .NET)?

New Post: How to add the ClearScript.V8 assemblies into GAC

0
0
Hi Taritsyn,

It possible in the future make loading of V8 assemblies like NSass?

It looks like you're asking about an assembly resolver, which certainly seems like a viable alternative loading strategy. Can you tell us more about your scenario? Specifically, how would an assembly resolver for ClearScript help you reach your objective?

It possible embed v8-ia32.dll into ClearScriptV8-32.dll, and v8-x64.dll into ClearScriptV8-64.dll (like Noesis Javascript .NET)?

Yes, and we've experimented with this successfully. V8 can be built as a static library and linked into ClearScriptV8. We chose to keep V8 separate to reduce ClearScriptV8 link time, among other things, but again, we'd love to hear more about your scenario.

Thanks!

Commented Feature: V8ScriptEngine does not support stack limits [26]

0
0
Hi there,

I'm trying to evaluate how ClearScript's V8 implementation works when it comes to scripts that could contain issues of any kind. One particular case led me to running a script that contains circular reference, such as this one:
```
var cnt=0;
var addCounter=function(){
++cnt;
console.WriteLine('Counter: #'+(cnt));
addCounter();
}
addCounter();
```
When I execute this script via ClearScript.Execute method, I end up with "An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll" (InvokeHelpers.cs, line 144 --> var result = method.Invoke(target, finalArgs);) and there is no way to recover from it. Is there anything that could be done to recover from this error without changing a script section above?

Thanks,
Max
Comments: Thank you guys for adding it as quickly as you did.

New Post: How to add the ClearScript.V8 assemblies into GAC

0
0
Hello!

I use JavaScript engines in most modules of my open-source library - Bundle Transformer. JavaScript engines are used not directly, but through the wrapper – JavaScriptEngineSwitcher. Currently, I have a problem with using the Noesis Javascript .NET library under 64-bit version of IIS 8.X, and I see as a replacement the ClearScript.V8 library.

But there are following problems:
  1. Bundle Transformer is used in some CMS, which register all used assemblies in GAC.
  2. Bundle Transformer is used in the web projects of various types, including ASP.NET Web Pages sites. In ASP.NET Web Pages sites cannot store assemblies for different processor architectures in the root of bin directory, therefore it should be placed in subdirectories. For such cases in static constructor of the V8JsEngine class I determine and add search paths of the ClearScript.V8 assemblies. In order to be use JavaScriptEngineSwitcher.V8 in different projects types I wrote a special NuGet package.
In ClearScript.V8 it would be good to have the ability to set own assembly resolver, or at least have the ability to affect the result of V8Proxy.GetDirPaths method.

In addition, it would be good if the ClearScript assembly will be divided into 3 assemblies:
  1. ClearScript.Common - common types and utilities
  2. ClearScript.Windows - windows script engines
  3. ClearScript.V8 - V8 script engine proxy

New Post: How to add the ClearScript.V8 assemblies into GAC

0
0
Hi Taritsyn,

We're not ASP.NET or CMS experts here, so please bear with us.

Bundle Transformer is used in the web projects of various types, including ASP.NET Web Pages sites. In ASP.NET Web Pages sites cannot store assemblies for different processor architectures in the root of bin directory, therefore it should be placed in subdirectories.

Our normal recommendation for ASP.NET projects is to add the V8 and ClearScriptV8 assemblies as content files at the root of the web application, where the V8Proxy loader looks for them. We've used this scheme successfully in local, on-premises, and Azure deployments. Is it not practical for you?

Bundle Transformer is used in some CMS, which register all used assemblies in GAC.

If we understand correctly, this means that ClearScript.dll would have to be in the GAC as well, but the V8 and ClearScriptV8 assemblies could still be deployed as recommended above. Do you agree?

In ClearScript.V8 it would be good to have the ability to set own assembly resolver, or at least have the ability to affect the result of V8Proxy.GetDirPaths method.

Yes, we can see how this might add some flexibility. We'll take a look at it. In the meantime, would it be possible to use AppDomainSetup.PrivateBinPath?

In addition, it would be good if the ClearScript assembly will be divided into 3 assemblies:

The ClearScript assembly is relatively small - currently about 260K - and uses late-binding to instantiate the underlying script engines. It can be deployed without the V8 assemblies if JScript/VBScript are sufficient. Why split it up?

Thanks!

New Post: How to add the ClearScript.V8 assemblies into GAC

0
0
Our normal recommendation for ASP.NET projects is to add the V8 and ClearScriptV8 assemblies as content files at
the root of the web application, where the V8Proxy loader looks for them. We've used this scheme successfully in local, on-premises, and Azure deployments. Is it not practical for you?
It seems to me that this is not correct. It is suitable for WebMatrix sites, but not for ASP.NET web applications.
If we understand correctly, this means that ClearScript.dll would have to be in the GAC as well, but the V8 and ClearScriptV8 assemblies could still be deployed as recommended above. Do you agree?
​OK
Yes, we can see how this might add some flexibility. We'll take a look at it. In the meantime, would it be possible to use AppDomainSetup.PrivateBinPath?
Unfortunately, the AppDomainSetup.PrivateBinPath property cannot be changed for the current AppDomain. Now I use the following decision:
/// <summary>
/// Sets a path under the base directory where the assembly resolver should probe for private assemblies
/// </summary>
static V8JsEngine()
{
    var currentDomain = AppDomain.CurrentDomain;

    string binDirectoryPath = currentDomain.SetupInformation.PrivateBinPath;
    if (string.IsNullOrEmpty(binDirectoryPath))
    {
        // `PrivateBinPath` property is empty in test scenarios, so
        // need to use the `BaseDirectory` property
        binDirectoryPath = currentDomain.BaseDirectory;
    }

    string assemblyDirectoryPath = Path.Combine(binDirectoryPath, ASSEMBLY_DIRECTORY_NAME);
    if (!Directory.Exists(assemblyDirectoryPath) && HttpContext.Current != null)
    {
        // Fix for WebMatrix
        string applicationRootPath = HttpContext.Current.Server.MapPath("~");
        assemblyDirectoryPath = Path.Combine(applicationRootPath, ASSEMBLY_DIRECTORY_NAME);
    }

    currentDomain.AppendPrivatePath(assemblyDirectoryPath);
}
But the AppendPrivatePath method is deprecated. I would like to have some solution at the level of ClearScript.V8.
The ClearScript assembly is relatively small - currently about 260K - and uses late-binding to instantiate the underlying script engines. It can be deployed without the V8 assemblies if JScript/VBScript are sufficient. Why split it up?
Problem is not the size of assembly. Simply divide to 3 assemblies, it would be more correct (from the point of view of creating NuGet packages). In future will be easier to add a new script engines (for example, Chakra or SpiderMonkey).

Thanks!

New Post: How to add the ClearScript.V8 assemblies into GAC

0
0
Hi Taritsyn,

It seems to me that this is not correct. It is suitable for WebMatrix sites, but not for ASP.NET web applications.

We've received confirmation from others (e.g., here, here, and here) that it does work. The V8Proxy loader supports this setup by attempting to load the V8 and ClearScriptV8 assemblies from AppDomain.BaseDirectory.

Unfortunately, the AppDomainSetup.PrivateBinPath property cannot be changed for the current AppDomain.

Ah, that is indeed unfortunate. We'll investigate the assembly resolver option. To be honest, we have yet to understand the ramifications; e.g., the behavior when multiple resolvers are installed.

Problem is not the size of assembly. Simply divide to 3 assemblies, it would be more correct (from the point of view of creating NuGet packages). In future will be easier to add a new script engines (for example, Chakra or SpiderMonkey).

Yes, that's a good point. There are advantages to a minimal assembly count - deployment simplicity and startup performance - but they're diminished in ASP.NET environments. In any case, we probably won't do any major refactoring until we add support for more script engines.

Thanks again for your input!

Commented Feature: V8ScriptEngine does not support stack limits [26]

0
0
Hi there,

I'm trying to evaluate how ClearScript's V8 implementation works when it comes to scripts that could contain issues of any kind. One particular case led me to running a script that contains circular reference, such as this one:
```
var cnt=0;
var addCounter=function(){
++cnt;
console.WriteLine('Counter: #'+(cnt));
addCounter();
}
addCounter();
```
When I execute this script via ClearScript.Execute method, I end up with "An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll" (InvokeHelpers.cs, line 144 --> var result = method.Invoke(target, finalArgs);) and there is no way to recover from it. Is there anything that could be done to recover from this error without changing a script section above?

Thanks,
Max
Comments: Thanks for your kind words, Max!

Commented Unassigned: ClearScript not finding function added dynamically to window object [31]

0
0
ClearScript apparently can't find a function added dynamically to the window object.

In a regular html file, I can call "var passwordAnalysis = zxcvbn($(this).val(), penalties);" just fine.

However, I am trying to execute https://raw.github.com/lowe/zxcvbn/master/zxcvbn.js inside a C# project.

I always get the exception:

ScriptEngineException: TypeError: Method or property not found.

I suspect it is because the zxcvbn method is added dynamically.

C# Code is as follows:

using Microsoft.ClearScript;
using Microsoft.ClearScript.V8;

public class RunScripts
{
public void GetPasswordStrength(string password, string[] penalties)
{
using (var engine = new V8ScriptEngine())
{
engine.Execute(ZxcvbnScript);

var result = engine.Script.zxcvbn(password, penalties);
//or
var result = engine.Script.zxcvbn(password);
//or
var result = engine.Script.zxcvbn(password);
}
}
}
Comments: Ok, I don't think this is actually a problem with ClearScript - it occurs to me that this is probably "just" a javascript engine, and does not include an implementation of the DOM. I was actually able to run the script like I wanted with a very simple modification: public class JsWindow { public object zxcvbn { get; set; } } public class RunScripts { using (var engine = new V8ScriptEngine()) { engine.AddHostObject("window", HostItemFlags.GlobalMembers, new JsWindow()); engine.Execute(ZxcvbnScript); var result = engine.Script.zxcvbn(password, penalties); } }

Edited Unassigned: ClearScript not finding function added dynamically to window object [31]

0
0
ClearScript apparently can't find a function added dynamically to the window object.

In a regular html file, I can call "var passwordAnalysis = zxcvbn($(this).val(), penalties);" just fine.

However, I am trying to execute https://raw.github.com/lowe/zxcvbn/master/zxcvbn.js inside a C# project.

I always get the exception:

ScriptEngineException: TypeError: Method or property not found.

I suspect it is because the zxcvbn method is added dynamically.

C# Code is as follows:

using Microsoft.ClearScript;
using Microsoft.ClearScript.V8;

public class RunScripts
{
public void GetPasswordStrength(string password, string[] penalties)
{
using (var engine = new V8ScriptEngine())
{
engine.Execute(ZxcvbnScript);

var result = engine.Script.zxcvbn(password, penalties);
//or
var result = engine.Script.zxcvbn(password);
//or
var result = engine.Script.zxcvbn(password);
}
}
}

Commented Unassigned: ClearScript not finding function added dynamically to window object [31]

0
0
ClearScript apparently can't find a function added dynamically to the window object.

In a regular html file, I can call "var passwordAnalysis = zxcvbn($(this).val(), penalties);" just fine.

However, I am trying to execute https://raw.github.com/lowe/zxcvbn/master/zxcvbn.js inside a C# project.

I always get the exception:

ScriptEngineException: TypeError: Method or property not found.

I suspect it is because the zxcvbn method is added dynamically.

C# Code is as follows:

using Microsoft.ClearScript;
using Microsoft.ClearScript.V8;

public class RunScripts
{
public void GetPasswordStrength(string password, string[] penalties)
{
using (var engine = new V8ScriptEngine())
{
engine.Execute(ZxcvbnScript);

var result = engine.Script.zxcvbn(password, penalties);
//or
var result = engine.Script.zxcvbn(password);
//or
var result = engine.Script.zxcvbn(password);
}
}
}
Comments: Hi davisnw, Yes, the zxcvbn.js script appears to be designed for a browser environment with a `window` object or a CommonJS environment with an `exports` object. ClearScript provides a bare JavaScript environment with only the standard JavaScript built-ins. By the way, instead of exposing a host object for `window`, you could simply do this: ``` C# engine.Execute("window = this"); engine.Execute(ZxcvbnScript); ``` Cheers!

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);
}
Viewing all 2297 articles
Browse latest View live




Latest Images