This repository is private.
All pages are served over SSL and all pushing and pulling is done over SSH.
No one may fork, clone, or view it unless they are added as a member.
Every repository with this icon (
) is private.
Every repository with this icon (
This repository is public.
Anyone may fork, clone, or view it.
Every repository with this icon (
) is public.
Every repository with this icon (
| e18f74d8 » | jbarnette | 2008-04-14 | 1 | #include "ruby_land_proxy.h" | |
| dc423367 » | matthewd | 2008-04-21 | 2 | #include "conversions.h" | |
| 3 | #include "error.h" | ||||
| fe394493 » | jbarnette | 2008-03-17 | 4 | ||
| eb42dce4 » | matthewd | 2008-04-29 | 5 | DECLARE_RUBY_WRAPPER(rb_call_super, int argc; const VALUE* argv) | |
| 6 | DEFINE_RUBY_WRAPPER(rb_call_super, rb_call_super, ARGLIST2(argc, argv)) | ||||
| 7 | |||||
| 8 | DECLARE_RUBY_WRAPPER(rb_yield, VALUE v) | ||||
| 9 | DEFINE_RUBY_WRAPPER(rb_yield, rb_yield, ARGLIST1(v)) | ||||
| 10 | |||||
| fe394493 » | jbarnette | 2008-03-17 | 11 | static VALUE proxy_class = Qnil; | |
| 12 | |||||
| df61324f » | matthewd | 2008-05-23 | 13 | static JSBool get_jsval_for_proxy(RubyLandProxy* proxy, jsval* jv) | |
| f21981e9 » | jbarnette | 2008-05-20 | 14 | { | |
| c7079b18 » | tenderlove | 2008-05-30 | 15 | JSContext * context = johnson_get_current_context(proxy->runtime); | |
| 6a981ce4 » | tenderlove | 2008-05-30 | 16 | PREPARE_JROOTS(context, 0); | |
| df61324f » | matthewd | 2008-05-23 | 17 | ||
| f21981e9 » | jbarnette | 2008-05-20 | 18 | // FIXME: this is totally lame | |
| 19 | char global_key[10]; | ||||
| 6a981ce4 » | tenderlove | 2008-05-30 | 20 | sprintf(global_key, "%x", (int)proxy->runtime->global); | |
| f21981e9 » | jbarnette | 2008-05-20 | 21 | ||
| 22 | if (0 == strcmp(global_key, proxy->key)) | ||||
| df61324f » | matthewd | 2008-05-23 | 23 | { | |
| 6a981ce4 » | tenderlove | 2008-05-30 | 24 | *jv = OBJECT_TO_JSVAL(proxy->runtime->global); | |
| df61324f » | matthewd | 2008-05-23 | 25 | JRETURN; | |
| 26 | } | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 27 | ||
| c7079b18 » | tenderlove | 2008-05-30 | 28 | JCHECK(JS_GetProperty(context, proxy->runtime->gcthings, proxy->key, jv)); | |
| df61324f » | matthewd | 2008-05-23 | 29 | JRETURN; | |
| f21981e9 » | jbarnette | 2008-05-20 | 30 | } | |
| 31 | |||||
| 6a981ce4 » | tenderlove | 2008-05-30 | 32 | static VALUE call_js_function_value(JohnsonRuntime* runtime, jsval target, jsval function, int argc, VALUE* argv) | |
| 3b26152f » | matthewd | 2008-04-26 | 33 | { | |
| c7079b18 » | tenderlove | 2008-05-30 | 34 | JSContext * context = johnson_get_current_context(runtime); | |
| 2b17b4dd » | matthewd | 2008-05-04 | 35 | PREPARE_RUBY_JROOTS(context, argc + 2); | |
| 06cd4a94 » | matthewd | 2008-04-27 | 36 | ||
| 37 | JROOT(target); | ||||
| 38 | JROOT(function); | ||||
| 3b26152f » | matthewd | 2008-04-26 | 39 | ||
| 40 | assert(JSVAL_IS_OBJECT(target)); | ||||
| 41 | |||||
| 42 | jsval args[argc]; | ||||
| 43 | jsval result; | ||||
| 44 | |||||
| 45 | int i; | ||||
| 46 | for(i = 0; i < argc; ++i) | ||||
| 06cd4a94 » | matthewd | 2008-04-27 | 47 | { | |
| 6a981ce4 » | tenderlove | 2008-05-30 | 48 | JCHECK(convert_to_js(runtime, argv[i], &(args[i]))); | |
| 06cd4a94 » | matthewd | 2008-04-27 | 49 | JROOT(args[i]); | |
| 3b26152f » | matthewd | 2008-04-26 | 50 | } | |
| 51 | |||||
| c7079b18 » | tenderlove | 2008-05-30 | 52 | JCHECK(JS_CallFunctionValue(context, | |
| 06cd4a94 » | matthewd | 2008-04-27 | 53 | JSVAL_TO_OBJECT(target), function, (unsigned) argc, args, &result)); | |
| 3b26152f » | matthewd | 2008-04-26 | 54 | ||
| 6a981ce4 » | tenderlove | 2008-05-30 | 55 | JRETURN_RUBY(CONVERT_TO_RUBY(runtime, result)); | |
| 3b26152f » | matthewd | 2008-04-26 | 56 | } | |
| 57 | |||||
| 2fc27423 » | tenderlove | 2008-05-09 | 58 | /* | |
| 59 | * call-seq: | ||||
| 60 | * [](name) | ||||
| 61 | * | ||||
| 62 | * Returns the property with +name+. | ||||
| 63 | */ | ||||
| 64 | static VALUE | ||||
| dfbd5bda » | jbarnette | 2008-03-18 | 65 | get(VALUE self, VALUE name) | |
| 82b9c932 » | jbarnette | 2008-03-17 | 66 | { | |
| e18f74d8 » | jbarnette | 2008-04-14 | 67 | RubyLandProxy* proxy; | |
| 68 | Data_Get_Struct(self, RubyLandProxy, proxy); | ||||
| 4867becd » | tenderlove | 2008-04-17 | 69 | ||
| c7079b18 » | tenderlove | 2008-05-30 | 70 | JSContext * context = johnson_get_current_context(proxy->runtime); | |
| 71 | PREPARE_RUBY_JROOTS(context, 1); | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 72 | ||
| df61324f » | matthewd | 2008-05-23 | 73 | jsval proxy_value; | |
| 74 | JCHECK(get_jsval_for_proxy(proxy, &proxy_value)); | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 75 | JROOT(proxy_value); | |
| 97b82442 » | matthewd | 2008-04-21 | 76 | ||
| 82b9c932 » | jbarnette | 2008-03-17 | 77 | jsval js_value; | |
| 4867becd » | tenderlove | 2008-04-17 | 78 | ||
| 79 | switch(TYPE(name)) { | ||||
| 80 | case T_FIXNUM: | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 81 | JCHECK(JS_GetElement(context, | |
| f21981e9 » | jbarnette | 2008-05-20 | 82 | JSVAL_TO_OBJECT(proxy_value), NUM2INT(name), &js_value)); | |
| 4867becd » | tenderlove | 2008-04-17 | 83 | break; | |
| 84 | default: | ||||
| 85 | Check_Type(name, T_STRING); | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 86 | JCHECK(JS_GetProperty(context, | |
| f21981e9 » | jbarnette | 2008-05-20 | 87 | JSVAL_TO_OBJECT(proxy_value), StringValueCStr(name), &js_value)); | |
| 4867becd » | tenderlove | 2008-04-17 | 88 | break; | |
| 89 | } | ||||
| 90 | |||||
| c7079b18 » | tenderlove | 2008-05-30 | 91 | JRETURN_RUBY(CONVERT_TO_RUBY(proxy->runtime, js_value)); | |
| 82b9c932 » | jbarnette | 2008-03-17 | 92 | } | |
| 93 | |||||
| 2fc27423 » | tenderlove | 2008-05-09 | 94 | /* | |
| 95 | * call-seq: | ||||
| 96 | * []=(name,value) | ||||
| 97 | * | ||||
| 98 | * Sets the property with +name+ to +value+. | ||||
| 99 | */ | ||||
| 100 | static VALUE | ||||
| dfbd5bda » | jbarnette | 2008-03-18 | 101 | set(VALUE self, VALUE name, VALUE value) | |
| 82b9c932 » | jbarnette | 2008-03-17 | 102 | { | |
| e18f74d8 » | jbarnette | 2008-04-14 | 103 | RubyLandProxy* proxy; | |
| 104 | Data_Get_Struct(self, RubyLandProxy, proxy); | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 105 | JSContext * context = johnson_get_current_context(proxy->runtime); | |
| 82b9c932 » | jbarnette | 2008-03-17 | 106 | ||
| 6a981ce4 » | tenderlove | 2008-05-30 | 107 | PREPARE_RUBY_JROOTS(context, 2); | |
| f21981e9 » | jbarnette | 2008-05-20 | 108 | ||
| df61324f » | matthewd | 2008-05-23 | 109 | jsval proxy_value; | |
| 110 | JCHECK(get_jsval_for_proxy(proxy, &proxy_value)); | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 111 | JROOT(proxy_value); | |
| 97b82442 » | matthewd | 2008-04-21 | 112 | ||
| a5d745ef » | matthewd | 2008-04-21 | 113 | jsval js_value; | |
| 6a981ce4 » | tenderlove | 2008-05-30 | 114 | JCHECK(convert_to_js(proxy->runtime, value, &js_value)); | |
| 82b9c932 » | jbarnette | 2008-03-17 | 115 | ||
| 06cd4a94 » | matthewd | 2008-04-27 | 116 | JROOT(js_value); | |
| 97b82442 » | matthewd | 2008-04-21 | 117 | ||
| 4867becd » | tenderlove | 2008-04-17 | 118 | switch(TYPE(name)) { | |
| 119 | case T_FIXNUM: | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 120 | JCHECK(JS_SetElement(context, | |
| f21981e9 » | jbarnette | 2008-05-20 | 121 | JSVAL_TO_OBJECT(proxy_value), NUM2INT(name), &js_value)); | |
| 4867becd » | tenderlove | 2008-04-17 | 122 | break; | |
| 123 | default: | ||||
| 124 | Check_Type(name, T_STRING); | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 125 | JCHECK(JS_SetProperty(context, | |
| f21981e9 » | jbarnette | 2008-05-20 | 126 | JSVAL_TO_OBJECT(proxy_value), StringValueCStr(name), &js_value)); | |
| 4867becd » | tenderlove | 2008-04-17 | 127 | break; | |
| 128 | } | ||||
| 97b82442 » | matthewd | 2008-04-21 | 129 | ||
| 06cd4a94 » | matthewd | 2008-04-27 | 130 | JRETURN_RUBY(value); | |
| 82b9c932 » | jbarnette | 2008-03-17 | 131 | } | |
| 132 | |||||
| 2fc27423 » | tenderlove | 2008-05-09 | 133 | /* | |
| 134 | * call-seq: | ||||
| 135 | * function? | ||||
| 136 | * | ||||
| 137 | * Returns <code>true</code> if this is a function. | ||||
| 138 | */ | ||||
| 139 | static VALUE | ||||
| dfbd5bda » | jbarnette | 2008-03-18 | 140 | function_p(VALUE self) | |
| 2660dba4 » | jbarnette | 2008-03-18 | 141 | { | |
| e18f74d8 » | jbarnette | 2008-04-14 | 142 | RubyLandProxy* proxy; | |
| 143 | Data_Get_Struct(self, RubyLandProxy, proxy); | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 144 | JSContext * context = johnson_get_current_context(proxy->runtime); | |
| 6a981ce4 » | tenderlove | 2008-05-30 | 145 | PREPARE_RUBY_JROOTS(context, 0); | |
| df61324f » | matthewd | 2008-05-23 | 146 | jsval proxy_value; | |
| 147 | JCHECK(get_jsval_for_proxy(proxy, &proxy_value)); | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 148 | JRETURN_RUBY(JS_TypeOfValue(context, proxy_value) == JSTYPE_FUNCTION ? Qtrue : Qfalse); | |
| 2660dba4 » | jbarnette | 2008-03-18 | 149 | } | |
| 150 | |||||
| 2fc27423 » | tenderlove | 2008-05-09 | 151 | /* | |
| 152 | * call-seq: | ||||
| 153 | * respond_to?(symbol) | ||||
| 154 | * | ||||
| 155 | * Returns <code>true</code> if _obj_ responds to given method. | ||||
| 156 | */ | ||||
| 157 | static VALUE | ||||
| dfbd5bda » | jbarnette | 2008-03-18 | 158 | respond_to_p(VALUE self, VALUE sym) | |
| 9d68f23b » | jbarnette | 2008-03-18 | 159 | { | |
| e18f74d8 » | jbarnette | 2008-04-14 | 160 | RubyLandProxy* proxy; | |
| 161 | Data_Get_Struct(self, RubyLandProxy, proxy); | ||||
| 06cd4a94 » | matthewd | 2008-04-27 | 162 | ||
| c7079b18 » | tenderlove | 2008-05-30 | 163 | JSContext * context = johnson_get_current_context(proxy->runtime); | |
| 6a981ce4 » | tenderlove | 2008-05-30 | 164 | PREPARE_RUBY_JROOTS(context, 2); | |
| 9d68f23b » | jbarnette | 2008-03-18 | 165 | ||
| 166 | char* name = rb_id2name(SYM2ID(sym)); | ||||
| 167 | |||||
| 168 | // assignment is always okay | ||||
| 169 | if (name[strlen(name) - 1] == '=') | ||||
| 06cd4a94 » | matthewd | 2008-04-27 | 170 | JRETURN_RUBY(Qtrue); | |
| 9d68f23b » | jbarnette | 2008-03-18 | 171 | ||
| df61324f » | matthewd | 2008-05-23 | 172 | jsval proxy_value; | |
| 173 | JCHECK(get_jsval_for_proxy(proxy, &proxy_value)); | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 174 | JROOT(proxy_value); | |
| 97b82442 » | matthewd | 2008-04-21 | 175 | ||
| 9d68f23b » | jbarnette | 2008-03-18 | 176 | JSObject *obj; | |
| 177 | JSBool found; | ||||
| 178 | |||||
| c7079b18 » | tenderlove | 2008-05-30 | 179 | JCHECK(JS_ValueToObject(context, proxy_value, &obj)); | |
| 06cd4a94 » | matthewd | 2008-04-27 | 180 | JROOT(obj); | |
| 97b82442 » | matthewd | 2008-04-21 | 181 | ||
| c7079b18 » | tenderlove | 2008-05-30 | 182 | JCHECK(JS_HasProperty(context, obj, name, &found)); | |
| 9d68f23b » | jbarnette | 2008-03-18 | 183 | ||
| eb42dce4 » | matthewd | 2008-04-29 | 184 | JRETURN_RUBY(found ? Qtrue : CALL_RUBY_WRAPPER(rb_call_super, 1, &sym)); | |
| 9d68f23b » | jbarnette | 2008-03-18 | 185 | } | |
| 186 | |||||
| 2fc27423 » | tenderlove | 2008-05-09 | 187 | /* | |
| 188 | * call-seq: | ||||
| 189 | * native_call(global, *args) | ||||
| 190 | * | ||||
| 191 | * Call as a function with given +global+ using *args. | ||||
| 192 | */ | ||||
| 193 | static VALUE | ||||
| b7616ddc » | jbarnette | 2008-04-20 | 194 | native_call(int argc, VALUE* argv, VALUE self) | |
| 2660dba4 » | jbarnette | 2008-03-18 | 195 | { | |
| 196 | if (!function_p(self)) | ||||
| e18f74d8 » | jbarnette | 2008-04-14 | 197 | Johnson_Error_raise("This Johnson::SpiderMonkey::RubyLandProxy isn't a function."); | |
| 2660dba4 » | jbarnette | 2008-03-18 | 198 | ||
| b05fc61d » | matthewd | 2008-04-25 | 199 | if (argc < 1) | |
| 200 | rb_raise(rb_eArgError, "Target object required"); | ||||
| 201 | |||||
| e18f74d8 » | jbarnette | 2008-04-14 | 202 | RubyLandProxy* proxy; | |
| 203 | Data_Get_Struct(self, RubyLandProxy, proxy); | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 204 | JSContext * context = johnson_get_current_context(proxy->runtime); | |
| 2660dba4 » | jbarnette | 2008-03-18 | 205 | ||
| 6a981ce4 » | tenderlove | 2008-05-30 | 206 | PREPARE_RUBY_JROOTS(context, 1); | |
| f21981e9 » | jbarnette | 2008-05-20 | 207 | ||
| df61324f » | matthewd | 2008-05-23 | 208 | jsval proxy_value; | |
| 209 | JCHECK(get_jsval_for_proxy(proxy, &proxy_value)); | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 210 | JROOT(proxy_value); | |
| 97b82442 » | matthewd | 2008-04-21 | 211 | ||
| a5d745ef » | matthewd | 2008-04-21 | 212 | jsval global; | |
| c7079b18 » | tenderlove | 2008-05-30 | 213 | JCHECK(convert_to_js(proxy->runtime, argv[0], &global)); | |
| 97b82442 » | matthewd | 2008-04-21 | 214 | ||
| c7079b18 » | tenderlove | 2008-05-30 | 215 | JRETURN_RUBY(call_js_function_value(proxy->runtime, global, proxy_value, argc - 1, &(argv[1]))); | |
| 2660dba4 » | jbarnette | 2008-03-18 | 216 | } | |
| 217 | |||||
| eb42dce4 » | matthewd | 2008-04-29 | 218 | static void | |
| c7079b18 » | tenderlove | 2008-05-30 | 219 | destroy_id_array(JSContext* context, void* data) | |
| eb42dce4 » | matthewd | 2008-04-29 | 220 | { | |
| c7079b18 » | tenderlove | 2008-05-30 | 221 | JS_DestroyIdArray(context, (JSIdArray*)data); | |
| eb42dce4 » | matthewd | 2008-04-29 | 222 | } | |
| 223 | |||||
| 2fc27423 » | tenderlove | 2008-05-09 | 224 | /* | |
| 225 | * call-seq: | ||||
| 226 | * each { |obj| block } | ||||
| 227 | * | ||||
| 228 | * Calls <em>block</em> with each item in the collection. | ||||
| 229 | */ | ||||
| 230 | static VALUE | ||||
| f062b403 » | jbarnette | 2008-03-19 | 231 | each(VALUE self) | |
| 232 | { | ||||
| e18f74d8 » | jbarnette | 2008-04-14 | 233 | RubyLandProxy* proxy; | |
| 234 | Data_Get_Struct(self, RubyLandProxy, proxy); | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 235 | JSContext * context = johnson_get_current_context(proxy->runtime); | |
| f062b403 » | jbarnette | 2008-03-19 | 236 | ||
| 6a981ce4 » | tenderlove | 2008-05-30 | 237 | PREPARE_RUBY_JROOTS(context, 5); | |
| f21981e9 » | jbarnette | 2008-05-20 | 238 | ||
| df61324f » | matthewd | 2008-05-23 | 239 | jsval proxy_value; | |
| 240 | JCHECK(get_jsval_for_proxy(proxy, &proxy_value)); | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 241 | JROOT(proxy_value); | |
| 97b82442 » | matthewd | 2008-04-21 | 242 | ||
| f21981e9 » | jbarnette | 2008-05-20 | 243 | JSObject* value = JSVAL_TO_OBJECT(proxy_value); | |
| 06cd4a94 » | matthewd | 2008-04-27 | 244 | JROOT(value); | |
| f062b403 » | jbarnette | 2008-03-19 | 245 | ||
| 246 | // arrays behave like you'd expect, indexes in order | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 247 | if (JS_IsArrayObject(context, value)) | |
| f062b403 » | jbarnette | 2008-03-19 | 248 | { | |
| 249 | jsuint length; | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 250 | JCHECK(JS_GetArrayLength(context, value, &length)); | |
| f062b403 » | jbarnette | 2008-03-19 | 251 | ||
| 70adb2d1 » | matthewd | 2008-04-25 | 252 | jsuint i = 0; | |
| f062b403 » | jbarnette | 2008-03-19 | 253 | for (i = 0; i < length; ++i) | |
| 254 | { | ||||
| 255 | jsval element; | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 256 | JCHECK(JS_GetElement(context, value, (signed) i, &element)); | |
| 257 | CALL_RUBY_WRAPPER(rb_yield, convert_to_ruby(proxy->runtime, element)); | ||||
| f062b403 » | jbarnette | 2008-03-19 | 258 | } | |
| 259 | } | ||||
| 260 | else | ||||
| 261 | { | ||||
| 262 | // not an array? behave like each on Hash; yield [key, value] | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 263 | JSIdArray* ids = JS_Enumerate(context, value); | |
| 06cd4a94 » | matthewd | 2008-04-27 | 264 | JCHECK(ids); | |
| 265 | |||||
| eb42dce4 » | matthewd | 2008-04-29 | 266 | JCLEANUP(destroy_id_array, ids); | |
| ce00ab69 » | matthewd | 2008-04-28 | 267 | ||
| f062b403 » | jbarnette | 2008-03-19 | 268 | int i; | |
| aa63d637 » | jbarnette | 2008-03-19 | 269 | for (i = 0; i < ids->length; ++i) | |
| f062b403 » | jbarnette | 2008-03-19 | 270 | { | |
| 271 | jsval js_key, js_value; | ||||
| 272 | |||||
| c7079b18 » | tenderlove | 2008-05-30 | 273 | JCHECK(JS_IdToValue(context, ids->vector[i], &js_key)); | |
| 06cd4a94 » | matthewd | 2008-04-27 | 274 | JROOT(js_key); | |
| f062b403 » | jbarnette | 2008-03-19 | 275 | ||
| 276 | if (JSVAL_IS_STRING(js_key)) | ||||
| 277 | { | ||||
| 278 | // regular properties have string keys | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 279 | JCHECK(JS_GetProperty(context, value, | |
| 06cd4a94 » | matthewd | 2008-04-27 | 280 | JS_GetStringBytes(JSVAL_TO_STRING(js_key)), &js_value)); | |
| f062b403 » | jbarnette | 2008-03-19 | 281 | } | |
| 282 | else | ||||
| 283 | { | ||||
| 284 | // it's a numeric property, use array access | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 285 | JCHECK(JS_GetElement(context, value, | |
| 06cd4a94 » | matthewd | 2008-04-27 | 286 | JSVAL_TO_INT(js_key), &js_value)); | |
| c1a7fbfe » | matthewd | 2008-04-24 | 287 | } | |
| 06cd4a94 » | matthewd | 2008-04-27 | 288 | JROOT(js_value); | |
| c1a7fbfe » | matthewd | 2008-04-24 | 289 | ||
| c7079b18 » | tenderlove | 2008-05-30 | 290 | VALUE key = CONVERT_TO_RUBY(proxy->runtime, js_key); | |
| 291 | VALUE value = CONVERT_TO_RUBY(proxy->runtime, js_value); | ||||
| f062b403 » | jbarnette | 2008-03-19 | 292 | ||
| eb42dce4 » | matthewd | 2008-04-29 | 293 | CALL_RUBY_WRAPPER(rb_yield, rb_ary_new3(2, key, value)); | |
| 97b82442 » | matthewd | 2008-04-21 | 294 | ||
| 06cd4a94 » | matthewd | 2008-04-27 | 295 | JUNROOT(js_value); | |
| 296 | JUNROOT(js_key); | ||||
| f062b403 » | jbarnette | 2008-03-19 | 297 | } | |
| 298 | } | ||||
| 97b82442 » | matthewd | 2008-04-21 | 299 | ||
| 06cd4a94 » | matthewd | 2008-04-27 | 300 | JRETURN_RUBY(self); | |
| f062b403 » | jbarnette | 2008-03-19 | 301 | } | |
| 302 | |||||
| 2fc27423 » | tenderlove | 2008-05-09 | 303 | /* | |
| 304 | * call-seq: | ||||
| 305 | * length | ||||
| 306 | * | ||||
| 307 | * Returns the length of the collection. | ||||
| 308 | */ | ||||
| 95108d5a » | jbarnette | 2008-03-19 | 309 | static VALUE | |
| 310 | length(VALUE self) | ||||
| 311 | { | ||||
| e18f74d8 » | jbarnette | 2008-04-14 | 312 | RubyLandProxy* proxy; | |
| 313 | Data_Get_Struct(self, RubyLandProxy, proxy); | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 314 | JSContext * context = johnson_get_current_context(proxy->runtime); | |
| 06cd4a94 » | matthewd | 2008-04-27 | 315 | ||
| 6a981ce4 » | tenderlove | 2008-05-30 | 316 | PREPARE_RUBY_JROOTS(context, 2); | |
| 95108d5a » | jbarnette | 2008-03-19 | 317 | ||
| df61324f » | matthewd | 2008-05-23 | 318 | jsval proxy_value; | |
| 319 | JCHECK(get_jsval_for_proxy(proxy, &proxy_value)); | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 320 | JROOT(proxy_value); | |
| 97b82442 » | matthewd | 2008-04-21 | 321 | ||
| f21981e9 » | jbarnette | 2008-05-20 | 322 | JSObject* value = JSVAL_TO_OBJECT(proxy_value); | |
| 06cd4a94 » | matthewd | 2008-04-27 | 323 | JROOT(value); | |
| 95108d5a » | jbarnette | 2008-03-19 | 324 | ||
| c7079b18 » | tenderlove | 2008-05-30 | 325 | if (JS_IsArrayObject(context, value)) | |
| 95108d5a » | jbarnette | 2008-03-19 | 326 | { | |
| 327 | jsuint length; | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 328 | JCHECK(JS_GetArrayLength(context, value, &length)); | |
| c1a7fbfe » | matthewd | 2008-04-24 | 329 | ||
| 06cd4a94 » | matthewd | 2008-04-27 | 330 | JRETURN_RUBY(INT2FIX(length)); | |
| 95108d5a » | jbarnette | 2008-03-19 | 331 | } | |
| 332 | else | ||||
| 333 | { | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 334 | JSIdArray* ids = JS_Enumerate(context, value); | |
| 06cd4a94 » | matthewd | 2008-04-27 | 335 | JCHECK(ids); | |
| 336 | VALUE length = INT2FIX(ids->length); | ||||
| 95108d5a » | jbarnette | 2008-03-19 | 337 | ||
| c7079b18 » | tenderlove | 2008-05-30 | 338 | JS_DestroyIdArray(context, ids); | |
| c1a7fbfe » | matthewd | 2008-04-24 | 339 | ||
| 06cd4a94 » | matthewd | 2008-04-27 | 340 | JRETURN_RUBY(length); | |
| 95108d5a » | jbarnette | 2008-03-19 | 341 | } | |
| 342 | } | ||||
| 343 | |||||
| 2fc27423 » | tenderlove | 2008-05-09 | 344 | /* | |
| 345 | * call-seq: | ||||
| dc2a8331 » | tenderlove | 2008-05-30 | 346 | * runtime | |
| 2fc27423 » | tenderlove | 2008-05-09 | 347 | * | |
| dc2a8331 » | tenderlove | 2008-05-30 | 348 | * Returns runtime. | |
| 2fc27423 » | tenderlove | 2008-05-09 | 349 | */ | |
| 350 | static VALUE | ||||
| dc2a8331 » | tenderlove | 2008-05-30 | 351 | runtime(VALUE self) | |
| 7084c002 » | tenderlove | 2008-04-09 | 352 | { | |
| e18f74d8 » | jbarnette | 2008-04-14 | 353 | RubyLandProxy* proxy; | |
| 354 | Data_Get_Struct(self, RubyLandProxy, proxy); | ||||
| dc2a8331 » | tenderlove | 2008-05-30 | 355 | return (VALUE)JS_GetRuntimePrivate(proxy->runtime->js); | |
| 7084c002 » | tenderlove | 2008-04-09 | 356 | } | |
| 357 | |||||
| 2fc27423 » | tenderlove | 2008-05-09 | 358 | /* | |
| 359 | * call-seq: | ||||
| 360 | * function_property?(name) | ||||
| 361 | * | ||||
| 362 | * Returns <code>true</code> if +name+ is a function property. | ||||
| 363 | */ | ||||
| 364 | static VALUE | ||||
| dfbd5bda » | jbarnette | 2008-03-18 | 365 | function_property_p(VALUE self, VALUE name) | |
| 366 | { | ||||
| 367 | Check_Type(name, T_STRING); | ||||
| 368 | |||||
| e18f74d8 » | jbarnette | 2008-04-14 | 369 | RubyLandProxy* proxy; | |
| 370 | Data_Get_Struct(self, RubyLandProxy, proxy); | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 371 | JSContext * context = johnson_get_current_context(proxy->runtime); | |
| 97b82442 » | matthewd | 2008-04-21 | 372 | ||
| 6a981ce4 » | tenderlove | 2008-05-30 | 373 | PREPARE_RUBY_JROOTS(context, 2); | |
| 06cd4a94 » | matthewd | 2008-04-27 | 374 | ||
| df61324f » | matthewd | 2008-05-23 | 375 | jsval proxy_value; | |
| 376 | JCHECK(get_jsval_for_proxy(proxy, &proxy_value)); | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 377 | JROOT(proxy_value); | |
| 97b82442 » | matthewd | 2008-04-21 | 378 | ||
| dfbd5bda » | jbarnette | 2008-03-18 | 379 | jsval js_value; | |
| 380 | |||||
| c7079b18 » | tenderlove | 2008-05-30 | 381 | JCHECK(JS_GetProperty(context, | |
| f21981e9 » | jbarnette | 2008-05-20 | 382 | JSVAL_TO_OBJECT(proxy_value), StringValueCStr(name), &js_value)); | |
| 97b82442 » | matthewd | 2008-04-21 | 383 | ||
| 06cd4a94 » | matthewd | 2008-04-27 | 384 | JROOT(js_value); | |
| 97b82442 » | matthewd | 2008-04-21 | 385 | ||
| c7079b18 » | tenderlove | 2008-05-30 | 386 | JSType type = JS_TypeOfValue(context, js_value); | |
| 97b82442 » | matthewd | 2008-04-21 | 387 | ||
| 06cd4a94 » | matthewd | 2008-04-27 | 388 | JRETURN_RUBY(type == JSTYPE_FUNCTION ? Qtrue : Qfalse); | |
| dfbd5bda » | jbarnette | 2008-03-18 | 389 | } | |
| 390 | |||||
| 2fc27423 » | tenderlove | 2008-05-09 | 391 | /* | |
| 392 | * call-seq: | ||||
| 393 | * call_function_property(name, arguments) | ||||
| 394 | * | ||||
| 395 | * Calls function +name+ with +arguments+. | ||||
| 396 | */ | ||||
| 397 | static VALUE | ||||
| dfbd5bda » | jbarnette | 2008-03-18 | 398 | call_function_property(int argc, VALUE* argv, VALUE self) | |
| 399 | { | ||||
| e18f74d8 » | jbarnette | 2008-04-14 | 400 | RubyLandProxy* proxy; | |
| 401 | Data_Get_Struct(self, RubyLandProxy, proxy); | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 402 | JSContext * context = johnson_get_current_context(proxy->runtime); | |
| b05fc61d » | matthewd | 2008-04-25 | 403 | ||
| 404 | if (argc < 1) | ||||
| 405 | rb_raise(rb_eArgError, "Function name required"); | ||||
| 406 | |||||
| 6a981ce4 » | tenderlove | 2008-05-30 | 407 | PREPARE_RUBY_JROOTS(context, 2); | |
| f21981e9 » | jbarnette | 2008-05-20 | 408 | ||
| df61324f » | matthewd | 2008-05-23 | 409 | jsval proxy_value; | |
| 410 | JCHECK(get_jsval_for_proxy(proxy, &proxy_value)); | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 411 | JROOT(proxy_value); | |
| 97b82442 » | matthewd | 2008-04-21 | 412 | ||
| dfbd5bda » | jbarnette | 2008-03-18 | 413 | jsval function; | |
| 414 | |||||
| c7079b18 » | tenderlove | 2008-05-30 | 415 | JCHECK(JS_GetProperty(context, | |
| f21981e9 » | jbarnette | 2008-05-20 | 416 | JSVAL_TO_OBJECT(proxy_value), StringValueCStr(argv[0]), &function)); | |
| 06cd4a94 » | matthewd | 2008-04-27 | 417 | ||
| 418 | JROOT(function); | ||||
| 3b26152f » | matthewd | 2008-04-26 | 419 | ||
| c7079b18 » | tenderlove | 2008-05-30 | 420 | JSType funtype = JS_TypeOfValue(context, function); | |
| dfbd5bda » | jbarnette | 2008-03-18 | 421 | ||
| 422 | // should never be anything but a function | ||||
| 3b26152f » | matthewd | 2008-04-26 | 423 | if (funtype != JSTYPE_FUNCTION) | |
| 06cd4a94 » | matthewd | 2008-04-27 | 424 | JERROR("Specified property \"%s\" isn't a function.", StringValueCStr(argv[0])); | |
| 3b26152f » | matthewd | 2008-04-26 | 425 | ||
| c7079b18 » | tenderlove | 2008-05-30 | 426 | JRETURN_RUBY(call_js_function_value(proxy->runtime, proxy_value, function, argc - 1, &(argv[1]))); | |
| dfbd5bda » | jbarnette | 2008-03-18 | 427 | } | |
| 428 | |||||
| 2fc27423 » | tenderlove | 2008-05-09 | 429 | /* | |
| 430 | * call-seq: | ||||
| 431 | * to_s | ||||
| 432 | * | ||||
| 433 | * Converts object to a string. | ||||
| 434 | */ | ||||
| 435 | static VALUE to_s(VALUE self) | ||||
| 436 | { | ||||
| 437 | RubyLandProxy* proxy; | ||||
| 438 | Data_Get_Struct(self, RubyLandProxy, proxy); | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 439 | JSContext * context = johnson_get_current_context(proxy->runtime); | |
| 2fc27423 » | tenderlove | 2008-05-09 | 440 | ||
| 6a981ce4 » | tenderlove | 2008-05-30 | 441 | PREPARE_RUBY_JROOTS(context, 1); | |
| f21981e9 » | jbarnette | 2008-05-20 | 442 | ||
| df61324f » | matthewd | 2008-05-23 | 443 | jsval proxy_value; | |
| 444 | JCHECK(get_jsval_for_proxy(proxy, &proxy_value)); | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 445 | JROOT(proxy_value); | |
| 446 | |||||
| c7079b18 » | tenderlove | 2008-05-30 | 447 | JSString* str = JS_ValueToString(context, proxy_value); | |
| 448 | JRETURN_RUBY(convert_js_string_to_ruby(proxy->runtime, str)); | ||||
| 2fc27423 » | tenderlove | 2008-05-09 | 449 | } | |
| 450 | |||||
| dfbd5bda » | jbarnette | 2008-03-18 | 451 | /////////////////////////////////////////////////////////////////////////// | |
| 452 | //// INFRASTRUCTURE BELOW HERE //////////////////////////////////////////// | ||||
| 453 | /////////////////////////////////////////////////////////////////////////// | ||||
| 454 | |||||
| e18f74d8 » | jbarnette | 2008-04-14 | 455 | static void finalize(RubyLandProxy* proxy) | |
| fe394493 » | jbarnette | 2008-03-17 | 456 | { | |
| c7079b18 » | tenderlove | 2008-05-30 | 457 | JSContext * context = johnson_get_current_context(proxy->runtime); | |
| 6a981ce4 » | tenderlove | 2008-05-30 | 458 | PREPARE_RUBY_JROOTS(context, 0); | |
| df61324f » | matthewd | 2008-05-23 | 459 | jsval proxy_value; | |
| 460 | JCHECK_RUBY(get_jsval_for_proxy(proxy, &proxy_value)); | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 461 | ||
| fe394493 » | jbarnette | 2008-03-17 | 462 | // could get finalized after the context has been freed | |
| 6a981ce4 » | tenderlove | 2008-05-30 | 463 | if (proxy->runtime && proxy->runtime->jsids) | |
| fe394493 » | jbarnette | 2008-03-17 | 464 | { | |
| 465 | // remove this proxy from the OID map | ||||
| 6a981ce4 » | tenderlove | 2008-05-30 | 466 | JS_HashTableRemove(proxy->runtime->jsids, (void *)proxy_value); | |
| fe394493 » | jbarnette | 2008-03-17 | 467 | ||
| 468 | // remove our GC handle on the JS value | ||||
| c7079b18 » | tenderlove | 2008-05-30 | 469 | JS_DeleteProperty(context, proxy->runtime->gcthings, proxy->key); | |
| f8a92fab » | jbarnette | 2008-03-17 | 470 | ||
| 6a981ce4 » | tenderlove | 2008-05-30 | 471 | proxy->runtime = 0; | |
| fe394493 » | jbarnette | 2008-03-17 | 472 | } | |
| 473 | |||||
| 474 | free(proxy); | ||||
| 475 | } | ||||
| 476 | |||||
| 0746d926 » | matthewd | 2008-04-21 | 477 | bool ruby_value_is_proxy(VALUE maybe_proxy) | |
| 89d849d3 » | jbarnette | 2008-03-23 | 478 | { | |
| 479 | return proxy_class == CLASS_OF(maybe_proxy); | ||||
| 480 | } | ||||
| 481 | |||||
| 0704a464 » | tenderlove | 2008-05-30 | 482 | JSBool unwrap_ruby_land_proxy(JohnsonRuntime* runtime, VALUE wrapped, jsval* retval) | |
| 89d849d3 » | jbarnette | 2008-03-23 | 483 | { | |
| c7079b18 » | tenderlove | 2008-05-30 | 484 | JSContext * context = johnson_get_current_context(runtime); | |
| 89d849d3 » | jbarnette | 2008-03-23 | 485 | assert(ruby_value_is_proxy(wrapped)); | |
| 486 | |||||
| df61324f » | matthewd | 2008-05-23 | 487 | PREPARE_JROOTS(context, 0); | |
| 488 | |||||
| e18f74d8 » | jbarnette | 2008-04-14 | 489 | RubyLandProxy* proxy; | |
| 490 | Data_Get_Struct(wrapped, RubyLandProxy, proxy); | ||||
| 89d849d3 » | jbarnette | 2008-03-23 | 491 | ||
| df61324f » | matthewd | 2008-05-23 | 492 | JCHECK(get_jsval_for_proxy(proxy, retval)); | |
| 493 | JRETURN; | ||||
| 89d849d3 » | jbarnette | 2008-03-23 | 494 | } | |
| 495 | |||||
| 3680b337 » | tenderlove | 2008-05-30 | 496 | VALUE make_ruby_land_proxy(JohnsonRuntime* runtime, jsval value) | |
| 3c24fe99 » | jbarnette | 2008-04-01 | 497 | { | |
| 3680b337 » | tenderlove | 2008-05-30 | 498 | VALUE id = (VALUE)JS_HashTableLookup(runtime->jsids, (void *)value); | |
| c7079b18 » | tenderlove | 2008-05-30 | 499 | JSContext * context = johnson_get_current_context(runtime); | |
| 3c24fe99 » | jbarnette | 2008-04-01 | 500 | ||
| 501 | if (id) | ||||
| 502 | { | ||||
| 503 | // if we already have a proxy, return it | ||||
| 504 | return rb_funcall(rb_const_get(rb_cObject, | ||||
| 505 | rb_intern("ObjectSpace")), rb_intern("_id2ref"), 1, id); | ||||
| 506 | } | ||||
| 507 | else | ||||
| f21981e9 » | jbarnette | 2008-05-20 | 508 | { | |
| 3c24fe99 » | jbarnette | 2008-04-01 | 509 | // otherwise make one and cache it | |
| e18f74d8 » | jbarnette | 2008-04-14 | 510 | RubyLandProxy* our_proxy; | |
| 511 | VALUE proxy = Data_Make_Struct(proxy_class, RubyLandProxy, 0, finalize, our_proxy); | ||||
| 3c24fe99 » | jbarnette | 2008-04-01 | 512 | ||
| 2b17b4dd » | matthewd | 2008-05-04 | 513 | PREPARE_RUBY_JROOTS(context, 1); | |
| 06cd4a94 » | matthewd | 2008-04-27 | 514 | JROOT(value); | |
| 97b82442 » | matthewd | 2008-04-21 | 515 | ||
| f21981e9 » | jbarnette | 2008-05-20 | 516 | // root the value for JS GC and lookups | |
| 517 | sprintf(our_proxy->key, "%x", (int)value); | ||||
| 518 | |||||
| c7079b18 » | tenderlove | 2008-05-30 | 519 | JCHECK(JS_SetProperty(context, runtime->gcthings, our_proxy->key, &value)); | |
| f21981e9 » | jbarnette | 2008-05-20 | 520 | ||
| 3680b337 » | tenderlove | 2008-05-30 | 521 | our_proxy->runtime = runtime; | |
| 3c24fe99 » | jbarnette | 2008-04-01 | 522 | ||
| 06cd4a94 » | matthewd | 2008-04-27 | 523 | // put the proxy OID in the id map | |
| 3680b337 » | tenderlove | 2008-05-30 | 524 | JCHECK(JS_HashTableAdd(runtime->jsids, (void *)value, (void *)rb_obj_id(proxy))); | |
| 3c24fe99 » | jbarnette | 2008-04-01 | 525 | ||
| 06cd4a94 » | matthewd | 2008-04-27 | 526 | JRETURN_RUBY(proxy); | |
| 3c24fe99 » | jbarnette | 2008-04-01 | 527 | } | |
| 528 | } | ||||
| 529 | |||||
| fe394493 » | jbarnette | 2008-03-17 | 530 | void init_Johnson_SpiderMonkey_Proxy(VALUE spidermonkey) | |
| 531 | { | ||||
| 2fc27423 » | tenderlove | 2008-05-09 | 532 | /* HACK: These comments are *only* to make RDoc happy. | |
| 533 | VALUE johnson = rb_define_module("Johnson"); | ||||
| 534 | VALUE spidermonkey = rb_define_module_under(johnson, "SpiderMonkey"); | ||||
| 535 | */ | ||||
| 536 | |||||
| 537 | /* RubyLandProxy class. */ | ||||
| e18f74d8 » | jbarnette | 2008-04-14 | 538 | proxy_class = rb_define_class_under(spidermonkey, "RubyLandProxy", rb_cObject); | |
| a2a230ef » | jbarnette | 2008-03-17 | 539 | ||
| 82b9c932 » | jbarnette | 2008-03-17 | 540 | rb_define_method(proxy_class, "[]", get, 1); | |
| a2a230ef » | jbarnette | 2008-03-17 | 541 | rb_define_method(proxy_class, "[]=", set, 2); | |
| 2660dba4 » | jbarnette | 2008-03-18 | 542 | rb_define_method(proxy_class, "function?", function_p, 0); | |
| 9d68f23b » | jbarnette | 2008-03-18 | 543 | rb_define_method(proxy_class, "respond_to?", respond_to_p, 1); | |
| f062b403 » | jbarnette | 2008-03-19 | 544 | rb_define_method(proxy_class, "each", each, 0); | |
| 95108d5a » | jbarnette | 2008-03-19 | 545 | rb_define_method(proxy_class, "length", length, 0); | |
| 70adb2d1 » | matthewd | 2008-04-25 | 546 | rb_define_method(proxy_class, "to_s", to_s, 0); | |
| dfbd5bda » | jbarnette | 2008-03-18 | 547 | ||
| 7084c002 » | tenderlove | 2008-04-09 | 548 | rb_define_private_method(proxy_class, "native_call", native_call, -1); | |
| dc2a8331 » | tenderlove | 2008-05-30 | 549 | rb_define_private_method(proxy_class, "runtime", runtime, 0); | |
| dfbd5bda » | jbarnette | 2008-03-18 | 550 | rb_define_private_method(proxy_class, "function_property?", function_property_p, 1); | |
| 551 | rb_define_private_method(proxy_class, "call_function_property", call_function_property, -1); | ||||
| fe394493 » | jbarnette | 2008-03-17 | 552 | } | |








