Search code examples
v8clearscript

ClearScript V8 JS Cannot use Arrow Functions and modify destructured values


Update 2: Add the usage usage scenario. Update 1: Interestingly enough

(
       function({ value }){ 
          return value * 2;
       }
)

works just fine (as well as "-", "/"). I'm not trying to be pathetic, but this looks like a fairly basic mistake for a project which is around for about a decade, is this project still maintained?


I'm using C# with Microsoft.ClearScript.V8 + Microsoft.ClearScript.V8.Native.win-x64 v7.4.3

Have a couple of questions:

  1. When can we get access to arrow function "=>" as they don't seem to work at all at present.

  2. Having the following simple JS script I can't modify the destructured value, due to an exception:

Script:

   (
       function({ value }){ 
          return value + 1;
       }
    )

Inputs: { value: 1 }

the restructuring part works (just remove the +1 bit), but I can't modify the destructured value due to the following exception (note "+" sign being cut off):

Microsoft.ClearScript.ScriptEngineException: SyntaxError: Unexpected number
 ---> Microsoft.ClearScript.ScriptEngineException: SyntaxError: Unexpected number
   at Microsoft.ClearScript.V8.SplitProxy.V8SplitProxyNative.ThrowScheduledException()
   at Microsoft.ClearScript.V8.SplitProxy.V8SplitProxyNative.Invoke[T](Func`2 func)
   at Microsoft.ClearScript.V8.SplitProxy.V8ContextProxyImpl.Execute(UniqueDocumentInfo documentInfo, String code, Boolean evaluate)
   at Microsoft.ClearScript.V8.V8ScriptEngine.ExecuteRaw(UniqueDocumentInfo documentInfo, String code, Boolean evaluate)
   at Microsoft.ClearScript.V8.V8ScriptEngine.ExecuteInternal(UniqueDocumentInfo documentInfo, String code, Boolean evaluate)
   at Microsoft.ClearScript.V8.V8ScriptEngine.<>c__DisplayClass130_0.<Execute>b__0()
   at Microsoft.ClearScript.ScriptEngine.ScriptInvokeInternal[T](Func`1 func)
   at Microsoft.ClearScript.V8.V8ScriptEngine.<>c__DisplayClass137_0`1.<ScriptInvoke>b__0()
   at Microsoft.ClearScript.V8.SplitProxy.V8SplitProxyManaged.InvokeHostAction(IntPtr pAction)
   --- Script error details follow ---
   SyntaxError: Unexpected number
       at Script [temp]:1:46 -> (   function({ value }){       return value  1;   })
   --- End of inner exception stack trace ---
   at Microsoft.ClearScript.V8.SplitProxy.V8SplitProxyNative.ThrowScheduledException()
   at Microsoft.ClearScript.V8.SplitProxy.V8SplitProxyNative.Invoke(Action`1 action)
   at Microsoft.ClearScript.V8.SplitProxy.V8ContextProxyImpl.InvokeWithLock(Action action)
   at Microsoft.ClearScript.V8.V8ScriptEngine.ScriptInvoke[T](Func`1 func)
   at Microsoft.ClearScript.V8.V8ScriptEngine.Execute(UniqueDocumentInfo documentInfo, String code, Boolean evaluate)
   at Microsoft.ClearScript.ScriptEngine.Evaluate(UniqueDocumentInfo documentInfo, String code, Boolean marshalResult)
   at Microsoft.ClearScript.ScriptEngine.Evaluate(DocumentInfo documentInfo, String code)
   at Microsoft.ClearScript.ScriptEngine.Evaluate(String documentName, Boolean discard, String code)
   at Microsoft.ClearScript.ScriptEngine.Evaluate(String documentName, String code)
   at Microsoft.ClearScript.ScriptEngine.Evaluate(String code)

Usage scenario:

(both script and data inputs are string)

using (var v8 = new V8ScriptEngine())
{
    dynamic evaluateScript = v8.Evaluate(script); 
    
    var inputs = data.ToObject();

    var result = evaluateScript(inputs);

    return JsonConvert.SerializeObject(result);
}

...

public static object ToObject(this string s) {

    if (new[] { "{", "}", ":" }.Any(s.Contains))
    {
        try
        {
            return JsonConvert.DeserializeObject<ExpandoObject>(s)!;
        }
        catch (Exception ex)
        {
            return s;
        }
    }
    else if (s.ToCharArray().Any(char.IsDigit))
    {
        if (s.Contains(".")
            && double.TryParse(s, out var @double))
        {
            return @double;
        }
        else if (int.TryParse(s, out var @int))
        {
            return @int;
        }
        else {
            return s;
        }
    }
    else
    {
        return s;
    }
}

Solution

  • Can you share more of your code? The following seems to work perfectly:

    using var v8 = new V8ScriptEngine();
    Console.WriteLine(v8.Evaluate(@"
        (
            function({ value }) { return value + 1; }
        )({ value: 1 })
    "));
    Console.WriteLine(v8.Evaluate(@"
        (
            ({ value }) => value + 2
        )({ value: 2 })
    "));
    

    As expected, this prints out "2" and "4". Is there something you're doing differently?