Skip to content

Commit

Permalink
Functions WORK !!!
Browse files Browse the repository at this point in the history
Signed-off-by: Dusan Malusev <dusan@dusanmalusev.dev>
  • Loading branch information
CodeLieutenant committed Jun 24, 2024
1 parent e15940e commit bf89d9d
Show file tree
Hide file tree
Showing 35 changed files with 1,247 additions and 1,199 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 15 additions & 1 deletion examples/complex/src/args_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,18 @@
#![allow(non_snake_case)]
#![allow(deref_nullptr)]
#![allow(clippy::all)]
include!(concat!(env!("OUT_DIR"), "/php_args_bindings.rs"));

use phper::zend_create_fn;

mod bindings {
include!(concat!(env!("OUT_DIR"), "/php_args_bindings.rs"));
}

use bindings::register_class_Complex_Foo;

pub use bindings::{
arginfo_Complex_get_all_ini, arginfo_Complex_say_hello, arginfo_Complex_throw_exception,
arginfo_class_Complex_Foo_getFoo, arginfo_class_Complex_Foo_setFoo,
};

zend_create_fn!(register_class_Complex_Foo, CLASS_COMPLEX_FOO);
94 changes: 46 additions & 48 deletions examples/complex/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,22 @@ use std::ffi::CStr;

use args_bindings::{
arginfo_Complex_get_all_ini, arginfo_Complex_say_hello, arginfo_Complex_throw_exception,
register_class_Complex_Foo,
arginfo_class_Complex_Foo_getFoo, arginfo_class_Complex_Foo_setFoo,
};

use crate::args_bindings::CLASS_COMPLEX_FOO;
use phper::arrays::ZArray;
use phper::classes::methods::MethodEntityBuilder;
use phper::classes::ClassEntity;
use phper::ini::{ini_get, Policy};
use phper::{modules::Module, php_get_module, values::ZVal, zend_args, zend_create_fn};
use phper::objects::StateObj;
use phper::{modules::Module, php_get_module, values::ZVal, zend_args};

fn say_hello(arguments: &mut [ZVal]) -> phper::Result<String> {
let name = &mut arguments[0];
name.convert_to_string();
let name = name.as_z_str().unwrap().to_str()?;

Ok(format!("Hello, {name}!\n"))
}

