Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

GC changes.

WaxClass objects created in objective-c ensure that an associated lua object exists when it's methods are called
  • Loading branch information...
commit 6d9ed44222d61ce5a00522784fb5f27903cd8065 1 parent 2dbac2e
@probablycorey authored
View
9 lib/extensions/HTTP/wax_http.m
@@ -93,15 +93,12 @@ static int request(lua_State *L) {
[urlRequest setHTTPBody:body];
wax_http_connection *connection;
-
- connection = [[wax_http_connection alloc] initWithRequest:urlRequest luaState:L];
-
- [connection autorelease];
+ connection = [[[wax_http_connection alloc] initWithRequest:urlRequest timeout:timeout luaState:L] autorelease];
connection.format = format;
-
[urlRequest release];
-
+
wax_instance_create(L, connection, NO);
+
if (pushCallback(L, WAX_HTTP_AUTH_CALLBACK_FUNCTION_NAME, 1)) {
lua_setfield(L, -2, WAX_HTTP_AUTH_CALLBACK_FUNCTION_NAME); // Set the authCallback function for the userdata
}
View
32 lib/stdlib/helpers/init.lua
@@ -17,7 +17,7 @@ function wax.alert(title, message, ...)
local alert = UIAlertView:init()
alert:setTitle(title)
alert:setMessage(message)
-
+
if not ... then
alert:addButtonWithTitle("OK")
else
@@ -25,29 +25,31 @@ function wax.alert(title, message, ...)
alert:addButtonWithTitle(name)
end
end
-
+
alert:show()
-
+
return alert
end
--- -- Forces print to use NSLog
--- function print(obj)
--- -- if there is an error, ignore it
--- pcall(function() wax.print(tostring(obj)) end)
--- end
+-- Forces print to use NSLog
+if not UIDevice:currentDevice():model():match("iPhone Simulator") then
+ function print(obj)
+ -- if there is an error, ignore it
+ pcall(function() wax.print(tostring(obj)) end)
+ end
+end
function wax.tostring(obj, ...)
- if type(obj) == "table" then
+ if type(obj) == "table" then
return table.tostring(obj)
end
-
- if ... then
- obj = string.format(tostring(obj), ...)
+
+ if ... then
+ obj = string.format(tostring(obj), ...)
else
obj = tostring(obj)
end
-
+
return obj
end
@@ -61,10 +63,10 @@ end
function wax.eval(input)
return pcall(function()
- if not input:match("=") then
+ if not input:match("=") then
input = "do return (" .. input .. ") end"
end
-
+
local code, err = loadstring(input, "REPL")
if err then
error("Syntax Error: " .. err)
View
37 lib/wax_class.m
@@ -106,9 +106,18 @@ static int __call(lua_State *L) {
class_addMethod(klass, @selector(valueForUndefinedKey:), (IMP)valueForUndefinedKey, "@@:@");
id metaclass = object_getClass(klass);
+
// So objects created in ObjC will get an associated lua object
- class_addMethod(metaclass, @selector(alloc), (IMP)alloc, "@@:");
- class_addMethod(metaclass, @selector(allocWithZone:), (IMP)allocWithZone, "@@:^{_NSZone=}");
+ // Store the original allocWithZone implementation in case something secret goes on in there.
+ // Calls to `alloc` always are end up calling `allocWithZone:` so we don't bother handling alloc here.
+ Method m = class_getInstanceMethod(metaclass, @selector(allocWithZone:));
+
+ // If we the method has already been swizzled (by the class's super, then
+ // just leave it up to the super!
+ if (method_getImplementation(m) != (IMP)allocWithZone) {
+ class_addMethod(metaclass, @selector(wax_originalAllocWithZone:), method_getImplementation(m), method_getTypeEncoding(m));
+ class_addMethod(metaclass, @selector(allocWithZone:), (IMP)allocWithZone, "@@:^{_NSZone=}");
+ }
}
wax_instance_create(L, klass, YES);
@@ -140,32 +149,12 @@ static int name(lua_State *L) {
return 1;
}
-static id alloc(id self, SEL _cmd) {
- lua_State *L = wax_currentLuaState();
-
- BEGIN_STACK_MODIFY(L);
-
- id instance = class_createInstance(self, 0);
- wax_instance_userdata *waxInstance = wax_instance_create(L, instance, NO);
- object_setInstanceVariable(instance, WAX_CLASS_INSTANCE_USERDATA_IVAR_NAME, waxInstance);
-
- END_STACK_MODIFY(L, 0);
-
- return instance;
-}
-
static id allocWithZone(id self, SEL _cmd, NSZone *zone) {
lua_State *L = wax_currentLuaState();
-
BEGIN_STACK_MODIFY(L);
- if (zone && zone != NSDefaultMallocZone()) {
- [NSException raise:@"Wax Error" format:@"Wax doesn't handle allocing in zones other than the default! (It could, we just haven't gotten around to it yet)"];
- }
-
- id instance = class_createInstance(self, 0);
- wax_instance_userdata *waxInstance = wax_instance_create(L, instance, NO);
- object_setInstanceVariable(instance, WAX_CLASS_INSTANCE_USERDATA_IVAR_NAME, waxInstance);
+ id instance = [self wax_originalAllocWithZone:zone];
+ object_setInstanceVariable(instance, WAX_CLASS_INSTANCE_USERDATA_IVAR_NAME, @"YEAP");
END_STACK_MODIFY(L, 0);
View
19 lib/wax_instance.m
@@ -250,6 +250,7 @@ void wax_instance_pushUserdata(lua_State *L, id object) {
lua_rawget(L, -2);
lua_remove(L, -2); // remove userdataTable
+
END_STACK_MODIFY(L, 1)
}
@@ -355,7 +356,7 @@ static int __gc(lua_State *L) {
lua_pushlightuserdata(L, instanceUserdata->instance);
lua_pushnil(L);
lua_rawset(L, -3);
- lua_pop(L, 1);
+ lua_pop(L, 1);
}
return 0;
@@ -527,10 +528,11 @@ static int customInitMethodClosure(lua_State *L) {
wax_instance_userdata *classInstanceUserdata = (wax_instance_userdata *)luaL_checkudata(L, 1, WAX_INSTANCE_METATABLE_NAME);
wax_instance_userdata *instanceUserdata = nil;
+ BOOL shouldRelease = NO;
if (classInstanceUserdata->isClass) {
+ shouldRelease = YES;
id instance = [classInstanceUserdata->instance alloc];
instanceUserdata = wax_instance_create(L, instance, NO);
- [instance release]; // The userdata takes care of retaining this now
lua_replace(L, 1); // replace the old userdata with the new one!
}
else {
@@ -545,6 +547,10 @@ static int customInitMethodClosure(lua_State *L) {
luaL_error(L, "Custom init method on '%s' failed.\n%s", class_getName([instanceUserdata->instance class]), errorString);
}
+ if (shouldRelease) {
+ [instanceUserdata->instance release];
+ }
+
if (lua_isnil(L, -1)) { // The init method returned nil... return the instanceUserdata instead
luaL_error(L, "Init method must return the self");
}
@@ -560,6 +566,15 @@ static int pcallUserdata(lua_State *L, id self, SEL selector, va_list args) {
if (![[NSThread currentThread] isEqual:[NSThread mainThread]]) NSLog(@"PCALLUSERDATA: OH NO SEPERATE THREAD");
+ // A WaxClass could have been created via objective-c (like via NSKeyUnarchiver)
+ // In this case, no lua object was ever associated with it, so we've got to
+ // create one.
+ if (wax_instance_isWaxClass(self)) {
+ BOOL isClass = self == [self class];
+ wax_instance_create(L, self, isClass); // If it already exists, then it will just return without doing anything
+ lua_pop(L, 1); // Pops userdata off
+ }
+
// Find the function... could be in the object or in the class
if (!wax_instance_pushFunction(L, self, selector)) {
lua_pushfstring(L, "Could not find function named \"%s\" associated with object %s(%p).(It may have been released by the GC)", selector, class_getName([self class]), self);

0 comments on commit 6d9ed44

Please sign in to comment.
Something went wrong with that request. Please try again.