From c5f1eb3b7e969dde73a6e485a19d5a2766651970 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 9 Feb 2016 13:21:12 +0100 Subject: [PATCH 1/1] flush --- src/libffi.c | 29 +++++++++++++++++++++++------ src/parser.h | 29 +++++++++++++++++++++++++++++ src/parser.re | 2 +- src/parser_proc.y | 19 ++++++++++++++++++- 4 files changed, 71 insertions(+), 8 deletions(-) diff --git a/src/libffi.c b/src/libffi.c index 428a7e6..13eab49 100644 --- a/src/libffi.c +++ b/src/libffi.c @@ -71,7 +71,29 @@ static void psi_ffi_closure_free(void *c) #endif } -static void psi_ffi_handler(ffi_cif *signature, void *_result, void **_args, void *_data); +static void psi_ffi_handler(ffi_cif *_sig, void *_result, void **_args, void *_data) +{ + psi_call(*(zend_execute_data **)_args[0], *(zval **)_args[1], _data); +} + +static void psi_ffi_callback(ffi_cif *_sig, void *_result, void **_args, void *_data) +{ + unsigned argc = _sig->nargs; + void **argv = _args; + ffi_arg *res = _result; + decl *decl = _data; + size_t i; + + // prepare args for the userland call + for (i = 0; i < decl->args->count; ++i) { + + } + // marshal return value of the userland call + switch (decl->func->type->type) { + + } +} + static inline ffi_type *psi_ffi_decl_arg_type(decl_arg *darg); typedef struct PSI_LibffiContext { @@ -319,11 +341,6 @@ static inline PSI_LibffiContext *PSI_LibffiContextInit(PSI_LibffiContext *L) { return L; } -static void psi_ffi_handler(ffi_cif *_sig, void *_result, void **_args, void *_data) -{ - psi_call(*(zend_execute_data **)_args[0], *(zval **)_args[1], _data); -} - static void psi_ffi_init(PSI_Context *C) { C->context = PSI_LibffiContextInit(NULL); diff --git a/src/parser.h b/src/parser.h index 350213c..820f445 100644 --- a/src/parser.h +++ b/src/parser.h @@ -891,6 +891,7 @@ typedef struct let_func { char *name; impl_var *var; impl_arg *arg; + set_values *callback; } let_func; static inline let_func *init_let_func(token_t type, const char *name, impl_var *var) { @@ -1067,6 +1068,34 @@ static inline void free_set_value(set_value *val) { free(val); } +typedef struct set_values { + set_value **vals; + size_t count; +} set_values; + +static inline set_values *init_set_values(set_value *val) { + set_values *vals = calloc(1, sizeof(*vals)); + if (val) { + vals->count = 1; + vals->vals = calloc(1, sizeof(val)); + vals->vals[0] = val; + } + return vals; +} + +static inline set_values *add_set_value(set_values *vals, set_value *val) { + vals->vals = realloc(vals->vals, ++vals->count * sizeof(val)); + vals->vals[vals->count-1] = val; + return vals; +} + +static inline void free_set_values(set_values *vals) { + if (vals->vals) { + free(vals->vals); + } + free(vals); +} + typedef struct set_stmt { impl_var *var; set_value *val; diff --git a/src/parser.re b/src/parser.re index bb6ccab..25bb565 100644 --- a/src/parser.re +++ b/src/parser.re @@ -214,6 +214,7 @@ token_t PSI_ParserScan(PSI_Parser *P) 'STRING' {RETURN(PSI_T_STRING);} 'ARRAY' {RETURN(PSI_T_ARRAY);} 'OBJECT' {RETURN(PSI_T_OBJECT);} + 'CALLBACK' {RETURN(PSI_T_CALLBACK);} 'FUNCTION' {RETURN(PSI_T_FUNCTION);} 'TYPEDEF' {RETURN(PSI_T_TYPEDEF);} 'STRUCT' {RETURN(PSI_T_STRUCT);} @@ -234,7 +235,6 @@ token_t PSI_ParserScan(PSI_Parser *P) 'BOOLVAL' {RETURN(PSI_T_BOOLVAL);} 'ARRVAL' {RETURN(PSI_T_ARRVAL);} 'OBJVAL' {RETURN(PSI_T_OBJVAL);} - 'CBVAL' {RETURN(PSI_T_CBVAL);} 'CALLOC' {RETURN(PSI_T_CALLOC);} 'TO_OBJECT' {RETURN(PSI_T_TO_OBJECT);} 'TO_ARRAY' {RETURN(PSI_T_TO_ARRAY);} diff --git a/src/parser_proc.y b/src/parser_proc.y index 87f5eae..4ae2b33 100644 --- a/src/parser_proc.y +++ b/src/parser_proc.y @@ -720,14 +720,31 @@ let_val(val) ::= let_func(func). { let_calloc(alloc) ::= num_exp(nmemb) COMMA num_exp(size). { alloc = init_let_calloc(nmemb, size); } -%token_class let_func_token CBVAL OBJVAL ARRVAL PATHVAL STRLEN STRVAL FLOATVAL INTVAL BOOLVAL. +%token_class let_func_token OBJVAL ARRVAL PATHVAL STRLEN STRVAL FLOATVAL INTVAL BOOLVAL. %type let_func {let_func*} %destructor let_func {free_let_func($$);} let_func(func) ::= let_func_token(T) LPAREN impl_var(var) RPAREN. { func = init_let_func(T->type, T->text, var); free(T); } +let_func(func_) ::= CALLBACK let_func_token(T) LPAREN impl_var(var) callback_arg_list(args_) RPAREN. { + func_ = init_let_func(T->type, T->text, var); + func_->callback.func = func_; + func_->callback.args = args_; + free(T); +} +callback_arg_list ::= . +callback_arg_list(args) ::= COMMA callback_args(args_). { + args = args_; +} + +callback_args(args) ::= set_value(val). { + args = init_set_values(val); +} +callback_args(args) ::= callback_args(args_) COMMA set_value(val). { + args = add_set_value(args_, val); +} %type set_stmt {set_stmt*} %destructor set_stmt {free_set_stmt($$);} -- 2.30.2