Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Let SpiderMonkey do the UTF-8 string conversion.

  • Loading branch information...
commit 104d4ca795fe4a3f8c0c31d45909af22948901a9 1 parent afb6861
@matthewd matthewd authored
View
29 ext/spidermonkey/conversions.c
@@ -113,9 +113,15 @@ JSBool convert_to_js(JohnsonRuntime* runtime, VALUE ruby, jsval* retval)
case T_STRING:
{
- VALUE encoded_ruby = CALL_RUBY_WRAPPER(rb_funcall_0, ruby, RB_INTERN("utf8_to_utf16"), 0);
- CALL_RUBY_WRAPPER(rb_string_value, &encoded_ruby);
- JSString* str = JS_NewUCStringCopyN(context, StringValuePtr(encoded_ruby), (size_t) StringValueLen(encoded_ruby) / 2);
+ CALL_RUBY_WRAPPER(rb_string_value, &ruby);
+ const char * src = StringValuePtr(ruby);
+ const size_t srclen = StringValueLen(ruby);
+ size_t dstlen = 0;
+ JCHECK(JS_DecodeBytes(context, src, srclen, NULL, &dstlen));
+ jschar* dstchars = JS_malloc(context, sizeof(jschar) * (1 + dstlen));
+ JCHECK(dstchars);
+ JCHECK(JS_DecodeBytes(context, src, srclen, dstchars, &dstlen));
+ JSString* str = JS_NewUCString(context, dstchars, dstlen);
JCHECK(str);
*retval = STRING_TO_JSVAL(str);
JRETURN;
@@ -174,11 +180,18 @@ VALUE convert_js_string_to_ruby(JohnsonRuntime* runtime, JSString* str)
JSContext * context = johnson_get_current_context(runtime);
PREPARE_RUBY_JROOTS(context, 1);
JROOT(str);
- jschar* chars = JS_GetStringChars(str);
- JCHECK(chars);
- size_t len = JS_GetStringLength(str);
- VALUE raw_ruby = rb_str_new(chars, len * 2);
- JRETURN_RUBY(RB_FUNCALL_0(raw_ruby, RB_INTERN("utf16_to_utf8")));
+ jschar* src = JS_GetStringChars(str);
+ JCHECK(src);
+ size_t srclen = JS_GetStringLength(str);
+ size_t dstlen = 0;
+ JCHECK(JS_EncodeCharacters(context, src, srclen, NULL, &dstlen));
+ char* dst = JS_malloc(context, sizeof(char) * (1 + dstlen));
+ JCHECK(dst);
+ JCHECK(JS_EncodeCharacters(context, src, srclen, dst, &dstlen));
+ // This will leak dst if rb_str_new raises
+ VALUE ruby_str = rb_str_new(dst, dstlen);
+ JS_free(context, dst);
+ JRETURN_RUBY(ruby_str);
}
static VALUE convert_regexp_to_ruby(JohnsonRuntime* runtime, jsval regexp)
View
2  ext/spidermonkey/spidermonkey.c
@@ -6,6 +6,8 @@
void Init_spidermonkey()
{
+ JS_SetCStringsAreUTF8();
+
VALUE johnson = rb_define_module("Johnson"); // FIXME: this belongs outside the extension
VALUE spidermonkey = rb_define_module_under(johnson, "SpiderMonkey");
View
15 lib/johnson/spidermonkey/ruby_land_proxy.rb
@@ -1,18 +1,3 @@
-require 'iconv'
-class String
- JavaScriptToRuby = Iconv.open('UTF-8', 'UTF-16')
- JavaScriptToRuby.iconv("\000x\000x")
- RubyToJavaScript = Iconv.open('UTF-16', 'UTF-8')
- RubyToJavaScript.iconv('xx')
-
- def utf16_to_utf8
- JavaScriptToRuby.iconv(self)
- end
- def utf8_to_utf16
- RubyToJavaScript.iconv(self)
- end
-end
-
module Johnson #:nodoc:
module SpiderMonkey #:nodoc:
class RubyLandProxy # native
View
8 test/johnson/conversions/string_test.rb
@@ -23,10 +23,14 @@ def test_strings_are_copies
end
def test_multibyte_character_roundtrip_js
- s = @runtime.evaluate("'\\u20AC'")
- @runtime[:s] = s
+ assert_equal(1, @runtime.evaluate("'\\u20AC'.length"))
+ assert_equal(0x20ac, @runtime.evaluate("'\\u20AC'.charCodeAt(0)"))
+ assert_equal(0x0000, @runtime.evaluate("'\\u0000'.charCodeAt(0)"))
+ @runtime[:s] = "\xe2\x82\xac"
+ assert_equal(0x20ac, @runtime.evaluate("s.charCodeAt(0)"))
assert_equal('', @runtime.evaluate("s.substr(1)"))
assert_equal(1, @runtime.evaluate("s.length"))
+ assert_equal("\xe2\x82\xac", @runtime.evaluate("s"))
assert_js("'\\u20ac' == s")
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.