flush
[m6w6/ext-psi] / src / compiler.c
index e075a398d9ed3f9005ee4034d1639375e6af19ea..0c5fcb5e63d35a5b3675774c56b84ea617928b4b 100644 (file)
@@ -7,7 +7,7 @@
 
 #include "compiler.h"
 
-PSI_Compiler *PSI_CompilerInit(PSI_Compiler *C, PSI_Validator *V)
+PSI_Compiler *PSI_CompilerInit(PSI_Compiler *C, PSI_Validator *V, void *context)
 {
        if (!C) {
                C = malloc(sizeof(*C));
@@ -15,13 +15,26 @@ PSI_Compiler *PSI_CompilerInit(PSI_Compiler *C, PSI_Validator *V)
        memset(C, 0, sizeof(*C));
 
        PSI_DataExchange((PSI_Data *) C, (PSI_Data *) V);
+
+       C->context = context;
+
        return C;
 }
 
 typedef struct PSI_ClosureData {
+       void *context;
        impl *impl;
 } PSI_ClosureData;
 
+static inline PSI_ClosureData *PSI_ClosureDataAlloc(void *context, impl *impl) {
+       PSI_ClosureData *data = malloc(sizeof(*data));
+
+       data->context = context;
+       data->impl = impl;
+
+       return data;
+}
+
 static inline size_t impl_num_min_args(impl *impl) {
        size_t i, n = impl->func->args->count;
 
@@ -32,7 +45,8 @@ static inline size_t impl_num_min_args(impl *impl) {
        }
        return n;
 }
-void PSI_Closure(jit_type_t signature, void *result, void **args, void *user_data)
+
+void jit_closure_handler(jit_type_t signature, void *result, void **args, void *user_data)
 {
        zend_execute_data *execute_data = args[0];
        zval *return_value = args[1];
@@ -79,3 +93,30 @@ void PSI_Closure(jit_type_t signature, void *result, void **args, void *user_dat
                goto nextarg;
        ZEND_PARSE_PARAMETERS_END();
 }
+
+zend_function_entry *PSI_CompilerCompile(PSI_Compiler *C)
+{
+       size_t i, j = 0;
+       jit_type_t signature, params[] = {
+               jit_type_void_ptr,
+               jit_type_void_ptr
+       };
+       zend_function_entry *zfe = calloc(C->impls->count + 1, sizeof(*zfe));
+
+       for (i = 0; i < C->impls->count; ++i) {
+               zend_function_entry *zf;
+               PSI_ClosureData *data;
+
+               if (!C->impls->list[i]->decl) {
+                       continue;
+               }
+               signature = jit_type_create_signature(jit_abi_cdecl, jit_type_void, params, 2, 1);
+
+               zf = &zfe[++j];
+               data = PSI_ClosureDataAlloc(C->context, C->impls->list[i]);
+               zf->fname = C->impls->list[i]->func->name;
+               zf->handler = jit_closure_create(C->context, signature, jit_closure_handler, data);
+       }
+
+       return zfe;
+}