Repository: metacall/core (language: rust)

Issue:
Rust loader, loading from memory bug when running `./docker-compose.sh test`
## 🐛 Bug Report

```
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from metacall_rust_load_from_mem_test
[ RUN      ] metacall_rust_load_from_mem_test.DefaultConstructor
[Wed Aug  3 23:31:44] #131 [ 104 | metacall_initialize | /usr/local/metacall/source/metacall/source/metacall.c ] @Debug : MetaCall default logger to stdout initialized
[Wed Aug  3 23:31:44] #131 [ 114 | metacall_initialize | /usr/local/metacall/source/metacall/source/metacall.c ] @Debug : Initializing MetaCall
==131==poisoning: 0x7fb445c00060 1000
[Wed Aug  3 23:31:44] #131 [ 77 | configuration_initialize | /usr/local/metacall/source/configuration/source/configuration.c ] @Debug : Global configuration loaded from /usr/local/metacall/build/configurations/global.json
[Wed Aug  3 23:31:44] #131 [ 44 | plugin_descriptor_create | /usr/local/metacall/source/plugin/source/plugin_descriptor.c ] @Debug : Loading plugin: rapid_json_seriald
==131==poisoning: 0x7fb445d010a0 1000
[Wed Aug  3 23:31:44] #131 [ 57 | plugin_descriptor_create | /usr/local/metacall/source/plugin/source/plugin_descriptor.c ] @Debug : Loading plugin symbol: dynlink_symbol_rapid_json_serial_impl_interface_singleton
[Wed Aug  3 23:31:44] #131 [ 172 | metacall_initialize | /usr/local/metacall/source/metacall/source/metacall.c ] @Information : Set MetaCall log level to Debug
[Wed Aug  3 23:31:44] #131 [ 77 | loader_manager_impl_script_paths_initialize | /usr/local/metacall/source/loader/source/loader_manager_impl.c ] @Debug : Loader script path: /usr/local/metacall/build/scripts/
==131==poisoning: 0x7fb445c06060 1000
[Wed Aug  3 23:31:44] #131 [ 190 | loader_initialization_register_plugin | /usr/local/metacall/source/loader/source/loader.c ] @Debug : Loader __metacall_host__ registered at position (0) in thread #131
[Wed Aug  3 23:31:44] #131 [ 137 | loader_initialize | /usr/local/metacall/source/loader/source/loader.c ] @Debug : Loader host initialized
[Wed Aug  3 23:31:44] #131 [ 44 | plugin_descriptor_create | /usr/local/metacall/source/plugin/source/plugin_descriptor.c ] @Debug : Loading plugin: rs_loaderd
==131==poisoning: 0x7fb445d050a0 1000
[Wed Aug  3 23:31:44] #131 [ 57 | plugin_descriptor_create | /usr/local/metacall/source/plugin/source/plugin_descriptor.c ] @Debug : Loading plugin symbol: dynlink_symbol_rs_loader_impl_interface_singleton
[Wed Aug  3 23:31:44] #131 [ 247 | loader_get_impl_plugin | /usr/local/metacall/source/loader/source/loader.c ] @Debug : Created loader (rs) implementation <0x6070000004f0>
[Wed Aug  3 23:31:44] #131 [ 340 | loader_load_from_package | /usr/local/metacall/source/loader/source/loader.c ] @Debug : Loading package (rs): libbasic.rlib
[Wed Aug  3 23:31:44] #131 [ 190 | loader_initialization_register_plugin | /usr/local/metacall/source/loader/source/loader.c ] @Debug : Loader rs registered at position (1) in thread #131
[Wed Aug  3 23:31:44] #131 [ 153 | loader_initialization_debug | /usr/local/metacall/source/loader/source/loader.c ] @Debug : Loader initialization order:
-----------------------------------
0) __metacall_host__ #131
1) rs #131
==131==T1: FakeStack created: 0x7fb43a54c000 -- 0x7fb43b055000 stack_size_log: 20; mmapped 11300K, noreserve=0 
==131==T1: stack [0x7fb43b056000,0x7fb43b854e80) size 0x7fee80; local=0x7fb43b854d9c
==131==T1 TSDDtor
==131==T1 exited
error[E0786]: found invalid metadata files for crate `metacall_package`
 --> /usr/local/metacall/build/scripts/metacall_wrapped_package.rs:1:1
  |
1 | extern crate metacall_package;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: invalid metadata version found: /usr/local/metacall/build/scripts/libbasic.rlib
error: aborting due to previous error

For more information about this error, try `rustc --explain E0786`.


ErrorReported

error[E0786]: found invalid metadata files for crate `metacall_package`
 --> /usr/local/metacall/build/scripts/metacall_wrapped_package.rs:1:1
  |
1 | extern crate metacall_package;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: invalid metadata version found: /usr/local/metacall/build/scripts/libbasic.rlib

error: aborting due to previous error

For more information about this error, try `rustc --explain E0786`.

[Wed Aug  3 23:31:44] #131 [ 990 | loader_impl_load_from_package | /usr/local/metacall/source/loader/source/loader_impl.c ] @Debug : Loader interface: 0x7fb446b32160 - Loader handle: (nil)
/usr/local/metacall/source/tests/metacall_rust_load_from_package_test/source/metacall_rust_load_from_package_test.cpp:36: Failure
Expected equality of these values:
  (int)0
    Which is: 0
  (int)metacall_load_from_package("rs", rs_script, __null)
    Which is: 1
metacall-rust-load-from-package-testd: /usr/local/metacall/source/metacall/source/metacall_value.c:242: metacall_value_to_int: Assertion `value_type_id(v) == TYPE_INT' failed.

        Start 127: metacall-rust-load-from-package-class-test
  7/164 Test #127: metacall-rust-load-from-package-class-test .......***Failed    0.60 sec
