Esempio n. 1
0
/*
 * call-seq:
 *   []=(name, value)
 *
 * Sets this JavaScript object's +name+ property to +value+.
 */
static VALUE
set(VALUE self, VALUE name, VALUE value)
{
  RubyLandProxy* proxy;
  Data_Get_Struct(self, RubyLandProxy, proxy);
  JSContext * context = johnson_get_current_context(proxy->runtime);
  
  PREPARE_RUBY_JROOTS(context, 2);
  
  jsval proxy_value;
  JCHECK(get_jsval_for_proxy(proxy, &proxy_value));
  JROOT(proxy_value);

  jsval js_value;
  JCHECK(convert_to_js(proxy->runtime, value, &js_value));
  
  JROOT(js_value);

  switch(TYPE(name)) {
    case T_FIXNUM:
      JCHECK(JS_SetElement(context,
              JSVAL_TO_OBJECT(proxy_value), (jsint)(NUM2INT(name)), &js_value));
      break;
    case T_SYMBOL:
      name = RB_FUNCALL_0(name, RB_INTERN("to_s"));
    default:
      CALL_RUBY_WRAPPER(rb_string_value_cstr, &name);
      JCHECK(JS_SetProperty(context,
            JSVAL_TO_OBJECT(proxy_value), StringValueCStr(name), &js_value));
      break;
  }

  JRETURN_RUBY(value);
}
Esempio n. 2
0
/*
 * call-seq:
 *   call_function_property(name, arguments)
 *
 * Calls this JavaScript object's +name+ method, passing the given
 * arguments.
 *
 * Equivalent to:
 *    proxy[name].native_call(proxy, *arguments)
 */
static VALUE
call_function_property(int argc, VALUE* argv, VALUE self)
{
  RubyLandProxy* proxy;
  Data_Get_Struct(self, RubyLandProxy, proxy);
  JSContext * context = johnson_get_current_context(proxy->runtime);

  if (argc < 1)
    rb_raise(rb_eArgError, "Function name required");

  PREPARE_RUBY_JROOTS(context, 2);
  
  jsval proxy_value;
  JCHECK(get_jsval_for_proxy(proxy, &proxy_value));
  JROOT(proxy_value);

  jsval function;

  VALUE name = argv[0];
  CALL_RUBY_WRAPPER(rb_string_value_cstr, &name);
  
  JCHECK(JS_GetProperty(context,
    JSVAL_TO_OBJECT(proxy_value), StringValueCStr(name), &function));

  JROOT(function);

  // should never be anything but a function
  if (!JS_ObjectIsFunction(context, function))
    JERROR("Specified property \"%s\" isn't a function.", StringValueCStr(name));

  REMOVE_JROOTS;

  return call_js_function_value(proxy->runtime, proxy_value, function, argc - 1, &(argv[1]));
}
Esempio n. 3
0
/*
 * call-seq:
 *   respond_to?(symbol)
 *
 * Returns <code>true</code> if this JavaScript object responds to the
 * named method.
 */
