Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 611 lines (465 sloc) 18.664 kB
e18f74d @jbarnette Renaming proxies for clarity.
authored
1 #include "js_land_proxy.h"
dc42336 @matthewd Deal with a couple of minor warnings.
matthewd authored
2 #include "conversions.h"
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
3
4 static JSBool get(JSContext* js_context, JSObject* obj, jsval id, jsval* retval);
5 static JSBool set(JSContext* context, JSObject* obj, jsval id, jsval* retval);
b77b3ad @jbarnette Make sure multiple proxy classes are supported.
authored
6 static JSBool construct(JSContext* js_context, JSObject* obj, uintN argc, jsval* argv, jsval* retval);
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
7 static JSBool resolve(JSContext *js_context, JSObject *obj, jsval id, uintN flags, JSObject **objp);
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
8 static JSBool call(JSContext* js_context, JSObject* obj, uintN argc, jsval* argv, jsval* retval);
b77b3ad @jbarnette Make sure multiple proxy classes are supported.
authored
9 static void finalize(JSContext* context, JSObject* obj);
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
10
510f1b5 @jbarnette Fix some vestigal renaming issues.
authored
11 static JSClass JSLandProxyClass = {
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
12 "JSLandProxy", JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
13 JS_PropertyStub,
14 JS_PropertyStub,
15 get,
16 set,
17 JS_EnumerateStub,
d3286d8 @jbarnette Fixing compiler warnings.
authored
18 (JSResolveOp) resolve,
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
19 JS_ConvertStub,
20 finalize
21 };
22
b77b3ad @jbarnette Make sure multiple proxy classes are supported.
authored
23 static JSClass JSLandClassProxyClass = {
24 "JSLandClassProxy", JSCLASS_HAS_PRIVATE,
25 JS_PropertyStub,
26 JS_PropertyStub,
27 get,
28 set,
29 JS_EnumerateStub,
30 JS_ResolveStub,
31 JS_ConvertStub,
32 finalize,
33 NULL,
34 NULL,
35 NULL,
36 construct
37 };
38
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
39 static JSClass JSLandCallableProxyClass = {
40 "JSLandCallableProxy", JSCLASS_HAS_PRIVATE,
41 JS_PropertyStub,
42 JS_PropertyStub,
f518879 @jbarnette Any Rubyland object that responds to call can be called as a function…
authored
43 get,
44 set,
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
45 JS_EnumerateStub,
46 JS_ResolveStub,
47 JS_ConvertStub,
48 finalize,
49 NULL,
50 NULL,
51 call
52 };
53
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
54 static VALUE call_ruby_from_js_invoke(VALUE args)
55 {
56 VALUE self = rb_ary_pop(args);
57 VALUE id = rb_ary_pop(args);
58 return rb_apply(self, SYM2ID(id), args);
59 }
60
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
61 JSBool call_ruby_from_js_va(JohnsonRuntime* runtime, VALUE* result, VALUE self, ID id, int argc, va_list va)
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
62 {
63 VALUE old_errinfo = ruby_errinfo;
e763385 @matthewd Resolve segfaults & warnings when sizeof(jsint) < sizeof(long).
matthewd authored
64 VALUE args = rb_ary_new2((long)argc + 2);
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
65
e763385 @matthewd Resolve segfaults & warnings when sizeof(jsint) < sizeof(long).
matthewd authored
66 long i;
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
67 for(i = 0; i < argc; i++)
68 rb_ary_store(args, i, va_arg(va, VALUE));
69
e763385 @matthewd Resolve segfaults & warnings when sizeof(jsint) < sizeof(long).
matthewd authored
70 rb_ary_store(args, (long)argc, ID2SYM(id));
71 rb_ary_store(args, (long)argc + 1, self);
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
72
73 int state;
74 *result = rb_protect(call_ruby_from_js_invoke, args, &state);
75
15f8763 @matthewd Deal with a couple of places that Ruby exceptions can leak through JS…
matthewd authored
76 if (state)
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
77 return report_ruby_error_in_js(runtime, state, old_errinfo);
15f8763 @matthewd Deal with a couple of places that Ruby exceptions can leak through JS…
matthewd authored
78
79 return JS_TRUE;
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
80 }
81
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
82 JSBool call_ruby_from_js(JohnsonRuntime* runtime, jsval* retval, VALUE self, ID id, int argc, ...)
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
83 {
84 VALUE result;
85 va_list va;
86 va_start(va, argc);
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
87 JSBool okay = call_ruby_from_js_va(runtime, &result, self, id, argc, va);
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
88 va_end(va);
89 if (!okay) return JS_FALSE;
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
90 return retval ? convert_to_js(runtime, result, retval) : JS_TRUE;
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
91 }
92
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
93 JSBool call_ruby_from_js2(JohnsonRuntime* runtime, VALUE* retval, VALUE self, ID id, int argc, ...)
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
94 {
95 va_list va;
96 va_start(va, argc);
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
97 JSBool okay = call_ruby_from_js_va(runtime, retval, self, id, argc, va);
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
98 va_end(va);
99 return okay;
100 }
101
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
102 static bool autovivified_p(VALUE UNUSED(ruby_context), VALUE self, char* name)
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
103 {
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
104 return RTEST(rb_funcall(Johnson_SpiderMonkey_JSLandProxy(), rb_intern("autovivified?"), 2,
105 self, rb_str_new2(name)));
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
106 }
107
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
108 static bool const_p(VALUE self, char* name)
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
109 {
c1b88cc @jbarnette Revert "Ruby.Class.prototype, not totally robust."
authored
110 return rb_obj_is_kind_of(self, rb_cModule)
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
111 && rb_is_const_id(rb_intern(name))
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
112 && RTEST( rb_funcall(self, rb_intern("const_defined?"), 1, ID2SYM(rb_intern(name))) );
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
113 }
114
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
115 static bool global_p(char* name)
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
116 {
c6ea599 @matthewd Use direct pointers in the hash tables etc, and just Root values we n…
matthewd authored
117 return *name == '$' && rb_ary_includes(rb_f_global_variables(), rb_str_new2(name));
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
118 }
119
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
120 static bool method_p(VALUE self, char* name)
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
121 {
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
122 return RTEST( rb_funcall(self, rb_intern("respond_to?"), 1, ID2SYM(rb_intern(name))) );
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
123 }
124
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
125 static bool attribute_p(VALUE self, char* name)
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
126 {
127 if (!method_p(self, name))
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
128 return false;
5447b86 @matthewd Be a little more certain that we've got a METHOD* before we poke it.
matthewd authored
129
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
130 VALUE rb_id = rb_intern(name);
131 VALUE rb_method = rb_funcall(self, rb_intern("method"), 1, ID2SYM(rb_id));
132
5447b86 @matthewd Be a little more certain that we've got a METHOD* before we poke it.
matthewd authored
133 if (TYPE(rb_method) == T_DATA)
134 {
135 VALUE klass = CLASS_OF(rb_method);
136 if (klass == rb_cMethod)
137 {
138 METHOD* method;
139 Data_Get_Struct(rb_method, METHOD, method);
140
141 if (method && nd_type(method->body) == NODE_IVAR)
142 return true;
143 }
144 }
145
146 return RTEST(rb_funcall(Johnson_SpiderMonkey_JSLandProxy(),
147 rb_intern("js_property?"), 2, self, ID2SYM(rb_id)));
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
148 }
149
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
150 static bool indexable_p(VALUE self)
e0d5bf2 @jbarnette Simple implementation for working numeric array indexes.
authored
151 {
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
152 return RTEST(rb_funcall(self, rb_intern("respond_to?"), 1, ID2SYM(rb_intern("[]"))));
e0d5bf2 @jbarnette Simple implementation for working numeric array indexes.
authored
153 }
154
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
155 static bool has_key_p(VALUE self, char* name)
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
156 {
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
157 return RTEST(rb_funcall(self, rb_intern("respond_to?"), 1, ID2SYM(rb_intern("[]"))))
158 && RTEST(rb_funcall(self, rb_intern("respond_to?"), 1, ID2SYM(rb_intern("key?"))))
159 && RTEST(rb_funcall(self, rb_intern("key?"), 1, rb_str_new2(name)));
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
160 }
161
0746d92 @matthewd Use C99 bool for simple conditionals, and JSBool only for JS engine.
matthewd authored
162 static bool respond_to_p(JSContext* js_context, JSObject* obj, char* name)
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
163 {
97b8244 @matthewd Root everything in sight.
matthewd authored
164 VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context);
165
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
166 JohnsonContext* context;
167 Data_Get_Struct(ruby_context, JohnsonContext, context);
97b8244 @matthewd Root everything in sight.
matthewd authored
168
169 VALUE self = (VALUE)JS_GetInstancePrivate(
170 context->js, obj, JS_GET_CLASS(context->js, obj), NULL);
171
172 if (!self) return false;
173
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
174 return autovivified_p(ruby_context, self, name)
175 || const_p(self, name)
176 || global_p(name)
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
177 || attribute_p(self, name)
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
178 || method_p(self, name)
179 || has_key_p(self, name);
180 }
181
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
182 static jsval evaluate_js_property_expression(JohnsonRuntime * runtime, const char * property, jsval* retval) {
183 JSContext * context = johnson_get_current_context(runtime);
e763385 @matthewd Resolve segfaults & warnings when sizeof(jsint) < sizeof(long).
matthewd authored
184 assert(strlen(property) < INT_MAX);
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
185 return JS_EvaluateScript(context, runtime->global,
e763385 @matthewd Resolve segfaults & warnings when sizeof(jsint) < sizeof(long).
matthewd authored
186 property, (unsigned int)strlen(property), "johnson:evaluate_js_property_expression", 1,
bda2acd @matthewd Merged up to removal of vendor/spidermonkey.
matthewd authored
187 retval);
63b6e8d @tenderlove reducing the iterator code
tenderlove authored
188 }
189
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
190 static JSBool get(JSContext* js_context, JSObject* obj, jsval id, jsval* retval)
191 {
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
192 // pull out our Ruby context, which is embedded in js_context
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
193
97b8244 @matthewd Root everything in sight.
matthewd authored
194 VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context);
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
195
196 // get our struct, which is embedded in ruby_context
197
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
198 JohnsonContext* context;
199 JohnsonRuntime* runtime;
200 Data_Get_Struct(ruby_context, JohnsonContext, context);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
201
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
202 VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(JS_GetRuntime(js_context));
203 Data_Get_Struct(ruby_runtime, JohnsonRuntime, runtime);
204
205 PREPARE_JROOTS(js_context, 1);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
206 JROOT(id);
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
207
208 // get the Ruby object that backs this proxy
209
97b8244 @matthewd Root everything in sight.
matthewd authored
210 VALUE self = (VALUE)JS_GetInstancePrivate(context->js, obj, JS_GET_CLASS(context->js, obj), NULL);
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
211
e0d5bf2 @jbarnette Simple implementation for working numeric array indexes.
authored
212 // Short-circuit for numeric indexes
213
214 if (JSVAL_IS_INT(id))
215 {
97b8244 @matthewd Root everything in sight.
matthewd authored
216 if (indexable_p(self)) {
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
217 VALUE idx = INT2FIX(JSVAL_TO_INT(id));
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
218 JCHECK(call_ruby_from_js(runtime, retval, self, rb_intern("[]"), 1, idx));
97b8244 @matthewd Root everything in sight.
matthewd authored
219 }
e0d5bf2 @jbarnette Simple implementation for working numeric array indexes.
authored
220
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
221 JRETURN;
e0d5bf2 @jbarnette Simple implementation for working numeric array indexes.
authored
222 }
223
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
224 char* name = JS_GetStringBytes(JSVAL_TO_STRING(id));
225 VALUE ruby_id = rb_intern(name);
97b8244 @matthewd Root everything in sight.
matthewd authored
226
d45a2d5 @jbarnette Added some notes for the future.
authored
227 // FIXME: we should probably just JS_DefineProperty this, and it shouldn't be enumerable
228
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
229 if (!strcasecmp("__iterator__", name)) {
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
230 JCHECK(evaluate_js_property_expression(runtime, "Johnson.Generator.create", retval));
576e1fe #28 #23 arrays work in js land and so does for .. in
Aaron Patterson authored
231 }
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
232
204c021 switching to hash based dynamic properties
Aaron Patterson authored
233 // if the Ruby object has a dynamic js property with a key
234 // matching the property we're looking for, pull the value out of
235 // that map.
78f8bf9 @jbarnette Naming and formatting nitpicks.
authored
236
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
237 else if (autovivified_p(ruby_context, self, name))
204c021 switching to hash based dynamic properties
Aaron Patterson authored
238 {
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
239 JCHECK(call_ruby_from_js(runtime, retval, Johnson_SpiderMonkey_JSLandProxy(),
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
240 rb_intern("autovivified"), 2, self, rb_str_new2(name)));
204c021 switching to hash based dynamic properties
Aaron Patterson authored
241 }
242
5ccbbfa Constants can be accessed as properties in JSLand.
jbarnette authored
243 // if the Ruby object is a Module or Class and has a matching
244 // const defined, return the converted result of const_get
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
245
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
246 else if (const_p(self, name))
5ccbbfa Constants can be accessed as properties in JSLand.
jbarnette authored
247 {
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
248 JCHECK(call_ruby_from_js(runtime, retval, self, rb_intern("const_get"),
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
249 1, ID2SYM(ruby_id)));
5ccbbfa Constants can be accessed as properties in JSLand.
jbarnette authored
250 }
1f9f150 @tenderlove giving spidermonkey access to ruby constants
tenderlove authored
251
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
252 // otherwise, if it's a global, return the global
253 else if (global_p(name))
1f9f150 @tenderlove giving spidermonkey access to ruby constants
tenderlove authored
254 {
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
255 JCHECK(convert_to_js(runtime, rb_gv_get(name), retval));
1f9f150 @tenderlove giving spidermonkey access to ruby constants
tenderlove authored
256 }
5ccbbfa Constants can be accessed as properties in JSLand.
jbarnette authored
257
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
258 // otherwise, if the Ruby object has a an attribute method matching
5ccbbfa Constants can be accessed as properties in JSLand.
jbarnette authored
259 // the property we're trying to get, call it and return the converted result
260
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
261 else if (attribute_p(self, name))
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
262 {
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
263 JCHECK(call_ruby_from_js(runtime, retval, self, ruby_id, 0));
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
264 }
5ccbbfa Constants can be accessed as properties in JSLand.
jbarnette authored
265
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
266 // otherwise, if the Ruby object quacks sorta like a hash (it responds to
267 // "[]" and "key?"), index it by key and return the converted result
268
269 else if (has_key_p(self, name))
270 {
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
271 JCHECK(call_ruby_from_js(runtime, retval, self, rb_intern("[]"), 1, rb_str_new2(name)));
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
272 }
273
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
274 // otherwise, it's a method being accessed as a property, which means
275 // we need to return a lambda
276
cfcba6d @jbarnette Added a few more FIXMEs.
authored
277 // FIXME: this should really wrap the Method for 'name' in a JS class
278 // rather than generating a wrapper Proc
279
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
280 else if (method_p(self, name))
281 {
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
282 JCHECK(call_ruby_from_js(runtime, retval, self, rb_intern("method"), 1, rb_str_new2(name)));
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
283 }
5a4b5f0 @matthewd Do a slightly better job of keeping +id+ rooted as long as we need +n…
matthewd authored
284
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
285 // else it's undefined (JS_VOID) by default
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
286 JRETURN;
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
287 }
288
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
289 // called for lazily resolved properties, which should go away
290 static JSBool get_and_destroy_resolved_property(
291 JSContext* js_context, JSObject* obj, jsval id, jsval* retval)
292 {
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
293 PREPARE_JROOTS(js_context, 1);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
294 JROOT(id);
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
295 char* name = JS_GetStringBytes(JSVAL_TO_STRING(id));
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
296 JCHECK(JS_DeleteProperty(js_context, obj, name));
297 JCHECK(get(js_context, obj, id, retval));
298 JRETURN;
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
299 }
300
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
301 static JSBool set(JSContext* js_context, JSObject* obj, jsval id, jsval* value)
302 {
97b8244 @matthewd Root everything in sight.
matthewd authored
303 VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context);
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
304
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
305 JohnsonContext* context;
306 JohnsonRuntime* runtime;
307 Data_Get_Struct(ruby_context, JohnsonContext, context);
308
309 VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(JS_GetRuntime(js_context));
310 Data_Get_Struct(ruby_runtime, JohnsonRuntime, runtime);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
311
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
312 PREPARE_JROOTS(js_context, 2);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
313 JROOT(id);
314 JROOT_PTR(value);
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
315
97b8244 @matthewd Root everything in sight.
matthewd authored
316 VALUE self = (VALUE)JS_GetInstancePrivate(context->js, obj, JS_GET_CLASS(context->js, obj), NULL);
15f8763 @matthewd Deal with a couple of places that Ruby exceptions can leak through JS…
matthewd authored
317
e0d5bf2 @jbarnette Simple implementation for working numeric array indexes.
authored
318 // Short-circuit for numeric indexes
319
320 if (JSVAL_IS_INT(id))
321 {
322 if (indexable_p(self))
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
323 {
324 VALUE idx = INT2FIX(JSVAL_TO_INT(id));
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
325 VALUE val = CONVERT_TO_RUBY(runtime, *value);
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
326
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
327 JCHECK(call_ruby_from_js(runtime, NULL, self, rb_intern("[]="), 2, idx, val));
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
328 }
97b8244 @matthewd Root everything in sight.
matthewd authored
329
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
330 JRETURN;
e0d5bf2 @jbarnette Simple implementation for working numeric array indexes.
authored
331 }
332
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
333 VALUE ruby_key = CONVERT_TO_RUBY(runtime, id);
334 VALUE ruby_value = CONVERT_TO_RUBY(runtime, *value);
97b8244 @matthewd Root everything in sight.
matthewd authored
335
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
336 VALUE setter = rb_str_append(rb_str_new3(ruby_key), rb_str_new2("="));
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
337 VALUE setter_id = rb_intern(StringValueCStr(setter));
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
338
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
339 VALUE settable_p, indexable_p;
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
340 JCHECK(call_ruby_from_js2(runtime, &settable_p, self, rb_intern("respond_to?"), 1, ID2SYM(setter_id)));
341 JCHECK(call_ruby_from_js2(runtime, &indexable_p, self, rb_intern("respond_to?"), 1, ID2SYM(rb_intern("[]="))));
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
342
46ffbc1 @jbarnette JSland proxies of Ruby classes have working constructors. [#29 state:…
authored
343 if (settable_p)
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
344 {
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
345 VALUE method, arity;
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
346 JCHECK(call_ruby_from_js2(runtime, &method, self, rb_intern("method"), 1, ID2SYM(setter_id)));
347 JCHECK(call_ruby_from_js2(runtime, &arity, method, rb_intern("arity"), 0));
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
348
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
349 // if the Ruby object has a 1-arity method named "property=",
350 // call it with the converted value
351
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
352 if (NUM2INT(arity) == 1)
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
353 JCHECK(call_ruby_from_js(runtime, NULL, self, setter_id, 1, ruby_value));
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
354 }
46ffbc1 @jbarnette JSland proxies of Ruby classes have working constructors. [#29 state:…
authored
355 else if(indexable_p)
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
356 {
357 // otherwise, if the Ruby object quacks sorta like a hash for assignment
358 // (it responds to "[]="), assign it by key
359
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
360 JCHECK(call_ruby_from_js(runtime, NULL, self, rb_intern("[]="), 2, ruby_key, ruby_value));
78f8bf9 @jbarnette Naming and formatting nitpicks.
authored
361 }
362 else
363 {
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
364 JCHECK(call_ruby_from_js(runtime, NULL, Johnson_SpiderMonkey_JSLandProxy(), rb_intern("autovivify"),
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
365 3, self, ruby_key, ruby_value));
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
366 }
97b8244 @matthewd Root everything in sight.
matthewd authored
367
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
368 JRETURN;
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
369 }
370
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
371 static JSBool construct(JSContext* js_context, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* retval)
b77b3ad @jbarnette Make sure multiple proxy classes are supported.
authored
372 {
97b8244 @matthewd Root everything in sight.
matthewd authored
373 VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context);
46ffbc1 @jbarnette JSland proxies of Ruby classes have working constructors. [#29 state:…
authored
374
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
375 JohnsonContext* context;
376 JohnsonRuntime* runtime;
377 Data_Get_Struct(ruby_context, JohnsonContext, context);
46ffbc1 @jbarnette JSland proxies of Ruby classes have working constructors. [#29 state:…
authored
378
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
379 VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(JS_GetRuntime(js_context));
380 Data_Get_Struct(ruby_runtime, JohnsonRuntime, runtime);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
381
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
382 PREPARE_JROOTS(js_context, 0);
383
384 VALUE klass = CONVERT_TO_RUBY(runtime, JS_ARGV_CALLEE(argv));
46ffbc1 @jbarnette JSland proxies of Ruby classes have working constructors. [#29 state:…
authored
385 VALUE args = rb_ary_new();
386
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
387 uintN i;
46ffbc1 @jbarnette JSland proxies of Ruby classes have working constructors. [#29 state:…
authored
388 for (i = 0; i < argc; ++i)
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
389 rb_ary_push(args, CONVERT_TO_RUBY(runtime, argv[i]));
46ffbc1 @jbarnette JSland proxies of Ruby classes have working constructors. [#29 state:…
authored
390
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
391 JCHECK(call_ruby_from_js(runtime, retval, Johnson_SpiderMonkey_JSLandProxy(),
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
392 rb_intern("send_with_possible_block"), 3, klass, ID2SYM(rb_intern("new")), args));
393 JRETURN;
b77b3ad @jbarnette Make sure multiple proxy classes are supported.
authored
394 }
395
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
396 static JSBool resolve(JSContext *js_context, JSObject *obj, jsval id, uintN UNUSED(flags), JSObject **objp)
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
397 {
97b8244 @matthewd Root everything in sight.
matthewd authored
398 VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context);
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
399
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
400 JohnsonContext* context;
401 Data_Get_Struct(ruby_context, JohnsonContext, context);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
402
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
403 PREPARE_JROOTS(js_context, 1);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
404 JROOT(id);
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
405
406 char* name = JS_GetStringBytes(JS_ValueToString(js_context, id));
97b8244 @matthewd Root everything in sight.
matthewd authored
407
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
408 if (respond_to_p(js_context, obj, name))
409 {
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
410 JCHECK(JS_DefineProperty(js_context, obj, name, JSVAL_VOID,
411 get_and_destroy_resolved_property, set, JSPROP_ENUMERATE));
97b8244 @matthewd Root everything in sight.
matthewd authored
412
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
413 *objp = obj;
414 }
97b8244 @matthewd Root everything in sight.
matthewd authored
415
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
416 JRETURN;
6b3683d @jbarnette Make with() work. [#31 state:resolved]
authored
417 }
418
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
419 static JSBool to_string(JSContext* js_context, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* retval)
420 {
421 VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context);
422
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
423 JohnsonContext* context;
424 JohnsonRuntime* runtime;
425 Data_Get_Struct(ruby_context, JohnsonContext, context);
426
427 VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(JS_GetRuntime(js_context));
428 Data_Get_Struct(ruby_runtime, JohnsonRuntime, runtime);
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
429
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
430 PREPARE_JROOTS(js_context, 0);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
431
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
432 VALUE self = (VALUE)JS_GetInstancePrivate(context->js, obj, JS_GET_CLASS(context->js, obj), NULL);
433
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
434 JCHECK(call_ruby_from_js(runtime, retval, self, rb_intern("to_s"), 0));
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
435 JRETURN;
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
436 }
437
438 static JSBool to_array(JSContext* js_context, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* retval)
439 {
440 VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context);
441
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
442 JohnsonContext* context;
443 JohnsonRuntime* runtime;
444 Data_Get_Struct(ruby_context, JohnsonContext, context);
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
445
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
446 VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(JS_GetRuntime(js_context));
447 Data_Get_Struct(ruby_runtime, JohnsonRuntime, runtime);
448
449 PREPARE_JROOTS(js_context, 0);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
450
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
451 VALUE self = (VALUE)JS_GetInstancePrivate(context->js, obj, JS_GET_CLASS(context->js, obj), NULL);
452
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
453 JCHECK(call_ruby_from_js(runtime, retval, self, rb_intern("to_a"), 0));
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
454 JRETURN;
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
455 }
456
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
457 static JSBool method_missing(JSContext* js_context, JSObject* obj, uintN argc, jsval* argv, jsval* retval)
458 {
97b8244 @matthewd Root everything in sight.
matthewd authored
459 VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context);
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
460
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
461 JohnsonContext* context;
462 JohnsonRuntime* runtime;
463 Data_Get_Struct(ruby_context, JohnsonContext, context);
464
465 VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(JS_GetRuntime(js_context));
466 Data_Get_Struct(ruby_runtime, JohnsonRuntime, runtime);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
467
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
468 PREPARE_JROOTS(js_context, 0);
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
469
97b8244 @matthewd Root everything in sight.
matthewd authored
470 VALUE self = (VALUE)JS_GetInstancePrivate(context->js, obj, JS_GET_CLASS(context->js, obj), NULL);
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
471
97b8244 @matthewd Root everything in sight.
matthewd authored
472 assert(argc >= 2);
473
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
474 char* key = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
475 VALUE ruby_id = rb_intern(key);
476
78f8bf9 @jbarnette Naming and formatting nitpicks.
authored
477 // FIXME: this is horrible and lazy, to_a comes from enumerable on proxy (argv[1] is a JSArray)
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
478 VALUE args;
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
479 JCHECK(call_ruby_from_js2(runtime, &args, CONVERT_TO_RUBY(runtime, argv[1]), rb_intern("to_a"), 0));
c1a7fbf @matthewd Added a bunch of exception propagation handling.
matthewd authored
480
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
481 JCHECK(call_ruby_from_js(runtime, retval, Johnson_SpiderMonkey_JSLandProxy(),
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
482 rb_intern("send_with_possible_block"), 3, self, ID2SYM(ruby_id), args));
483
484 JRETURN;
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
485 }
486
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
487 static JSBool call(JSContext* js_context, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* retval)
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
488 {
97b8244 @matthewd Root everything in sight.
matthewd authored
489 VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context);
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
490
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
491 JohnsonContext* context;
492 JohnsonRuntime* runtime;
493 Data_Get_Struct(ruby_context, JohnsonContext, context);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
494
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
495 VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(JS_GetRuntime(js_context));
496 Data_Get_Struct(ruby_runtime, JohnsonRuntime, runtime);
497
498 PREPARE_JROOTS(js_context, 0);
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
499
97b8244 @matthewd Root everything in sight.
matthewd authored
500 VALUE self = (VALUE)JS_GetInstancePrivate(context->js, JSVAL_TO_OBJECT(JS_ARGV_CALLEE(argv)), &JSLandCallableProxyClass, NULL);
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
501
502 VALUE args = rb_ary_new();
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
503
504 uintN i;
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
505 for (i = 0; i < argc; ++i)
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
506 rb_ary_push(args, CONVERT_TO_RUBY(runtime, argv[i]));
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
507
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
508 JCHECK(call_ruby_from_js(runtime, retval, Johnson_SpiderMonkey_JSLandProxy(),
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
509 rb_intern("send_with_possible_block"), 3, self, ID2SYM(rb_intern("call")), args));
510 JRETURN;
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
511 }
512
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
513 bool js_value_is_proxy(JohnsonRuntime* MAYBE_UNUSED(runtime), jsval maybe_proxy)
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
514 {
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
515 JSClass* klass = JS_GET_CLASS(
516 johnson_get_current_context(runtime),
517 JSVAL_TO_OBJECT(maybe_proxy));
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
518
519 return &JSLandProxyClass == klass
520 || &JSLandClassProxyClass == klass
521 || &JSLandCallableProxyClass == klass;
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
522 }
523
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
524 VALUE unwrap_js_land_proxy(JohnsonRuntime* runtime, jsval proxy)
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
525 {
01b0682 @jbarnette JS proxies roundtrip.
authored
526 VALUE value;
109858e @jbarnette Make JSLandProxyClass more easily parameterizable.
authored
527 JSObject *proxy_object = JSVAL_TO_OBJECT(proxy);
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
528 JSContext * context = johnson_get_current_context(runtime);
109858e @jbarnette Make JSLandProxyClass more easily parameterizable.
authored
529
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
530 value = (VALUE)JS_GetInstancePrivate(context, proxy_object,
531 JS_GET_CLASS(context, proxy_object), NULL);
109858e @jbarnette Make JSLandProxyClass more easily parameterizable.
authored
532
f0cc336 js proxies roundtrip correctly. still no gc root.
jbarnette authored
533 return value;
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
534 }
535
3c24fe9 Fixed Ruby value tracking/GC rooting.
jbarnette authored
536 static void finalize(JSContext* js_context, JSObject* obj)
537 {
538 VALUE ruby_context = (VALUE)JS_GetContextPrivate(js_context);
539
540 if (ruby_context)
541 {
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
542 JohnsonContext* context;
543 JohnsonRuntime* runtime;
544 Data_Get_Struct(ruby_context, JohnsonContext, context);
545
546 VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(JS_GetRuntime(js_context));
547 Data_Get_Struct(ruby_runtime, JohnsonRuntime, runtime);
3c24fe9 Fixed Ruby value tracking/GC rooting.
jbarnette authored
548
97b8244 @matthewd Root everything in sight.
matthewd authored
549 VALUE self = (VALUE)JS_GetInstancePrivate(context->js, obj,
550 JS_GET_CLASS(context->js, obj), NULL);
0795f89 @matthewd Track gcthings on the runtime, not the context.
matthewd authored
551
3c24fe9 Fixed Ruby value tracking/GC rooting.
jbarnette authored
552 // remove the proxy OID from the id map
c6ea599 @matthewd Use direct pointers in the hash tables etc, and just Root values we n…
matthewd authored
553 JS_HashTableRemove(runtime->rbids, (void *)self);
a84310c @tenderlove removing gc thing by object id
tenderlove authored
554
3c24fe9 Fixed Ruby value tracking/GC rooting.
jbarnette authored
555 // free up the ruby value for GC
a84310c @tenderlove removing gc thing by object id
tenderlove authored
556 rb_funcall(ruby_runtime, rb_intern("remove_gcthing"), 1, rb_obj_id(self));
557 }
3c24fe9 Fixed Ruby value tracking/GC rooting.
jbarnette authored
558 }
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
559
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
560 JSBool make_js_land_proxy(JohnsonRuntime* runtime, VALUE value, jsval* retval)
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
561 {
c6ea599 @matthewd Use direct pointers in the hash tables etc, and just Root values we n…
matthewd authored
562 *retval = (jsval)JS_HashTableLookup(runtime->rbids, (void *)value);
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
563
c6ea599 @matthewd Use direct pointers in the hash tables etc, and just Root values we n…
matthewd authored
564 if (*retval)
3c24fe9 Fixed Ruby value tracking/GC rooting.
jbarnette authored
565 {
c6ea599 @matthewd Use direct pointers in the hash tables etc, and just Root values we n…
matthewd authored
566 return JS_TRUE;
3c24fe9 Fixed Ruby value tracking/GC rooting.
jbarnette authored
567 }
568 else
569 {
c6ea599 @matthewd Use direct pointers in the hash tables etc, and just Root values we n…
matthewd authored
570 JSContext * context = johnson_get_current_context(runtime);
2b17b4d @matthewd Simplified the PREPARE_JROOTS API back to just one number.
matthewd authored
571 PREPARE_JROOTS(context, 1);
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
572
3c24fe9 Fixed Ruby value tracking/GC rooting.
jbarnette authored
573 JSObject *jsobj;
b77b3ad @jbarnette Make sure multiple proxy classes are supported.
authored
574
575 JSClass *klass = &JSLandProxyClass;
576 if (T_CLASS == TYPE(value)) klass = &JSLandClassProxyClass;
577
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
578 // FIXME: hack; should happen in Rubyland
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
579 if (T_STRUCT == TYPE(value))
580 rb_funcall(Johnson_SpiderMonkey_JSLandProxy(),
581 rb_intern("treat_all_properties_as_methods"), 1, value);
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
582
f518879 @jbarnette Any Rubyland object that responds to call can be called as a function…
authored
583 bool callable_p = Qtrue == rb_funcall(value,
584 rb_intern("respond_to?"), 1, rb_str_new2("call"));
b7616dd @jbarnette Reimplement property and method access. Mostly.
authored
585
73ad637 @jbarnette Cleaned up proxying of callable (Proc, Method) Ruby objects.
authored
586 if (callable_p)
587 klass = &JSLandCallableProxyClass;
588
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
589 JCHECK((jsobj = JS_NewObject(context, klass, NULL, NULL)));
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
590 JROOT(jsobj);
f518879 @jbarnette Any Rubyland object that responds to call can be called as a function…
authored
591
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
592 JCHECK(JS_SetPrivate(context, jsobj, (void*)value));
3c24fe9 Fixed Ruby value tracking/GC rooting.
jbarnette authored
593
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
594 JCHECK(JS_DefineFunction(context, jsobj, "__noSuchMethod__", method_missing, 2, 0));
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
595
ae3584f @jbarnette Runtime is the new Context. One context per Ruby thread.
authored
596 JCHECK(JS_DefineFunction(context, jsobj, "toArray", to_array, 0, 0));
597 JCHECK(JS_DefineFunction(context, jsobj, "toString", to_string, 0, 0));
70adb2d @matthewd Enabled a bunch of warnings, and added .toString/.toArray/.to_s
matthewd authored
598
9149af0 @matthewd More JSBool conversions.
matthewd authored
599 *retval = OBJECT_TO_JSVAL(jsobj);
3c24fe9 Fixed Ruby value tracking/GC rooting.
jbarnette authored
600
601 // put the proxy OID in the id map
c6ea599 @matthewd Use direct pointers in the hash tables etc, and just Root values we n…
matthewd authored
602 JCHECK(JS_HashTableAdd(runtime->rbids, (void *)value, (void *)(*retval)));
3c24fe9 Fixed Ruby value tracking/GC rooting.
jbarnette authored
603
604 // root the ruby value for GC
0795f89 @matthewd Track gcthings on the runtime, not the context.
matthewd authored
605 VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(runtime->js);
606 rb_funcall(ruby_runtime, rb_intern("add_gcthing"), 1, value);
9149af0 @matthewd More JSBool conversions.
matthewd authored
607
06cd4a9 @matthewd Use some macros to keep track of what's been rooted.
matthewd authored
608 JRETURN;
3c24fe9 Fixed Ruby value tracking/GC rooting.
jbarnette authored
609 }
69ace87 JS-land proxies for Ruby objects. No support for GC or roundtripping.
jbarnette authored
610 }
Something went wrong with that request. Please try again.