]> git.saurik.com Git - cycript.git/commitdiff
Support array ffi_type through some shady argumentaton, implement Type[] syntax for...
authorJay Freeman (saurik) <saurik@saurik.com>
Mon, 19 Oct 2009 22:08:37 +0000 (22:08 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Mon, 19 Oct 2009 22:08:37 +0000 (22:08 +0000)
Bridge.def
Cycript.l
Cycript.y
Library.mm
sig/ffi_type.cpp

index 2994bd11084fd09c9161b3852101950fe37a5b85..7ce9cda654416cbf722285c7beedc52a70c11d02 100644 (file)
@@ -4,6 +4,20 @@ C nil null
 
 : applicationDidFinishLaunching: v12@0:4@8
 
+T id @
+
+T short s
+T int i
+T long l
+
+T uint I
+T ulong L
+T ushort S
+
+T char c
+T boolean B
+T float f
+T double d
 
 S CGPoint "x"f"y"f
 S CGRect "origin"{CGPoint}"size"{CGSize}
index 063e9004fd0fcc584dd053cde11b51423316fa99..20a4ede060ed74026fdc04f929a149f4ab44b9b2 100644 (file)
--- a/Cycript.l
+++ b/Cycript.l
@@ -126,6 +126,10 @@ Escape   \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\\n
 "@end"         L C return tk::AtEnd;
 "@selector"    L C return tk::AtSelector;
 
+"false"        L C yylval->false_ = new CYFalse(); return tk::False;
+"null"         L C yylval->null_ = new CYNull(); return tk::Null;
+"true"         L C yylval->true_ = new CYTrue(); return tk::True;
+
 "break"        L R yylval->word_ = new CYWord("break"); return tk::Break;
 "case"         L C yylval->word_ = new CYWord("case"); return tk::Case;
 "catch"        L C yylval->word_ = new CYWord("catch"); return tk::Catch;
@@ -134,7 +138,6 @@ Escape   \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\\n
 "delete"       L C yylval->word_ = new CYWord("delete"); return tk::Delete;
 "do"           L C yylval->word_ = new CYWord("do"); return tk::Do;
 "else"         L C yylval->word_ = new CYWord("else"); return tk::Else;
-"false"        L C yylval->false_ = new CYFalse(); return tk::False;
 "finally"      L C yylval->word_ = new CYWord("finally"); return tk::Finally;
 "for"          L C yylval->word_ = new CYWord("for"); return tk::For;
 "function"     L C yylval->word_ = new CYWord("function"); return tk::Function;
@@ -142,12 +145,10 @@ Escape   \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\\n
 "in"           L C yylval->word_ = new CYWord("in"); return tk::In;
 "instanceof"   L C yylval->word_ = new CYWord("instanceof"); return tk::InstanceOf;
 "new"          L C yylval->word_ = new CYWord("new"); return tk::New;
-"null"         L C yylval->null_ = new CYNull(); return tk::Null;
 "return"       L R yylval->word_ = new CYWord("return"); return tk::Return;
 "switch"       L C yylval->word_ = new CYWord("switch"); return tk::Switch;
 "this"         L C yylval->this_ = new CYThis(); return tk::This;
 "throw"        L R yylval->word_ = new CYWord("throw"); return tk::Throw;
-"true"         L C yylval->true_ = new CYTrue(); return tk::True;
 "try"          L C yylval->word_ = new CYWord("try"); return tk::Try;
 "typeof"       L C yylval->word_ = new CYWord("typeof"); return tk::TypeOf;
 "var"          L C yylval->word_ = new CYWord("var"); return tk::Var;
@@ -155,40 +156,46 @@ Escape   \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\\n
 "while"        L C yylval->word_ = new CYWord("while"); return tk::While;
 "with"         L C yylval->word_ = new CYWord("with"); return tk::With;
 
-"abstract"     L C yylval->word_ = new CYWord("abstract"); return tk::Abstract;
-"boolean"      L C yylval->word_ = new CYWord("boolean"); return tk::Boolean;
-"byte"         L C yylval->word_ = new CYWord("byte"); return tk::Byte;
-"char"         L C yylval->word_ = new CYWord("char"); return tk::Char;
-"class"        L C yylval->word_ = new CYWord("class"); return tk::Class;
-"const"        L C yylval->word_ = new CYWord("const"); return tk::Const;
 "debugger"     L C yylval->word_ = new CYWord("debugger"); return tk::Debugger;
-"double"       L C yylval->word_ = new CYWord("double"); return tk::Double;
+
+"const"        L C yylval->word_ = new CYWord("const"); return tk::Const;
+
+"class"        L C yylval->word_ = new CYWord("class"); return tk::Class;
 "enum"         L C yylval->word_ = new CYWord("enum"); return tk::Enum;
 "export"       L C yylval->word_ = new CYWord("export"); return tk::Export;
 "extends"      L C yylval->word_ = new CYWord("extends"); return tk::Extends;
-"final"        L C yylval->word_ = new CYWord("final"); return tk::Final;
-"float"        L C yylval->word_ = new CYWord("float"); return tk::Float;
-"goto"         L C yylval->word_ = new CYWord("goto"); return tk::Goto;
-"implements"   L C yylval->word_ = new CYWord("implements"); return tk::Implements;
 "import"       L C yylval->word_ = new CYWord("import"); return tk::Import;
-"int"          L C yylval->word_ = new CYWord("int"); return tk::Int;
-"interface"    L C yylval->word_ = new CYWord("interface"); return tk::Interface;
-"long"         L C yylval->word_ = new CYWord("long"); return tk::Long;
-"native"       L C yylval->word_ = new CYWord("native"); return tk::Native;
-"package"      L C yylval->word_ = new CYWord("package"); return tk::Package;
-"private"      L C yylval->word_ = new CYWord("private"); return tk::Private;
-"protected"    L C yylval->word_ = new CYWord("protected"); return tk::Protected;
-"public"       L C yylval->word_ = new CYWord("public"); return tk::Public;
-"short"        L C yylval->word_ = new CYWord("short"); return tk::Short;
-"static"       L C yylval->word_ = new CYWord("static"); return tk::Static;
 "super"        L C yylval->word_ = new CYWord("super"); return tk::Super;
-"synchronized" L C yylval->word_ = new CYWord("synchronized"); return tk::Synchronized;
-"throws"       L C yylval->word_ = new CYWord("throws"); return tk::Throws;
-"transient"    L C yylval->word_ = new CYWord("transient"); return tk::Transient;
-"volatile"     L C yylval->word_ = new CYWord("volatile"); return tk::Volatile;
 
-"each"         L C yylval->word_ = new CYIdentifier("each"); return tk::Each;
-"let"          L C yylval->word_ = new CYIdentifier("let"); return tk::Let;
+"implements"   L C yylval->identifier_ = new CYIdentifier("implements"); return tk::Implements;
+"interface"    L C yylval->identifier_ = new CYIdentifier("interface"); return tk::Interface;
+"package"      L C yylval->identifier_ = new CYIdentifier("package"); return tk::Package;
+"private"      L C yylval->identifier_ = new CYIdentifier("private"); return tk::Private;
+"protected"    L C yylval->identifier_ = new CYIdentifier("protected"); return tk::Protected;
+"public"       L C yylval->identifier_ = new CYIdentifier("public"); return tk::Public;
+"static"       L C yylval->identifier_ = new CYIdentifier("static"); return tk::Static;
+
+"abstract"     L C yylval->identifier_ = new CYIdentifier("abstract"); return tk::Abstract;
+"boolean"      L C yylval->identifier_ = new CYIdentifier("boolean"); return tk::Boolean;
+"byte"         L C yylval->identifier_ = new CYIdentifier("byte"); return tk::Byte;
+"char"         L C yylval->identifier_ = new CYIdentifier("char"); return tk::Char;
+"double"       L C yylval->identifier_ = new CYIdentifier("double"); return tk::Double;
+"final"        L C yylval->identifier_ = new CYIdentifier("final"); return tk::Final;
+"float"        L C yylval->identifier_ = new CYIdentifier("float"); return tk::Float;
+"goto"         L C yylval->identifier_ = new CYIdentifier("goto"); return tk::Goto;
+"int"          L C yylval->identifier_ = new CYIdentifier("int"); return tk::Int;
+"long"         L C yylval->identifier_ = new CYIdentifier("long"); return tk::Long;
+"native"       L C yylval->identifier_ = new CYIdentifier("native"); return tk::Native;
+"short"        L C yylval->identifier_ = new CYIdentifier("short"); return tk::Short;
+"synchronized" L C yylval->identifier_ = new CYIdentifier("synchronized"); return tk::Synchronized;
+"throws"       L C yylval->identifier_ = new CYIdentifier("throws"); return tk::Throws;
+"transient"    L C yylval->identifier_ = new CYIdentifier("transient"); return tk::Transient;
+"volatile"     L C yylval->identifier_ = new CYIdentifier("volatile"); return tk::Volatile;
+
+"let"          L C yylval->identifier_ = new CYIdentifier("let"); return tk::Let;
+"yield"        L C yylval->identifier_ = new CYIdentifier("yield"); return tk::Yield;
+
+"each"         L C yylval->identifier_ = new CYIdentifier("each"); return tk::Each;
 
 [a-zA-Z$_][a-zA-Z$_0-9]* yylval->identifier_ = new CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); L C return tk::Identifier_;
 
