*/
/* }}} */
-#define _GNU_SOURCE
-
#include <substrate.h>
#include "cycript.hpp"
#include "Pooling.hpp"
#include "Struct.hpp"
+#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFLogUtilities.h>
+#include <JavaScriptCore/JSStringRefCF.h>
+#endif
+
+#include <Foundation/Foundation.h>
#include <WebKit/WebScriptObject.h>
#include "Parser.hpp"
#include "Cycript.tab.hh"
-#include <apr-1/apr_thread_proc.h>
+#include <apr_thread_proc.h>
#undef _assert
#undef _trace
void CYThrow(JSContextRef context, JSValueRef value);
+const char *CYPoolCCYON(apr_pool_t *pool, JSContextRef context, JSValueRef value, JSValueRef *exception);
+JSStringRef CYCopyJSString(const char *value);
+
+void CYSetProperty(JSContextRef context, JSObjectRef object, JSStringRef name, JSValueRef value);
+
+JSValueRef CYCallFunction(apr_pool_t *pool, JSContextRef context, size_t setups, void *setup[], size_t count, const JSValueRef arguments[], bool initialize, JSValueRef *exception, sig::Signature *signature, ffi_cif *cif, void (*function)());
+JSValueRef CYSendMessage(apr_pool_t *pool, JSContextRef context, id self, SEL _cmd, size_t count, const JSValueRef arguments[], bool initialize, JSValueRef *exception);
+
/* JavaScript Properties {{{ */
JSValueRef CYGetProperty(JSContextRef context, JSObjectRef object, size_t index) {
JSValueRef exception(NULL);
}
/* }}} */
/* JavaScript Strings {{{ */
-JSStringRef CYCopyJSString(id value) {
- // XXX: this definition scares me; is anyone using this?!
- return value == NULL ? NULL : JSStringCreateWithCFString(reinterpret_cast<CFStringRef>([value description]));
-}
-
JSStringRef CYCopyJSString(const char *value) {
return value == NULL ? NULL : JSStringCreateWithUTF8CString(value);
}
return string_;
}
};
+/* }}} */
+/* Objective-C Strings {{{ */
+JSStringRef CYCopyJSString_(NSString *value) {
+#ifdef __APPLE__
+ return JSStringCreateWithCFString(reinterpret_cast<CFStringRef>(string));
+#else
+ return CYCopyJSString([value UTF8String]);
+#endif
+}
+
+JSStringRef CYCopyJSString(id value) {
+ if (value == nil)
+ return NULL;
+ // XXX: this definition scares me; is anyone using this?!
+ NSString *string([value description]);
+ return CYCopyJSString_(string);
+}
+#ifdef __APPLE__
CFStringRef CYCopyCFString(JSStringRef value) {
return JSStringCopyCFString(kCFAllocatorDefault, value);
}
CFStringRef CYCopyCFString(JSContextRef context, JSValueRef value) {
return CYCopyCFString(CYJSString(context, value));
}
-
+#endif
/* }}} */
static JSGlobalContextRef Context_;
static JSClassRef Runtime_;
static JSClassRef Selector_;
static JSClassRef Struct_;
-static JSClassRef Type_;
static JSClassRef ObjectiveC_Classes_;
static JSClassRef ObjectiveC_Image_Classes_;
CYValue() {
}
- CYValue(void *value) :
- value_(value)
+ CYValue(const void *value) :
+ value_(const_cast<void *>(value))
{
}
return Instance_prototype_;
// XXX: I need to think through multi-context
- typedef std::map<Class, JSValueRef> CacheMap;
+ typedef std::map<id, JSValueRef> CacheMap;
static CacheMap cache_;
JSValueRef &value(cache_[self]);
virtual ~Instance() {
if ((flags_ & Transient) == 0)
// XXX: does this handle background threads correctly?
+ // XXX: this simply does not work on the console because I'm stupid
[GetValue() performSelector:@selector(release) withObject:nil afterDelay:0];
}
if (sig::IsAggregate(rhs.primitive))
Copy(pool, lhs.data.signature, rhs.data.signature);
else {
- if (rhs.data.data.type != NULL) {
- lhs.data.data.type = new(pool) Type;
- Copy(pool, *lhs.data.data.type, *rhs.data.data.type);
+ sig::Type *&lht(lhs.data.data.type);
+ sig::Type *&rht(rhs.data.data.type);
+
+ if (rht == NULL)
+ lht = NULL;
+ else {
+ lht = new(pool) Type;
+ Copy(pool, *lht, *rht);
}
lhs.data.data.size = rhs.data.data.size;
static Type_privateData *Object;
static Type_privateData *Selector;
+ static JSClassRef Class;
+
ffi_type *ffi_;
sig::Type *type_;
- (void *) cy$symbol;
@end
+#ifdef __APPLE__
struct PropertyAttributes {
CYPool pool_;
}
};
+#endif
+#ifdef __APPLE__
NSString *NSCFType$cy$toJSON(id self, SEL sel, NSString *key) {
return [(NSString *) CFCopyDescription((CFTypeRef) self) autorelease];
}
+#endif
/* Bridge: NSArray {{{ */
@implementation NSArray (Cycript)
[json appendString:@"["];
bool comma(false);
+#ifdef __APPLE__
for (id object in self) {
+#else
+ id object;
+ for (size_t index(0), count([self count]); index != count; ++index) {
+ object = [self objectAtIndex:index];
+#endif
if (comma)
[json appendString:@","];
else
}
- (NSObject *) cy$getProperty:(NSString *)name {
- if ([name isEqualToString:@"length"])
- return [NSNumber numberWithUnsignedInteger:[self count]];
+ if ([name isEqualToString:@"length"]) {
+ NSUInteger count([self count]);
+#ifdef __APPLE__
+ return [NSNumber numberWithUnsignedInteger:count];
+#else
+ return [NSNumber numberWithUnsignedInt:count];
+#endif
+ }
size_t index(CYGetIndex(NULL, name));
if (index == _not(size_t) || index >= [self count])
[json appendString:@"{"];
bool comma(false);
+#ifdef __APPLE__
for (id key in self) {
+#else
+ NSEnumerator *keys([self keyEnumerator]);
+ while (id key = [keys nextObject]) {
+#endif
if (comma)
[json appendString:@","];
else
- (bool) cy$setProperty:(NSString *)name to:(NSObject *)value {
if ([name isEqualToString:@"length"]) {
// XXX: is this not intelligent?
- NSUInteger size([(NSNumber *)value unsignedIntegerValue]);
+ NSNumber *number(reinterpret_cast<NSNumber *>(value));
+#ifdef __APPLE__
+ NSUInteger size([number unsignedIntegerValue]);
+#else
+ NSUInteger size([number unsignedIntValue]);
+#endif
NSUInteger count([self count]);
if (size < count)
[self removeObjectsInRange:NSMakeRange(size, count - size)];
@end
-CYRange DigitRange_ (0x3ff000000000000LLU, 0x000000000000000LLU); // 0-9
-CYRange WordStartRange_(0x000001000000000LLU, 0x7fffffe87fffffeLLU); // A-Za-z_$
-CYRange WordEndRange_ (0x3ff001000000000LLU, 0x7fffffe87fffffeLLU); // A-Za-z_$0-9
-
#define CYTry \
@try
#define CYCatch \
const char *string(CYPoolCString(pool, name));
Class _class(object_getClass(self));
+#ifdef __APPLE__
if (objc_property_t property = class_getProperty(_class, string)) {
PropertyAttributes attributes(property);
SEL sel(sel_registerName(attributes.Getter()));
return CYSendMessage(pool, context, self, sel, 0, NULL, false, exception);
}
+#endif
if (SEL sel = sel_getUid(string))
if (CYImplements(self, _class, sel, true))
const char *string(CYPoolCString(pool, name));
Class _class(object_getClass(self));
+#ifdef __APPLE__
if (objc_property_t property = class_getProperty(_class, string)) {
PropertyAttributes attributes(property);
if (const char *setter = attributes.Setter()) {
return true;
}
}
+#endif
size_t length(strlen(string));
extern "C" {
int *_NSGetArgc(void);
char ***_NSGetArgv(void);
- int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);
}
static JSValueRef System_print(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
CYTry {
- NSLog(@"%s", CYCastCString(context, arguments[0]));
+ if (count == 0)
+ NSLog(@"");
+ else
+ NSLog(@"%s", CYCastCString(context, arguments[0]));
return CYJSUndefined(context);
} CYCatch
}
}
/* }}} */
+static JSValueRef Cycript_gc_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+ JSGarbageCollect(context);
+ return CYJSUndefined(context);
+}
+
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;
{NULL, NULL, 0}
};
-CYDriver::CYDriver(const std::string &filename) :
- state_(CYClear),
- data_(NULL),
- size_(0),
- file_(NULL),
- filename_(filename),
- source_(NULL)
-{
- ScannerInit();
-}
-
-CYDriver::~CYDriver() {
- ScannerDestroy();
-}
-
-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);
-}
-
void CYSetArgs(int argc, const char *argv[]) {
JSContextRef context(CYGetJSContext());
JSValueRef args[argc];
return json;
}
-bool CYRecvAll_(int socket, uint8_t *data, size_t size) {
- while (size != 0) if (size_t writ = _syscall(recv(socket, data, size, 0))) {
- data += writ;
- size -= writ;
- } else
- return false;
- return true;
-}
-
-bool CYSendAll_(int socket, const uint8_t *data, size_t size) {
- while (size != 0) if (size_t writ = _syscall(send(socket, data, size, 0))) {
- data += writ;
- size -= writ;
- } else
- return false;
- return true;
-}
-
static apr_pool_t *Pool_;
struct CYExecute_ {
json = NULL;
size = _not(size_t);
} else {
+ CYContext context(driver.pool_);
+ driver.program_->Replace(context);
std::ostringstream str;
CYOutput out(str);
- driver.source_->Show(out);
+ out << *driver.program_;
std::string code(str.str());
CYExecute_ execute = {pool, code.c_str()};
[client performSelectorOnMainThread:@selector(execute:) withObject:[NSValue valueWithPointer:&execute] waitUntilDone:YES];
definition.callAsFunction = &Type_callAsFunction;
definition.callAsConstructor = &Type_callAsConstructor;
definition.finalize = &Finalize;
- Type_ = JSClassCreate(&definition);
+ Type_privateData::Class = JSClassCreate(&definition);
definition = kJSClassDefinitionEmpty;
definition.className = "Runtime";
MSHookFunction(&objc_registerClassPair, MSHake(objc_registerClassPair));
+#ifdef __APPLE__
class_addMethod(NSCFType_, @selector(cy$toJSON:), reinterpret_cast<IMP>(&NSCFType$cy$toJSON), "@12@0:4@8");
+#endif
+
+ JSObjectRef cycript(JSObjectMake(context, NULL, NULL));
+ CYSetProperty(context, global, CYJSString("Cycript"), cycript);
+ CYSetProperty(context, cycript, CYJSString("gc"), JSObjectMakeFunctionWithCallback(context, CYJSString("gc"), &Cycript_gc_callAsFunction));
CYSetProperty(context, global, CYJSString("objc_registerClassPair"), JSObjectMakeFunctionWithCallback(context, CYJSString("objc_registerClassPair"), &objc_registerClassPair_));
CYSetProperty(context, global, CYJSString("objc_msgSend"), JSObjectMakeFunctionWithCallback(context, CYJSString("objc_msgSend"), &$objc_msgSend));