Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 679b5ddb0a
Fetching contributors…

Cannot retrieve contributors at this time

file 178 lines (150 sloc) 6.049 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <dlfcn.h>
#include <limits.h>
#include <errno.h>
#define __STDC_LIMIT_MACROS true
#include <stdint.h>
#include <sys/mman.h>
#ifdef __APPLE__
#include <ffi/ffi.h>
#else
#include <ffi.h>
#endif
#include <eio.h>
#include <node_events.h>
#include <node_object_wrap.h>
#include <node.h>
#include <pthread.h>
#include <queue>

#define INTEGER_CONVERSION_BUFFER_SIZE 64

#define UINT8_MIN 0
#define UINT16_MIN 0
#define UINT32_MIN 0
#define UINT64_MIN 0

#define THROW_ERROR_EXCEPTION(x) ThrowException(Exception::Error(String::New(x)))

#define STR_TO_INT64(x) strtoll(x, NULL, 0)
#define STR_TO_UINT64(x) strtoull(x, NULL, 0)

using namespace v8;
using namespace node;

class Pointer : public ObjectWrap {
    public:
        Pointer(unsigned char *ptr);
        ~Pointer();
        
        static void Initialize(Handle<Object> Target);
        static Handle<Object> WrapInstance(Pointer *inst);
        static Handle<Object> WrapPointer(unsigned char *ptr);
        unsigned char *GetPointer();
        void MovePointer(int bytes);
        void Alloc(size_t bytes);
        void Free();
        
    protected:
        static Handle<Value> New(const Arguments& args);
        static Handle<Value> Seek(const Arguments& args);
        static Handle<Value> PutInt8(const Arguments& args);
        static Handle<Value> GetInt8(const Arguments& args);
        static Handle<Value> PutUInt8(const Arguments& args);
        static Handle<Value> GetUInt8(const Arguments& args);
        static Handle<Value> PutInt16(const Arguments& args);
        static Handle<Value> GetInt16(const Arguments& args);
        static Handle<Value> PutUInt16(const Arguments& args);
        static Handle<Value> GetUInt16(const Arguments& args);
        static Handle<Value> PutInt32(const Arguments& args);
        static Handle<Value> GetInt32(const Arguments& args);
        static Handle<Value> PutUInt32(const Arguments& args);
        static Handle<Value> GetUInt32(const Arguments& args);
        static Handle<Value> PutInt64(const Arguments& args);
        static Handle<Value> GetInt64(const Arguments& args);
        static Handle<Value> PutUInt64(const Arguments& args);
        static Handle<Value> GetUInt64(const Arguments& args);
        static Handle<Value> PutFloat(const Arguments& args);
        static Handle<Value> GetFloat(const Arguments& args);
        static Handle<Value> PutDouble(const Arguments& args);
        static Handle<Value> GetDouble(const Arguments& args);
        static Handle<Value> PutPointerMethod(const Arguments& args);
        static Handle<Value> GetPointerMethod(const Arguments& args);
        static Handle<Value> PutCString(const Arguments& args);
        static Handle<Value> GetCString(const Arguments& args);
        static Handle<Value> IsNull(const Arguments& args);
        
        static Handle<Value> GetAddress(Local<String> name, const AccessorInfo& info);
        static Handle<Value> GetAllocated(Local<String> name, const AccessorInfo& info);
        
    private:
        static Persistent<FunctionTemplate> pointer_template;
        static Handle<FunctionTemplate> MakeTemplate();
        unsigned char *m_ptr;
        unsigned int m_allocated;
};

class AsyncCallParams {
public:
    ffi_cif *cif;
    void (*ptr)(void);
    void *res;
    void **args;
    Persistent<Object> emitter;
};

class FFI : public ObjectWrap {
    public:
        static void InitializeStaticFunctions(Handle<Object> Target);
        static void InitializeBindings(Handle<Object> Target);

    protected:
        static Handle<Value> FFIPrepCif(const Arguments& args);
        static Handle<Value> Strtoul(const Arguments& args);
};

class ForeignCaller : public ObjectWrap {
    public:
        ForeignCaller();
        ~ForeignCaller();
        static void Initialize(Handle<Object> Target);
        
    protected:
        static Handle<Value> New(const Arguments& args);
        static Handle<Value> Exec(const Arguments& args);
        static int AsyncFFICall(eio_req *req);
        static int FinishAsyncFFICall(eio_req *req);
        
        ffi_cif *m_cif;
        void (*m_fn)(void);
        void *m_res;
        void **m_fnargs;
        
        bool m_async;
                
    private:
        static Persistent<FunctionTemplate> foreign_caller_template;
        static Handle<FunctionTemplate> MakeTemplate();
};

class ThreadedCallbackInvokation;

class CallbackInfo : public ObjectWrap {
    public:
        CallbackInfo(Handle<Function> func, void *closure);
        ~CallbackInfo();
        static void Initialize(Handle<Object> Target);
        Handle<Value> GetPointerObject();
        static void WatcherCallback(EV_P_ ev_async *w, int revents);
        
    protected:
        static void DispatchToV8(CallbackInfo *self, void *retval, void **parameters);
        static Handle<Value> New(const Arguments& args);
        static Handle<Value> GetPointer(Local<String> name, const AccessorInfo& info);
        static void Invoke(ffi_cif *cif, void *retval, void **parameters, void *user_data);

    private:
        static Persistent<FunctionTemplate> callback_template;
        static Handle<FunctionTemplate> MakeTemplate();

        static pthread_t g_mainthread;
        static pthread_mutex_t g_queue_mutex;
        static std::queue<ThreadedCallbackInvokation *> g_queue;
        static ev_async g_async;
        
        void *m_closure;
        Persistent<Function> m_function;
        Handle<Object> m_this;
};

class ThreadedCallbackInvokation {
    public:
        ThreadedCallbackInvokation(CallbackInfo *cbinfo, void *retval, void **parameters);
        ~ThreadedCallbackInvokation();
        
        void SignalDoneExecuting();
        void WaitForExecution();

        void *m_retval;
        void **m_parameters;
        CallbackInfo *m_cbinfo;
        
    private:
        pthread_cond_t m_cond;
        pthread_mutex_t m_mutex;
};
Something went wrong with that request. Please try again.