index 6a304b3ab9989a25ecc8db857f4d1a8f9df76c89..f1cbcfeb0a36b912cb7727b1a2a0157f8816be6d 100644 (file)
--- a/Cycript.y
+++ b/Cycript.y
@@ -107,8 +107,8 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 
 %defines
 
-%glr-parser
-%expect 1
+//%glr-parser
+//%expect 1
 
 %debug
 
@@ -178,6 +178,11 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 %token AtSelector "@selector"
 %token AtEnd "@end"
 
+%token <false_> False "false"
+%token <null_> Null "null"
+%token <true_> True "true"
+
+// ES3/ES5/WIE/JSC Reserved
 %token <word_> Break "break"
 %token <word_> Case "case"
 %token <word_> Catch "catch"
@@ -186,7 +191,6 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 %token <word_> Delete "delete"
 %token <word_> Do "do"
 %token <word_> Else "else"
-%token <false_> False "false"
 %token <word_> Finally "finally"
 %token <word_> For "for"
 %token <word_> Function "function"
@@ -194,12 +198,10 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 %token <word_> In "in"
 %token <word_> InstanceOf "instanceof"
 %token <word_> New "new"
-%token <null_> Null "null"
 %token <word_> Return "return"
 %token <word_> Switch "switch"
 %token <this_> This "this"
 %token <word_> Throw "throw"