```

@MediosZ


Discussion / hints:
I am into this.

Fix patch:
diff --git a/source/loaders/rs_loader/rust/compiler/src/api/class.rs b/source/loaders/rs_loader/rust/compiler/src/api/class.rs
index f15e79175..9acf5afa0 100644
--- a/source/loaders/rs_loader/rust/compiler/src/api/class.rs
+++ b/source/loaders/rs_loader/rust/compiler/src/api/class.rs
@@ -119,11 +119,11 @@ extern "C" fn class_singleton_static_await(
 
 #[no_mangle]
 extern "C" fn class_singleton_destroy(_klass: OpaqueType, class_impl: OpaqueType) {
-    unsafe {
-        let class_impl_ptr = class_impl as *mut class::Class;
-        let class = Box::from_raw(class_impl_ptr);
-        drop(class);
-    }
+    // unsafe {
+    //     let class_impl_ptr = class_impl as *mut class::Class;
+    //     let class = Box::from_raw(class_impl_ptr);
+    //     drop(class);
+    // }
     println!("class destroy");
 }
 
diff --git a/source/loaders/rs_loader/rust/compiler/src/api/function.rs b/source/loaders/rs_loader/rust/compiler/src/api/function.rs
index b1dbe6f8d..6d8d31d6c 100644
--- a/source/loaders/rs_loader/rust/compiler/src/api/function.rs
+++ b/source/loaders/rs_loader/rust/compiler/src/api/function.rs
@@ -61,10 +61,11 @@ extern "C" fn function_singleton_await(
 
 #[no_mangle]
 extern "C" fn function_singleton_destroy(_func: OpaqueType, func_impl: OpaqueType) {
-    unsafe {
-        let func_ptr = Box::from_raw(func_impl as *mut class::NormalFunction);
-        drop(func_ptr);
-    }
+    // comment out this due to the seg fault
+    // unsafe {
+    //     let func_ptr = Box::from_raw(func_impl as *mut class::NormalFunction);
+    //     drop(func_ptr);
+    // }
 }
 
 #[no_mangle]
diff --git a/source/loaders/rs_loader/rust/compiler/src/api/object.rs b/source/loaders/rs_loader/rust/compiler/src/api/object.rs
index dd4fe9710..6314f8a6c 100644
--- a/source/loaders/rs_loader/rust/compiler/src/api/object.rs
+++ b/source/loaders/rs_loader/rust/compiler/src/api/object.rs
@@ -123,11 +123,11 @@ extern "C" fn object_singleton_method_await(
 }
 #[no_mangle]
 extern "C" fn object_singleton_destructor(_object: OpaqueType, object_impl: OpaqueType) -> c_int {
-    unsafe {
-        let object_impl_ptr = object_impl as *mut Object;
-        let object = Box::from_raw(object_impl_ptr);
-        drop(object);
-    }
+    // unsafe {
+    //     let object_impl_ptr = object_impl as *mut Object;
+    //     let object = Box::from_raw(object_impl_ptr);
+    //     drop(object);
+    // }
     println!("destruct object");
     0
 }
diff --git a/source/loaders/rs_loader/rust/compiler/src/wrapper/class.rs b/source/loaders/rs_loader/rust/compiler/src/wrapper/class.rs
index b3c02109a..32c74cbb4 100644
--- a/source/loaders/rs_loader/rust/compiler/src/wrapper/class.rs
+++ b/source/loaders/rs_loader/rust/compiler/src/wrapper/class.rs
@@ -6,6 +6,7 @@ use std::collections::HashMap;
 use std::ffi::CStr;
 use std::fmt;
 use std::sync::Arc;
+use std::convert::TryInto;
 type Result<T, E = i32> = core::result::Result<T, E>;
 use std::os::raw::{c_char, c_double, c_float, c_int, c_long, c_short, c_void};
 extern "C" {
diff --git a/source/ports/rs_port/CMakeLists.txt b/source/ports/rs_port/CMakeLists.txt
index 84d9ced1e..7ab839b7c 100644
--- a/source/ports/rs_port/CMakeLists.txt
+++ b/source/ports/rs_port/CMakeLists.txt
@@ -47,7 +47,7 @@ add_dependencies(${target}
 #
 
 add_test(NAME ${target}
-	COMMAND ${CMAKE_COMMAND} -E env RUSTFLAGS=-Zmacro-backtrace ${Rust_CARGO_EXECUTABLE} test
+	COMMAND ${CMAKE_COMMAND} -E env CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} CMAKE_BINARY_DIR=${CMAKE_BINARY_DIR} RUSTFLAGS=-Zmacro-backtrace ${Rust_CARGO_EXECUTABLE} test
 	WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
 )
 
diff --git a/source/ports/rs_port/build.rs b/source/ports/rs_port/build.rs
new file mode 100644
index 000000000..9d46b0be1
--- /dev/null
+++ b/source/ports/rs_port/build.rs
@@ -0,0 +1,30 @@
+use std::env;
+fn main() {
+    // when running tests
+    if let Ok(val) = env::var("CMAKE_BINARY_DIR") {
+        println!("cargo:rustc-link-search={val}");
+
+        match env::var("CMAKE_BUILD_TYPE") {
+            Ok(val) => {
+                if val == "Debug" {
+                    // try to link the debug version when running tests
+                    println!("cargo:rustc-link-lib=metacalld");
+                } else {
+                    println!("cargo:rustc-link-lib=metacall");
+                }
+            }
+            Err(_) => {
+                println!("cargo:rustc-link-lib=metacall");
+            }
+        }
+
+        println!("cargo:rustc-env=LD_LIBRARY_PATH={val}");
+        println!("cargo:rustc-env=CONFIGURATION_PATH={val}/configurations/global.json")
+    } else {
+        println!("cargo:rustc-link-lib=metacall");
+    }
+
+    // default install location
+
+    // user defined location
+}
diff --git a/source/ports/rs_port/src/abi.rs b/source/ports/rs_port/src/abi.rs
index 97da47166..c6489ea4c 100644
--- a/source/ports/rs_port/src/abi.rs
+++ b/source/ports/rs_port/src/abi.rs
@@ -2,7 +2,8 @@ pub mod interface {
     use std::os::raw::{c_char, c_double, c_float, c_int, c_long, c_short, c_void};
 
     // requires libmetacall to be in $PATH
-    #[link(name = "metacall")]
+    // we will set it in build.rs
+    // #[link(name = "metacall")]
     extern "C" {
         pub fn metacall_destroy() -> c_int;
         pub fn metacall_initialize() -> c_int;
diff --git a/source/scripts/rust/cmake/RustProject.cmake b/source/scripts/rust/cmake/RustProject.cmake
index 92c259a8f..7aaa4947b 100644
--- a/source/scripts/rust/cmake/RustProject.cmake
+++ b/source/scripts/rust/cmake/RustProject.cmake
@@ -46,7 +46,7 @@ function(rust_project target version)
 	set(PACKAGE_OUTPUT		"${CMAKE_CURRENT_BINARY_DIR}/build/timestamp")
 
 	# Create project file
-    script_project(${target} rust ${RUST_PROJECT_CONFIG_PATH}/RustProject.cmake.in)
+	script_project(${target} rust ${RUST_PROJECT_CONFIG_PATH}/RustProject.cmake.in)
 
 endfunction()
 
@@ -100,6 +100,8 @@ function(rust_package target version script)
 
 	# Compile scripts
 	add_custom_command(TARGET ${custom_target} PRE_BUILD
+		# fix the version of rustc
+		COMMAND ${Rust_RUSTUP_EXECUTABLE} default nightly-2021-12-04
 		COMMAND ${Rust_RUSTC_EXECUTABLE} --crate-type=lib 
 		${CMAKE_CURRENT_SOURCE_DIR}/source/${script}.rs 
 		--out-dir ${LOADER_SCRIPT_PATH}


Test patch: