#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 {
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);
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) {
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;
'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);}
'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);}
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($$);}