DelSkayn / rquickjs

High level bindings to the quickjs javascript engine
MIT License
539 stars 67 forks source link

u64 conversions #381

Open lastmjs opened 2 weeks ago

lastmjs commented 2 weeks ago

Hi, I would like some insight into u64 conversions from and into JavaScript. To me they seem incorrect.

When I return a u64 like this:

use ic_cdk::api::canister_version;
use rquickjs::{Ctx, Function, Result};

pub fn get_function(ctx: Ctx) -> Result<Function> {
    Function::new(ctx, || canister_version()) // canister_version returns a u64
}

The runtime type of the returned value is a number. This does not seem correct as I don't believe the JavaScript number type can store all u64s.

IIRC I also had a bigint that I wanted to pass into Rust, but it was converted into an f64 or something.

Are there problems with the number conversions in rquickjs?

In my mind and working with other JavaScript engines I would expect bigints for things like u64 and u128...

DelSkayn commented 1 week ago

u64 converting into a number is a design decision I made because it seemed reasonable. A JavaScript number can handle up to 52 bits without losing any precision and QuickJS API for big ints is very limited so we chose to have u64 convert into and from a number by default.

Rquickjs has a flexible API for converting types into and from js so if this behavior is not desired you can manually do the conversion or implement IntoJs and FromJs traits for a wrapper type.

A bigint shouldn't convert to a u64 unless explicitly done with the Coerce type.