-%token <true_> True "true"
 %token <word_> Try "try"
 %token <word_> TypeOf "typeof"
 %token <word_> Var "var"
@@ -207,40 +209,53 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 %token <word_> While "while"
 %token <word_> With "with"
 
-%token <word_> Abstract "abstract"
-%token <word_> Boolean "boolean"
-%token <word_> Byte "byte"
-%token <word_> Char "char"
-%token <word_> Class "class"
-%token <word_> Const "const"
+// ES3/IE6 Future, ES5/JSC Reserved
 %token <word_> Debugger "debugger"
-%token <word_> Double "double"
+
+// ES3/ES5/IE6 Future, JSC Reserved
+%token <word_> Const "const"
+
+// ES3/ES5/IE6/JSC Future
+%token <word_> Class "class"
 %token <word_> Enum "enum"
 %token <word_> Export "export"
 %token <word_> Extends "extends"
-%token <word_> Final "final"
-%token <word_> Float "float"
-%token <word_> Goto "goto"
-%token <word_> Implements "implements"
 %token <word_> Import "import"
-%token <word_> Int "int"
-%token <word_> Interface "interface"
-%token <word_> Long "long"
-%token <word_> Native "native"
-%token <word_> Package "package"
-%token <word_> Private "private"
-%token <word_> Protected "protected"
-%token <word_> Public "public"
-%token <word_> Short "short"
-%token <word_> Static "static"
 %token <word_> Super "super"
-%token <word_> Synchronized "synchronized"
-%token <word_> Throws "throws"
-%token <word_> Transient "transient"
-%token <word_> Volatile "volatile"
 
-%token <identifier_> Each "each"
+// ES3 Future, ES5 Strict Future
+%token <identifier_> Implements "implements"
+%token <identifier_> Interface "interface"
+%token <identifier_> Package "package"
+%token <identifier_> Private "private"
+%token <identifier_> Protected "protected"
+%token <identifier_> Public "public"
+%token <identifier_> Static "static"
+
+// ES3 Future
+%token <identifier_> Abstract "abstract"
+%token <identifier_> Boolean "boolean"
+%token <identifier_> Byte "byte"
+%token <identifier_> Char "char"
+%token <identifier_> Double "double"
+%token <identifier_> Final "final"
+%token <identifier_> Float "float"
+%token <identifier_> Goto "goto"
+%token <identifier_> Int "int"
+%token <identifier_> Long "long"
+%token <identifier_> Native "native"
+%token <identifier_> Short "short"
+%token <identifier_> Synchronized "synchronized"
+%token <identifier_> Throws "throws"
+%token <identifier_> Transient "transient"
+%token <identifier_> Volatile "volatile"
+
+// ES5 Strict
 %token <identifier_> Let "let"
