sciter-sdk / rust-sciter

Rust bindings for Sciter
https://sciter.com
MIT License
804 stars 75 forks source link

ArrayBuffer memory leak #123

Closed armersong closed 2 years ago

armersong commented 2 years ago

When extension demo runs, memory grows, It seems value(ArrayBuffer) is not release by engine. Pls help to check.

sciter.js: 4.4.8.13 - 4.4.8.14 quick js: 2021-03-27 os: linux mint 20.02

Modified from examples/extension

<html>
<head>
  <title>extension test</title>
  <style type="text/css">
  </style>
  <script type="text/javascript" type="module">
    import { loadLibrary } from "@sciter";
    const ext = loadLibrary("extension");
    console.log(ext); // Object
    console.log(JSON.stringify(ext)); // "{"add":"","sub":""}"
    console.log(typeof ext.add); // string
    console.log(ext.add(1,2)); // TypeError: not a function
    console.log(ext.sub(1,2));
    console.log(ext.print_args(1,2, new ArrayBuffer(100)));
    setInterval(function() {
        ext.callback(function(data){
            console.log("callback " + data);
        });
    }, 1000);
  </script>
</head>
<body>
  <h4>see logs in Inspector</h4>
</body>
</html>
//! Sciter extension library example.
//!
//! See the [blog post](https://sciter.com/include-library-name-native-extensions/).

#[macro_use]
extern crate sciter;

use sciter::types::{BOOL, VALUE};
use sciter::Value;

/// Extension entry point.
#[no_mangle]
pub extern "system" fn SciterLibraryInit(api: &'static sciter::ISciterAPI, exported: &mut VALUE) -> BOOL {
    sciter::set_host_api(api);

    let ext_api = vmap! {
        "add" => add,
        "sub" => sub,
        "print_args" => print_args,
        "callback" => callback,
    };

    ext_api.pack_to(exported);

    true as BOOL
}

/// Calculate the sum of all the given arguments.
pub fn add(args: &[Value]) -> Value {
    let sum: i32 = args
        .iter()
        .map(|v| v.to_int())
        .filter(|v| v.is_some())
        .map(|v| v.unwrap())
        .sum();

    sum.into()
}

/// `function sub(a, b) { return a - b; }`
pub fn sub(args: &[Value]) -> std::result::Result<Value, String> {
    if let [a, b] = args {
        let a = a.to_int().ok_or("`a` is not an int")?;
        let b = b.to_int().ok_or("`b` is not an int")?;

        let result = a - b;

        Ok(result.into())
    } else {
        Err(format!("sub(a,b) expects 2 parameters, given {} instead.", args.len()))
    }
}

pub fn print_args(args: &[Value]) -> Value {
    for i in 0..args.len() {
        println!("args[{}]: type {:?} {:?}", i, args[i].get_type(), args[i]);
    }
    println!("{:?}", args[2].as_bytes());
    Value::null()
}

pub fn callback(args: &[Value]) -> Value {
    assert!(args.len() >=1 && args[0].is_object_function());
    const SIZE:usize = 1024*1024;
    let mut data = Vec::with_capacity(SIZE);
    unsafe { data.set_len(SIZE) };
    let _ = args[0].call(None, &make_args!(Value::from(data.as_slice())), None);
    Value::null()
}

extension.zip

pravic commented 2 years ago

cc @c-smile

pravic commented 2 years ago

@armersong I think, it's better to ask on http://sciter.com/forums - most likely, it's Sciter-specific.

armersong commented 2 years ago

Ok, thanks