1 /* Cycript - The Truly Universal Scripting Language 
   2  * Copyright (C) 2009-2016  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" 
  48 #include "Execute.hpp" 
  49 #include "Internal.hpp" 
  50 #include "JavaScript.hpp" 
  51 #include "Pooling.hpp" 
  54 const char *sqlite3_column_string(sqlite3_stmt 
*stmt
, int n
) { 
  55     return reinterpret_cast<const char *>(sqlite3_column_text(stmt
, n
)); 
  58 char *sqlite3_column_pooled(CYPool 
&pool
, sqlite3_stmt 
*stmt
, int n
) { 
  59     if (const char *value 
= sqlite3_column_string(stmt
, n
)) 
  60         return pool
.strdup(value
); 
  64 static std::vector
<CYHook 
*> &GetHooks() { 
  65     static std::vector
<CYHook 
*> hooks
; 
  69 CYRegisterHook::CYRegisterHook(CYHook 
*hook
) { 
  70     GetHooks().push_back(hook
); 
  73 /* JavaScript Properties {{{ */ 
  74 bool CYHasProperty(JSContextRef context
, JSObjectRef object
, JSStringRef name
) { 
  75     return JSObjectHasProperty(context
, object
, name
); 
  78 JSValueRef 
CYGetProperty(JSContextRef context
, JSObjectRef object
, size_t index
) { 
  79     return _jsccall(JSObjectGetPropertyAtIndex
, context
, object
, index
); 
  82 JSValueRef 
CYGetProperty(JSContextRef context
, JSObjectRef object
, JSStringRef name
) { 
  83     return _jsccall(JSObjectGetProperty
, context
, object
, name
); 
  86 void CYSetProperty(JSContextRef context
, JSObjectRef object
, size_t index
, JSValueRef value
) { 
  87     _jsccall(JSObjectSetPropertyAtIndex
, context
, object
, index
, value
); 
  90 void CYSetProperty(JSContextRef context
, JSObjectRef object
, JSStringRef name
, JSValueRef value
, JSPropertyAttributes attributes
) { 
  91     _jsccall(JSObjectSetProperty
, context
, object
, name
, value
, attributes
); 
  94 void CYSetProperty(JSContextRef context
, JSObjectRef object
, JSStringRef name
, JSValueRef (*callback
)(JSContextRef
, JSObjectRef
, JSObjectRef
, size_t, const JSValueRef
[], JSValueRef 
*), JSPropertyAttributes attributes
) { 
  95     CYSetProperty(context
, object
, name
, JSObjectMakeFunctionWithCallback(context
, name
, callback
), attributes
); 
  98 JSObjectRef 
CYGetPrototype(JSContextRef context
, JSObjectRef object
) { 
  99     return CYCastJSObject(context
, JSObjectGetPrototype(context
, object
)); 
 102 void CYSetPrototype(JSContextRef context
, JSObjectRef object
, JSValueRef value
) { 
 103     _assert(!JSValueIsUndefined(context
, value
)); 
 104     JSObjectSetPrototype(context
, object
, value
); 
 105     _assert(CYIsStrictEqual(context
, JSObjectGetPrototype(context
, object
), value
)); 
 108 /* JavaScript Strings {{{ */ 
 109 JSStringRef 
CYCopyJSString(const char *value
) { 
 110     return value 
== NULL 
? NULL 
: JSStringCreateWithUTF8CString(value
); 
 113 JSStringRef 
CYCopyJSString(JSStringRef value
) { 
 114     return value 
== NULL 
? NULL 
: JSStringRetain(value
); 
 117 JSStringRef 
CYCopyJSString(CYUTF8String value
) { 
 118     if (memchr(value
.data
, '\0', value
.size
) != NULL
) { 
 120         return CYCopyJSString(CYPoolUTF16String(pool
, value
)); 
 121     } else if (value
.data
[value
.size
] != '\0') { 
 123         return CYCopyJSString(pool
.strmemdup(value
.data
, value
.size
)); 
 125         return CYCopyJSString(value
.data
); 
 129 JSStringRef 
CYCopyJSString(const std::string 
&value
) { 
 130     return CYCopyJSString(CYUTF8String(value
.c_str(), value
.size())); 
 133 JSStringRef 
CYCopyJSString(CYUTF16String value
) { 
 134     return JSStringCreateWithCharacters(value
.data
, value
.size
); 
 137 JSStringRef 
CYCopyJSString(JSContextRef context
, JSValueRef value
) { 
 138     if (JSValueIsNull(context
, value
)) 
 140     return _jsccall(JSValueToStringCopy
, context
, value
); 
 143 CYUTF16String 
CYCastUTF16String(JSStringRef value
) { 
 144     return CYUTF16String(JSStringGetCharactersPtr(value
), JSStringGetLength(value
)); 
 147 const char *CYPoolCString(CYPool 
&pool
, CYUTF8String utf8
) { 
 148     return pool
.strndup(utf8
.data
, utf8
.size
); 
 151 CYUTF8String 
CYPoolUTF8String(CYPool 
&pool
, CYUTF8String utf8
) { 
 152     return {pool
.strndup(utf8
.data
, utf8
.size
), utf8
.size
}; 
 155 _visible CYUTF8String 
CYPoolUTF8String(CYPool 
&pool
, const std::string 
&value
) { 
 156     return {pool
.strndup(value
.data(), value
.size()), value
.size()}; 
 159 CYUTF8String 
CYPoolUTF8String(CYPool 
&pool
, JSContextRef context
, JSStringRef value
) { 
 160     return CYPoolUTF8String(pool
, CYCastUTF16String(value
)); 
 163 const char *CYPoolCString(CYPool 
&pool
, JSContextRef context
, JSStringRef value
) { 
 164     CYUTF8String 
utf8(CYPoolUTF8String(pool
, context
, value
)); 
 165     _assert(memchr(utf8
.data
, '\0', utf8
.size
) == NULL
); 
 169 const char *CYPoolCString(CYPool 
&pool
, JSContextRef context
, JSValueRef value
) { 
 170     return JSValueIsNull(context
, value
) ? NULL 
: CYPoolCString(pool
, context
, CYJSString(context
, value
)); 
 173 /* Index Offsets {{{ */ 
 174 size_t CYGetIndex(CYPool 
&pool
, JSContextRef context
, JSStringRef value
) { 
 175     return CYGetIndex(CYPoolUTF8String(pool
, context
, value
)); 
 179 static JSObjectRef (*JSObjectMakeArray$
)(JSContextRef
, size_t, const JSValueRef
[], JSValueRef 
*); 
 181 JSObjectRef 
CYObjectMakeArray(JSContextRef context
, size_t length
, const JSValueRef values
[]) { 
 182     if (JSObjectMakeArray$ 
!= NULL
) 
 183         return _jsccall(*JSObjectMakeArray$
, context
, length
, values
); 
 184     JSObjectRef 
Array(CYGetCachedObject(context
, CYJSString("Array"))); 
 185     bool wat(length 
== 1 && JSValueGetType(context
, values
[0]) == kJSTypeNumber
); 
 186     JSValueRef 
value(CYCallAsFunction(context
, Array
, NULL
, wat 
? 0 : length
, values
)); 
 187     JSObjectRef 
object(CYCastJSObject(context
, value
)); 
 188     if (wat
) CYArrayPush(context
, object
, 1, values
); 
 192 static JSClassRef All_
; 
 193 JSClassRef 
cy::Functor::Class_
; 
 194 static JSClassRef Global_
; 
 197 JSStringRef constructor_s
; 
 201 JSStringRef length_s
; 
 202 JSStringRef message_s
; 
 205 JSStringRef prototype_s
; 
 207 JSStringRef splice_s
; 
 208 JSStringRef toCYON_s
; 
 209 JSStringRef toJSON_s
; 
 210 JSStringRef toPointer_s
; 
 211 JSStringRef toString_s
; 
 214 static sqlite3 
*database_
; 
 216 static JSStringRef Result_
; 
 218 void CYFinalize(JSObjectRef object
) { 
 219     CYData 
*internal(reinterpret_cast<CYData 
*>(JSObjectGetPrivate(object
))); 
 220     _assert(internal
->count_ 
!= _not(unsigned)); 
 221     if (--internal
->count_ 
== 0) 
 225 sig::Type 
*Structor_(CYPool 
&pool
, sig::Aggregate 
*aggregate
) { 
 233     JSGlobalContextRef context_
; 
 235     Context(JSGlobalContextRef context
) : 
 246     Type_privateData 
*type_
; 
 249     CArray(void *value
, size_t length
, const sig::Type 
&type
, ffi_type 
*ffi
, JSContextRef context
, JSObjectRef owner
) : 
 251         owner_(context
, owner
), 
 252         type_(new(*pool_
) Type_privateData(type
, ffi
)), 
 264     CString(char *value
, JSContextRef context
, JSObjectRef owner
) : 
 266         owner_(context
, owner
) 
 276     Type_privateData 
*type_
; 
 278     Pointer(void *value
, const sig::Type 
&type
, JSContextRef context
, JSObjectRef owner
) : 
 280         owner_(context
, owner
), 
 281         type_(new(*pool_
) Type_privateData(type
)) 
 285     Pointer(void *value
, const char *encoding
, JSContextRef context
, JSObjectRef owner
) : 
 287         owner_(context
, owner
), 
 288         type_(new(*pool_
) Type_privateData(encoding
)) 
 293 struct Struct_privateData 
: 
 298     Type_privateData 
*type_
; 
 300     Struct_privateData(void *value
, const sig::Type 
&type
, ffi_type 
*ffi
, JSContextRef context
, JSObjectRef owner
) : 
 302         owner_(context
, owner
), 
 303         type_(new(*pool_
) Type_privateData(type
, ffi
)) 
 306             size_t size(ffi
->size
); 
 307             void *copy(pool_
->malloc
<void>(size
, ffi
->alignment
)); 
 308             memcpy(copy
, value_
, size
); 
 314 static void *CYCastSymbol(const char *name
) { 
 315     for (CYHook 
*hook 
: GetHooks()) 
 316         if (hook
->CastSymbol 
!= NULL
) 
 317             if (void *value 
= (*hook
->CastSymbol
)(name
)) 
 319     return dlsym(RTLD_DEFAULT
, name
); 
 322 JSValueRef 
CYCastJSValue(JSContextRef context
, bool value
) { 
 323     return JSValueMakeBoolean(context
, value
); 
 326 JSValueRef 
CYCastJSValue(JSContextRef context
, double value
) { 
 327     return JSValueMakeNumber(context
, value
); 
 330 #define CYCastJSValue_(Type_) \ 
 331     JSValueRef CYCastJSValue(JSContextRef context, Type_ value) { \ 
 332         _assert(static_cast<Type_>(static_cast<double>(value)) == value); \ 
 333         return JSValueMakeNumber(context, static_cast<double>(value)); \ 
 336 CYCastJSValue_(long double) 
 337 CYCastJSValue_(signed short int) 
 338 CYCastJSValue_(unsigned short int) 
 339 CYCastJSValue_(signed int) 
 340 CYCastJSValue_(unsigned int) 
 341 CYCastJSValue_(signed long int) 
 342 CYCastJSValue_(unsigned long int) 
 343 CYCastJSValue_(signed long long int) 
 344 CYCastJSValue_(unsigned long long int) 
 346 #ifdef __SIZEOF_INT128__ 
 347 CYCastJSValue_(signed __int128
) 
 348 CYCastJSValue_(unsigned __int128
) 
 351 JSValueRef 
CYJSUndefined(JSContextRef context
) { 
 352     return JSValueMakeUndefined(context
); 
 355 double CYCastDouble(JSContextRef context
, JSValueRef value
) { 
 356     return _jsccall(JSValueToNumber
, context
, value
); 
 359 bool CYCastBool(JSContextRef context
, JSValueRef value
) { 
 360     return JSValueToBoolean(context
, value
); 
 363 JSValueRef 
CYJSNull(JSContextRef context
) { 
 364     return JSValueMakeNull(context
); 
 367 JSValueRef 
CYCastJSValue(JSContextRef context
, JSStringRef value
) { 
 368     return value 
== NULL 
? CYJSNull(context
) : JSValueMakeString(context
, value
); 
 371 JSValueRef 
CYCastJSValue(JSContextRef context
, const char *value
) { 
 372     return CYCastJSValue(context
, CYJSString(value
)); 
 375 JSObjectRef 
CYCastJSObject(JSContextRef context
, JSValueRef value
) { 
 376     return _jsccall(JSValueToObject
, context
, value
); 
 379 JSValueRef 
CYCallAsFunction(JSContextRef context
, JSObjectRef function
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[]) { 
 380     return _jsccall(JSObjectCallAsFunction
, context
, function
, _this
, count
, arguments
); 
 383 bool CYIsCallable(JSContextRef context
, JSValueRef value
) { 
 384     return value 
!= NULL 
&& JSValueIsObject(context
, value
) && JSObjectIsFunction(context
, (JSObjectRef
) value
); 
 387 bool CYIsEqual(JSContextRef context
, JSValueRef lhs
, JSValueRef rhs
) { 
 388     return _jsccall(JSValueIsEqual
, context
, lhs
, rhs
); 
 391 bool CYIsStrictEqual(JSContextRef context
, JSValueRef lhs
, JSValueRef rhs
) { 
 392     return JSValueIsStrictEqual(context
, lhs
, rhs
); 
 395 size_t CYArrayLength(JSContextRef context
, JSObjectRef array
) { 
 396     return CYCastDouble(context
, CYGetProperty(context
, array
, length_s
)); 
 399 JSValueRef 
CYArrayGet(JSContextRef context
, JSObjectRef array
, size_t index
) { 
 400     return _jsccall(JSObjectGetPropertyAtIndex
, context
, array
, index
); 
 403 void CYArrayPush(JSContextRef context
, JSObjectRef array
, size_t length
, const JSValueRef arguments
[]) { 
 404     JSObjectRef 
Array(CYGetCachedObject(context
, CYJSString("Array_prototype"))); 
 405     _jsccall(JSObjectCallAsFunction
, context
, CYCastJSObject(context
, CYGetProperty(context
, Array
, push_s
)), array
, length
, arguments
); 
 408 void CYArrayPush(JSContextRef context
, JSObjectRef array
, JSValueRef value
) { 
 409     return CYArrayPush(context
, array
, 1, &value
); 
 412 static JSValueRef 
System_print(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
 419         CYUTF8String 
string(CYPoolUTF8String(pool
, context
, CYJSString(context
, arguments
[0]))); 
 420         fwrite(string
.data
, string
.size
, 1, file
); 
 424     return CYJSUndefined(context
); 
 427 static JSValueRef 
Global_print(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
 431     for (size_t i(0); i 
!= count
; ++i
) { 
 434         CYUTF8String 
string(CYPoolUTF8String(pool
, context
, CYJSString(context
, arguments
[i
]))); 
 435         fwrite(string
.data
, string
.size
, 1, file
); 
 440     return CYJSUndefined(context
); 
 443 static void (*JSSynchronousGarbageCollectForDebugging$
)(JSContextRef
); 
 445 _visible 
void CYGarbageCollect(JSContextRef context
) { 
 446     (JSSynchronousGarbageCollectForDebugging$ 
?: &JSGarbageCollect
)(context
); 
 449 static JSValueRef 
Cycript_compile_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
 451     CYUTF8String 
before(CYPoolUTF8String(pool
, context
, CYJSString(context
, arguments
[0]))); 
 452     CYUTF8String 
after(CYPoolCode(pool
, before
)); 
 453     return CYCastJSValue(context
, CYJSString(after
)); 
 454 } CYCatch_(NULL
, "SyntaxError") } 
 456 static JSValueRef 
Cycript_gc_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
 457     CYGarbageCollect(context
); 
 458     return CYJSUndefined(context
); 
 461 const char *CYPoolCCYON(CYPool 
&pool
, JSContextRef context
, JSValueRef value
, std::set
<void *> &objects
, JSValueRef 
*exception
) { CYTry 
{ 
 462     switch (JSType type 
= JSValueGetType(context
, value
)) { 
 463         case kJSTypeUndefined
: 
 468             return CYCastBool(context
, value
) ? "true" : "false"; 
 470         case kJSTypeNumber
: { 
 471             std::ostringstream str
; 
 472             CYNumerify(str
, CYCastDouble(context
, value
)); 
 473             std::string 
value(str
.str()); 
 474             return pool
.strmemdup(value
.c_str(), value
.size()); 
 477         case kJSTypeString
: { 
 478             std::ostringstream str
; 
 479             CYUTF8String 
string(CYPoolUTF8String(pool
, context
, CYJSString(context
, value
))); 
 480             CYStringify(str
, string
.data
, string
.size
, CYStringifyModeCycript
); 
 481             std::string 
value(str
.str()); 
 482             return pool
.strmemdup(value
.c_str(), value
.size()); 
 486             return CYPoolCCYON(pool
, context
, (JSObjectRef
) value
, objects
); 
 488             throw CYJSError(context
, "JSValueGetType() == 0x%x", type
); 
 492 const char *CYPoolCCYON(CYPool 
&pool
, JSContextRef context
, JSValueRef value
, std::set
<void *> &objects
) { 
 493     return _jsccall(CYPoolCCYON
, pool
, context
, value
, objects
); 
 496 const char *CYPoolCCYON(CYPool 
&pool
, JSContextRef context
, JSValueRef value
, std::set
<void *> *objects
) { 
 498         return CYPoolCCYON(pool
, context
, value
, *objects
); 
 500         std::set
<void *> objects
; 
 501         return CYPoolCCYON(pool
, context
, value
, objects
); 
 505 const char *CYPoolCCYON(CYPool 
&pool
, JSContextRef context
, JSObjectRef object
, std::set
<void *> &objects
) { 
 506     JSValueRef 
toCYON(CYGetProperty(context
, object
, toCYON_s
)); 
 507     if (CYIsCallable(context
, toCYON
)) { 
 508         // XXX: this needs to be abstracted behind some kind of function 
 509         JSValueRef arguments
[1] = {CYCastJSValue(context
, reinterpret_cast<uintptr_t>(&objects
))}; 
 510         JSValueRef 
value(CYCallAsFunction(context
, (JSObjectRef
) toCYON
, object
, 1, arguments
)); 
 511         _assert(value 
!= NULL
); 
 512         return CYPoolCString(pool
, context
, value
); 
 515     JSValueRef 
toJSON(CYGetProperty(context
, object
, toJSON_s
)); 
 516     if (CYIsCallable(context
, toJSON
)) { 
 517         JSValueRef arguments
[1] = {CYCastJSValue(context
, CYJSString(""))}; 
 518         return _jsccall(CYPoolCCYON
, pool
, context
, CYCallAsFunction(context
, (JSObjectRef
) toJSON
, object
, 1, arguments
), objects
); 
 521     if (JSObjectIsFunction(context
, object
)) { 
 522         JSValueRef 
toString(CYGetProperty(context
, object
, toString_s
)); 
 523         if (CYIsCallable(context
, toString
)) { 
 524             JSValueRef arguments
[1] = {CYCastJSValue(context
, CYJSString(""))}; 
 525             JSValueRef 
value(CYCallAsFunction(context
, (JSObjectRef
) toString
, object
, 1, arguments
)); 
 526             _assert(value 
!= NULL
); 
 527             return CYPoolCString(pool
, context
, value
); 
 531     _assert(objects
.insert(object
).second
); 
 533     std::ostringstream str
; 
 535     JSValueRef 
value(CYGetProperty(context
, object
, constructor_s
)); 
 536     if (JSValueIsObject(context
, value
)) { 
 537         JSObjectRef 
constructor(CYCastJSObject(context
, value
)); 
 538         JSValueRef 
theory(CYGetProperty(context
, constructor
, prototype_s
)); 
 539         JSValueRef 
practice(JSObjectGetPrototype(context
, object
)); 
 541         if (CYIsStrictEqual(context
, theory
, practice
)) { 
 542             JSValueRef 
name(CYGetProperty(context
, constructor
, name_s
)); 
 543             if (!JSValueIsUndefined(context
, name
)) { 
 544                 auto utf8(CYPoolUTF8String(pool
, context
, CYJSString(context
, name
))); 
 545                 if (utf8 
!= "Object") 
 546                     str 
<< "new" << ' ' << utf8
; 
 553     // XXX: this is, sadly, going to leak 
 554     JSPropertyNameArrayRef 
names(JSObjectCopyPropertyNames(context
, object
)); 
 558     for (size_t index(0), count(JSPropertyNameArrayGetCount(names
)); index 
!= count
; ++index
) { 
 564         JSStringRef 
name(JSPropertyNameArrayGetNameAtIndex(names
, index
)); 
 565         CYUTF8String 
string(CYPoolUTF8String(pool
, context
, name
)); 
 570             CYStringify(str
, string
.data
, string
.size
, CYStringifyModeLegacy
); 
 575             JSValueRef 
value(CYGetProperty(context
, object
, name
)); 
 576             str 
<< CYPoolCCYON(pool
, context
, value
, objects
); 
 577         } catch (const CYException 
&error
) { 
 582     JSPropertyNameArrayRelease(names
); 
 586     std::string 
string(str
.str()); 
 587     return pool
.strmemdup(string
.c_str(), string
.size()); 
 590 std::set
<void *> *CYCastObjects(JSContextRef context
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[]) { 
 593     return CYCastPointer
<std::set
<void *> *>(context
, arguments
[0]); 
 596 static JSValueRef 
Array_callAsFunction_toCYON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
 597     std::set
<void *> *objects(CYCastObjects(context
, _this
, count
, arguments
)); 
 598     // XXX: this is horribly inefficient 
 599     std::set
<void *> backup
; 
 604     std::ostringstream str
; 
 608     JSValueRef 
length(CYGetProperty(context
, _this
, length_s
)); 
 611     for (size_t index(0), count(CYCastDouble(context
, length
)); index 
!= count
; ++index
) { 
 618             JSValueRef 
value(CYGetProperty(context
, _this
, index
)); 
 619             if (!JSValueIsUndefined(context
, value
)) 
 620                 str 
<< CYPoolCCYON(pool
, context
, value
, *objects
); 
 625         } catch (const CYException 
&error
) { 
 632     std::string 
value(str
.str()); 
 633     return CYCastJSValue(context
, CYJSString(CYUTF8String(value
.c_str(), value
.size()))); 
 636 static JSValueRef 
String_callAsFunction_toCYON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
 638     std::ostringstream str
; 
 640     CYUTF8String 
string(CYPoolUTF8String(pool
, context
, CYJSString(context
, _this
))); 
 641     CYStringify(str
, string
.data
, string
.size
, CYStringifyModeCycript
); 
 643     std::string 
value(str
.str()); 
 644     return CYCastJSValue(context
, CYJSString(CYUTF8String(value
.c_str(), value
.size()))); 
 647 JSObjectRef 
CYMakePointer(JSContextRef context
, void *pointer
, const sig::Type 
&type
, ffi_type 
*ffi
, JSObjectRef owner
) { 
 648     return CYPrivate
<Pointer
>::Make(context
, pointer
, type
, context
, owner
); 
 651 static JSValueRef 
CYMakeFunctor(JSContextRef context
, void (*function
)(), bool variadic
, const sig::Signature 
&signature
) { 
 652     if (function 
== NULL
) 
 653         return CYJSNull(context
); 
 654     return JSObjectMake(context
, cy::Functor::Class_
, new cy::Functor(function
, variadic
, signature
)); 
 657 // XXX: remove this, as it is really stupid 
 658 static JSObjectRef 
CYMakeFunctor(JSContextRef context
, const char *symbol
, const char *encoding
) { 
 659     void (*function
)()(reinterpret_cast<void (*)()>(CYCastSymbol(symbol
))); 
 660     if (function 
== NULL
) 
 663     cy::Functor 
*internal(new cy::Functor(function
, encoding
)); 
 665     return JSObjectMake(context
, cy::Functor::Class_
, internal
); 
 668 bool CYGetOffset(CYPool 
&pool
, JSContextRef context
, JSStringRef value
, ssize_t 
&index
) { 
 669     return CYGetOffset(CYPoolCString(pool
, context
, value
), index
); 
 672 void *CYCastPointer_(JSContextRef context
, JSValueRef value
, bool *guess
) { 
 675     else switch (JSValueGetType(context
, value
)) { 
 678         case kJSTypeObject
: { 
 679             JSObjectRef 
object((JSObjectRef
) value
); 
 680             if (JSValueIsObjectOfClass(context
, value
, CYPrivate
<Pointer
>::Class_
)) { 
 681                 Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(object
))); 
 682                 return internal
->value_
; 
 684             JSValueRef 
toPointer(CYGetProperty(context
, object
, toPointer_s
)); 
 685             if (CYIsCallable(context
, toPointer
)) { 
 686                 JSValueRef 
value(CYCallAsFunction(context
, (JSObjectRef
) toPointer
, object
, 0, NULL
)); 
 687                 _assert(value 
!= NULL
); 
 688                 return CYCastPointer_(context
, value
, guess
); 
 694             double number(CYCastDouble(context
, value
)); 
 695             if (!std::isnan(number
)) 
 696                 return reinterpret_cast<void *>(static_cast<uintptr_t>(static_cast<long long>(number
))); 
 698                 throw CYJSError(context
, "cannot convert value to pointer"); 
 708 // XXX: this is somehow not quite a template :/ 
 711 void Primitive
<bool>::PoolFFI(CYPool 
*pool
, JSContextRef context
, ffi_type 
*ffi
, void *data
, JSValueRef value
) const { 
 712     *reinterpret_cast<bool *>(data
) = JSValueToBoolean(context
, value
); 
 715 #define CYPoolFFI_(Type_) \ 
 717 void Primitive<Type_>::PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const { \ 
 718     *reinterpret_cast<Type_ *>(data) = CYCastDouble(context, value); \ 
 724 CYPoolFFI_(long double) 
 726 CYPoolFFI_(signed char) 
 727 CYPoolFFI_(signed int) 
 728 CYPoolFFI_(signed long int) 
 729 CYPoolFFI_(signed long long int) 
 730 CYPoolFFI_(signed short int) 
 732 CYPoolFFI_(unsigned char) 
 733 CYPoolFFI_(unsigned int) 
 734 CYPoolFFI_(unsigned long int) 
 735 CYPoolFFI_(unsigned long long int) 
 736 CYPoolFFI_(unsigned short int) 
 738 #ifdef __SIZEOF_INT128__ 
 739 CYPoolFFI_(signed __int128
) 
 740 CYPoolFFI_(unsigned __int128
) 
 744 void Primitive
<char>::PoolFFI(CYPool 
*pool
, JSContextRef context
, ffi_type 
*ffi
, void *data
, JSValueRef value
) const { 
 745     if (JSValueGetType(context
, value
) != kJSTypeString
) 
 746         *reinterpret_cast<char *>(data
) = CYCastDouble(context
, value
); 
 748         CYJSString 
script(context
, value
); 
 749         auto string(CYCastUTF16String(script
)); 
 750         _assert(string
.size 
== 1); 
 751         *reinterpret_cast<char *>(data
) = string
.data
[0]; 
 755 void Void::PoolFFI(CYPool 
*pool
, JSContextRef context
, ffi_type 
*ffi
, void *data
, JSValueRef value
) const { 
 759 void Unknown::PoolFFI(CYPool 
*pool
, JSContextRef context
, ffi_type 
*ffi
, void *data
, JSValueRef value
) const { 
 763 void String::PoolFFI(CYPool 
*pool
, JSContextRef context
, ffi_type 
*ffi
, void *data
, JSValueRef value
) const { 
 765     *reinterpret_cast<const char **>(data
) = CYCastPointer
<const char *>(context
, value
, &guess
); 
 766     if (guess 
&& pool 
!= NULL
) 
 767         *reinterpret_cast<const char **>(data
) = CYPoolCString(*pool
, context
, value
); 
 770 void Bits::PoolFFI(CYPool 
*pool
, JSContextRef context
, ffi_type 
*ffi
, void *data
, JSValueRef value
) const { 
 774 static void CYArrayCopy(CYPool 
*pool
, JSContextRef context
, uint8_t *base
, size_t length
, const sig::Type 
&type
, ffi_type 
*ffi
, JSObjectRef object
) { 
 775     for (size_t index(0); index 
!= length
; ++index
) { 
 776         JSValueRef 
rhs(CYGetProperty(context
, object
, index
)); 
 777         if (JSValueIsUndefined(context
, rhs
)) 
 778             throw CYJSError(context
, "unable to extract array value"); 
 779         type
.PoolFFI(pool
, context
, ffi
, base
, rhs
); 
 784 void Pointer::PoolFFI(CYPool 
*pool
, JSContextRef context
, ffi_type 
*ffi
, void *data
, JSValueRef value
) const { 
 786     *reinterpret_cast<void **>(data
) = CYCastPointer
<void *>(context
, value
, &guess
); 
 787     if (!guess 
|| pool 
== NULL 
|| !JSValueIsObject(context
, value
)) 
 789     JSObjectRef 
object(CYCastJSObject(context
, value
)); 
 790     if (CYHasProperty(context
, object
, length_s
)) { 
 791         size_t length(CYArrayLength(context
, object
)); 
 792         ffi_type 
*element(type
.GetFFI(*pool
)); 
 793         size_t size(element
->size 
* length
); 
 794         uint8_t *base(pool
->malloc
<uint8_t>(size
, element
->alignment
)); 
 795         CYArrayCopy(pool
, context
, base
, length
, type
, element
, object
); 
 796         *reinterpret_cast<void **>(data
) = base
; 
 800 void Array::PoolFFI(CYPool 
*pool
, JSContextRef context
, ffi_type 
*ffi
, void *data
, JSValueRef value
) const { 
 803     uint8_t *base(reinterpret_cast<uint8_t *>(data
)); 
 804     CYArrayCopy(pool
, context
, base
, size
, type
, ffi
->elements
[0], CYCastJSObject(context
, value
)); 
 807 void Enum::PoolFFI(CYPool 
*pool
, JSContextRef context
, ffi_type 
*ffi
, void *data
, JSValueRef value
) const { 
 808     return type
.PoolFFI(pool
, context
, ffi
, data
, value
); 
 811 void Aggregate::PoolFFI(CYPool 
*pool
, JSContextRef context
, ffi_type 
*ffi
, void *data
, JSValueRef value
) const { 
 813     _assert(signature
.count 
!= _not(size_t)); 
 816     uint8_t *base(reinterpret_cast<uint8_t *>(data
)); 
 817     JSObjectRef 
aggregate(JSValueIsObject(context
, value
) ? (JSObjectRef
) value 
: NULL
); 
 818     for (size_t index(0); index 
!= signature
.count
; ++index
) { 
 819         sig::Element 
*element(&signature
.elements
[index
]); 
 820         ffi_type 
*field(ffi
->elements
[index
]); 
 823         if (aggregate 
== NULL
) 
 826             rhs 
= CYGetProperty(context
, aggregate
, index
); 
 827             if (JSValueIsUndefined(context
, rhs
)) { 
 828                 if (element
->name 
!= NULL
) 
 829                     rhs 
= CYGetProperty(context
, aggregate
, CYJSString(element
->name
)); 
 832                 if (JSValueIsUndefined(context
, rhs
)) undefined
: 
 833                     throw CYJSError(context
, "unable to extract structure value"); 
 837         element
->type
->PoolFFI(pool
, context
, field
, base 
+ offset
, rhs
); 
 838         offset 
+= field
->size
; 
 839         CYAlign(offset
, field
->alignment
); 
 843 void Function::PoolFFI(CYPool 
*pool
, JSContextRef context
, ffi_type 
*ffi
, void *data
, JSValueRef value
) const { 
 847 #define CYFromFFI_(Type_) \ 
 849 JSValueRef Primitive<Type_>::FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const { \ 
 850     JSValueRef value(CYCastJSValue(context, *reinterpret_cast<Type_ *>(data))); \ 
 851     JSObjectRef typed(_jsccall(JSObjectCallAsConstructor, context, CYGetCachedObject(context, CYJSString("Number")), 1, &value)); \ 
 852     CYSetProperty(context, typed, cyt_s, CYMakeType(context, *this), kJSPropertyAttributeDontEnum); \ 
 859 CYFromFFI_(long double) 
 861 CYFromFFI_(signed char) 
 862 CYFromFFI_(signed int) 
 863 CYFromFFI_(signed long int) 
 864 CYFromFFI_(signed long long int) 
 865 CYFromFFI_(signed short int) 
 867 CYFromFFI_(unsigned char) 
 868 CYFromFFI_(unsigned int) 
 869 CYFromFFI_(unsigned long int) 
 870 CYFromFFI_(unsigned long long int) 
 871 CYFromFFI_(unsigned short int) 
 873 #ifdef __SIZEOF_INT128__ 
 874 CYFromFFI_(signed __int128
) 
 875 CYFromFFI_(unsigned __int128
) 
 879 JSValueRef Primitive
<bool>::FromFFI(JSContextRef context
, ffi_type 
*ffi
, void *data
, bool initialize
, JSObjectRef owner
) const { 
 880     return CYCastJSValue(context
, *reinterpret_cast<bool *>(data
)); 
 884 JSValueRef Primitive
<char>::FromFFI(JSContextRef context
, ffi_type 
*ffi
, void *data
, bool initialize
, JSObjectRef owner
) const { 
 885     uint16_t string(uint8_t(*reinterpret_cast<char *>(data
))); 
 886     JSValueRef 
value(CYCastJSValue(context
, CYJSString(CYUTF16String(&string
, 1)))); 
 887     JSObjectRef 
typed(_jsccall(JSObjectCallAsConstructor
, context
, CYGetCachedObject(context
, CYJSString("String")), 1, &value
)); 
 888     CYSetProperty(context
, typed
, cyt_s
, CYMakeType(context
, sig::Primitive
<char>()), kJSPropertyAttributeDontEnum
); 
 889     CYSetPrototype(context
, typed
, CYGetCachedValue(context
, CYJSString("Character_prototype"))); 
 893 JSValueRef 
Void::FromFFI(JSContextRef context
, ffi_type 
*ffi
, void *data
, bool initialize
, JSObjectRef owner
) const { 
 894     return CYJSUndefined(context
); 
 897 JSValueRef 
Unknown::FromFFI(JSContextRef context
, ffi_type 
*ffi
, void *data
, bool initialize
, JSObjectRef owner
) const { 
 901 JSValueRef 
String::FromFFI(JSContextRef context
, ffi_type 
*ffi
, void *data
, bool initialize
, JSObjectRef owner
) const { 
 902     if (char *value 
= *reinterpret_cast<char **>(data
)) 
 903         return CYPrivate
<CString
>::Make(context
, value
, context
, owner
); 
 904     return CYJSNull(context
); 
 907 JSValueRef 
Bits::FromFFI(JSContextRef context
, ffi_type 
*ffi
, void *data
, bool initialize
, JSObjectRef owner
) const { 
 911 JSValueRef 
Pointer::FromFFI(JSContextRef context
, ffi_type 
*ffi
, void *data
, bool initialize
, JSObjectRef owner
) const { 
 912     if (void *value 
= *reinterpret_cast<void **>(data
)) 
 913         return CYMakePointer(context
, value
, type
, NULL
, owner
); 
 914     return CYJSNull(context
); 
 917 JSValueRef 
Array::FromFFI(JSContextRef context
, ffi_type 
*ffi
, void *data
, bool initialize
, JSObjectRef owner
) const { 
 918     return CYPrivate
<CArray
>::Make(context
, data
, size
, type
, ffi
->elements
[0], context
, owner
); 
 921 JSValueRef 
Enum::FromFFI(JSContextRef context
, ffi_type 
*ffi
, void *data
, bool initialize
, JSObjectRef owner
) const { 
 922     return type
.FromFFI(context
, ffi
, data
, initialize
, owner
); 
 925 JSValueRef 
Aggregate::FromFFI(JSContextRef context
, ffi_type 
*ffi
, void *data
, bool initialize
, JSObjectRef owner
) const { 
 927     _assert(signature
.count 
!= _not(size_t)); 
 928     return CYPrivate
<Struct_privateData
>::Make(context
, data
, *this, ffi
, context
, owner
); 
 931 JSValueRef 
Function::FromFFI(JSContextRef context
, ffi_type 
*ffi
, void *data
, bool initialize
, JSObjectRef owner
) const { 
 932     return CYMakeFunctor(context
, reinterpret_cast<void (*)()>(data
), variadic
, signature
); 
 937 void CYExecuteClosure(ffi_cif 
*cif
, void *result
, void **arguments
, void *arg
) { 
 938     Closure_privateData 
*internal(reinterpret_cast<Closure_privateData 
*>(arg
)); 
 940     JSContextRef 
context(internal
->function_
); 
 942     size_t count(internal
->cif_
.nargs
); 
 943     JSValueRef values
[count
]; 
 945     for (size_t index(0); index 
!= count
; ++index
) 
 946         values
[index
] = internal
->signature_
.elements
[1 + index
].type
->FromFFI(context
, internal
->cif_
.arg_types
[index
], arguments
[index
]); 
 948     JSValueRef 
value(internal
->adapter_(context
, count
, values
, internal
->function_
)); 
 949     if (internal
->cif_
.rtype 
!= &ffi_type_void
) 
 950         internal
->signature_
.elements
[0].type
->PoolFFI(NULL
, context
, internal
->cif_
.rtype
, result
, value
); 
 953 static JSValueRef 
FunctionAdapter_(JSContextRef context
, size_t count
, JSValueRef values
[], JSObjectRef function
) { 
 954     return CYCallAsFunction(context
, function
, NULL
, count
, values
); 
 957 #if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) 
 958 static void CYFreeFunctor(void *data
) { 
 959     ffi_closure_free(data
); 
 962 static void CYFreeFunctor(void *data
) { 
 963     _syscall(munmap(data
, sizeof(ffi_closure
))); 
 967 Closure_privateData 
*CYMakeFunctor_(JSContextRef context
, JSObjectRef function
, const sig::Signature 
&signature
, JSValueRef (*adapter
)(JSContextRef
, size_t, JSValueRef
[], JSObjectRef
)) { 
 968     // XXX: in case of exceptions this will leak 
 969     Closure_privateData 
*internal(new Closure_privateData(context
, function
, adapter
, signature
)); 
 971 #if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) 
 973     ffi_closure 
*writable(reinterpret_cast<ffi_closure 
*>(ffi_closure_alloc(sizeof(ffi_closure
), &executable
))); 
 975     ffi_status 
status(ffi_prep_closure_loc(writable
, &internal
->cif_
, &CYExecuteClosure
, internal
, executable
)); 
 976     _assert(status 
== FFI_OK
); 
 978     internal
->pool_
->atexit(&CYFreeFunctor
, writable
); 
 979     internal
->value_ 
= reinterpret_cast<void (*)()>(executable
); 
 981     ffi_closure 
*closure((ffi_closure 
*) _syscall(mmap( 
 982         NULL
, sizeof(ffi_closure
), 
 983         PROT_READ 
| PROT_WRITE
, MAP_ANON 
| MAP_PRIVATE
, 
 987     ffi_status 
status(ffi_prep_closure(closure
, &internal
->cif_
, &CYExecuteClosure
, internal
)); 
 988     _assert(status 
== FFI_OK
); 
 990     _syscall(mprotect(closure
, sizeof(*closure
), PROT_READ 
| PROT_EXEC
)); 
 992     internal
->pool_
->atexit(&CYFreeFunctor
, closure
); 
 993     internal
->value_ 
= reinterpret_cast<void (*)()>(closure
); 
 999 static JSObjectRef 
CYMakeFunctor(JSContextRef context
, JSObjectRef function
, const sig::Signature 
&signature
) { 
1000     Closure_privateData 
*internal(CYMakeFunctor_(context
, function
, signature
, &FunctionAdapter_
)); 
1001     JSObjectRef 
object(JSObjectMake(context
, cy::Functor::Class_
, internal
)); 
1002     // XXX: see above notes about needing to leak 
1003     JSValueProtect(CYGetJSContext(context
), object
); 
1007 JSValueRef 
CYGetCachedValue(JSContextRef context
, JSStringRef name
) { 
1008     return CYGetProperty(context
, CYCastJSObject(context
, CYGetProperty(context
, CYGetGlobalObject(context
), cy_s
)), name
); 
1011 JSObjectRef 
CYGetCachedObject(JSContextRef context
, JSStringRef name
) { 
1012     return CYCastJSObject(context
, CYGetCachedValue(context
, name
)); 
1015 static JSValueRef 
CYMakeFunctor(JSContextRef context
, JSValueRef value
, bool variadic
, const sig::Signature 
&signature
) { 
1016     JSObjectRef 
Function(CYGetCachedObject(context
, CYJSString("Function"))); 
1018     bool function(_jsccall(JSValueIsInstanceOfConstructor
, context
, value
, Function
)); 
1020         JSObjectRef 
function(CYCastJSObject(context
, value
)); 
1021         return CYMakeFunctor(context
, function
, signature
); 
1023         void (*function
)()(CYCastPointer
<void (*)()>(context
, value
)); 
1024         return CYMakeFunctor(context
, function
, variadic
, signature
); 
1028 static JSValueRef 
CString_getProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1030     CString 
*internal(reinterpret_cast<CString 
*>(JSObjectGetPrivate(object
))); 
1033     if (JSStringIsEqualToUTF8CString(property
, "$cyi")) 
1035     else if (!CYGetOffset(pool
, context
, property
, offset
)) 
1038     sig::Primitive
<char> type
; 
1039     return type
.FromFFI(context
, type
.GetFFI(pool
), internal
->value_ 
+ offset
, false, NULL
); 
1042 static bool CString_setProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef value
, JSValueRef 
*exception
) { CYTry 
{ 
1044     CString 
*internal(reinterpret_cast<CString 
*>(JSObjectGetPrivate(object
))); 
1047     if (JSStringIsEqualToUTF8CString(property
, "$cyi")) 
1049     else if (!CYGetOffset(pool
, context
, property
, offset
)) 
1052     sig::Primitive
<char> type
; 
1053     type
.PoolFFI(NULL
, context
, type
.GetFFI(pool
), internal
->value_ 
+ offset
, value
); 
1057 static bool Index_(CYPool 
&pool
, JSContextRef context
, Struct_privateData 
*internal
, JSStringRef property
, ssize_t 
&index
, uint8_t *&base
) { 
1058     Type_privateData 
*typical(internal
->type_
); 
1059     sig::Aggregate 
*type(static_cast<sig::Aggregate 
*>(typical
->type_
)); 
1063     const char *name(CYPoolCString(pool
, context
, property
)); 
1064     size_t length(strlen(name
)); 
1065     double number(CYCastDouble(name
, length
)); 
1067     size_t count(type
->signature
.count
); 
1069     if (std::isnan(number
)) { 
1070         if (property 
== NULL
) 
1073         sig::Element 
*elements(type
->signature
.elements
); 
1075         for (size_t local(0); local 
!= count
; ++local
) { 
1076             sig::Element 
*element(&elements
[local
]); 
1077             if (element
->name 
!= NULL 
&& strcmp(name
, element
->name
) == 0) { 
1085         index 
= static_cast<ssize_t
>(number
); 
1086         if (index 
!= number 
|| index 
< 0 || static_cast<size_t>(index
) >= count
) 
1091     ffi_type 
**elements(typical
->GetFFI()->elements
); 
1094     for (ssize_t 
local(0); local 
!= index
; ++local
) { 
1095         offset 
+= elements
[local
]->size
; 
1096         CYAlign(offset
, elements
[local 
+ 1]->alignment
); 
1099     base 
= reinterpret_cast<uint8_t *>(internal
->value_
) + offset
; 
1103 static void *Offset_(CYPool 
&pool
, JSContextRef context
, JSStringRef property
, void *data
, ffi_type 
*ffi
) { 
1105     if (JSStringIsEqualToUTF8CString(property
, "$cyi")) 
1107     else if (!CYGetOffset(pool
, context
, property
, offset
)) 
1109     return reinterpret_cast<uint8_t *>(data
) + ffi
->size 
* offset
; 
1112 static JSValueRef 
Offset_getProperty(CYPool 
&pool
, JSContextRef context
, JSStringRef property
, void *data
, Type_privateData 
*typical
, JSObjectRef owner
) { 
1113     ffi_type 
*ffi(typical
->GetFFI()); 
1114     void *base(Offset_(pool
, context
, property
, data
, ffi
)); 
1117     return typical
->type_
->FromFFI(context
, ffi
, base
, false, owner
); 
1120 static bool Offset_setProperty(CYPool 
&pool
, JSContextRef context
, JSStringRef property
, void *data
, Type_privateData 
*typical
, JSValueRef value
) { 
1121     ffi_type 
*ffi(typical
->GetFFI()); 
1122     void *base(Offset_(pool
, context
, property
, data
, ffi
)); 
1126     typical
->type_
->PoolFFI(NULL
, context
, ffi
, base
, value
); 
1130 static JSValueRef 
CArray_getProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1132     CArray 
*internal(reinterpret_cast<CArray 
*>(JSObjectGetPrivate(object
))); 
1133     if (JSStringIsEqual(property
, length_s
)) 
1134         return CYCastJSValue(context
, internal
->length_
); 
1135     Type_privateData 
*typical(internal
->type_
); 
1136     JSObjectRef 
owner(internal
->owner_ 
?: object
); 
1137     return Offset_getProperty(pool
, context
, property
, internal
->value_
, typical
, owner
); 
1140 static bool CArray_setProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef value
, JSValueRef 
*exception
) { CYTry 
{ 
1142     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(object
))); 
1143     Type_privateData 
*typical(internal
->type_
); 
1144     return Offset_setProperty(pool
, context
, property
, internal
->value_
, typical
, value
); 
1147 static JSValueRef 
Pointer_getProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1149     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(object
))); 
1151     Type_privateData 
*typical(internal
->type_
); 
1153     if (sig::Function 
*function 
= dynamic_cast<sig::Function 
*>(typical
->type_
)) { 
1154         if (!JSStringIsEqualToUTF8CString(property
, "$cyi")) 
1156         return CYMakeFunctor(context
, reinterpret_cast<void (*)()>(internal
->value_
), function
->variadic
, function
->signature
); 
1159     JSObjectRef 
owner(internal
->owner_ 
?: object
); 
1160     return Offset_getProperty(pool
, context
, property
, internal
->value_
, typical
, owner
); 
1163 static bool Pointer_setProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef value
, JSValueRef 
*exception
) { CYTry 
{ 
1165     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(object
))); 
1166     Type_privateData 
*typical(internal
->type_
); 
1167     return Offset_setProperty(pool
, context
, property
, internal
->value_
, typical
, value
); 
1170 static JSValueRef Struct_callAsFunction_$
cya(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1171     Struct_privateData 
*internal(reinterpret_cast<Struct_privateData 
*>(JSObjectGetPrivate(_this
))); 
1172     Type_privateData 
*typical(internal
->type_
); 
1173     return CYMakePointer(context
, internal
->value_
, *typical
->type_
, typical
->ffi_
, _this
); 
1176 static JSValueRef Struct_getProperty_$
cyt(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1177     Struct_privateData 
*internal(reinterpret_cast<Struct_privateData 
*>(JSObjectGetPrivate(object
))); 
1178     return CYMakeType(context
, *internal
->type_
->type_
); 
1181 static JSValueRef 
Struct_getProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1183     Struct_privateData 
*internal(reinterpret_cast<Struct_privateData 
*>(JSObjectGetPrivate(object
))); 
1184     Type_privateData 
*typical(internal
->type_
); 
1185     sig::Aggregate 
*type(static_cast<sig::Aggregate 
*>(typical
->type_
)); 
1190     if (!Index_(pool
, context
, internal
, property
, index
, base
)) 
1193     JSObjectRef 
owner(internal
->owner_ 
?: object
); 
1195     return type
->signature
.elements
[index
].type
->FromFFI(context
, typical
->GetFFI()->elements
[index
], base
, false, owner
); 
1198 static bool Struct_setProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef value
, JSValueRef 
*exception
) { CYTry 
{ 
1200     Struct_privateData 
*internal(reinterpret_cast<Struct_privateData 
*>(JSObjectGetPrivate(object
))); 
1201     Type_privateData 
*typical(internal
->type_
); 
1202     sig::Aggregate 
*type(static_cast<sig::Aggregate 
*>(typical
->type_
)); 
1207     if (!Index_(pool
, context
, internal
, property
, index
, base
)) 
1210     type
->signature
.elements
[index
].type
->PoolFFI(NULL
, context
, typical
->GetFFI()->elements
[index
], base
, value
); 
1214 static void Struct_getPropertyNames(JSContextRef context
, JSObjectRef object
, JSPropertyNameAccumulatorRef names
) { 
1215     Struct_privateData 
*internal(reinterpret_cast<Struct_privateData 
*>(JSObjectGetPrivate(object
))); 
1216     Type_privateData 
*typical(internal
->type_
); 
1217     sig::Aggregate 
*type(static_cast<sig::Aggregate 
*>(typical
->type_
)); 
1222     size_t count(type
->signature
.count
); 
1223     sig::Element 
*elements(type
->signature
.elements
); 
1227     for (size_t index(0); index 
!= count
; ++index
) { 
1229         name 
= elements
[index
].name
; 
1232             sprintf(number
, "%zu", index
); 
1236         JSPropertyNameAccumulatorAddName(names
, CYJSString(name
)); 
1240 static sig::Void Void_
; 
1241 static sig::Pointer 
PointerToVoid_(Void_
); 
1243 static sig::Type 
*CYGetType(CYPool 
&pool
, JSContextRef context
, JSValueRef value
) { 
1244     if (JSValueIsNull(context
, value
)) 
1245         return &PointerToVoid_
; 
1246     JSObjectRef 
object(CYCastJSObject(context
, value
)); 
1247     JSObjectRef 
type(CYCastJSObject(context
, CYGetProperty(context
, object
, cyt_s
))); 
1248     _assert(JSValueIsObjectOfClass(context
, type
, CYPrivate
<Type_privateData
>::Class_
)); 
1249     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(type
))); 
1250     return internal
->type_
; 
1253 void CYCallFunction(CYPool 
&pool
, JSContextRef context
, ffi_cif 
*cif
, void (*function
)(), void *value
, void **values
) { 
1254     ffi_call(cif
, function
, value
, values
); 
1257 JSValueRef 
CYCallFunction(CYPool 
&pool
, JSContextRef context
, size_t setups
, void *setup
[], size_t count
, const JSValueRef arguments
[], bool initialize
, bool variadic
, const sig::Signature 
&signature
, ffi_cif 
*cif
, void (*function
)()) { 
1258     size_t have(setups 
+ count
); 
1259     size_t need(signature
.count 
- 1); 
1262         throw CYJSError(context
, "insufficient number of arguments to ffi function"); 
1265     sig::Element 
*elements(signature
.elements
); 
1269             throw CYJSError(context
, "exorbitant number of arguments to ffi function"); 
1271         elements 
= new (pool
) sig::Element
[have 
+ 1]; 
1272         memcpy(elements
, signature
.elements
, sizeof(sig::Element
) * (need 
+ 1)); 
1274         for (size_t index(need
); index 
!= have
; ++index
) { 
1275             sig::Element 
&element(elements
[index 
+ 1]); 
1276             element
.name 
= NULL
; 
1277             element
.offset 
= _not(size_t); 
1278             element
.type 
= CYGetType(pool
, context
, arguments
[index 
- setups
]); 
1281         sig::Signature extended
; 
1282         extended
.elements 
= elements
; 
1283         extended
.count 
= have 
+ 1; 
1284         sig::sig_ffi_cif(pool
, signature
.count
, extended
, &corrected
); 
1289     memcpy(values
, setup
, sizeof(void *) * setups
); 
1291     for (size_t index(setups
); index 
!= have
; ++index
) { 
1292         sig::Element 
&element(elements
[index 
+ 1]); 
1293         ffi_type 
*ffi(cif
->arg_types
[index
]); 
1294         values
[index
] = pool
.malloc
<uint8_t>(ffi
->size
, ffi
->alignment
); 
1295         element
.type
->PoolFFI(&pool
, context
, ffi
, values
[index
], arguments
[index 
- setups
]); 
1298     CYBuffer 
buffer(context
); 
1299     uint8_t *value(buffer
->malloc
<uint8_t>(std::max
<size_t>(cif
->rtype
->size
, sizeof(ffi_arg
)), std::max
<size_t>(cif
->rtype
->alignment
, alignof(ffi_arg
)))); 
1301     void (*call
)(CYPool 
&, JSContextRef
, ffi_cif 
*, void (*)(), void *, void **) = &CYCallFunction
; 
1302     // XXX: this only supports one hook, but it is a bad idea anyway 
1303     for (CYHook 
*hook 
: GetHooks()) 
1304         if (hook
->CallFunction 
!= NULL
) 
1305             call 
= hook
->CallFunction
; 
1307     call(pool
, context
, cif
, function
, value
, values
); 
1308     return signature
.elements
[0].type
->FromFFI(context
, cif
->rtype
, value
, initialize
, buffer
); 
1311 static JSValueRef 
Functor_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1313     cy::Functor 
*internal(reinterpret_cast<cy::Functor 
*>(JSObjectGetPrivate(object
))); 
1314     return CYCallFunction(pool
, context
, 0, NULL
, count
, arguments
, false, internal
->variadic_
, internal
->signature_
, &internal
->cif_
, internal
->value_
); 
1317 static JSValueRef 
Pointer_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1318     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(object
))); 
1319     if (dynamic_cast<sig::Function 
*>(internal
->type_
->type_
) == NULL
) 
1320         throw CYJSError(context
, "cannot call a pointer to non-function"); 
1321     JSObjectRef 
functor(CYCastJSObject(context
, CYGetProperty(context
, object
, cyi_s
))); 
1322     return CYCallAsFunction(context
, functor
, _this
, count
, arguments
); 
1325 JSObjectRef 
CYMakeType(JSContextRef context
, const sig::Type 
&type
) { 
1326     return CYPrivate
<Type_privateData
>::Make(context
, type
); 
1329 extern "C" bool CYBridgeHash(CYPool 
&pool
, CYUTF8String name
, const char *&code
, unsigned &flags
) { 
1330     sqlite3_stmt 
*statement
; 
1332     _sqlcall(sqlite3_prepare(database_
, 
1334             "\"cache\".\"code\", " 
1335             "\"cache\".\"flags\" " 
1338             " \"cache\".\"system\" & " CY_SYSTEM 
" == " CY_SYSTEM 
" and" 
1339             " \"cache\".\"name\" = ?" 
1341     , -1, &statement
, NULL
)); 
1343     _sqlcall(sqlite3_bind_text(statement
, 1, name
.data
, name
.size
, SQLITE_STATIC
)); 
1346     if (_sqlcall(sqlite3_step(statement
)) == SQLITE_DONE
) 
1350         code 
= sqlite3_column_pooled(pool
, statement
, 0); 
1351         flags 
= sqlite3_column_int(statement
, 1); 
1354     _sqlcall(sqlite3_finalize(statement
)); 
1358 static bool All_hasProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
) { 
1359     if (JSStringIsEqualToUTF8CString(property
, "errno")) 
1362     JSObjectRef 
global(CYGetGlobalObject(context
)); 
1363     JSObjectRef 
cycript(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Cycript")))); 
1364     JSObjectRef 
alls(CYCastJSObject(context
, CYGetProperty(context
, cycript
, CYJSString("alls")))); 
1366     for (size_t i(0), count(CYArrayLength(context
, alls
)); i 
!= count
; ++i
) 
1367         if (JSObjectRef space 
= CYCastJSObject(context
, CYArrayGet(context
, alls
, count 
- i 
- 1))) 
1368             if (CYHasProperty(context
, space
, property
)) 
1374     if (CYBridgeHash(pool
, CYPoolUTF8String(pool
, context
, property
), code
, flags
)) 
1380 static JSValueRef 
All_getProperty(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1381     if (JSStringIsEqualToUTF8CString(property
, "errno")) 
1382         return CYCastJSValue(context
, errno
); 
1384     JSObjectRef 
global(CYGetGlobalObject(context
)); 
1385     JSObjectRef 
cycript(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Cycript")))); 
1386     JSObjectRef 
alls(CYCastJSObject(context
, CYGetProperty(context
, cycript
, CYJSString("alls")))); 
1388     for (size_t i(0), count(CYArrayLength(context
, alls
)); i 
!= count
; ++i
) 
1389         if (JSObjectRef space 
= CYCastJSObject(context
, CYArrayGet(context
, alls
, count 
- i 
- 1))) 
1390             if (JSValueRef value 
= CYGetProperty(context
, space
, property
)) 
1391                 if (!JSValueIsUndefined(context
, value
)) 
1397     if (CYBridgeHash(pool
, CYPoolUTF8String(pool
, context
, property
), code
, flags
)) { 
1398         CYUTF8String parsed
; 
1401             parsed 
= CYPoolCode(pool
, code
); 
1402         } catch (const CYException 
&error
) { 
1403             CYThrow("%s", pool
.strcat("error caching ", CYPoolCString(pool
, context
, property
), ": ", error
.PoolCString(pool
), NULL
)); 
1406         JSObjectRef 
cache(CYGetCachedObject(context
, CYJSString("cache"))); 
1409         if (flags 
== CYBridgeType
) { 
1410             stub 
= CYMakeType(context
, sig::Void()); 
1411             CYSetProperty(context
, cache
, property
, stub
); 
1415         JSValueRef 
value(_jsccall(JSEvaluateScript
, context
, CYJSString(parsed
), NULL
, NULL
, 0)); 
1418             case CYBridgeVoid
: { 
1421             case CYBridgeHold
: { 
1422                 CYSetProperty(context
, cache
, property
, value
); 
1425             case CYBridgeType
: { 
1426                 JSObjectRef 
swap(CYCastJSObject(context
, value
)); 
1427                 void *source(JSObjectGetPrivate(swap
)); 
1428                 _assert(source 
!= NULL
); 
1429                 void *target(JSObjectGetPrivate(stub
)); 
1430                 _assert(JSObjectSetPrivate(swap
, target
)); 
1431                 _assert(JSObjectSetPrivate(stub
, source
)); 
1442 static JSValueRef 
All_complete_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1443     _assert(count 
== 1 || count 
== 2); 
1445     CYUTF8String 
prefix(CYPoolUTF8String(pool
, context
, CYJSString(context
, arguments
[0]))); 
1447     JSObjectRef 
array(NULL
); 
1450     CYArrayBuilder
<1024> values(context
, array
); 
1452     sqlite3_stmt 
*statement
; 
1454     if (prefix
.size 
== 0) 
1455         _sqlcall(sqlite3_prepare(database_
, 
1457                 "\"cache\".\"name\" " 
1460                 " \"cache\".\"system\" & " CY_SYSTEM 
" == " CY_SYSTEM
 
1461         , -1, &statement
, NULL
)); 
1463         _sqlcall(sqlite3_prepare(database_
, 
1465                 "\"cache\".\"name\" " 
1468                 " \"cache\".\"name\" >= ? and \"cache\".\"name\" < ? and " 
1469                 " \"cache\".\"system\" & " CY_SYSTEM 
" == " CY_SYSTEM
 
1470         , -1, &statement
, NULL
)); 
1472         _sqlcall(sqlite3_bind_text(statement
, 1, prefix
.data
, prefix
.size
, SQLITE_STATIC
)); 
1474         char *after(pool
.strndup(prefix
.data
, prefix
.size
)); 
1475         ++after
[prefix
.size 
- 1]; 
1476         _sqlcall(sqlite3_bind_text(statement
, 2, after
, prefix
.size
, SQLITE_STATIC
)); 
1479     while (_sqlcall(sqlite3_step(statement
)) != SQLITE_DONE
) 
1480         values(CYCastJSValue(context
, CYJSString(sqlite3_column_string(statement
, 0)))); 
1482     _sqlcall(sqlite3_finalize(statement
)); 
1488 static void All_getPropertyNames(JSContextRef context
, JSObjectRef object
, JSPropertyNameAccumulatorRef names
) { 
1489     JSObjectRef 
global(CYGetGlobalObject(context
)); 
1490     JSObjectRef 
cycript(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Cycript")))); 
1491     JSObjectRef 
alls(CYCastJSObject(context
, CYGetProperty(context
, cycript
, CYJSString("alls")))); 
1493     for (size_t i(0), count(CYArrayLength(context
, alls
)); i 
!= count
; ++i
) 
1494         if (JSObjectRef space 
= CYCastJSObject(context
, CYArrayGet(context
, alls
, count 
- i 
- 1))) { 
1495             JSPropertyNameArrayRef 
subset(JSObjectCopyPropertyNames(context
, space
)); 
1496             for (size_t index(0), count(JSPropertyNameArrayGetCount(subset
)); index 
!= count
; ++index
) 
1497                 JSPropertyNameAccumulatorAddName(names
, JSPropertyNameArrayGetNameAtIndex(subset
, index
)); 
1498             JSPropertyNameArrayRelease(subset
); 
1502 static JSObjectRef 
CArray_new(JSContextRef context
, JSObjectRef object
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1506 static JSObjectRef 
CString_new(JSContextRef context
, JSObjectRef object
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1510 static JSObjectRef 
Pointer_new(JSContextRef context
, JSObjectRef object
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1514 static JSObjectRef 
Type_new(JSContextRef context
, JSObjectRef object
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1518     } else if (count 
== 1) { 
1519         switch (JSValueGetType(context
, arguments
[0])) { 
1520             case kJSTypeString
: { 
1521                 const char *encoding(CYPoolCString(pool
, context
, arguments
[0])); 
1522                 sig::Signature signature
; 
1523                 sig::Parse(pool
, &signature
, encoding
, &Structor_
); 
1524                 return CYMakeType(context
, *signature
.elements
[0].type
); 
1527             case kJSTypeObject
: { 
1528                 // XXX: accept a set of enum constants and /guess/ at their size 
1533                 throw CYJSError(context
, "incorrect kind of argument to new Type"); 
1535     } else if (count 
== 2) { 
1536         JSObjectRef 
types(CYCastJSObject(context
, arguments
[0])); 
1537         size_t count(CYArrayLength(context
, types
)); 
1539         JSObjectRef 
names(CYCastJSObject(context
, arguments
[1])); 
1541         sig::Aggregate 
type(false); 
1542         type
.signature
.elements 
= new(pool
) sig::Element
[count
]; 
1543         type
.signature
.count 
= count
; 
1545         for (size_t i(0); i 
!= count
; ++i
) { 
1546             sig::Element 
&element(type
.signature
.elements
[i
]); 
1547             element
.offset 
= _not(size_t); 
1549             JSValueRef 
name(CYArrayGet(context
, names
, i
)); 
1550             if (JSValueIsUndefined(context
, name
)) 
1551                 element
.name 
= NULL
; 
1553                 element
.name 
= CYPoolCString(pool
, context
, name
); 
1555             JSObjectRef 
object(CYCastJSObject(context
, CYArrayGet(context
, types
, i
))); 
1556             _assert(JSValueIsObjectOfClass(context
, object
, CYPrivate
<Type_privateData
>::Class_
)); 
1557             Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1558             element
.type 
= internal
->type_
; 
1559             _assert(element
.type 
!= NULL
); 
1562         return CYMakeType(context
, type
); 
1564         throw CYJSError(context
, "incorrect number of arguments to Type constructor"); 
1568 static JSValueRef Type_callAsFunction_$
With(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], sig::Callable 
&type
, JSValueRef 
*exception
) { CYTry 
{ 
1569     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1573     type
.signature
.elements 
= new(pool
) sig::Element
[1 + count
]; 
1574     type
.signature
.count 
= 1 + count
; 
1576     type
.signature
.elements
[0].name 
= NULL
; 
1577     type
.signature
.elements
[0].type 
= internal
->type_
; 
1578     type
.signature
.elements
[0].offset 
= _not(size_t); 
1580     for (size_t i(0); i 
!= count
; ++i
) { 
1581         sig::Element 
&element(type
.signature
.elements
[i 
+ 1]); 
1582         element
.name 
= NULL
; 
1583         element
.offset 
= _not(size_t); 
1585         JSObjectRef 
object(CYCastJSObject(context
, arguments
[i
])); 
1586         _assert(JSValueIsObjectOfClass(context
, object
, CYPrivate
<Type_privateData
>::Class_
)); 
1587         Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1589         element
.type 
= internal
->type_
; 
1592     return CYMakeType(context
, type
); 
1595 static JSValueRef 
Type_callAsFunction_arrayOf(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1597         throw CYJSError(context
, "incorrect number of arguments to Type.arrayOf"); 
1598     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1601     size_t index(CYGetIndex(pool
, context
, CYJSString(context
, arguments
[0]))); 
1602     if (index 
== _not(size_t)) 
1603         throw CYJSError(context
, "invalid array size used with Type.arrayOf"); 
1605     sig::Array 
type(*internal
->type_
, index
); 
1606     return CYMakeType(context
, type
); 
1609 static JSValueRef 
Type_callAsFunction_blockWith(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { 
1610 #ifdef CY_OBJECTIVEC 
1612     return Type_callAsFunction_$
With(context
, object
, _this
, count
, arguments
, type
, exception
); 
1618 static JSValueRef 
Type_callAsFunction_constant(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1620         throw CYJSError(context
, "incorrect number of arguments to Type.constant"); 
1621     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1624     sig::Type 
*type(internal
->type_
->Copy(pool
)); 
1625     type
->flags 
|= JOC_TYPE_CONST
; 
1626     return CYMakeType(context
, *type
); 
1629 static JSValueRef 
Type_callAsFunction_enumFor(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1631         throw CYJSError(context
, "incorrect number of arguments to Type.enumFor"); 
1632     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1636     JSObjectRef 
constants(CYCastJSObject(context
, arguments
[0])); 
1638     // XXX: this is, sadly, going to leak 
1639     JSPropertyNameArrayRef 
names(JSObjectCopyPropertyNames(context
, constants
)); 
1641     size_t count(JSPropertyNameArrayGetCount(names
)); 
1643     sig::Enum 
type(*internal
->type_
, count
); 
1644     type
.constants 
= new(pool
) sig::Constant
[count
]; 
1646     for (size_t index(0); index 
!= count
; ++index
) { 
1647         JSStringRef 
name(JSPropertyNameArrayGetNameAtIndex(names
, index
)); 
1648         JSValueRef 
value(CYGetProperty(context
, constants
, name
)); 
1649         _assert(JSValueGetType(context
, value
) == kJSTypeNumber
); 
1650         CYUTF8String 
string(CYPoolUTF8String(pool
, context
, name
)); 
1651         type
.constants
[index
].name 
= string
.data
; 
1652         type
.constants
[index
].value 
= CYCastDouble(context
, value
); 
1655     JSPropertyNameArrayRelease(names
); 
1657     return CYMakeType(context
, type
); 
1660 static JSValueRef 
Type_callAsFunction_functionWith(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { 
1661     bool variadic(count 
!= 0 && JSValueIsNull(context
, arguments
[count 
- 1])); 
1662     sig::Function 
type(variadic
); 
1663     return Type_callAsFunction_$
With(context
, object
, _this
, variadic 
? count 
- 1 : count
, arguments
, type
, exception
); 
1666 static JSValueRef 
Type_callAsFunction_pointerTo(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1668         throw CYJSError(context
, "incorrect number of arguments to Type.pointerTo"); 
1669     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1671     if (dynamic_cast<sig::Primitive
<char> *>(internal
->type_
) != NULL
) 
1672         return CYMakeType(context
, sig::String()); 
1674         return CYMakeType(context
, sig::Pointer(*internal
->type_
)); 
1677 static JSValueRef 
Type_callAsFunction_withName(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1679         throw CYJSError(context
, "incorrect number of arguments to Type.withName"); 
1680     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1683     return CYMakeType(context
, *internal
->type_
->Copy(pool
, CYPoolCString(pool
, context
, arguments
[0]))); 
1686 static JSValueRef 
Type_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1688         throw CYJSError(context
, "incorrect number of arguments to type cast function"); 
1689     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1691     if (sig::Function 
*function 
= dynamic_cast<sig::Function 
*>(internal
->type_
)) 
1692         return CYMakeFunctor(context
, arguments
[0], function
->variadic
, function
->signature
); 
1694     CYBuffer 
buffer(context
); 
1696     sig::Type 
*type(internal
->type_
); 
1697     ffi_type 
*ffi(internal
->GetFFI()); 
1700     if (_this 
== NULL 
|| CYIsStrictEqual(context
, _this
, CYGetGlobalObject(context
))) 
1701         data 
= buffer
->malloc
<void>(ffi
->size
, ffi
->alignment
); 
1703         CYSetProperty(context
, buffer
, CYJSString("$cyo"), _this
, kJSPropertyAttributeDontEnum
); 
1704         data 
= CYCastPointer
<void *>(context
, _this
); 
1707     type
->PoolFFI(buffer
, context
, ffi
, data
, arguments
[0]); 
1708     JSValueRef 
value(type
->FromFFI(context
, ffi
, data
, false, buffer
)); 
1712 static JSObjectRef 
Type_callAsConstructor(JSContextRef context
, JSObjectRef object
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1714         throw CYJSError(context
, "incorrect number of arguments to Type allocator"); 
1715     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1717     JSObjectRef 
pointer(CYMakePointer(context
, NULL
, *internal
->type_
, NULL
, NULL
)); 
1718     Pointer 
*value(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(pointer
))); 
1720     sig::Type 
*type(internal
->type_
); 
1721     ffi_type 
*ffi(internal
->GetFFI()); 
1722     value
->value_ 
= value
->pool_
->malloc
<void>(ffi
->size
, ffi
->alignment
); 
1725         memset(value
->value_
, 0, ffi
->size
); 
1727         type
->PoolFFI(value
->pool_
, context
, ffi
, value
->value_
, arguments
[0]); 
1732 // XXX: I don't even think the user should be allowed to do this 
1733 static JSObjectRef 
Functor_new(JSContextRef context
, JSObjectRef object
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1735         throw CYJSError(context
, "incorrect number of arguments to Functor constructor"); 
1737     const char *encoding(CYPoolCString(pool
, context
, arguments
[1])); 
1738     sig::Signature signature
; 
1739     sig::Parse(pool
, &signature
, encoding
, &Structor_
); 
1740     // XXX: this can try to return null, and I guess then it just fails 
1741     return CYCastJSObject(context
, CYMakeFunctor(context
, arguments
[0], false, signature
)); 
1744 static JSValueRef 
CArray_callAsFunction_toPointer(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1745     CArray 
*internal(reinterpret_cast<CArray 
*>(JSObjectGetPrivate(_this
))); 
1746     JSObjectRef 
owner(internal
->owner_ 
?: object
); 
1747     return CYMakePointer(context
, internal
->value_
, *internal
->type_
->type_
, NULL
, owner
); 
1750 static JSValueRef 
CString_callAsFunction_toPointer(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1751     CString 
*internal(reinterpret_cast<CString 
*>(JSObjectGetPrivate(_this
))); 
1752     JSObjectRef 
owner(internal
->owner_ 
?: object
); 
1753     return CYMakePointer(context
, internal
->value_
, sig::Primitive
<char>(), NULL
, owner
); 
1756 static JSValueRef Functor_callAsFunction_$
cya(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1758     cy::Functor 
*internal(reinterpret_cast<cy::Functor 
*>(JSObjectGetPrivate(_this
))); 
1760     sig::Function 
type(internal
->variadic_
); 
1761     sig::Copy(pool
, type
.signature
, internal
->signature_
); 
1763     return CYMakePointer(context
, reinterpret_cast<void *>(internal
->value_
), type
, NULL
, NULL
); 
1766 static JSValueRef 
Pointer_callAsFunction_toPointer(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1770 static JSValueRef 
CArray_callAsFunction_valueOf(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1771     CArray 
*internal(reinterpret_cast<CArray 
*>(JSObjectGetPrivate(_this
))); 
1772     return CYCastJSValue(context
, reinterpret_cast<uintptr_t>(internal
->value_
)); 
1775 static JSValueRef 
Pointer_callAsFunction_valueOf(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1776     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(_this
))); 
1777     return CYCastJSValue(context
, reinterpret_cast<uintptr_t>(internal
->value_
)); 
1780 static JSValueRef 
Functor_callAsFunction_valueOf(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1781     cy::Functor 
*internal(reinterpret_cast<cy::Functor 
*>(JSObjectGetPrivate(_this
))); 
1782     return CYCastJSValue(context
, reinterpret_cast<uintptr_t>(internal
->value_
)); 
1785 static JSValueRef 
Functor_callAsFunction_toCYON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1786     cy::Functor 
*internal(reinterpret_cast<cy::Functor 
*>(JSObjectGetPrivate(_this
))); 
1787     uint8_t *value(reinterpret_cast<uint8_t *>(internal
->value_
)); 
1788     _assert(value 
!= NULL
); 
1792     sig::Function 
function(internal
->variadic_
); 
1793     sig::Copy(pool
, function
.signature
, internal
->signature_
); 
1795     CYPropertyName 
*name(internal
->GetName(pool
)); 
1796     auto typed(CYDecodeType(pool
, &function
)); 
1798     std::ostringstream str
; 
1800     CYOutput 
output(*str
.rdbuf(), options
); 
1801     output
.pretty_ 
= true; 
1802     (new(pool
) CYExternalExpression(new(pool
) CYString("C"), typed
, name
))->Output(output
, CYNoFlags
); 
1803     return CYCastJSValue(context
, CYJSString(str
.str())); 
1806 CYPropertyName 
*cy::Functor::GetName(CYPool 
&pool
) const { 
1808     if (dladdr(reinterpret_cast<void *>(value_
), &info
) == 0 || strcmp(info
.dli_sname
, "<redacted>") == 0) 
1809         return new(pool
) CYNumber(reinterpret_cast<uintptr_t>(value_
)); 
1811     std::ostringstream str
; 
1812     str 
<< info
.dli_sname
; 
1813     off_t 
offset(reinterpret_cast<uint8_t *>(value_
) - reinterpret_cast<uint8_t *>(info
.dli_saddr
)); 
1815         str 
<< "+0x" << std::hex 
<< offset
; 
1816     return new(pool
) CYString(pool
.strdup(str
.str().c_str())); 
1819 static JSValueRef 
Pointer_callAsFunction_toCYON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1820     std::set
<void *> *objects(CYCastObjects(context
, _this
, count
, arguments
)); 
1822     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(_this
))); 
1825         JSValueRef 
value(CYGetProperty(context
, _this
, cyi_s
)); 
1826         if (!JSValueIsUndefined(context
, value
)) { 
1828             return CYCastJSValue(context
, pool
.strcat("&", CYPoolCCYON(pool
, context
, value
, objects
), NULL
)); 
1830     } catch (const CYException 
&e
) { 
1831         // XXX: it might be interesting to include this error 
1835     std::ostringstream str
; 
1837     sig::Pointer 
type(*internal
->type_
->type_
); 
1840     CYOutput 
output(*str
.rdbuf(), options
); 
1841     (new(pool
) CYTypeExpression(CYDecodeType(pool
, &type
)))->Output(output
, CYNoFlags
); 
1843     str 
<< "(" << internal
->value_ 
<< ")"; 
1844     std::string 
value(str
.str()); 
1845     return CYCastJSValue(context
, CYJSString(CYUTF8String(value
.c_str(), value
.size()))); 
1848 static JSValueRef 
CString_getProperty_length(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1849     CString 
*internal(reinterpret_cast<CString 
*>(JSObjectGetPrivate(object
))); 
1850     return CYCastJSValue(context
, strlen(internal
->value_
)); 
1853 static JSValueRef CString_getProperty_$
cyt(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1854     return CYMakeType(context
, sig::String()); 
1857 static JSValueRef CArray_getProperty_$
cyt(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1858     CArray 
*internal(reinterpret_cast<CArray 
*>(JSObjectGetPrivate(object
))); 
1859     sig::Array 
type(*internal
->type_
->type_
, internal
->length_
); 
1860     return CYMakeType(context
, type
); 
1863 static JSValueRef Pointer_getProperty_$
cyt(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1864     Pointer 
*internal(reinterpret_cast<Pointer 
*>(JSObjectGetPrivate(object
))); 
1865     sig::Pointer 
type(*internal
->type_
->type_
); 
1866     return CYMakeType(context
, type
); 
1869 static JSValueRef 
CString_callAsFunction_toCYON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1870     CString 
*internal(reinterpret_cast<CString 
*>(JSObjectGetPrivate(_this
))); 
1871     const char *string(internal
->value_
); 
1872     std::ostringstream str
; 
1877         CYStringify(str
, string
, strlen(string
), CYStringifyModeNative
); 
1879     std::string 
value(str
.str()); 
1880     return CYCastJSValue(context
, CYJSString(CYUTF8String(value
.c_str(), value
.size()))); 
1883 static JSValueRef 
CString_callAsFunction_toString(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1884     CString 
*internal(reinterpret_cast<CString 
*>(JSObjectGetPrivate(_this
))); 
1885     return CYCastJSValue(context
, internal
->value_
); 
1888 static JSValueRef Functor_getProperty_$
cyt(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1889     cy::Functor 
*internal(reinterpret_cast<cy::Functor 
*>(JSObjectGetPrivate(object
))); 
1891     sig::Function 
type(internal
->variadic_
); 
1892     sig::Copy(pool
, type
.signature
, internal
->signature_
); 
1893     return CYMakeType(context
, type
); 
1896 static JSValueRef 
Type_getProperty_alignment(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1897     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1898     return CYCastJSValue(context
, internal
->GetFFI()->alignment
); 
1901 static JSValueRef 
Type_getProperty_name(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1902     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1903     return CYCastJSValue(context
, internal
->type_
->GetName()); 
1906 static JSValueRef 
Type_getProperty_size(JSContextRef context
, JSObjectRef object
, JSStringRef property
, JSValueRef 
*exception
) { CYTry 
{ 
1907     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(object
))); 
1908     return CYCastJSValue(context
, internal
->GetFFI()->size
); 
1911 static JSValueRef 
Type_callAsFunction_toString(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1912     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1914     const char *type(sig::Unparse(pool
, internal
->type_
)); 
1915     return CYCastJSValue(context
, CYJSString(type
)); 
1918 static JSValueRef 
Type_callAsFunction_toCYON(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
1919     Type_privateData 
*internal(reinterpret_cast<Type_privateData 
*>(JSObjectGetPrivate(_this
))); 
1923     CYOutput 
output(out
, options
); 
1924     output
.pretty_ 
= true; 
1925     (new(pool
) CYTypeExpression(CYDecodeType(pool
, internal
->type_
->Copy(pool
, ""))))->Output(output
, CYNoFlags
); 
1926     return CYCastJSValue(context
, CYJSString(out
.str().c_str())); 
1929 static JSStaticFunction All_staticFunctions
[2] = { 
1930     {"cy$complete", &All_complete_callAsFunction
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1934 static JSStaticFunction CArray_staticFunctions
[3] = { 
1935     {"toPointer", &CArray_callAsFunction_toPointer
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1936     {"valueOf", &CArray_callAsFunction_valueOf
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1940 static JSStaticValue CArray_staticValues
[2] = { 
1941     {"$cyt", &CArray_getProperty_$cyt
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1942     {NULL
, NULL
, NULL
, 0} 
1945 static JSStaticFunction CString_staticFunctions
[5] = { 
1946     {"toCYON", &CString_callAsFunction_toCYON
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1947     {"toPointer", &CString_callAsFunction_toPointer
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1948     {"toString", &CString_callAsFunction_toString
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1949     {"valueOf", &CString_callAsFunction_toString
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1953 static JSStaticValue CString_staticValues
[3] = { 
1954     {"length", &CString_getProperty_length
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1955     {"$cyt", &CString_getProperty_$cyt
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1956     {NULL
, NULL
, NULL
, 0} 
1959 static JSStaticFunction Pointer_staticFunctions
[4] = { 
1960     {"toCYON", &Pointer_callAsFunction_toCYON
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1961     {"toPointer", &Pointer_callAsFunction_toPointer
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1962     {"valueOf", &Pointer_callAsFunction_valueOf
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1966 static JSStaticValue Pointer_staticValues
[2] = { 
1967     {"$cyt", &Pointer_getProperty_$cyt
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1968     {NULL
, NULL
, NULL
, 0} 
1971 static JSStaticFunction Struct_staticFunctions
[2] = { 
1972     {"$cya", &Struct_callAsFunction_$cya
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1976 static JSStaticValue Struct_staticValues
[2] = { 
1977     {"$cyt", &Struct_getProperty_$cyt
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1978     {NULL
, NULL
, NULL
, 0} 
1981 static JSStaticFunction Functor_staticFunctions
[4] = { 
1982     {"$cya", &Functor_callAsFunction_$cya
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1983     {"toCYON", &Functor_callAsFunction_toCYON
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1984     {"valueOf", &Functor_callAsFunction_valueOf
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1988 static JSStaticValue Functor_staticValues
[2] = { 
1989     {"$cyt", &Functor_getProperty_$cyt
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1990     {NULL
, NULL
, NULL
, 0} 
1993 static JSStaticValue Type_staticValues
[4] = { 
1994     {"alignment", &Type_getProperty_alignment
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1995     {"name", &Type_getProperty_name
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1996     {"size", &Type_getProperty_size
, NULL
, kJSPropertyAttributeReadOnly 
| kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
1997     {NULL
, NULL
, NULL
, 0} 
2000 static JSStaticFunction Type_staticFunctions
[10] = { 
2001     {"arrayOf", &Type_callAsFunction_arrayOf
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
2002     {"blockWith", &Type_callAsFunction_blockWith
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
2003     {"constant", &Type_callAsFunction_constant
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
2004     {"enumFor", &Type_callAsFunction_enumFor
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
2005     {"functionWith", &Type_callAsFunction_functionWith
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
2006     {"pointerTo", &Type_callAsFunction_pointerTo
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
2007     {"withName", &Type_callAsFunction_withName
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
2008     {"toCYON", &Type_callAsFunction_toCYON
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
2009     {"toString", &Type_callAsFunction_toString
, kJSPropertyAttributeDontEnum 
| kJSPropertyAttributeDontDelete
}, 
2013 _visible 
void CYSetArgs(const char *argv0
, const char *script
, int argc
, const char *argv
[]) { 
2014     JSContextRef 
context(CYGetJSContext()); 
2015     JSValueRef args
[argc 
+ 2]; 
2016     for (int i(0); i 
!= argc
; ++i
) 
2017         args
[i 
+ 2] = CYCastJSValue(context
, argv
[i
]); 
2024         args
[1] = CYCastJSValue(context
, CYJSString(script
)); 
2027     args
[offset
] = CYCastJSValue(context
, CYJSString(argv0
)); 
2029     CYSetProperty(context
, CYGetCachedObject(context
, CYJSString("System")), CYJSString("args"), CYObjectMakeArray(context
, argc
, args 
+ 2)); 
2030     CYSetProperty(context
, CYGetCachedObject(context
, CYJSString("process")), CYJSString("argv"), CYObjectMakeArray(context
, argc 
+ 2 - offset
, args 
+ offset
)); 
2033 JSObjectRef 
CYGetGlobalObject(JSContextRef context
) { 
2034     return JSContextGetGlobalObject(context
); 
2037 // XXX: this is neither exceptin safe nor even terribly sane 
2038 class ExecutionHandle 
{ 
2040     JSContextRef context_
; 
2041     std::vector
<void *> handles_
; 
2044     ExecutionHandle(JSContextRef context
) : 
2047         handles_
.resize(GetHooks().size()); 
2048         for (size_t i(0); i 
!= GetHooks().size(); ++i
) { 
2049             CYHook 
*hook(GetHooks()[i
]); 
2050             if (hook
->ExecuteStart 
!= NULL
) 
2051                 handles_
[i
] = (*hook
->ExecuteStart
)(context_
); 
2057     ~ExecutionHandle() { 
2058         for (size_t i(GetHooks().size()); i 
!= 0; --i
) { 
2059             CYHook 
*hook(GetHooks()[i
-1]); 
2060             if (hook
->ExecuteEnd 
!= NULL
) 
2061                 (*hook
->ExecuteEnd
)(context_
, handles_
[i
-1]); 
2067 static volatile bool cancel_
; 
2069 static bool CYShouldTerminate(JSContextRef context
, void *arg
) { 
2074 _visible 
const char *CYExecute(JSContextRef context
, CYPool 
&pool
, CYUTF8String code
) { 
2075     ExecutionHandle 
handle(context
); 
2079     if (&JSContextGroupSetExecutionTimeLimit 
!= NULL
) 
2080         JSContextGroupSetExecutionTimeLimit(JSContextGetGroup(context
), 0.5, &CYShouldTerminate
, NULL
); 
2084         JSValueRef 
result(_jsccall(JSEvaluateScript
, context
, CYJSString(code
), NULL
, NULL
, 0)); 
2085         if (JSValueIsUndefined(context
, result
)) 
2088         std::set
<void *> objects
; 
2089         const char *json(_jsccall(CYPoolCCYON
, pool
, context
, result
, objects
)); 
2090         CYSetProperty(context
, CYGetGlobalObject(context
), Result_
, result
); 
2093     } catch (const CYException 
&error
) { 
2094         return pool
.strcat("throw ", error
.PoolCString(pool
), NULL
); 
2099 _visible 
void CYCancel() { 
2104 const char *CYPoolLibraryPath(CYPool 
&pool
); 
2106 static bool initialized_ 
= false; 
2108 void CYInitializeDynamic() { 
2110         initialized_ 
= true; 
2114     const char *db(pool
.strcat(CYPoolLibraryPath(pool
), "/libcycript.db", NULL
)); 
2115     _sqlcall(sqlite3_open_v2(db
, &database_
, SQLITE_OPEN_READONLY
, NULL
)); 
2117     JSObjectMakeArray$ 
= reinterpret_cast<JSObjectRef (*)(JSContextRef
, size_t, const JSValueRef
[], JSValueRef 
*)>(dlsym(RTLD_DEFAULT
, "JSObjectMakeArray")); 
2118     JSSynchronousGarbageCollectForDebugging$ 
= reinterpret_cast<void (*)(JSContextRef
)>(dlsym(RTLD_DEFAULT
, "JSSynchronousGarbageCollectForDebugging")); 
2120     JSClassDefinition definition
; 
2122     definition 
= kJSClassDefinitionEmpty
; 
2123     definition
.className 
= "All"; 
2124     definition
.staticFunctions 
= All_staticFunctions
; 
2125     definition
.hasProperty 
= &All_hasProperty
; 
2126     definition
.getProperty 
= &All_getProperty
; 
2127     definition
.getPropertyNames 
= &All_getPropertyNames
; 
2128     All_ 
= JSClassCreate(&definition
); 
2130     definition 
= kJSClassDefinitionEmpty
; 
2131     definition
.className 
= "Context"; 
2132     definition
.finalize 
= &CYFinalize
; 
2133     CYPrivate
<Context
>::Class_ 
= JSClassCreate(&definition
); 
2135     definition 
= kJSClassDefinitionEmpty
; 
2136     definition
.className 
= "CArray"; 
2137     definition
.staticFunctions 
= CArray_staticFunctions
; 
2138     definition
.staticValues 
= CArray_staticValues
; 
2139     definition
.getProperty 
= &CArray_getProperty
; 
2140     definition
.setProperty 
= &CArray_setProperty
; 
2141     definition
.finalize 
= &CYFinalize
; 
2142     CYPrivate
<CArray
>::Class_ 
= JSClassCreate(&definition
); 
2144     definition 
= kJSClassDefinitionEmpty
; 
2145     definition
.className 
= "CString"; 
2146     definition
.staticFunctions 
= CString_staticFunctions
; 
2147     definition
.staticValues 
= CString_staticValues
; 
2148     definition
.getProperty 
= &CString_getProperty
; 
2149     definition
.setProperty 
= &CString_setProperty
; 
2150     definition
.finalize 
= &CYFinalize
; 
2151     CYPrivate
<CString
>::Class_ 
= JSClassCreate(&definition
); 
2153     definition 
= kJSClassDefinitionEmpty
; 
2154     definition
.className 
= "Functor"; 
2155     definition
.staticFunctions 
= Functor_staticFunctions
; 
2156     definition
.staticValues 
= Functor_staticValues
; 
2157     definition
.callAsFunction 
= &Functor_callAsFunction
; 
2158     definition
.finalize 
= &CYFinalize
; 
2159     cy::Functor::Class_ 
= JSClassCreate(&definition
); 
2161     definition 
= kJSClassDefinitionEmpty
; 
2162     definition
.className 
= "Pointer"; 
2163     definition
.staticFunctions 
= Pointer_staticFunctions
; 
2164     definition
.staticValues 
= Pointer_staticValues
; 
2165     definition
.callAsFunction 
= &Pointer_callAsFunction
; 
2166     definition
.getProperty 
= &Pointer_getProperty
; 
2167     definition
.setProperty 
= &Pointer_setProperty
; 
2168     definition
.finalize 
= &CYFinalize
; 
2169     CYPrivate
<Pointer
>::Class_ 
= JSClassCreate(&definition
); 
2171     definition 
= kJSClassDefinitionEmpty
; 
2172     definition
.className 
= "Root"; 
2173     definition
.finalize 
= &CYFinalize
; 
2174     CYPrivate
<CYRoot
>::Class_ 
= JSClassCreate(&definition
); 
2176     definition 
= kJSClassDefinitionEmpty
; 
2177     definition
.className 
= "Struct"; 
2178     definition
.staticFunctions 
= Struct_staticFunctions
; 
2179     definition
.staticValues 
= Struct_staticValues
; 
2180     definition
.getProperty 
= &Struct_getProperty
; 
2181     definition
.setProperty 
= &Struct_setProperty
; 
2182     definition
.getPropertyNames 
= &Struct_getPropertyNames
; 
2183     definition
.finalize 
= &CYFinalize
; 
2184     CYPrivate
<Struct_privateData
>::Class_ 
= JSClassCreate(&definition
); 
2186     definition 
= kJSClassDefinitionEmpty
; 
2187     definition
.className 
= "Type"; 
2188     definition
.staticValues 
= Type_staticValues
; 
2189     definition
.staticFunctions 
= Type_staticFunctions
; 
2190     definition
.callAsFunction 
= &Type_callAsFunction
; 
2191     definition
.callAsConstructor 
= &Type_callAsConstructor
; 
2192     definition
.finalize 
= &CYFinalize
; 
2193     CYPrivate
<Type_privateData
>::Class_ 
= JSClassCreate(&definition
); 
2195     definition 
= kJSClassDefinitionEmpty
; 
2196     definition
.className 
= "Global"; 
2197     //definition.getProperty = &Global_getProperty; 
2198     Global_ 
= JSClassCreate(&definition
); 
2200     Array_s 
= JSStringCreateWithUTF8CString("Array"); 
2201     constructor_s 
= JSStringCreateWithUTF8CString("constructor"); 
2202     cy_s 
= JSStringCreateWithUTF8CString("$cy"); 
2203     cyi_s 
= JSStringCreateWithUTF8CString("$cyi"); 
2204     cyt_s 
= JSStringCreateWithUTF8CString("$cyt"); 
2205     length_s 
= JSStringCreateWithUTF8CString("length"); 
2206     message_s 
= JSStringCreateWithUTF8CString("message"); 
2207     name_s 
= JSStringCreateWithUTF8CString("name"); 
2208     pop_s 
= JSStringCreateWithUTF8CString("pop"); 
2209     prototype_s 
= JSStringCreateWithUTF8CString("prototype"); 
2210     push_s 
= JSStringCreateWithUTF8CString("push"); 
2211     splice_s 
= JSStringCreateWithUTF8CString("splice"); 
2212     toCYON_s 
= JSStringCreateWithUTF8CString("toCYON"); 
2213     toJSON_s 
= JSStringCreateWithUTF8CString("toJSON"); 
2214     toPointer_s 
= JSStringCreateWithUTF8CString("toPointer"); 
2215     toString_s 
= JSStringCreateWithUTF8CString("toString"); 
2216     weak_s 
= JSStringCreateWithUTF8CString("weak"); 
2218     Result_ 
= JSStringCreateWithUTF8CString("_"); 
2220     for (CYHook 
*hook 
: GetHooks()) 
2221         if (hook
->Initialize 
!= NULL
) 
2222             (*hook
->Initialize
)(); 
2225 void CYThrow(JSContextRef context
, JSValueRef value
) { 
2227         throw CYJSError(context
, value
); 
2230 const char *CYJSError::PoolCString(CYPool 
&pool
) const { 
2231     std::set
<void *> objects
; 
2232     // XXX: this used to be CYPoolCString 
2233     return CYPoolCCYON(pool
, context_
, value_
, objects
); 
2236 JSValueRef 
CYJSError::CastJSValue(JSContextRef context
, const char *name
) const { 
2237     // XXX: what if the context is different? or the name? I dunno. ("epic" :/) 
2241 JSValueRef 
CYCastJSError(JSContextRef context
, const char *name
, const char *message
) { 
2242     JSObjectRef 
Error(CYGetCachedObject(context
, CYJSString(name
))); 
2243     JSValueRef arguments
[1] = {CYCastJSValue(context
, message
)}; 
2244     return _jsccall(JSObjectCallAsConstructor
, context
, Error
, 1, arguments
); 
2247 JSValueRef 
CYPoolError::CastJSValue(JSContextRef context
, const char *name
) const { 
2248     return CYCastJSError(context
, name
, message_
); 
2251 CYJSError::CYJSError(JSContextRef context
, const char *format
, ...) { 
2252     _assert(context 
!= NULL
); 
2257     va_start(args
, format
); 
2258     // XXX: there might be a beter way to think about this 
2259     const char *message(pool
.vsprintf(64, format
, args
)); 
2262     value_ 
= CYCastJSError(context
, "Error", message
); 
2265 JSGlobalContextRef 
CYGetJSContext(JSContextRef context
) { 
2266     return reinterpret_cast<Context 
*>(JSObjectGetPrivate(CYCastJSObject(context
, CYGetProperty(context
, CYGetGlobalObject(context
), cy_s
))))->context_
; 
2270 char *CYPoolLibraryPath_(CYPool 
&pool
) { 
2271     FILE *maps(fopen("/proc/self/maps", "r")); 
2272     struct F 
{ FILE *f
; F(FILE *f
) : f(f
) {} 
2273         ~F() { fclose(f
); } } f(maps
); 
2275     size_t function(reinterpret_cast<size_t>(&CYPoolLibraryPath
)); 
2278         size_t start
; size_t end
; char flags
[8]; unsigned long long offset
; 
2279         int major
; int minor
; unsigned long long inode
; char file
[1024]; 
2280         int count(fscanf(maps
, "%zx-%zx %7s %llx %x:%x %llu%[ ]%1024[^\n]\n", 
2281             &start
, &end
, flags
, &offset
, &major
, &minor
, &inode
, file
, file
)); 
2282         if (count 
< 8) break; else if (start 
<= function 
&& function 
< end
) 
2283             return pool
.strdup(file
); 
2289 char *CYPoolLibraryPath_(CYPool 
&pool
) { 
2291     _assert(dladdr(reinterpret_cast<void *>(&CYPoolLibraryPath
), &addr
) != 0); 
2292     return pool
.strdup(addr
.dli_fname
); 
2296 const char *CYPoolLibraryPath(CYPool 
&pool
) { 
2297     char *lib(CYPoolLibraryPath_(pool
)); 
2299     char *slash(strrchr(lib
, '/')); 
2304     slash 
= strrchr(lib
, '/'); 
2305     if (slash 
!= NULL
) { 
2306         if (strcmp(slash
, "/.libs") == 0) 
2308     } else if (strcmp(lib
, ".libs") == 0) 
2314 static JSValueRef 
require_callAsFunction(JSContextRef context
, JSObjectRef object
, JSObjectRef _this
, size_t count
, const JSValueRef arguments
[], JSValueRef 
*exception
) { CYTry 
{ 
2315     _assert(count 
== 1); 
2318     CYUTF8String 
name(CYPoolUTF8String(pool
, context
, CYJSString(context
, arguments
[0]))); 
2319     if (memchr(name
.data
, '/', name
.size
) == NULL 
&& ( 
2321         dlopen(pool
.strcat("/System/Library/Frameworks/", name
.data
, ".framework/", name
.data
, NULL
), RTLD_LAZY 
| RTLD_GLOBAL
) != NULL 
|| 
2322         dlopen(pool
.strcat("/System/Library/PrivateFrameworks/", name
.data
, ".framework/", name
.data
, NULL
), RTLD_LAZY 
| RTLD_GLOBAL
) != NULL 
|| 
2325         return CYJSUndefined(context
); 
2330     sqlite3_stmt 
*statement
; 
2332     _sqlcall(sqlite3_prepare(database_
, 
2334             "\"module\".\"code\", " 
2335             "\"module\".\"flags\" " 
2338             " \"module\".\"name\" = ?" 
2340     , -1, &statement
, NULL
)); 
2342     _sqlcall(sqlite3_bind_text(statement
, 1, name
.data
, name
.size
, SQLITE_STATIC
)); 
2344     if (_sqlcall(sqlite3_step(statement
)) != SQLITE_DONE
) { 
2345         code
.data 
= static_cast<const char *>(sqlite3_column_blob(statement
, 0)); 
2346         code
.size 
= sqlite3_column_bytes(statement
, 0); 
2347         path 
= CYJSString(name
); 
2348         code 
= CYPoolUTF8String(pool
, code
); 
2350         JSObjectRef 
resolve(CYCastJSObject(context
, CYGetProperty(context
, object
, CYJSString("resolve")))); 
2351         path 
= CYJSString(context
, CYCallAsFunction(context
, resolve
, NULL
, 1, arguments
)); 
2354     _sqlcall(sqlite3_finalize(statement
)); 
2356     CYJSString 
property("exports"); 
2358     JSObjectRef 
modules(CYGetCachedObject(context
, CYJSString("modules"))); 
2359     JSValueRef 
cache(CYGetProperty(context
, modules
, path
)); 
2362     if (!JSValueIsUndefined(context
, cache
)) { 
2363         JSObjectRef 
module(CYCastJSObject(context
, cache
)); 
2364         result 
= CYGetProperty(context
, module, property
); 
2366         if (code
.data 
== NULL
) { 
2367             code 
= CYPoolFileUTF8String(pool
, CYPoolCString(pool
, context
, path
)); 
2368             _assert(code
.data 
!= NULL
); 
2371         size_t length(name
.size
); 
2372         if (length 
>= 5 && strncmp(name
.data 
+ length 
- 5, ".json", 5) == 0) { 
2373             JSObjectRef 
JSON(CYGetCachedObject(context
, CYJSString("JSON"))); 
2374             JSObjectRef 
parse(CYCastJSObject(context
, CYGetProperty(context
, JSON
, CYJSString("parse")))); 
2375             JSValueRef arguments
[1] = { CYCastJSValue(context
, CYJSString(code
)) }; 
2376             result 
= CYCallAsFunction(context
, parse
, JSON
, 1, arguments
); 
2378             JSObjectRef 
module(JSObjectMake(context
, NULL
, NULL
)); 
2379             CYSetProperty(context
, modules
, path
, module); 
2381             JSObjectRef 
exports(JSObjectMake(context
, NULL
, NULL
)); 
2382             CYSetProperty(context
, module, property
, exports
); 
2384             std::stringstream wrap
; 
2385             wrap 
<< "(function (exports, require, module, __filename) { " << code 
<< "\n});"; 
2386             code 
= CYPoolCode(pool
, *wrap
.rdbuf()); 
2388             JSValueRef 
value(_jsccall(JSEvaluateScript
, context
, CYJSString(code
), NULL
, NULL
, 0)); 
2389             JSObjectRef 
function(CYCastJSObject(context
, value
)); 
2391             JSValueRef arguments
[4] = { exports
, object
, module, CYCastJSValue(context
, path
) }; 
2392             CYCallAsFunction(context
, function
, NULL
, 4, arguments
); 
2393             result 
= CYGetProperty(context
, module, property
); 
2400 static bool CYRunScript(JSGlobalContextRef context
, const char *path
) { 
2402     CYUTF8String 
code(CYPoolFileUTF8String(pool
, pool
.strcat(CYPoolLibraryPath(pool
), path
, NULL
))); 
2403     if (code
.data 
== NULL
) 
2406     code 
= CYPoolCode(pool
, code
); 
2407     _jsccall(JSEvaluateScript
, context
, CYJSString(code
), NULL
, NULL
, 0); 
2411 extern "C" void CYDestroyWeak(JSWeakObjectMapRef weak
, void *data
) { 
2414 extern "C" void CYSetupContext(JSGlobalContextRef context
) { 
2415     CYInitializeDynamic(); 
2417     JSObjectRef 
global(CYGetGlobalObject(context
)); 
2419     JSObjectRef 
cy(CYPrivate
<Context
>::Make(context
, context
)); 
2420     CYSetProperty(context
, global
, cy_s
, cy
, kJSPropertyAttributeDontEnum
); 
2422 /* Cache Globals {{{ */ 
2423     JSObjectRef 
Array(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Array")))); 
2424     CYSetProperty(context
, cy
, CYJSString("Array"), Array
); 
2426     JSObjectRef 
Array_prototype(CYCastJSObject(context
, CYGetProperty(context
, Array
, prototype_s
))); 
2427     CYSetProperty(context
, cy
, CYJSString("Array_prototype"), Array_prototype
); 
2429     JSObjectRef 
Boolean(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Boolean")))); 
2430     CYSetProperty(context
, cy
, CYJSString("Boolean"), Boolean
); 
2432     JSObjectRef 
Boolean_prototype(CYCastJSObject(context
, CYGetProperty(context
, Boolean
, prototype_s
))); 
2433     CYSetProperty(context
, cy
, CYJSString("Boolean_prototype"), Boolean_prototype
); 
2435     JSObjectRef 
Error(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Error")))); 
2436     CYSetProperty(context
, cy
, CYJSString("Error"), Error
); 
2438     JSObjectRef 
Function(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Function")))); 
2439     CYSetProperty(context
, cy
, CYJSString("Function"), Function
); 
2441     JSObjectRef 
Function_prototype(CYCastJSObject(context
, CYGetProperty(context
, Function
, prototype_s
))); 
2442     CYSetProperty(context
, cy
, CYJSString("Function_prototype"), Function_prototype
); 
2444     JSObjectRef 
JSON(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("JSON")))); 
2445     CYSetProperty(context
, cy
, CYJSString("JSON"), JSON
); 
2447     JSObjectRef 
Number(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Number")))); 
2448     CYSetProperty(context
, cy
, CYJSString("Number"), Number
); 
2450     JSObjectRef 
Number_prototype(CYCastJSObject(context
, CYGetProperty(context
, Number
, prototype_s
))); 
2451     CYSetProperty(context
, cy
, CYJSString("Number_prototype"), Number_prototype
); 
2453     JSObjectRef 
Object(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("Object")))); 
2454     CYSetProperty(context
, cy
, CYJSString("Object"), Object
); 
2456     JSObjectRef 
Object_prototype(CYCastJSObject(context
, CYGetProperty(context
, Object
, prototype_s
))); 
2457     CYSetProperty(context
, cy
, CYJSString("Object_prototype"), Object_prototype
); 
2459     JSObjectRef 
String(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("String")))); 
2460     CYSetProperty(context
, cy
, CYJSString("String"), String
); 
2462     JSObjectRef 
String_prototype(CYCastJSObject(context
, CYGetProperty(context
, String
, prototype_s
))); 
2463     CYSetProperty(context
, cy
, CYJSString("String_prototype"), String_prototype
); 
2465     JSObjectRef 
SyntaxError(CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("SyntaxError")))); 
2466     CYSetProperty(context
, cy
, CYJSString("SyntaxError"), SyntaxError
); 
2469     CYSetProperty(context
, Array_prototype
, toCYON_s
, &Array_callAsFunction_toCYON
, kJSPropertyAttributeDontEnum
); 
2470     CYSetProperty(context
, String_prototype
, toCYON_s
, &String_callAsFunction_toCYON
, kJSPropertyAttributeDontEnum
); 
2472     JSObjectRef 
cycript(JSObjectMake(context
, NULL
, NULL
)); 
2473     CYSetProperty(context
, global
, CYJSString("Cycript"), cycript
); 
2474     CYSetProperty(context
, cycript
, CYJSString("compile"), &Cycript_compile_callAsFunction
); 
2475     CYSetProperty(context
, cycript
, CYJSString("gc"), &Cycript_gc_callAsFunction
); 
2477     JSObjectRef 
CArray(JSObjectMakeConstructor(context
, CYPrivate
<::CArray
>::Class_
, &CArray_new
)); 
2478     CYSetPrototype(context
, CYCastJSObject(context
, CYGetProperty(context
, CArray
, prototype_s
)), Array_prototype
); 
2479     CYSetProperty(context
, cycript
, CYJSString("CArray"), CArray
); 
2481     JSObjectRef 
CString(JSObjectMakeConstructor(context
, CYPrivate
<::CString
>::Class_
, &CString_new
)); 
2482     CYSetPrototype(context
, CYCastJSObject(context
, CYGetProperty(context
, CString
, prototype_s
)), String_prototype
); 
2483     CYSetProperty(context
, cycript
, CYJSString("CString"), CString
); 
2485     JSObjectRef 
Functor(JSObjectMakeConstructor(context
, cy::Functor::Class_
, &Functor_new
)); 
2486     JSObjectRef 
Functor_prototype(CYCastJSObject(context
, CYGetProperty(context
, Functor
, prototype_s
))); 
2487     CYSetPrototype(context
, Functor_prototype
, Function_prototype
); 
2488     CYSetProperty(context
, cy
, CYJSString("Functor_prototype"), Functor_prototype
); 
2489     CYSetProperty(context
, cycript
, CYJSString("Functor"), Functor
); 
2491     CYSetProperty(context
, cycript
, CYJSString("Pointer"), JSObjectMakeConstructor(context
, CYPrivate
<Pointer
>::Class_
, &Pointer_new
)); 
2493     JSObjectRef 
Type(JSObjectMakeConstructor(context
, CYPrivate
<Type_privateData
>::Class_
, &Type_new
)); 
2494     JSObjectRef 
Type_prototype(CYCastJSObject(context
, CYGetProperty(context
, Type
, prototype_s
))); 
2495     CYSetPrototype(context
, Type_prototype
, Function_prototype
); 
2496     CYSetProperty(context
, cy
, CYJSString("Type_prototype"), Type_prototype
); 
2497     CYSetProperty(context
, cycript
, CYJSString("Type"), Type
); 
2499     JSObjectRef 
Character_prototype(JSObjectMake(context
, NULL
, NULL
)); 
2500     CYSetPrototype(context
, Character_prototype
, String_prototype
); 
2501     CYSetProperty(context
, cy
, CYJSString("Character_prototype"), Character_prototype
); 
2502     CYSetProperty(context
, Character_prototype
, CYJSString("valueOf"), _jsccall(JSEvaluateScript
, context
, CYJSString("(function(){return this.charCodeAt(0);})"), NULL
, NULL
, 0)); 
2504     JSObjectRef 
modules(JSObjectMake(context
, NULL
, NULL
)); 
2505     CYSetProperty(context
, cy
, CYJSString("modules"), modules
); 
2507     JSObjectRef 
all(JSObjectMake(context
, All_
, NULL
)); 
2508     CYSetProperty(context
, cycript
, CYJSString("all"), all
); 
2510     JSObjectRef 
cache(JSObjectMake(context
, NULL
, NULL
)); 
2511     CYSetProperty(context
, cy
, CYJSString("cache"), cache
); 
2512     CYSetPrototype(context
, cache
, all
); 
2514     JSObjectRef 
alls(_jsccall(JSObjectCallAsConstructor
, context
, Array
, 0, NULL
)); 
2515     CYSetProperty(context
, cycript
, CYJSString("alls"), alls
); 
2518         JSObjectRef 
last(NULL
), curr(global
); 
2520         goto next
; for (JSValueRef next
;;) { 
2521             if (JSValueIsNull(context
, next
)) 
2524             curr 
= CYCastJSObject(context
, next
); 
2526             next 
= JSObjectGetPrototype(context
, curr
); 
2529         CYSetPrototype(context
, last
, cache
); 
2533     if (&JSWeakObjectMapCreate 
!= NULL
) { 
2534         JSWeakObjectMapRef 
weak(JSWeakObjectMapCreate(context
, NULL
, &CYDestroyWeak
)); 
2535         CYSetProperty(context
, cy
, weak_s
, CYCastJSValue(context
, reinterpret_cast<uintptr_t>(weak
))); 
2539     CYSetProperty(context
, String_prototype
, cyt_s
, CYMakeType(context
, sig::String()), kJSPropertyAttributeDontEnum
); 
2541     CYSetProperty(context
, cache
, CYJSString("dlerror"), CYMakeFunctor(context
, "dlerror", "*"), kJSPropertyAttributeDontEnum
); 
2542     CYSetProperty(context
, cache
, CYJSString("RTLD_DEFAULT"), CYCastJSValue(context
, reinterpret_cast<intptr_t>(RTLD_DEFAULT
)), kJSPropertyAttributeDontEnum
); 
2543     CYSetProperty(context
, cache
, CYJSString("dlsym"), CYMakeFunctor(context
, "dlsym", "^v^v*"), kJSPropertyAttributeDontEnum
); 
2545     CYSetProperty(context
, cache
, CYJSString("NULL"), CYJSNull(context
), kJSPropertyAttributeDontEnum
); 
2547     CYSetProperty(context
, cache
, CYJSString("bool"), CYMakeType(context
, sig::Primitive
<bool>()), kJSPropertyAttributeDontEnum
); 
2548     CYSetProperty(context
, cache
, CYJSString("char"), CYMakeType(context
, sig::Primitive
<char>()), kJSPropertyAttributeDontEnum
); 
2549     CYSetProperty(context
, cache
, CYJSString("schar"), CYMakeType(context
, sig::Primitive
<signed char>()), kJSPropertyAttributeDontEnum
); 
2550     CYSetProperty(context
, cache
, CYJSString("uchar"), CYMakeType(context
, sig::Primitive
<unsigned char>()), kJSPropertyAttributeDontEnum
); 
2552     CYSetProperty(context
, cache
, CYJSString("short"), CYMakeType(context
, sig::Primitive
<short>()), kJSPropertyAttributeDontEnum
); 
2553     CYSetProperty(context
, cache
, CYJSString("int"), CYMakeType(context
, sig::Primitive
<int>()), kJSPropertyAttributeDontEnum
); 
2554     CYSetProperty(context
, cache
, CYJSString("long"), CYMakeType(context
, sig::Primitive
<long>()), kJSPropertyAttributeDontEnum
); 
2555     CYSetProperty(context
, cache
, CYJSString("longlong"), CYMakeType(context
, sig::Primitive
<long long>()), kJSPropertyAttributeDontEnum
); 
2557     CYSetProperty(context
, cache
, CYJSString("ushort"), CYMakeType(context
, sig::Primitive
<unsigned short>()), kJSPropertyAttributeDontEnum
); 
2558     CYSetProperty(context
, cache
, CYJSString("uint"), CYMakeType(context
, sig::Primitive
<unsigned int>()), kJSPropertyAttributeDontEnum
); 
2559     CYSetProperty(context
, cache
, CYJSString("ulong"), CYMakeType(context
, sig::Primitive
<unsigned long>()), kJSPropertyAttributeDontEnum
); 
2560     CYSetProperty(context
, cache
, CYJSString("ulonglong"), CYMakeType(context
, sig::Primitive
<unsigned long long>()), kJSPropertyAttributeDontEnum
); 
2562 #ifdef __SIZEOF_INT128__ 
2563     CYSetProperty(context
, cache
, CYJSString("int128"), CYMakeType(context
, sig::Primitive
<__int128
>()), kJSPropertyAttributeDontEnum
); 
2564     CYSetProperty(context
, cache
, CYJSString("uint128"), CYMakeType(context
, sig::Primitive
<unsigned __int128
>()), kJSPropertyAttributeDontEnum
); 
2567     CYSetProperty(context
, cache
, CYJSString("float"), CYMakeType(context
, sig::Primitive
<float>()), kJSPropertyAttributeDontEnum
); 
2568     CYSetProperty(context
, cache
, CYJSString("double"), CYMakeType(context
, sig::Primitive
<double>()), kJSPropertyAttributeDontEnum
); 
2569     CYSetProperty(context
, cache
, CYJSString("longdouble"), CYMakeType(context
, sig::Primitive
<long double>()), kJSPropertyAttributeDontEnum
); 
2571     CYSetProperty(context
, global
, CYJSString("require"), &require_callAsFunction
, kJSPropertyAttributeDontEnum
); 
2573     JSObjectRef 
System(JSObjectMake(context
, NULL
, NULL
)); 
2574     CYSetProperty(context
, all
, CYJSString("system"), System
); 
2575     System 
= CYCastJSObject(context
, CYGetProperty(context
, global
, CYJSString("system"))); 
2576     CYSetProperty(context
, cy
, CYJSString("System"), System
); 
2578     JSObjectRef 
process(JSObjectMake(context
, NULL
, NULL
)); 
2579     CYSetProperty(context
, global
, CYJSString("process"), process
); 
2580     CYSetProperty(context
, cy
, CYJSString("process"), process
); 
2582     CYSetProperty(context
, System
, CYJSString("args"), CYJSNull(context
)); 
2583     CYSetProperty(context
, System
, CYJSString("print"), &System_print
); 
2585     CYSetProperty(context
, global
, CYJSString("global"), global
); 
2586     CYSetProperty(context
, global
, CYJSString("print"), &Global_print
); 
2588     for (CYHook 
*hook 
: GetHooks()) 
2589         if (hook
->SetupContext 
!= NULL
) 
2590             (*hook
->SetupContext
)(context
); 
2592     CYArrayPush(context
, alls
, cycript
); 
2594     CYRunScript(context
, "/libcycript.cy"); 
2597 static JSGlobalContextRef context_
; 
2599 _visible JSGlobalContextRef 
CYGetJSContext() { 
2600     CYInitializeDynamic(); 
2602     if (context_ 
== NULL
) { 
2603         context_ 
= JSGlobalContextCreate(Global_
); 
2604         CYSetupContext(context_
); 
2610 _visible 
void CYDestroyContext() { 
2611     if (context_ 
== NULL
) 
2613     JSGlobalContextRelease(context_
);