+%token <identifier_> Yield "yield"
+
+// Woah?!
+%token <identifier_> Each "each"
 
 %token <identifier_> Identifier_
 %token <number_> NumericLiteral
@@ -335,7 +350,7 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 %type <statement_> LabelledStatement
 %type <expression_> LeftHandSideExpression
 %type <expression_> LeftHandSideExpressionNoBF
-%type <statement_> LetStatement
+//%type <statement_> LetStatement
 %type <literal_> Literal
 %type <expression_> LogicalANDExpression
 %type <expression_> LogicalANDExpressionNoBF
@@ -459,13 +474,9 @@ WordOpt
 
 Word
     : Identifier { $$ = $1; }
-    | "abstract" { $$ = $1; }
-    | "boolean" { $$ = $1; }
     | "break" NewLineOpt { $$ = $1; }
-    | "byte" { $$ = $1; }
     | "case" { $$ = $1; }
     | "catch" { $$ = $1; }
-    | "char" { $$ = $1; }
     | "class" { $$ = $1; }
     | "const" { $$ = $1; }
     | "continue" NewLineOpt { $$ = $1; }
@@ -473,57 +484,66 @@ Word
     | "default" { $$ = $1; }
     | "delete" { $$ = $1; }
     | "do" { $$ = $1; }
-    | "double" { $$ = $1; }
     | "else" { $$ = $1; }
     | "enum" { $$ = $1; }
     | "export" { $$ = $1; }
     | "extends" { $$ = $1; }
     | "false" { $$ = $1; }
-    | "final" { $$ = $1; }
     | "finally" { $$ = $1; }
-    | "float" { $$ = $1; }
     | "for" { $$ = $1; }
     | "function" { $$ = $1; }
-    | "goto" { $$ = $1; }
     | "if" { $$ = $1; }
-    | "implements" { $$ = $1; }
     | "import" { $$ = $1; }
     /* XXX: | "in" { $$ = $1; } */
     /* XXX: | "instanceof" { $$ = $1; } */
-    | "int" { $$ = $1; }
-    | "interface" { $$ = $1; }
-    | "long" { $$ = $1; }
-    | "native" { $$ = $1; }
     | "new" { $$ = $1; }
     | "null" { $$ = $1; }
-    | "package" { $$ = $1; }
-    | "private" { $$ = $1; }
-    | "protected" { $$ = $1; }
-    | "public" { $$ = $1; }
     | "return" NewLineOpt { $$ = $1; }
-    | "short" { $$ = $1; }
-    | "static" { $$ = $1; }
     | "super" { $$ = $1; }
     | "switch" { $$ = $1; }
-    | "synchronized" { $$ = $1; }
     | "this" { $$ = $1; }
     | "throw" NewLineOpt { $$ = $1; }
-    | "throws" { $$ = $1; }
-    | "transient" { $$ = $1; }
     | "true" { $$ = $1; }
     | "try" { $$ = $1; }
     | "typeof" { $$ = $1; }
     | "var" { $$ = $1; }
     | "void" { $$ = $1; }
-    | "volatile" { $$ = $1; }
     | "while" { $$ = $1; }
     | "with" { $$ = $1; }
     ;
 
 Identifier
     : Identifier_ { $$ = $1; }
-    | "each" { $$ = $1; }
+
+    | "implements" { $$ = $1; }
+    | "interface" { $$ = $1; }
+    | "package" { $$ = $1; }
+    | "private" { $$ = $1; }
+    | "protected" { $$ = $1; }
+    | "public" { $$ = $1; }
+    | "static" { $$ = $1; }
+
+    | "abstract" { $$ = $1; }
+    | "boolean" { $$ = $1; }
+    | "byte" { $$ = $1; }
+    | "char" { $$ = $1; }
+    | "double" { $$ = $1; }
+    | "final" { $$ = $1; }
+    | "float" { $$ = $1; }
+    | "goto" { $$ = $1; }
+    | "int" { $$ = $1; }
+    | "long" { $$ = $1; }
+    | "native" { $$ = $1; }
+    | "short" { $$ = $1; }
+    | "synchronized" { $$ = $1; }
+    | "throws" { $$ = $1; }
+    | "transient" { $$ = $1; }
+    | "volatile" { $$ = $1; }
+
     | "let" { $$ = $1; }
+    | "yield" { $$ = $1; }
+
+    | "each" { $$ = $1; }
     ;
 
 IdentifierOpt
@@ -1384,7 +1404,7 @@ ForInStatement
     : "for" "each" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = new(driver.pool_) CYForEachIn($4, $6, $8); }
     ;
 /* }}} */
