Objective-C Runtime bindings and wrapper for Rust.

Overview

Objective-C Runtime bindings and wrapper for Rust.

Messaging objects

Objective-C objects can be messaged using the msg_send! macro:

let cls = class!(NSObject);
let obj: *mut Object = msg_send![cls, new];
let hash: usize = msg_send![obj, hash];
let is_kind: BOOL = msg_send![obj, isKindOfClass:cls];
// Even void methods must have their return type annotated
let _: () = msg_send![obj, release];

Reference counting

The utilities of the rc module provide ARC-like semantics for working with Objective-C's reference counted objects in Rust. A StrongPtr retains an object and releases the object when dropped. A WeakPtr will not retain the object, but can be upgraded to a StrongPtr and safely fails if the object has been deallocated.

// StrongPtr will release the object when dropped
let obj = unsafe {
    StrongPtr::new(msg_send![class!(NSObject), new])
};

// Cloning retains the object an additional time
let cloned = obj.clone();
autoreleasepool(|| {
    // Autorelease consumes the StrongPtr, but won't
    // actually release until the end of an autoreleasepool
    cloned.autorelease();
});

// Weak references won't retain the object
let weak = obj.weak();
drop(obj);
assert!(weak.load().is_null());

Declaring classes

Classes can be declared using the ClassDecl struct. Instance variables and methods can then be added before the class is ultimately registered.

The following example demonstrates declaring a class named MyNumber that has one ivar, a u32 named _number and a number method that returns it:

let superclass = class!(NSObject);
let mut decl = ClassDecl::new("MyNumber", superclass).unwrap();

// Add an instance variable
decl.add_ivar::<u32>("_number");

// Add an ObjC method for getting the number
extern fn my_number_get(this: &Object, _cmd: Sel) -> u32 {
    unsafe { *this.get_ivar("_number") }
}
unsafe {
    decl.add_method(sel!(number),
        my_number_get as extern fn(&Object, Sel) -> u32);
}

decl.register();

Exceptions

By default, if the msg_send! macro causes an exception to be thrown, this will unwind into Rust resulting in unsafe, undefined behavior. However, this crate has an "exception" feature which, when enabled, wraps each msg_send! in a @try/@catch and panics if an exception is caught, preventing Objective-C from unwinding into Rust.

Message type verification

The Objective-C runtime includes encodings for each method that describe the argument and return types. This crate can take advantage of these encodings to verify that the types used in Rust match the types encoded for the method.

To use this functionality, enable the "verify_message" feature. With this feature enabled, type checking is performed for every message send, which also requires that all arguments and return values for all messages implement Encode.

If this requirement is burdensome or you'd rather just verify specific messages, you can call the Message::verify_message method for specific selectors.

Support for other Operating Systems

The bindings can be used on Linux or *BSD utilizing the GNUstep Objective-C runtime.

