1 /* Cycript - Optimizing JavaScript Compiler/Runtime 
   2  * Copyright (C) 2009-2015  Jay Freeman (saurik) 
   5 /* GNU Affero General Public License, Version 3 {{{ */ 
   7  * This program is free software: you can redistribute it and/or modify 
   8  * it under the terms of the GNU Affero General Public License as published by 
   9  * the Free Software Foundation, either version 3 of the License, or 
  10  * (at your option) any later version. 
  12  * This program is distributed in the hope that it will be useful, 
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15  * GNU Affero General Public License for more details. 
  17  * You should have received a copy of the GNU Affero General Public License 
  18  * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  22 #include "cycript.hpp" 
  41 #include "sig/parse.hpp" 
  42 #include "sig/ffi_type.hpp" 
  47 #include "Execute.hpp" 
  48 #include "Internal.hpp" 
  49 #include "JavaScript.hpp" 
  50 #include "Pooling.hpp" 
  53 char *sqlite3_column_pooled(CYPool 
&pool
, sqlite3_stmt 
*stmt
, int n
) { 
  54     if (const unsigned char *value 
= sqlite3_column_text(stmt
, n
)) 
  55         return pool
.strdup(reinterpret_cast<const char *>(value
)); 
  59 static std::vector
<CYHook 
*> &GetHooks() { 
  60     static std::vector
<CYHook 
*> hooks
; 
  64 CYRegisterHook::CYRegisterHook(CYHook 
*hook
) { 
  65     GetHooks().push_back(hook
); 
  68 /* JavaScript Properties {{{ */ 
  69 bool CYHasProperty(JSContextRef context
, JSObjectRef object
, JSStringRef name
) { 
  70     return JSObjectHasProperty(context
, object
, name
); 
  73 JSValueRef 
CYGetProperty(JSContextRef context
, JSObjectRef object
, size_t index
) { 
  74     return _jsccall(JSObjectGetPropertyAtIndex
, context
, object
, index
); 
  77 JSValueRef 
CYGetProperty(JSContextRef context
, JSObjectRef object
, JSStringRef name
) { 
  78     return _jsccall(JSObjectGetProperty
, context
, object
, name
); 
  81 void CYSetProperty(JSContextRef context
, JSObjectRef object
, size_t index
, JSValueRef value
) { 
  82     _jsccall(JSObjectSetPropertyAtIndex
, context
, object
, index
, value
); 
  85 void CYSetProperty(JSContextRef context
, JSObjectRef object
, JSStringRef name
, JSValueRef value
, JSPropertyAttributes attributes
) { 
  86     _jsccall(JSObjectSetProperty
, context
, object
, name
, value
, attributes
); 
  89 void CYSetProperty(JSContextRef context
, JSObjectRef object
, JSStringRef name
, JSValueRef (*callback
)(JSContextRef
, JSObjectRef
, JSObjectRef
, size_t, const JSValueRef
[], JSValueRef 
*), JSPropertyAttributes attributes
) { 
  90     CYSetProperty(context
, object
, name
, JSObjectMakeFunctionWithCallback(context
, name
, callback
), attributes
); 
  93 void CYSetPrototype(JSContextRef context
, JSObjectRef object
, JSValueRef value
) { 
  94     JSObjectSetPrototype(context
, object
, value
); 
  95     _assert(CYIsStrictEqual(context
, JSObjectGetPrototype(context
, object
), value
)); 
  98 /* JavaScript Strings {{{ */ 
  99 JSStringRef 
CYCopyJSString(const char *value
) { 
 100     return value 
== NULL 
? NULL 
: JSStringCreateWithUTF8CString(value
); 
 103 JSStringRef 
CYCopyJSString(JSStringRef value
) { 
 104     return value 
== NULL 
? NULL 
: JSStringRetain(value
); 
 107 JSStringRef 
CYCopyJSString(CYUTF8String value
) { 
 108     if (memchr(value
.data
, '\0', value
.size
) != NULL
) { 
 110         return CYCopyJSString(pool
.memdup(value
.data
, value
.size
)); 
 111     } else if (value
.data
[value
.size
] != '\0') { 
 113         return CYCopyJSString(CYPoolUTF16String(pool
, value
)); 
 115         return CYCopyJSString(value
.data
); 
 119 JSStringRef 
CYCopyJSString(CYUTF16String value
) { 
 120     return JSStringCreateWithCharacters(value
.data
, value
.size
); 
 123 JSStringRef 
CYCopyJSString(JSContextRef context
, JSValueRef value
) { 
 124     if (JSValueIsNull(context
, value
)) 
 126     return _jsccall(JSValueToStringCopy
, context
, value
); 
 129 static CYUTF16String 
CYCastUTF16String(JSStringRef value
) { 
 130     return CYUTF16String(JSStringGetCharactersPtr(value
), JSStringGetLength(value
)); 
 133 CYUTF8String 
CYPoolUTF8String(CYPool 
&pool
, JSContextRef context
, JSStringRef value
) { 
 134     return CYPoolUTF8String(pool
, CYCastUTF16String(value
)); 
 137 const char *CYPoolCString(CYPool 
&pool
, JSContextRef context
, JSStringRef value
) { 
 138     CYUTF8String 
utf8(CYPoolUTF8String(pool
, context
, value
)); 
 139     _assert(memchr(utf8
.data
, '\0', utf8
.size
) == NULL
); 
 143 const char *CYPoolCString(CYPool 
&pool
, JSContextRef context
, JSValueRef value
) { 
 144     return JSValueIsNull(context
, value
) ? NULL 
: CYPoolCString(pool
, context
, CYJSString(context
, value
)); 
 147 /* Index Offsets {{{ */ 
 148 size_t CYGetIndex(CYPool 
&pool
, JSContextRef context
, JSStringRef value
) { 
 149     return CYGetIndex(CYPoolUTF8String(pool
, context
, value
)); 
 153 static JSClassRef All_
; 
 154 static JSClassRef Context_
; 
 155 static JSClassRef CString_
; 
 157 static JSClassRef Global_
; 
 158 static JSClassRef Pointer_
; 
 159 static JSClassRef Struct_
; 
 164 JSStringRef length_s
; 
 165 JSStringRef message_s
; 
 168 JSStringRef prototype_s
; 
 170 JSStringRef splice_s
; 
 171 JSStringRef toCYON_s
; 
 172 JSStringRef toJSON_s
; 
 173 JSStringRef toPointer_s
; 
 174 JSStringRef toString_s
; 
 177 static sqlite3 
*database_
; 
 179 static JSStringRef Result_
; 
 181 void CYFinalize(JSObjectRef object
) { 
 182     CYData 
*internal(reinterpret_cast<CYData 
*>(JSObjectGetPrivate(object
))); 
 183     _assert(internal
->count_ 
!= _not(unsigned)); 
 184     if (--internal
->count_ 
== 0) 
 188 void Structor_(CYPool 
&pool
, sig::Type 
*&type
) { 
 190         type
->primitive 
== sig::pointer_P 
&& 
 191         type
->data
.data
.type
->primitive 
== sig::struct_P 
&& 
 192         type
->data
.data
.type
->name 
!= NULL 
&& 
 193         strcmp(type
->data
.data
.type
->name
, "_objc_class") == 0 
 195         type
->primitive 
= sig::typename_P
; 
 196         type
->data
.data
.type 
= NULL
; 
 200     if (type
->primitive 
!= sig::struct_P 
|| type
->name 
== NULL
) 
 206 JSClassRef 
Type_privateData::Class_
; 
 211     JSGlobalContextRef context_
; 
 213     Context(JSGlobalContextRef context
) : 
 222     CString(char *value
, JSContextRef context
, JSObjectRef owner
) : 
 223         CYOwned(value
, context
, owner
) 
 231     Type_privateData 
*type_
; 
 234     Pointer(void *value
, JSContextRef context
, JSObjectRef owner
, size_t length
, sig::Type 
*type
) : 
 235         CYOwned(value
, context
, owner
), 
 236         type_(new(*pool_
) Type_privateData(type
)), 
 241     Pointer(void *value
, JSContextRef context
, JSObjectRef owner
, size_t length
, const char *encoding
) : 
 242         CYOwned(value
, context
, owner
), 
 243         type_(new(*pool_
) Type_privateData(encoding
)), 
 249 struct Struct_privateData 
: 
 252     Type_privateData 
*type_
; 
 254     Struct_privateData(JSContextRef context
, JSObjectRef owner
) : 
 255         CYOwned(NULL
, context
, owner
) 
 260 JSObjectRef 
CYMakeStruct(JSContextRef context
, void *data
, sig::Type 
*type
, ffi_type 
*ffi
, JSObjectRef owner
) { 
 261     Struct_privateData 
*internal(new Struct_privateData(context
, owner
)); 
 262     CYPool 
&pool(*internal
->pool_
); 
 263     Type_privateData 
*typical(new(pool
) Type_privateData(type
, ffi
)); 
 264     internal
->type_ 
= typical
; 
 267         internal
->value_ 
= data
; 
 269         size_t size(typical
->GetFFI()->size
); 
 270         void *copy(internal
->pool_
->malloc
<void>(size
)); 
 271         memcpy(copy
, data
, size
); 
 272         internal
->value_ 
= copy
; 
 275     return JSObjectMake(context
, Struct_
, internal
); 
 278 static void *CYCastSymbol(const char *name
) { 
 279     for (CYHook 
*hook 
: GetHooks()) 
 280         if (hook
->CastSymbol 
!= NULL
) 
 281             if (void *value 
= (*hook
->CastSymbol
)(name
)) 
 283     return dlsym(RTLD_DEFAULT
, name
); 
 286 JSValueRef 
CYCastJSValue(JSContextRef context
, bool value
) { 
 287     return JSValueMakeBoolean(context
, value
); 
 290 JSValueRef 
CYCastJSValue(JSContextRef context
, double value
) { 
 291     return JSValueMakeNumber(context
, value
); 
 294 #define CYCastJSValue_(Type_) \ 
 295     JSValueRef CYCastJSValue(JSContextRef context, Type_ value) { \ 
 296         _assert(static_cast<Type_>(static_cast<double>(value)) == value); \ 
 297         return JSValueMakeNumber(context, static_cast<double>(value)); \ 
 301 CYCastJSValue_(unsigned int) 
 302 CYCastJSValue_(long int) 
 303 CYCastJSValue_(long unsigned int) 
 304 CYCastJSValue_(long long int) 
 305 CYCastJSValue_(long long unsigned int) 
 307 JSValueRef 
CYJSUndefined(JSContextRef context
) { 
 308     return JSValueMakeUndefined(context
); 
 311 double CYCastDouble(JSContextRef context
, JSValueRef value
) { 
 312     return _jsccall(JSValueToNumber
, context
, value
); 
 315 bool CYCastBool(JSContextRef context
, JSValueRef value
) { 
 316     return JSValueToBoolean(context
, value
); 
 319 JSValueRef 
CYJSNull(JSContextRef context
) { 
 320     return JSValueMakeNull(context
); 
 323 JSValueRef 
CYCastJSValue(JSContextRef context
, JSStringRef value
) { 
 324     return value 
== NULL 
? CYJSNull(context
) : JSValueMakeString(context
, value
); 
 327 JSValueRef 
CYCastJSValue(JSContextRef context
, const char *value
) { 
 328     return CYCastJSValue(context
, CYJSString(value
)); 
 331 JSObjectRef 
CYCastJSObject(JSContextRef context
, JSValueRef value
) { 
 332     return _jsccall(JSValueToObject
, context
, value
); 
 335 JSValueRef 
CYCallAsFunction(JSContextRef context
, JSObjectRef function
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[]) { 
 336     return _jsccall(JSObjectCallAsFunction
, context
, function
, _this
, count
, arguments
); 
 339 bool CYIsCallable(JSContextRef context
, JSValueRef value
) { 
 340     return value 
!= NULL 
&& JSValueIsObject(context
, value
) && JSObjectIsFunction(context
, (JSObjectRef
) value
); 
 343 bool CYIsEqual(JSContextRef context
, JSValueRef lhs
, JSValueRef rhs
) { 
 344     return _jsccall(JSValueIsEqual
, context
, lhs
, rhs
); 
 347 bool CYIsStrictEqual(JSContextRef context
, JSValueRef lhs
, JSValueRef rhs
) { 
 348     return JSValueIsStrictEqual(context
, lhs
, rhs
); 
 351 size_t CYArrayLength(JSContextRef context
, JSObjectRef array
) { 
 352     return CYCastDouble(context
, CYGetProperty(context
, array
, length_s
)); 
 355 JSValueRef 
CYArrayGet(JSContextRef context
, JSObjectRef array
, size_t index
) { 
 356     return _jsccall(JSObjectGetPropertyAtIndex
, context
, array
, index
); 
 359 void CYArrayPush(JSContextRef context
, JSObjectRef array
, JSValueRef value
) { 
 360     JSValueRef arguments
[1]; 
 361     arguments
[0] = value
; 
 362     JSObjectRef 
Array(CYGetCachedObject(context
, CYJSString("Array_prototype"))); 
 363     _jsccall(JSObjectCallAsFunction
, context
, CYCastJSObject(context
, CYGetProperty(context
, Array
, push_s
)), array
, 1, arguments
); 
 366 static JSValueRef 
System_print(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
 373         CYUTF8String 
string(CYPoolUTF8String(pool
, context
, CYJSString(context
, arguments
[0]))); 
 374         fwrite(string
.data
, string
.size
, 1, file
); 
 378     return CYJSUndefined(context
); 
 381 static void (*JSSynchronousGarbageCollectForDebugging$
)(JSContextRef
); 
 383 _visible 
void CYGarbageCollect(JSContextRef context
) { 
 384     (JSSynchronousGarbageCollectForDebugging$ 
?: &JSGarbageCollect
)(context
); 
 387 static JSValueRef 
Cycript_compile_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
 389     CYUTF8String 
before(CYPoolUTF8String(pool
, context
, CYJSString(context
, arguments
[0]))); 
 390     std::stringbuf 
value(std::string(before
.data
, before
.size
)); 
 391     CYUTF8String 
after(CYPoolCode(pool
, value
)); 
 392     return CYCastJSValue(context
, CYJSString(after
)); 
 393 } CYCatch_(NULL
, "SyntaxError") } 
 395 static JSValueRef 
Cycript_gc_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
 396     CYGarbageCollect(context
); 
 397     return CYJSUndefined(context
); 
 400 const char *CYPoolCCYON(CYPool 
&pool
, JSContextRef context
, JSValueRef value
, std::set
<void *> &objects
, JSValueRef 
*exception
) { CYTry 
{ 
 401     switch (JSType type 
= JSValueGetType(context
, value
)) { 
 402         case kJSTypeUndefined
: 
 407             return CYCastBool(context
, value
) ? "true" : "false"; 
 409         case kJSTypeNumber
: { 
 410             std::ostringstream str
; 
 411             CYNumerify(str
, CYCastDouble(context
, value
)); 
 412             std::string 
value(str
.str()); 
 413             return pool
.strmemdup(value
.c_str(), value
.size()); 
 416         case kJSTypeString
: { 
 417             std::ostringstream str
; 
 418             CYUTF8String 
string(CYPoolUTF8String(pool
, context
, CYJSString(context
, value
))); 
 419             CYStringify(str
, string
.data
, string
.size
); 
 420             std::string 
value(str
.str()); 
 421             return pool
.strmemdup(value
.c_str(), value
.size()); 
 425             return CYPoolCCYON(pool
, context
, (JSObjectRef
) value
, objects
); 
 427             throw CYJSError(context
, "JSValueGetType() == 0x%x", type
); 
 431 const char *CYPoolCCYON(CYPool 
&pool
, JSContextRef context
, JSValueRef value
, std::set
<void *> &objects
) { 
 432     return _jsccall(CYPoolCCYON
, pool
, context
, value
, objects
); 
 435 const char *CYPoolCCYON(CYPool 
&pool
, JSContextRef context
, JSValueRef value
, std::set
<void *> *objects
) { 
 437         return CYPoolCCYON(pool
, context
, value
, *objects
); 
 439         std::set
<void *> objects
; 
 440         return CYPoolCCYON(pool
, context
, value
, objects
); 
 444 const char *CYPoolCCYON(CYPool 
&pool
, JSContextRef context
, JSObjectRef object
, std::set
<void *> &objects
) { 
 445     JSValueRef 
toCYON(CYGetProperty(context
, object
, toCYON_s
)); 
 446     if (CYIsCallable(context
, toCYON
)) { 
 447         // XXX: this needs to be abstracted behind some kind of function 
 448         JSValueRef arguments
[1] = {CYCastJSValue(context
, reinterpret_cast<uintptr_t>(&objects
))}; 
 449         JSValueRef 
value(CYCallAsFunction(context
, (JSObjectRef
) toCYON
, object
, 1, arguments
)); 
 450         _assert(value 
!= NULL
); 
 451         return CYPoolCString(pool
, context
, value
); 
 454     JSValueRef 
toJSON(CYGetProperty(context
, object
, toJSON_s
)); 
 455     if (CYIsCallable(context
, toJSON
)) { 
 456         JSValueRef arguments
[1] = {CYCastJSValue(context
, CYJSString(""))}; 
 457         return _jsccall(CYPoolCCYON
, pool
, context
, CYCallAsFunction(context
, (JSObjectRef
) toJSON
, object
, 1, arguments
), objects
); 
 460     if (JSObjectIsFunction(context
, object
)) { 
 461         JSValueRef 
toString(CYGetProperty(context
, object
, toString_s
)); 
 462         if (CYIsCallable(context
, toString
)) { 
 463             JSValueRef arguments
[1] = {CYCastJSValue(context
, CYJSString(""))}; 
 464             JSValueRef 
value(CYCallAsFunction(context
, (JSObjectRef
) toString
, object
, 1, arguments
)); 
 465             _assert(value 
!= NULL
); 
 466             return CYPoolCString(pool
, context
, value
); 
 470     _assert(objects
.insert(object
).second
); 
 472     std::ostringstream str
; 
 476     // XXX: this is, sadly, going to leak 
 477     JSPropertyNameArrayRef 
names(JSObjectCopyPropertyNames(context
, object
)); 
 481     for (size_t index(0), count(JSPropertyNameArrayGetCount(names
)); index 
!= count
; ++index
) { 
 487         JSStringRef 
name(JSPropertyNameArrayGetNameAtIndex(names
, index
)); 
 488         CYUTF8String 
string(CYPoolUTF8String(pool
, context
, name
)); 
 493             CYStringify(str
, string
.data
, string
.size
); 
 498             JSValueRef 
value(CYGetProperty(context
, object
, name
)); 
 499             str 
<< CYPoolCCYON(pool
, context
, value
, objects
); 
 500         } catch (const CYException 
&error
) { 
 505     JSPropertyNameArrayRelease(names
); 
 509     std::string 
string(str
.str()); 
 510     return pool
.strmemdup(string
.c_str(), string
.size()); 
 513 std::set
<void *> *CYCastObjects(JSContextRef context
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[]) { 
 516     return CYCastPointer
<std::set
<void *> *>(context
, arguments
[0]); 
 519 static JSValueRef 
Array_callAsFunction_toCYON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
 520     std::set
<void *> *objects(CYCastObjects(context
, _this
, count
, arguments
)); 
 521     // XXX: this is horribly inefficient 
 522     std::set
<void *> backup
; 
 527     std::ostringstream str
; 
 531     JSValueRef 
length(CYGetProperty(context
, _this
, length_s
)); 
 534     for (size_t index(0), count(CYCastDouble(context
, length
)); index 
!= count
; ++index
) { 
 541             JSValueRef 
value(CYGetProperty(context
, _this
, index
)); 
 542             if (!JSValueIsUndefined(context
, value
)) 
 543                 str 
<< CYPoolCCYON(pool
, context
, value
, *objects
); 
 548         } catch (const CYException 
&error
) { 
 555     std::string 
value(str
.str()); 
 556     return CYCastJSValue(context
, CYJSString(CYUTF8String(value
.c_str(), value
.size()))); 
 559 static JSValueRef 
String_callAsFunction_toCYON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
 561     std::ostringstream str
; 
 563     CYUTF8String 
string(CYPoolUTF8String(pool
, context
, CYJSString(context
, _this
))); 
 564     CYStringify(str
, string
.data
, string
.size
); 
 566     std::string 
value(str
.str()); 
 567     return CYCastJSValue(context
, CYJSString(CYUTF8String(value
.c_str(), value
.size()))); 
 570 JSObjectRef 
CYMakePointer(JSContextRef context
, void *pointer
, size_t length
, sig::Type 
*type
, ffi_type 
*ffi
, JSObjectRef owner
) { 
 571     Pointer 
*internal(new Pointer(pointer
, context
, owner
, length
, type
)); 
 572     return JSObjectMake(context
, Pointer_
, internal
); 
 575 JSObjectRef 
CYMakePointer(JSContextRef context
, void *pointer
, size_t length
, const char *encoding
, JSObjectRef owner
) { 
 576     Pointer 
*internal(new Pointer(pointer
, context
, owner
, length
, encoding
)); 
 577     return JSObjectMake(context
, Pointer_
, internal
); 
 580 JSObjectRef 
CYMakeCString(JSContextRef context
, char *pointer
, JSObjectRef owner
) { 
 581     CString 
*internal(new CString(pointer
, context
, owner
)); 
 582     return JSObjectMake(context
, CString_
, internal
); 
 585 static JSObjectRef 
CYMakeFunctor(JSContextRef context
, void (*function
)(), const sig::Signature 
&signature
) { 
 586     return JSObjectMake(context
, Functor_
, new cy::Functor(signature
, function
)); 
 589 static JSObjectRef 
CYMakeFunctor(JSContextRef context
, const char *symbol
, const char *encoding
) { 
 590     void (*function
)()(reinterpret_cast<void (*)()>(CYCastSymbol(symbol
))); 
 591     if (function 
== NULL
) 
 594     cy::Functor 
*internal(new cy::Functor(encoding
, function
)); 
 596     return JSObjectMake(context
, Functor_
, internal
); 
 599 static bool CYGetOffset(CYPool 
&pool
, JSContextRef context
, JSStringRef value
, ssize_t 
&index
) { 
 600     return CYGetOffset(CYPoolCString(pool
, context
, value
), index
); 
 603 void *CYCastPointer_(JSContextRef context
, JSValueRef value
, bool *guess
) { 
 606     else switch (JSValueGetType(context
, value
)) { 
 609         case kJSTypeObject
: { 
 610             JSObjectRef 
object((JSObjectRef
) value
); 
 611             if (JSValueIsObjectOfClass(context
, value
, Pointer_
)) { 
 612                 Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(object
))); 
 613                 return internal
->value_
; 
 615             JSValueRef 
toPointer(CYGetProperty(context
, object
, toPointer_s
)); 
 616             if (CYIsCallable(context
, toPointer
)) { 
 617                 JSValueRef 
value(CYCallAsFunction(context
, (JSObjectRef
) toPointer
, object
, 0, NULL
)); 
 618                 _assert(value 
!= NULL
); 
 619                 return CYCastPointer_(context
, value
, guess
); 
 625             double number(CYCastDouble(context
, value
)); 
 626             if (!std::isnan(number
)) 
 627                 return reinterpret_cast<void *>(static_cast<uintptr_t>(static_cast<long long>(number
))); 
 629                 throw CYJSError(context
, "cannot convert value to pointer"); 
 637 void CYPoolFFI(CYPool 
*pool
, JSContextRef context
, sig::Type 
*type
, ffi_type 
*ffi
, void *data
, JSValueRef value
) { 
 638     switch (type
->primitive
) { 
 640             *reinterpret_cast<bool *>(data
) = JSValueToBoolean(context
, value
); 
 643 #define CYPoolFFI_(primitive, native) \ 
 644         case sig::primitive ## _P: \ 
 645             *reinterpret_cast<native *>(data) = CYCastDouble(context, value); \ 
 648         CYPoolFFI_(uchar
, unsigned char) 
 649         CYPoolFFI_(char, char) 
 650         CYPoolFFI_(ushort
, unsigned short) 
 651         CYPoolFFI_(short, short) 
 652         CYPoolFFI_(ulong
, unsigned long) 
 653         CYPoolFFI_(long, long) 
 654         CYPoolFFI_(uint
, unsigned int) 
 656         CYPoolFFI_(ulonglong
, unsigned long long) 
 657         CYPoolFFI_(longlong
, long long) 
 658         CYPoolFFI_(float, float) 
 659         CYPoolFFI_(double, double) 
 662             uint8_t *base(reinterpret_cast<uint8_t *>(data
)); 
 663             JSObjectRef 
aggregate(JSValueIsObject(context
, value
) ? (JSObjectRef
) value 
: NULL
); 
 664             for (size_t index(0); index 
!= type
->data
.data
.size
; ++index
) { 
 665                 ffi_type 
*field(ffi
->elements
[index
]); 
 668                 if (aggregate 
== NULL
) 
 671                     rhs 
= CYGetProperty(context
, aggregate
, index
); 
 672                     if (JSValueIsUndefined(context
, rhs
)) 
 673                         throw CYJSError(context
, "unable to extract array value"); 
 676                 CYPoolFFI(pool
, context
, type
->data
.data
.type
, field
, base
, rhs
); 
 683             *reinterpret_cast<void **>(data
) = CYCastPointer
<void *>(context
, value
); 
 686         case sig::string_P
: { 
 688             *reinterpret_cast<const char **>(data
) = CYCastPointer
<const char *>(context
, value
, &guess
); 
 689             if (guess 
&& pool 
!= NULL
) 
 690                 *reinterpret_cast<const char **>(data
) = CYPoolCString(*pool
, context
, value
); 
 693         case sig::struct_P
: { 
 694             uint8_t *base(reinterpret_cast<uint8_t *>(data
)); 
 695             JSObjectRef 
aggregate(JSValueIsObject(context
, value
) ? (JSObjectRef
) value 
: NULL
); 
 696             for (size_t index(0); index 
!= type
->data
.signature
.count
; ++index
) { 
 697                 sig::Element 
*element(&type
->data
.signature
.elements
[index
]); 
 698                 ffi_type 
*field(ffi
->elements
[index
]); 
 701                 if (aggregate 
== NULL
) 
 704                     rhs 
= CYGetProperty(context
, aggregate
, index
); 
 705                     if (JSValueIsUndefined(context
, rhs
)) { 
 706                         if (element
->name 
!= NULL
) 
 707                             rhs 
= CYGetProperty(context
, aggregate
, CYJSString(element
->name
)); 
 710                         if (JSValueIsUndefined(context
, rhs
)) undefined
: 
 711                             throw CYJSError(context
, "unable to extract structure value"); 
 715                 CYPoolFFI(pool
, context
, element
->type
, field
, base
, rhs
); 
 725             for (CYHook 
*hook 
: GetHooks()) 
 726                 if (hook
->PoolFFI 
!= NULL
) 
 727                     if ((*hook
->PoolFFI
)(pool
, context
, type
, ffi
, data
, value
)) 
 730             CYThrow("unimplemented signature code: '%c''\n", type
->primitive
); 
 734 JSValueRef 
CYFromFFI(JSContextRef context
, sig::Type 
*type
, ffi_type 
*ffi
, void *data
, bool initialize
, JSObjectRef owner
) { 
 735     switch (type
->primitive
) { 
 737             return CYCastJSValue(context
, *reinterpret_cast<bool *>(data
)); 
 739 #define CYFromFFI_(primitive, native) \ 
 740         case sig::primitive ## _P: \ 
 741             return CYCastJSValue(context, *reinterpret_cast<native *>(data)); \ 
 743         CYFromFFI_(uchar, unsigned char) 
 744         CYFromFFI_(char, char) 
 745         CYFromFFI_(ushort
, unsigned short) 
 746         CYFromFFI_(short, short) 
 747         CYFromFFI_(ulong
, unsigned long) 
 748         CYFromFFI_(long, long) 
 749         CYFromFFI_(uint
, unsigned int) 
 751         CYFromFFI_(ulonglong
, unsigned long long) 
 752         CYFromFFI_(longlong
, long long) 
 753         CYFromFFI_(float, float) 
 754         CYFromFFI_(double, double) 
 757             if (void *pointer 
= data
) 
 758                 return CYMakePointer(context
, pointer
, type
->data
.data
.size
, type
->data
.data
.type
, NULL
, owner
); 
 762             if (void *pointer 
= *reinterpret_cast<void **>(data
)) 
 763                 return CYMakePointer(context
, pointer
, _not(size_t), type
->data
.data
.type
, NULL
, owner
); 
 767             if (char *pointer 
= *reinterpret_cast<char **>(data
)) 
 768                 return CYMakeCString(context
, pointer
, owner
); 
 772             return CYMakeStruct(context
, data
, type
, ffi
, owner
); 
 774             return CYJSUndefined(context
); 
 777             return CYJSNull(context
); 
 779             for (CYHook 
*hook 
: GetHooks()) 
 780                 if (hook
->FromFFI 
!= NULL
) 
 781                     if (JSValueRef value 
= (*hook
->FromFFI
)(context
, type
, ffi
, data
, initialize
, owner
)) 
 784             CYThrow("unimplemented signature code: '%c''\n", type
->primitive
); 
 788 void CYExecuteClosure(ffi_cif 
*cif
, void *result
, void **arguments
, void *arg
) { 
 789     Closure_privateData 
*internal(reinterpret_cast<Closure_privateData 
*>(arg
)); 
 791     JSContextRef 
context(internal
->context_
); 
 793     size_t count(internal
->cif_
.nargs
); 
 794     JSValueRef values
[count
]; 
 796     for (size_t index(0); index 
!= count
; ++index
) 
 797         values
[index
] = CYFromFFI(context
, internal
->signature_
.elements
[1 + index
].type
, internal
->cif_
.arg_types
[index
], arguments
[index
]); 
 799     JSValueRef 
value(internal
->adapter_(context
, count
, values
, internal
->function_
)); 
 800     CYPoolFFI(NULL
, context
, internal
->signature_
.elements
[0].type
, internal
->cif_
.rtype
, result
, value
); 
 803 static JSValueRef 
FunctionAdapter_(JSContextRef context
, size_t count
, JSValueRef values
[], JSObjectRef function
) { 
 804     return CYCallAsFunction(context
, function
, NULL
, count
, values
); 
 807 Closure_privateData 
*CYMakeFunctor_(JSContextRef context
, JSObjectRef function
, const sig::Signature 
&signature
, JSValueRef (*adapter
)(JSContextRef
, size_t, JSValueRef
[], JSObjectRef
)) { 
 808     // XXX: in case of exceptions this will leak 
 809     // XXX: in point of fact, this may /need/ to leak :( 
 810     Closure_privateData 
*internal(new Closure_privateData(context
, function
, adapter
, signature
)); 
 812 #if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) 
 814     ffi_closure 
*writable(reinterpret_cast<ffi_closure 
*>(ffi_closure_alloc(sizeof(ffi_closure
), &executable
))); 
 816     ffi_status 
status(ffi_prep_closure_loc(writable
, &internal
->cif_
, &CYExecuteClosure
, internal
, executable
)); 
 817     _assert(status 
== FFI_OK
); 
 819     internal
->value_ 
= executable
; 
 821     ffi_closure 
*closure((ffi_closure 
*) _syscall(mmap( 
 822         NULL
, sizeof(ffi_closure
), 
 823         PROT_READ 
| PROT_WRITE
, MAP_ANON 
| MAP_PRIVATE
, 
 827     ffi_status 
status(ffi_prep_closure(closure
, &internal
->cif_
, &CYExecuteClosure
, internal
)); 
 828     _assert(status 
== FFI_OK
); 
 830     _syscall(mprotect(closure
, sizeof(*closure
), PROT_READ 
| PROT_EXEC
)); 
 832     internal
->value_ 
= closure
; 
 838 static JSObjectRef 
CYMakeFunctor(JSContextRef context
, JSObjectRef function
, const sig::Signature 
&signature
) { 
 839     Closure_privateData 
*internal(CYMakeFunctor_(context
, function
, signature
, &FunctionAdapter_
)); 
 840     JSObjectRef 
object(JSObjectMake(context
, Functor_
, internal
)); 
 841     // XXX: see above notes about needing to leak 
 842     JSValueProtect(CYGetJSContext(context
), object
); 
 846 JSValueRef 
CYGetCachedValue(JSContextRef context
, JSStringRef name
) { 
 847     return CYGetProperty(context
, CYCastJSObject(context
, CYGetProperty(context
, CYGetGlobalObject(context
), cy_s
)), name
); 
 850 JSObjectRef 
CYGetCachedObject(JSContextRef context
, JSStringRef name
) { 
 851     return CYCastJSObject(context
, CYGetCachedValue(context
, name
)); 
 854 static JSObjectRef 
CYMakeFunctor(JSContextRef context
, JSValueRef value
, const sig::Signature 
&signature
) { 
 855     JSObjectRef 
Function(CYGetCachedObject(context
, CYJSString("Function"))); 
 857     bool function(_jsccall(JSValueIsInstanceOfConstructor
, context
, value
, Function
)); 
 859         JSObjectRef 
function(CYCastJSObject(context
, value
)); 
 860         return CYMakeFunctor(context
, function
, signature
); 
 862         void (*function
)()(CYCastPointer
<void (*)()>(context
, value
)); 
 863         return CYMakeFunctor(context
, function
, signature
); 
 867 static JSValueRef 
CString_getProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
 869     CString 
*internal(reinterpret_cast<CString 
*>(JSObjectGetPrivate(object
))); 
 870     char *string(static_cast<char *>(internal
->value_
)); 
 873     if (!CYGetOffset(pool
, context
, property
, offset
)) 
 876     return CYCastJSValue(context
, CYJSString(CYUTF8String(&string
[offset
], 1))); 
 879 static bool CString_setProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef value
, JSValueRef 
*exception
) { CYTry 
{ 
 881     CString 
*internal(reinterpret_cast<CString 
*>(JSObjectGetPrivate(object
))); 
 882     char *string(static_cast<char *>(internal
->value_
)); 
 885     if (!CYGetOffset(pool
, context
, property
, offset
)) 
 888     const char *data(CYPoolCString(pool
, context
, value
)); 
 889     string
[offset
] = *data
; 
 893 static bool Index_(CYPool 
&pool
, JSContextRef context
, Struct_privateData 
*internal
, JSStringRef property
, ssize_t 
&index
, uint8_t *&base
) { 
 894     Type_privateData 
*typical(internal
->type_
); 
 895     sig::Type 
*type(typical
->type_
); 
 899     const char *name(CYPoolCString(pool
, context
, property
)); 
 900     size_t length(strlen(name
)); 
 901     double number(CYCastDouble(name
, length
)); 
 903     size_t count(type
->data
.signature
.count
); 
 905     if (std::isnan(number
)) { 
 906         if (property 
== NULL
) 
 909         sig::Element 
*elements(type
->data
.signature
.elements
); 
 911         for (size_t local(0); local 
!= count
; ++local
) { 
 912             sig::Element 
*element(&elements
[local
]); 
 913             if (element
->name 
!= NULL 
&& strcmp(name
, element
->name
) == 0) { 
 921         index 
= static_cast<ssize_t
>(number
); 
 922         if (index 
!= number 
|| index 
< 0 || static_cast<size_t>(index
) >= count
) 
 927     ffi_type 
**elements(typical
->GetFFI()->elements
); 
 929     base 
= reinterpret_cast<uint8_t *>(internal
->value_
); 
 930     for (ssize_t 
local(0); local 
!= index
; ++local
) 
 931         base 
+= elements
[local
]->size
; 
 936 static JSValueRef 
Pointer_getProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
 938     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(object
))); 
 940     if (JSStringIsEqual(property
, length_s
)) 
 941         return internal
->length_ 
== _not(size_t) ? CYJSUndefined(context
) : CYCastJSValue(context
, internal
->length_
); 
 943     Type_privateData 
*typical(internal
->type_
); 
 944     if (typical
->type_ 
== NULL
) 
 946     sig::Type 
&type(*typical
->type_
); 
 949     if (JSStringIsEqualToUTF8CString(property
, "$cyi")) 
 951     else if (!CYGetOffset(pool
, context
, property
, offset
)) 
 954     if (type
.primitive 
== sig::function_P
) 
 955         return CYMakeFunctor(context
, reinterpret_cast<void (*)()>(internal
->value_
), type
.data
.signature
); 
 957     ffi_type 
*ffi(typical
->GetFFI()); 
 959     uint8_t *base(reinterpret_cast<uint8_t *>(internal
->value_
)); 
 960     base 
+= ffi
->size 
* offset
; 
 962     JSObjectRef 
owner(internal
->GetOwner() ?: object
); 
 963     return CYFromFFI(context
, &type
, ffi
, base
, false, owner
); 
 966 static bool Pointer_setProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef value
, JSValueRef 
*exception
) { CYTry 
{ 
 968     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(object
))); 
 969     Type_privateData 
*typical(internal
->type_
); 
 971     if (typical
->type_ 
== NULL
) 
 975     if (JSStringIsEqualToUTF8CString(property
, "$cyi")) 
 977     else if (!CYGetOffset(pool
, context
, property
, offset
)) 
 980     ffi_type 
*ffi(typical
->GetFFI()); 
 982     uint8_t *base(reinterpret_cast<uint8_t *>(internal
->value_
)); 
 983     base 
+= ffi
->size 
* offset
; 
 985     CYPoolFFI(NULL
, context
, typical
->type_
, ffi
, base
, value
); 
 989 static JSValueRef Struct_callAsFunction_$
cya(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
 990     Struct_privateData 
*internal(reinterpret_cast<Struct_privateData 
*>(JSObjectGetPrivate(_this
))); 
 991     Type_privateData 
*typical(internal
->type_
); 
 992     return CYMakePointer(context
, internal
->value_
, _not(size_t), typical
->type_
, typical
->ffi_
, _this
); 
 995 static JSValueRef 
Struct_getProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
 997     Struct_privateData 
*internal(reinterpret_cast<Struct_privateData 
*>(JSObjectGetPrivate(object
))); 
 998     Type_privateData 
*typical(internal
->type_
); 
1003     if (!Index_(pool
, context
, internal
, property
, index
, base
)) 
1006     JSObjectRef 
owner(internal
->GetOwner() ?: object
); 
1008     return CYFromFFI(context
, typical
->type_
->data
.signature
.elements
[index
].type
, typical
->GetFFI()->elements
[index
], base
, false, owner
); 
1011 static bool Struct_setProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef value
, JSValueRef 
*exception
) { CYTry 
{ 
1013     Struct_privateData 
*internal(reinterpret_cast<Struct_privateData 
*>(JSObjectGetPrivate(object
))); 
1014     Type_privateData 
*typical(internal
->type_
); 
1019     if (!Index_(pool
, context
, internal
, property
, index
, base
)) 
1022     CYPoolFFI(NULL
, context
, typical
->type_
->data
.signature
.elements
[index
].type
, typical
->GetFFI()->elements
[index
], base
, value
); 
1026 static void Struct_getPropertyNames(JSContextRef context
, JSObjectRef object
, JSPropertyNameAccumulatorRef names
) { 
1027     Struct_privateData 
*internal(reinterpret_cast<Struct_privateData 
*>(JSObjectGetPrivate(object
))); 
1028     Type_privateData 
*typical(internal
->type_
); 
1029     sig::Type 
*type(typical
->type_
); 
1034     size_t count(type
->data
.signature
.count
); 
1035     sig::Element 
*elements(type
->data
.signature
.elements
); 
1039     for (size_t index(0); index 
!= count
; ++index
) { 
1041         name 
= elements
[index
].name
; 
1044             sprintf(number
, "%zu", index
); 
1048         JSPropertyNameAccumulatorAddName(names
, CYJSString(name
)); 
1052 void CYCallFunction(CYPool 
&pool
, JSContextRef context
, ffi_cif 
*cif
, void (*function
)(), void *value
, void **values
) { 
1053     ffi_call(cif
, function
, value
, values
); 
1056 JSValueRef 
CYCallFunction(CYPool 
&pool
, JSContextRef context
, size_t setups
, void *setup
[], size_t count
, const JSValueRef arguments
[], bool initialize
, sig::Signature 
*signature
, ffi_cif 
*cif
, void (*function
)()) { 
1057     if (setups 
+ count 
!= signature
->count 
- 1) 
1058         throw CYJSError(context
, "incorrect number of arguments to ffi function"); 
1060     size_t size(setups 
+ count
); 
1062     memcpy(values
, setup
, sizeof(void *) * setups
); 
1064     for (size_t index(setups
); index 
!= size
; ++index
) { 
1065         sig::Element 
*element(&signature
->elements
[index 
+ 1]); 
1066         ffi_type 
*ffi(cif
->arg_types
[index
]); 
1068         values
[index
] = new(pool
) uint8_t[ffi
->size
]; 
1069         CYPoolFFI(&pool
, context
, element
->type
, ffi
, values
[index
], arguments
[index 
- setups
]); 
1072     uint8_t value
[cif
->rtype
->size
]; 
1074     void (*call
)(CYPool 
&, JSContextRef
, ffi_cif 
*, void (*)(), void *, void **) = &CYCallFunction
; 
1075     // XXX: this only supports one hook, but it is a bad idea anyway 
1076     for (CYHook 
*hook 
: GetHooks()) 
1077         if (hook
->CallFunction 
!= NULL
) 
1078             call 
= hook
->CallFunction
; 
1080     call(pool
, context
, cif
, function
, value
, values
); 
1081     return CYFromFFI(context
, signature
->elements
[0].type
, cif
->rtype
, value
, initialize
); 
1084 static JSValueRef 
Functor_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1086     cy::Functor 
*internal(reinterpret_cast<cy::Functor 
*>(JSObjectGetPrivate(object
))); 
1087     return CYCallFunction(pool
, context
, 0, NULL
, count
, arguments
, false, &internal
->signature_
, &internal
->cif_
, internal
->GetValue()); 
1090 static JSValueRef 
Pointer_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1091     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(object
))); 
1092     if (internal
->type_
->type_
->primitive 
!= sig::function_P
) 
1093         throw CYJSError(context
, "cannot call a pointer to non-function"); 
1094     JSObjectRef 
functor(CYCastJSObject(context
, CYGetProperty(context
, object
, cyi_s
))); 
1095     return CYCallAsFunction(context
, functor
, _this
, count
, arguments
); 
1098 JSObjectRef 
CYMakeType(JSContextRef context
, const char *encoding
) { 
1099     Type_privateData 
*internal(new Type_privateData(encoding
)); 
1100     return JSObjectMake(context
, Type_privateData::Class_
, internal
); 
1103 JSObjectRef 
CYMakeType(JSContextRef context
, sig::Type 
*type
) { 
1104     Type_privateData 
*internal(new Type_privateData(type
)); 
1105     return JSObjectMake(context
, Type_privateData::Class_
, internal
); 
1108 JSObjectRef 
CYMakeType(JSContextRef context
, sig::Signature 
*signature
) { 
1115     type
.primitive 
= sig::function_P
; 
1116     sig::Copy(pool
, type
.data
.signature
, *signature
); 
1118     return CYMakeType(context
, &type
); 
1121 extern "C" const char *CYBridgeHash(CYPool 
&pool
, CYUTF8String name
) { 
1122     sqlite3_stmt 
*statement
; 
1124     _sqlcall(sqlite3_prepare(database_
, 
1126             "\"cache\".\"value\" " 
1129             " \"cache\".\"system\" & " CY_SYSTEM 
" == " CY_SYSTEM 
" and" 
1130             " \"cache\".\"name\" = ?" 
1132     , -1, &statement
, NULL
)); 
1134     _sqlcall(sqlite3_bind_text(statement
, 1, name
.data
, name
.size
, SQLITE_STATIC
)); 
1137     if (_sqlcall(sqlite3_step(statement
)) == SQLITE_DONE
) 
1140         value 
= sqlite3_column_pooled(pool
, statement
, 0); 
1142     _sqlcall(sqlite3_finalize(statement
)); 
1146 static bool All_hasProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
) { 
1147     JSObjectRef 
global(CYGetGlobalObject(context
)); 
1148     JSObjectRef 
cycript(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Cycript")))); 
1149     JSObjectRef 
alls(CYCastJSObject(context
, CYGetProperty(context
, cycript
, CYJSString("alls")))); 
1151     for (size_t i(0), count(CYArrayLength(context
, alls
)); i 
!= count
; ++i
) 
1152         if (JSObjectRef space 
= CYCastJSObject(context
, CYArrayGet(context
, alls
, count 
- i 
- 1))) 
1153             if (CYHasProperty(context
, space
, property
)) 
1157     if (CYBridgeHash(pool
, CYPoolUTF8String(pool
, context
, property
)) != NULL
) 
1163 static JSValueRef 
All_getProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1164     JSObjectRef 
global(CYGetGlobalObject(context
)); 
1165     JSObjectRef 
cycript(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Cycript")))); 
1166     JSObjectRef 
alls(CYCastJSObject(context
, CYGetProperty(context
, cycript
, CYJSString("alls")))); 
1168     for (size_t i(0), count(CYArrayLength(context
, alls
)); i 
!= count
; ++i
) 
1169         if (JSObjectRef space 
= CYCastJSObject(context
, CYArrayGet(context
, alls
, count 
- i 
- 1))) 
1170             if (JSValueRef value 
= CYGetProperty(context
, space
, property
)) 
1171                 if (!JSValueIsUndefined(context
, value
)) 
1175     if (const char *code 
= CYBridgeHash(pool
, CYPoolUTF8String(pool
, context
, property
))) { 
1176         JSValueRef 
result(_jsccall(JSEvaluateScript
, context
, CYJSString(CYPoolCode(pool
, code
)), NULL
, NULL
, 0)); 
1177         CYSetProperty(context
, object
, property
, result
, kJSPropertyAttributeDontEnum
); 
1184 static void All_getPropertyNames(JSContextRef context
, JSObjectRef object
, JSPropertyNameAccumulatorRef names
) { 
1185     JSObjectRef 
global(CYGetGlobalObject(context
)); 
1186     JSObjectRef 
cycript(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Cycript")))); 
1187     JSObjectRef 
alls(CYCastJSObject(context
, CYGetProperty(context
, cycript
, CYJSString("alls")))); 
1189     for (size_t i(0), count(CYArrayLength(context
, alls
)); i 
!= count
; ++i
) 
1190         if (JSObjectRef space 
= CYCastJSObject(context
, CYArrayGet(context
, alls
, count 
- i 
- 1))) { 
1191             JSPropertyNameArrayRef 
subset(JSObjectCopyPropertyNames(context
, space
)); 
1192             for (size_t index(0), count(JSPropertyNameArrayGetCount(subset
)); index 
!= count
; ++index
) 
1193                 JSPropertyNameAccumulatorAddName(names
, JSPropertyNameArrayGetNameAtIndex(subset
, index
)); 
1194             JSPropertyNameArrayRelease(subset
); 
1198 static JSObjectRef 
CString_new(JSContextRef context
, JSObjectRef object
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1200         throw CYJSError(context
, "incorrect number of arguments to CString constructor"); 
1201     char *value(CYCastPointer
<char *>(context
, arguments
[0])); 
1202     return CYMakeCString(context
, value
, NULL
); 
1205 static JSObjectRef 
Pointer_new(JSContextRef context
, JSObjectRef object
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1207         throw CYJSError(context
, "incorrect number of arguments to Pointer constructor"); 
1211     void *value(CYCastPointer
<void *>(context
, arguments
[0])); 
1212     const char *type(CYPoolCString(pool
, context
, arguments
[1])); 
1214     sig::Signature signature
; 
1215     sig::Parse(pool
, &signature
, type
, &Structor_
); 
1217     return CYMakePointer(context
, value
, _not(size_t), signature
.elements
[0].type
, NULL
, NULL
); 
1220 static JSObjectRef 
Type_new(JSContextRef context
, JSObjectRef object
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1224     } else if (count 
== 1) { 
1225         const char *type(CYPoolCString(pool
, context
, arguments
[0])); 
1226         return CYMakeType(context
, type
); 
1227     } else if (count 
== 2) { 
1228         JSObjectRef 
types(CYCastJSObject(context
, arguments
[0])); 
1229         size_t count(CYArrayLength(context
, types
)); 
1231         JSObjectRef 
names(CYCastJSObject(context
, arguments
[1])); 
1237         type
.primitive 
= sig::struct_P
; 
1238         type
.data
.signature
.elements 
= new(pool
) sig::Element
[count
]; 
1239         type
.data
.signature
.count 
= count
; 
1241         for (size_t i(0); i 
!= count
; ++i
) { 
1242             sig::Element 
&element(type
.data
.signature
.elements
[i
]); 
1243             element
.offset 
= _not(size_t); 
1245             JSValueRef 
name(CYArrayGet(context
, names
, i
)); 
1246             if (JSValueIsUndefined(context
, name
)) 
1247                 element
.name 
= NULL
; 
1249                 element
.name 
= CYPoolCString(pool
, context
, name
); 
1251             JSObjectRef 
object(CYCastJSObject(context
, CYArrayGet(context
, types
, i
))); 
1252             _assert(JSValueIsObjectOfClass(context
, object
, Type_privateData::Class_
)); 
1253             Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1254             element
.type 
= internal
->type_
; 
1257         return CYMakeType(context
, &type
); 
1259         throw CYJSError(context
, "incorrect number of arguments to Type constructor"); 
1263 static JSValueRef Type_callAsFunction_$
With(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], sig::Primitive primitive
, JSValueRef 
*exception
) { CYTry 
{ 
1264     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1272     type
.primitive 
= primitive
; 
1273     type
.data
.signature
.elements 
= new(pool
) sig::Element
[1 + count
]; 
1274     type
.data
.signature
.count 
= 1 + count
; 
1276     type
.data
.signature
.elements
[0].name 
= NULL
; 
1277     type
.data
.signature
.elements
[0].type 
= internal
->type_
; 
1278     type
.data
.signature
.elements
[0].offset 
= _not(size_t); 
1280     for (size_t i(0); i 
!= count
; ++i
) { 
1281         sig::Element 
&element(type
.data
.signature
.elements
[i 
+ 1]); 
1282         element
.name 
= NULL
; 
1283         element
.offset 
= _not(size_t); 
1285         JSObjectRef 
object(CYCastJSObject(context
, arguments
[i
])); 
1286         _assert(JSValueIsObjectOfClass(context
, object
, Type_privateData::Class_
)); 
1287         Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1289         element
.type 
= internal
->type_
; 
1292     return CYMakeType(context
, &type
); 
1295 static JSValueRef 
Type_callAsFunction_arrayOf(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1297         throw CYJSError(context
, "incorrect number of arguments to Type.arrayOf"); 
1298     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1301     size_t index(CYGetIndex(pool
, context
, CYJSString(context
, arguments
[0]))); 
1302     if (index 
== _not(size_t)) 
1303         throw CYJSError(context
, "invalid array size used with Type.arrayOf"); 
1309     type
.primitive 
= sig::array_P
; 
1310     type
.data
.data
.type 
= internal
->type_
; 
1311     type
.data
.data
.size 
= index
; 
1313     return CYMakeType(context
, &type
); 
1316 static JSValueRef 
Type_callAsFunction_blockWith(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { 
1317     return Type_callAsFunction_$
With(context
, object
, _this
, count
, arguments
, sig::block_P
, exception
); 
1320 static JSValueRef 
Type_callAsFunction_constant(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1322         throw CYJSError(context
, "incorrect number of arguments to Type.constant"); 
1323     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1325     sig::Type 
type(*internal
->type_
); 
1326     type
.flags 
|= JOC_TYPE_CONST
; 
1327     return CYMakeType(context
, &type
); 
1330 static JSValueRef 
Type_callAsFunction_long(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1332         throw CYJSError(context
, "incorrect number of arguments to Type.long"); 
1333     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1335     sig::Type 
type(*internal
->type_
); 
1337     switch (type
.primitive
) { 
1338         case sig::short_P
: type
.primitive 
= sig::int_P
; break; 
1339         case sig::int_P
: type
.primitive 
= sig::long_P
; break; 
1340         case sig::long_P
: type
.primitive 
= sig::longlong_P
; break; 
1341         default: throw CYJSError(context
, "invalid type argument to Type.long"); 
1344     return CYMakeType(context
, &type
); 
1347 static JSValueRef 
Type_callAsFunction_short(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1349         throw CYJSError(context
, "incorrect number of arguments to Type.short"); 
1350     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1352     sig::Type 
type(*internal
->type_
); 
1354     switch (type
.primitive
) { 
1355         case sig::int_P
: type
.primitive 
= sig::short_P
; break; 
1356         case sig::long_P
: type
.primitive 
= sig::int_P
; break; 
1357         case sig::longlong_P
: type
.primitive 
= sig::long_P
; break; 
1358         default: throw CYJSError(context
, "invalid type argument to Type.short"); 
1361     return CYMakeType(context
, &type
); 
1364 static JSValueRef 
Type_callAsFunction_signed(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1366         throw CYJSError(context
, "incorrect number of arguments to Type.signed"); 
1367     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1369     sig::Type 
type(*internal
->type_
); 
1371     switch (type
.primitive
) { 
1372         case sig::char_P
: case sig::uchar_P
: type
.primitive 
= sig::char_P
; break; 
1373         case sig::short_P
: case sig::ushort_P
: type
.primitive 
= sig::short_P
; break; 
1374         case sig::int_P
: case sig::uint_P
: type
.primitive 
= sig::int_P
; break; 
1375         case sig::long_P
: case sig::ulong_P
: type
.primitive 
= sig::long_P
; break; 
1376         case sig::longlong_P
: case sig::ulonglong_P
: type
.primitive 
= sig::longlong_P
; break; 
1377         default: throw CYJSError(context
, "invalid type argument to Type.signed"); 
1380     return CYMakeType(context
, &type
); 
1383 static JSValueRef 
Type_callAsFunction_unsigned(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1385         throw CYJSError(context
, "incorrect number of arguments to Type.unsigned"); 
1386     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1388     sig::Type 
type(*internal
->type_
); 
1390     switch (type
.primitive
) { 
1391         case sig::char_P
: case sig::uchar_P
: type
.primitive 
= sig::uchar_P
; break; 
1392         case sig::short_P
: case sig::ushort_P
: type
.primitive 
= sig::ushort_P
; break; 
1393         case sig::int_P
: case sig::uint_P
: type
.primitive 
= sig::uint_P
; break; 
1394         case sig::long_P
: case sig::ulong_P
: type
.primitive 
= sig::ulong_P
; break; 
1395         case sig::longlong_P
: case sig::ulonglong_P
: type
.primitive 
= sig::ulonglong_P
; break; 
1396         default: throw CYJSError(context
, "invalid type argument to Type.unsigned"); 
1399     return CYMakeType(context
, &type
); 
1402 static JSValueRef 
Type_callAsFunction_functionWith(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { 
1403     return Type_callAsFunction_$
With(context
, object
, _this
, count
, arguments
, sig::function_P
, exception
); 
1406 static JSValueRef 
Type_callAsFunction_pointerTo(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1408         throw CYJSError(context
, "incorrect number of arguments to Type.pointerTo"); 
1409     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1414     if (internal
->type_
->primitive 
== sig::char_P
) { 
1415         type
.flags 
= internal
->type_
->flags
; 
1416         type
.primitive 
= sig::string_P
; 
1417         type
.data
.data
.type 
= NULL
; 
1418         type
.data
.data
.size 
= 0; 
1421         type
.primitive 
= sig::pointer_P
; 
1422         type
.data
.data
.type 
= internal
->type_
; 
1423         type
.data
.data
.size 
= 0; 
1426     return CYMakeType(context
, &type
); 
1429 static JSValueRef 
Type_callAsFunction_withName(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1431         throw CYJSError(context
, "incorrect number of arguments to Type.withName"); 
1432     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1435     const char *name(CYPoolCString(pool
, context
, arguments
[0])); 
1437     sig::Type 
type(*internal
->type_
); 
1439     return CYMakeType(context
, &type
); 
1442 static JSValueRef 
Type_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1444         throw CYJSError(context
, "incorrect number of arguments to type cast function"); 
1445     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1447     if (internal
->type_
->primitive 
== sig::function_P
) 
1448         return CYMakeFunctor(context
, arguments
[0], internal
->type_
->data
.signature
); 
1450     sig::Type 
*type(internal
->type_
); 
1451     ffi_type 
*ffi(internal
->GetFFI()); 
1453     uint8_t value
[ffi
->size
]; 
1455     CYPoolFFI(&pool
, context
, type
, ffi
, value
, arguments
[0]); 
1456     return CYFromFFI(context
, type
, ffi
, value
); 
1459 static JSObjectRef 
Type_callAsConstructor(JSContextRef context
, JSObjectRef object
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1461         throw CYJSError(context
, "incorrect number of arguments to Type allocator"); 
1462     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1464     sig::Type 
*type(internal
->type_
); 
1467     if (type
->primitive 
!= sig::array_P
) 
1468         length 
= _not(size_t); 
1470         length 
= type
->data
.data
.size
; 
1471         type 
= type
->data
.data
.type
; 
1474     JSObjectRef 
pointer(CYMakePointer(context
, NULL
, length
, type
, NULL
, NULL
)); 
1475     Pointer 
*value(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(pointer
))); 
1476     value
->value_ 
= value
->pool_
->malloc
<void>(internal
->GetFFI()->size
); 
1477     memset(value
->value_
, 0, internal
->GetFFI()->size
); 
1481 static JSObjectRef 
Functor_new(JSContextRef context
, JSObjectRef object
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1483         throw CYJSError(context
, "incorrect number of arguments to Functor constructor"); 
1485     const char *encoding(CYPoolCString(pool
, context
, arguments
[1])); 
1486     sig::Signature signature
; 
1487     sig::Parse(pool
, &signature
, encoding
, &Structor_
); 
1488     return CYMakeFunctor(context
, arguments
[0], signature
); 
1491 static JSValueRef 
CString_callAsFunction_toPointer(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1492     CString 
*internal(reinterpret_cast<CString 
*>(JSObjectGetPrivate(_this
))); 
1498     type
.primitive 
= sig::char_P
; 
1499     type
.data
.data
.type 
= NULL
; 
1500     type
.data
.data
.size 
= 0; 
1502     return CYMakePointer(context
, internal
->value_
, _not(size_t), &type
, NULL
, NULL
); 
1505 static JSValueRef Functor_callAsFunction_$
cya(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1507     cy::Functor 
*internal(reinterpret_cast<cy::Functor 
*>(JSObjectGetPrivate(_this
))); 
1513     type
.primitive 
= sig::function_P
; 
1514     sig::Copy(pool
, type
.data
.signature
, internal
->signature_
); 
1516     return CYMakePointer(context
, internal
->value_
, _not(size_t), &type
, NULL
, NULL
); 
1519 static JSValueRef 
Pointer_callAsFunction_toPointer(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1523 static JSValueRef 
CYValue_callAsFunction_valueOf(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1524     CYValue 
*internal(reinterpret_cast<CYValue 
*>(JSObjectGetPrivate(_this
))); 
1525     return CYCastJSValue(context
, reinterpret_cast<uintptr_t>(internal
->value_
)); 
1528 static JSValueRef 
CYValue_callAsFunction_toJSON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { 
1529     return CYValue_callAsFunction_valueOf(context
, object
, _this
, count
, arguments
, exception
); 
1532 static JSValueRef 
CYValue_callAsFunction_toCYON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1533     CYValue 
*internal(reinterpret_cast<CYValue 
*>(JSObjectGetPrivate(_this
))); 
1534     std::ostringstream str
; 
1536     if (internal
->value_ 
== NULL
) 
1538     else if (dladdr(internal
->value_
, &info
) == 0) 
1539         str 
<< internal
->value_
; 
1541         str 
<< info
.dli_sname
; 
1542         off_t 
offset(static_cast<char *>(internal
->value_
) - static_cast<char *>(info
.dli_saddr
)); 
1544             str 
<< "+0x" << std::hex 
<< offset
; 
1546     std::string 
value(str
.str()); 
1547     return CYCastJSValue(context
, CYJSString(CYUTF8String(value
.c_str(), value
.size()))); 
1550 static JSValueRef 
Pointer_callAsFunction_toCYON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1551     std::set
<void *> *objects(CYCastObjects(context
, _this
, count
, arguments
)); 
1553     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(_this
))); 
1554     if (internal
->length_ 
!= _not(size_t)) { 
1555         JSObjectRef 
Array(CYGetCachedObject(context
, CYJSString("Array_prototype"))); 
1556         JSObjectRef 
toCYON(CYCastJSObject(context
, CYGetProperty(context
, Array
, toCYON_s
))); 
1557         return CYCallAsFunction(context
, toCYON
, _this
, count
, arguments
); 
1558     } else if (internal
->type_
->type_ 
== NULL
) pointer
: { 
1560         std::ostringstream str
; 
1566         type
.primitive 
= sig::pointer_P
; 
1567         type
.data
.data
.type 
= internal
->type_
->type_
; 
1568         type
.data
.data
.size 
= 0; 
1571         CYOutput 
output(*str
.rdbuf(), options
); 
1572         (new(pool
) CYTypeExpression(Decode(pool
, &type
)))->Output(output
, CYNoFlags
); 
1574         str 
<< "(" << internal
->value_ 
<< ")"; 
1575         std::string 
value(str
.str()); 
1576         return CYCastJSValue(context
, CYJSString(CYUTF8String(value
.c_str(), value
.size()))); 
1578         JSValueRef 
value(CYGetProperty(context
, _this
, cyi_s
)); 
1579         if (JSValueIsUndefined(context
, value
)) 
1582         return CYCastJSValue(context
, pool
.strcat("&", CYPoolCCYON(pool
, context
, value
, objects
), NULL
)); 
1583     } catch (const CYException 
&e
) { 
1588 static JSValueRef 
CString_getProperty_length(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1589     CString 
*internal(reinterpret_cast<CString 
*>(JSObjectGetPrivate(object
))); 
1590     char *string(static_cast<char *>(internal
->value_
)); 
1591     return CYCastJSValue(context
, strlen(string
)); 
1594 static JSValueRef 
CString_getProperty_type(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1599     type
.primitive 
= sig::char_P
; 
1600     type
.data
.data
.type 
= NULL
; 
1601     type
.data
.data
.size 
= 0; 
1603     return CYMakeType(context
, &type
); 
1606 static JSValueRef 
Pointer_getProperty_type(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1607     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(object
))); 
1608     return CYMakeType(context
, internal
->type_
->type_
); 
1611 static JSValueRef 
CString_callAsFunction_toCYON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1612     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(_this
))); 
1613     const char *string(static_cast<const char *>(internal
->value_
)); 
1614     std::ostringstream str
; 
1616     CYStringify(str
, string
, strlen(string
), true); 
1617     std::string 
value(str
.str()); 
1618     return CYCastJSValue(context
, CYJSString(CYUTF8String(value
.c_str(), value
.size()))); 
1621 static JSValueRef 
CString_callAsFunction_toString(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1622     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(_this
))); 
1623     const char *string(static_cast<const char *>(internal
->value_
)); 
1624     return CYCastJSValue(context
, string
); 
1627 static JSValueRef 
Functor_getProperty_type(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1628     cy::Functor 
*internal(reinterpret_cast<cy::Functor 
*>(JSObjectGetPrivate(object
))); 
1629     return CYMakeType(context
, &internal
->signature_
); 
1632 static JSValueRef 
Type_getProperty_alignment(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1633     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1634     return CYCastJSValue(context
, internal
->GetFFI()->alignment
); 
1637 static JSValueRef 
Type_getProperty_name(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1638     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1639     return CYCastJSValue(context
, internal
->type_
->name
); 
1642 static JSValueRef 
Type_getProperty_size(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1643     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1644     return CYCastJSValue(context
, internal
->GetFFI()->size
); 
1647 static JSValueRef 
Type_callAsFunction_toString(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1648     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1650     const char *type(sig::Unparse(pool
, internal
->type_
)); 
1651     return CYCastJSValue(context
, CYJSString(type
)); 
1654 static JSValueRef 
Type_callAsFunction_toCYON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1655     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1659     CYOutput 
output(out
, options
); 
1660     (new(pool
) CYTypeExpression(Decode(pool
, internal
->type_
)))->Output(output
, CYNoFlags
); 
1661     return CYCastJSValue(context
, CYJSString(out
.str().c_str())); 
1664 static JSValueRef 
Type_callAsFunction_toJSON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { 
1665     return Type_callAsFunction_toString(context
, object
, _this
, count
, arguments
, exception
); 
1668 static JSStaticFunction CString_staticFunctions
[6] = { 
1669     {"toCYON", &CString_callAsFunction_toCYON
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1670     {"toJSON", &CYValue_callAsFunction_toJSON
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1671     {"toPointer", &CString_callAsFunction_toPointer
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1672     {"toString", &CString_callAsFunction_toString
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1673     {"valueOf", &CString_callAsFunction_toString
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1677 static JSStaticValue CString_staticValues
[3] = { 
1678     {"length", &CString_getProperty_length
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1679     {"type", &CString_getProperty_type
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1680     {NULL
, NULL
, NULL
, 0} 
1683 static JSStaticFunction Pointer_staticFunctions
[5] = { 
1684     {"toCYON", &Pointer_callAsFunction_toCYON
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1685     {"toJSON", &CYValue_callAsFunction_toJSON
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1686     {"toPointer", &Pointer_callAsFunction_toPointer
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1687     {"valueOf", &CYValue_callAsFunction_valueOf
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1691 static JSStaticValue Pointer_staticValues
[2] = { 
1692     {"type", &Pointer_getProperty_type
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1693     {NULL
, NULL
, NULL
, 0} 
1696 static JSStaticFunction Struct_staticFunctions
[2] = { 
1697     {"$cya", &Struct_callAsFunction_$cya
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1701 static JSStaticFunction Functor_staticFunctions
[5] = { 
1702     {"$cya", &Functor_callAsFunction_$cya
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1703     {"toCYON", &CYValue_callAsFunction_toCYON
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1704     {"toJSON", &CYValue_callAsFunction_toJSON
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1705     {"valueOf", &CYValue_callAsFunction_valueOf
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1710     JSStaticFunction 
const * const Functor::StaticFunctions 
= Functor_staticFunctions
; 
1713 static JSStaticValue Functor_staticValues
[2] = { 
1714     {"type", &Functor_getProperty_type
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1715     {NULL
, NULL
, NULL
, 0} 
1719     JSStaticValue 
const * const Functor::StaticValues 
= Functor_staticValues
; 
1722 static JSStaticValue Type_staticValues
[4] = { 
1723     {"alignment", &Type_getProperty_alignment
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1724     {"name", &Type_getProperty_name
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1725     {"size", &Type_getProperty_size
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1726     {NULL
, NULL
, NULL
, 0} 
1729 static JSStaticFunction Type_staticFunctions
[14] = { 
1730     {"arrayOf", &Type_callAsFunction_arrayOf
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1731     {"blockWith", &Type_callAsFunction_blockWith
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1732     {"constant", &Type_callAsFunction_constant
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1733     {"functionWith", &Type_callAsFunction_functionWith
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1734     {"long", &Type_callAsFunction_long
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1735     {"pointerTo", &Type_callAsFunction_pointerTo
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1736     {"short", &Type_callAsFunction_short
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1737     {"signed", &Type_callAsFunction_signed
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1738     {"withName", &Type_callAsFunction_withName
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1739     {"toCYON", &Type_callAsFunction_toCYON
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1740     {"toJSON", &Type_callAsFunction_toJSON
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1741     {"toString", &Type_callAsFunction_toString
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1742     {"unsigned", &Type_callAsFunction_unsigned
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1746 static JSObjectRef (*JSObjectMakeArray$
)(JSContextRef
, size_t, const JSValueRef
[], JSValueRef 
*); 
1748 _visible 
void CYSetArgs(int argc
, const char *argv
[]) { 
1749     JSContextRef 
context(CYGetJSContext()); 
1750     JSValueRef args
[argc
]; 
1751     for (int i(0); i 
!= argc
; ++i
) 
1752         args
[i
] = CYCastJSValue(context
, argv
[i
]); 
1755     if (JSObjectMakeArray$ 
!= NULL
) 
1756         array 
= _jsccall(*JSObjectMakeArray$
, context
, argc
, args
); 
1758         JSObjectRef 
Array(CYGetCachedObject(context
, CYJSString("Array"))); 
1759         JSValueRef 
value(CYCallAsFunction(context
, Array
, NULL
, argc
, args
)); 
1760         array 
= CYCastJSObject(context
, value
); 
1763     JSObjectRef 
System(CYGetCachedObject(context
, CYJSString("System"))); 
1764     CYSetProperty(context
, System
, CYJSString("args"), array
); 
1767 JSObjectRef 
CYGetGlobalObject(JSContextRef context
) { 
1768     return JSContextGetGlobalObject(context
); 
1771 // XXX: this is neither exceptin safe nor even terribly sane 
1772 class ExecutionHandle 
{ 
1774     JSContextRef context_
; 
1775     std::vector
<void *> handles_
; 
1778     ExecutionHandle(JSContextRef context
) : 
1781         handles_
.resize(GetHooks().size()); 
1782         for (size_t i(0); i 
!= GetHooks().size(); ++i
) { 
1783             CYHook 
*hook(GetHooks()[i
]); 
1784             if (hook
->ExecuteStart 
!= NULL
) 
1785                 handles_
[i
] = (*hook
->ExecuteStart
)(context_
); 
1791     ~ExecutionHandle() { 
1792         for (size_t i(GetHooks().size()); i 
!= 0; --i
) { 
1793             CYHook 
*hook(GetHooks()[i
-1]); 
1794             if (hook
->ExecuteEnd 
!= NULL
) 
1795                 (*hook
->ExecuteEnd
)(context_
, handles_
[i
-1]); 
1800 static volatile bool cancel_
; 
1802 static bool CYShouldTerminate(JSContextRef context
, void *arg
) { 
1806 _visible 
const char *CYExecute(JSContextRef context
, CYPool 
&pool
, CYUTF8String code
) { 
1807     ExecutionHandle 
handle(context
); 
1810     if (&JSContextGroupSetExecutionTimeLimit 
!= NULL
) 
1811         JSContextGroupSetExecutionTimeLimit(JSContextGetGroup(context
), 0.5, &CYShouldTerminate
, NULL
); 
1814         JSValueRef 
result(_jsccall(JSEvaluateScript
, context
, CYJSString(code
), NULL
, NULL
, 0)); 
1815         if (JSValueIsUndefined(context
, result
)) 
1818         std::set
<void *> objects
; 
1819         const char *json(_jsccall(CYPoolCCYON
, pool
, context
, result
, objects
)); 
1820         CYSetProperty(context
, CYGetGlobalObject(context
), Result_
, result
); 
1823     } catch (const CYException 
&error
) { 
1824         return pool
.strcat("throw ", error
.PoolCString(pool
), NULL
); 
1828 _visible 
void CYCancel() { 
1832 static const char *CYPoolLibraryPath(CYPool 
&pool
); 
1834 static bool initialized_ 
= false; 
1836 void CYInitializeDynamic() { 
1838         initialized_ 
= true; 
1842     const char *db(pool
.strcat(CYPoolLibraryPath(pool
), "/libcycript.db", NULL
)); 
1843     _sqlcall(sqlite3_open_v2(db
, &database_
, SQLITE_OPEN_READONLY
, NULL
)); 
1845     JSObjectMakeArray$ 
= reinterpret_cast<JSObjectRef (*)(JSContextRef
, size_t, const JSValueRef
[], JSValueRef 
*)>(dlsym(RTLD_DEFAULT
, "JSObjectMakeArray")); 
1846     JSSynchronousGarbageCollectForDebugging$ 
= reinterpret_cast<void (*)(JSContextRef
)>(dlsym(RTLD_DEFAULT
, "JSSynchronousGarbageCollectForDebugging")); 
1848     JSClassDefinition definition
; 
1850     definition 
= kJSClassDefinitionEmpty
; 
1851     definition
.className 
= "All"; 
1852     definition
.hasProperty 
= &All_hasProperty
; 
1853     definition
.getProperty 
= &All_getProperty
; 
1854     definition
.getPropertyNames 
= &All_getPropertyNames
; 
1855     All_ 
= JSClassCreate(&definition
); 
1857     definition 
= kJSClassDefinitionEmpty
; 
1858     definition
.className 
= "Context"; 
1859     definition
.finalize 
= &CYFinalize
; 
1860     Context_ 
= JSClassCreate(&definition
); 
1862     definition 
= kJSClassDefinitionEmpty
; 
1863     definition
.className 
= "CString"; 
1864     definition
.staticFunctions 
= CString_staticFunctions
; 
1865     definition
.staticValues 
= CString_staticValues
; 
1866     definition
.getProperty 
= &CString_getProperty
; 
1867     definition
.setProperty 
= &CString_setProperty
; 
1868     definition
.finalize 
= &CYFinalize
; 
1869     CString_ 
= JSClassCreate(&definition
); 
1871     definition 
= kJSClassDefinitionEmpty
; 
1872     definition
.className 
= "Functor"; 
1873     definition
.staticFunctions 
= cy::Functor::StaticFunctions
; 
1874     definition
.staticValues 
= Functor_staticValues
; 
1875     definition
.callAsFunction 
= &Functor_callAsFunction
; 
1876     definition
.finalize 
= &CYFinalize
; 
1877     Functor_ 
= JSClassCreate(&definition
); 
1879     definition 
= kJSClassDefinitionEmpty
; 
1880     definition
.className 
= "Pointer"; 
1881     definition
.staticFunctions 
= Pointer_staticFunctions
; 
1882     definition
.staticValues 
= Pointer_staticValues
; 
1883     definition
.callAsFunction 
= &Pointer_callAsFunction
; 
1884     definition
.getProperty 
= &Pointer_getProperty
; 
1885     definition
.setProperty 
= &Pointer_setProperty
; 
1886     definition
.finalize 
= &CYFinalize
; 
1887     Pointer_ 
= JSClassCreate(&definition
); 
1889     definition 
= kJSClassDefinitionEmpty
; 
1890     definition
.className 
= "Struct"; 
1891     definition
.staticFunctions 
= Struct_staticFunctions
; 
1892     definition
.getProperty 
= &Struct_getProperty
; 
1893     definition
.setProperty 
= &Struct_setProperty
; 
1894     definition
.getPropertyNames 
= &Struct_getPropertyNames
; 
1895     definition
.finalize 
= &CYFinalize
; 
1896     Struct_ 
= JSClassCreate(&definition
); 
1898     definition 
= kJSClassDefinitionEmpty
; 
1899     definition
.className 
= "Type"; 
1900     definition
.staticValues 
= Type_staticValues
; 
1901     definition
.staticFunctions 
= Type_staticFunctions
; 
1902     definition
.callAsFunction 
= &Type_callAsFunction
; 
1903     definition
.callAsConstructor 
= &Type_callAsConstructor
; 
1904     definition
.finalize 
= &CYFinalize
; 
1905     Type_privateData::Class_ 
= JSClassCreate(&definition
); 
1907     definition 
= kJSClassDefinitionEmpty
; 
1908     definition
.className 
= "Global"; 
1909     //definition.getProperty = &Global_getProperty; 
1910     Global_ 
= JSClassCreate(&definition
); 
1912     Array_s 
= JSStringCreateWithUTF8CString("Array"); 
1913     cy_s 
= JSStringCreateWithUTF8CString("$cy"); 
1914     cyi_s 
= JSStringCreateWithUTF8CString("$cyi"); 
1915     length_s 
= JSStringCreateWithUTF8CString("length"); 
1916     message_s 
= JSStringCreateWithUTF8CString("message"); 
1917     name_s 
= JSStringCreateWithUTF8CString("name"); 
1918     pop_s 
= JSStringCreateWithUTF8CString("pop"); 
1919     prototype_s 
= JSStringCreateWithUTF8CString("prototype"); 
1920     push_s 
= JSStringCreateWithUTF8CString("push"); 
1921     splice_s 
= JSStringCreateWithUTF8CString("splice"); 
1922     toCYON_s 
= JSStringCreateWithUTF8CString("toCYON"); 
1923     toJSON_s 
= JSStringCreateWithUTF8CString("toJSON"); 
1924     toPointer_s 
= JSStringCreateWithUTF8CString("toPointer"); 
1925     toString_s 
= JSStringCreateWithUTF8CString("toString"); 
1926     weak_s 
= JSStringCreateWithUTF8CString("weak"); 
1928     Result_ 
= JSStringCreateWithUTF8CString("_"); 
1930     for (CYHook 
*hook 
: GetHooks()) 
1931         if (hook
->Initialize 
!= NULL
) 
1932             (*hook
->Initialize
)(); 
1935 void CYThrow(JSContextRef context
, JSValueRef value
) { 
1937         throw CYJSError(context
, value
); 
1940 const char *CYJSError::PoolCString(CYPool 
&pool
) const { 
1941     std::set
<void *> objects
; 
1942     // XXX: this used to be CYPoolCString 
1943     return CYPoolCCYON(pool
, context_
, value_
, objects
); 
1946 JSValueRef 
CYJSError::CastJSValue(JSContextRef context
, const char *name
) const { 
1947     // XXX: what if the context is different? or the name? I dunno. ("epic" :/) 
1951 JSValueRef 
CYCastJSError(JSContextRef context
, const char *name
, const char *message
) { 
1952     JSObjectRef 
Error(CYGetCachedObject(context
, CYJSString(name
))); 
1953     JSValueRef arguments
[1] = {CYCastJSValue(context
, message
)}; 
1954     return _jsccall(JSObjectCallAsConstructor
, context
, Error
, 1, arguments
); 
1957 JSValueRef 
CYPoolError::CastJSValue(JSContextRef context
, const char *name
) const { 
1958     return CYCastJSError(context
, name
, message_
); 
1961 CYJSError::CYJSError(JSContextRef context
, const char *format
, ...) { 
1962     _assert(context 
!= NULL
); 
1967     va_start(args
, format
); 
1968     // XXX: there might be a beter way to think about this 
1969     const char *message(pool
.vsprintf(64, format
, args
)); 
1972     value_ 
= CYCastJSError(context
, "Error", message
); 
1975 JSGlobalContextRef 
CYGetJSContext(JSContextRef context
) { 
1976     return reinterpret_cast<Context 
*>(JSObjectGetPrivate(CYCastJSObject(context
, CYGetProperty(context
, CYGetGlobalObject(context
), cy_s
))))->context_
; 
1983     CYFile(void *data
, size_t size
) : 
1990 static void CYFileExit(void *data
) { 
1991     CYFile 
*file(reinterpret_cast<CYFile 
*>(data
)); 
1992     _syscall(munmap(file
->data_
, file
->size_
)); 
1995 static void *CYPoolFile(CYPool 
&pool
, const char *path
, size_t *psize
) { 
1996     int fd(_syscall_(open(path
, O_RDONLY
), 1, ENOENT
)); 
2001     _syscall(fstat(fd
, &stat
)); 
2002     size_t size(stat
.st_size
); 
2008         base 
= pool
.strndup("", 0); 
2010         _syscall(base 
= mmap(NULL
, size
, PROT_READ
, MAP_SHARED
, fd
, 0)); 
2012         CYFile 
*file(new (pool
) CYFile(base
, size
)); 
2013         pool
.atexit(&CYFileExit
, file
); 
2016     _syscall(close(fd
)); 
2020 static CYUTF8String 
CYPoolFileUTF8String(CYPool 
&pool
, const char *path
) { 
2022     data
.data 
= reinterpret_cast<char *>(CYPoolFile(pool
, path
, &data
.size
)); 
2026 static const char *CYPoolLibraryPath(CYPool 
&pool
) { 
2028     _assert(dladdr(reinterpret_cast<void *>(&CYPoolLibraryPath
), &addr
) != 0); 
2029     char *lib(pool
.strdup(addr
.dli_fname
)); 
2031     char *slash(strrchr(lib
, '/')); 
2032     _assert(slash 
!= NULL
); 
2038 static JSValueRef 
require_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
2039     _assert(count 
== 1); 
2042     const char *name(CYPoolCString(pool
, context
, arguments
[0])); 
2043     if (strchr(name
, '/') == NULL 
&& ( 
2045         dlopen(pool
.strcat("/System/Library/Frameworks/", name
, ".framework/", name
, NULL
), RTLD_LAZY 
| RTLD_GLOBAL
) != NULL 
|| 
2046         dlopen(pool
.strcat("/System/Library/PrivateFrameworks/", name
, ".framework/", name
, NULL
), RTLD_LAZY 
| RTLD_GLOBAL
) != NULL 
|| 
2049         return CYJSUndefined(context
); 
2051     JSObjectRef 
resolve(CYCastJSObject(context
, CYGetProperty(context
, object
, CYJSString("resolve")))); 
2052     CYJSString 
path(context
, CYCallAsFunction(context
, resolve
, NULL
, 1, arguments
)); 
2054     CYJSString 
property("exports"); 
2056     JSObjectRef 
modules(CYGetCachedObject(context
, CYJSString("modules"))); 
2057     JSValueRef 
cache(CYGetProperty(context
, modules
, path
)); 
2060     if (!JSValueIsUndefined(context
, cache
)) { 
2061         JSObjectRef 
module(CYCastJSObject(context
, cache
)); 
2062         result 
= CYGetProperty(context
, module, property
); 
2064         CYUTF8String 
code(CYPoolFileUTF8String(pool
, CYPoolCString(pool
, context
, path
))); 
2065         _assert(code
.data 
!= NULL
); 
2067         size_t length(strlen(name
)); 
2068         if (length 
>= 5 && strcmp(name 
+ length 
- 5, ".json") == 0) { 
2069             JSObjectRef 
JSON(CYGetCachedObject(context
, CYJSString("JSON"))); 
2070             JSObjectRef 
parse(CYCastJSObject(context
, CYGetProperty(context
, JSON
, CYJSString("parse")))); 
2071             JSValueRef arguments
[1] = { CYCastJSValue(context
, CYJSString(code
)) }; 
2072             result 
= CYCallAsFunction(context
, parse
, JSON
, 1, arguments
); 
2074             JSObjectRef 
module(JSObjectMake(context
, NULL
, NULL
)); 
2075             CYSetProperty(context
, modules
, path
, module); 
2077             JSObjectRef 
exports(JSObjectMake(context
, NULL
, NULL
)); 
2078             CYSetProperty(context
, module, property
, exports
); 
2080             std::stringstream wrap
; 
2081             wrap 
<< "(function (exports, require, module, __filename) { " << code 
<< "\n});"; 
2082             code 
= CYPoolCode(pool
, *wrap
.rdbuf()); 
2084             JSValueRef 
value(_jsccall(JSEvaluateScript
, context
, CYJSString(code
), NULL
, NULL
, 0)); 
2085             JSObjectRef 
function(CYCastJSObject(context
, value
)); 
2087             JSValueRef arguments
[4] = { exports
, object
, module, CYCastJSValue(context
, path
) }; 
2088             CYCallAsFunction(context
, function
, NULL
, 4, arguments
); 
2089             result 
= CYGetProperty(context
, module, property
); 
2096 static bool CYRunScript(JSGlobalContextRef context
, const char *path
) { 
2098     CYUTF8String 
code(CYPoolFileUTF8String(pool
, path
)); 
2099     if (code
.data 
== NULL
) 
2102     code 
= CYPoolCode(pool
, code
); 
2103     _jsccall(JSEvaluateScript
, context
, CYJSString(code
), NULL
, NULL
, 0); 
2107 extern "C" void CYDestroyWeak(JSWeakObjectMapRef weak
, void *data
) { 
2110 extern "C" void CYSetupContext(JSGlobalContextRef context
) { 
2111     CYInitializeDynamic(); 
2113     JSObjectRef 
global(CYGetGlobalObject(context
)); 
2115     JSObjectRef 
cy(JSObjectMake(context
, Context_
, new Context(context
))); 
2116     CYSetProperty(context
, global
, cy_s
, cy
, kJSPropertyAttributeDontEnum
); 
2118 /* Cache Globals {{{ */ 
2119     JSObjectRef 
Array(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Array")))); 
2120     CYSetProperty(context
, cy
, CYJSString("Array"), Array
); 
2122     JSObjectRef 
Array_prototype(CYCastJSObject(context
, CYGetProperty(context
, Array
, prototype_s
))); 
2123     CYSetProperty(context
, cy
, CYJSString("Array_prototype"), Array_prototype
); 
2125     JSObjectRef 
Boolean(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Boolean")))); 
2126     CYSetProperty(context
, cy
, CYJSString("Boolean"), Boolean
); 
2128     JSObjectRef 
Boolean_prototype(CYCastJSObject(context
, CYGetProperty(context
, Boolean
, prototype_s
))); 
2129     CYSetProperty(context
, cy
, CYJSString("Boolean_prototype"), Boolean_prototype
); 
2131     JSObjectRef 
Error(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Error")))); 
2132     CYSetProperty(context
, cy
, CYJSString("Error"), Error
); 
2134     JSObjectRef 
Function(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Function")))); 
2135     CYSetProperty(context
, cy
, CYJSString("Function"), Function
); 
2137     JSObjectRef 
Function_prototype(CYCastJSObject(context
, CYGetProperty(context
, Function
, prototype_s
))); 
2138     CYSetProperty(context
, cy
, CYJSString("Function_prototype"), Function_prototype
); 
2140     JSObjectRef 
JSON(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("JSON")))); 
2141     CYSetProperty(context
, cy
, CYJSString("JSON"), JSON
); 
2143     JSObjectRef 
Number(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Number")))); 
2144     CYSetProperty(context
, cy
, CYJSString("Number"), Number
); 
2146     JSObjectRef 
Number_prototype(CYCastJSObject(context
, CYGetProperty(context
, Number
, prototype_s
))); 
2147     CYSetProperty(context
, cy
, CYJSString("Number_prototype"), Number_prototype
); 
2149     JSObjectRef 
Object(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Object")))); 
2150     CYSetProperty(context
, cy
, CYJSString("Object"), Object
); 
2152     JSObjectRef 
Object_prototype(CYCastJSObject(context
, CYGetProperty(context
, Object
, prototype_s
))); 
2153     CYSetProperty(context
, cy
, CYJSString("Object_prototype"), Object_prototype
); 
2155     JSObjectRef 
String(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("String")))); 
2156     CYSetProperty(context
, cy
, CYJSString("String"), String
); 
2158     JSObjectRef 
String_prototype(CYCastJSObject(context
, CYGetProperty(context
, String
, prototype_s
))); 
2159     CYSetProperty(context
, cy
, CYJSString("String_prototype"), String_prototype
); 
2161     JSObjectRef 
SyntaxError(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("SyntaxError")))); 
2162     CYSetProperty(context
, cy
, CYJSString("SyntaxError"), SyntaxError
); 
2165     CYSetProperty(context
, Array_prototype
, toCYON_s
, &Array_callAsFunction_toCYON
, kJSPropertyAttributeDontEnum
); 
2166     CYSetProperty(context
, String_prototype
, toCYON_s
, &String_callAsFunction_toCYON
, kJSPropertyAttributeDontEnum
); 
2168     JSObjectRef 
cycript(JSObjectMake(context
, NULL
, NULL
)); 
2169     CYSetProperty(context
, global
, CYJSString("Cycript"), cycript
); 
2170     CYSetProperty(context
, cycript
, CYJSString("compile"), &Cycript_compile_callAsFunction
); 
2171     CYSetProperty(context
, cycript
, CYJSString("gc"), &Cycript_gc_callAsFunction
); 
2173     JSObjectRef 
CString(JSObjectMakeConstructor(context
, CString_
, &CString_new
)); 
2174     CYSetPrototype(context
, CYCastJSObject(context
, CYGetProperty(context
, CString
, prototype_s
)), String_prototype
); 
2175     CYSetProperty(context
, cycript
, CYJSString("CString"), CString
); 
2177     JSObjectRef 
Functor(JSObjectMakeConstructor(context
, Functor_
, &Functor_new
)); 
2178     CYSetPrototype(context
, CYCastJSObject(context
, CYGetProperty(context
, Functor
, prototype_s
)), Function_prototype
); 
2179     CYSetProperty(context
, cycript
, CYJSString("Functor"), Functor
); 
2181     CYSetProperty(context
, cycript
, CYJSString("Pointer"), JSObjectMakeConstructor(context
, Pointer_
, &Pointer_new
)); 
2182     CYSetProperty(context
, cycript
, CYJSString("Type"), JSObjectMakeConstructor(context
, Type_privateData::Class_
, &Type_new
)); 
2184     JSObjectRef 
modules(JSObjectMake(context
, NULL
, NULL
)); 
2185     CYSetProperty(context
, cy
, CYJSString("modules"), modules
); 
2187     JSObjectRef 
all(JSObjectMake(context
, All_
, NULL
)); 
2188     CYSetProperty(context
, cycript
, CYJSString("all"), all
); 
2190     JSObjectRef 
alls(_jsccall(JSObjectCallAsConstructor
, context
, Array
, 0, NULL
)); 
2191     CYSetProperty(context
, cycript
, CYJSString("alls"), alls
); 
2194         JSObjectRef 
last(NULL
), curr(global
); 
2196         goto next
; for (JSValueRef next
;;) { 
2197             if (JSValueIsNull(context
, next
)) 
2200             curr 
= CYCastJSObject(context
, next
); 
2202             next 
= JSObjectGetPrototype(context
, curr
); 
2205         CYSetPrototype(context
, last
, all
); 
2208     JSObjectRef 
System(JSObjectMake(context
, NULL
, NULL
)); 
2209     CYSetProperty(context
, cy
, CYJSString("System"), System
); 
2211     CYSetProperty(context
, all
, CYJSString("require"), &require_callAsFunction
, kJSPropertyAttributeDontEnum
); 
2213     CYSetProperty(context
, global
, CYJSString("system"), System
); 
2214     CYSetProperty(context
, System
, CYJSString("args"), CYJSNull(context
)); 
2215     CYSetProperty(context
, System
, CYJSString("print"), &System_print
); 
2217     CYSetProperty(context
, global
, CYJSString("global"), global
); 
2220     if (&JSWeakObjectMapCreate 
!= NULL
) { 
2221         JSWeakObjectMapRef 
weak(JSWeakObjectMapCreate(context
, NULL
, &CYDestroyWeak
)); 
2222         CYSetProperty(context
, cy
, weak_s
, CYCastJSValue(context
, reinterpret_cast<uintptr_t>(weak
))); 
2226     CYSetProperty(context
, global
, CYJSString("dlerror"), CYMakeFunctor(context
, "dlerror", "*"), kJSPropertyAttributeDontEnum
); 
2227     CYSetProperty(context
, global
, CYJSString("RTLD_DEFAULT"), CYCastJSValue(context
, reinterpret_cast<intptr_t>(RTLD_DEFAULT
)), kJSPropertyAttributeDontEnum
); 
2228     CYSetProperty(context
, global
, CYJSString("dlsym"), CYMakeFunctor(context
, "dlsym", "^v^v*"), kJSPropertyAttributeDontEnum
); 
2230     CYSetProperty(context
, global
, CYJSString("NULL"), CYJSNull(context
), kJSPropertyAttributeDontEnum
); 
2232     CYSetProperty(context
, global
, CYJSString("bool"), CYMakeType(context
, "B"), kJSPropertyAttributeDontEnum
); 
2233     CYSetProperty(context
, global
, CYJSString("char"), CYMakeType(context
, "c"), kJSPropertyAttributeDontEnum
); 
2234     CYSetProperty(context
, global
, CYJSString("short"), CYMakeType(context
, "s"), kJSPropertyAttributeDontEnum
); 
2235     CYSetProperty(context
, global
, CYJSString("int"), CYMakeType(context
, "i"), kJSPropertyAttributeDontEnum
); 
2236     CYSetProperty(context
, global
, CYJSString("long"), CYMakeType(context
, "l"), kJSPropertyAttributeDontEnum
); 
2237     CYSetProperty(context
, global
, CYJSString("float"), CYMakeType(context
, "f"), kJSPropertyAttributeDontEnum
); 
2238     CYSetProperty(context
, global
, CYJSString("double"), CYMakeType(context
, "d"), kJSPropertyAttributeDontEnum
); 
2240     CYRunScript(context
, "libcycript.cy"); 
2242     for (CYHook 
*hook 
: GetHooks()) 
2243         if (hook
->SetupContext 
!= NULL
) 
2244             (*hook
->SetupContext
)(context
); 
2246     CYArrayPush(context
, alls
, cycript
); 
2249 static JSGlobalContextRef context_
; 
2251 _visible JSGlobalContextRef 
CYGetJSContext() { 
2252     CYInitializeDynamic(); 
2254     if (context_ 
== NULL
) { 
2255         context_ 
= JSGlobalContextCreate(Global_
); 
2256         CYSetupContext(context_
); 
2262 _visible 
void CYDestroyContext() { 
2263     if (context_ 
== NULL
) 
2265     JSGlobalContextRelease(context_
);