High-level Rust bindings to Perl XS API

Overview

Build Status

Perl XS for Rust

High-level Rust bindings to Perl XS API.

Example

xs! {
  package Array::Sum;
  sub sum_array(ctx, array: AV) {
    array.iter().map(|it| it.unwrap_or(0.0)).sum::<NV>()
  }
}

For a more complete example see the XSTest package in the t/ directory.

Goals

  • safety
  • correctness
  • speed

Perl XS API is deliberately low-level and requires user to maintain a good deal of internal invariants, thus allowing for very fast code. This package takes a different approach of encapsulating implementation details to provide a simpler and safer API at the cost of speed.

For now, this library focuses on Perl's public documented API, which is a small subset of what is available to authors of modules written in C.

Work in progress

This project is very much in progress. It is not yet clear if project goals are attainable at all or if the API will make any sense in practice.

How to use

Module::Install::Rust integrates traditional Perl build system with Cargo, allowing Rust code to be compiled and installed using familiar perl Makefile.PL && make process. For example, see test package under t directory.

Prerequisites

  • Perl 5.20+ (for 64-bit array methods)
  • Rust 1.31+

Testing

To install packages required for testing and benchmarking:

cpanm --installdeps .

To run tests:

(cd t && perl Makefile.PL && make test)
Comments
  • perlxs function macro, subcrate refactor

    perlxs function macro, subcrate refactor

    • Implement perlxs function macro - allows for additional flexibility in argument unpacking, and more idiomatic function authoring
    • Reorganize subcrates to be more tidy
    • Update test cases to use new perlxs function macro

    This PR replaces #21

    Known issue: If arguments are unpacked, AND context object is desired, the &mut Context must be the final argument of the subroutine, otherwise it will experience a double mutable borrow. Does the context object need to be mutable, or does it utilize interior mutability?

    opened by dnorman 6
  • First pass of FromPerlKV derive

    First pass of FromPerlKV derive

    First swing at FromPerlKV derive. Tests passing: https://travis-ci.org/dnorman/perl-xs/builds/301790192

    I'm pretty inexperienced with proc_macros, so I'm sure there's lots of ways this can be improved. Additionally, I couldn't figure out how to each over HV contents, so hashrefs are currently unhandled.

    Option on the struct is handled differently versus T. The end goal here is to loosely reproduce the behavior of a moose constructor. Feedback and improvements greatly welcomed.

    #[derive(FromPerlKV)]
    struct Test {
        foo: Option<String>,
        bar: String,
        #[perlxs(key = "-meow")]
        meow: bool
    };
    
    xs! {
        package Test;
    
        sub new(ctx, class: String) {
            println!("new {:?}", class);
            let test = Test::from_perl_kv(&mut ctx, 1); # offset to avoid $_[0]
        }
    }
    
    ...
    Test->new( bar => "Something", -meow => 1 ) #does not error for missing foo
    
    opened by dnorman 6
  • Subcrate cleanups

    Subcrate cleanups

    • Reorganize existing subcrates in the style of the wasm_bindgen subcrate layout (which seems to be the new hotness) in preparation for the introduction of additional subcrates for #[perlxs] function attribute macro.

    • Relicense subcrates to match current best-practice: dual-license MIT/Apache-2.0

    • update main perl-xs crate to export macros without having to directly use the subcrate

    ^_^

    opened by dnorman 4
  • Added travisci config and build status badge. Some minor tweaks to dep management

    Added travisci config and build status badge. Some minor tweaks to dep management

    Added travisci config and build status badge. In theory all of the environment setup is working for each combination of perl and rust version.

    The build still not succeeding at this time, but at least it's failing with the same error under travis (debian) now as it is on my local OSX machine. This implies that there is some bug, or setup step/dependency which I did not understand.

    See here for details: https://travis-ci.org/dnorman/perl-xs/jobs/282089474#L517

    opened by dnorman 3
  • Test perl versions 5.24 and 5.26

    Test perl versions 5.24 and 5.26

    Debian stretch ships with perl version 5.24, and would be helpful to include it (plus 5.26 for giggles) in the CI testing. Does this seem reasonable? I don't see any need to restore testing for 5.*-shrplib, but these would be helpful :)

    opened by dnorman 1
  • Add a Gitter chat badge to README.md

    Add a Gitter chat badge to README.md

    vickenty/perl-xs now has a Chat Room on Gitter

    @vickenty has just created a chat room. You can visit it here: https://gitter.im/vickenty/perl-xs.

    This pull-request adds this badge to your README.md:

    Gitter

    If my aim is a little off, please let me know.

    Happy chatting.

    PS: Click here if you would prefer not to receive automatic pull-requests from Gitter in future.

    opened by gitter-badger 1
  • Fix compilation bug

    Fix compilation bug

    perlxs_derive included dependency on perl_xs, which, on later versions of rustc caused the compiled proc macro library to require perl's symbols. Since the proc macro is loaded by the rustc and not perl, these symbols could not be resolved and compilation failed.

    Fix the problem by removing the unnecessary import.

    opened by vickenty 0
  • Avoid panic messages when perl croaks

    Avoid panic messages when perl croaks

    Rust programs will print a message to standard output every time a panic happens in a program. We use panics to propagate perl croaks through rust part of the stack - this is internal detail and the messages produced are not useful to the user. These messages can be disabled by installing a custom panic handler.

    Should it be installed globally from a module bootstrap routine, or locally every time a sub is called?

    opened by vickenty 0
  • Procedural function attribute macro, Optional argument handling

    Procedural function attribute macro, Optional argument handling

    Objectives:

    1. Export functions to perl which contain optional arguments.
    2. Make argument handling more magical
    3. Move toward more idiomatic rust conventions for function binding

    At present, the xs! macro is unable to handle Option arguments which may be omitted by the perl caller.

    I propose that we do away with the xs! macro_rules in favor of a procedural function attribute macro, similar to wasm_bindgen or the pyo3 crate.

    Proposed syntax:

    //lib.rs:
    mod bar;
    mod blah;
    perl_base_module!("Foo")
    
    //bar.rs
    #[perl]
    fn alpha (maybe: Option<Something>){}
    
    //blah.rs
    #[perl]
    fn beta (definitely: Something){}
    

    By doing this as a procedural macro, this will also improve the ability to perform smarter argument handling / coercion, including derive structs, optional context argument, etc.

    The goal here is to have a perfectly ordinary rust function be callable from within perl with little or no special accommodation for the perl guts, at least in some circumstances.

    opened by dnorman 4
  • Calling Perl from Rust

    Calling Perl from Rust

    There are four functions to call into Perl in XS, of which only one is currently supported.

    • [ ] I32 call_sv(SV* sv, I32 flags);
    • [x] I32 call_pv(char *subname, I32 flags);
    • [ ] I32 call_method(char *methname, I32 flags);
    • [ ] I32 call_argv(char *subname, I32 flags, char **argv);

    What would be the best way to represent different combinations of flags? Some of them are mutually exclusive, others depend on other flags.

    A further improvement can be a macro that hides different ways to call a sub, and handles argument passing, something like:

    call!(ctx, sub_sv, a, b, c);
    call!(ctx, "Foo::name", a, b, c);
    call!(ctx, sv->"name", a, b, c);
    call!(ctx, sv->method_sv, a, b, c);
    
    opened by vickenty 0
  • Custom objects

    Custom objects

    Allow blessing Rust values into Perl objects.

    Allocate struct on the heap. Construct a SV with a pointer. Register destructor in the SV's magic table.

    opened by vickenty 0
  • Borrowing PV from a unique SV

    Borrowing PV from a unique SV

    It might be possible to safely borrow string buffer of an SV if it is uniquely owned - reference count is 1 and there are no weak references. At least newly created SVs should allow this.

    opened by vickenty 0
