X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/a2d9403cf5757908ff5912e7312d595c88700da2..135d950ba2493a5bb0464946551786c832a00df0:/Library.mm diff --git a/Library.mm b/Library.mm index aa0b42c..0dceaea 100644 --- a/Library.mm +++ b/Library.mm @@ -40,13 +40,13 @@ #define _GNU_SOURCE #include -#include "Struct.hpp" +#include "cycript.hpp" #include "sig/parse.hpp" #include "sig/ffi_type.hpp" -#include -#include +#include "Pooling.hpp" +#include "Struct.hpp" #include @@ -54,14 +54,6 @@ #include #include -#include - -#include -#include -#include -#include -#include -#include #include @@ -74,6 +66,9 @@ #include #include +#include "Parser.hpp" +#include "Cycript.tab.hh" + #undef _assert #undef _trace @@ -86,85 +81,6 @@ CFLog(kCFLogLevelNotice, CFSTR("_trace():%u"), __LINE__); \ } while (false) -/* Objective-C Handle<> {{{ */ -template -class _H { - typedef _H This_; - - private: - Type_ *value_; - - _finline void Retain_() { - if (value_ != nil) - [value_ retain]; - } - - _finline void Clear_() { - if (value_ != nil) - [value_ release]; - } - - public: - _finline _H(const This_ &rhs) : - value_(rhs.value_ == nil ? nil : [rhs.value_ retain]) - { - } - - _finline _H(Type_ *value = NULL, bool mended = false) : - value_(value) - { - if (!mended) - Retain_(); - } - - _finline ~_H() { - Clear_(); - } - - _finline operator Type_ *() const { - return value_; - } - - _finline This_ &operator =(Type_ *value) { - if (value_ != value) { - Type_ *old(value_); - value_ = value; - Retain_(); - if (old != nil) - [old release]; - } return *this; - } -}; -/* }}} */ -/* APR Pool Helpers {{{ */ -void *operator new(size_t size, apr_pool_t *pool) { - return apr_palloc(pool, size); -} - -void *operator new [](size_t size, apr_pool_t *pool) { - return apr_palloc(pool, size); -} - -class CYPool { - private: - apr_pool_t *pool_; - - public: - CYPool() { - apr_pool_create(&pool_, NULL); - } - - ~CYPool() { - apr_pool_destroy(pool_); - } - - operator apr_pool_t *() const { - return pool_; - } -}; -/* }}} */ - -#define _pooled _H _pool([[NSAutoreleasePool alloc] init], true); static JSContextRef Context_; @@ -174,6 +90,7 @@ static JSClassRef Pointer_; static JSClassRef Selector_; static JSObjectRef Array_; +static JSObjectRef Function_; static JSStringRef name_; static JSStringRef message_; @@ -197,6 +114,7 @@ JSObjectRef CYMakeObject(JSContextRef context, id object) { @end @interface NSObject (Cycript) +- (bool) cy$isUndefined; - (NSString *) cy$toJSON; - (JSValueRef) cy$JSValueInContext:(JSContextRef)context; @end @@ -211,6 +129,10 @@ JSObjectRef CYMakeObject(JSContextRef context, id object) { @implementation NSObject (Cycript) +- (bool) cy$isUndefined { + return false; +} + - (NSString *) cy$toJSON { return [self description]; } @@ -223,6 +145,10 @@ JSObjectRef CYMakeObject(JSContextRef context, id object) { @implementation WebUndefined (Cycript) +- (bool) cy$isUndefined { + return true; +} + - (NSString *) cy$toJSON { return @"undefined"; } @@ -245,7 +171,12 @@ JSObjectRef CYMakeObject(JSContextRef context, id object) { [json appendString:@","]; else comma = true; - [json appendString:[object cy$toJSON]]; + if (![object cy$isUndefined]) + [json appendString:[object cy$toJSON]]; + else { + [json appendString:@","]; + comma = false; + } } [json appendString:@"]"]; @@ -258,8 +189,7 @@ JSObjectRef CYMakeObject(JSContextRef context, id object) { - (NSString *) cy$toJSON { NSMutableString *json([[[NSMutableString alloc] init] autorelease]); - [json appendString:@"("]; - [json appendString:@"{"]; + [json appendString:@"({"]; bool comma(false); for (id key in self) { @@ -345,7 +275,10 @@ JSObjectRef CYMakeObject(JSContextRef context, id object) { @end -JSContextRef JSGetContext() { +CYRange WordStartRange_(0x1000000000LLU,0x7fffffe87fffffeLLU); // A-Za-z_$ +CYRange WordEndRange_(0x3ff001000000000LLU,0x7fffffe87fffffeLLU); // A-Za-z_$0-9 + +JSContextRef CYGetJSContext() { return Context_; } @@ -388,22 +321,22 @@ JSStringRef CYCopyJSString(JSContextRef context, JSValueRef value) { } // XXX: this is not a safe handle -class CYString { +class CYJSString { private: JSStringRef string_; public: template - CYString(Arg0_ arg0) { + CYJSString(Arg0_ arg0) { string_ = CYCopyJSString(arg0); } template - CYString(Arg0_ arg0, Arg1_ arg1) { + CYJSString(Arg0_ arg0, Arg1_ arg1) { string_ = CYCopyJSString(arg0, arg1); } - ~CYString() { + ~CYJSString() { JSStringRelease(string_); } @@ -417,7 +350,7 @@ CFStringRef CYCopyCFString(JSStringRef value) { } CFStringRef CYCopyCFString(JSContextRef context, JSValueRef value) { - return CYCopyCFString(CYString(context, value)); + return CYCopyCFString(CYJSString(context, value)); } double CYCastDouble(JSContextRef context, JSValueRef value) { @@ -478,6 +411,26 @@ JSValueRef CYCastJSValue(JSContextRef context, id value) { return value == nil ? JSValueMakeNull(context) : [value cy$JSValueInContext:context]; } +JSObjectRef CYCastJSObject(JSContextRef context, JSValueRef value) { + JSValueRef exception(NULL); + JSObjectRef object(JSValueToObject(context, value, &exception)); + CYThrow(context, exception); + return object; +} + +JSValueRef CYGetProperty(JSContextRef context, JSObjectRef object, JSStringRef name) { + JSValueRef exception(NULL); + JSValueRef value(JSObjectGetProperty(context, object, name, &exception)); + CYThrow(context, exception); + return value; +} + +void CYSetProperty(JSContextRef context, JSObjectRef object, JSStringRef name, JSValueRef value) { + JSValueRef exception(NULL); + JSObjectSetProperty(context, object, name, value, kJSPropertyAttributeNone, &exception); + CYThrow(context, exception); +} + void CYThrow(JSContextRef context, id error, JSValueRef *exception) { *exception = CYCastJSValue(context, error); } @@ -499,10 +452,7 @@ void CYThrow(JSContextRef context, id error, JSValueRef *exception) { } - (id) objectForKey:(id)key { - JSValueRef exception(NULL); - JSValueRef value(JSObjectGetProperty(context_, object_, CYString(key), &exception)); - CYThrow(context_, exception); - return CYCastNSObject(context_, value); + return CYCastNSObject(context_, CYGetProperty(context_, object_, CYJSString(key))); } - (NSEnumerator *) keyEnumerator { @@ -513,15 +463,13 @@ void CYThrow(JSContextRef context, id error, JSValueRef *exception) { } - (void) setObject:(id)object forKey:(id)key { - JSValueRef exception(NULL); - JSObjectSetProperty(context_, object_, CYString(key), CYCastJSValue(context_, object), kJSPropertyAttributeNone, &exception); - CYThrow(context_, exception); + CYSetProperty(context_, object_, CYJSString(key), CYCastJSValue(context_, object)); } - (void) removeObjectForKey:(id)key { JSValueRef exception(NULL); // XXX: this returns a bool... throw exception, or ignore? - JSObjectDeleteProperty(context_, object_, CYString(key), &exception); + JSObjectDeleteProperty(context_, object_, CYJSString(key), &exception); CYThrow(context_, exception); } @@ -537,10 +485,7 @@ void CYThrow(JSContextRef context, id error, JSValueRef *exception) { } - (NSUInteger) count { - JSValueRef exception(NULL); - JSValueRef value(JSObjectGetProperty(context_, object_, length_, &exception)); - CYThrow(context_, exception); - return CYCastDouble(context_, value); + return CYCastDouble(context_, CYGetProperty(context_, object_, length_)); } - (id) objectAtIndex:(NSUInteger)index { @@ -553,7 +498,7 @@ void CYThrow(JSContextRef context, id error, JSValueRef *exception) { @end -CFStringRef JSValueToJSONCopy(JSContextRef context, JSValueRef value) { +CFStringRef CYCopyJSONString(JSContextRef context, JSValueRef value) { id object(CYCastNSObject(context, value)); return reinterpret_cast([(object == nil ? @"null" : [object cy$toJSON]) retain]); } @@ -581,13 +526,13 @@ static void OnData(CFSocketRef socket, CFSocketCallBackType type, CFDataRef addr JSStringRef script(JSStringCreateWithCFString(code)); CFRelease(code); - JSValueRef result(JSEvaluateScript(JSGetContext(), script, NULL, NULL, 0, NULL)); + JSValueRef result(JSEvaluateScript(CYGetJSContext(), script, NULL, NULL, 0, NULL)); JSStringRelease(script); CFHTTPMessageRef response(CFHTTPMessageCreateResponse(kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1)); CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Type"), CFSTR("application/json; charset=utf-8")); - CFStringRef json(JSValueToJSONCopy(JSGetContext(), result)); + CFStringRef json(CYCopyJSONString(CYGetJSContext(), result)); CFDataRef body(CFStringCreateExternalRepresentation(kCFAllocatorDefault, json, kCFStringEncodingUTF8, NULL)); CFRelease(json); @@ -686,6 +631,16 @@ struct selData : ptrData { } }; +JSObjectRef CYMakeSelector(JSContextRef context, SEL sel) { + selData *data(new selData(sel)); + return JSObjectMake(context, Selector_, data); +} + +JSObjectRef CYMakePointer(JSContextRef context, void *pointer) { + ptrData *data(new ptrData(pointer)); + return JSObjectMake(context, Pointer_, data); +} + static void Pointer_finalize(JSObjectRef object) { ptrData *data(reinterpret_cast(JSObjectGetPrivate(object))); apr_pool_destroy(data->pool_); @@ -701,17 +656,10 @@ JSObjectRef CYMakeFunction(JSContextRef context, void (*function)(), const char return JSObjectMake(context, Functor_, data); } - JSObjectRef CYMakeFunction(JSContextRef context, void *function, const char *type) { return CYMakeFunction(context, reinterpret_cast(function), type); } -void CYSetProperty(JSContextRef context, JSObjectRef object, const char *name, JSValueRef value) { - JSValueRef exception(NULL); - JSObjectSetProperty(context, object, CYString(name), value, kJSPropertyAttributeNone, &exception); - CYThrow(context, exception); -} - char *CYPoolCString(apr_pool_t *pool, JSStringRef value) { size_t size(JSStringGetMaximumUTF8CStringSize(value)); char *string(new(pool) char[size]); @@ -721,14 +669,12 @@ char *CYPoolCString(apr_pool_t *pool, JSStringRef value) { } char *CYPoolCString(apr_pool_t *pool, JSContextRef context, JSValueRef value) { - return CYPoolCString(pool, CYString(context, value)); + return CYPoolCString(pool, CYJSString(context, value)); } // XXX: this macro is unhygenic #define CYCastCString(context, value) ({ \ - JSValueRef exception(NULL); \ - JSStringRef string(JSValueToStringCopy(context, value, &exception)); \ - CYThrow(context, exception); \ + JSStringRef string(CYCopyJSString(context, value)); \ size_t size(JSStringGetMaximumUTF8CStringSize(string)); \ char *utf8(reinterpret_cast(alloca(size))); \ JSStringGetUTF8CString(string, utf8, size); \ @@ -842,29 +788,27 @@ JSValueRef CYFromFFI(JSContextRef context, sig::Type *type, void *data) { CYFromFFI_(double, double) case sig::object_P: - case sig::typename_P: { + case sig::typename_P: value = CYCastJSValue(context, *reinterpret_cast(data)); - } break; - - case sig::selector_P: { - if (SEL sel = *reinterpret_cast(data)) { - selData *data(new selData(sel)); - value = JSObjectMake(context, Selector_, data); - } else goto null; - } break; - - case sig::pointer_P: { - if (void *pointer = *reinterpret_cast(data)) { - ptrData *data(new ptrData(pointer)); - value = JSObjectMake(context, Pointer_, data); - } else goto null; - } break; - - case sig::string_P: { + break; + + case sig::selector_P: + if (SEL sel = *reinterpret_cast(data)) + value = CYMakeSelector(context, sel); + else goto null; + break; + + case sig::pointer_P: + if (void *pointer = *reinterpret_cast(data)) + value = CYMakePointer(context, pointer); + else goto null; + break; + + case sig::string_P: if (char *utf8 = *reinterpret_cast(data)) - value = JSValueMakeString(context, CYString(utf8)); + value = JSValueMakeString(context, CYJSString(utf8)); else goto null; - } break; + break; case sig::struct_P: goto fail; @@ -915,7 +859,7 @@ static JSValueRef Global_getProperty(JSContextRef context, JSObjectRef object, J if (NSMutableArray *entry = [Bridge_ objectForKey:name]) switch ([[entry objectAtIndex:0] intValue]) { case 0: - return JSEvaluateScript(JSGetContext(), CYString([entry objectAtIndex:1]), NULL, NULL, 0, NULL); + return JSEvaluateScript(CYGetJSContext(), CYJSString([entry objectAtIndex:1]), NULL, NULL, 0, NULL); case 1: return CYMakeFunction(context, [name cy$symbol], [[entry objectAtIndex:1] UTF8String]); case 2: @@ -966,15 +910,32 @@ static JSValueRef $objc_msgSend(JSContextRef context, JSObjectRef object, JSObje return CYCallFunction(context, count, arguments, exception, &signature, &cif, function); } -static JSValueRef ffi_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { +static JSValueRef Selector_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { + JSValueRef setup[count + 2]; + setup[0] = _this; + setup[1] = object; + memmove(setup + 2, arguments, sizeof(JSValueRef) * count); + return $objc_msgSend(context, NULL, NULL, count + 2, setup, exception); +} + +static JSValueRef Functor_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { ffiData *data(reinterpret_cast(JSObjectGetPrivate(object))); return CYCallFunction(context, count, arguments, exception, &data->signature_, &data->cif_, reinterpret_cast(data->value_)); } +JSObjectRef sel(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { + @try { + if (count != 1) + @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Selector constructor" userInfo:nil]; + const char *name(CYCastCString(context, arguments[0])); + return CYMakeSelector(context, sel_registerName(name)); + } CYCatch +} + JSObjectRef ffi(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { @try { if (count != 2) - @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to ffi constructor" userInfo:nil]; + @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Functor constructor" userInfo:nil]; void *function(CYCastPointer(context, arguments[0])); const char *type(CYCastCString(context, arguments[1])); return CYMakeFunction(context, function, type); @@ -986,279 +947,39 @@ JSValueRef Pointer_getProperty_value(JSContextRef context, JSObjectRef object, J return JSValueMakeNumber(context, reinterpret_cast(data->value_)); } +JSValueRef Selector_getProperty_prototype(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { + return Function_; +} + static JSStaticValue Pointer_staticValues[2] = { {"value", &Pointer_getProperty_value, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete}, {NULL, NULL, NULL, 0} }; -enum CYTokenType { - CYTokenBreak, CYTokenCase, CYTokenCatch, CYTokenContinue, CYTokenDefault, - CYTokenDelete, CYTokenDo, CYTokenElse, CYTokenFinally, CYTokenFor, - CYTokenFunction, CYTokenIf, CYTokenIn, CYTokenInstanceOf, CYTokenNew, - CYTokenReturn, CYTokenSwitch, CYTokenThis, CYTokenThrow, CYTokenTry, - CYTokenTypeOf, CYTokenVar, CYTokenVoid, CYTokenWhile, CYTokenWith, - - CYTokenOpenBrace, CYTokenOpenParen, CYTokenOpenBracket, - CYTokenCloseBrace, CYTokenCloseParen, CYTokenCloseBracket, - - CYTokenPeriod, CYTokenSemiColon, CYTokenComma, CYTokenLeft, CYTokenRight, - CYTokenLeftEqual, CYTokenRightEqual, CYTokenEqualEqual, CYTokenExclamationEqual, - CYTokenEqualEqualEqual, CYTokenExclamationEqualEqual, CYTokenPlus, CYTokenHyphen, - CYTokenStar, CYTokenPercent, CYTokenPlusPlus, CYTokenHyphenHyphen, CYTokenLeftLeft, - CYTokenRightRight, CYTokenRightRightRight, CYTokenAmpersand, CYTokenPipe, - CYTokenCarrot, CYTokenExclamation, CYTokenTilde, CYTokenAmpersandAmpersand, - CYTokenPipePipe, CYTokenQuestion, CYTokenColon, CYTokenEqual, CYTokenPlusEqual, - CYTokenHyphenEqual, CYTokenStarEqual, CYTokenPercentEqual, CYTokenLeftLeftEqual, - CYTokenRightRightEqual, CYTokenRightRightRightEqual, CYTokenAmpersandEqual, - CYTokenPipeEqual, CYTokenCarrotEqual, CYTokenSlash, CYTokenSlashEqual, - - CYTokenIdentifier, CYTokenLiteral -}; - -typedef std::map TokenMap; -TokenMap Tokens_; - -struct CYToken { - enum CYTokenType type_; - char *value_; - CYToken *next_; - CYToken **prev_; -}; - -struct CYExpression { -}; - -struct CYRange { - uint64_t lo_; - uint64_t hi_; - - CYRange(uint64_t lo, uint64_t hi) : - lo_(lo), hi_(hi) - { - } - - bool operator [](uint8_t value) const { - return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1; - } - - void operator()(uint8_t value) { - if (value >> 7) - return; - (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f); - } -}; - -CYRange WordStartRange_(0x1000000000LLU,0x7fffffe87fffffeLLU); // A-Za-z_$ -CYRange WordEndRange_(0x3ff001000000000LLU,0x7fffffe87fffffeLLU); // A-Za-z_$0-9 -CYRange NumberRange_(0x3ff400000000000LLU,0x100007e0100007eLLU); // 0-9.eExXA-Fa-f -CYRange PunctuationRange_(0xfc00fc6200000000LLU,0x5000000040000000LLU); // -.,;<>=!+*/%&|^~?: - -struct CStringMapLess : - std::binary_function +/*static JSStaticValue Selector_staticValues[2] = { + {"prototype", &Selector_getProperty_prototype, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete}, + {NULL, NULL, NULL, 0} +};*/ + +CYDriver::CYDriver(const std::string &filename) : + state_(CYClear), + data_(NULL), + size_(0), + filename_(filename), + source_(NULL) { - _finline bool operator ()(const char *lhs, const char *rhs) const { - return strcmp(lhs, rhs) < 0; - } -}; - -std::set OperatorWords_; - -struct CYParser { - FILE *fin_; - FILE *fout_; - - size_t capacity_; - char *data_; - - size_t offset_; - size_t size_; - - CYParser(FILE *fin, FILE *fout) : - fin_(fin), - fout_(fout), - capacity_(1024), - data_(reinterpret_cast(malloc(capacity_))), - offset_(0), - size_(0) - { - } - - ~CYParser() { - // XXX: this will not deconstruct in constructor failures - free(data_); - } - - bool ReadLine(const char *prompt) { - offset_ = 0; - data_[capacity_ - 1] = ~'\0'; - - start: - if (fout_ != NULL) { - fputs(prompt, fout_); - fputs(" ", fout_); - fflush(fout_); - } - - if (fgets(data_, capacity_, fin_) == NULL) - return false; - - check: - if (data_[capacity_ - 1] != '\0') { - size_ = strlen(data_); - if (size_ == 0) - goto start; - if (data_[size_ - 1] == '\n') { - --size_; - goto newline; - } - } else if (data_[capacity_ - 2] == '\n') { - size_ = capacity_ - 2; - newline: - data_[size_] = '\0'; - } else { - size_t capacity(capacity_ * 2); - char *data(reinterpret_cast(realloc(data_, capacity))); - _assert(data != NULL); - data_ = data; - size_ = capacity_ - 1; - capacity_ = capacity; - fgets(data_ + size_, capacity_ - size_, fin_); - goto check; - } - - return true; - } - - _finline void ScanRange(const CYRange &range) { - while (range[data_[++offset_]]); - } - - CYToken *ParseToken(apr_pool_t *pool, const char *prompt) { - char next; - - for (;;) { - if (offset_ == size_ && (prompt == NULL || !ReadLine(prompt))) - return false; - next = data_[offset_]; - if (next != ' ' && next != '\t') - break; - ++offset_; - } - - CYTokenType type; - size_t index(offset_); - - if (WordStartRange_[next]) { - ScanRange(WordEndRange_); - type = CYTokenWord; - } else if (next == '.') { - char after(data_[offset_ + 1]); - if (after >= '0' && next <= '9') - goto number; - goto punctuation; - } else if (next >= '0' && next <= '9') { - number: - ScanRange(NumberRange_); - type = CYTokenLiteral; - } else if (PunctuationRange_[next]) { - punctuation: - ScanRange(PunctuationRange_); - type = CYTokenPunctuation; - } else if (next == '"' || next == '\'') { - for (;;) { - char after(data_[++offset_]); - if (after == '\\') { - after = data_[offset_]; - _assert(after != '\0'); - if (after == 'u') { - offset_ += 4; - _assert(offset_ < size_); - } - } else if (after == next) - break; - } - - ++offset_; - type = CYTokenLiteral; - } else if (next == '(' || next == '{' || next == '[') { - ++offset_; - type = CYTokenOpen; - } else if (next == ')' || next == '}' || next == ']') { - ++offset_; - type = CYTokenClose; - } else if (next == ';') { - ++offset_; - type = CYTokenSemiColon; - } else { - printf(":( %u\n", next); - _assert(false); - } - - char *value(apr_pstrndup(pool, data_ + index, offset_ - index)); - - if (type == CYTokenWord && OperatorWords_.find(value) != OperatorWords_.end()) - type = CYTokenPunctuation; - - CYToken *token(new(pool) CYToken()); - token->type_ = type; - token->value_ = value; - token->next_ = token; - token->prev_ = &token->next_; - return token; - } - - CYToken *ParseExpression(apr_pool_t *pool, const char *prompt) { - CYToken *token(ParseToken(pool, prompt)); - return token; - } -}; - -void CYConsole(FILE *fin, FILE *fout, FILE *ferr) { - CYParser parser(fin, fout); - - for (;;) { _pooled - CYPool pool; - CYToken *token(parser.ParseExpression(pool, ">>>")); - if (token == NULL) - return; - fputs("<", fout); - CYToken *next(token); - do { - fputs(next->value_, fout); - next = next->next_; - fputs("|", fout); - } while (next != token); - fputs(">\n", fout); -#if 0 - JSStringRef script(JSStringCreateWithUTF8CString(line.c_str())); - - JSContextRef context(JSGetContext()); - - JSValueRef exception(NULL); - JSValueRef result(JSEvaluateScript(context, script, NULL, NULL, 0, &exception)); - JSStringRelease(script); - - if (exception != NULL) - result = exception; - - if (!JSValueIsUndefined(context, result)) { - CFStringRef json; - - @try { json: - json = JSValueToJSONCopy(context, result); - } @catch (id error) { - CYThrow(context, error, &result); - goto json; - } + ScannerInit(); +} - fputs([reinterpret_cast(json) UTF8String], fout); - CFRelease(json); +CYDriver::~CYDriver() { + ScannerDestroy(); +} - fputs("\n", fout); - fflush(fout); - } -#endif - } +void cy::parser::error(const cy::parser::location_type &location, const std::string &message) { + CYDriver::Error error; + error.location_ = location; + error.message_ = message; + driver.errors_.push_back(error); } MSInitialize { _pooled @@ -1296,12 +1017,14 @@ MSInitialize { _pooled definition = kJSClassDefinitionEmpty; definition.className = "Functor"; definition.parentClass = Pointer_; - definition.callAsFunction = &ffi_callAsFunction; + definition.callAsFunction = &Functor_callAsFunction; Functor_ = JSClassCreate(&definition); definition = kJSClassDefinitionEmpty; definition.className = "Selector"; definition.parentClass = Pointer_; + //definition.staticValues = Selector_staticValues; + definition.callAsFunction = &Selector_callAsFunction; Selector_ = JSClassCreate(&definition); definition = kJSClassDefinitionEmpty; @@ -1320,88 +1043,17 @@ MSInitialize { _pooled JSObjectRef global(JSContextGetGlobalObject(context)); - CYSetProperty(context, global, "ffi", JSObjectMakeConstructor(context, Functor_, &ffi)); + CYSetProperty(context, global, CYJSString("SEL"), JSObjectMakeConstructor(context, Selector_, &sel)); + CYSetProperty(context, global, CYJSString("ffi"), JSObjectMakeConstructor(context, Functor_, &ffi)); - CYSetProperty(context, global, "objc_msgSend", JSObjectMakeFunctionWithCallback(context, CYString("objc_msgSend"), &$objc_msgSend)); + CYSetProperty(context, global, CYJSString("objc_msgSend"), JSObjectMakeFunctionWithCallback(context, CYJSString("objc_msgSend"), &$objc_msgSend)); Bridge_ = [[NSMutableDictionary dictionaryWithContentsOfFile:@"/usr/lib/libcycript.plist"] retain]; - Tokens_.insert(TokenMap::value_type("break", CYTokenBreak)); - Tokens_.insert(TokenMap::value_type("case", CYTokenCase)); - Tokens_.insert(TokenMap::value_type("catch", CYTokenCatch)); - Tokens_.insert(TokenMap::value_type("continue", CYTokenContinue)); - Tokens_.insert(TokenMap::value_type("default", CYTokenDefault)); - Tokens_.insert(TokenMap::value_type("delete", CYTokenDelete)); - Tokens_.insert(TokenMap::value_type("do", CYTokenDo)); - Tokens_.insert(TokenMap::value_type("else", CYTokenElse)); - Tokens_.insert(TokenMap::value_type("finally", CYTokenFinally)); - Tokens_.insert(TokenMap::value_type("for", CYTokenFor)); - Tokens_.insert(TokenMap::value_type("function", CYTokenFunction)); - Tokens_.insert(TokenMap::value_type("if", CYTokenIf)); - Tokens_.insert(TokenMap::value_type("in", CYTokenIn)); - Tokens_.insert(TokenMap::value_type("instanceof", CYTokenInstanceOf)); - Tokens_.insert(TokenMap::value_type("new", CYTokenNew)); - Tokens_.insert(TokenMap::value_type("return", CYTokenReturn)); - Tokens_.insert(TokenMap::value_type("switch", CYTokenSwitch)); - Tokens_.insert(TokenMap::value_type("this", CYTokenThis)); - Tokens_.insert(TokenMap::value_type("throw", CYTokenThrow)); - Tokens_.insert(TokenMap::value_type("try", CYTokenTry)); - Tokens_.insert(TokenMap::value_type("typeof", CYTokenTypeOf)); - Tokens_.insert(TokenMap::value_type("var", CYTokenVar)); - Tokens_.insert(TokenMap::value_type("void", CYTokenVoid)); - Tokens_.insert(TokenMap::value_type("while", CYTokenWhile)); - Tokens_.insert(TokenMap::value_type("with", CYTokenWith)); - - Tokens_.insert(TokenMap::value_type("&", CYTokenAmpersand)); - Tokens_.insert(TokenMap::value_type("&&", CYTokenAmpersandAmpersand)); - Tokens_.insert(TokenMap::value_type("&=", CYTokenAmpersandEqual)); - Tokens_.insert(TokenMap::value_type("^", CYTokenCarrot)); - Tokens_.insert(TokenMap::value_type("^=", CYTokenCarrotEqual)); - Tokens_.insert(TokenMap::value_type(":", CYTokenColon)); - Tokens_.insert(TokenMap::value_type(",", CYTokenComma)); - Tokens_.insert(TokenMap::value_type("=", CYTokenEqual)); - Tokens_.insert(TokenMap::value_type("==", CYTokenEqualEqual)); - Tokens_.insert(TokenMap::value_type("===", CYTokenEqualEqualEqual)); - Tokens_.insert(TokenMap::value_type("!", CYTokenExclamation)); - Tokens_.insert(TokenMap::value_type("!=", CYTokenExclamationEqual)); - Tokens_.insert(TokenMap::value_type("!==", CYTokenExclamationEqualEqual)); - Tokens_.insert(TokenMap::value_type("-", CYTokenHyphen)); - Tokens_.insert(TokenMap::value_type("-=", CYTokenHyphenEqual)); - Tokens_.insert(TokenMap::value_type("--", CYTokenHyphenHyphen)); - Tokens_.insert(TokenMap::value_type("<", CYTokenLeft)); - Tokens_.insert(TokenMap::value_type("<=", CYTokenLeftEqual)); - Tokens_.insert(TokenMap::value_type("<<", CYTokenLeftLeft)); - Tokens_.insert(TokenMap::value_type("<<=", CYTokenLeftLeftEqual)); - Tokens_.insert(TokenMap::value_type("%", CYTokenPercent)); - Tokens_.insert(TokenMap::value_type("%=", CYTokenPercentEqual)); - Tokens_.insert(TokenMap::value_type(".", CYTokenPeriod)); - Tokens_.insert(TokenMap::value_type("|", CYTokenPipe)); - Tokens_.insert(TokenMap::value_type("|=", CYTokenPipeEqual)); - Tokens_.insert(TokenMap::value_type("||", CYTokenPipePipe)); - Tokens_.insert(TokenMap::value_type("+", CYTokenPlus)); - Tokens_.insert(TokenMap::value_type("+=", CYTokenPlusEqual)); - Tokens_.insert(TokenMap::value_type("++", CYTokenPlusPlus)); - Tokens_.insert(TokenMap::value_type("?", CYTokenQuestion)); - Tokens_.insert(TokenMap::value_type(">", CYTokenRight)); - Tokens_.insert(TokenMap::value_type(">=", CYTokenRightEqual)); - Tokens_.insert(TokenMap::value_type(">>", CYTokenRightRight)); - Tokens_.insert(TokenMap::value_type(">>=", CYTokenRightRightEqual)); - Tokens_.insert(TokenMap::value_type(">>>", CYTokenRightRightRight)); - Tokens_.insert(TokenMap::value_type(">>>=", CYTokenRightRightRightEqual)); - Tokens_.insert(TokenMap::value_type(";", CYTokenSemiColon)); - Tokens_.insert(TokenMap::value_type("/", CYTokenSlash)); - Tokens_.insert(TokenMap::value_type("/=", CYTokenSlashEqual)); - Tokens_.insert(TokenMap::value_type("*", CYTokenStar)); - Tokens_.insert(TokenMap::value_type("*=", CYTokenStarEqual)); - Tokens_.insert(TokenMap::value_type("~", CYTokenTilde)); - name_ = JSStringCreateWithUTF8CString("name"); message_ = JSStringCreateWithUTF8CString("message"); length_ = JSStringCreateWithUTF8CString("length"); - JSValueRef exception(NULL); - JSValueRef value(JSObjectGetProperty(JSGetContext(), global, CYString("Array"), &exception)); - CYThrow(context, exception); - Array_ = JSValueToObject(JSGetContext(), value, &exception); - CYThrow(context, exception); + Array_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Array"))); + Function_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Function"))); }