Skip to content
This repository has been archived by the owner on Aug 18, 2018. It is now read-only.

Commit

Permalink
Simple implementation for working numeric array indexes.
Browse files Browse the repository at this point in the history
  • Loading branch information
jbarnette committed Apr 20, 2008
1 parent b7616dd commit e0d5bf2
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 14 deletions.
27 changes: 27 additions & 0 deletions ext/spidermonkey/js_land_proxy.c
Expand Up @@ -73,6 +73,11 @@ static JSBool attribute_p(VALUE self, char* name)
rb_intern("js_property?"), 2, self, ID2SYM(rb_id));
}

static JSBool indexable_p(VALUE self)
{
rb_funcall(self, rb_intern("respond_to?"), 1, ID2SYM(rb_intern("[]")));
}

static JSBool has_key_p(VALUE self, char* name)
{
return rb_funcall(self, rb_intern("respond_to?"), 1, ID2SYM(rb_intern("[]")))
Expand Down Expand Up @@ -119,6 +124,17 @@ static JSBool get(JSContext* js_context, JSObject* obj, jsval id, jsval* retval)
VALUE self;
assert(self = (VALUE)JS_GetInstancePrivate(context->js, obj, JS_GET_CLASS(context->js, obj), NULL));

// Short-circuit for numeric indexes

if (JSVAL_IS_INT(id))
{
if (indexable_p(self))
*retval = convert_to_js(context,
rb_funcall(self, rb_intern("[]"), 1, INT2FIX(JSVAL_TO_INT(id))));

return JS_TRUE;
}

char* name = JS_GetStringBytes(JSVAL_TO_STRING(id));
VALUE ruby_id = rb_intern(name);

Expand Down Expand Up @@ -218,6 +234,17 @@ static JSBool set(JSContext* js_context, JSObject* obj, jsval id, jsval* value)
VALUE self;
assert(self = (VALUE)JS_GetInstancePrivate(context->js, obj, JS_GET_CLASS(context->js, obj), NULL));

// Short-circuit for numeric indexes

if (JSVAL_IS_INT(id))
{
if (indexable_p(self))
rb_funcall(self, rb_intern("[]="),
2, INT2FIX(JSVAL_TO_INT(id)), convert_to_ruby(context, *value));

return JS_TRUE;
}

char* key = JS_GetStringBytes(JSVAL_TO_STRING(id));
VALUE ruby_key = rb_str_new2(key);

Expand Down
36 changes: 36 additions & 0 deletions test/johnson/conversions/array_test.rb
@@ -0,0 +1,36 @@
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))

module Johnson
module Conversions
class ArrayTest < Johnson::TestCase
def setup
@context = Johnson::Context.new
end

def test_array_index_get
@context[:list] = [1, 2, 3, 4]
assert_equal(1, @context.evaluate("list[0]"))
end

def test_array_index_set
@context[:list] = []
@context.evaluate("list[0] = 42")
assert_equal(42, @context[:list][0])
end

def test_array_works_with_for_in
list = [1, 2, 3, 4]

@context['alert'] = lambda { |x| p x }
@context['list'] = list
@context.evaluate("
var new_list = [];
for(x in list) {
new_list.push(x + 1);
}
")
assert_equal(list.map { |x| x + 1}, @context['new_list'].to_a)
end
end
end
end
14 changes: 0 additions & 14 deletions test/johnson/spidermonkey/js_land_proxy_test.rb
Expand Up @@ -79,20 +79,6 @@ def test_catch_missing_require
}
")
end

def test_array_gets_returned
list = [1,2,3,4]

@context['alert'] = lambda { |x| p x }
@context['list'] = list
@context.evaluate("
var new_list = [];
for(x in list) {
new_list.push(x + 1);
}
")
assert_equal(list.map { |x| x + 1}, @context['new_list'].to_a)
end

def test_proxies_get_reused
@context["foo"] = @context["bar"] = Foo.new
Expand Down

0 comments on commit e0d5bf2

Please sign in to comment.