Owner
Vickenty Fesunov
Vickenty Fesunov
High-level memory-safe binding generator for Flutter/Dart <-> Rust

flutter_rust_bridge: High-level memory-safe binding generator for Flutter/Dart <-> Rust Want to combine the best between Flutter, a cross-platform hot

fzyzcjy 2.1k Dec 31, 2022
Facilitating high-level interactions between Wasm modules and JavaScript

wasm-bindgen Facilitating high-level interactions between Wasm modules and JavaScript. Guide | API Docs | Contributing | Chat Built with ?? ?? by The

Rust and WebAssembly 5.9k Jan 8, 2023
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
Tyrade: a pure functional language for type-level programming in Rust

A pure functional language for type-level programming in Rust

Will Crichton 286 Jan 1, 2023
Low level tooling for WebAssembly in JavaScript using wasm-tools

js-wasm-tools js-wasm-tools compiles some of the API of wasm-tools to JavaScript and WebAssembly via wasm-bindgen. This offers low level tooling for W

Dominic Elm 59 Dec 19, 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
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-JDBC bindings

jdbc A Rust library that allows you to use JDBC and JDBC drivers. Usage First, add the following to your Cargo.toml: [dependencies] jdbc = "0.1" Next,

Aurora 18 Feb 9, 2022
Lua 5.3 bindings for Rust

rust-lua53 Aims to be complete Rust bindings for Lua 5.3 and beyond. Currently, master is tracking Lua 5.3.3. Requires a Unix-like environment. On Win

J.C. Moyer 150 Dec 14, 2022
Safe Rust bindings to Lua 5.1

rust-lua Copyright 2014 Lily Ballard Description This is a set of Rust bindings to Lua 5.1. The goal is to provide a (relatively) safe interface to Lu

Lily Ballard 124 Jan 5, 2023
mruby safe bindings for Rust

mrusty. mruby safe bindings for Rust mrusty lets you: run Ruby 1.9 files with a very restricted API (without having to install Ruby) reflect Rust stru

Anima 200 Oct 12, 2022
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
Objective-C Runtime bindings and wrapper for Rust.

Objective-C Runtime bindings and wrapper for Rust. Documentation: http://ssheldon.github.io/rust-objc/objc/ Crate: https://crates.io/crates/objc Messa

Steven Sheldon 336 Jan 2, 2023
Rust <-> Python bindings

rust-cpython Rust bindings for the python interpreter. Documentation Cargo package: cpython Copyright (c) 2015-2020 Daniel Grunwald. Rust-cpython is l

Daniel Grunwald 1.7k Dec 29, 2022
Rust bindings for the Python interpreter

PyO3 Rust bindings for Python. This includes running and interacting with Python code from a Rust binary, as well as writing native Python modules. Us

PyO3 7.2k Jan 4, 2023
Safe Rust <---> GraalVM Polyglot bindings using procedural macros

The class macro is the primary way to generate bindings to Java types; it will generate a struct (with generics if specified) that implements Pass and Receive and has all the methods you give stubs for. The methods generated can be used like normal rust methods, however mutability is not enforced. The fully-qualified type name should precede a block containing method and constructor stubs. Java primitives like char, int, and byte are aliased to corresponding Rust types.

Alec Petridis 33 Dec 28, 2022
Rust bindings for accessing the Go containers/image stack

Rust bindings for accessing the Go containers/image stack This crate contains a Rust API that forks /usr/bin/skopeo and talks to it via a custom API.

Containers 16 Dec 26, 2022
Rust bindings for accessing the Go containers/image stack

Rust bindings for accessing the Go containers/image stack This crate contains a Rust API that forks /usr/bin/skopeo and talks to it via a custom API.

Colin Walters 1 Oct 15, 2021