gtk-webkit-ruby 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
{
|