Skip to content

Commit

Permalink
pass by ref done
Browse files Browse the repository at this point in the history
  • Loading branch information
littledivy committed Nov 8, 2023
1 parent bd65ddd commit 91e6d2e
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 64 deletions.
18 changes: 11 additions & 7 deletions deno_bindgen_ir/codegen/deno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ impl TypeScriptType<'_> {
Self("Uint8Array", false) => {
Cow::Owned(format!("{ident},\n {ident}.byteLength"))
}
Self(_, true) => Cow::Owned(format!("{ident}.ptr")),
_ => Cow::Borrowed(ident),
}
}
Expand All @@ -48,7 +49,7 @@ impl TypeScriptType<'_> {
impl From<Type> for TypeScriptType<'_> {
fn from(value: Type) -> Self {
Self(
(match value {
match value {
Type::Void => "void",
Type::Uint8
| Type::Uint16
Expand All @@ -63,7 +64,7 @@ impl From<Type> for TypeScriptType<'_> {
Type::Pointer => "Deno.PointerObject | null",
Type::Buffer => "Uint8Array",
Type::CustomType(name) => name,
}),
},
matches!(value, Type::CustomType(_)),
)
}
Expand Down Expand Up @@ -256,11 +257,7 @@ impl<'a> Codegen<'a> {
}
writeln!(writer, "\n}}\n")?;
}
Inventory::Struct(Struct {
name,
methods,
constructor,
}) => {
Inventory::Struct(Struct { name, methods }) => {
write!(writer, "export class {name} ")?;

format_paren(
Expand All @@ -270,6 +267,7 @@ impl<'a> Codegen<'a> {
|writer, methods| {
writeln!(writer, " ptr: Deno.PointerObject | null = null;\n")?;

// Internal constructor.
writeln!(
writer,
" static __constructor(ptr: Deno.PointerObject | null) {{"
Expand All @@ -280,6 +278,12 @@ impl<'a> Codegen<'a> {
)?;
writeln!(writer, " self.ptr = ptr;")?;
writeln!(writer, " return self;")?;
writeln!(writer, " }}\n")?;

// Dispose method (explicit resource management)
writeln!(writer, " [Symbol.dispose]() {{")?;
writeln!(writer, " this.dealloc();")?;
writeln!(writer, " this.ptr = null;")?;
writeln!(writer, " }}")?;

for method in methods {
Expand Down
1 change: 0 additions & 1 deletion deno_bindgen_ir/inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::Symbol;
#[derive(Debug)]
pub struct Struct {
pub name: &'static str,
pub constructor: Option<Symbol>,
pub methods: &'static [Symbol],
}

Expand Down
1 change: 1 addition & 0 deletions deno_bindgen_ir/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ impl Type {
Self::CustomType(_) => {
let pointer = &args[0];
Some(quote! {
debug_assert!(!#pointer.is_null());
let #name = unsafe { &mut *(#pointer as *mut _) };
})
}
Expand Down
17 changes: 13 additions & 4 deletions deno_bindgen_macro/src/fn_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ use crate::{
FnAttributes,
};

fn custom_type(ty: &str) -> Type {
// yeah, don't worry about it.
Type::CustomType(Box::leak(ty.to_string().into_boxed_str()))
}

fn parse_type(ty: &Box<syn::Type>) -> Result<Type> {
match **ty {
syn::Type::Path(TypePath { ref path, .. }) => {
Expand All @@ -31,10 +36,7 @@ fn parse_type(ty: &Box<syn::Type>) -> Result<Type> {
"usize" => return Ok(Type::Uint64),
"isize" => return Ok(Type::Int64),
ty_str => {
return Ok(Type::CustomType(
// yeah, don't worry about it.
Box::leak(ty_str.to_string().into_boxed_str()),
))
return Ok(custom_type(ty_str));
}
}
}
Expand All @@ -48,6 +50,13 @@ fn parse_type(ty: &Box<syn::Type>) -> Result<Type> {
}
}

if let syn::Type::Path(TypePath { ref path, .. }) = *elem.as_ref() {
if let Some(ident) = path.get_ident() {
let ref ty_str = ident.to_string();
return Ok(custom_type(ty_str));
}
}

Err(Error::UnsupportedType)
}

Expand Down
35 changes: 27 additions & 8 deletions deno_bindgen_macro/src/impl_.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use proc_macro2::TokenStream as TokenStream2;
use quote::format_ident;
use syn::{parse, parse_quote, punctuated::Punctuated, ImplItemFn, ItemImpl};
use syn::{parse_quote, punctuated::Punctuated, ImplItemFn, ItemImpl};

use crate::util::{self, Result};

Expand Down Expand Up @@ -69,7 +69,7 @@ pub fn handle(mut impl_: ItemImpl) -> Result<TokenStream2> {
}
}
} else if is_constructor {
let idents = idents_with_skip(inputs.clone(), 1);
let idents = idents_with_skip(inputs.clone(), 0);
parse_quote!(
#[allow(non_snake_case)]
fn #mangled_name (#(#inputs),*) #out {
Expand Down Expand Up @@ -100,11 +100,31 @@ pub fn handle(mut impl_: ItemImpl) -> Result<TokenStream2> {
}
}

// TODO:
// - create a new quoted function for each method and codegen using fn_::handle
// where first arg is self ptr and rest are method args
// - constructor is a simply special case with no self ptr.
// - we also need to be aware of &mut self and Self types.
// Generate a dealloc method.
{
let ident = format_ident!("__{}_dealloc", ty_str);
let dispose = parse_quote! {
#[allow(non_snake_case)]
fn #ident(self_: *mut #ty_str) {
if self_.is_null() {
return;
}
unsafe { drop(Box::from_raw(self_)) }
}
};
let (generated, mut sym) = crate::fn_::handle_inner(
dispose,
crate::FnAttributes {
internal: true,
..Default::default()
},
)?;

sym.set_name(format_ident!("dealloc"));

methods.push(generated);
syms.push(quote::quote! { #sym });
}

Ok(quote::quote! {
#impl_
Expand All @@ -118,7 +138,6 @@ pub fn handle(mut impl_: ItemImpl) -> Result<TokenStream2> {
pub static _B: deno_bindgen::Inventory = deno_bindgen::Inventory::Struct(
deno_bindgen::inventory::Struct {
name: stringify!(#ty_str),
constructor: None,
methods: &[#syms],
}
);
Expand Down
69 changes: 59 additions & 10 deletions example/bindings/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,21 @@ const { symbols } = dlopen('./target/debug/libdeno_bindgen_test.dylib', {
result: 'pointer',
nonblocking: false
},
inc_foo: {
parameters: [
'pointer',
],
result: 'void',
nonblocking: false
},
__Foo_new: {
parameters: [],
parameters: [
'u32',
],
result: 'pointer',
nonblocking: false
},
__Foo_foo: {
__Foo_inc: {
parameters: [
'pointer',
],
Expand All @@ -80,6 +89,13 @@ const { symbols } = dlopen('./target/debug/libdeno_bindgen_test.dylib', {
result: 'u32',
nonblocking: false
},
__Foo_dealloc: {
parameters: [
'pointer',
],
result: 'void',
nonblocking: false
},
});

export function add(
Expand Down Expand Up @@ -141,15 +157,27 @@ export function make_foo(): Foo {
return Foo.__constructor(ret);
}

function __Foo_new(): Foo {
const ret = symbols.__Foo_new()
export function inc_foo(
arg0: Foo,
): void {
return symbols.inc_foo(
arg0.ptr,
)
}

function __Foo_new(
arg0: number,
): Foo {
const ret = symbols.__Foo_new(
arg0,
)
return Foo.__constructor(ret);
}

function __Foo_foo(
function __Foo_inc(
arg0: Deno.PointerObject | null,
): void {
return symbols.__Foo_foo(
return symbols.__Foo_inc(
arg0,
)
}
Expand All @@ -164,6 +192,14 @@ function __Foo_bar(
)
}

function __Foo_dealloc(
arg0: Deno.PointerObject | null,
): void {
return symbols.__Foo_dealloc(
arg0,
)
}

export class Foo {
ptr: Deno.PointerObject | null = null;

Expand All @@ -173,12 +209,19 @@ export class Foo {
return self;
}

constructor() {
return __Foo_new()
[Symbol.dispose]() {
this.dealloc();
this.ptr = null;
}

constructor(arg0: number) {
return __Foo_new(
arg0,
)
}

foo(): void {
return __Foo_foo(
inc(): void {
return __Foo_inc(
this.ptr,
)
}
Expand All @@ -189,4 +232,10 @@ export class Foo {
arg0,
)
}

dealloc(): void {
return __Foo_dealloc(
this.ptr,
)
}
}
36 changes: 33 additions & 3 deletions example/bindings_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import {
strlen,
non_blocking,
make_foo,
Foo,
inc_foo,
Foo,
} from "./bindings/bindings.ts";
import { assert, assertEquals } from "https://deno.land/std/testing/asserts.ts";
import { assert, assertEquals } from "https://deno.land/std@0.178.0/testing/asserts.ts";

Deno.test({
name: "add#test",
Expand Down Expand Up @@ -72,7 +73,36 @@ Deno.test({
Deno.test({
name: "Foo#constructor",
fn() {
const foo = new Foo();
const foo = new Foo(42);
assertEquals(foo.bar(1), 43);
}
})

Deno.test({
name: "Foo#using",
fn() {
using foo = new Foo(1);
foo.inc();
assertEquals(foo.bar(1), 3);
}
});

Deno.test({
name: "Foo#using explicit",
fn() {
using foo = make_foo();

// Multiple dipose calls are nop.
foo[Symbol.dispose]();
foo[Symbol.dispose]();
}
});

Deno.test({
name: "inc_foo#test",
fn: () => {
using foo = new Foo(22);
inc_foo(foo);
assertEquals(foo.bar(0), 23);
}
})
28 changes: 0 additions & 28 deletions example/s.ts

This file was deleted.

Loading

0 comments on commit 91e6d2e

Please sign in to comment.