candle 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE.txt +20 -0
- data/README.md +4 -0
- data/VERSION +1 -0
- data/bin/candle +21 -0
- data/lib/candle.rb +68 -0
- data/lib/candle/command.rb +27 -0
- data/lib/candle/generators/actions.rb +183 -0
- data/lib/candle/generators/blank.rb +127 -0
- data/lib/candle/generators/cli.rb +55 -0
- data/lib/candle/generators/help.rb +47 -0
- data/lib/candle/generators/jam.rb +80 -0
- data/lib/candle/generators/lua/scripts/AppDelegate.lua +36 -0
- data/lib/candle/generators/lua/scripts/tests/init.lua +6 -0
- data/lib/candle/generators/lua/scripts/tests/someTest.lua +12 -0
- data/lib/candle/generators/lua/wax/ProtocolLoader.h +12 -0
- data/lib/candle/generators/lua/wax/bin/hammer +157 -0
- data/lib/candle/generators/lua/wax/bin/update-xibs +131 -0
- data/lib/candle/generators/lua/wax/bin/waxsim +0 -0
- data/lib/candle/generators/lua/wax/lib/build-scripts/compile-stdlib.sh +14 -0
- data/lib/candle/generators/lua/wax/lib/build-scripts/copy-scripts.sh +58 -0
- data/lib/candle/generators/lua/wax/lib/build-scripts/luac.lua +80 -0
- data/lib/candle/generators/lua/wax/lib/extensions/CGAffine/wax_CGTransform.h +12 -0
- data/lib/candle/generators/lua/wax/lib/extensions/CGAffine/wax_CGTransform.m +85 -0
- data/lib/candle/generators/lua/wax/lib/extensions/CGContext/wax_CGContext.h +12 -0
- data/lib/candle/generators/lua/wax/lib/extensions/CGContext/wax_CGContext.m +251 -0
- data/lib/candle/generators/lua/wax/lib/extensions/HTTP/wax_http.h +14 -0
- data/lib/candle/generators/lua/wax/lib/extensions/HTTP/wax_http.m +240 -0
- data/lib/candle/generators/lua/wax/lib/extensions/HTTP/wax_http_connection.h +54 -0
- data/lib/candle/generators/lua/wax/lib/extensions/HTTP/wax_http_connection.m +304 -0
- data/lib/candle/generators/lua/wax/lib/extensions/filesystem/wax_filesystem.h +9 -0
- data/lib/candle/generators/lua/wax/lib/extensions/filesystem/wax_filesystem.m +273 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/Rakefile +10 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/wax_json.c +304 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/wax_json.h +11 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl-1.0.9.tar.gz +0 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/api/yajl_common.h +85 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/api/yajl_gen.h +159 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/api/yajl_parse.h +193 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl.c +159 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_alloc.c +65 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_alloc.h +50 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_buf.c +119 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_buf.h +73 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_bytestack.h +85 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_common.h +85 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_encode.c +188 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_encode.h +50 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_gen.c +322 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_gen.h +159 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_lex.c +737 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_lex.h +133 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_parse.h +193 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_parser.c +448 -0
- data/lib/candle/generators/lua/wax/lib/extensions/json/yajl/yajl_parser.h +82 -0
- data/lib/candle/generators/lua/wax/lib/lua/lapi.c +1087 -0
- data/lib/candle/generators/lua/wax/lib/lua/lapi.h +16 -0
- data/lib/candle/generators/lua/wax/lib/lua/lauxlib.c +652 -0
- data/lib/candle/generators/lua/wax/lib/lua/lauxlib.h +174 -0
- data/lib/candle/generators/lua/wax/lib/lua/lbaselib.c +653 -0
- data/lib/candle/generators/lua/wax/lib/lua/lcode.c +839 -0
- data/lib/candle/generators/lua/wax/lib/lua/lcode.h +76 -0
- data/lib/candle/generators/lua/wax/lib/lua/ldblib.c +397 -0
- data/lib/candle/generators/lua/wax/lib/lua/ldebug.c +638 -0
- data/lib/candle/generators/lua/wax/lib/lua/ldebug.h +33 -0
- data/lib/candle/generators/lua/wax/lib/lua/ldo.c +518 -0
- data/lib/candle/generators/lua/wax/lib/lua/ldo.h +57 -0
- data/lib/candle/generators/lua/wax/lib/lua/ldump.c +164 -0
- data/lib/candle/generators/lua/wax/lib/lua/lfunc.c +174 -0
- data/lib/candle/generators/lua/wax/lib/lua/lfunc.h +34 -0
- data/lib/candle/generators/lua/wax/lib/lua/lgc.c +711 -0
- data/lib/candle/generators/lua/wax/lib/lua/lgc.h +110 -0
- data/lib/candle/generators/lua/wax/lib/lua/linit.c +38 -0
- data/lib/candle/generators/lua/wax/lib/lua/liolib.c +553 -0
- data/lib/candle/generators/lua/wax/lib/lua/llex.c +461 -0
- data/lib/candle/generators/lua/wax/lib/lua/llex.h +81 -0
- data/lib/candle/generators/lua/wax/lib/lua/llimits.h +128 -0
- data/lib/candle/generators/lua/wax/lib/lua/lmathlib.c +263 -0
- data/lib/candle/generators/lua/wax/lib/lua/lmem.c +86 -0
- data/lib/candle/generators/lua/wax/lib/lua/lmem.h +49 -0
- data/lib/candle/generators/lua/wax/lib/lua/loadlib.c +666 -0
- data/lib/candle/generators/lua/wax/lib/lua/lobject.c +214 -0
- data/lib/candle/generators/lua/wax/lib/lua/lobject.h +381 -0
- data/lib/candle/generators/lua/wax/lib/lua/lopcodes.c +102 -0
- data/lib/candle/generators/lua/wax/lib/lua/lopcodes.h +268 -0
- data/lib/candle/generators/lua/wax/lib/lua/loslib.c +243 -0
- data/lib/candle/generators/lua/wax/lib/lua/lparser.c +1339 -0
- data/lib/candle/generators/lua/wax/lib/lua/lparser.h +82 -0
- data/lib/candle/generators/lua/wax/lib/lua/lstate.c +214 -0
- data/lib/candle/generators/lua/wax/lib/lua/lstate.h +169 -0
- data/lib/candle/generators/lua/wax/lib/lua/lstring.c +111 -0
- data/lib/candle/generators/lua/wax/lib/lua/lstring.h +31 -0
- data/lib/candle/generators/lua/wax/lib/lua/lstrlib.c +869 -0
- data/lib/candle/generators/lua/wax/lib/lua/ltable.c +588 -0
- data/lib/candle/generators/lua/wax/lib/lua/ltable.h +40 -0
- data/lib/candle/generators/lua/wax/lib/lua/ltablib.c +287 -0
- data/lib/candle/generators/lua/wax/lib/lua/ltm.c +75 -0
- data/lib/candle/generators/lua/wax/lib/lua/ltm.h +54 -0
- data/lib/candle/generators/lua/wax/lib/lua/lua.h +388 -0
- data/lib/candle/generators/lua/wax/lib/lua/luaconf.h +753 -0
- data/lib/candle/generators/lua/wax/lib/lua/lualib.h +53 -0
- data/lib/candle/generators/lua/wax/lib/lua/lundump.c +227 -0
- data/lib/candle/generators/lua/wax/lib/lua/lundump.h +36 -0
- data/lib/candle/generators/lua/wax/lib/lua/lvm.c +763 -0
- data/lib/candle/generators/lua/wax/lib/lua/lvm.h +36 -0
- data/lib/candle/generators/lua/wax/lib/lua/lzio.c +82 -0
- data/lib/candle/generators/lua/wax/lib/lua/lzio.h +67 -0
- data/lib/candle/generators/lua/wax/lib/lua/print.c +227 -0
- data/lib/candle/generators/lua/wax/lib/project.rake +159 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/enums.lua +396 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/ext/http.lua +43 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/ext/init.lua +4 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/ext/number.lua +21 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/ext/string.lua +97 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/ext/table.lua +165 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/helpers/WaxServer.lua +49 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/helpers/autoload.lua +10 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/helpers/base64.lua +64 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/helpers/bit.lua +274 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/helpers/cache.lua +73 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/helpers/callback.lua +22 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/helpers/frame.lua +76 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/helpers/init.lua +78 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/helpers/pickView.lua +54 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/helpers/time.lua +102 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/init.lua +18 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/luaspec/init.lua +2 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/luaspec/luamock.lua +84 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/luaspec/luaspec.lua +377 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/repl.lua +9 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/structs.lua +11 -0
- data/lib/candle/generators/lua/wax/lib/stdlib/waxClass.lua +42 -0
- data/lib/candle/generators/lua/wax/lib/wax.h +16 -0
- data/lib/candle/generators/lua/wax/lib/wax.m +260 -0
- data/lib/candle/generators/lua/wax/lib/wax_class.h +18 -0
- data/lib/candle/generators/lua/wax/lib/wax_class.m +190 -0
- data/lib/candle/generators/lua/wax/lib/wax_gc.h +20 -0
- data/lib/candle/generators/lua/wax/lib/wax_gc.m +56 -0
- data/lib/candle/generators/lua/wax/lib/wax_helpers.h +102 -0
- data/lib/candle/generators/lua/wax/lib/wax_helpers.m +870 -0
- data/lib/candle/generators/lua/wax/lib/wax_instance.h +34 -0
- data/lib/candle/generators/lua/wax/lib/wax_instance.m +810 -0
- data/lib/candle/generators/lua/wax/lib/wax_server.h +47 -0
- data/lib/candle/generators/lua/wax/lib/wax_server.m +252 -0
- data/lib/candle/generators/lua/wax/lib/wax_stdlib.h +3 -0
- data/lib/candle/generators/lua/wax/lib/wax_struct.h +26 -0
- data/lib/candle/generators/lua/wax/lib/wax_struct.m +335 -0
- data/lib/candle/generators/templates/blank/WaxApplication.xcodeproj/project.pbxproj +836 -0
- data/lib/candle/generators/templates/blank/WaxApplication.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/lib/candle/generators/templates/blank/WaxApplication.xcodeproj/project.xcworkspace/xcuserdata/eiffel.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/lib/candle/generators/templates/blank/WaxApplication.xcodeproj/xcuserdata/eiffel.xcuserdatad/xcschemes/WaxApplication.xcscheme +86 -0
- data/lib/candle/generators/templates/blank/WaxApplication.xcodeproj/xcuserdata/eiffel.xcuserdatad/xcschemes/xcschememanagement.plist +22 -0
- data/lib/candle/generators/templates/blank/WaxApplication/Default-568h@2x.png +0 -0
- data/lib/candle/generators/templates/blank/WaxApplication/Default.png +0 -0
- data/lib/candle/generators/templates/blank/WaxApplication/Default@2x.png +0 -0
- data/lib/candle/generators/templates/blank/WaxApplication/ProtocolLoader.h +12 -0
- data/lib/candle/generators/templates/blank/WaxApplication/WaxApplication-Info.plist.tt +38 -0
- data/lib/candle/generators/templates/blank/WaxApplication/WaxApplication-Prefix.pch.tt +14 -0
- data/lib/candle/generators/templates/blank/WaxApplication/en.lproj/InfoPlist.strings +2 -0
- data/lib/candle/generators/templates/blank/WaxApplication/main.m.tt +20 -0
- data/lib/candle/tasks.rb +22 -0
- data/lib/candle/utility.rb +30 -0
- data/lib/candle/version.rb +9 -0
- data/lib/candle/view.rb +48 -0
- metadata +582 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//
|
|
2
|
+
// wax_garbage_collection.h
|
|
3
|
+
// WaxTests
|
|
4
|
+
//
|
|
5
|
+
// Created by Corey Johnson on 2/23/10.
|
|
6
|
+
// Copyright 2010 Probably Interactive. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <Foundation/Foundation.h>
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@interface wax_gc : NSObject {
|
|
13
|
+
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
+ (void)start;
|
|
17
|
+
+ (void)stop;
|
|
18
|
+
+ (void)cleanupUnusedObject;
|
|
19
|
+
|
|
20
|
+
@end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
//
|
|
2
|
+
// wax_garbage_collection.m
|
|
3
|
+
// WaxTests
|
|
4
|
+
//
|
|
5
|
+
// Created by Corey Johnson on 2/23/10.
|
|
6
|
+
// Copyright 2010 Probably Interactive. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import "wax_gc.h"
|
|
10
|
+
|
|
11
|
+
#import "lua.h"
|
|
12
|
+
#import "lauxlib.h"
|
|
13
|
+
|
|
14
|
+
#import "wax.h"
|
|
15
|
+
#import "wax_instance.h"
|
|
16
|
+
#import "wax_helpers.h"
|
|
17
|
+
|
|
18
|
+
#define WAX_GC_TIMEOUT 1
|
|
19
|
+
|
|
20
|
+
@implementation wax_gc
|
|
21
|
+
|
|
22
|
+
static NSTimer* timer = nil;
|
|
23
|
+
|
|
24
|
+
+ (void)start {
|
|
25
|
+
[timer invalidate];
|
|
26
|
+
timer = [NSTimer scheduledTimerWithTimeInterval:WAX_GC_TIMEOUT target:self selector:@selector(cleanupUnusedObject) userInfo:nil repeats:YES];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
+ (void)stop {
|
|
30
|
+
[timer invalidate];
|
|
31
|
+
timer = nil;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
+ (void)cleanupUnusedObject {
|
|
35
|
+
lua_State *L = wax_currentLuaState();
|
|
36
|
+
BEGIN_STACK_MODIFY(L)
|
|
37
|
+
|
|
38
|
+
wax_instance_pushStrongUserdataTable(L);
|
|
39
|
+
|
|
40
|
+
lua_pushnil(L); // first key
|
|
41
|
+
while (lua_next(L, -2)) {
|
|
42
|
+
wax_instance_userdata *instanceUserdata = (wax_instance_userdata *)luaL_checkudata(L, -1, WAX_INSTANCE_METATABLE_NAME);
|
|
43
|
+
lua_pop(L, 1); // pops the value, keeps the key
|
|
44
|
+
|
|
45
|
+
if (!instanceUserdata->isClass && !instanceUserdata->isSuper && [instanceUserdata->instance retainCount] <= 1) {
|
|
46
|
+
lua_pushvalue(L, -1);
|
|
47
|
+
lua_pushnil(L);
|
|
48
|
+
lua_rawset(L, -4); // Clear it!
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
END_STACK_MODIFY(L, 0);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
//
|
|
2
|
+
// wax_helpers.h
|
|
3
|
+
// Lua
|
|
4
|
+
//
|
|
5
|
+
// Created by ProbablyInteractive on 5/18/09.
|
|
6
|
+
// Copyright 2009 Probably Interactive. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <Foundation/Foundation.h>
|
|
10
|
+
#import <objc/runtime.h>
|
|
11
|
+
#import <objc/message.h>
|
|
12
|
+
|
|
13
|
+
#import "wax_instance.h"
|
|
14
|
+
|
|
15
|
+
#import "lua.h"
|
|
16
|
+
|
|
17
|
+
//#define _C_ATOM '%'
|
|
18
|
+
//#define _C_VECTOR '!'
|
|
19
|
+
//#define _C_CONST 'r'
|
|
20
|
+
|
|
21
|
+
// ENCODINGS CAN BE FOUND AT http://developer.apple.com/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html
|
|
22
|
+
#define WAX_TYPE_CHAR _C_CHR
|
|
23
|
+
#define WAX_TYPE_INT _C_INT
|
|
24
|
+
#define WAX_TYPE_SHORT _C_SHT
|
|
25
|
+
#define WAX_TYPE_UNSIGNED_CHAR _C_UCHR
|
|
26
|
+
#define WAX_TYPE_UNSIGNED_INT _C_UINT
|
|
27
|
+
#define WAX_TYPE_UNSIGNED_SHORT _C_USHT
|
|
28
|
+
|
|
29
|
+
#define WAX_TYPE_LONG _C_LNG
|
|
30
|
+
#define WAX_TYPE_LONG_LONG _C_LNG_LNG
|
|
31
|
+
#define WAX_TYPE_UNSIGNED_LONG _C_ULNG
|
|
32
|
+
#define WAX_TYPE_UNSIGNED_LONG_LONG _C_ULNG_LNG
|
|
33
|
+
#define WAX_TYPE_FLOAT _C_FLT
|
|
34
|
+
#define WAX_TYPE_DOUBLE _C_DBL
|
|
35
|
+
|
|
36
|
+
#define WAX_TYPE_C99_BOOL _C_BOOL
|
|
37
|
+
|
|
38
|
+
#define WAX_TYPE_STRING _C_CHARPTR
|
|
39
|
+
#define WAX_TYPE_VOID _C_VOID
|
|
40
|
+
#define WAX_TYPE_ARRAY _C_ARY_B
|
|
41
|
+
#define WAX_TYPE_ARRAY_END _C_ARY_E
|
|
42
|
+
#define WAX_TYPE_BITFIELD _C_BFLD
|
|
43
|
+
#define WAX_TYPE_ID _C_ID
|
|
44
|
+
#define WAX_TYPE_CLASS _C_CLASS
|
|
45
|
+
#define WAX_TYPE_SELECTOR _C_SEL
|
|
46
|
+
#define WAX_TYPE_STRUCT _C_STRUCT_B
|
|
47
|
+
#define WAX_TYPE_STRUCT_END _C_STRUCT_E
|
|
48
|
+
#define WAX_TYPE_UNION _C_UNION_B
|
|
49
|
+
#define WAX_TYPE_UNION_END _C_UNION_E
|
|
50
|
+
#define WAX_TYPE_POINTER _C_PTR
|
|
51
|
+
#define WAX_TYPE_UNKNOWN _C_UNDEF
|
|
52
|
+
|
|
53
|
+
#define WAX_PROTOCOL_TYPE_CONST 'r'
|
|
54
|
+
#define WAX_PROTOCOL_TYPE_IN 'n'
|
|
55
|
+
#define WAX_PROTOCOL_TYPE_INOUT 'N'
|
|
56
|
+
#define WAX_PROTOCOL_TYPE_OUT 'o'
|
|
57
|
+
#define WAX_PROTOCOL_TYPE_BYCOPY 'O'
|
|
58
|
+
#define WAX_PROTOCOL_TYPE_BYREF 'R'
|
|
59
|
+
#define WAX_PROTOCOL_TYPE_ONEWAY 'V'
|
|
60
|
+
|
|
61
|
+
#define BEGIN_STACK_MODIFY(L) int __startStackIndex = lua_gettop((L));
|
|
62
|
+
|
|
63
|
+
#define END_STACK_MODIFY(L, i) while(lua_gettop((L)) > (__startStackIndex + (i))) lua_remove((L), __startStackIndex + 1);
|
|
64
|
+
|
|
65
|
+
#ifndef LOG_FLAGS
|
|
66
|
+
#define LOG_FLAGS (LOG_FATAL | LOG_ERROR | LOG_DEBUG)
|
|
67
|
+
#endif
|
|
68
|
+
|
|
69
|
+
#define LOG_DEBUG 1 << 0
|
|
70
|
+
#define LOG_ERROR 1 << 1
|
|
71
|
+
#define LOG_FATAL 1 << 2
|
|
72
|
+
|
|
73
|
+
#define LOG_GC 1 << 5
|
|
74
|
+
#define LOG_NETWORK 1 << 6
|
|
75
|
+
|
|
76
|
+
// Debug Helpers
|
|
77
|
+
void wax_printStack(lua_State *L);
|
|
78
|
+
void wax_printStackAt(lua_State *L, int i);
|
|
79
|
+
void wax_printTable(lua_State *L, int t);
|
|
80
|
+
void wax_log(int flag, NSString *format, ...);
|
|
81
|
+
int wax_getStackTrace(lua_State *L);
|
|
82
|
+
|
|
83
|
+
// Convertion Helpers
|
|
84
|
+
int wax_fromObjc(lua_State *L, const char *typeDescription, void *buffer);
|
|
85
|
+
void wax_fromInstance(lua_State *L, id instance);
|
|
86
|
+
void wax_fromStruct(lua_State *L, const char *typeDescription, void *buffer);
|
|
87
|
+
|
|
88
|
+
void *wax_copyToObjc(lua_State *L, const char *typeDescription, int stackIndex, int *outsize);
|
|
89
|
+
|
|
90
|
+
// Misc Helpers
|
|
91
|
+
void wax_selectorsForName(const char *methodName, SEL selectors[2]);
|
|
92
|
+
BOOL wax_selectorForInstance(wax_instance_userdata *instanceUserdata, SEL* foundSelectors, const char *methodName, BOOL forceInstanceCheck);
|
|
93
|
+
void wax_pushMethodNameFromSelector(lua_State *L, SEL selector);
|
|
94
|
+
BOOL wax_isInitMethod(const char *methodName);
|
|
95
|
+
|
|
96
|
+
const char *wax_removeProtocolEncodings(const char *type_descriptions);
|
|
97
|
+
|
|
98
|
+
int wax_sizeOfTypeDescription(const char *full_type_description);
|
|
99
|
+
int wax_simplifyTypeDescription(const char *in, char *out);
|
|
100
|
+
|
|
101
|
+
int wax_errorFunction(lua_State *L);
|
|
102
|
+
int wax_pcall(lua_State *L, int argumentCount, int returnCount);
|
|
@@ -0,0 +1,870 @@
|
|
|
1
|
+
//
|
|
2
|
+
// wax_helpers.m
|
|
3
|
+
// Lua
|
|
4
|
+
//
|
|
5
|
+
// Created by ProbablyInteractive on 5/18/09.
|
|
6
|
+
// Copyright 2009 Probably Interactive. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import "wax_helpers.h"
|
|
10
|
+
#import "wax_instance.h"
|
|
11
|
+
#import "wax_struct.h"
|
|
12
|
+
#import "lauxlib.h"
|
|
13
|
+
|
|
14
|
+
@interface WaxFunction : NSObject {}
|
|
15
|
+
@end
|
|
16
|
+
|
|
17
|
+
@implementation WaxFunction // Used to pass lua fuctions around
|
|
18
|
+
@end
|
|
19
|
+
|
|
20
|
+
void wax_printStack(lua_State *L) {
|
|
21
|
+
int i;
|
|
22
|
+
int top = lua_gettop(L);
|
|
23
|
+
|
|
24
|
+
for (i = 1; i <= top; i++) {
|
|
25
|
+
printf("%d: ", i);
|
|
26
|
+
wax_printStackAt(L, i);
|
|
27
|
+
printf("\n");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
printf("\n");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
void wax_printStackAt(lua_State *L, int i) {
|
|
34
|
+
int t = lua_type(L, i);
|
|
35
|
+
printf("(%s) ", lua_typename(L, t));
|
|
36
|
+
|
|
37
|
+
switch (t) {
|
|
38
|
+
case LUA_TSTRING:
|
|
39
|
+
printf("'%s'", lua_tostring(L, i));
|
|
40
|
+
break;
|
|
41
|
+
case LUA_TBOOLEAN:
|
|
42
|
+
printf(lua_toboolean(L, i) ? "true" : "false");
|
|
43
|
+
break;
|
|
44
|
+
case LUA_TNUMBER:
|
|
45
|
+
printf("'%g'", lua_tonumber(L, i));
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
printf("%p", lua_topointer(L, i));
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
void wax_printTable(lua_State *L, int t) {
|
|
54
|
+
// table is in the stack at index 't'
|
|
55
|
+
|
|
56
|
+
if (t < 0) t = lua_gettop(L) + t + 1; // if t is negative, we need to normalize
|
|
57
|
+
if (t <= 0 || t > lua_gettop(L)) {
|
|
58
|
+
printf("%d is not within stack boundries.\n", t);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
else if (!lua_istable(L, t)) {
|
|
62
|
+
printf("Object at stack index %d is not a table.\n", t);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
lua_pushnil(L); // first key
|
|
67
|
+
while (lua_next(L, t) != 0) {
|
|
68
|
+
wax_printStackAt(L, -2);
|
|
69
|
+
printf(" : ");
|
|
70
|
+
wax_printStackAt(L, -1);
|
|
71
|
+
printf("\n");
|
|
72
|
+
|
|
73
|
+
lua_pop(L, 1); // remove 'value'; keeps 'key' for next iteration
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
void wax_log(int flag, NSString *format, ...) {
|
|
78
|
+
if (flag & LOG_FLAGS) {
|
|
79
|
+
va_list args;
|
|
80
|
+
va_start(args, format);
|
|
81
|
+
NSString *output = [[[NSString alloc] initWithFormat:format arguments:args] autorelease];
|
|
82
|
+
printf("%s\n", [output UTF8String]);
|
|
83
|
+
va_end(args);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
int wax_getStackTrace(lua_State *L) {
|
|
88
|
+
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
|
|
89
|
+
if (!lua_istable(L, -1)) {
|
|
90
|
+
lua_pop(L, 1);
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
lua_getfield(L, -1, "traceback");
|
|
95
|
+
if (!lua_isfunction(L, -1)) {
|
|
96
|
+
lua_pop(L, 2);
|
|
97
|
+
return 1;
|
|
98
|
+
}
|
|
99
|
+
lua_remove(L, -2); // Remove debug
|
|
100
|
+
|
|
101
|
+
lua_call(L, 0, 1);
|
|
102
|
+
return 1;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
int wax_fromObjc(lua_State *L, const char *typeDescription, void *buffer) {
|
|
106
|
+
BEGIN_STACK_MODIFY(L)
|
|
107
|
+
|
|
108
|
+
typeDescription = wax_removeProtocolEncodings(typeDescription);
|
|
109
|
+
|
|
110
|
+
int size = wax_sizeOfTypeDescription(typeDescription);
|
|
111
|
+
|
|
112
|
+
switch (typeDescription[0]) {
|
|
113
|
+
case WAX_TYPE_VOID:
|
|
114
|
+
lua_pushnil(L);
|
|
115
|
+
break;
|
|
116
|
+
|
|
117
|
+
case WAX_TYPE_POINTER:
|
|
118
|
+
lua_pushlightuserdata(L, *(void **)buffer);
|
|
119
|
+
break;
|
|
120
|
+
|
|
121
|
+
case WAX_TYPE_CHAR: {
|
|
122
|
+
char c = *(char *)buffer;
|
|
123
|
+
if (c <= 1) lua_pushboolean(L, c); // If it's 1 or 0, then treat it like a bool
|
|
124
|
+
else lua_pushinteger(L, c);
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
case WAX_TYPE_SHORT:
|
|
129
|
+
lua_pushinteger(L, *(short *)buffer);
|
|
130
|
+
break;
|
|
131
|
+
|
|
132
|
+
case WAX_TYPE_INT:
|
|
133
|
+
lua_pushnumber(L, *(int *)buffer);
|
|
134
|
+
break;
|
|
135
|
+
|
|
136
|
+
case WAX_TYPE_UNSIGNED_CHAR:
|
|
137
|
+
lua_pushnumber(L, *(unsigned char *)buffer);
|
|
138
|
+
break;
|
|
139
|
+
|
|
140
|
+
case WAX_TYPE_UNSIGNED_INT:
|
|
141
|
+
lua_pushnumber(L, *(unsigned int *)buffer);
|
|
142
|
+
break;
|
|
143
|
+
|
|
144
|
+
case WAX_TYPE_UNSIGNED_SHORT:
|
|
145
|
+
lua_pushinteger(L, *(short *)buffer);
|
|
146
|
+
break;
|
|
147
|
+
|
|
148
|
+
case WAX_TYPE_LONG:
|
|
149
|
+
lua_pushnumber(L, *(long *)buffer);
|
|
150
|
+
break;
|
|
151
|
+
|
|
152
|
+
case WAX_TYPE_LONG_LONG:
|
|
153
|
+
lua_pushnumber(L, *(long long *)buffer);
|
|
154
|
+
break;
|
|
155
|
+
|
|
156
|
+
case WAX_TYPE_UNSIGNED_LONG:
|
|
157
|
+
lua_pushnumber(L, *(unsigned long *)buffer);
|
|
158
|
+
break;
|
|
159
|
+
|
|
160
|
+
case WAX_TYPE_UNSIGNED_LONG_LONG:
|
|
161
|
+
lua_pushnumber(L, *(unsigned long long *)buffer);
|
|
162
|
+
break;
|
|
163
|
+
|
|
164
|
+
case WAX_TYPE_FLOAT:
|
|
165
|
+
lua_pushnumber(L, *(float *)buffer);
|
|
166
|
+
break;
|
|
167
|
+
|
|
168
|
+
case WAX_TYPE_DOUBLE:
|
|
169
|
+
lua_pushnumber(L, *(double *)buffer);
|
|
170
|
+
break;
|
|
171
|
+
|
|
172
|
+
case WAX_TYPE_C99_BOOL:
|
|
173
|
+
lua_pushboolean(L, *(BOOL *)buffer);
|
|
174
|
+
break;
|
|
175
|
+
|
|
176
|
+
case WAX_TYPE_STRING:
|
|
177
|
+
lua_pushstring(L, *(char **)buffer);
|
|
178
|
+
break;
|
|
179
|
+
|
|
180
|
+
case WAX_TYPE_ID: {
|
|
181
|
+
id instance = *(id *)buffer;
|
|
182
|
+
wax_fromInstance(L, instance);
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
case WAX_TYPE_STRUCT: {
|
|
187
|
+
wax_fromStruct(L, typeDescription, buffer);
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
case WAX_TYPE_SELECTOR:
|
|
192
|
+
lua_pushstring(L, sel_getName(*(SEL *)buffer));
|
|
193
|
+
break;
|
|
194
|
+
|
|
195
|
+
case WAX_TYPE_CLASS: {
|
|
196
|
+
id instance = *(id *)buffer;
|
|
197
|
+
wax_instance_create(L, instance, YES);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
default:
|
|
202
|
+
luaL_error(L, "Unable to convert Obj-C type with type description '%s'", typeDescription);
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
END_STACK_MODIFY(L, 1)
|
|
207
|
+
|
|
208
|
+
return size;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
void wax_fromStruct(lua_State *L, const char *typeDescription, void *buffer) {
|
|
212
|
+
wax_struct_create(L, typeDescription, buffer);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
void wax_fromInstance(lua_State *L, id instance) {
|
|
216
|
+
BEGIN_STACK_MODIFY(L)
|
|
217
|
+
|
|
218
|
+
if (instance) {
|
|
219
|
+
if ([instance isKindOfClass:[NSString class]]) {
|
|
220
|
+
lua_pushstring(L, [(NSString *)instance UTF8String]);
|
|
221
|
+
}
|
|
222
|
+
else if ([instance isKindOfClass:[NSNumber class]]) {
|
|
223
|
+
lua_pushnumber(L, [instance doubleValue]);
|
|
224
|
+
}
|
|
225
|
+
else if ([instance isKindOfClass:[NSArray class]]) {
|
|
226
|
+
lua_newtable(L);
|
|
227
|
+
for (id obj in instance) {
|
|
228
|
+
int i = lua_objlen(L, -1);
|
|
229
|
+
wax_fromInstance(L, obj);
|
|
230
|
+
lua_rawseti(L, -2, i + 1);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else if ([instance isKindOfClass:[NSDictionary class]]) {
|
|
234
|
+
lua_newtable(L);
|
|
235
|
+
for (id key in instance) {
|
|
236
|
+
wax_fromInstance(L, key);
|
|
237
|
+
wax_fromInstance(L, [instance objectForKey:key]);
|
|
238
|
+
lua_rawset(L, -3);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else if ([instance isKindOfClass:[NSValue class]]) {
|
|
242
|
+
void *buffer = malloc(wax_sizeOfTypeDescription([instance objCType]));
|
|
243
|
+
[instance getValue:buffer];
|
|
244
|
+
wax_fromObjc(L, [instance objCType], buffer);
|
|
245
|
+
free(buffer);
|
|
246
|
+
}
|
|
247
|
+
else if ([instance isKindOfClass:[WaxFunction class]]) {
|
|
248
|
+
wax_instance_pushUserdata(L, instance);
|
|
249
|
+
if (lua_isnil(L, -1)) {
|
|
250
|
+
luaL_error(L, "Could not get userdata associated with WaxFunction");
|
|
251
|
+
}
|
|
252
|
+
lua_getfield(L, -1, "function");
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
wax_instance_create(L, instance, NO);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
lua_pushnil(L);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
END_STACK_MODIFY(L, 1)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
#define WAX_TO_INTEGER(_type_) *outsize = sizeof(_type_); value = calloc(sizeof(_type_), 1); *((_type_ *)value) = (_type_)lua_tointeger(L, stackIndex);
|
|
266
|
+
#define WAX_TO_NUMBER(_type_) *outsize = sizeof(_type_); value = calloc(sizeof(_type_), 1); *((_type_ *)value) = (_type_)lua_tonumber(L, stackIndex);
|
|
267
|
+
#define WAX_TO_BOOL_OR_CHAR(_type_) *outsize = sizeof(_type_); value = calloc(sizeof(_type_), 1); *((_type_ *)value) = (_type_)(lua_isstring(L, stackIndex) ? lua_tostring(L, stackIndex)[0] : lua_toboolean(L, stackIndex));
|
|
268
|
+
|
|
269
|
+
// MAKE SURE YOU RELEASE THE RETURN VALUE!
|
|
270
|
+
void *wax_copyToObjc(lua_State *L, const char *typeDescription, int stackIndex, int *outsize) {
|
|
271
|
+
void *value = nil;
|
|
272
|
+
|
|
273
|
+
// Ignore method encodings
|
|
274
|
+
switch (typeDescription[0]) {
|
|
275
|
+
case WAX_PROTOCOL_TYPE_CONST:
|
|
276
|
+
case WAX_PROTOCOL_TYPE_IN:
|
|
277
|
+
case WAX_PROTOCOL_TYPE_INOUT:
|
|
278
|
+
case WAX_PROTOCOL_TYPE_OUT:
|
|
279
|
+
case WAX_PROTOCOL_TYPE_BYCOPY:
|
|
280
|
+
case WAX_PROTOCOL_TYPE_BYREF:
|
|
281
|
+
case WAX_PROTOCOL_TYPE_ONEWAY:
|
|
282
|
+
typeDescription = typeDescription + 1; // Skip first
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
if (outsize == nil) outsize = alloca(sizeof(int)); // if no outsize address set, treat it as a junk var
|
|
288
|
+
|
|
289
|
+
switch (typeDescription[0]) {
|
|
290
|
+
case WAX_TYPE_C99_BOOL:
|
|
291
|
+
WAX_TO_BOOL_OR_CHAR(BOOL)
|
|
292
|
+
break;
|
|
293
|
+
|
|
294
|
+
case WAX_TYPE_CHAR:
|
|
295
|
+
WAX_TO_BOOL_OR_CHAR(char)
|
|
296
|
+
break;
|
|
297
|
+
|
|
298
|
+
case WAX_TYPE_INT:
|
|
299
|
+
WAX_TO_INTEGER(int)
|
|
300
|
+
break;
|
|
301
|
+
|
|
302
|
+
case WAX_TYPE_SHORT:
|
|
303
|
+
WAX_TO_INTEGER(short)
|
|
304
|
+
break;
|
|
305
|
+
|
|
306
|
+
case WAX_TYPE_UNSIGNED_CHAR:
|
|
307
|
+
WAX_TO_INTEGER(unsigned char)
|
|
308
|
+
break;
|
|
309
|
+
|
|
310
|
+
case WAX_TYPE_UNSIGNED_INT:
|
|
311
|
+
WAX_TO_INTEGER(unsigned int)
|
|
312
|
+
break;
|
|
313
|
+
|
|
314
|
+
case WAX_TYPE_UNSIGNED_SHORT:
|
|
315
|
+
WAX_TO_INTEGER(unsigned short)
|
|
316
|
+
break;
|
|
317
|
+
|
|
318
|
+
case WAX_TYPE_LONG:
|
|
319
|
+
WAX_TO_NUMBER(long)
|
|
320
|
+
break;
|
|
321
|
+
|
|
322
|
+
case WAX_TYPE_LONG_LONG:
|
|
323
|
+
WAX_TO_NUMBER(long long)
|
|
324
|
+
break;
|
|
325
|
+
|
|
326
|
+
case WAX_TYPE_UNSIGNED_LONG:
|
|
327
|
+
WAX_TO_NUMBER(unsigned long)
|
|
328
|
+
break;
|
|
329
|
+
|
|
330
|
+
case WAX_TYPE_UNSIGNED_LONG_LONG:
|
|
331
|
+
WAX_TO_NUMBER(unsigned long long);
|
|
332
|
+
break;
|
|
333
|
+
|
|
334
|
+
case WAX_TYPE_FLOAT:
|
|
335
|
+
WAX_TO_NUMBER(float);
|
|
336
|
+
break;
|
|
337
|
+
|
|
338
|
+
case WAX_TYPE_DOUBLE:
|
|
339
|
+
WAX_TO_NUMBER(double);
|
|
340
|
+
break;
|
|
341
|
+
|
|
342
|
+
case WAX_TYPE_SELECTOR:
|
|
343
|
+
if (lua_isnil(L, stackIndex)) { // If no slector is passed it, just use an empty string
|
|
344
|
+
lua_pushstring(L, "");
|
|
345
|
+
lua_replace(L, stackIndex);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
*outsize = sizeof(SEL);
|
|
349
|
+
value = calloc(sizeof(SEL), 1);
|
|
350
|
+
const char *selectorName = luaL_checkstring(L, stackIndex);
|
|
351
|
+
*((SEL *)value) = sel_getUid(selectorName);
|
|
352
|
+
|
|
353
|
+
break;
|
|
354
|
+
|
|
355
|
+
case WAX_TYPE_CLASS:
|
|
356
|
+
*outsize = sizeof(Class);
|
|
357
|
+
value = calloc(sizeof(Class), 1);
|
|
358
|
+
if (lua_isuserdata(L, stackIndex)) {
|
|
359
|
+
wax_instance_userdata *instanceUserdata = (wax_instance_userdata *)luaL_checkudata(L, stackIndex, WAX_INSTANCE_METATABLE_NAME);
|
|
360
|
+
*(id *)value = instanceUserdata->instance;
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
*((Class *)value) = objc_getClass(lua_tostring(L, stackIndex));
|
|
364
|
+
}
|
|
365
|
+
break;
|
|
366
|
+
|
|
367
|
+
case WAX_TYPE_STRING: {
|
|
368
|
+
const char *string = lua_tostring(L, stackIndex);
|
|
369
|
+
int length = strlen(string) + 1;
|
|
370
|
+
*outsize = length;
|
|
371
|
+
|
|
372
|
+
value = calloc(sizeof(char *), length);
|
|
373
|
+
strcpy(value, string);
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
case WAX_TYPE_POINTER:
|
|
378
|
+
*outsize = sizeof(void *);
|
|
379
|
+
|
|
380
|
+
value = calloc(sizeof(void *), 1);
|
|
381
|
+
void *pointer = nil;
|
|
382
|
+
|
|
383
|
+
switch (typeDescription[1]) {
|
|
384
|
+
case WAX_TYPE_VOID:
|
|
385
|
+
case WAX_TYPE_ID: {
|
|
386
|
+
switch (lua_type(L, stackIndex)) {
|
|
387
|
+
case LUA_TNIL:
|
|
388
|
+
case LUA_TNONE:
|
|
389
|
+
break;
|
|
390
|
+
|
|
391
|
+
case LUA_TUSERDATA: {
|
|
392
|
+
wax_instance_userdata *instanceUserdata = (wax_instance_userdata *)luaL_checkudata(L, stackIndex, WAX_INSTANCE_METATABLE_NAME);
|
|
393
|
+
if (typeDescription[1] == WAX_TYPE_VOID) {
|
|
394
|
+
pointer = instanceUserdata->instance;
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
pointer = &instanceUserdata->instance;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
default:
|
|
403
|
+
luaL_error(L, "Can't convert %s to wax_instance_userdata.", luaL_typename(L, stackIndex));
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
default:
|
|
409
|
+
if (lua_islightuserdata(L, stackIndex)) {
|
|
410
|
+
pointer = lua_touserdata(L, stackIndex);
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
free(value);
|
|
414
|
+
luaL_error(L, "Converstion from %s to Objective-c not implemented.", typeDescription);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (pointer) {
|
|
419
|
+
memcpy(value, &pointer, *outsize);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
break;
|
|
423
|
+
|
|
424
|
+
case WAX_TYPE_ID: {
|
|
425
|
+
*outsize = sizeof(id);
|
|
426
|
+
|
|
427
|
+
value = calloc(sizeof(id), 1);
|
|
428
|
+
// add number, string
|
|
429
|
+
|
|
430
|
+
id instance = nil;
|
|
431
|
+
|
|
432
|
+
switch (lua_type(L, stackIndex)) {
|
|
433
|
+
case LUA_TNIL:
|
|
434
|
+
case LUA_TNONE:
|
|
435
|
+
instance = nil;
|
|
436
|
+
break;
|
|
437
|
+
|
|
438
|
+
case LUA_TBOOLEAN: {
|
|
439
|
+
BOOL value = lua_toboolean(L, stackIndex);
|
|
440
|
+
instance = [NSValue valueWithBytes:&value objCType:@encode(bool)];
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
case LUA_TNUMBER:
|
|
444
|
+
instance = [NSNumber numberWithDouble:lua_tonumber(L, stackIndex)];
|
|
445
|
+
break;
|
|
446
|
+
|
|
447
|
+
case LUA_TSTRING:
|
|
448
|
+
instance = [NSString stringWithUTF8String:lua_tostring(L, stackIndex)];
|
|
449
|
+
break;
|
|
450
|
+
|
|
451
|
+
case LUA_TTABLE: {
|
|
452
|
+
BOOL dictionary = NO;
|
|
453
|
+
|
|
454
|
+
lua_pushvalue(L, stackIndex); // Push the table reference on the top
|
|
455
|
+
lua_pushnil(L); /* first key */
|
|
456
|
+
while (!dictionary && lua_next(L, -2)) {
|
|
457
|
+
if (lua_type(L, -2) != LUA_TNUMBER) {
|
|
458
|
+
dictionary = YES;
|
|
459
|
+
lua_pop(L, 2); // pop key and value off the stack
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
lua_pop(L, 1);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if (dictionary) {
|
|
467
|
+
instance = [NSMutableDictionary dictionary];
|
|
468
|
+
|
|
469
|
+
lua_pushnil(L); /* first key */
|
|
470
|
+
while (lua_next(L, -2)) {
|
|
471
|
+
id *key = wax_copyToObjc(L, "@", -2, nil);
|
|
472
|
+
id *object = wax_copyToObjc(L, "@", -1, nil);
|
|
473
|
+
[instance setObject:*object forKey:*key];
|
|
474
|
+
lua_pop(L, 1); // Pop off the value
|
|
475
|
+
free(key);
|
|
476
|
+
free(object);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
instance = [NSMutableArray array];
|
|
481
|
+
|
|
482
|
+
lua_pushnil(L); /* first key */
|
|
483
|
+
while (lua_next(L, -2)) {
|
|
484
|
+
int index = lua_tonumber(L, -2) - 1;
|
|
485
|
+
id *object = wax_copyToObjc(L, "@", -1, nil);
|
|
486
|
+
[instance insertObject:*object atIndex:index];
|
|
487
|
+
lua_pop(L, 1);
|
|
488
|
+
free(object);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
lua_pop(L, 1); // Pop the table reference off
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
case LUA_TUSERDATA: {
|
|
497
|
+
wax_instance_userdata *instanceUserdata = (wax_instance_userdata *)luaL_checkudata(L, stackIndex, WAX_INSTANCE_METATABLE_NAME);
|
|
498
|
+
instance = instanceUserdata->instance;
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
case LUA_TLIGHTUSERDATA: {
|
|
502
|
+
instance = lua_touserdata(L, -1);
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
505
|
+
case LUA_TFUNCTION: {
|
|
506
|
+
instance = [[[WaxFunction alloc] init] autorelease];
|
|
507
|
+
wax_instance_create(L, instance, NO);
|
|
508
|
+
lua_pushvalue(L, -2);
|
|
509
|
+
lua_setfield(L, -2, "function"); // Stores function inside of this instance
|
|
510
|
+
lua_pop(L, 1);
|
|
511
|
+
|
|
512
|
+
break;
|
|
513
|
+
}
|
|
514
|
+
default:
|
|
515
|
+
luaL_error(L, "Can't convert %s to obj-c.", luaL_typename(L, stackIndex));
|
|
516
|
+
break;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
if (instance) {
|
|
520
|
+
*(id *)value = instance;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
break;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
case WAX_TYPE_STRUCT: {
|
|
528
|
+
if (lua_isuserdata(L, stackIndex)) {
|
|
529
|
+
wax_struct_userdata *structUserdata = (wax_struct_userdata *)luaL_checkudata(L, stackIndex, WAX_STRUCT_METATABLE_NAME);
|
|
530
|
+
value = malloc(structUserdata->size);
|
|
531
|
+
memcpy(value, structUserdata->data, structUserdata->size);
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
void *data = (void *)lua_tostring(L, stackIndex);
|
|
535
|
+
size_t length = lua_objlen(L, stackIndex);
|
|
536
|
+
*outsize = length;
|
|
537
|
+
|
|
538
|
+
value = malloc(length);
|
|
539
|
+
memcpy(value, data, length);
|
|
540
|
+
}
|
|
541
|
+
break;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
default:
|
|
545
|
+
luaL_error(L, "Unable to get type for Obj-C method argument with type description '%s'", typeDescription);
|
|
546
|
+
break;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
return value;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// You can't tell if there are 0 or 1 arguments based on selector alone, so pass in an SEL[2] for possibleSelectors
|
|
553
|
+
void wax_selectorsForName(const char *methodName, SEL possibleSelectors[2]) {
|
|
554
|
+
int strlength = strlen(methodName) + 2; // Add 2. One for trailing : and one for \0
|
|
555
|
+
char *objcMethodName = calloc(strlength, 1);
|
|
556
|
+
|
|
557
|
+
int argCount = 0;
|
|
558
|
+
strcpy(objcMethodName, methodName);
|
|
559
|
+
for(int i = 0; objcMethodName[i]; i++) {
|
|
560
|
+
if (objcMethodName[i] == '_') {
|
|
561
|
+
argCount++;
|
|
562
|
+
objcMethodName[i] = ':';
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
objcMethodName[strlength - 2] = ':'; // Add final arg portion
|
|
567
|
+
possibleSelectors[0] = sel_getUid(objcMethodName);
|
|
568
|
+
|
|
569
|
+
if (argCount == 0) {
|
|
570
|
+
objcMethodName[strlength - 2] = '\0';
|
|
571
|
+
possibleSelectors[1] = sel_getUid(objcMethodName);
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
possibleSelectors[1] = nil;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
free(objcMethodName);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
BOOL wax_selectorForInstance(wax_instance_userdata *instanceUserdata, SEL* foundSelectors, const char *methodName, BOOL forceInstanceCheck) {
|
|
582
|
+
SEL possibleSelectors[2];
|
|
583
|
+
wax_selectorsForName(methodName, possibleSelectors);
|
|
584
|
+
|
|
585
|
+
for (int i = 0; i < 2; i++) {
|
|
586
|
+
SEL selector = possibleSelectors[i];
|
|
587
|
+
if (!selector) continue; // There may be only one acceptable selector (i.e. methods with multiple keyword args)
|
|
588
|
+
|
|
589
|
+
BOOL addSelector = NO;
|
|
590
|
+
if (instanceUserdata->isClass && (forceInstanceCheck || wax_isInitMethod(methodName))) {
|
|
591
|
+
if ([instanceUserdata->instance instanceMethodSignatureForSelector:selector]) addSelector = YES;
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
if ([instanceUserdata->instance methodSignatureForSelector:selector]) addSelector = YES;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
if (addSelector) {
|
|
598
|
+
if (!foundSelectors[0]) foundSelectors[0] = selector;
|
|
599
|
+
else foundSelectors[1] = selector;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// True if it found any selectors
|
|
604
|
+
return foundSelectors[0] || foundSelectors[1];
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
void wax_pushMethodNameFromSelector(lua_State *L, SEL selector) {
|
|
608
|
+
BEGIN_STACK_MODIFY(L)
|
|
609
|
+
const char *methodName = [NSStringFromSelector(selector) UTF8String];
|
|
610
|
+
int length = strlen(methodName);
|
|
611
|
+
|
|
612
|
+
luaL_Buffer b;
|
|
613
|
+
luaL_buffinit(L, &b);
|
|
614
|
+
|
|
615
|
+
int i = 0;
|
|
616
|
+
while(methodName[i]) {
|
|
617
|
+
if (methodName[i] == ':') {
|
|
618
|
+
if (i < length - 1) luaL_addchar(&b, '_');
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
luaL_addchar(&b, methodName[i]);
|
|
622
|
+
}
|
|
623
|
+
i++;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
luaL_pushresult(&b);
|
|
627
|
+
|
|
628
|
+
END_STACK_MODIFY(L, 1)
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
// Wax assumes anything that starts with init[A-Z0-9]? is an init method
|
|
632
|
+
BOOL wax_isInitMethod(const char *methodName) {
|
|
633
|
+
if (strncmp(methodName, "init", 4) == 0) {
|
|
634
|
+
if (methodName[4] == '\0') return YES; // It's just an init
|
|
635
|
+
if (isupper(methodName[4]) || isdigit(methodName[4])) return YES; // It's init[A-Z0-9]
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
return NO;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// I could get rid of this <- Then why don't you?
|
|
642
|
+
const char *wax_removeProtocolEncodings(const char *type_descriptions) {
|
|
643
|
+
switch (type_descriptions[0]) {
|
|
644
|
+
case WAX_PROTOCOL_TYPE_CONST:
|
|
645
|
+
case WAX_PROTOCOL_TYPE_INOUT:
|
|
646
|
+
case WAX_PROTOCOL_TYPE_OUT:
|
|
647
|
+
case WAX_PROTOCOL_TYPE_BYCOPY:
|
|
648
|
+
case WAX_PROTOCOL_TYPE_BYREF:
|
|
649
|
+
case WAX_PROTOCOL_TYPE_ONEWAY:
|
|
650
|
+
return &type_descriptions[1];
|
|
651
|
+
break;
|
|
652
|
+
default:
|
|
653
|
+
return type_descriptions;
|
|
654
|
+
break;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
int wax_sizeOfTypeDescription(const char *full_type_description) {
|
|
659
|
+
int index = 0;
|
|
660
|
+
int size = 0;
|
|
661
|
+
|
|
662
|
+
size_t length = strlen(full_type_description) + 1;
|
|
663
|
+
char *type_description = alloca(length);
|
|
664
|
+
bzero(type_description, length);
|
|
665
|
+
wax_simplifyTypeDescription(full_type_description, type_description);
|
|
666
|
+
|
|
667
|
+
while(type_description[index]) {
|
|
668
|
+
switch (type_description[index]) {
|
|
669
|
+
case WAX_TYPE_POINTER:
|
|
670
|
+
size += sizeof(void *);
|
|
671
|
+
|
|
672
|
+
case WAX_TYPE_CHAR:
|
|
673
|
+
size += sizeof(char);
|
|
674
|
+
break;
|
|
675
|
+
|
|
676
|
+
case WAX_TYPE_INT:
|
|
677
|
+
size += sizeof(int);
|
|
678
|
+
break;
|
|
679
|
+
|
|
680
|
+
case WAX_TYPE_ARRAY:
|
|
681
|
+
case WAX_TYPE_ARRAY_END:
|
|
682
|
+
[NSException raise:@"Wax Error" format:@"C array's are not implemented yet."];
|
|
683
|
+
break;
|
|
684
|
+
|
|
685
|
+
case WAX_TYPE_SHORT:
|
|
686
|
+
size += sizeof(short);
|
|
687
|
+
break;
|
|
688
|
+
|
|
689
|
+
case WAX_TYPE_UNSIGNED_CHAR:
|
|
690
|
+
size += sizeof(unsigned char);
|
|
691
|
+
break;
|
|
692
|
+
|
|
693
|
+
case WAX_TYPE_UNSIGNED_INT:
|
|
694
|
+
size += sizeof(unsigned int);
|
|
695
|
+
break;
|
|
696
|
+
|
|
697
|
+
case WAX_TYPE_UNSIGNED_SHORT:
|
|
698
|
+
size += sizeof(unsigned short);
|
|
699
|
+
break;
|
|
700
|
+
|
|
701
|
+
case WAX_TYPE_LONG:
|
|
702
|
+
size += sizeof(long);
|
|
703
|
+
break;
|
|
704
|
+
|
|
705
|
+
case WAX_TYPE_LONG_LONG:
|
|
706
|
+
size += sizeof(long long);
|
|
707
|
+
break;
|
|
708
|
+
|
|
709
|
+
case WAX_TYPE_UNSIGNED_LONG:
|
|
710
|
+
size += sizeof(unsigned long);
|
|
711
|
+
break;
|
|
712
|
+
|
|
713
|
+
case WAX_TYPE_UNSIGNED_LONG_LONG:
|
|
714
|
+
size += sizeof(unsigned long long);
|
|
715
|
+
break;
|
|
716
|
+
|
|
717
|
+
case WAX_TYPE_FLOAT:
|
|
718
|
+
size += sizeof(float);
|
|
719
|
+
break;
|
|
720
|
+
|
|
721
|
+
case WAX_TYPE_DOUBLE:
|
|
722
|
+
size += sizeof(double);
|
|
723
|
+
break;
|
|
724
|
+
|
|
725
|
+
case WAX_TYPE_C99_BOOL:
|
|
726
|
+
size += sizeof(_Bool);
|
|
727
|
+
break;
|
|
728
|
+
|
|
729
|
+
case WAX_TYPE_STRING:
|
|
730
|
+
size += sizeof(char *);
|
|
731
|
+
break;
|
|
732
|
+
|
|
733
|
+
case WAX_TYPE_VOID:
|
|
734
|
+
size += sizeof(char);
|
|
735
|
+
break;
|
|
736
|
+
|
|
737
|
+
case WAX_TYPE_BITFIELD:
|
|
738
|
+
[NSException raise:@"Wax Error" format:@"Bitfields are not implemented yet"];
|
|
739
|
+
break;
|
|
740
|
+
|
|
741
|
+
case WAX_TYPE_ID:
|
|
742
|
+
size += sizeof(id);
|
|
743
|
+
break;
|
|
744
|
+
|
|
745
|
+
case WAX_TYPE_CLASS:
|
|
746
|
+
size += sizeof(Class);
|
|
747
|
+
break;
|
|
748
|
+
|
|
749
|
+
case WAX_TYPE_SELECTOR:
|
|
750
|
+
size += sizeof(SEL);
|
|
751
|
+
break;
|
|
752
|
+
|
|
753
|
+
case WAX_TYPE_STRUCT:
|
|
754
|
+
case WAX_TYPE_STRUCT_END:
|
|
755
|
+
case WAX_TYPE_UNION:
|
|
756
|
+
case WAX_TYPE_UNION_END:
|
|
757
|
+
case WAX_TYPE_UNKNOWN:
|
|
758
|
+
case WAX_PROTOCOL_TYPE_CONST:
|
|
759
|
+
case WAX_PROTOCOL_TYPE_IN:
|
|
760
|
+
case WAX_PROTOCOL_TYPE_INOUT:
|
|
761
|
+
case WAX_PROTOCOL_TYPE_OUT:
|
|
762
|
+
case WAX_PROTOCOL_TYPE_BYCOPY:
|
|
763
|
+
case WAX_PROTOCOL_TYPE_BYREF:
|
|
764
|
+
case WAX_PROTOCOL_TYPE_ONEWAY:
|
|
765
|
+
// Weeeee! Just ignore this stuff I guess?
|
|
766
|
+
break;
|
|
767
|
+
default:
|
|
768
|
+
[NSException raise:@"Wax Error" format:@"Unknown type encoding %c", type_description[index]];
|
|
769
|
+
break;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
index++;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
return size;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
int wax_simplifyTypeDescription(const char *in, char *out) {
|
|
779
|
+
int out_index = 0;
|
|
780
|
+
int in_index = 0;
|
|
781
|
+
|
|
782
|
+
while(in[in_index]) {
|
|
783
|
+
switch (in[in_index]) {
|
|
784
|
+
case WAX_TYPE_STRUCT:
|
|
785
|
+
case WAX_TYPE_UNION:
|
|
786
|
+
for (; in[in_index] != '='; in_index++); // Eat the name!
|
|
787
|
+
in_index++; // Eat the = sign
|
|
788
|
+
break;
|
|
789
|
+
|
|
790
|
+
case WAX_TYPE_ARRAY:
|
|
791
|
+
do {
|
|
792
|
+
out[out_index++] = in[in_index++];
|
|
793
|
+
} while(in[in_index] != WAX_TYPE_ARRAY_END);
|
|
794
|
+
break;
|
|
795
|
+
|
|
796
|
+
case WAX_TYPE_POINTER: { //get rid of internal stucture parts
|
|
797
|
+
out[out_index++] = in[in_index++];
|
|
798
|
+
for (; in[in_index] == '^'; in_index++); // Eat all the pointers
|
|
799
|
+
|
|
800
|
+
switch (in[in_index]) {
|
|
801
|
+
case WAX_TYPE_UNION:
|
|
802
|
+
case WAX_TYPE_STRUCT: {
|
|
803
|
+
in_index++;
|
|
804
|
+
int openCurlies = 1;
|
|
805
|
+
|
|
806
|
+
for (; openCurlies > 1 || (in[in_index] != WAX_TYPE_UNION_END && in[in_index] != WAX_TYPE_STRUCT_END); in_index++) {
|
|
807
|
+
if (in[in_index] == WAX_TYPE_UNION || in[in_index] == WAX_TYPE_STRUCT) openCurlies++;
|
|
808
|
+
else if (in[in_index] == WAX_TYPE_UNION_END || in[in_index] == WAX_TYPE_STRUCT_END) openCurlies--;
|
|
809
|
+
}
|
|
810
|
+
break;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
case WAX_TYPE_STRUCT_END:
|
|
816
|
+
case WAX_TYPE_UNION_END:
|
|
817
|
+
case '0':
|
|
818
|
+
case '1':
|
|
819
|
+
case '2':
|
|
820
|
+
case '3':
|
|
821
|
+
case '4':
|
|
822
|
+
case '5':
|
|
823
|
+
case '6':
|
|
824
|
+
case '7':
|
|
825
|
+
case '8':
|
|
826
|
+
case '9':
|
|
827
|
+
in_index++;
|
|
828
|
+
break;
|
|
829
|
+
|
|
830
|
+
default:
|
|
831
|
+
out[out_index++] = in[in_index++];
|
|
832
|
+
break;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
out[out_index] = '\0';
|
|
837
|
+
|
|
838
|
+
return out_index;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
int wax_errorFunction(lua_State *L) {
|
|
842
|
+
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
|
|
843
|
+
if (!lua_istable(L, -1)) {
|
|
844
|
+
lua_pop(L, 1);
|
|
845
|
+
return 1;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
lua_getfield(L, -1, "traceback");
|
|
849
|
+
if (!lua_isfunction(L, -1)) {
|
|
850
|
+
lua_pop(L, 2);
|
|
851
|
+
return 1;
|
|
852
|
+
}
|
|
853
|
+
lua_remove(L, -2); // Remove debug
|
|
854
|
+
|
|
855
|
+
lua_pushvalue(L, -2); // Grab the error string and place it on the stack
|
|
856
|
+
|
|
857
|
+
lua_call(L, 1, 1);
|
|
858
|
+
lua_remove(L, -2); // Remove original error string
|
|
859
|
+
|
|
860
|
+
return 1;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
int wax_pcall(lua_State *L, int argumentCount, int returnCount) {
|
|
864
|
+
lua_pushcclosure(L, wax_errorFunction, 0);
|
|
865
|
+
int errorFuncStackIndex = lua_gettop(L) - (argumentCount + 1); // Insert error function before arguments
|
|
866
|
+
lua_insert(L, errorFuncStackIndex);
|
|
867
|
+
|
|
868
|
+
return lua_pcall(L, argumentCount, returnCount, errorFuncStackIndex);
|
|
869
|
+
}
|
|
870
|
+
|