X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/fd9856445e11b3740edc0dfc8caff92b1522af80..cde525f7e0bded621b0c3f39dfbbc5f49e067dac:/Library.mm?ds=sidebyside diff --git a/Library.mm b/Library.mm index 16db5d0..b4eb9f5 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 @@ -71,6 +63,11 @@ #include #include +#include +#include + +#include "Parser.hpp" +#include "Cycript.tab.hh" #undef _assert #undef _trace @@ -84,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_; @@ -195,6 +113,7 @@ JSObjectRef CYMakeObject(JSContextRef context, id object) { @end @interface NSObject (Cycript) +- (bool) cy$isUndefined; - (NSString *) cy$toJSON; - (JSValueRef) cy$JSValueInContext:(JSContextRef)context; @end @@ -209,6 +128,10 @@ JSObjectRef CYMakeObject(JSContextRef context, id object) { @implementation NSObject (Cycript) +- (bool) cy$isUndefined { + return false; +} + - (NSString *) cy$toJSON { return [self description]; } @@ -221,6 +144,10 @@ JSObjectRef CYMakeObject(JSContextRef context, id object) { @implementation WebUndefined (Cycript) +- (bool) cy$isUndefined { + return true; +} + - (NSString *) cy$toJSON { return @"undefined"; } @@ -243,7 +170,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:@"]"]; @@ -256,8 +188,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) { @@ -343,7 +274,7 @@ JSObjectRef CYMakeObject(JSContextRef context, id object) { @end -JSContextRef JSGetContext() { +JSContextRef CYGetJSContext() { return Context_; } @@ -386,22 +317,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_); } @@ -415,7 +346,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) { @@ -498,7 +429,7 @@ void CYThrow(JSContextRef context, id error, JSValueRef *exception) { - (id) objectForKey:(id)key { JSValueRef exception(NULL); - JSValueRef value(JSObjectGetProperty(context_, object_, CYString(key), &exception)); + JSValueRef value(JSObjectGetProperty(context_, object_, CYJSString(key), &exception)); CYThrow(context_, exception); return CYCastNSObject(context_, value); } @@ -512,14 +443,14 @@ 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); + JSObjectSetProperty(context_, object_, CYJSString(key), CYCastJSValue(context_, object), kJSPropertyAttributeNone, &exception); CYThrow(context_, exception); } - (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); } @@ -551,7 +482,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]); } @@ -579,13 +510,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); @@ -706,7 +637,7 @@ JSObjectRef CYMakeFunction(JSContextRef context, void *function, const char *typ void CYSetProperty(JSContextRef context, JSObjectRef object, const char *name, JSValueRef value) { JSValueRef exception(NULL); - JSObjectSetProperty(context, object, CYString(name), value, kJSPropertyAttributeNone, &exception); + JSObjectSetProperty(context, object, CYJSString(name), value, kJSPropertyAttributeNone, &exception); CYThrow(context, exception); } @@ -719,7 +650,7 @@ 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 @@ -860,7 +791,7 @@ JSValueRef CYFromFFI(JSContextRef context, sig::Type *type, void *data) { case sig::string_P: { if (char *utf8 = *reinterpret_cast(data)) - value = JSValueMakeString(context, CYString(utf8)); + value = JSValueMakeString(context, CYJSString(utf8)); else goto null; } break; @@ -913,7 +844,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: @@ -989,47 +920,25 @@ static JSStaticValue Pointer_staticValues[2] = { {NULL, NULL, NULL, 0} }; -void CYConsole(FILE *fin, FILE *fout, FILE *ferr) { - std::string line; - - __gnu_cxx::stdio_filebuf bin(fin, std::ios::in); - std::istream sin(&bin); - - for (;;) { _pooled - fputs(">>> ", fout); - fflush(fout); - - if (!std::getline(sin, line)) - break; - - 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; - } +CYDriver::CYDriver(const std::string &filename) : + state_(CYClear), + data_(NULL), + size_(0), + filename_(filename), + source_(NULL) +{ + ScannerInit(); +} - fputs([reinterpret_cast(json) UTF8String], fout); - CFRelease(json); +CYDriver::~CYDriver() { + ScannerDestroy(); +} - fputs("\n", fout); - fflush(fout); - } - } +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 @@ -1093,7 +1002,7 @@ MSInitialize { _pooled CYSetProperty(context, global, "ffi", JSObjectMakeConstructor(context, Functor_, &ffi)); - CYSetProperty(context, global, "objc_msgSend", JSObjectMakeFunctionWithCallback(context, CYString("objc_msgSend"), &$objc_msgSend)); + CYSetProperty(context, global, "objc_msgSend", JSObjectMakeFunctionWithCallback(context, CYJSString("objc_msgSend"), &$objc_msgSend)); Bridge_ = [[NSMutableDictionary dictionaryWithContentsOfFile:@"/usr/lib/libcycript.plist"] retain]; @@ -1102,8 +1011,8 @@ MSInitialize { _pooled length_ = JSStringCreateWithUTF8CString("length"); JSValueRef exception(NULL); - JSValueRef value(JSObjectGetProperty(JSGetContext(), global, CYString("Array"), &exception)); + JSValueRef value(JSObjectGetProperty(CYGetJSContext(), global, CYJSString("Array"), &exception)); CYThrow(context, exception); - Array_ = JSValueToObject(JSGetContext(), value, &exception); + Array_ = JSValueToObject(CYGetJSContext(), value, &exception); CYThrow(context, exception); }