static VALUE
respond_to_p(int argc, const VALUE* argv, VALUE self)
{
  VALUE sym, priv;

  rb_scan_args(argc, argv, "11", &sym, &priv);

  RubyLandProxy* proxy;
  Data_Get_Struct(self, RubyLandProxy, proxy);

  JSContext * context = johnson_get_current_context(proxy->runtime);
  PREPARE_RUBY_JROOTS(context, 2);
  
  VALUE stringval = rb_funcall(sym, rb_intern("to_s"), 0);
  char* name = StringValuePtr(stringval);
  
  // assignment is always okay
  if (name[strlen(name) - 1] == '=')
    JRETURN_RUBY(Qtrue);
  
  jsval proxy_value;
  JCHECK(get_jsval_for_proxy(proxy, &proxy_value));
  JROOT(proxy_value);

  JSObject *obj;
  JSBool found;
  
  JCHECK(JS_ValueToObject(context, proxy_value, &obj));
  JROOT(obj);

  JCHECK(JS_HasProperty(context, obj, name, &found));

  JRETURN_RUBY(found ? Qtrue : CALL_RUBY_WRAPPER(rb_call_super, argc, argv));
}
Esempio n. 4
0
static VALUE convert_regexp_to_ruby(JohnsonRuntime* runtime, jsval regexp)
{
  JSContext * context = johnson_get_current_context(runtime);
  PREPARE_RUBY_JROOTS(context, 1);
  JROOT(regexp);
  JSRegExp* re = (JSRegExp*)JS_GetPrivate(context, JSVAL_TO_OBJECT(regexp));

  JRETURN_RUBY(CALL_RUBY_WRAPPER(rb_funcall_2, rb_cRegexp, rb_intern("new"), 2,
    convert_js_string_to_ruby(runtime, re->source),
    INT2NUM((long)re->flags)));
}
Esempio n. 5
0
static JSBool convert_symbol_to_js(JohnsonRuntime* runtime, VALUE symbol, jsval* retval)
{
  JSContext * context = johnson_get_current_context(runtime);
  PREPARE_JROOTS(context, 2);

  VALUE to_s = CALL_RUBY_WRAPPER(rb_funcall_0, symbol, rb_intern("to_s"), 0);
  jsval name = STRING_TO_JSVAL(JS_NewStringCopyN(context, StringValuePtr(to_s), (size_t) StringValueLen(to_s)));

  JROOT(name);

  // calls Johnson.symbolize(name) in JS-land. See lib/prelude.js

  jsval nsJohnson;    
  JCHECK(JS_GetProperty(context, runtime->global, "Johnson", &nsJohnson));
  JROOT(nsJohnson);

  JCHECK(JS_CallFunctionName(context, JSVAL_TO_OBJECT(nsJohnson), "symbolize", 1, &name, retval));

  JRETURN;
}
Esempio n. 6
0
/*
 * call-seq:
 *   each {| element | block }
 *   each {| name, value | block }
 *
 * Calls <em>block</em> with each item in this JavaScript array, or with
 * each +name+/+value+ pair (like a Hash) for any other JavaScript
 * object.
 */
static VALUE
each(VALUE self)
{
  RubyLandProxy* proxy;
  Data_Get_Struct(self, RubyLandProxy, proxy);
  JSContext * context = johnson_get_current_context(proxy->runtime);
  
  PREPARE_RUBY_JROOTS(context, 5);
  
  jsval proxy_value;
  JCHECK(get_jsval_for_proxy(proxy, &proxy_value));
  JROOT(proxy_value);

  JSObject* value = JSVAL_TO_OBJECT(proxy_value);
  JROOT(value);
  
  // arrays behave like you'd expect, indexes in order
  if (JS_IsArrayObject(context, value))
  {
    jsuint length;
    JCHECK(JS_GetArrayLength(context, value, &length));
    
    jsuint i = 0;
    for (i = 0; i < length; ++i)
    {
      jsval element;
      JCHECK(JS_GetElement(context, value, (signed) i, &element));
      CALL_RUBY_WRAPPER(rb_yield, CONVERT_TO_RUBY(proxy->runtime, element));
    }
  }
  else
  {
    // not an array? behave like each on Hash; yield [key, value]
    JSIdArray* ids = JS_Enumerate(context, value);
    JCHECK(ids);

    JCLEANUP(destroy_id_array, ids);

    int i;
    for (i = 0; i < ids->length; ++i)
    {
      jsval js_key, js_value;

      JCHECK(JS_IdToValue(context, ids->vector[i], &js_key));
      JROOT(js_key);

      if (JSVAL_IS_STRING(js_key))
      {
        // regular properties have string keys
        JCHECK(JS_GetProperty(context, value,
          JS_GetStringBytes(JSVAL_TO_STRING(js_key)), &js_value));
      }
      else
      {
        // it's a numeric property, use array access
        JCHECK(JS_GetElement(context, value,
          JSVAL_TO_INT(js_key), &js_value));
      }
      JROOT(js_value);

      VALUE key = CONVERT_TO_RUBY(proxy->runtime, js_key);
      VALUE value = CONVERT_TO_RUBY(proxy->runtime, js_value);

      CALL_RUBY_WRAPPER(rb_yield, rb_ary_new3(2L, key, value));

      JUNROOT(js_value);
      JUNROOT(js_key);
    }
  }

  JRETURN_RUBY(self);
}