Commits

Andrei Homescu committed e5e12e1

Added a Python script to auto-generate a C header for the extension API.

  • Participants
  • Parent commits 3722d9d
  • Branches rewrite

Comments (0)

Files changed (5)

     def decorate(fn):
         fn_name = fn.func_name
         fn_ll_type = lltype.Ptr(lltype.FuncType(arg_types, res_type))
-        _API_FUNCS.append((fn_name, fn, fn_ll_type))
+        _API_FUNCS.append((fn_name, fn, fn_ll_type, res_type, arg_types))
         fn._always_inline_ = True
         return fn
 
     return annlowlevel.cast_instance_to_base_ptr(w_obj)
 
 @api_func(lltype.Signed, [object_type])
-def get_type_func(ext_obj):
+def get_type(ext_obj):
     return 0
 
 @api_func(object_type, [object_type])
-def deref_func(ext_obj):
+def deref(ext_obj):
     return ext_obj
 
 _api_struct_args = [(fn_name, fn_ll_type) for
-        fn_name, _, fn_ll_type in _API_FUNCS]
+        fn_name, _, fn_ll_type, _, _ in _API_FUNCS]
 api_type = lltype.Struct('API', *_api_struct_args)
 api_ptr_type = lltype.Ptr(api_type)
 
 _API_FUNCS_iterable = unrolling_iterable(_API_FUNCS)
 def get_api_ptr():
     api_ptr = rffi.make(api_type)
-    for fn_name, fn, fn_ll_type in _API_FUNCS_iterable:
+    for fn_name, fn, fn_ll_type, _, _ in _API_FUNCS_iterable:
         setattr(api_ptr, fn_name, rffi.llhelper(fn_ll_type, fn))
     return api_ptr
 
+# FIXME: use actual rffi types
+_type_dict = {
+        lltype.Signed: 'long',
+        object_type: 'void*'
+        }
+
+def get_api_struct():
+    struct  = 'struct HappyAPI {\n'
+    for fn_name, _, _, res_type, arg_types in _API_FUNCS:
+        struct += '    %s %s(%s);\n' % (_type_dict[res_type]
+                , fn_name, ', '.join((_type_dict[arg_type] for arg_type in
+                    arg_types)))
+    struct += '};\n'
+    return struct
+

File extensions/happy_api.h

+#ifndef __HAPPY_API_H__
+#define __HAPPY_API_H__
+
+struct HappyAPI {
+    long get_type(void*);
+    void* deref(void*);
+};
+
+#endif // __HAPPY_API_H__

File extensions/happy_ext.cpp

 
 namespace HAPPY {
     
-const struct API *API::api = NULL;
+struct HappyAPI *HappyAPI = NULL;
 
-extern "C" void *init_happy_api(const struct API *api) {
-    API::init(api);
+extern "C" void *init_happy_api(struct HappyAPI *api) {
+    ASSERT(HappyAPI == NULL);
+    HappyAPI = api;
     return NULL;
 }
 

File extensions/happy_ext.h

 #include <cassert>
 #include <cstdlib>
 
-#include <runtime/base/types.h>
+//#include <runtime/base/types.h>
+
+#include "happy_api.h"
 
 namespace HAPPY {
 
-typedef void *W_object;
+extern struct HappyAPI *HappyAPI;
 
 #define ASSERT(x)  assert(x)
 
-struct API {
-    /*
-     * Actual API functions
-     */
-    HPHP::DataType (*get_type)(W_object obj);
-    W_object (*deref)(W_object obj);
-    bool (*to_boolean)(W_object obj);
-    long long (*to_int)(W_object obj, int base);
-    double (*to_double)(W_object obj);
-    bool (*is_numeric)(W_object obj);
-    W_object (*new_boolean)(bool v);
-    W_object (*new_int)(int64_t v);
-    W_object (*new_double)(double v);
-    W_object (*array_create)(W_object key, W_object value);
-    ssize_t (*array_get_length)(W_object arr);
-    W_object (*array_get_value)(W_object arr, W_object key);
-    void (*array_set_value)(W_object arr, W_object key, W_object value);
-    W_object (*iter_new)(W_object arr);
-    W_object (*iter_next)(W_object iter);
-    bool (*iter_at_end)(W_object iter);
-    W_object (*iter_key)(W_object elem);
-    W_object (*iter_value)(W_object elem);
-
-    /*
-     * Helper functions
-     */
-    static void init(const struct API *new_api) { 
-        ASSERT(api == NULL);
-        api = new_api;
-    }
-
-    static const struct API *get() {
-        ASSERT(api);
-        return api;
-    }
-
-private:
-    static const struct API *api;
-
-    // Disable construction and copy
-    API();
-    API(const API&);
-    API &operator=(const API&);
-};
-
 #define HAPPY_EXT(x)    extern "C" W_object happy_ext_ ## x (int param_count,\
                                                              W_object *params)
 
-#define HAPPY_API       (HAPPY::API::get())
+#define HAPPY_API       (HappyAPI)
 
 #define EXT_PROLOGUE()  
 

File gen_api_header.py

+
+import ext_api
+
+with open('extensions/happy_api.h', 'w') as hdr:
+    print >>hdr, '#ifndef __HAPPY_API_H__'
+    print >>hdr, '#define __HAPPY_API_H__'
+    print >>hdr
+    print >>hdr, ext_api.get_api_struct()
+    print >>hdr, '#endif // __HAPPY_API_H__'
+