-/* JavaScript 1.7: Let Statements {{{ */
+/* JavaScript 1.7: Let Statements {{{ *//*
 LetStatement
     : "let" "(" VariableDeclarationList ")" Block_ { $$ = new(driver.pool_) CYLet($3, $5); }
     ;
@@ -1392,6 +1412,6 @@ LetStatement
 Statement
     : LetStatement
     ;
-/* }}} */
+*//* }}} */
 
 %%
index 61eafe18caa5bf1e2856b2b8e34275934df3320c..b550bf5a290c7d39600b49a4ca3872c46d6bebe8 100644 (file)
@@ -756,10 +756,17 @@ size_t CYGetIndex(const char *value) {
     return _not(size_t);
 }
 
+// XXX: fix this
+static const char *CYPoolCString(apr_pool_t *pool, JSStringRef value);
+
 size_t CYGetIndex(apr_pool_t *pool, NSString *value) {
     return CYGetIndex(CYPoolCString(pool, value));
 }
 
+size_t CYGetIndex(apr_pool_t *pool, JSStringRef value) {
+    return CYGetIndex(CYPoolCString(pool, value));
+}
+
 bool CYGetOffset(const char *value, ssize_t &index) {
     if (value[0] != '0') {
         char *end;
@@ -1730,23 +1737,24 @@ struct CYInternal :
     }
 };
 
