flush
authorMichael Wallner <mike@php.net>
Tue, 9 Feb 2016 12:21:12 +0000 (13:21 +0100)
committerMichael Wallner <mike@php.net>
Tue, 9 Feb 2016 12:22:54 +0000 (13:22 +0100)
src/libffi.c
src/parser.h
src/parser.re
src/parser_proc.y

index 428a7e647e8441a9a499728fcbb2f38bb349c9a8..13eab49d5ecbd958b804cac32525a05c8c968de9 100644 (file)
@@ -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);
index 350213c940d88a133c007b91886bd4a25539cf90..820f44528f9aeae8038a7c1b671a8758738cc591 100644 (file)
@@ -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;
index bb6ccab9225579572ee59defec89fbdd8ef74a6f..25bb56550cf8a7f46919edcaf1c0d8aac29a3e4d 100644 (file)
@@ -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);}
index 87f5eae89835b67773ae584161b3c30326a64edc..4ae2b33d2fe24d3e4967541a6d46c0f3a6410170 100644 (file)
@@ -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($$);}