gtk-webkit-ruby 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -2
- data/ext/webkit/extconf.rb +38 -1
- data/ext/webkit/javascript-type-convert.h +152 -0
- data/ext/webkit/javascript.h +284 -114
- data/ext/webkit/webkit.c +400 -35
- data/ext/webkit/webkit.cr +112 -2
- data/ext/webkit/webkit.rd +61 -0
- metadata +55 -63
data/Rakefile
CHANGED
@@ -22,10 +22,10 @@ spec = Gem::Specification.new do |s|
|
|
22
22
|
s.name = "gtk-webkit-ruby"
|
23
23
|
s.author = "Geoff Youngs"
|
24
24
|
s.email = "git@intersect-uk.co.uk"
|
25
|
-
s.version = "0.0.
|
25
|
+
s.version = "0.0.4"
|
26
26
|
s.homepage = "http://github.com/geoffyoungs/gtk-webkit-ruby"
|
27
27
|
s.summary = "Webkit bindings using rubber-generate"
|
28
|
-
s.add_dependency("rubber-generate", ">= 0.0.
|
28
|
+
s.add_dependency("rubber-generate", ">= 0.0.17")
|
29
29
|
s.platform = Gem::Platform::RUBY
|
30
30
|
s.extensions = FileList["ext/*/extconf.rb"]
|
31
31
|
s.files = FileList['ext/*/*.{c,h,cr,rd}'] + ['Rakefile', 'README.md']
|
data/ext/webkit/extconf.rb
CHANGED
@@ -1,9 +1,46 @@
|
|
1
1
|
require 'mkmf'
|
2
|
-
|
2
|
+
use_gems = false
|
3
|
+
begin
|
4
|
+
require 'mkmf-gnome2'
|
5
|
+
rescue LoadError
|
6
|
+
use_gems = true
|
7
|
+
end
|
8
|
+
|
9
|
+
if use_gems or Object.const_defined?('Gem')
|
10
|
+
require 'rubygems'
|
11
|
+
gem 'glib2'
|
12
|
+
require 'mkmf-gnome2'
|
13
|
+
%w[rbglib.h rbgtk.h rbpango.h rbatk.h].each do |header|
|
14
|
+
Gem.find_files(header).each do |f|
|
15
|
+
$CFLAGS += " '-I#{File.dirname(f)}'"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
%w[
|
20
|
+
glib2 gdk_pixbuf2 atk gtk2].each do |package|
|
21
|
+
require package
|
22
|
+
$CFLAGS += " -I"+Gem.loaded_specs[package].full_gem_path+"/ext/"+package
|
23
|
+
end
|
24
|
+
if RbConfig::CONFIG.has_key?('rubyhdrdir')
|
25
|
+
$CFLAGS += " -I" + RbConfig::CONFIG['rubyhdrdir']+'/ruby'
|
26
|
+
end
|
27
|
+
|
28
|
+
have_func("rb_errinfo")
|
3
29
|
PKGConfig.have_package("gtk+-2.0") or exit(-1)
|
4
30
|
PKGConfig.have_package("webkit-1.0") or exit(-1)
|
31
|
+
have_header("dlfcn.h") or exit(-1)
|
32
|
+
have_header("errno.h") or exit(-1)
|
33
|
+
have_header("ffi.h") or exit(-1)
|
34
|
+
have_header("rbgobject.h") or exit(-1)
|
35
|
+
have_header("sys/mman.h") or exit(-1)
|
36
|
+
have_header("intern.h") or exit(-1)
|
5
37
|
have_header("webkit/webkit.h") or exit(-1)
|
38
|
+
have_header("webkit/webkitenumtypes.h") or exit(-1)
|
6
39
|
have_header("JavaScriptCore/JavaScript.h") or exit(-1)
|
40
|
+
have_library("dl") or exit(-1)
|
41
|
+
$LIBS += " -ldl"
|
42
|
+
have_library("ffi") or exit(-1)
|
43
|
+
$LIBS += " -lffi"
|
7
44
|
|
8
45
|
STDOUT.print("checking for new allocation framework... ") # for ruby-1.7
|
9
46
|
if Object.respond_to? :allocate
|
@@ -0,0 +1,152 @@
|
|
1
|
+
static JSValueRef
|
2
|
+
convert_string_to_jsval(JSContextRef ctx, char *str) {
|
3
|
+
JSStringRef js_s_ref;
|
4
|
+
JSValueRef js_val_ref;
|
5
|
+
|
6
|
+
js_s_ref = JSStringCreateWithUTF8CString(str);
|
7
|
+
js_val_ref = JSValueMakeString(ctx, js_s_ref);
|
8
|
+
JSStringRelease(js_s_ref);
|
9
|
+
|
10
|
+
return js_val_ref;
|
11
|
+
}
|
12
|
+
|
13
|
+
static char *jsstrref_to_charp(JSStringRef str, size_t *out_len)
|
14
|
+
{
|
15
|
+
size_t max = 0, len;
|
16
|
+
char *buf;
|
17
|
+
|
18
|
+
max = JSStringGetMaximumUTF8CStringSize(str);
|
19
|
+
buf = malloc(max);
|
20
|
+
len = JSStringGetUTF8CString(str, buf, max);
|
21
|
+
|
22
|
+
if (out_len) {
|
23
|
+
*out_len = len;
|
24
|
+
}
|
25
|
+
|
26
|
+
return buf;
|
27
|
+
}
|
28
|
+
|
29
|
+
static char *
|
30
|
+
convert_javascript_to_utf8_string(JSContextRef ctx, JSValueRef val, size_t* out_len)
|
31
|
+
{
|
32
|
+
JSStringRef str = JSValueToStringCopy(ctx, val, NULL);
|
33
|
+
char *buf;
|
34
|
+
|
35
|
+
buf = jsstrref_to_charp(str, out_len);
|
36
|
+
|
37
|
+
JSStringRelease(str);
|
38
|
+
|
39
|
+
return buf;
|
40
|
+
}
|
41
|
+
|
42
|
+
static ID
|
43
|
+
convert_javascript_to_intern(JSStringRef str)
|
44
|
+
{
|
45
|
+
ID id;
|
46
|
+
size_t max = 0, len;
|
47
|
+
char *buf;
|
48
|
+
|
49
|
+
max = JSStringGetMaximumUTF8CStringSize(str);
|
50
|
+
buf = malloc(max);
|
51
|
+
len = JSStringGetUTF8CString(str, buf, max);
|
52
|
+
buf[len-1] = 0;
|
53
|
+
id = rb_intern(buf);
|
54
|
+
|
55
|
+
free(buf);
|
56
|
+
|
57
|
+
return id;
|
58
|
+
}
|
59
|
+
|
60
|
+
static inline VALUE conv_jsstrref_to_value(JSStringRef str)
|
61
|
+
{
|
62
|
+
VALUE output = Qnil;
|
63
|
+
size_t len = 0, max = 0;
|
64
|
+
char *buf;
|
65
|
+
|
66
|
+
max = JSStringGetMaximumUTF8CStringSize(str);
|
67
|
+
buf = malloc(max);
|
68
|
+
len = JSStringGetUTF8CString(str, buf, max);
|
69
|
+
|
70
|
+
output = rb_str_new(buf, len-1); // Ignore terminator
|
71
|
+
|
72
|
+
free(buf);
|
73
|
+
|
74
|
+
return output;
|
75
|
+
|
76
|
+
}
|
77
|
+
|
78
|
+
static inline VALUE
|
79
|
+
convert_javascript_string_to_ruby(JSContextRef ctx, JSValueRef val)
|
80
|
+
{
|
81
|
+
VALUE output = Qnil;
|
82
|
+
JSStringRef str;
|
83
|
+
|
84
|
+
str = JSValueToStringCopy(ctx, val, NULL);
|
85
|
+
|
86
|
+
output = conv_jsstrref_to_value(str);
|
87
|
+
|
88
|
+
JSStringRelease(str);
|
89
|
+
|
90
|
+
return output;
|
91
|
+
}
|
92
|
+
|
93
|
+
static VALUE
|
94
|
+
convert_javascript_to_ruby(JSContextRef ctx, JSValueRef val)
|
95
|
+
{
|
96
|
+
VALUE output = Qnil;
|
97
|
+
JSValueRef *_exception = NULL;
|
98
|
+
|
99
|
+
switch (JSValueGetType(ctx, val)) {
|
100
|
+
case kJSTypeUndefined:
|
101
|
+
case kJSTypeNull:
|
102
|
+
output = Qnil;
|
103
|
+
break;
|
104
|
+
case kJSTypeBoolean:
|
105
|
+
output = JSValueToBoolean(ctx, val) ? Qtrue : Qfalse;
|
106
|
+
break;
|
107
|
+
case kJSTypeNumber:
|
108
|
+
output = rb_float_new(JSValueToNumber(ctx, val, _exception));
|
109
|
+
break;
|
110
|
+
case kJSTypeString:
|
111
|
+
output = convert_javascript_string_to_ruby(ctx, val);
|
112
|
+
break;
|
113
|
+
case kJSTypeObject:
|
114
|
+
output = convert_javascript_string_to_ruby(ctx, val);
|
115
|
+
break;
|
116
|
+
}
|
117
|
+
|
118
|
+
return output;
|
119
|
+
}
|
120
|
+
|
121
|
+
|
122
|
+
static JSValueRef
|
123
|
+
convert_ruby_to_javascript(JSContextRef ctx, VALUE value)
|
124
|
+
{
|
125
|
+
JSStringRef str;
|
126
|
+
JSValueRef jsval;
|
127
|
+
|
128
|
+
switch (TYPE(value)) {
|
129
|
+
case T_FIXNUM:
|
130
|
+
return JSValueMakeNumber(ctx, (double) FIX2LONG(value));
|
131
|
+
case T_FLOAT:
|
132
|
+
return JSValueMakeNumber(ctx, (double) NUM2DBL(value));
|
133
|
+
case T_BIGNUM:
|
134
|
+
return JSValueMakeNumber(ctx, (double) rb_big2long(value));
|
135
|
+
case T_TRUE:
|
136
|
+
case T_FALSE:
|
137
|
+
return JSValueMakeBoolean(ctx, RTEST(value));
|
138
|
+
case T_UNDEF:
|
139
|
+
return JSValueMakeUndefined(ctx);
|
140
|
+
case T_NIL:
|
141
|
+
return JSValueMakeNull(ctx);
|
142
|
+
default:
|
143
|
+
if (TYPE(value) != T_STRING) {
|
144
|
+
value = rb_funcall(value, rb_intern("to_s"), 0);
|
145
|
+
}
|
146
|
+
str = JSStringCreateWithUTF8CString(RSTRING_PTR(value));
|
147
|
+
jsval = JSValueMakeString(ctx, str);
|
148
|
+
JSStringRelease(str);
|
149
|
+
return jsval;
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
data/ext/webkit/javascript.h
CHANGED
@@ -1,9 +1,19 @@
|
|
1
1
|
#include <alloca.h>
|
2
|
+
#include "javascript-type-convert.h"
|
2
3
|
|
3
4
|
#define STRINGIZE(s) #s
|
4
5
|
|
5
6
|
#define JS_fn(f) _JS_fn(ctx, STRINGIZE(f), f)
|
6
7
|
|
8
|
+
|
9
|
+
typedef struct {
|
10
|
+
JSClassDefinition definition;
|
11
|
+
JSClassRef class_ref;
|
12
|
+
VALUE rbObject;
|
13
|
+
JSContextRef ctx;
|
14
|
+
} ruby_js_class_def;
|
15
|
+
static ruby_js_class_def *jsrb_newClass(VALUE robject);
|
16
|
+
|
7
17
|
JSObjectRef _JS_fn(JSContextRef ctx, const char *name, JSObjectCallAsFunctionCallback f)
|
8
18
|
{
|
9
19
|
JSStringRef nameStr = JSStringCreateWithUTF8CString(name);
|
@@ -27,118 +37,6 @@ js_obj_set_value(JSContextRef ctx, JSObjectRef object, char *name, JSObjectRef v
|
|
27
37
|
return true;
|
28
38
|
}
|
29
39
|
|
30
|
-
static JSValueRef
|
31
|
-
convert_string_to_jsval(JSContextRef ctx, char *str) {
|
32
|
-
JSStringRef js_s_ref;
|
33
|
-
JSValueRef js_val_ref;
|
34
|
-
|
35
|
-
js_s_ref = JSStringCreateWithUTF8CString(str);
|
36
|
-
js_val_ref = JSValueMakeString(ctx, js_s_ref);
|
37
|
-
JSStringRelease(js_s_ref);
|
38
|
-
|
39
|
-
return js_val_ref;
|
40
|
-
}
|
41
|
-
|
42
|
-
static char *
|
43
|
-
convert_javascript_to_utf8_string(JSContextRef ctx, JSValueRef val, size_t* out_len)
|
44
|
-
{
|
45
|
-
JSStringRef str = JSValueToStringCopy(ctx, val, NULL);
|
46
|
-
size_t max = 0, len;
|
47
|
-
char *buf;
|
48
|
-
|
49
|
-
max = JSStringGetMaximumUTF8CStringSize(str);
|
50
|
-
buf = malloc(max);
|
51
|
-
len = JSStringGetUTF8CString(str, buf, max);
|
52
|
-
|
53
|
-
if (out_len) {
|
54
|
-
*out_len = len;
|
55
|
-
}
|
56
|
-
|
57
|
-
JSStringRelease(str);
|
58
|
-
|
59
|
-
return buf;
|
60
|
-
}
|
61
|
-
|
62
|
-
static inline VALUE
|
63
|
-
convert_javascript_string_to_ruby(JSContextRef ctx, JSValueRef val)
|
64
|
-
{
|
65
|
-
VALUE output = Qnil;
|
66
|
-
JSStringRef str;
|
67
|
-
size_t len = 0, max = 0;
|
68
|
-
char *buf;
|
69
|
-
|
70
|
-
str = JSValueToStringCopy(ctx, val, NULL);
|
71
|
-
max = JSStringGetMaximumUTF8CStringSize(str);
|
72
|
-
buf = malloc(max);
|
73
|
-
len = JSStringGetUTF8CString(str, buf, max);
|
74
|
-
|
75
|
-
output = rb_str_new(buf, len-1); // Ignore terminator
|
76
|
-
|
77
|
-
free(buf);
|
78
|
-
JSStringRelease(str);
|
79
|
-
|
80
|
-
return output;
|
81
|
-
}
|
82
|
-
|
83
|
-
static VALUE
|
84
|
-
convert_javascript_to_ruby(JSContextRef ctx, JSValueRef val)
|
85
|
-
{
|
86
|
-
VALUE output = Qnil;
|
87
|
-
JSValueRef *_exception = NULL;
|
88
|
-
|
89
|
-
switch (JSValueGetType(ctx, val)) {
|
90
|
-
case kJSTypeUndefined:
|
91
|
-
case kJSTypeNull:
|
92
|
-
output = Qnil;
|
93
|
-
break;
|
94
|
-
case kJSTypeBoolean:
|
95
|
-
output = JSValueToBoolean(ctx, val) ? Qtrue : Qfalse;
|
96
|
-
break;
|
97
|
-
case kJSTypeNumber:
|
98
|
-
output = rb_float_new(JSValueToNumber(ctx, val, _exception));
|
99
|
-
break;
|
100
|
-
case kJSTypeString:
|
101
|
-
output = convert_javascript_string_to_ruby(ctx, val);
|
102
|
-
break;
|
103
|
-
case kJSTypeObject:
|
104
|
-
output = convert_javascript_string_to_ruby(ctx, val);
|
105
|
-
break;
|
106
|
-
}
|
107
|
-
|
108
|
-
return output;
|
109
|
-
}
|
110
|
-
|
111
|
-
|
112
|
-
static JSValueRef
|
113
|
-
convert_ruby_to_javascript(JSContextRef ctx, VALUE value)
|
114
|
-
{
|
115
|
-
JSStringRef str;
|
116
|
-
JSValueRef jsval;
|
117
|
-
|
118
|
-
switch (TYPE(value)) {
|
119
|
-
case T_FIXNUM:
|
120
|
-
return JSValueMakeNumber(ctx, (double) FIX2LONG(value));
|
121
|
-
case T_FLOAT:
|
122
|
-
return JSValueMakeNumber(ctx, (double) NUM2DBL(value));
|
123
|
-
case T_BIGNUM:
|
124
|
-
return JSValueMakeNumber(ctx, (double) rb_big2long(value));
|
125
|
-
case T_TRUE:
|
126
|
-
case T_FALSE:
|
127
|
-
return JSValueMakeBoolean(ctx, RTEST(value));
|
128
|
-
case T_UNDEF:
|
129
|
-
return JSValueMakeUndefined(ctx);
|
130
|
-
case T_NIL:
|
131
|
-
return JSValueMakeNull(ctx);
|
132
|
-
default:
|
133
|
-
if (TYPE(value) != T_STRING) {
|
134
|
-
value = rb_funcall(value, rb_intern("to_s"), 0);
|
135
|
-
}
|
136
|
-
str = JSStringCreateWithUTF8CString(RSTRING_PTR(value));
|
137
|
-
jsval = JSValueMakeString(ctx, str);
|
138
|
-
JSStringRelease(str);
|
139
|
-
return jsval;
|
140
|
-
}
|
141
|
-
}
|
142
40
|
|
143
41
|
static JSValueRef
|
144
42
|
js_call_ruby_eval (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
|
@@ -178,8 +76,6 @@ js_ruby_fn(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
|
|
178
76
|
ruby_fn = (VALUE)g_hash_table_lookup(ruby_fns, (gpointer)function);
|
179
77
|
}
|
180
78
|
|
181
|
-
//printf("Hmm. Found: %p\n", function);
|
182
|
-
|
183
79
|
for (i = 0; i < argumentCount; i++) {
|
184
80
|
args[i] = convert_javascript_to_ruby(ctx, arguments[i]);
|
185
81
|
}
|
@@ -192,9 +88,283 @@ js_ruby_fn(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
|
|
192
88
|
return retval;
|
193
89
|
}
|
194
90
|
|
91
|
+
static void jsrb_class_init(JSContextRef ctx, JSObjectRef object)
|
92
|
+
{
|
93
|
+
// Do something here?
|
94
|
+
}
|
95
|
+
|
96
|
+
static void jsrb_class_final(JSObjectRef object) {
|
97
|
+
// Clean up?
|
98
|
+
VALUE robject = JSObjectGetPrivate(object);
|
99
|
+
if (RTEST(robject)) {
|
100
|
+
ruby_js_class_def *def = (ruby_js_class_def*)DATA_PTR(rb_iv_get(robject, "_js_ref"));
|
101
|
+
rb_iv_set(robject, "_js_ref", Qnil);
|
102
|
+
free(def);
|
103
|
+
RUBYFUNC_DEL(object);
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Heuristic:
|
109
|
+
* - return true if obj.respond_to?(property) # i.e. method
|
110
|
+
* - return true if obj.respond_to?("#{property}=") # ie. setter
|
111
|
+
* - return true if obj.instance_variables.includj?("@#{property}") # ? maybe ?
|
112
|
+
*/
|
113
|
+
|
114
|
+
static bool jsrb_has_prop(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
|
115
|
+
{
|
116
|
+
VALUE robject = JSObjectGetPrivate(object);
|
117
|
+
|
118
|
+
if (RTEST(robject)) {
|
119
|
+
ID prop = convert_javascript_to_intern(propertyName);
|
120
|
+
if (rb_respond_to(robject, prop)) {
|
121
|
+
return true;
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
return false;
|
126
|
+
}
|
127
|
+
|
128
|
+
|
129
|
+
/**
|
130
|
+
* Heuristic:
|
131
|
+
* - return method(property) if obj.method(property).arity > 0
|
132
|
+
* - return send(property) if obj.respond_to?("#{property}=") # ie. setter - implemented as property
|
133
|
+
* - return send(property) if obj.instance_variables.includj?("@#{property}") # ? maybe ?
|
134
|
+
* - return send(property) if obj.respond_to?(property) # i.e. method
|
135
|
+
*/
|
136
|
+
|
137
|
+
static JSObjectRef jsrb_get_prop(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
|
138
|
+
{
|
139
|
+
VALUE robject = JSObjectGetPrivate(object);
|
140
|
+
|
141
|
+
if (RTEST(robject)) {
|
142
|
+
ID prop = convert_javascript_to_intern(propertyName);
|
143
|
+
if (rb_respond_to(robject, prop)) {
|
144
|
+
VALUE rbo = rb_funcall(robject, rb_intern("method"), 1, conv_jsstrref_to_value(propertyName));
|
145
|
+
ruby_js_class_def *def = jsrb_newClass(rbo);
|
146
|
+
def->ctx = ctx;
|
147
|
+
return JSObjectMake(def->ctx, def->class_ref, (void*)rbo);
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
return false;
|
152
|
+
}
|
153
|
+
|
154
|
+
static bool jsrb_set_prop(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
|
155
|
+
{
|
156
|
+
return false;
|
157
|
+
}
|
158
|
+
|
159
|
+
static bool jsrb_del_prop(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
|
160
|
+
{
|
161
|
+
return false;
|
162
|
+
}
|
163
|
+
|
164
|
+
static void jsrb_get_prop_names(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames)
|
165
|
+
{
|
166
|
+
}
|
167
|
+
|
168
|
+
static JSValueRef jsrb_call_fn(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
|
169
|
+
{
|
170
|
+
//
|
171
|
+
VALUE robject = JSObjectGetPrivate(function);
|
172
|
+
VALUE self = JSObjectGetPrivate(thisObject);
|
173
|
+
if (RTEST(robject)) {
|
174
|
+
VALUE rbo = rb_funcall2(robject, rb_intern("call"), 0, NULL);
|
175
|
+
JSValueRef retval = convert_ruby_to_javascript(ctx, rbo);
|
176
|
+
return retval;
|
177
|
+
}
|
178
|
+
return JSValueMakeUndefined(ctx);
|
179
|
+
}
|
180
|
+
|
181
|
+
typedef struct {
|
182
|
+
JSContextRef ctx;
|
183
|
+
JSObjectRef constructor;
|
184
|
+
size_t argumentCount;
|
185
|
+
JSValueRef *arguments;
|
186
|
+
JSValueRef* exception;
|
187
|
+
} construct_args;
|
188
|
+
|
189
|
+
static JSObjectRef wrapRubyObject(JSContextRef ctx, VALUE value)
|
190
|
+
{
|
191
|
+
ruby_js_class_def *def;
|
192
|
+
JSObjectRef object;
|
193
|
+
|
194
|
+
def = jsrb_newClass(value);
|
195
|
+
def->ctx = ctx;
|
196
|
+
rb_iv_set(value, "_js_ref", Data_Wrap_Struct(cJsPtr, NULL, NULL, def));
|
197
|
+
object = JSObjectMake(ctx, def->class_ref, value);
|
198
|
+
return object;
|
199
|
+
}
|
200
|
+
|
201
|
+
static void jsrb_class_construct_ffi(ffi_cif* cif,
|
202
|
+
void** resp,
|
203
|
+
void** vargs,
|
204
|
+
void* userdata) {
|
205
|
+
|
206
|
+
ruby_js_class_def *def = (ruby_js_class_def*)userdata;
|
207
|
+
construct_args *args = (construct_args*)vargs;
|
208
|
+
|
209
|
+
{
|
210
|
+
int no_args = 0;
|
211
|
+
VALUE *arg_list = NULL;
|
212
|
+
JSObjectRef object;
|
213
|
+
VALUE value = Qnil;
|
214
|
+
|
215
|
+
|
216
|
+
if (is_ruby_native_thread()) {
|
217
|
+
value = rb_class_new_instance(no_args, arg_list, def->rbObject);
|
218
|
+
// Convert JS values...
|
219
|
+
|
220
|
+
RUBYFUNC_ADD(value);
|
221
|
+
}
|
222
|
+
|
223
|
+
|
224
|
+
object = JSObjectMake(def->ctx, def->class_ref, (void*)value);
|
225
|
+
|
226
|
+
|
227
|
+
*resp = (void*)object;
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
|
232
|
+
static JSObjectRef jsrb_call_create(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
|
233
|
+
{
|
234
|
+
int no_args = 0;
|
235
|
+
VALUE *arg_list = NULL;
|
236
|
+
JSObjectRef object;
|
237
|
+
VALUE value = Qnil;
|
238
|
+
|
239
|
+
VALUE robject = JSObjectGetPrivate(constructor);
|
240
|
+
|
241
|
+
if (RTEST(robject)) {
|
242
|
+
value = rb_class_new_instance(no_args, arg_list, robject);
|
243
|
+
RUBYFUNC_ADD(value);
|
244
|
+
|
245
|
+
return wrapRubyObject(ctx, value);
|
246
|
+
}
|
247
|
+
|
248
|
+
return NULL;
|
249
|
+
}
|
250
|
+
|
251
|
+
static bool jsrb_has_instance(JSContextRef ctx, JSObjectRef constructor, JSValueRef possibleInstance, JSValueRef* exception)
|
252
|
+
{
|
253
|
+
return false;
|
254
|
+
}
|
255
|
+
|
256
|
+
static JSValueRef jsrb_convert(JSContextRef ctx, JSObjectRef object, JSType type, JSValueRef* exception)
|
257
|
+
{
|
258
|
+
return false;
|
259
|
+
}
|
260
|
+
|
261
|
+
static ruby_js_class_def *jsrb_newClass(VALUE robject) {
|
262
|
+
JSClassDefinition *jclass;
|
263
|
+
ruby_js_class_def *def;
|
264
|
+
|
265
|
+
def = ALLOC_N(ruby_js_class_def,1);
|
266
|
+
def->definition = kJSClassDefinitionEmpty;
|
267
|
+
jclass = &(def->definition);
|
268
|
+
|
269
|
+
jclass->version = 0;
|
270
|
+
jclass->attributes = kJSClassAttributeNoAutomaticPrototype;
|
271
|
+
|
272
|
+
// Check this? It should probably be a valid JS name...
|
273
|
+
|
274
|
+
// ignore
|
275
|
+
// staticValues
|
276
|
+
// staticFunctions
|
277
|
+
|
278
|
+
/* Basics */
|
279
|
+
jclass->initialize = jsrb_class_init;
|
280
|
+
|
281
|
+
jclass->finalize = jsrb_class_final;
|
282
|
+
|
283
|
+
/* Property accessors... */
|
284
|
+
jclass->hasProperty = jsrb_has_prop;
|
285
|
+
jclass->getProperty = jsrb_get_prop;
|
286
|
+
jclass->setProperty = jsrb_set_prop;
|
287
|
+
jclass->deleteProperty = jsrb_del_prop;
|
288
|
+
jclass->getPropertyNames = jsrb_get_prop_names;
|
289
|
+
|
290
|
+
/* Function */
|
291
|
+
//rb_p(robject);
|
292
|
+
if (rb_respond_to(robject, rb_intern("call"))) {
|
293
|
+
jclass->callAsFunction = jsrb_call_fn;
|
294
|
+
} else {
|
295
|
+
|
296
|
+
jclass->callAsFunction = NULL;
|
297
|
+
}
|
298
|
+
|
299
|
+
if (rb_obj_is_instance_of(robject, rb_cClass)) {
|
300
|
+
jclass->className = rb_class2name(robject);
|
301
|
+
jclass->callAsConstructor = jsrb_call_create;
|
302
|
+
/*ffi_cif *cif;
|
303
|
+
ffi_closure *closure;
|
304
|
+
void *code;
|
305
|
+
ffi_type **types;
|
306
|
+
int args_len = 5;
|
307
|
+
|
308
|
+
cif = ALLOC_N(ffi_cif, 1);
|
309
|
+
closure = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
310
|
+
types = ALLOC_N(ffi_type*, args_len);
|
311
|
+
|
312
|
+
types[0] = &ffi_type_pointer;
|
313
|
+
types[1] = &ffi_type_pointer;
|
314
|
+
types[2] = &ffi_type_uint32;
|
315
|
+
types[3] = &ffi_type_pointer;
|
316
|
+
types[4] = &ffi_type_pointer;
|
317
|
+
|
318
|
+
if (ffi_prep_cif(cif, FFI_DEFAULT_ABI, args_len, &ffi_type_pointer, types) == FFI_OK) {
|
319
|
+
if (ffi_prep_closure_loc(closure, cif, jsrb_class_construct_ffi, (void*)def, code) == FFI_OK) {
|
320
|
+
jclass->callAsConstructor = closure;
|
321
|
+
}
|
322
|
+
}*/
|
323
|
+
} else {
|
324
|
+
jclass->className = rb_class2name(rb_obj_class(robject));
|
325
|
+
jclass->callAsConstructor = NULL;
|
326
|
+
}
|
327
|
+
|
328
|
+
//jclass->callAsConstructor = jsrb_call_create;
|
329
|
+
jclass->hasInstance = jsrb_has_instance;
|
330
|
+
jclass->convertToType = jsrb_convert;
|
331
|
+
|
332
|
+
def->rbObject = robject;
|
333
|
+
def->class_ref = JSClassCreate(jclass);
|
334
|
+
|
335
|
+
return def;
|
336
|
+
}
|
337
|
+
|
338
|
+
/*static void jsrb_create_class(VALUE robject) {
|
339
|
+
//JSClassDefinition *def = jsrb_newClass(robject);
|
340
|
+
}*/
|
341
|
+
|
342
|
+
|
343
|
+
|
344
|
+
|
195
345
|
/**
|
196
346
|
* Javascript functions called directly from binding
|
197
347
|
**/
|
348
|
+
static void javascript_add_class(JSGlobalContextRef ctx, char *name, VALUE robject)
|
349
|
+
{
|
350
|
+
JSObjectRef global = JSContextGetGlobalObject(ctx), object;
|
351
|
+
|
352
|
+
// Should we store this on the class?
|
353
|
+
/* VALUE v = Qfalse;
|
354
|
+
ruby_js_class_def *def;
|
355
|
+
|
356
|
+
if (0 && RTEST(v = rb_iv_get(robject, "_js_ref"))) {
|
357
|
+
def = (ruby_js_class_def*)v;
|
358
|
+
} else {
|
359
|
+
def = jsrb_newClass(robject);
|
360
|
+
def->ctx = ctx;
|
361
|
+
rb_iv_set(robject, "_js_ref", (VALUE)def);
|
362
|
+
}*/
|
363
|
+
|
364
|
+
/* object = JSObjectMake(ctx, def->class_ref, NULL);*/
|
365
|
+
|
366
|
+
js_obj_set_value(ctx, global, name, wrapRubyObject(ctx, robject)); // Check failure?
|
367
|
+
}
|
198
368
|
static void *
|
199
369
|
javascript_add_ruby_fn(JSGlobalContextRef ctx, char *name, VALUE ruby_fn)
|
200
370
|
{
|