-JSObjectRef CYMakeSelector(JSContextRef context, SEL sel) {
+static JSObjectRef CYMakeSelector(JSContextRef context, SEL sel) {
     Selector_privateData *internal(new Selector_privateData(sel));
     return JSObjectMake(context, Selector_, internal);
 }
 
-JSObjectRef CYMakePointer(JSContextRef context, void *pointer, sig::Type *type, ffi_type *ffi, JSObjectRef owner) {
+static JSObjectRef CYMakePointer(JSContextRef context, void *pointer, sig::Type *type, ffi_type *ffi, JSObjectRef owner) {
     Pointer *internal(new Pointer(pointer, context, owner, type));
     return JSObjectMake(context, Pointer_, internal);
 }
 
-JSObjectRef CYMakeFunctor(JSContextRef context, void (*function)(), const char *type) {
+static JSObjectRef CYMakeFunctor(JSContextRef context, void (*function)(), const char *type) {
     Functor_privateData *internal(new Functor_privateData(type, function));
     return JSObjectMake(context, Functor_, internal);
 }
 
-const char *CYPoolCString(apr_pool_t *pool, JSStringRef value) {
+static const char *CYPoolCString(apr_pool_t *pool, JSStringRef value) {
     if (pool == NULL) {
+        // XXX: this could be much more efficient
         const char *string([CYCastNSString(NULL, value) UTF8String]);
         return string;
     } else {
@@ -1757,11 +1765,11 @@ const char *CYPoolCString(apr_pool_t *pool, JSStringRef value) {
     }
 }
 
-const char *CYPoolCString(apr_pool_t *pool, JSContextRef context, JSValueRef value) {
+static const char *CYPoolCString(apr_pool_t *pool, JSContextRef context, JSValueRef value) {
     return JSValueIsNull(context, value) ? NULL : CYPoolCString(pool, CYJSString(context, value));
 }
 
-bool CYGetOffset(apr_pool_t *pool, JSStringRef value, ssize_t &index) {
+static bool CYGetOffset(apr_pool_t *pool, JSStringRef value, ssize_t &index) {
     return CYGetOffset(CYPoolCString(pool, value), index);
 }
 
@@ -1780,7 +1788,7 @@ bool CYGetOffset(apr_pool_t *pool, JSStringRef value, ssize_t &index) {
     utf8; \
 })
 
-void *CYCastPointer_(JSContextRef context, JSValueRef value) {
+static void *CYCastPointer_(JSContextRef context, JSValueRef value) {
     switch (JSValueGetType(context, value)) {
         case kJSTypeNull:
             return NULL;
@@ -1800,11 +1808,11 @@ void *CYCastPointer_(JSContextRef context, JSValueRef value) {
 }
 
 template <typename Type_>
-_finline Type_ CYCastPointer(JSContextRef context, JSValueRef value) {
+static _finline Type_ CYCastPointer(JSContextRef context, JSValueRef value) {
     return reinterpret_cast<Type_>(CYCastPointer_(context, value));
 }
 
-SEL CYCastSEL(JSContextRef context, JSValueRef value) {
+static SEL CYCastSEL(JSContextRef context, JSValueRef value) {
     if (JSValueIsObjectOfClass(context, value, Selector_)) {
         Selector_privateData *internal(reinterpret_cast<Selector_privateData *>(JSObjectGetPrivate((JSObjectRef) value)));
         return reinterpret_cast<SEL>(internal->value_);
@@ -1812,7 +1820,7 @@ SEL CYCastSEL(JSContextRef context, JSValueRef value) {
         return CYCastPointer<SEL>(context, value);
 }
 
-void CYPoolFFI(apr_pool_t *pool, JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, JSValueRef value) {
+static void CYPoolFFI(apr_pool_t *pool, JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, JSValueRef value) {
     switch (type->primitive) {
         case sig::boolean_P:
             *reinterpret_cast<bool *>(data) = JSValueToBoolean(context, value);
@@ -1890,7 +1898,7 @@ void CYPoolFFI(apr_pool_t *pool, JSContextRef context, sig::Type *type, ffi_type
     }
 }
 
-JSValueRef CYFromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, bool initialize = false, JSObjectRef owner = NULL) {
+static JSValueRef CYFromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, bool initialize = false, JSObjectRef owner = NULL) {
     JSValueRef value;
 
     switch (type->primitive) {
@@ -1980,7 +1988,7 @@ static bool CYImplements(id object, Class _class, SEL selector, bool devoid) {
     return false;
 }
 
-const char *CYPoolTypeEncoding(apr_pool_t *pool, Class _class, SEL sel, Method method) {
+static const char *CYPoolTypeEncoding(apr_pool_t *pool, Class _class, SEL sel, Method method) {
     if (method != NULL)
         return method_getTypeEncoding(method);
     else if (NSString *type = [[Bridge_ objectAtIndex:1] objectForKey:CYCastNSString(pool, sel_getName(sel))])
@@ -1989,7 +1997,7 @@ const char *CYPoolTypeEncoding(apr_pool_t *pool, Class _class, SEL sel, Method m
         return NULL;
 }
 
-void FunctionClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
+static void FunctionClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
     Closure_privateData *internal(reinterpret_cast<Closure_privateData *>(arg));
 
     JSContextRef context(internal->context_);
@@ -2004,7 +2012,7 @@ void FunctionClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
     CYPoolFFI(NULL, context, internal->signature_.elements[0].type, internal->cif_.rtype, result, value);
 }
 
-void MessageClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
+static void MessageClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
     Closure_privateData *internal(reinterpret_cast<Closure_privateData *>(arg));
 
     JSContextRef context(internal->context_);
@@ -2021,7 +2029,7 @@ void MessageClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
     CYPoolFFI(NULL, context, internal->signature_.elements[0].type, internal->cif_.rtype, result, value);
 }
 
-Closure_privateData *CYMakeFunctor_(JSContextRef context, JSObjectRef function, const char *type, void (*callback)(ffi_cif *, void *, void **, void *)) {
+static Closure_privateData *CYMakeFunctor_(JSContextRef context, JSObjectRef function, const char *type, void (*callback)(ffi_cif *, void *, void **, void *)) {
     // XXX: in case of exceptions this will leak
     // XXX: in point of fact, this may /need/ to leak :(
     Closure_privateData *internal(new Closure_privateData(CYGetJSContext(), function, type));
@@ -2042,7 +2050,7 @@ Closure_privateData *CYMakeFunctor_(JSContextRef context, JSObjectRef function,
     return internal;
 }
 
-JSObjectRef CYMakeFunctor(JSContextRef context, JSObjectRef function, const char *type) {
+static JSObjectRef CYMakeFunctor(JSContextRef context, JSObjectRef function, const char *type) {
     Closure_privateData *internal(CYMakeFunctor_(context, function, type, &FunctionClosure_));
     return JSObjectMake(context, Functor_, internal);
 }
@@ -2328,7 +2336,7 @@ static JSObjectRef Instance_callAsConstructor(JSContextRef context, JSObjectRef
     } CYCatch
 }
 
-bool CYIsClass(id self) {
+static bool CYIsClass(id self) {
     // XXX: this is a lame object_isClass
     return class_getInstanceMethod(object_getClass(self), @selector(alloc)) != NULL;
 }
@@ -2424,7 +2432,7 @@ static JSValueRef Internal_callAsFunction_$cya(JSContextRef context, JSObjectRef
     return internal->GetOwner();
 }
 
-bool Index_(apr_pool_t *pool, Struct_privateData *internal, JSStringRef property, ssize_t &index, uint8_t *&base) {
+static bool Index_(apr_pool_t *pool, Struct_privateData *internal, JSStringRef property, ssize_t &index, uint8_t *&base) {
     Type_privateData *typical(internal->type_);
     sig::Type *type(typical->type_);
     if (type == NULL)
@@ -2739,6 +2747,16 @@ static void ObjectiveC_Protocols_getPropertyNames(JSContextRef context, JSObject
     free(data);
 }
 
+static JSObjectRef CYMakeType(JSContextRef context, const char *type) {
+    Type_privateData *internal(new Type_privateData(NULL, type));
+    return JSObjectMake(context, Type_, internal);
+}
+
+static JSObjectRef CYMakeType(JSContextRef context, sig::Type *type) {
+    Type_privateData *internal(new Type_privateData(type));
+    return JSObjectMake(context, Type_, internal);
+}
+
 static JSValueRef Runtime_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
     if (JSStringIsEqualToUTF8CString(property, "nil"))
         return Instance::Make(context, nil);
@@ -2762,11 +2780,17 @@ static JSValueRef Runtime_getProperty(JSContextRef context, JSObjectRef object,
                     sig::sig_ffi_cif(pool, &sig::ObjectiveC, &signature, &cif);
                     return CYFromFFI(context, signature.elements[0].type, cif.rtype, [name cy$symbol]);
             }
+        if (NSMutableArray *entry = [[Bridge_ objectAtIndex:2] objectForKey:name])
+            switch ([[entry objectAtIndex:0] intValue]) {
+                // XXX: implement case 0
+                case 1:
+                    return CYMakeType(context, CYPoolCString(pool, [entry objectAtIndex:1]));
+            }
         return NULL;
     } CYCatch
 }
 
-bool stret(ffi_type *ffi_type) {
+static bool stret(ffi_type *ffi_type) {
     return ffi_type->type == FFI_TYPE_STRUCT && (
         ffi_type->size > OBJC_MAX_STRUCT_BY_VALUE ||
         struct_forward_array[ffi_type->size] != 0
@@ -2918,7 +2942,7 @@ static JSValueRef Functor_callAsFunction(JSContextRef context, JSObjectRef objec
     return CYCallFunction(pool, context, 0, NULL, count, arguments, false, exception, &internal->signature_, &internal->cif_, internal->GetValue());
 }
 
-JSObjectRef Selector_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+static JSObjectRef Selector_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
     CYTry {
         if (count != 1)
             @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Selector constructor" userInfo:nil];
@@ -2927,7 +2951,7 @@ JSObjectRef Selector_new(JSContextRef context, JSObjectRef object, size_t count,
     } CYCatch
 }
 
-JSObjectRef Pointer_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+static JSObjectRef Pointer_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
     CYTry {
         if (count != 2)
             @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Functor constructor" userInfo:nil];
@@ -2944,25 +2968,47 @@ JSObjectRef Pointer_new(JSContextRef context, JSObjectRef object, size_t count,
     } CYCatch
 }
 
-JSObjectRef CYMakeType(JSContextRef context, JSObjectRef object, const char *type) {
-    Type_privateData *internal(new Type_privateData(NULL, type));
-    return JSObjectMake(context, Type_, internal);
-}
-
-JSObjectRef Type_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+static JSObjectRef Type_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
     CYTry {
         if (count != 1)
             @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Type constructor" userInfo:nil];
         const char *type(CYCastCString(context, arguments[0]));
-        return CYMakeType(context, object, type);
+        return CYMakeType(context, type);
+    } CYCatch
+}
+
+static JSValueRef Type_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
+    Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(object)));
+
+    CYTry {
+        sig::Type type;
+
+        if (JSStringIsEqualToUTF8CString(property, "$cyi")) {
+            type.primitive = sig::pointer_P;
+            type.data.data.size = 0;
+        } else {
+            size_t index(CYGetIndex(NULL, property));
+            if (index == _not(size_t))
+                return NULL;
+            type.primitive = sig::array_P;
+            type.data.data.size = index;
+        }
+
+        type.name = NULL;
+        type.flags = 0;
+
+        type.data.data.type = internal->type_;
+
+        return CYMakeType(context, &type);
     } CYCatch
 }
 
 static JSValueRef Type_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+    Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(object)));
+
     CYTry {
         if (count != 1)
             @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to type cast function" userInfo:nil];
-        Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(object)));
         sig::Type *type(internal->type_);
         ffi_type *ffi(internal->GetFFI());
         // XXX: alignment?
@@ -2975,17 +3021,26 @@ static JSValueRef Type_callAsFunction(JSContextRef context, JSObjectRef object,
 
 static JSObjectRef Type_callAsConstructor(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
     CYTry {
-        if (count > 1)
+        if (count != 0)
             @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to type cast function" userInfo:nil];
         Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(object)));
-        size_t size(count == 0 ? 0 : CYCastDouble(context, arguments[0]));
-        // XXX: alignment?
-        void *value(malloc(internal->GetFFI()->size * size));
-        return CYMakePointer(context, value, internal->type_, internal->ffi_, NULL);
+
+        sig::Type *type(internal->type_);
+        size_t size;
+
+        if (type->primitive != sig::array_P)
+            size = 0;
+        else {
+            size = type->data.data.size;
+            type = type->data.data.type;
+        }
+
+        void *value(malloc(internal->GetFFI()->size));
+        return CYMakePointer(context, value, type, NULL, NULL);
     } CYCatch
 }
 
-JSObjectRef Instance_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+static JSObjectRef Instance_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
     CYTry {
         if (count > 1)
             @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Instance constructor" userInfo:nil];
@@ -2994,7 +3049,7 @@ JSObjectRef Instance_new(JSContextRef context, JSObjectRef object, size_t count,
     } CYCatch
 }
 
-JSObjectRef Functor_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+static JSObjectRef Functor_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
     CYTry {
         if (count != 2)
             @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Functor constructor" userInfo:nil];
@@ -3003,7 +3058,7 @@ JSObjectRef Functor_new(JSContextRef context, JSObjectRef object, size_t count,
     } CYCatch
 }
 
-JSValueRef CYValue_getProperty_value(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
+static JSValueRef CYValue_getProperty_value(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
     CYValue *internal(reinterpret_cast<CYValue *>(JSObjectGetPrivate(object)));
     return CYCastJSValue(context, reinterpret_cast<uintptr_t>(internal->value_));
 }
@@ -3328,7 +3383,7 @@ bool CYSendAll_(int socket, const uint8_t *data, size_t size) {
     return true;
 }
 
-apr_pool_t *Pool_;
+static apr_pool_t *Pool_;
 
 struct CYExecute_ {
     apr_pool_t *pool_;
@@ -3536,7 +3591,7 @@ JSGlobalContextRef CYGetJSContext() {
         definition = kJSClassDefinitionEmpty;
         definition.className = "Type";
         definition.staticFunctions = Type_staticFunctions;
-        //definition.getProperty = &Type_getProperty;
+        definition.getProperty = &Type_getProperty;
         definition.callAsFunction = &Type_callAsFunction;
         definition.callAsConstructor = &Type_callAsConstructor;
         definition.finalize = &Finalize;
index 7092dda239a90d100bfd9b1a3d1e1f3e4fed4aee..b38d652f27217af5e3a4e952a2b69cecbacc2d79 100644 (file)
@@ -79,10 +79,23 @@ ffi_type *ObjectiveC(apr_pool_t *pool, struct Type *type) {
         case ulonglong_P: return &ffi_type_ulonglong;
         case ushort_P: return &ffi_type_ushort;
 
-        case array_P:
-            /* XXX: implement */
-            _assert(false);
-        break;
+        case array_P: {
+            // XXX: this is really lame
+            ffi_type *aggregate(reinterpret_cast<ffi_type *>(apr_palloc(pool, sizeof(ffi_type))));
+            aggregate->size = 0;
+            aggregate->alignment = 0;
+            aggregate->type = FFI_TYPE_STRUCT;
+
+            ffi_type *element(ObjectiveC(pool, type->data.data.type));
+            size_t size(type->data.data.size);
+
+            aggregate->elements = reinterpret_cast<ffi_type **>(apr_palloc(pool, (size + 1) * sizeof(ffi_type *)));
+            for (size_t i(0); i != size; ++i)
+                aggregate->elements[i] = element;
+            aggregate->elements[size] = NULL;
+
+            return aggregate;
+        } break;
 
         case pointer_P: return &ffi_type_pointer;
 
@@ -102,7 +115,7 @@ ffi_type *ObjectiveC(apr_pool_t *pool, struct Type *type) {
         case void_P: return &ffi_type_void;
 
         case struct_P: {
-            ffi_type *aggregate = reinterpret_cast<ffi_type *>(apr_palloc(pool, sizeof(ffi_type)));
+            ffi_type *aggregate(reinterpret_cast<ffi_type *>(apr_palloc(pool, sizeof(ffi_type))));
             aggregate->size = 0;
             aggregate->alignment = 0;
             aggregate->type = FFI_TYPE_STRUCT;