sebastienros / jint

Javascript Interpreter for .NET

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

tomatosalat0 opened this issue · comments

Version used
Current main branch (commit c0b0369)

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.

  • The theory Operator_then_assignment_performs_operation tests are basic tests which all works fine.
  • The theory MathAssignmentOperator_performs_operation tests are doing the same as the test above, but with the -assignment operator (e.g. a += b instead of a = a + b). Three out of four of these tests fail (the divide works).
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.

Thanks for the detailed repro, should be fixed now.

This is part of the latest 3.1.3 release.