quickjs-oxide-core 0.4.0

The new quickjs-oxide core: 8-byte values, typed arenas and a mark-sweep heap
Documentation
//! The global functions: qjs's `print`, `parseInt`, `parseFloat`, `isNaN`
//! and `isFinite`.

use super::to_string_id;
use crate::value::Value;
use crate::vm::native::CallSite;
use crate::vm::number::number;
use crate::vm::{Cx, Output, Throw, ops, radix};

/// qjs's `performance.now()`: milliseconds on a monotonic clock.
pub(super) fn performance_now(_: &mut Cx<'_>, _: CallSite) -> Result<Value, Throw> {
    Ok(Value::number(super::agent::monotonic_ms()))
}

/// qjs's `print`: the arguments' strings joined by a space, then a newline.
pub(super) fn print(cx: &mut Cx<'_>, site: CallSite) -> Result<Value, Throw> {
    let mut line = Vec::new();
    for index in 0..site.argc {
        if index > 0 {
            line.push(b' ');
        }
        let argument = site.arg(cx, index);
        // QuickJS's `js_print`: a string as is (WTF-8), anything else
        // through `JS_PrintValue`.
        match argument.as_string() {
            Some(id) => crate::vm::print::wtf8(cx.heap.string(id).repr().units(), &mut line),
            None => line.extend_from_slice(&crate::vm::print::print_value(cx, argument)),
        }
    }
    line.push(b'\n');
    match &mut cx.host.output {
        Output::Stdout => cx.host.hooks.write(crate::host::Stream::Stdout, &line),
        Output::Capture(text) => text.push_str(&String::from_utf8_lossy(&line)),
    }
    Ok(Value::UNDEFINED)
}

/// `parseInt(string, radix)`: `ToString`, then `ToInt32` of the radix.
pub(super) fn parse_int(cx: &mut Cx<'_>, site: CallSite) -> Result<Value, Throw> {
    let input = site.arg(cx, 0);
    let input = to_string_id(cx, input)?;
    let radix = site.arg(cx, 1);
    let radix = match radix.as_int32() {
        Some(radix) => radix,
        None => crate::vm::number::to_int32(ops::to_number(cx, radix)?),
    };
    let units: Vec<u16> = cx.heap.string(input).repr().units().collect();
    Ok(number(radix::parse_int(&units, radix)))
}

pub(super) fn parse_float(cx: &mut Cx<'_>, site: CallSite) -> Result<Value, Throw> {
    let input = site.arg(cx, 0);
    let input = to_string_id(cx, input)?;
    let units: Vec<u16> = cx.heap.string(input).repr().units().collect();
    Ok(number(radix::parse_float(&units)))
}

pub(super) fn is_nan(cx: &mut Cx<'_>, site: CallSite) -> Result<Value, Throw> {
    let value = site.arg(cx, 0);
    Ok(Value::bool(ops::to_number(cx, value)?.is_nan()))
}

pub(super) fn is_finite(cx: &mut Cx<'_>, site: CallSite) -> Result<Value, Throw> {
    let value = site.arg(cx, 0);
    Ok(Value::bool(ops::to_number(cx, value)?.is_finite()))
}