Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 184 lines (150 sloc) 8.315 kb
ab0b75a @rbranson Tree (Re)organization; Added type aliases for common C types; StructType...
rbranson authored
1 #include "ffi.h"
2
3 ///////////////
4
27d2d24 @TooTallNate Whitespace.
TooTallNate authored
5 void FFI::InitializeStaticFunctions(Handle<Object> target) {
e55356e @TooTallNate The rest of the src files formatting and whitespace fixes.
TooTallNate authored
6 Local<Object> o = Object::New();
bd33583 @TooTallNate Remove *ALL* trailing whitespace.
TooTallNate authored
7
0860da6 @TooTallNate Re-enable the static 'atoi' and 'abs' bindings, even on Windows.
TooTallNate authored
8 // atoi and abs here for testing purposes
9 o->Set(String::New("atoi"), Pointer::WrapPointer((unsigned char *)atoi));
10 // Windows has multiple `abs` signatures, so we need to manually disambiguate
11 int (*absPtr)(int)(abs);
12 o->Set(String::New("abs"), Pointer::WrapPointer((unsigned char *)absPtr));
13
14 // dl functions used by the DynamicLibrary JS class
e55356e @TooTallNate The rest of the src files formatting and whitespace fixes.
TooTallNate authored
15 o->Set(String::New("dlopen"), Pointer::WrapPointer((unsigned char *)dlopen));
16 o->Set(String::New("dlclose"), Pointer::WrapPointer((unsigned char *)dlclose));
17 o->Set(String::New("dlsym"), Pointer::WrapPointer((unsigned char *)dlsym));
18 o->Set(String::New("dlerror"), Pointer::WrapPointer((unsigned char *)dlerror));
bd33583 @TooTallNate Remove *ALL* trailing whitespace.
TooTallNate authored
19
e55356e @TooTallNate The rest of the src files formatting and whitespace fixes.
TooTallNate authored
20 target->Set(String::NewSymbol("StaticFunctions"), o);
ab0b75a @rbranson Tree (Re)organization; Added type aliases for common C types; StructType...
rbranson authored
21 }
22
23 ///////////////
24
27d2d24 @TooTallNate Whitespace.
TooTallNate authored
25 void FFI::InitializeBindings(Handle<Object> target) {
bd33583 @TooTallNate Remove *ALL* trailing whitespace.
TooTallNate authored
26
e55356e @TooTallNate The rest of the src files formatting and whitespace fixes.
TooTallNate authored
27 target->Set(String::New("free"), FunctionTemplate::New(Free)->GetFunction());
28 target->Set(String::New("prepCif"), FunctionTemplate::New(FFIPrepCif)->GetFunction());
29 target->Set(String::New("strtoul"), FunctionTemplate::New(Strtoul)->GetFunction());
30 target->Set(String::New("POINTER_SIZE"), Integer::New(sizeof(unsigned char *)));
31 target->Set(String::New("FFI_TYPE_SIZE"), Integer::New(sizeof(ffi_type)));
7174a4c @TooTallNate Always write the 'HAS_OBJC' constant to the ffi bindings.
TooTallNate authored
32
33 bool hasObjc = false;
4c90225 @TooTallNate hasObjC → HAS_OBJC, since it is really a constant.
TooTallNate authored
34 #if __OBJC__ || __OBJC2__
7174a4c @TooTallNate Always write the 'HAS_OBJC' constant to the ffi bindings.
TooTallNate authored
35 hasObjc = true;
4c90225 @TooTallNate hasObjC → HAS_OBJC, since it is really a constant.
TooTallNate authored
36 #endif
7174a4c @TooTallNate Always write the 'HAS_OBJC' constant to the ffi bindings.
TooTallNate authored
37 target->Set(String::New("HAS_OBJC"), Boolean::New(hasObjc), static_cast<PropertyAttribute>(ReadOnly|DontDelete));
bd33583 @TooTallNate Remove *ALL* trailing whitespace.
TooTallNate authored
38
e55356e @TooTallNate The rest of the src files formatting and whitespace fixes.
TooTallNate authored
39 Local<Object> smap = Object::New();
40 smap->Set(String::New("byte"), Integer::New(sizeof(unsigned char)));
41 smap->Set(String::New("int8"), Integer::New(sizeof(int8_t)));
42 smap->Set(String::New("uint8"), Integer::New(sizeof(uint8_t)));
43 smap->Set(String::New("int16"), Integer::New(sizeof(int16_t)));
44 smap->Set(String::New("uint16"), Integer::New(sizeof(uint16_t)));
45 smap->Set(String::New("int32"), Integer::New(sizeof(int32_t)));
46 smap->Set(String::New("uint32"), Integer::New(sizeof(uint32_t)));
47 smap->Set(String::New("int64"), Integer::New(sizeof(int64_t)));
48 smap->Set(String::New("uint64"), Integer::New(sizeof(uint64_t)));
49 smap->Set(String::New("char"), Integer::New(sizeof(char)));
50 smap->Set(String::New("uchar"), Integer::New(sizeof(unsigned char)));
51 smap->Set(String::New("short"), Integer::New(sizeof(short)));
52 smap->Set(String::New("ushort"), Integer::New(sizeof(unsigned short)));
53 smap->Set(String::New("int"), Integer::New(sizeof(int)));
54 smap->Set(String::New("uint"), Integer::New(sizeof(unsigned int)));
55 smap->Set(String::New("long"), Integer::New(sizeof(long)));
56 smap->Set(String::New("ulong"), Integer::New(sizeof(unsigned long)));
57 smap->Set(String::New("longlong"), Integer::New(sizeof(long long)));
58 smap->Set(String::New("ulonglong"), Integer::New(sizeof(unsigned long long)));
59 smap->Set(String::New("float"), Integer::New(sizeof(float)));
60 smap->Set(String::New("double"), Integer::New(sizeof(double)));
61 smap->Set(String::New("pointer"), Integer::New(sizeof(unsigned char *)));
62 smap->Set(String::New("string"), Integer::New(sizeof(char *)));
63 smap->Set(String::New("size_t"), Integer::New(sizeof(size_t)));
64 // Size of a Persistent handle to a JS object
65 smap->Set(String::New("Object"), Integer::New(sizeof(Persistent<Object>)));
66
67 Local<Object> ftmap = Object::New();
68 ftmap->Set(String::New("void"), Pointer::WrapPointer((unsigned char *)&ffi_type_void));
69 ftmap->Set(String::New("byte"), Pointer::WrapPointer((unsigned char *)&ffi_type_uint8));
70 ftmap->Set(String::New("int8"), Pointer::WrapPointer((unsigned char *)&ffi_type_sint8));
71 ftmap->Set(String::New("uint8"), Pointer::WrapPointer((unsigned char *)&ffi_type_uint8));
72 ftmap->Set(String::New("uint16"), Pointer::WrapPointer((unsigned char *)&ffi_type_uint16));
73 ftmap->Set(String::New("int16"), Pointer::WrapPointer((unsigned char *)&ffi_type_sint16));
74 ftmap->Set(String::New("uint32"), Pointer::WrapPointer((unsigned char *)&ffi_type_uint32));
75 ftmap->Set(String::New("int32"), Pointer::WrapPointer((unsigned char *)&ffi_type_sint32));
76 ftmap->Set(String::New("uint64"), Pointer::WrapPointer((unsigned char *)&ffi_type_uint64));
77 ftmap->Set(String::New("int64"), Pointer::WrapPointer((unsigned char *)&ffi_type_sint64));
78 ftmap->Set(String::New("uchar"), Pointer::WrapPointer((unsigned char *)&ffi_type_uchar));
79 ftmap->Set(String::New("char"), Pointer::WrapPointer((unsigned char *)&ffi_type_schar));
80 ftmap->Set(String::New("ushort"), Pointer::WrapPointer((unsigned char *)&ffi_type_ushort));
81 ftmap->Set(String::New("short"), Pointer::WrapPointer((unsigned char *)&ffi_type_sshort));
82 ftmap->Set(String::New("uint"), Pointer::WrapPointer((unsigned char *)&ffi_type_uint));
83 ftmap->Set(String::New("int"), Pointer::WrapPointer((unsigned char *)&ffi_type_sint));
84 ftmap->Set(String::New("float"), Pointer::WrapPointer((unsigned char *)&ffi_type_float));
85 ftmap->Set(String::New("double"), Pointer::WrapPointer((unsigned char *)&ffi_type_double));
86 ftmap->Set(String::New("pointer"), Pointer::WrapPointer((unsigned char *)&ffi_type_pointer));
87 ftmap->Set(String::New("string"), Pointer::WrapPointer((unsigned char *)&ffi_type_pointer));
88 ftmap->Set(String::New("size_t"), Pointer::WrapPointer((unsigned char *)&ffi_type_pointer));
89
90 // libffi is weird when it comes to long data types (defaults to 64-bit), so we emulate here, since
91 // some platforms have 32-bit longs and some platforms have 64-bit longs.
92 if (sizeof(long) == 4) {
93 ftmap->Set(String::New("ulong"), Pointer::WrapPointer((unsigned char *)&ffi_type_uint32));
94 ftmap->Set(String::New("long"), Pointer::WrapPointer((unsigned char *)&ffi_type_sint32));
95 } else if (sizeof(long) == 8) {
96 ftmap->Set(String::New("ulong"), Pointer::WrapPointer((unsigned char *)&ffi_type_uint64));
97 ftmap->Set(String::New("long"), Pointer::WrapPointer((unsigned char *)&ffi_type_sint64));
98 }
99
100 // Let libffi handle "long long"
101 ftmap->Set(String::New("ulonglong"),Pointer::WrapPointer((unsigned char *)&ffi_type_ulong));
102 ftmap->Set(String::New("longlong"), Pointer::WrapPointer((unsigned char *)&ffi_type_slong));
103
104 target->Set(String::New("FFI_TYPES"), ftmap);
105 target->Set(String::New("TYPE_SIZE_MAP"), smap);
ab0b75a @rbranson Tree (Re)organization; Added type aliases for common C types; StructType...
rbranson authored
106 }
107
27d2d24 @TooTallNate Whitespace.
TooTallNate authored
108 Handle<Value> FFI::Free(const Arguments &args) {
e55356e @TooTallNate The rest of the src files formatting and whitespace fixes.
TooTallNate authored
109 HandleScope scope;
27d2d24 @TooTallNate Whitespace.
TooTallNate authored
110
e55356e @TooTallNate The rest of the src files formatting and whitespace fixes.
TooTallNate authored
111 Pointer *p = ObjectWrap::Unwrap<Pointer>(args[0]->ToObject());
112 free(p->GetPointer());
113 return Undefined();
cab1216 @TooTallNate Add a hard-coded binding to free().
TooTallNate authored
114 }
115
9391a99 @TooTallNate Misc.
TooTallNate authored
116 /**
117 * Hard-coded `stftoul` binding, for the benchmarks.
118 */
119
27d2d24 @TooTallNate Whitespace.
TooTallNate authored
120 Handle<Value> FFI::Strtoul(const Arguments &args) {
e55356e @TooTallNate The rest of the src files formatting and whitespace fixes.
TooTallNate authored
121 HandleScope scope;
27d2d24 @TooTallNate Whitespace.
TooTallNate authored
122
e55356e @TooTallNate The rest of the src files formatting and whitespace fixes.
TooTallNate authored
123 Pointer *middle = ObjectWrap::Unwrap<Pointer>(args[1]->ToObject());
124 char buf[128];
125 args[0]->ToString()->WriteUtf8(buf);
bd33583 @TooTallNate Remove *ALL* trailing whitespace.
TooTallNate authored
126
e55356e @TooTallNate The rest of the src files formatting and whitespace fixes.
TooTallNate authored
127 unsigned long val = strtoul(buf, (char **)middle->GetPointer(), args[2]->Int32Value());
bd33583 @TooTallNate Remove *ALL* trailing whitespace.
TooTallNate authored
128
e55356e @TooTallNate The rest of the src files formatting and whitespace fixes.
TooTallNate authored
129 return scope.Close(Integer::NewFromUnsigned(val));
ab0b75a @rbranson Tree (Re)organization; Added type aliases for common C types; StructType...
rbranson authored
130 }
131
23f4a3f @TooTallNate Rewrite FFIPrepCif() to be more readable.
TooTallNate authored
132 /**
133 * Function that creates and returns an `ffi_cif` pointer from the given return
134 * value type and argument types.
135 */
ab0b75a @rbranson Tree (Re)organization; Added type aliases for common C types; StructType...
rbranson authored
136
23f4a3f @TooTallNate Rewrite FFIPrepCif() to be more readable.
TooTallNate authored
137 Handle<Value> FFI::FFIPrepCif(const Arguments& args) {
138 HandleScope scope;
bd33583 @TooTallNate Remove *ALL* trailing whitespace.
TooTallNate authored
139
23f4a3f @TooTallNate Rewrite FFIPrepCif() to be more readable.
TooTallNate authored
140 unsigned int nargs;
141 Pointer *rtype, *atypes, *cif;
142 ffi_status status;
bd33583 @TooTallNate Remove *ALL* trailing whitespace.
TooTallNate authored
143
23f4a3f @TooTallNate Rewrite FFIPrepCif() to be more readable.
TooTallNate authored
144 if (args.Length() != 3) {
145 return THROW_ERROR_EXCEPTION("prepCif() requires 3 arguments!");
146 }
bd33583 @TooTallNate Remove *ALL* trailing whitespace.
TooTallNate authored
147
23f4a3f @TooTallNate Rewrite FFIPrepCif() to be more readable.
TooTallNate authored
148 nargs = args[0]->Uint32Value();
149 rtype = ObjectWrap::Unwrap<Pointer>(args[1]->ToObject());
150 atypes = ObjectWrap::Unwrap<Pointer>(args[2]->ToObject());
bd33583 @TooTallNate Remove *ALL* trailing whitespace.
TooTallNate authored
151
23f4a3f @TooTallNate Rewrite FFIPrepCif() to be more readable.
TooTallNate authored
152 cif = new Pointer(NULL);
153 cif->Alloc(sizeof(ffi_cif));
154
155 status = ffi_prep_cif(
e55356e @TooTallNate The rest of the src files formatting and whitespace fixes.
TooTallNate authored
156 (ffi_cif *)cif->GetPointer(),
157 FFI_DEFAULT_ABI,
158 nargs,
159 (ffi_type *)rtype->GetPointer(),
160 (ffi_type **)atypes->GetPointer());
23f4a3f @TooTallNate Rewrite FFIPrepCif() to be more readable.
TooTallNate authored
161
162 if (status != FFI_OK) {
163 delete cif;
164 return THROW_ERROR_EXCEPTION("ffi_prep_cif() returned error.");
165 }
166
167 return scope.Close(Pointer::WrapInstance(cif));
ab0b75a @rbranson Tree (Re)organization; Added type aliases for common C types; StructType...
rbranson authored
168 }
169
170 ///////////////
171
f5fc31f @TooTallNate I've been told this is good to have, for forwards compatibility.
TooTallNate authored
172 extern "C" {
173 static void init(Handle<Object> target) {
ab0b75a @rbranson Tree (Re)organization; Added type aliases for common C types; StructType...
rbranson authored
174 HandleScope scope;
f5fc31f @TooTallNate I've been told this is good to have, for forwards compatibility.
TooTallNate authored
175
ab0b75a @rbranson Tree (Re)organization; Added type aliases for common C types; StructType...
rbranson authored
176 Pointer::Initialize(target);
177 FFI::InitializeBindings(target);
178 FFI::InitializeStaticFunctions(target);
179 CallbackInfo::Initialize(target);
80032e8 @rbranson Added ForeignFunction class to wrap ffi_call() parameters so they don't ...
rbranson authored
180 ForeignCaller::Initialize(target);
f5fc31f @TooTallNate I've been told this is good to have, for forwards compatibility.
TooTallNate authored
181 }
182 NODE_MODULE(ffi_bindings, init);
ab0b75a @rbranson Tree (Re)organization; Added type aliases for common C types; StructType...
rbranson authored
183 }
Something went wrong with that request. Please try again.