sebastienros / jint

Javascript Interpreter for .NET
BSD 2-Clause "Simplified" License
4.02k stars 556 forks source link

Addition-assignment -, subtract-assignment - and multiply-assignment operator throws an error when using BigInt #1885

Closed tomatosalat0 closed 2 months ago

tomatosalat0 commented 2 months ago

Version used Current main branch (commit c0b0369d)

Describe the bug

When using BigInt values, the addition-assignment, subtract-assignment, ...-assignment operators will throw an error:

Cannot convert a BigInt value to a number

To Reproduce Here is a finished xUnit test class.

using Jint.Native;

namespace Jint.Tests.Runtime;

public class BigIntTests
{
    [Theory]
    [InlineData("a = a + b;", "146")]
    [InlineData("a = a - b;", "100")]
    [InlineData("a = a * b;", "2829")]
    [InlineData("a = a / b;", "5")]
    public void Operator_then_assignment_performs_operation(string statement, string expected)
    {
        var outputValues = new List<JsValue>();
        var engine = new Engine()
            .SetValue("log", outputValues.Add);
        engine.Evaluate("let a = 123n; let b = 23n;");

        engine.Evaluate(statement);

        engine.Evaluate("log(a)");
        Assert.True(outputValues[0].IsBigInt(), "The type of the value is expected to stay BigInt");
        Assert.Equal(expected, outputValues[0].ToString());
    }

    [Theory]
    [InlineData("a += b;", "146")]
    [InlineData("a -= b;", "100")]
    [InlineData("a *= b;", "2829")]
    [InlineData("a /= b;", "5")]
    public void MathAssignmentOperator_performs_operation(string statement, string expected)
    {
        var outputValues = new List<JsValue>();
        var engine = new Engine()
            .SetValue("log", outputValues.Add);
        engine.Evaluate("let a = 123n; let b = 23n;");

        engine.Evaluate(statement);

        engine.Evaluate("log(a)");
        Assert.True(outputValues[0].IsBigInt(), "The type of the value is expected to stay BigInt");
        Assert.Equal(expected, outputValues[0].ToString());
    }
}

Additional context

I've looked into the JintAssignmentExpression.EvaluateInternal, but I am not deep enough into the inner workings of the code there + all the quirks of the JS math operators with different types which all needs to be solved by the engine.

lahma commented 2 months ago

Thanks for the detailed repro, should be fixed now.

lahma commented 2 months ago

This is part of the latest 3.1.3 release.