]> git.saurik.com Git - cycript.git/commitdiff
Improve support for char values (from JS strings).
authorJay Freeman (saurik) <saurik@saurik.com>
Sat, 9 Jan 2016 03:37:26 +0000 (19:37 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Sat, 9 Jan 2016 03:37:26 +0000 (19:37 -0800)
Execute.cpp

index 1a49f26d97f268374897387490356d8c60f22329..0f27732ce57d36bb12392bb0b89f34c363751389 100644 (file)
@@ -716,7 +716,6 @@ void Primitive<Type_>::PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi
     *reinterpret_cast<Type_ *>(data) = CYCastDouble(context, value); \
 }
 
-CYPoolFFI_(char)
 CYPoolFFI_(double)
 CYPoolFFI_(float)
 CYPoolFFI_(signed char)
@@ -735,6 +734,18 @@ CYPoolFFI_(signed __int128)
 CYPoolFFI_(unsigned __int128)
 #endif
 
+template <>
+void Primitive<char>::PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const {
+    if (JSValueGetType(context, value) != kJSTypeString)
+        *reinterpret_cast<char *>(data) = CYCastDouble(context, value);
+    else {
+        CYJSString script(context, value);
+        auto string(CYCastUTF16String(script));
+        _assert(string.size == 1);
+        *reinterpret_cast<char *>(data) = string.data[0];
+    }
+}
+
 void Void::PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const {
     _assert(false);
 }
@@ -841,7 +852,6 @@ JSValueRef Primitive<Type_>::FromFFI(JSContextRef context, ffi_type *ffi, void *
 }
 
 CYFromFFI_(bool)
-CYFromFFI_(char)
 CYFromFFI_(double)
 CYFromFFI_(float)
 CYFromFFI_(signed char)
@@ -860,6 +870,16 @@ CYFromFFI_(signed __int128)
 CYFromFFI_(unsigned __int128)
 #endif
 
+template <>
+JSValueRef Primitive<char>::FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const {
+    uint16_t string(uint8_t(*reinterpret_cast<char *>(data)));
+    JSValueRef value(CYCastJSValue(context, CYJSString(CYUTF16String(&string, 1))));
+    JSObjectRef typed(_jsccall(JSObjectCallAsConstructor, context, CYGetCachedObject(context, CYJSString("String")), 1, &value));
+    CYSetProperty(context, typed, cyt_s, CYMakeType(context, sig::Primitive<char>()), kJSPropertyAttributeDontEnum);
+    CYSetPrototype(context, typed, CYGetCachedValue(context, CYJSString("Character_prototype")));
+    return typed;
+}
+
 JSValueRef Void::FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const {
     return CYJSUndefined(context);
 }
@@ -1005,8 +1025,8 @@ static JSValueRef CString_getProperty(JSContextRef context, JSObjectRef object,
     else if (!CYGetOffset(pool, context, property, offset))
         return NULL;
 
-    uint16_t value(uint8_t(internal->value_[offset]));
-    return CYCastJSValue(context, CYJSString(CYUTF16String(&value, 1)));
+    sig::Primitive<char> type;
+    return type.FromFFI(context, type.GetFFI(pool), internal->value_ + offset, false, NULL);
 } CYCatch(NULL) }
 
 static bool CString_setProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef *exception) { CYTry {
@@ -1019,9 +1039,8 @@ static bool CString_setProperty(JSContextRef context, JSObjectRef object, JSStri
     else if (!CYGetOffset(pool, context, property, offset))
         return false;
 
-    auto data(CYCastUTF16String(CYJSString(context, value)));
-    _assert(data.size == 1);
-    internal->value_[offset] = data.data[0];
+    sig::Primitive<char> type;
+    type.PoolFFI(NULL, context, type.GetFFI(pool), internal->value_ + offset, value);
     return true;
 } CYCatch(false) }
 
@@ -2474,6 +2493,11 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) {
     CYSetProperty(context, cy, CYJSString("Type_prototype"), Type_prototype);
     CYSetProperty(context, cycript, CYJSString("Type"), Type);
 
+    JSObjectRef Character_prototype(JSObjectMake(context, NULL, NULL));
+    CYSetPrototype(context, Character_prototype, String_prototype);
+    CYSetProperty(context, cy, CYJSString("Character_prototype"), Character_prototype);
+    CYSetProperty(context, Character_prototype, CYJSString("valueOf"), _jsccall(JSEvaluateScript, context, CYJSString("(function(){return this.charCodeAt(0);})"), NULL, NULL, 0));
+
     JSObjectRef modules(JSObjectMake(context, NULL, NULL));
     CYSetProperty(context, cy, CYJSString("modules"), modules);