Comments
  • Add support for the GNUstep Objective-C runtime

    Add support for the GNUstep Objective-C runtime

    Hi!

    I've fiddled with a few things and gotten the bindings to work with the GNUstep Objective-C runtime, so that they can also be used for interop between Rust and Objective-C code on non-Apple platforms. It's controlled by a new feature called gnustep_runtime,

    This mainly involved adding support for the slightly different message sending mechanism. Also getting the tests back into working order proved a bit difficult because if you're not on Mac OS or iOS you usually don't have NSObject available unless you link a Foundation implementation. I've made it so that the bindings will build without one, but the tests will need to link the GNUstep base library (Foundation equivalent) in order to run.

    There's also an outstanding bug in the runtime that I found thanks to the unit tests in rust-objc ;-)

    Also, I've tested on Mac OS for regressions and things should continue to work there as expected.

    opened by ngrewe 16
  • Cache selectors so we don't call `sel_registerName` over and over.

    Cache selectors so we don't call `sel_registerName` over and over.

    Improves #49.

    This is what the assembly looks like. The fast path is only 4 instructions.

    	lea    r15, [rip + 0xbf936]      ; cocoa::foundation::NSString::alloc::register_sel::SEL::h005daf5ee04d2745
    	mov    rbx, qword ptr [r15]
    	test   rbx, rbx
    	jne    ok
    	lea    rdi, [rip + 0x95b2c]      ; byte_str.o.llvm.2369336028792347561
    	call   0x10008fa02               ; symbol stub for: sel_registerName
    	mov    rbx, rax
    	mov    qword ptr [r15], rbx
    ok:
    

    cc @jrmuizel, @kvark, @mystor

    opened by pcwalton 12
  • How do you not cause memory leaks?

    How do you not cause memory leaks?

    I'm using the objc crate to get the icon/image of a macos .app file.

    But my following snippet leaks memory. I am fairly certain it is this snippet because if I replace the snippet with a String of b64 of the same image, no memory leak occurs.

    Does this snippet use the objc crate in a wrong way? I suspect I'm not seeing something obvious in the docs. How can I prevent this snippet from causing memory leaks?

    fn get_icon_for_app_file(path: &str) -> String {
      // Get a class
      let ns_workspace_class = objc::class!(NSWorkspace); // NSObject
      // Allocate an instance
      let ns_workspace_obj = unsafe {
          let obj: *mut Object = objc::msg_send![ns_workspace_class, alloc];
          let obj: *mut Object = objc::msg_send![obj, init];
          StrongPtr::new(obj)
      };
      let path = unsafe { NSString::alloc(nil).init_str(path) };
    
      let ns_image: Id<Object> = unsafe {
          let img = msg_send!(*ns_workspace_obj, iconForFile:path);
          img
      };
      // let _: () = unsafe { msg_send![*ns_workspace_obj, release] };
      // drop(ns_workspace_obj);
    
      let foundation_ns_data: Id<Object> = unsafe {
          msg_send!(ns_image, TIFFRepresentationUsingCompression:6 factor:90)
      };
    
      let ns_bitmap_image_rep: Id<Object> = unsafe {
          msg_send!(class!(NSBitmapImageRep), imageRepWithData: ns_data)
      };
    
      let foundation_data: Id<Object> = unsafe {
          msg_send!(ns_bitmap_image_rep, representationUsingType:3 properties:nil)
      };
    
      let b64 = unsafe {
          msg_send!(data, base64EncodedStringWithOptions:nil)
      };
    
      let c_buf: *const c_char = unsafe {
          // GITHUB COMMENT EDIT: renamed from about_item_prefix
          let init_string = NSString::alloc(nil).init_str("");
          // GITHUB COMMENT EDIT: renamed from about_item_title
          let b64_string = init_string.stringByAppendingString_(b64);
          let c_pointer: *const libc::c_char = b64_string.UTF8String();
          c_pointer
      };
    
      let c_str: &CStr = unsafe { CStr::from_ptr(c_buf) };
      let str_slice: &str = c_str.to_str().unwrap();
    
      let mut img = String::from("data:image/jpeg;base64,");
      img.push_str(str_slice);
    
      println!("Final image data is: {}", img);
      Ok(img)
    }
    

    I've tried using various expressions of let _: () = unsafe { msg_send![some_object, release] }; to release memory, but I get segmentation faults and rarely bus faults (for context this snippet is run in multithreaded env, perhaps contributing). Should the snippet be using release, and wrapping this snippet in something like a mutex so it can only be run by 1 thread at a time?

    opened by selfconfigio 6
  • Is the underlying BOOL type a bool on Apple silicon

    Is the underlying BOOL type a bool on Apple silicon

    I was confused about this library's definition of BOOL until finding this comment on SO, which explains that BOOL is a C signed char on Darwin and a C bool on iOS. I think we need to also check the target_os to distinguish between aarch64-apple-darwin and aarch64-apple-ios, because I'm seeing odd errors when compiling bluster https://github.com/dfrankland/bluster/issues/44 on my M1 laptop.

    I will submit a patch if it ends up working.

    opened by schell 6
  • msg_send! still compiles when the return type cannot be inferred (relying on behavior that will change in future versions of Rust)

    msg_send! still compiles when the return type cannot be inferred (relying on behavior that will change in future versions of Rust)

    This is probably not a bug that needs to be fixed in rust-objc, but a warning to developers since it causes runtime crashes with unclear errors.

    Previously, both of these worked, assuming setThing: returned void:

    let _ = msg_send![obj, setThing: 1];
    msg_send![obj, setThing: 0];
    

    They worked because Rust inferred unknown types as (). As of recent Rust nightly builds, unknown types are inferred as a new '!' type (see: https://github.com/rust-lang/rust/issues/48950).

    Unfortunately, Rust will build it and the crashes occur at runtime. Depending on which features you have compiled rust-objc with, you either get a panic at the calling line, a panic in objc_exception, or a segfault.

    The error messages are entirely unhelpful unless you build rust-objc with the verify_message feature, which catches it at compile-time.

    Fix by forcing the type back to ():

    let _: () = msg_send![obj, setThing: 1];
    
    opened by mrmekon 5
  • Add protocols

    Add protocols

    Adds protocol support to rust-objc. This request adds the Protocol and ProtocolDecl structs, and lets you build Protocols, as well as query them. It also adds a test for protocol conformance to the Class struct.

    opened by burtonageo 5
  • Encode is not implemented for *mut libc::c_void anymore

    Encode is not implemented for *mut libc::c_void anymore

    https://github.com/SSheldon/rust-objc/commit/dee2e48594bb271d93f006db59929f23c35d0e87#diff-00e732ca6ab3c3211cacd023da8d7b48L4 is not on crates.io yet, but I think it’s breaking for dependents like glutin who rely on the Encode trait being implemented for libc types. That’s OK for c_char which is just a type alias of u8 or i8, but not for c_void which is unfortunately a different type in std::os::raw and libc: rust-lang-nursery/libc#71

    I’d recommend bringing back the libc dependency (unfortunate, but the alternative will be a pain) and implementing the trait for both c_void types.

    opened by SimonSapin 5
  • to_owned should be used in favor of to_string

    to_owned should be used in favor of to_string

    Hi, this PR stumbles upon a small nit I covered while seeking some code in cocoa-rs and servo.

    It fixes the to_string calls for to_owned. It is much lighter in resources.

    To_string as uses the whole formatting machinery just to clone a string.

    Thanks for looking into it !

    opened by ddrmanxbxfr 5
  • How do I call a class function?

    How do I call a class function?

    I'm trying to call NSFont.boldSystemFont, but I can't figure out how. This doesn't work (size is a *mut NSObject):

    let font: *mut Object = msg_send![class!(NSFont), boldSystemFont:size];
    

    Or this:

    let font: *mut Object = msg_send![class!(NSFont), boldSystemFont(size)];
    

    Or this:

    let font: *mut Object = msg_send![class!(NSFont), boldSystemFont, ofSize:size];
    

    Or this:

    let font: *mut Object = msg_send![class!(NSFont), boldSystemFont:, ofSize:size];
    

    Or this:

    let font: *mut Object = msg_send![class!(NSFont), boldSystemFont:ofSize:size];
    

    Or this:

    let font: *mut Object = msg_send![class!(NSFont), ofSize:size];
    

    Or this:

    let nsfont = class!(NSFont);
    let method = nsfont.instance_method(sel!(boldSystemFont)).unwrap();
    let font: *mut Object = msg_send![method, ofSize:size];
    

    Or this:

    let method = sel!(NSFont.boldSystemFont);
    let font: *mut Object = msg_send![method, ofSize:size];
    

    Or this:

    let class = class!(NSFont);
    let method = sel!(boldSystemFont:);
    let font: *mut Object = class.send_message(method, size).unwrap();
    

    I feel like I've tried everything, but this is just so basic that objc MUST have functionality for it somewhere... right?

    Please help me, I've spent way too much time trying to figure this out... That's not even everything I tried, but I don't want to make this issue any longer!

    opened by LoganDark 4
  • iOS ClassDecl panic - Should I do something before a ClassDecl?

    iOS ClassDecl panic - Should I do something before a ClassDecl?

    Hey hi!

    I'm trying to do something simple, just declaring my AppDelegate like this lib.rs:

    use objc::declare::ClassDecl;
    use objc::runtime::{BOOL, Object, Sel, YES, NO};
    
    type Obj = *mut Object;
    
    extern "C" fn did_finish_launching_with_options(_: &mut Object, _: Sel, _: Obj, _: Obj) -> BOOL {
        println!("DID FINISH LAUNCHING");
        YES
    }
    
    pub fn start() {
        println!("START - HELLO FROM LIB?");
    
    
        let ui_responder_cls = class!(UIResponder);
        let mut app_delegate_cls = ClassDecl::new("AppDelegate", ui_responder_cls)
            .expect("Failed to declare AppDelegate");
    
        unsafe {
            app_delegate_cls.add_method(
                sel!(application:didFinishLaunchingWithOptions:),
                did_finish_launching_with_options as extern "C" fn(&mut Object, Sel, Obj, Obj) -> BOOL,
            );
    
            app_delegate_cls.register();
        }
    }
    
    #[no_mangle]
    pub extern "C" fn start_app() {
        start();
    }
    

    And it's used on xcode as this main.m:

    #import "ffi.h"
    
    int main(int argc, char * argv[]) {
            start_app();
            return 0;
    }
    

    But always got a panic when I do the expect, is an Option so I don't have an error to read and to know what was wrong. I checked the examples, and reduced the examples to the minimum, using NSObject and extending it instead of using UIResponder, and it's the same result.

    Am I missing something? (Testing on simulator).

    Thanks!

    opened by Nazariglez 3
  • Use 'AtomicUsize::new' instead of 'ATOMIC_USIZE_INIT' (stable as of 1.24.0 on 2018-02-15)

    Use 'AtomicUsize::new' instead of 'ATOMIC_USIZE_INIT' (stable as of 1.24.0 on 2018-02-15)

    Primary reason is I get dozens of

    warning: using `ATOMIC_USIZE_INIT`
      --> filename:66:13
       |
    66 |             msg_send![ ... ];
       |             ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `AtomicUsize::new(0)`
       |
    

    with clippy in pedantic mode.

    opened by mehcode 3
  • increase number of MessageArguments impl tuples

    increase number of MessageArguments impl tuples

    because there are 16-argument method in Apple library

    https://developer.apple.com/documentation/metalperformanceshaders/mpssvgf/3143562-encodereprojectiontocommandbuffe

    opened by youknowone 0
  • How to link struct from framework?

    How to link struct from framework?

    I'm currently attempting to call the controllers functions as seen here in order to get a list of connected controllers on mac. I'm attempting to achieve this with the following code:

    use objc::{class, msg_send, sel, sel_impl};
    use objc::runtime::{BOOL, Object};
    
    fn main() {
        unsafe {
            let class = class!(GCController);
            let selector = sel!(controllers);
            let obj: *mut Object = msg_send![class, new];
    
            let _: *mut Object = msg_send![class, selector];
    
            // Even void methods must have their return type annotated
            let _: () = msg_send![obj, release];
        }
    }
    

    However, it fails as follows:

    thread 'main' panicked at 'Class with name GCController could not be found', src/main.rs:6:21
    stack backtrace:
       0: rust_begin_unwind
                 at /rustc/2f3ddd9f594adf9773547aa7cedb43c4ac8ffd2f/library/std/src/panicking.rs:584:5
       1: core::panicking::panic_fmt
                 at /rustc/2f3ddd9f594adf9773547aa7cedb43c4ac8ffd2f/library/core/src/panicking.rs:142:14
       2: objc_test::main
                 at ./src/main.rs:6:21
       3: core::ops::function::FnOnce::call_once
                 at /rustc/2f3ddd9f594adf9773547aa7cedb43c4ac8ffd2f/library/core/src/ops/function.rs:248:5
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    

    How do I link against the Controllers framework to get this to work? Also, any advice for calling functions would be incredibly appreciated.

    opened by KSBilodeau 1
  • How to import and use constants

    How to import and use constants

    I'm modifying a library that uses objc. I need to import a constant NSString. I tried const* NSString and Id<NSString> but rustc warned me that these are not "FFI safe". This, however, appears to work:

    // required to bring NSPasteboard into the path of the class-resolver
    #[link(name = "AppKit", kind = "framework")]
    extern "C" {
        // NSString
        static NSPasteboardURLReadingFileURLsOnlyKey: &'static Object;
    }
    

    Here is the usage:

    let ns_dict = class!(NSDictionary);
    let ns_number = class!(NSNumber);
    
    let options: Id<NSDictionary<NSObject, NSObject>> = unsafe {
        let obj: Id<NSObject> = msg_send![ns_number, numberWithBool: objc::runtime::YES];
        msg_send![ns_dict, dictionaryWithObject:obj forKey: NSPasteboardURLReadingFileURLsOnlyKey]
    };
    

    Is this correct, safe and idiomatic?

    opened by betamos 5
  • Soundness issue with `msg_send!`

    Soundness issue with `msg_send!`

    So, during my work on objc2 I decided to test some things in Miri, to try to get a feel for how sound everything is, and found this issue (which is currently present in both crates).

    Below is a piece of code that tries to mutate an ivar on an object, resembling fairly closely something that is quite commonly done in winit. Try placing it under objc/examples/msg_send_unsound.rs, and running cargo miri run --example msg_send_unsound.

    #[macro_use]
    extern crate objc; // v0.2.7
    
    use objc::runtime::{Object, Sel};
    
    // Assume this is registered to the object with `ClassDecl::add_method`
    extern "C" fn my_selector(obj: *mut Object, _sel: Sel) {
        let obj = unsafe { &mut *obj };
        let a = unsafe { obj.get_mut_ivar::<i32>("a") };
        *a += 1;
    }
    
    fn main() {
        let ptr: *mut Object = new_object(42); // ivar a = 42
        let obj: &mut Object = unsafe { &mut *ptr };
    
        // Get an immutable reference to the instance variable
        let a = unsafe { obj.get_ivar::<i32>("a") };
    
        unsafe {
            // Uses `obj` mutably, but the signature says it's used immutably
            let _: () = msg_send![obj, my_selector];
        }
    
        // So the compiler can't catch that we're not allowed to access `a` here!
        assert_eq!(*a, 43);
    
        free_object(ptr);
    }
    
    // ------------------------------------
    //
    // HACKY STUBS BELOW TO MAKE MIRI WORK!
    //
    // ------------------------------------
    
    use std::ffi::CStr;
    use std::os::raw::c_char;
    use std::ptr;
    
    use objc::runtime::{Class, Ivar};
    
    #[repr(C)]
    struct MyObject {
        isa: *const Class,
        a: i32,
    }
    
    fn new_object(a: i32) -> *mut Object {
        let obj = Box::new(MyObject {
            isa: ptr::null(),
            a,
        });
        Box::into_raw(obj) as *mut Object
    }
    
    fn free_object(obj: *mut Object) {
        unsafe { Box::from_raw(obj as *mut MyObject) };
    }
    
    #[no_mangle]
    extern "C" fn sel_registerName(name: *const c_char) -> Sel {
        unsafe { Sel::from_ptr(name.cast()) }
    }
    
    #[no_mangle]
    extern "C" fn objc_msgSend(obj: *mut Object, sel: Sel) {
        my_selector(obj, sel)
    }
    
    #[no_mangle]
    extern "C" fn object_getClass(obj: *const Object) -> *const Class {
        // Must be a valid pointer, so don't return isa
        obj.cast()
    }
    
    #[no_mangle]
    extern "C" fn class_getInstanceVariable(cls: *const Class, _name: *const c_char) -> *const Ivar {
        cls.cast()
    }
    
    #[no_mangle]
    extern "C" fn ivar_getTypeEncoding(_ivar: *const Ivar) -> *const c_char {
        CStr::from_bytes_with_nul(b"i\0").unwrap().as_ptr()
    }
    
    #[no_mangle]
    extern "C" fn ivar_getOffset(_ivar: *const Ivar) -> isize {
        // isa is 64 bits
        8
    }
    

    You should see the following miri error, which makes sense as explained in the code comments:

    error: Undefined Behavior: trying to reborrow <6300> for SharedReadOnly permission at alloc1621[0x8], but that tag does not exist in the borrow stack for this location
       --> examples/msg_send_unsound.rs:26:5
        |
    26  |     assert_eq!(*a, 43);
        |     ^^^^^^^^^^^^^^^^^^
        |     |
        |     trying to reborrow <6300> for SharedReadOnly permission at alloc1621[0x8], but that tag does not exist in the borrow stack for this location
        |     this error occurs as part of a reborrow at alloc1621[0x8..0xc]
        |
        = help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
        = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
    help: <6300> was created by a retag at offsets [0x8..0xc]
       --> examples/msg_send_unsound.rs:18:22
        |
    18  |     let a = unsafe { obj.get_ivar::<i32>("a") };
        |                      ^^^^^^^^^^^^^^^^^^^^^^^^
    help: <6300> was later invalidated at offsets [0x8..0xc]
       --> src/runtime.rs:510:9
        |
    510 |         &mut *ptr
        |         ^^^^^^^^^
        = note: inside `main` at $TOOLCHAIN/lib/rustlib/src/rust/library/core/src/macros/mod.rs:38:16
        = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
    
    A bit more info

    The problem is that you have to somehow specify that the object is mutated by the message send, which you can't really do properly.

    Just to illustrate that this is indeed an issue with how msg_send! works, try applying the following quick patch which changes msg_send! to always require mutable objects (obviously not a real fix):

    diff --git a/src/macros.rs b/src/macros.rs
    --- a/src/macros.rs
    +++ b/src/macros.rs
    @@ -130,7 +130,7 @@ macro_rules! msg_send {
         ($obj:expr, $name:ident) => ({
             let sel = sel!($name);
             let result;
    -        match $crate::__send_message(&*$obj, sel, ()) {
    +        match $crate::__send_message(&mut *$obj, sel, ()) {
                 Err(s) => panic!("{}", s),
                 Ok(r) => result = r,
             }
    @@ -139,7 +139,7 @@ macro_rules! msg_send {
         ($obj:expr, $($name:ident : $arg:expr)+) => ({
             let sel = sel!($($name:)+);
             let result;
    -        match $crate::__send_message(&*$obj, sel, ($($arg,)*)) {
    +        match $crate::__send_message(&mut *$obj, sel, ($($arg,)*)) {
                 Err(s) => panic!("{}", s),
                 Ok(r) => result = r,
             }
    

    Then you'll get the expected rustc error:

    error[E0502]: cannot borrow `*obj` as mutable because it is also borrowed as immutable
      --> examples/msg_send_unsound.rs:22:21
       |
    18 |     let a = unsafe { obj.get_ivar::<i32>("a") };
       |                      ------------------------ immutable borrow occurs here
    ...
    22 |         let _: () = msg_send![obj, my_selector];
       |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
    ...
    26 |     assert_eq!(*a, 43);
       |     ------------------ immutable borrow later used here
       |
       = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)
    

    This is similar to the problem with nulls I noted in https://github.com/SSheldon/rust-objc/pull/102, and probably requires some kind of change in msg_send!, though I don't actually know how to do this yet (suggestions appreciated).

    opened by madsmtm 3
  • Strange conflict between NSProcessInfo and NSScreen, causing segmentation fault.

    Strange conflict between NSProcessInfo and NSScreen, causing segmentation fault.

    I found a strange conflict issue between NSScreen and NSProcessInfo. Using both NSProcessInfo.operatingSystemVersion and UIScreen.mainScreen will cause the application to crash with "segmentation fault". But I can't imagine the relation between them.

    Minimal Example:

    #[macro_use]
    extern crate objc;
    
    use cocoa::{appkit::NSScreen, base::nil};
    use objc::{runtime::Object};
    
    fn main() {
        unsafe {
            let ns_process_info = class!(NSProcessInfo);
            let process_info: *mut Object = msg_send![ns_process_info, processInfo];
            // Deleting either of the following two lines will avoid the crash.
            let os_version: *const Object = msg_send![process_info, operatingSystemVersion];
            let screen = NSScreen::mainScreen(nil);
        }
    }
    
    [package]
    name = "rsplg"
    version = "0.1.0"
    edition = "2018"
    
    [dependencies]
    cocoa = "0.24"
    objc = "0.2.7"
    objc-foundation = "0.1"
    
    opened by wspl 1
Javascript wrapper bindings for diamond types

Diamond JS wrapper library This is a javascript / WASM wrapper around diamond types. This code is currently experimental WIP. Do not trust this for an

Seph Gentle 14 Jun 16, 2022
A JavaScript Runtime built with Mozilla's SpiderMonkey Engine and Rust

Spiderfire Spiderfire is a javascript runtime built with Mozilla's SpiderMonkey engine and Rust. Spiderfire aims to disrupt the server-side javascript

Redfire 122 Dec 15, 2022
Modern JavaScript runtime for Sony PSP, based on rust-psp and QuickJS.

PSP.js Modern JavaScript runtime for Sony PSP, based on rust-psp and QuickJS. ⚠️ Currently in PoC state, unusable for developing JavaScript apps yet.

Yifeng Wang 15 Nov 28, 2022
Livny is a modern JavaScript and TypeScript runtime built on top of Rust

Livny is a modern JavaScript and TypeScript runtime built on top of Rust, Golang and the GraalVM Polyglot infrastructure that can run all of Deno and Node.jS applications. It is fine-tuned for user satisfaction, performance and security.

LivnyJS 1 Mar 2, 2022
The JavaScript runtime that aims for productivity and ease

Byte Byte is a easy and productive runtime for Javascript . It makes making complex programs simple and easy-to-scale with its large and fast Rust API

Byte 32 Jun 16, 2021
Diamond is a minimalistic, powerful, and modern Javascript runtime that uses Deno_Core.

Diamond Diamond is a minimalistic, powerful, and modern Javascript runtime that uses Deno_Core. Installation Diamond is currently in beta(not even Alp

Catermelon 4 Aug 30, 2021
Minimal framework to inject the .NET Runtime into a process in Rust

錆の核 sabinokaku Minimal framework to inject the .NET Runtime into a process. Supports Windows and Linux. macOS support is complicated due to SIP, and w

Snowflake Emulator Frontend 8 Mar 6, 2022
A Lean Secure Runtime for JavaScript

Tera tera is a lean secure capability-based runtime for JavaScript. It is primarily designed for multi-tenant serverless environment but has uses in o

Gigamono 7 Oct 7, 2022
Zinnia is a runtime for Filecoin Station modules. It provides a sandboxed environment to execute untrusted code on consumer-grade computers.

?? Zinnia Zinnia is a runtime for Filecoin Station modules. It provides a sandboxed environment to execute untrusted code on consumer-grade computers.

Filecoin Station 5 Jan 25, 2023
An serverless framework based on wasm runtime.

wasm_serverless An distributed serverless framework based on wasm runtime. Feishu doc https://fvd360f8oos.feishu.cn/docx/XSxcdONk2oVJD5xtZuicxftqn3f?f

null 3 Nov 23, 2023
Zero-cost high-level lua 5.3 wrapper for Rust

td_rlua This library is a high-level binding for Lua 5.3. You don't have access to the Lua stack, all you can do is read/write variables (including ca

null 47 May 4, 2022
libnotcurses-sys is a low-level Rust wrapper for the notcurses C library

libnotcurses-sys is a low-level Rust wrapper for the notcurses C library This library is built with several layers of zero-overhead abstractions over

nick black 29 Nov 26, 2022
Unstable wrapper API for winapi's Console Functions

maulingmonkey-console-winapi-wrappers Unstable wrapper API for winapi's Console Functions Quickstart # Cargo.toml [dependencies] maulingmonkey-console

null 3 Nov 26, 2021
Inkwell - It's a New Kind of Wrapper for Exposing LLVM (Safely)

Inkwell(s) It's a New Kind of Wrapper for Exposing LLVM (Safely) Inkwell aims to help you pen your own programming languages by safely wrapping llvm-s

Daniel Kolsoi 1.5k Dec 31, 2022
Automatically generates Rust FFI bindings to C (and some C++) libraries.

bindgen bindgen automatically generates Rust FFI bindings to C (and some C++) libraries. For example, given the C header doggo.h: typedef struct Doggo

The Rust Programming Language 3.2k Jan 4, 2023
Rust bindings for writing safe and fast native Node.js modules.

Rust bindings for writing safe and fast native Node.js modules. Getting started Once you have the platform dependencies installed, getting started is

The Neon Project 7k Jan 4, 2023
WASM bindings for React - enables you to write and use React components in Rust

This library enables you to write and use React components in Rust, which then can be exported to JS to be reused or rendered.

Yichuan Shen 55 Dec 24, 2022
Rust based WASM/JS bindings for ur-rust

ur-wasm-js WASM/JS bindings for the ur-rust rust library Getting started Installation Either build the library yourself with wasm-pack or install for

Lightning Digital Entertainment 5 Feb 28, 2024
A project for generating C bindings from Rust code

cbindgen   Read the full user docs here! cbindgen creates C/C++11 headers for Rust libraries which expose a public C API. While you could do this by h

Ryan Hunt 1.7k Jan 3, 2023