Expand Down Expand Up @@ -58,58 +62,52 @@ pub fn get_module() -> Module {
module.on_request_init(|_info| {});
module.on_request_shutdown(|_info| {});

module
.add_function(
"Comples\\say_hello",
zend_args!(arginfo_Complex_say_hello),
say_hello,
)
.add_function(
"Complex\\throw_exception",
zend_args!(arginfo_Complex_throw_exception),
throw_exception,
)
.add_function(
"Comples\\get_all_ini",
zend_args!(arginfo_Complex_get_all_ini),
|_: &mut [ZVal]| {
let mut arr = ZArray::new();

let complex_enable = ZVal::from(ini_get::<bool>("complex.enable"));
arr.insert("complex.enable", complex_enable);

let complex_description =
ZVal::from(ini_get::<Option<&CStr>>("complex.description"));
arr.insert("complex.description", complex_description);
Ok::<_, Infallible>(arr)
},
);

module.add_function(
"Complex\\say_hello",
zend_args!(arginfo_Complex_say_hello),
say_hello,
);
// .add_function(
// "Complex\\throw_exception",
// zend_args!(arginfo_Complex_throw_exception),
// throw_exception,
// )
// .add_function(
// "Complex\\get_all_ini",
// zend_args!(arginfo_Complex_get_all_ini),
// |_: &mut [ZVal]| {
// let mut arr = ZArray::new();
//
// let complex_enable = ZVal::from(ini_get::<bool>("complex.enable"));
// arr.insert("complex.enable", complex_enable);
//
// let complex_description =
// ZVal::from(ini_get::<Option<&CStr>>("complex.description"));
// arr.insert("complex.description", complex_description);
// Ok::<_, Infallible>(arr)
// },
// );
//
// let mut foo_class = ClassEntity::new(CLASS_COMPLEX_FOO);
//
// // register classes
let mut foo_class = ClassEntity::new(zend_create_fn!(register_class_Complex_Foo));
// foo_class.add_property("foo", Visibility::Private, 100);
// foo_class.add_method(
// "getFoo",
// Visibility::Public,
// |this: &mut StateObj, _: &mut [ZVal]| {
// let prop = this.get_property("foo");
// Ok::<_, phper::Error>(prop.clone())
// Ok::<_, phper::Error>(this.get_property("foo").clone())
// },
// MethodEntityBuilder::new("getFoo", zend_args!(arginfo_class_Complex_Foo_getFoo))
// .set_public(),
// );
// foo_class
// .add_method(
// "setFoo",
// Visibility::Public,
// |this: &mut StateObj, arguments: &mut [ZVal]| -> phper::Result<()> {
// this.set_property("foo", arguments[0].clone());
// Ok(())
// },
// )
// .argument(Argument::by_val("foo"));
// module.add_class(foo_class);
//
// // register extra info
// foo_class.add_method(
// |this: &mut StateObj, arguments: &mut [ZVal]| -> phper::Result<()> {
// this.set_property("foo", arguments[0].clone());
// Ok(())
// },
// MethodEntityBuilder::new("setFoo", zend_args!(arginfo_class_Complex_Foo_setFoo))
// .set_public(),
// );
// module.add_class(foo_class);

module.add_info("extra info key", "extra info value");

module
Expand Down
3 changes: 3 additions & 0 deletions examples/complex/stubs/say_hello.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
/** @generate-class-entries */

namespace Complex {
// const HELLO_WORLD = 'hello world';

function say_hello(string $name): string {}

function throw_exception(): void
Expand All @@ -19,6 +21,7 @@ function get_all_ini(): array
*/
class Foo {
private int|\JsonSerializable|\ArrayAccess $foo = 100;

public function getFoo(): int {}

public function setFoo(int $foo): void {}
Expand Down
38 changes: 20 additions & 18 deletions examples/complex/tests/php/test.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,26 @@
ini_set("display_startup_errors", "On");
error_reporting(E_ALL);

assert_eq(complex_say_hello("world"), "Hello, world!\n");

try {
complex_throw_exception();
} catch (ErrorException $e) {
assert_eq($e->getMessage(), "I am sorry");
}

assert_eq(complex_get_all_ini(), [
"complex.enable" => false,
"complex.description" => "hello world.",
]);

$foo = new FooClass();
assert_eq($foo->getFoo(), 100);

$foo->setFoo("Hello");
assert_eq($foo->getFoo(), "Hello");
// print_r(get_defined_functions());
// print_r(ini_get_all());
assert_eq(Complex\say_hello("world"), "Hello, world!\n");
//
// try {
// Complex\throw_exception();
// } catch (ErrorException $e) {
// assert_eq($e->getMessage(), "I am sorry");
// }
//
// assert_eq(Complex\get_all_ini(), [
// "complex.enable" => false,
// "complex.description" => "hello world.",
// ]);

// $foo = new Complex\\FooClass();
// assert_eq($foo->getFoo(), 100);
//
// $foo->setFoo(200);
// assert_eq($foo->getFoo(), 200);

function assert_eq($left, $right) {
if ($left !== $right) {
Expand Down
4 changes: 2 additions & 2 deletions phper-alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ impl<T> EBox<T> {
/// Consumes and returning a wrapped raw pointer.
///
/// Will leak memory.
pub fn into_raw(b: EBox<T>) -> *mut T {
ManuallyDrop::new(b).ptr
pub fn into_raw(self) -> *mut T {
ManuallyDrop::new(self).ptr
}

/// Consumes the `EBox`, returning the wrapped value.
Expand Down
2 changes: 2 additions & 0 deletions phper-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ quote = "1.0.31"
syn = { version = "2.0.26", features = ["full"] }
proc-macro2 = "1.0.66"

phper-sys = { workspace = true }

[dev-dependencies]
syn = { version = "2.0.26", features = ["full", "extra-traits"] }
9 changes: 0 additions & 9 deletions phper-macros/src/alloc.rs

This file was deleted.

9 changes: 0 additions & 9 deletions phper-macros/src/derives.rs

This file was deleted.

9 changes: 0 additions & 9 deletions phper-macros/src/globals.rs

This file was deleted.

16 changes: 8 additions & 8 deletions phper-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,14 @@
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.

#![warn(rust_2018_idioms, missing_docs)]
#![warn(rust_2021_compatibility, rust_2018_idioms)]
#![allow(missing_docs)]
#![warn(clippy::dbg_macro, clippy::print_stdout)]
#![doc = include_str!("../README.md")]

// TODO Write a bridge macro for easy usage about register functions and
// classes, like `cxx`.

mod alloc;
mod derives;
mod globals;
mod inner;
mod log;
mod utils;
mod zend_create_fn;

use proc_macro::TokenStream;

Expand Down Expand Up @@ -52,6 +47,11 @@ pub fn c_str_ptr(input: TokenStream) -> TokenStream {
utils::c_str_ptr(input)
}

#[proc_macro]
pub fn zend_create_fn(input: TokenStream) -> TokenStream {
zend_create_fn::zend_create_fn(input)
}

/// PHP module entry, wrap the `phper::modules::Module` write operation.
///
/// # Examples
Expand Down
9 changes: 0 additions & 9 deletions phper-macros/src/log.rs

This file was deleted.

44 changes: 44 additions & 0 deletions phper-macros/src/zend_create_fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::quote;
use syn::parse::{Parse, ParseBuffer};
use syn::Ident;
use syn::{parse_macro_input, Token};

struct ZendFn {
original_zend_fn: Ident,
const_name: Ident,
}

impl Parse for ZendFn {
fn parse(input: &'_ ParseBuffer<'_>) -> syn::Result<Self> {
let original_zend_fn: Ident = input.parse()?;
input.parse::<Token![,]>()?;
let const_name: Ident = input.parse()?;
Ok(ZendFn {
original_zend_fn,
const_name,
})
}
}

pub(crate) fn zend_create_fn(input: TokenStream) -> TokenStream {
let ZendFn {
original_zend_fn,
const_name,
} = parse_macro_input!(input as ZendFn);

let fn_name = format!("zend_create_fn_{}", original_zend_fn.to_string());
let new_fn_name = Ident::new(&fn_name, Span::call_site());

let result = quote! {
unsafe extern "C" fn #new_fn_name() -> *mut phper::sys::zend_class_entry
{
unsafe { #original_zend_fn() as *mut phper::sys::zend_class_entry }
}

pub(crate) const #const_name: unsafe extern "C" fn() -> *mut phper::sys::zend_class_entry = #new_fn_name;
};

result.into()
}
Loading

0 comments on commit bf89d9d

Please sign in to comment.