├── .gitignore ├── LICENSE ├── README.md ├── scripts └── githook │ └── commit-msg ├── spa.podspec └── spa ├── Spa ├── Spa+Private.h ├── Spa.h ├── Spa.m ├── SpaClass.h ├── SpaClass.m ├── SpaConverter.h ├── SpaConverter.m ├── SpaDefine.h ├── SpaInstance.h ├── SpaInstance.m ├── SpaSimplePing.h ├── SpaSimplePing.m ├── SpaTrace.h ├── SpaTrace.m ├── SpaUtil.h ├── SpaUtil.m ├── block │ ├── SpaBlockDescription.h │ ├── SpaBlockDescription.m │ ├── SpaBlockInstance.h │ ├── SpaBlockInstance.m │ ├── SpaDynamicBlock.h │ └── SpaDynamicBlock.m ├── build-scripts │ ├── compile-stdlib.sh │ ├── lua32 │ ├── lua64 │ ├── luac32.lua │ └── luac64.lua ├── libffi │ ├── include │ │ └── ffi │ │ │ ├── ffi.h │ │ │ ├── ffi_arm64.h │ │ │ ├── ffi_armv7.h │ │ │ ├── ffi_i386.h │ │ │ ├── ffi_x86_64.h │ │ │ ├── ffitarget.h │ │ │ ├── ffitarget_arm64.h │ │ │ ├── ffitarget_armv7.h │ │ │ ├── ffitarget_i386.h │ │ │ └── ffitarget_x86_64.h │ ├── libffi.a │ └── libffi_sim.a ├── lua │ ├── lapi.c │ ├── lapi.h │ ├── lauxlib.c │ ├── lauxlib.h │ ├── lbaselib.c │ ├── lcode.c │ ├── lcode.h │ ├── ldblib.c │ ├── ldebug.c │ ├── ldebug.h │ ├── ldo.c │ ├── ldo.h │ ├── ldump.c │ ├── lfunc.c │ ├── lfunc.h │ ├── lgc.c │ ├── lgc.h │ ├── linit.c │ ├── liolib.c │ ├── llex.c │ ├── llex.h │ ├── llimits.h │ ├── lmathlib.c │ ├── lmem.c │ ├── lmem.h │ ├── loadlib.c │ ├── lobject.c │ ├── lobject.h │ ├── lopcodes.c │ ├── lopcodes.h │ ├── loslib.c │ ├── lparser.c │ ├── lparser.h │ ├── lstate.c │ ├── lstate.h │ ├── lstring.c │ ├── lstring.h │ ├── lstrlib.c │ ├── ltable.c │ ├── ltable.h │ ├── ltablib.c │ ├── ltm.c │ ├── ltm.h │ ├── lua.h │ ├── luaconf.h │ ├── lualib.h │ ├── lundump.c │ ├── lundump.h │ ├── lvm.c │ ├── lvm.h │ ├── lzio.c │ ├── lzio.h │ └── print.c ├── spa_stdlib.h └── stdlib │ ├── class.lua │ ├── init.lua │ └── trace.lua ├── SpaDemo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── familyfan.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── xcdebugger │ │ └── Expressions.xcexplist ├── xcshareddata │ └── xcschemes │ │ └── Spa.xcscheme └── xcuserdata │ └── familyfan.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── SpaDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m ├── SpaDemoTests ├── Info.plist ├── SpaBlockCovertTest.m ├── SpaBlockCreateTest.m ├── SpaBlockFunctionTest.m ├── SpaConvertTest.m ├── SpaCreateTest.m ├── SpaDemoTests.m ├── SpaFunctionTest.m ├── SpaInvokeTest.m └── SpaOtherTest.m └── serverSample ├── patch.lua └── server.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | .DS_Store 31 | .android 32 | 33 | # CocoaPods 34 | # 35 | # We recommend against adding the Pods directory to your .gitignore. However 36 | # you should judge for yourself, the pros and cons are mentioned at: 37 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 38 | # 39 | # Pods/ 40 | # 41 | # Add this line if you want to avoid checking in source code from the Xcode workspace 42 | # *.xcworkspace 43 | 44 | # Carthage 45 | # 46 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 47 | # Carthage/Checkouts 48 | 49 | Carthage/Build 50 | 51 | # fastlane 52 | # 53 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 54 | # screenshots whenever they are needed. 55 | # For more information about the recommended setup visit: 56 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 57 | 58 | fastlane/report.xml 59 | fastlane/Preview.html 60 | fastlane/screenshots/**/*.png 61 | fastlane/test_output 62 | 63 | # Code Injection 64 | # 65 | # After new code Injection tools there's a generated folder /iOSInjectionProject 66 | # https://github.com/johnno1962/injectionforxcode 67 | 68 | iOSInjectionProject/ 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 fan fei 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SPA 2 | 3 | lua hotfix ios app 4 | 5 | ### before run spa demo 6 | 7 | cd serverSample 8 | 9 | node server.js 10 | 11 | ### situation 1 12 | 13 | Objective-c 14 | 15 | ```objective-c 16 | @implementation ViewController 17 | 18 | - (void)doSomeThing 19 | { 20 | [self.view setBackgroundColor:[UIColor grayColor]]; 21 | } 22 | ``` 23 | 24 | lua 25 | 26 | ```lua 27 | spa_class("ViewController") 28 | 29 | function doSomeThing(self) 30 | self:view():setBackgroundColor_(UIColor:grayColor()) 31 | end 32 | ``` 33 | 34 | ### situation 2 35 | 36 | Objective-c 37 | 38 | ```objective-c 39 | @implementation ViewController 40 | 41 | - (void)doSomeThing:(UIColor *)color 42 | { 43 | [self.view setBackgroundColor:color]; 44 | } 45 | ``` 46 | 47 | lua 48 | 49 | ```lua 50 | spa_class("ViewController") 51 | 52 | function doSomeThing_(self, color) 53 | self:view():setBackgroundColor_(color) 54 | end 55 | ``` 56 | 57 | ### situation 3 58 | 59 | Objective-c 60 | 61 | ```objective-c 62 | @implementation ViewController 63 | 64 | - (void)doSomeThing:(UIColor *)color 65 | { 66 | [self.view setBackgroundColor:color]; 67 | } 68 | ``` 69 | 70 | lua 71 | 72 | ```lua 73 | spa_class("ViewController") 74 | 75 | function doSomeThing_(self, color) 76 | self:ORIGdoSomeThing_(color) 77 | end 78 | ``` 79 | 80 | ### situation 4 81 | 82 | Objective-c 83 | 84 | ```objective-c 85 | @implementation SUBViewController 86 | 87 | - (void)doSomeThing:(UIColor *)color 88 | { 89 | [super doSomeThing:color]; 90 | } 91 | ``` 92 | 93 | lua 94 | 95 | ```lua 96 | spa_class("ViewController") 97 | 98 | function doSomeThing_(self, color) 99 | self:SUPERdoSomeThing_(color) 100 | end 101 | ``` 102 | ### situation 5 103 | 104 | Objective-c 105 | 106 | ```objective-c 107 | @implementation SUBViewController 108 | 109 | - (void)doSomeThing:(void(^)(int i))block 110 | { 111 | block(5); 112 | } 113 | ``` 114 | 115 | lua 116 | 117 | ```lua 118 | spa_class("ViewController") 119 | 120 | function doSomeThing_(self, block) 121 | block(5) 122 | end 123 | ``` 124 | 125 | ### situation 6 126 | 127 | Objective-c 128 | 129 | ```objective-c 130 | @implementation ViewController 131 | 132 | - (void(^)(void))doSomeThing 133 | { 134 | void(^block)(void) = ^() { }; 135 | return block; 136 | } 137 | ``` 138 | 139 | lua 140 | 141 | ```lua 142 | spa_class("ViewController") 143 | 144 | function doSomeThing_(self, block) 145 | return function (i) end 146 | end 147 | ``` 148 | 149 | Objective-c 150 | 151 | ```objective-c 152 | @implementation ViewController 153 | 154 | - (void(^)(int))doSomeThing 155 | { 156 | void(^block)(int) = ^(int i) { }; 157 | return block; 158 | } 159 | ``` 160 | 161 | lua 162 | 163 | ```lua 164 | spa_class("ViewController") 165 | 166 | function doSomeThing_(self, block) 167 | return block(function (i) end, 'v', {'i'}) 168 | end 169 | ``` 170 | 171 | ### situation 7 172 | 173 | Objective-c 174 | 175 | ```objective-c 176 | @implementation ViewController 177 | 178 | - (void)doSomeThing_(CGPoint)p 179 | { 180 | int x = p.x; 181 | int y = p.y; 182 | } 183 | ``` 184 | 185 | lua 186 | 187 | ```lua 188 | spa_class("ViewController") 189 | 190 | function doSomeThing_(self, p) 191 | local x = p.x1 192 | local y = p.x2 193 | end 194 | ``` 195 | 196 | Objective-c 197 | 198 | ```objective-c 199 | @implementation ViewController 200 | 201 | - (CGPoint)doSomeThing 202 | { 203 | CGPoint p; 204 | p.x = 3; 205 | p.y = 4; 206 | return p; 207 | } 208 | ``` 209 | 210 | lua 211 | 212 | ```lua 213 | spa_class("ViewController") 214 | 215 | function doSomeThing(self) 216 | return {3,4} 217 | end 218 | ``` 219 | 220 | ### situation 8 221 | 222 | Objective-c 223 | 224 | ```objective-c 225 | @implementation ViewController 226 | 227 | - (void(^)(CGPoint, CGRect))doSomeThing 228 | { 229 | void(^block)(CGPoint, CGRect) = ^(CGPoint, CGRect) { 230 | 231 | }; 232 | return block; 233 | } 234 | ``` 235 | 236 | lua 237 | 238 | ```lua 239 | spa_class("ViewController") 240 | 241 | function doSomeThing() 242 | return block(function (point, rect) end, 'v', {'{CGPoint=gg}', '{CGRect=gggg}'}) 243 | end 244 | ``` 245 | ### situation 9 246 | 247 | ```objective-c 248 | @implementation ViewController 249 | 250 | - (void)doSomeThing 251 | { 252 | ... 253 | [self doSomeThingInternal]; 254 | ... 255 | } 256 | 257 | - (void)doSomeThingInternal 258 | { 259 | ... 260 | } 261 | ``` 262 | 263 | lua 264 | 265 | ```lua 266 | class_deep('ViewController', 'doSomeThing', 'ViewController', 'doSomeThingInternal', function () end) -- remove doSomeThingInternal impl in doSomeThing only 267 | ``` 268 | 269 | ### situation 10 270 | 271 | ```objective-c 272 | @implementation ViewController 273 | 274 | - (void)doSomeThing 275 | { 276 | if(self.view == nil){ 277 | ... 278 | } 279 | } 280 | 281 | 282 | ``` 283 | 284 | lua 285 | 286 | ```lua 287 | spa_class("ViewController") 288 | 289 | function doSomeThing() 290 | if(spa.isNull(self:view())) 291 | then 292 | end 293 | end 294 | 295 | ``` 296 | > use spa.isNull to determinate whether instance is nil or not. https://github.com/hzfanfei/spa/issues/1 297 | 298 | 299 | -------------------------------------------------------------------------------- /scripts/githook/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | import sys 5 | import re 6 | import commands 7 | 8 | commit_msg_path = str(sys.argv[1]) 9 | file_object = open(commit_msg_path,'r+w') 10 | try: 11 | file_context = file_object.readline() 12 | ret = re.search(r"^((feat|fix|docs|style|refactor|perf|test|chore|revert|build):|Revert|Merge)", file_context, re.IGNORECASE) 13 | if ret == None: 14 | print("commit failed,格式要求 : msg, 例如 feat: some message") 15 | print("- Type \n \ 16 | - feat - 新功能 feature \n \ 17 | - fix - 修复 bug, 要注明bug号 \n \ 18 | - docs - 文档注释 \n \ 19 | - style - 代码格式(不影响代码运行的变动) \n \ 20 | - refactor - 重构、优化(既不增加新功能,也不是修复bug) \n \ 21 | - perf - 性能优化 \n \ 22 | - test - 增加测试 \n \ 23 | - chore - 构建过程或辅助工具的变动 \n \ 24 | - revert - 回退") 25 | file_object.close() 26 | sys.exit(1) 27 | else: 28 | # add scopes 29 | scopes = [] 30 | _, git_result = commands.getstatusoutput('git diff head --stat') 31 | git_lines = git_result.split("\n") 32 | for line in git_lines: 33 | line = line.strip() 34 | if re.search(r"^ghmail/", line): 35 | scope = "ghmail" 36 | if scope not in scopes: 37 | scopes.append(scope) 38 | if re.search(r"^GHPods/", line): 39 | paths = line.split("/") 40 | if len(paths) >= 2: 41 | scope = line.split("/")[1] 42 | if scope not in scopes and re.search(r"^GH", scope): 43 | scopes.append(scope) 44 | if len(scopes) > 0: 45 | type = file_context.split(":")[0] 46 | file_context = file_context.replace(type+":", type+" ("+",".join(scopes)+"):") 47 | file_object.seek(0) 48 | file_object.truncate() 49 | file_object.write(file_context) 50 | file_object.close() 51 | finally: 52 | file_object.close() 53 | -------------------------------------------------------------------------------- /spa.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "spa" 3 | s.version = "1.2.1" 4 | s.summary = "lua hotfix solution" 5 | 6 | s.description = "hope to online" 7 | s.platform = :ios, "8.0" 8 | s.homepage = "https://github.com/hzfanfei/spa" 9 | s.license = "hzfanfei" 10 | s.requires_arc = true 11 | s.author = { "hzfanfei" => "hzfanfei@corp.netease.com" } 12 | s.source = { :git => "https://github.com/hzfanfei/spa.git", :tag => "#{s.version}" } 13 | s.source_files = "spa", "spa/Spa/**/*.{h,m,c}" 14 | s.ios.vendored_libraries = "spa/Spa/libffi/libffi_sim.a", "spa/Spa/libffi/libffi.a" 15 | s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' } 16 | s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' } 17 | end 18 | 19 | -------------------------------------------------------------------------------- /spa/Spa/Spa+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // Spa+Private.h 3 | // Spa 4 | // 5 | // Created by Family Fan on 2018/12/1. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #ifndef Spa_Private_h 10 | #define Spa_Private_h 11 | 12 | #import "Spa.h" 13 | #import "lua.h" 14 | 15 | @class SpaTrace; 16 | @interface Spa(Private) 17 | 18 | - (lua_State *)lua_state; 19 | - (SpaTrace *)spaTrace; 20 | - (spa_log_block_t)spaLogBlock; 21 | - (spa_complete_block_t)spaCompleteBlock; 22 | - (spa_complete_block_t)spaSwizzleBlock; 23 | @end 24 | 25 | #endif /* Spa_Private_h */ 26 | -------------------------------------------------------------------------------- /spa/Spa/Spa.h: -------------------------------------------------------------------------------- 1 | // 2 | // Spa.h 3 | // Spa 4 | // 5 | // Created by Family Fan on 2018/11/29. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "lauxlib.h" 11 | #import "lobject.h" 12 | #import "lualib.h" 13 | #import "SpaClass.h" 14 | 15 | #define SPA_MODULE "spa" 16 | 17 | typedef void (^spa_log_block_t)(NSString *log); 18 | typedef void (^spa_complete_block_t)(BOOL complete,NSString *log); 19 | 20 | @interface Spa : NSObject 21 | 22 | + (instancetype)sharedInstace; 23 | 24 | - (void)usePatch:(NSString *)patch; 25 | - (void)usePatchAppend:(NSString *)patch; 26 | - (void)usePatch:(NSString *)patch complete:(spa_complete_block_t)completeBlock; 27 | 28 | - (void)setLogBlock:(spa_log_block_t)block; 29 | - (void)setCompleteBlock:(spa_complete_block_t)complete; 30 | - (void)setSwizzleBlock:(spa_complete_block_t)block; 31 | 32 | - (lua_State *)getLuaState; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /spa/Spa/SpaClass.h: -------------------------------------------------------------------------------- 1 | // 2 | // SpaClass.h 3 | // Spa 4 | // 5 | // Created by Family Fan on 2018/11/30. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "lua.h" 12 | 13 | #define SPA_CLASS "spa.class" // lua class module 14 | #define SPA_CLASS_META_TABLE "spaClassMetaTable" // class instance meta table 15 | #define SPA_CLASS_LIST_TABLE "spaClassListTable" // for save class 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface SpaClass : NSObject 20 | 21 | - (void)setup:(lua_State *)L; 22 | 23 | + (int)createClassUserData:(lua_State *)L klass_name:(const char *)klass_name; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /spa/Spa/SpaConverter.h: -------------------------------------------------------------------------------- 1 | // 2 | // SpaConverter.h 3 | // Spa 4 | // 5 | // Created by Family Fan on 2018/12/1. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "lua.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface SpaConverter : NSObject 16 | 17 | + (void *)toOCObject:(lua_State *)L typeDescription:(const char *)typeDescription index:(int)index; 18 | 19 | + (int)toLuaObject:(lua_State *)L object:(id)object; 20 | 21 | + (int)toLuaObject:(lua_State *)L typeDescription:(const char *)typeDescription buffer:(void *)buffer; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /spa/Spa/SpaDefine.h: -------------------------------------------------------------------------------- 1 | // 2 | // SpaDefine.h 3 | // SpaDemo 4 | // 5 | // Created by Family Fan on 2018/12/3. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #ifndef SpaDefine_h 10 | #define SpaDefine_h 11 | 12 | typedef struct _SpaInstanceUserdata { 13 | __weak id instance; 14 | bool isBlock; 15 | } SpaInstanceUserdata; 16 | 17 | #define SPA_ORIGIN_PREFIX @"ORIG" 18 | #define SPA_SUPER_PREFIX @"SUPER" 19 | #define SPA_STATIC_PREFIX @"STATIC" 20 | #define SPA_ORIGIN_FORWARD_INVOCATION_SELECTOR_NAME @"__spa_origin_forwardInvocation:" 21 | 22 | #endif /* SpaDefine_h */ 23 | -------------------------------------------------------------------------------- /spa/Spa/SpaInstance.h: -------------------------------------------------------------------------------- 1 | // 2 | // SpaInstance.h 3 | // Spa 4 | // 5 | // Created by Family Fan on 2018/12/4. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "lua.h" 12 | 13 | #define SPA_INSTANCE "spa.instance" // lua instance module 14 | #define SPA_INSTANCE_META_TABLE "spaInstanceMetaTable" // instance meta table 15 | #define SPA_INSTANCE_LIST_TABLE "spaInstanceListTable" // for save instances 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface SpaInstance : NSObject 20 | 21 | - (void)setup:(lua_State *)L; 22 | 23 | + (int)createInstanceUserData:(lua_State *)L object:(id)object; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /spa/Spa/SpaInstance.m: -------------------------------------------------------------------------------- 1 | // 2 | // SpaInstance.m 3 | // Spa 4 | // 5 | // Created by Family Fan on 2018/12/4. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import "SpaInstance.h" 10 | #import "SpaUtil.h" 11 | #import "Spa+Private.h" 12 | #import "SpaConverter.h" 13 | #import "SpaDefine.h" 14 | #import "lauxlib.h" 15 | #import 16 | #import 17 | 18 | static int __index(lua_State *L) 19 | { 20 | const char* func = lua_tostring(L, -1); 21 | if (func) { 22 | NSString* selector = [NSString stringWithFormat:@"%s", func]; 23 | // if super 24 | if ([selector hasPrefix:SPA_SUPER_PREFIX]) { 25 | spa_safeInLuaStack(L, ^int{ 26 | // make a super selector 27 | SEL superSelector = NSSelectorFromString(selector); 28 | SEL sel = NSSelectorFromString([selector substringFromIndex:[SPA_SUPER_PREFIX length]]); 29 | SpaInstanceUserdata* instance = lua_touserdata(L, -2); 30 | Class klass = object_getClass(instance->instance); 31 | Class superClass = class_getSuperclass(klass); 32 | Method superMethod = class_getInstanceMethod(superClass, sel); 33 | IMP superMethodImp = method_getImplementation(superMethod); 34 | char *typeDescription = (char *)method_getTypeEncoding(superMethod); 35 | BOOL b = class_addMethod(klass, superSelector, superMethodImp, typeDescription); 36 | assert(b); 37 | return 0; 38 | }); 39 | } 40 | lua_pushcclosure(L, spa_invoke, 1); 41 | return 1; 42 | } 43 | return 0; 44 | } 45 | 46 | char *propName2funcName(const char *prop) 47 | { 48 | if (!prop) { 49 | return NULL; 50 | } 51 | size_t len = strlen(prop) + 3 + 2; 52 | char* func = malloc(len); 53 | memset(func, 0, len); 54 | 55 | char c = prop[0]; 56 | if(c >= 'a' && c <= 'z') { 57 | c = c - 32; 58 | } 59 | 60 | strcpy(func, "set"); 61 | memset(func+3, c, 1); 62 | strcpy(func+4, prop+1); 63 | strcat(func, ":"); 64 | return func; 65 | } 66 | 67 | static int __newIndex(lua_State *L) 68 | { 69 | SpaInstanceUserdata* instance = lua_touserdata(L, -3); 70 | if (!instance || !instance->instance) { 71 | return 0; 72 | } 73 | const char* prop = lua_tostring(L, -2); 74 | char* func = propName2funcName(prop); 75 | if (!func) { 76 | return 0; 77 | } 78 | 79 | SEL sel = NSSelectorFromString([NSString stringWithFormat:@"%s", func]); 80 | Class klass = object_getClass(instance->instance); 81 | NSMethodSignature *signature = [klass instanceMethodSignatureForSelector:sel]; 82 | if (signature) { 83 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 84 | invocation.target = instance->instance; 85 | invocation.selector = sel; 86 | const char* typeDescription = [signature getArgumentTypeAtIndex:2]; 87 | if (typeDescription) { 88 | void *argValue = [SpaConverter toOCObject:L typeDescription:typeDescription index:-1]; 89 | if (argValue == NULL) { 90 | id object = nil; 91 | [invocation setArgument:&object atIndex:2]; 92 | } else { 93 | [invocation setArgument:argValue atIndex:2]; 94 | } 95 | [invocation invoke]; 96 | } else { 97 | NSString* error = [NSString stringWithFormat:@"can not found param [%@ %s]", klass, func]; 98 | SPA_ERROR(L, error.UTF8String); 99 | } 100 | } else { 101 | NSString* error = [NSString stringWithFormat:@"can not found prop [%@ %s]", klass, func]; 102 | SPA_ERROR(L, error.UTF8String); 103 | } 104 | free(func); 105 | return 0; 106 | } 107 | 108 | static bool isBlock(id object) 109 | { 110 | Class klass = object_getClass(object); 111 | if (klass == NSClassFromString(@"__NSGlobalBlock__") 112 | || klass == NSClassFromString(@"__NSStackBlock__") 113 | || klass == NSClassFromString(@"__NSMallocBlock__")) { 114 | return true; 115 | } 116 | return false; 117 | } 118 | 119 | static int __call(lua_State *L) 120 | { 121 | SpaInstanceUserdata* instance = lua_touserdata(L, 1); 122 | id object = instance->instance; 123 | if (isBlock(object)) { 124 | return spa_callBlock(L); 125 | } 126 | return 0; 127 | } 128 | 129 | static int __gc(lua_State *L) 130 | { 131 | SpaInstanceUserdata* instance = lua_touserdata(L, -1); 132 | if (instance && !instance->isBlock && instance->instance) { 133 | [SpaInstance createInstanceUserData:L object:instance->instance]; 134 | } 135 | return 0; 136 | } 137 | 138 | static const struct luaL_Reg Methods[] = { 139 | {NULL, NULL} 140 | }; 141 | 142 | static const struct luaL_Reg MetaMethods[] = { 143 | {"__index", __index}, 144 | {"__newindex", __newIndex}, 145 | {"__call", __call}, 146 | {"__gc", __gc}, 147 | {NULL, NULL} 148 | }; 149 | 150 | @implementation SpaInstance 151 | 152 | - (void)setup:(lua_State *)L 153 | { 154 | luaL_register(L, SPA_INSTANCE, Methods); 155 | luaL_newmetatable(L, SPA_INSTANCE_META_TABLE); 156 | luaL_register(L, NULL, MetaMethods); 157 | luaL_newmetatable(L, SPA_INSTANCE_LIST_TABLE); 158 | 159 | lua_newtable(L); 160 | lua_pushstring(L, "k"); 161 | lua_setfield(L, -2, "__mode"); // Make weak table 162 | lua_setmetatable(L, -2); 163 | } 164 | 165 | + (int)createInstanceUserData:(lua_State *)L object:(id)object 166 | { 167 | return spa_safeInLuaStack(L, ^int{ 168 | // printf("create instance\n"); 169 | // spa_stackDump(L); 170 | // get from table 171 | luaL_getmetatable(L, SPA_INSTANCE_LIST_TABLE); 172 | lua_pushlightuserdata(L, (__bridge void *)(object)); 173 | lua_rawget(L, -2); 174 | lua_remove(L, -2); // remove userdataTable 175 | 176 | SpaInstanceUserdata* instanceInTable = lua_touserdata(L, -1); 177 | // if create already, not create any more 178 | if (!instanceInTable || !instanceInTable->instance) { 179 | lua_pop(L, 1); // pop nil stack 180 | size_t nbytes = sizeof(SpaInstanceUserdata); 181 | SpaInstanceUserdata *instance = (SpaInstanceUserdata *)lua_newuserdata(L, nbytes); 182 | instance->instance = object; 183 | instance->isBlock = isBlock(object); 184 | 185 | luaL_getmetatable(L, SPA_INSTANCE_META_TABLE); 186 | lua_setmetatable(L, -2); 187 | 188 | // block not push in weak table 189 | if (!instance->isBlock) { 190 | luaL_getmetatable(L, SPA_INSTANCE_LIST_TABLE); 191 | // copy a userdata on stack 192 | lua_pushlightuserdata(L, (__bridge void *)(instance->instance)); 193 | lua_pushvalue(L, -3); 194 | lua_rawset(L, -3); 195 | lua_pop(L, 1); // pop list table 196 | } 197 | 198 | // clean env 199 | lua_newtable(L); 200 | lua_setfenv(L, -2); 201 | } 202 | return 1; 203 | }); 204 | } 205 | 206 | 207 | @end 208 | -------------------------------------------------------------------------------- /spa/Spa/SpaTrace.h: -------------------------------------------------------------------------------- 1 | // 2 | // SpaTrace.h 3 | // Spa 4 | // 5 | // Created by Family Fan on 2018/12/13. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "lua.h" 12 | 13 | #define SPA_TRACE "spa.trace" 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface SpaTrace : NSObject 18 | 19 | - (void)setup:(lua_State *)L; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /spa/Spa/SpaTrace.m: -------------------------------------------------------------------------------- 1 | // 2 | // SpaTrace.m 3 | // Spa 4 | // 5 | // Created by Family Fan on 2018/12/13. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import "SpaTrace.h" 10 | #import "SpaSimplePing.h" 11 | #import "Spa+Private.h" 12 | #include 13 | #import "lauxlib.h" 14 | 15 | @interface SpaTrace () 16 | 17 | @property (nonatomic) SpaSimplePing* traceRoute; 18 | @property (nonatomic, copy) spa_log_block_t logBlock; 19 | @property NSTimer *sendTimer; 20 | @property NSTimer *sendTimeoutTimer; 21 | @property (nonatomic) NSString *ipAddress; 22 | @property (nonatomic) NSString* host; 23 | @property NSInteger sendCountDown; 24 | @property NSInteger sendTimeout; 25 | @property NSInteger sendSequence; 26 | #define TRACERT_MAX_TTL 30 27 | @property int currentTTL; // ttl increase from number 1 28 | @property NSInteger packetCountPerTTL; // per RTT, send out 3 packets 29 | @property NSDate *startDate; 30 | @property (nonatomic) NSString *icmpSrcAddress; 31 | 32 | @end 33 | 34 | @implementation SpaTrace 35 | 36 | static int traceStart(lua_State *L) 37 | { 38 | const char* host = lua_tostring(L, -1); 39 | if (host == NULL) { 40 | return 0; 41 | } 42 | SpaTrace* st = [[Spa sharedInstace] spaTrace]; 43 | [st stop]; 44 | [st startWithHost:[NSString stringWithFormat:@"%s", host]]; 45 | return 0; 46 | } 47 | 48 | static int traceStop(lua_State *L) 49 | { 50 | SpaTrace* st = [[Spa sharedInstace] spaTrace]; 51 | [st stop]; 52 | 53 | return 0; 54 | } 55 | 56 | static const struct luaL_Reg Methods[] = { 57 | {"start", traceStart}, 58 | {"stop", traceStop}, 59 | {NULL, NULL} 60 | }; 61 | 62 | - (void)setup:(lua_State *)L 63 | { 64 | luaL_register(L, SPA_TRACE, Methods); 65 | } 66 | 67 | - (void)startWithHost:(NSString *)host 68 | { 69 | self.traceRoute = [[SpaSimplePing alloc] initWithHostName:host]; 70 | self.host = host; 71 | self.logBlock = [Spa sharedInstace].spaLogBlock; 72 | self.traceRoute.delegate = self; 73 | [self.traceRoute start]; 74 | } 75 | 76 | #pragma mark - SimplePingDelegate 77 | 78 | - (void)simplePing:(SpaSimplePing *)pinger didStartWithAddress:(NSData *)address 79 | { 80 | self.ipAddress = [self displayAddressForAddress:address]; 81 | NSString *msg = [NSString stringWithFormat:@"Tracert %@ (%@)\n", self.host, self.ipAddress]; 82 | [self appendText:msg]; 83 | 84 | self.currentTTL = 1; // init ttl 85 | [self sendPingWithTTL:self.currentTTL]; 86 | 87 | } 88 | 89 | - (void)simplePing:(SpaSimplePing *)pinger didFailWithError:(NSError *)error 90 | { 91 | NSString *msg = [NSString stringWithFormat:@"Failed to resolve %@", self.host]; 92 | [self appendText:msg]; 93 | [self stop]; 94 | } 95 | 96 | - (void)simplePing:(SpaSimplePing *)pinger didSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber 97 | { 98 | self.sendSequence = sequenceNumber; 99 | self.startDate = [NSDate date]; 100 | } 101 | 102 | - (void)simplePing:(SpaSimplePing *)pinger didFailToSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber error:(NSError *)error 103 | { 104 | NSLog(@"%s", __func__); 105 | NSLog(@"%@ %d %@", packet, sequenceNumber, error); 106 | } 107 | 108 | - (void)invalidSendTimer 109 | { 110 | [self.sendTimer invalidate]; 111 | self.sendTimer = nil; 112 | } 113 | 114 | - (void)simplePing:(SpaSimplePing *)pinger didReceivePingResponsePacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber 115 | { 116 | [self invalidSendTimer]; 117 | [self.sendTimeoutTimer invalidate]; 118 | if (sequenceNumber != self.sendSequence) { 119 | return; 120 | } 121 | NSString *msg = [NSString stringWithFormat:@"#%u reach the destination %@, test completed", sequenceNumber, self.ipAddress]; 122 | [self appendText:msg]; 123 | 124 | [self stop]; 125 | } 126 | 127 | - (void)simplePing:(SpaSimplePing *)pinger didReceiveUnexpectedPacket:(NSData *)packet 128 | { 129 | NSString *msg; 130 | NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:self.startDate]; 131 | NSString *srcAddr = [self.traceRoute srcAddrInIPv4Packet:packet]; 132 | if (0 == self.packetCountPerTTL) { 133 | self.icmpSrcAddress = srcAddr; 134 | self.packetCountPerTTL += 1; 135 | msg = [NSString stringWithFormat:@"#%ld %@ %0.2lfms", (long)self.sendSequence, self.icmpSrcAddress, interval*1000]; 136 | } else { 137 | self.packetCountPerTTL += 1; 138 | msg = [NSString stringWithFormat:@" %0.2lfms", interval*1000]; 139 | } 140 | 141 | [self appendTextOneLine:msg]; 142 | 143 | if (3 == self.packetCountPerTTL) { 144 | [self invalidSendTimer]; 145 | [self appendText:@"\n"]; 146 | [self sendPing]; 147 | } 148 | } 149 | 150 | - (void)appendTextOneLine:(NSString *)msg 151 | { 152 | if (self.logBlock) { 153 | self.logBlock(msg); 154 | } 155 | } 156 | 157 | - (void)appendText:(NSString *)msg 158 | { 159 | if (self.logBlock) { 160 | self.logBlock([NSString stringWithFormat:@"%@\n", msg]); 161 | } 162 | } 163 | 164 | - (void)sendPingWithTTL:(int)ttl 165 | { 166 | self.packetCountPerTTL = 0; 167 | 168 | [self.traceRoute setTTL:ttl]; 169 | [self.traceRoute sendPing]; 170 | 171 | self.sendTimer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(checkSingleRoundTimeout) userInfo:nil repeats:NO]; 172 | 173 | } 174 | 175 | - (void)checkSingleRoundTimeout 176 | { 177 | NSString *msg; 178 | switch (self.packetCountPerTTL) { 179 | case 0: 180 | msg = [NSString stringWithFormat:@"#%ld * * *\n", (long)self.sendSequence]; 181 | break; 182 | case 1: 183 | msg = [NSString stringWithFormat:@" * *\n"]; 184 | break; 185 | case 2: 186 | msg = [NSString stringWithFormat:@" *\n"]; 187 | break; 188 | 189 | default: 190 | break; 191 | } 192 | [self appendText:msg]; 193 | 194 | [self sendPing]; 195 | } 196 | 197 | - (BOOL)sendPing 198 | { 199 | self.currentTTL += 1; 200 | if (self.currentTTL > TRACERT_MAX_TTL) { 201 | NSString *msg = [NSString stringWithFormat:@"TTL exceed the Max, stop the test"]; 202 | [self appendText:msg]; 203 | [self stop]; 204 | return NO; 205 | } 206 | 207 | [self sendPingWithTTL:self.currentTTL]; 208 | return YES; 209 | } 210 | 211 | - (void)stop 212 | { 213 | [self.sendTimer invalidate]; 214 | self.sendTimer = nil; 215 | [self.sendTimeoutTimer invalidate]; 216 | self.sendTimeoutTimer = nil; 217 | 218 | [self.traceRoute stop]; 219 | self.traceRoute = nil; 220 | } 221 | 222 | - (NSString *)displayAddressForAddress:(NSData *)address 223 | { 224 | 225 | #define NI_MAXHOST 1025 226 | #define NI_NUMERICHOST 0x00000002 227 | int err; 228 | NSString * result; 229 | char hostStr[NI_MAXHOST]; 230 | 231 | result = nil; 232 | 233 | if (address != nil) { 234 | err = getnameinfo(address.bytes, (socklen_t) address.length, hostStr, sizeof(hostStr), NULL, 0, NI_NUMERICHOST); 235 | if (err == 0) { 236 | result = @(hostStr); 237 | } 238 | } 239 | 240 | if (result == nil) { 241 | result = @"?"; 242 | } 243 | 244 | return result; 245 | } 246 | 247 | @end 248 | -------------------------------------------------------------------------------- /spa/Spa/SpaUtil.h: -------------------------------------------------------------------------------- 1 | // 2 | // SpaUtil.h 3 | // Spa 4 | // 5 | // Created by Family Fan on 2018/11/30. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "lua.h" 11 | 12 | #define SPA_ERROR(L, err) luaL_error(L, "[Spa] error %s line %d %s: %s", __FILE__, __LINE__, __FUNCTION__, err); 13 | 14 | typedef int (^spa_lua_save_stack_block_t)(void); 15 | typedef int (^spa_lua_perfrom_locked_block_t)(void); 16 | 17 | extern int spa_safeInLuaStack(lua_State *L, spa_lua_save_stack_block_t block); 18 | 19 | extern int spa_performLocked(spa_lua_perfrom_locked_block_t block); 20 | 21 | extern void spa_stackDump(lua_State *L); 22 | 23 | extern char spa_getTypeFromTypeDescription(const char *typeDescription); 24 | 25 | extern const char* spa_toObjcSel(const char *luaFuncName); 26 | 27 | extern const char* spa_toLuaFuncName(const char *objcSel); 28 | 29 | extern SEL spa_originForSelector(SEL sel); 30 | 31 | extern int spa_callBlock(lua_State *L); 32 | 33 | extern int spa_invoke(lua_State *L); 34 | 35 | extern NSArray* spa_parseStructFromTypeDescription(NSString *typeDes); 36 | -------------------------------------------------------------------------------- /spa/Spa/block/SpaBlockDescription.h: -------------------------------------------------------------------------------- 1 | // 2 | // CTBlockDescription.h 3 | // CTBlockDescription 4 | // 5 | // Created by Oliver Letterer on 01.09.12. 6 | // Copyright (c) 2012 olettere. All rights reserved. 7 | // code from https://github.com/ebf/CTObjectiveCRuntimeAdditions 8 | 9 | #import 10 | 11 | struct CTBlockLiteral { 12 | void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock 13 | int flags; 14 | int reserved; 15 | void (*invoke)(void *, ...); 16 | struct block_descriptor { 17 | unsigned long int reserved; // NULL 18 | unsigned long int size; // sizeof(struct Block_literal_1) 19 | // optional helper functions 20 | void (*copy_helper)(void *dst, void *src); // IFF (1<<25) 21 | void (*dispose_helper)(void *src); // IFF (1<<25) 22 | // required ABI.2010.3.16 23 | const char *signature; // IFF (1<<30) 24 | } *descriptor; 25 | // imported variables 26 | }; 27 | 28 | enum { 29 | CTBlockDescriptionFlagsHasCopyDispose = (1 << 25), 30 | CTBlockDescriptionFlagsHasCtor = (1 << 26), // helpers have C++ code 31 | CTBlockDescriptionFlagsIsGlobal = (1 << 28), 32 | CTBlockDescriptionFlagsHasStret = (1 << 29), // IFF BLOCK_HAS_SIGNATURE 33 | CTBlockDescriptionFlagsHasSignature = (1 << 30) 34 | }; 35 | typedef int CTBlockDescriptionFlags; 36 | 37 | 38 | 39 | @interface SpaBlockDescription : NSObject 40 | 41 | @property (nonatomic, readonly) CTBlockDescriptionFlags flags; 42 | @property (nonatomic, readonly) NSMethodSignature *blockSignature; 43 | @property (nonatomic, readonly) unsigned long int size; 44 | @property (nonatomic, readonly) id block; 45 | 46 | - (id)initWithBlock:(id)block; 47 | @end 48 | -------------------------------------------------------------------------------- /spa/Spa/block/SpaBlockDescription.m: -------------------------------------------------------------------------------- 1 | // 2 | // CTBlockDescription.m 3 | // CTBlockDescription 4 | // 5 | // Created by Oliver Letterer on 01.09.12. 6 | // Copyright (c) 2012 olettere. All rights reserved. 7 | // 8 | 9 | #import "SpaBlockDescription.h" 10 | 11 | @implementation SpaBlockDescription 12 | 13 | - (id)initWithBlock:(id)block 14 | { 15 | if (self = [super init]) { 16 | _block = block; 17 | 18 | struct CTBlockLiteral *blockRef = (__bridge struct CTBlockLiteral *)block; 19 | _flags = blockRef->flags; 20 | _size = blockRef->descriptor->size; 21 | 22 | if (_flags & CTBlockDescriptionFlagsHasSignature) { 23 | void *signatureLocation = blockRef->descriptor; 24 | signatureLocation += sizeof(unsigned long int); 25 | signatureLocation += sizeof(unsigned long int); 26 | 27 | if (_flags & CTBlockDescriptionFlagsHasCopyDispose) { 28 | signatureLocation += sizeof(void(*)(void *dst, void *src)); 29 | signatureLocation += sizeof(void (*)(void *src)); 30 | } 31 | 32 | const char *signature = (*(const char **)signatureLocation); 33 | _blockSignature = [NSMethodSignature signatureWithObjCTypes:signature]; 34 | } 35 | } 36 | return self; 37 | } 38 | 39 | - (NSString *)description 40 | { 41 | return [NSString stringWithFormat:@"%@: %@", [super description], _blockSignature.description]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /spa/Spa/block/SpaBlockInstance.h: -------------------------------------------------------------------------------- 1 | // 2 | // SpaBlockInstance.h 3 | // Spa 4 | // 5 | // Created by Family Fan on 2018/12/10. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "lua.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface SpaBlockInstance : NSObject 15 | 16 | -(void (^)(void))voidBlock; 17 | - (id)blockWithParamsTypeArray:(NSArray *)paramsTypeArray returnType:(NSString *)returnType; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /spa/Spa/block/SpaBlockInstance.m: -------------------------------------------------------------------------------- 1 | // 2 | // SpaBlockInstance.m 3 | // Spa 4 | // 5 | // Created by Family Fan on 2018/12/10. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import "SpaBlockInstance.h" 10 | #import "SpaUtil.h" 11 | #import "Spa+Private.h" 12 | #import "SpaInstance.h" 13 | #import "SpaDynamicBlock.h" 14 | #import "SpaConverter.h" 15 | #import "lauxlib.h" 16 | 17 | @implementation SpaBlockInstance 18 | 19 | -(void (^)(void))voidBlock 20 | { 21 | return ^() { 22 | lua_State* L = [Spa sharedInstace].lua_state; 23 | spa_safeInLuaStack(L, ^int{ 24 | luaL_getmetatable(L, SPA_INSTANCE_LIST_TABLE); 25 | lua_pushlightuserdata(L, (__bridge void *)(self)); 26 | lua_rawget(L, -2); 27 | lua_remove(L, -2); // remove userdataTable 28 | 29 | // get function 30 | lua_getfenv(L, -1); 31 | lua_getfield(L, -1, "f"); 32 | 33 | if (!lua_isnil(L, -1) && lua_type(L, -1) == LUA_TFUNCTION) { 34 | if(lua_pcall(L, 0, 0, 0) != 0){ 35 | NSString* log = [NSString stringWithFormat:@"[SPA] PANIC: unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1)]; 36 | NSLog(log); 37 | Spa* spa = [Spa sharedInstace]; 38 | if (spa.spaSwizzleBlock) { 39 | spa.spaSwizzleBlock(NO, log); 40 | } 41 | NSCAssert(NO, log); 42 | } 43 | } 44 | return 0; 45 | }); 46 | }; 47 | } 48 | 49 | - (id)blockWithParamsTypeArray:(NSArray *)paramsTypeArray returnType:(NSString *)returnType 50 | { 51 | SpaDynamicBlock* __autoreleasing blk = [[SpaDynamicBlock alloc] initWithArgsTypes:paramsTypeArray retType:returnType replaceBlock:^void *(void **args) { 52 | 53 | __block void *returnBuffer = nil; 54 | 55 | lua_State* L = [Spa sharedInstace].lua_state; 56 | spa_safeInLuaStack(L, ^int{ 57 | 58 | luaL_getmetatable(L, SPA_INSTANCE_LIST_TABLE); 59 | lua_pushlightuserdata(L, (__bridge void *)(self)); 60 | lua_rawget(L, -2); 61 | lua_remove(L, -2); // remove userdataTable 62 | 63 | // get function 64 | lua_getfenv(L, -1); 65 | lua_getfield(L, -1, "f"); 66 | 67 | if (lua_isnil(L, -1) || lua_type(L, -1) != LUA_TFUNCTION) { 68 | return 0; 69 | } 70 | 71 | // push args 72 | [paramsTypeArray enumerateObjectsUsingBlock:^(NSString* _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 73 | if ([obj isEqualToString:DyIdType]) { 74 | struct S 75 | { 76 | id instance; 77 | }; 78 | struct S* s = (struct S*)args[idx+1]; 79 | [SpaConverter toLuaObject:L object:s->instance]; 80 | } else { 81 | [SpaConverter toLuaObject:L typeDescription:obj.UTF8String buffer:args[idx+1]]; 82 | } 83 | }]; 84 | 85 | NSUInteger paramNum = [paramsTypeArray count]; 86 | 87 | if (returnType == nil) { 88 | if(lua_pcall(L, (int)paramNum, 0, 0) != 0){ 89 | NSString* log = [NSString stringWithFormat:@"[SPA] PANIC: unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1)]; 90 | NSLog(log); 91 | Spa* spa = [Spa sharedInstace]; 92 | if (spa.spaSwizzleBlock) { 93 | spa.spaSwizzleBlock(NO, log); 94 | } 95 | NSCAssert(NO, log); 96 | } 97 | 98 | } else { 99 | if(lua_pcall(L, (int)paramNum, 1, 0) != 0){ 100 | NSString* log = [NSString stringWithFormat:@"[SPA] PANIC: unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1)]; 101 | NSLog(log); 102 | Spa* spa = [Spa sharedInstace]; 103 | if (spa.spaSwizzleBlock) { 104 | spa.spaSwizzleBlock(NO, log); 105 | } 106 | NSCAssert(NO, log); 107 | } 108 | returnBuffer = [SpaConverter toOCObject:L typeDescription:returnType.UTF8String index:-1]; 109 | } 110 | 111 | return 0; 112 | }); 113 | return returnBuffer; 114 | }]; 115 | return blk.invokeBlock; 116 | } 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /spa/Spa/block/SpaDynamicBlock.h: -------------------------------------------------------------------------------- 1 | // 2 | // SpaDynamicBlock.h 3 | // OCBlock 4 | // 5 | // Created by familymrfan on 2018/3/13. 6 | // Copyright © 2018年 niuniu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | extern NSString* DyVoidType; 12 | extern NSString* DyCharType; 13 | extern NSString* DyIntType; 14 | extern NSString* DyShortType; 15 | extern NSString* DyLongType; 16 | extern NSString* DyLongLongType; 17 | extern NSString* DyFloatType; 18 | extern NSString* DyDoubleType; 19 | extern NSString* DyBoolType; 20 | extern NSString* DyIdType; 21 | extern NSString* DyPtrType; 22 | extern NSString* DySELType; 23 | extern NSString* DyCGFloatType; 24 | 25 | @interface SpaDynamicBlock : NSObject 26 | 27 | @property (nonatomic, readonly, copy) id invokeBlock; 28 | 29 | - (id)initWithArgsTypes:(NSArray *)types retType:(NSString *)retType replaceBlock:(void *(^)(void** args))replaceBlock; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /spa/Spa/build-scripts/compile-stdlib.sh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | #manual compile set path 4 | PROJECT_DIR="../" 5 | 6 | ###32 bit stdlib 7 | # Compiles the spa stdlib into one file 8 | ./lua32 "$PROJECT_DIR/build-scripts/luac32.lua" spa spa32.dat "$PROJECT_DIR/stdlib/" "$PROJECT_DIR/stdlib/init.lua" -L "$PROJECT_DIR/stdlib"/**/*.lua 9 | #"$PROJECT_DIR/stdlib"/*.lua 10 | 11 | lua32Byte=$(hexdump -v -e '1/1 "%d,"' spa32.dat) 12 | # Dumps the compiled file into a byte array, then it places this into the source code 13 | # cat > "$PROJECT_DIR/spa_stdlib32.h" < "$PROJECT_DIR/spa_stdlib64.h" < "$PROJECT_DIR/spa_stdlib.h" < 17 | -- Tue Aug 5 22:57:33 BRT 2008 18 | -- This code is hereby placed in the public domain. 19 | 20 | local MARK = "////////" 21 | local NAME = "luac" 22 | 23 | local MODULE_NAME = table.remove(arg, 1) 24 | local OUTPUT = table.remove(arg, 1) 25 | local BASE_DIR = table.remove(arg, 1) 26 | NAME = "=("..NAME..")" 27 | 28 | local argCount = #arg 29 | local executableIndex = n 30 | local b 31 | 32 | for i = 1, argCount do 33 | if arg[i] == "-L" then executableIndex = i - 1 break end 34 | end 35 | 36 | if executableIndex + 2 <= argCount then b = "local t=package.preload;\n" else b = "local t;\n" end 37 | 38 | for i = executableIndex + 2, argCount do 39 | 40 | local requireString = string.gsub(arg[i], "^" .. string.gsub(BASE_DIR, "(%W)", "%%%1"), "") 41 | requireString = string.gsub(requireString,"^[\./]*(.-)\.lua$", "%1") 42 | requireString = string.gsub(requireString, "/", ".") 43 | requireString = string.gsub(requireString, ".init$", "") -- if it is an init file within a directory... ignore it! 44 | --print("requireString=" .. requireString) 45 | if MODULE_NAME and #MODULE_NAME > 0 then requireString = MODULE_NAME .. "." .. requireString end 46 | 47 | b = b.."t['"..requireString.."']=function()end;\n" 48 | arg[i]=string.sub(string.dump(assert(loadfile(arg[i]))), 13) -- string.sub Removes header from file 49 | end 50 | b = b.."t='"..MARK.."';\n" 51 | 52 | 53 | for i = 1, executableIndex do 54 | b = b.."(function()end)();\n" 55 | arg[i]=string.sub(string.dump(assert(loadfile(arg[i]))), 13) -- string.sub Removes header from file 56 | end 57 | 58 | b = string.dump(assert(loadstring(b, NAME))) 59 | local x, y = string.find(b, MARK) 60 | -- 64 61 | --b = string.sub(b, 1, x - 6 - 4).."\0"..string.sub(b, y + 2, y + 5) -- WTF does this do? 62 | 63 | -- 32 64 | b = string.sub(b, 1, x - 6).."\0"..string.sub(b, y + 2, y + 5) -- WTF does this do? 65 | 66 | f = assert(io.open(OUTPUT, "wb")) 67 | 68 | assert(f:write(b)) 69 | 70 | for i = executableIndex + 2, argCount do 71 | assert(f:write(arg[i])) 72 | end 73 | 74 | for i=1,executableIndex do 75 | assert(f:write(arg[i])) 76 | end 77 | 78 | -- 64 79 | --assert(f:write(string.rep("\0", 3 * 8))) 80 | print("end complie lua 32") 81 | -- 32 82 | assert(f:write(string.rep("\0", 12))) 83 | assert(f:close()) -------------------------------------------------------------------------------- /spa/Spa/build-scripts/luac64.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | print("start complie lua 64") 3 | -- usage: lua luac.lua module-name output.file base_dir starting-file.lua [-L [other-files.lua]*] 4 | -- 5 | -- base_dir: The root for all the lua files. So folder modules can be used 6 | -- 7 | -- creates a precompiled chunk that preloads all modules listed after 8 | -- -L and then runs all programs listed before -L. 9 | -- 10 | -- assumptions: 11 | -- file xxx.lua contains module xxx 12 | -- '/' is the directory separator (could have used package.config) 13 | -- int and size_t take 4 bytes (could have read sizes from header) 14 | -- does not honor package.path 15 | -- 16 | -- Luiz Henrique de Figueiredo 17 | -- Tue Aug 5 22:57:33 BRT 2008 18 | -- This code is hereby placed in the public domain. 19 | 20 | local MARK = "////////" 21 | local NAME = "luac" 22 | 23 | local MODULE_NAME = table.remove(arg, 1) 24 | local OUTPUT = table.remove(arg, 1) 25 | local BASE_DIR = table.remove(arg, 1) 26 | NAME = "=("..NAME..")" 27 | 28 | local argCount = #arg 29 | local executableIndex = n 30 | local b 31 | 32 | for i = 1, argCount do 33 | if arg[i] == "-L" then executableIndex = i - 1 break end 34 | end 35 | 36 | if executableIndex + 2 <= argCount then b = "local t=package.preload;\n" else b = "local t;\n" end 37 | 38 | for i = executableIndex + 2, argCount do 39 | local requireString = string.gsub(arg[i], "^" .. string.gsub(BASE_DIR, "(%W)", "%%%1"), "") 40 | requireString = string.gsub(requireString,"^[\./]*(.-)\.lua$", "%1") 41 | requireString = string.gsub(requireString, "/", ".") 42 | requireString = string.gsub(requireString, ".init$", "") -- if it is an init file within a directory... ignore it! 43 | if MODULE_NAME and #MODULE_NAME > 0 then requireString = MODULE_NAME .. "." .. requireString end 44 | 45 | b = b.."t['"..requireString.."']=function()end;\n" 46 | arg[i]=string.sub(string.dump(assert(loadfile(arg[i]))), 13) -- string.sub Removes header from file 47 | end 48 | b = b.."t='"..MARK.."';\n" 49 | 50 | for i = 1, executableIndex do 51 | b = b.."(function()end)();\n" 52 | arg[i]=string.sub(string.dump(assert(loadfile(arg[i]))), 13) -- string.sub Removes header from file 53 | end 54 | 55 | b = string.dump(assert(loadstring(b, NAME))) 56 | local x, y = string.find(b, MARK) 57 | -- 64 58 | b = string.sub(b, 1, x - 6 - 4).."\0"..string.sub(b, y + 2, y + 5) -- WTF does this do? 59 | 60 | -- 32 61 | -- b = string.sub(b, 1, x - 6).."\0"..string.sub(b, y + 2, y + 5) -- WTF does this do? 62 | -- print("luac complie 32 bit lua") 63 | 64 | f = assert(io.open(OUTPUT, "wb")) 65 | 66 | assert(f:write(b)) 67 | 68 | for i = executableIndex + 2, argCount do 69 | assert(f:write(arg[i])) 70 | end 71 | 72 | for i=1,executableIndex do 73 | assert(f:write(arg[i])) 74 | end 75 | 76 | -- 64 77 | assert(f:write(string.rep("\0", 3 * 8))) 78 | print("end complie lua 64") 79 | 80 | -- 32 81 | -- assert(f:write(string.rep("\0", 12))) 82 | -- print("luac complie 32 bit lua") 83 | assert(f:close()) -------------------------------------------------------------------------------- /spa/Spa/libffi/include/ffi/ffi.h: -------------------------------------------------------------------------------- 1 | #ifdef __arm64__ 2 | 3 | #include "ffi_arm64.h" 4 | 5 | 6 | #endif 7 | #ifdef __i386__ 8 | 9 | #include "ffi_i386.h" 10 | 11 | 12 | #endif 13 | #ifdef __arm__ 14 | 15 | #include "ffi_armv7.h" 16 | 17 | 18 | #endif 19 | #ifdef __x86_64__ 20 | 21 | #include "ffi_x86_64.h" 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /spa/Spa/libffi/include/ffi/ffitarget.h: -------------------------------------------------------------------------------- 1 | #ifdef __arm64__ 2 | 3 | #include "ffitarget_arm64.h" 4 | 5 | 6 | #endif 7 | #ifdef __i386__ 8 | 9 | #include "ffitarget_i386.h" 10 | 11 | 12 | #endif 13 | #ifdef __arm__ 14 | 15 | #include "ffitarget_armv7.h" 16 | 17 | 18 | #endif 19 | #ifdef __x86_64__ 20 | 21 | #include "ffitarget_x86_64.h" 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /spa/Spa/libffi/include/ffi/ffitarget_arm64.h: -------------------------------------------------------------------------------- 1 | #ifdef __arm64__ 2 | 3 | /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | ``Software''), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | 24 | #ifndef LIBFFI_TARGET_H 25 | #define LIBFFI_TARGET_H 26 | 27 | #ifndef LIBFFI_H 28 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 29 | #endif 30 | 31 | #ifndef LIBFFI_ASM 32 | #ifdef __ILP32__ 33 | #define FFI_SIZEOF_ARG 8 34 | #define FFI_SIZEOF_JAVA_RAW 4 35 | typedef unsigned long long ffi_arg; 36 | typedef signed long long ffi_sarg; 37 | #else 38 | typedef unsigned long ffi_arg; 39 | typedef signed long ffi_sarg; 40 | #endif 41 | 42 | typedef enum ffi_abi 43 | { 44 | FFI_FIRST_ABI = 0, 45 | FFI_SYSV, 46 | FFI_LAST_ABI, 47 | FFI_DEFAULT_ABI = FFI_SYSV 48 | } ffi_abi; 49 | #endif 50 | 51 | /* ---- Definitions for closures ----------------------------------------- */ 52 | 53 | #define FFI_CLOSURES 1 54 | #define FFI_NATIVE_RAW_API 0 55 | 56 | #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE 57 | 58 | #ifdef __MACH__ 59 | #define FFI_TRAMPOLINE_SIZE 16 60 | #define FFI_TRAMPOLINE_CLOSURE_OFFSET 16 61 | #else 62 | #error "No trampoline table implementation" 63 | #endif 64 | 65 | #else 66 | #define FFI_TRAMPOLINE_SIZE 24 67 | #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE 68 | #endif 69 | 70 | /* ---- Internal ---- */ 71 | 72 | #if defined (__APPLE__) 73 | #define FFI_TARGET_SPECIFIC_VARIADIC 74 | #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs 75 | #else 76 | /* iOS reserves x18 for the system. Disable Go closures until 77 | a new static chain is chosen. */ 78 | #define FFI_GO_CLOSURES 1 79 | #endif 80 | 81 | #define FFI_TARGET_HAS_COMPLEX_TYPE 82 | 83 | #endif 84 | 85 | 86 | #endif -------------------------------------------------------------------------------- /spa/Spa/libffi/include/ffi/ffitarget_armv7.h: -------------------------------------------------------------------------------- 1 | #ifdef __arm__ 2 | 3 | /* -----------------------------------------------------------------*-C-*- 4 | ffitarget.h - Copyright (c) 2012 Anthony Green 5 | Copyright (c) 2010 CodeSourcery 6 | Copyright (c) 1996-2003 Red Hat, Inc. 7 | 8 | Target configuration macros for ARM. 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining 11 | a copy of this software and associated documentation files (the 12 | ``Software''), to deal in the Software without restriction, including 13 | without limitation the rights to use, copy, modify, merge, publish, 14 | distribute, sublicense, and/or sell copies of the Software, and to 15 | permit persons to whom the Software is furnished to do so, subject to 16 | the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included 19 | in all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 22 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28 | DEALINGS IN THE SOFTWARE. 29 | 30 | ----------------------------------------------------------------------- */ 31 | 32 | #ifndef LIBFFI_TARGET_H 33 | #define LIBFFI_TARGET_H 34 | 35 | #ifndef LIBFFI_H 36 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 37 | #endif 38 | 39 | #ifndef LIBFFI_ASM 40 | typedef unsigned long ffi_arg; 41 | typedef signed long ffi_sarg; 42 | 43 | typedef enum ffi_abi { 44 | FFI_FIRST_ABI = 0, 45 | FFI_SYSV, 46 | FFI_VFP, 47 | FFI_LAST_ABI, 48 | #ifdef __ARM_PCS_VFP 49 | FFI_DEFAULT_ABI = FFI_VFP, 50 | #else 51 | FFI_DEFAULT_ABI = FFI_SYSV, 52 | #endif 53 | } ffi_abi; 54 | #endif 55 | 56 | #define FFI_EXTRA_CIF_FIELDS \ 57 | int vfp_used; \ 58 | unsigned short vfp_reg_free, vfp_nargs; \ 59 | signed char vfp_args[16] \ 60 | 61 | #define FFI_TARGET_SPECIFIC_VARIADIC 62 | #define FFI_TARGET_HAS_COMPLEX_TYPE 63 | 64 | /* ---- Definitions for closures ----------------------------------------- */ 65 | 66 | #define FFI_CLOSURES 1 67 | #define FFI_GO_CLOSURES 1 68 | #define FFI_NATIVE_RAW_API 0 69 | 70 | #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE 71 | 72 | #ifdef __MACH__ 73 | #define FFI_TRAMPOLINE_SIZE 12 74 | #define FFI_TRAMPOLINE_CLOSURE_OFFSET 8 75 | #else 76 | #error "No trampoline table implementation" 77 | #endif 78 | 79 | #else 80 | #define FFI_TRAMPOLINE_SIZE 12 81 | #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE 82 | #endif 83 | 84 | #endif 85 | 86 | 87 | #endif -------------------------------------------------------------------------------- /spa/Spa/libffi/include/ffi/ffitarget_i386.h: -------------------------------------------------------------------------------- 1 | #ifdef __i386__ 2 | 3 | /* -----------------------------------------------------------------*-C-*- 4 | ffitarget.h - Copyright (c) 2012, 2014 Anthony Green 5 | Copyright (c) 1996-2003, 2010 Red Hat, Inc. 6 | Copyright (C) 2008 Free Software Foundation, Inc. 7 | 8 | Target configuration macros for x86 and x86-64. 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining 11 | a copy of this software and associated documentation files (the 12 | ``Software''), to deal in the Software without restriction, including 13 | without limitation the rights to use, copy, modify, merge, publish, 14 | distribute, sublicense, and/or sell copies of the Software, and to 15 | permit persons to whom the Software is furnished to do so, subject to 16 | the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included 19 | in all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 22 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28 | DEALINGS IN THE SOFTWARE. 29 | 30 | ----------------------------------------------------------------------- */ 31 | 32 | #ifndef LIBFFI_TARGET_H 33 | #define LIBFFI_TARGET_H 34 | 35 | #ifndef LIBFFI_H 36 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 37 | #endif 38 | 39 | /* ---- System specific configurations ----------------------------------- */ 40 | 41 | /* For code common to all platforms on x86 and x86_64. */ 42 | #define X86_ANY 43 | 44 | #if defined (X86_64) && defined (__i386__) 45 | #undef X86_64 46 | #define X86 47 | #endif 48 | 49 | #ifdef X86_WIN64 50 | #define FFI_SIZEOF_ARG 8 51 | #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */ 52 | #endif 53 | 54 | #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 55 | #ifndef _MSC_VER 56 | #define FFI_TARGET_HAS_COMPLEX_TYPE 57 | #endif 58 | 59 | /* ---- Generic type definitions ----------------------------------------- */ 60 | 61 | #ifndef LIBFFI_ASM 62 | #ifdef X86_WIN64 63 | #ifdef _MSC_VER 64 | typedef unsigned __int64 ffi_arg; 65 | typedef __int64 ffi_sarg; 66 | #else 67 | typedef unsigned long long ffi_arg; 68 | typedef long long ffi_sarg; 69 | #endif 70 | #else 71 | #if defined __x86_64__ && defined __ILP32__ 72 | #define FFI_SIZEOF_ARG 8 73 | #define FFI_SIZEOF_JAVA_RAW 4 74 | typedef unsigned long long ffi_arg; 75 | typedef long long ffi_sarg; 76 | #else 77 | typedef unsigned long ffi_arg; 78 | typedef signed long ffi_sarg; 79 | #endif 80 | #endif 81 | 82 | typedef enum ffi_abi { 83 | #if defined(X86_WIN64) 84 | FFI_FIRST_ABI = 0, 85 | FFI_WIN64, 86 | FFI_LAST_ABI, 87 | FFI_DEFAULT_ABI = FFI_WIN64 88 | 89 | #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN)) 90 | FFI_FIRST_ABI = 1, 91 | FFI_UNIX64, 92 | FFI_WIN64, 93 | FFI_EFI64 = FFI_WIN64, 94 | FFI_LAST_ABI, 95 | FFI_DEFAULT_ABI = FFI_UNIX64 96 | 97 | #elif defined(X86_WIN32) 98 | FFI_FIRST_ABI = 0, 99 | FFI_SYSV = 1, 100 | FFI_STDCALL = 2, 101 | FFI_THISCALL = 3, 102 | FFI_FASTCALL = 4, 103 | FFI_MS_CDECL = 5, 104 | FFI_PASCAL = 6, 105 | FFI_REGISTER = 7, 106 | FFI_LAST_ABI, 107 | FFI_DEFAULT_ABI = FFI_MS_CDECL 108 | #else 109 | FFI_FIRST_ABI = 0, 110 | FFI_SYSV = 1, 111 | FFI_THISCALL = 3, 112 | FFI_FASTCALL = 4, 113 | FFI_STDCALL = 5, 114 | FFI_PASCAL = 6, 115 | FFI_REGISTER = 7, 116 | FFI_MS_CDECL = 8, 117 | FFI_LAST_ABI, 118 | FFI_DEFAULT_ABI = FFI_SYSV 119 | #endif 120 | } ffi_abi; 121 | #endif 122 | 123 | /* ---- Definitions for closures ----------------------------------------- */ 124 | 125 | #define FFI_CLOSURES 1 126 | #define FFI_GO_CLOSURES 1 127 | 128 | #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1) 129 | #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2) 130 | #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3) 131 | #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4) 132 | 133 | #if defined (X86_64) || defined(X86_WIN64) \ 134 | || (defined (__x86_64__) && defined (X86_DARWIN)) 135 | # define FFI_TRAMPOLINE_SIZE 24 136 | # define FFI_NATIVE_RAW_API 0 137 | #else 138 | # define FFI_TRAMPOLINE_SIZE 12 139 | # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ 140 | #endif 141 | 142 | #endif 143 | 144 | 145 | 146 | #endif -------------------------------------------------------------------------------- /spa/Spa/libffi/include/ffi/ffitarget_x86_64.h: -------------------------------------------------------------------------------- 1 | #ifdef __x86_64__ 2 | 3 | /* -----------------------------------------------------------------*-C-*- 4 | ffitarget.h - Copyright (c) 2012, 2014 Anthony Green 5 | Copyright (c) 1996-2003, 2010 Red Hat, Inc. 6 | Copyright (C) 2008 Free Software Foundation, Inc. 7 | 8 | Target configuration macros for x86 and x86-64. 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining 11 | a copy of this software and associated documentation files (the 12 | ``Software''), to deal in the Software without restriction, including 13 | without limitation the rights to use, copy, modify, merge, publish, 14 | distribute, sublicense, and/or sell copies of the Software, and to 15 | permit persons to whom the Software is furnished to do so, subject to 16 | the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included 19 | in all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 22 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28 | DEALINGS IN THE SOFTWARE. 29 | 30 | ----------------------------------------------------------------------- */ 31 | 32 | #ifndef LIBFFI_TARGET_H 33 | #define LIBFFI_TARGET_H 34 | 35 | #ifndef LIBFFI_H 36 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 37 | #endif 38 | 39 | /* ---- System specific configurations ----------------------------------- */ 40 | 41 | /* For code common to all platforms on x86 and x86_64. */ 42 | #define X86_ANY 43 | 44 | #if defined (X86_64) && defined (__i386__) 45 | #undef X86_64 46 | #define X86 47 | #endif 48 | 49 | #ifdef X86_WIN64 50 | #define FFI_SIZEOF_ARG 8 51 | #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */ 52 | #endif 53 | 54 | #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 55 | #ifndef _MSC_VER 56 | #define FFI_TARGET_HAS_COMPLEX_TYPE 57 | #endif 58 | 59 | /* ---- Generic type definitions ----------------------------------------- */ 60 | 61 | #ifndef LIBFFI_ASM 62 | #ifdef X86_WIN64 63 | #ifdef _MSC_VER 64 | typedef unsigned __int64 ffi_arg; 65 | typedef __int64 ffi_sarg; 66 | #else 67 | typedef unsigned long long ffi_arg; 68 | typedef long long ffi_sarg; 69 | #endif 70 | #else 71 | #if defined __x86_64__ && defined __ILP32__ 72 | #define FFI_SIZEOF_ARG 8 73 | #define FFI_SIZEOF_JAVA_RAW 4 74 | typedef unsigned long long ffi_arg; 75 | typedef long long ffi_sarg; 76 | #else 77 | typedef unsigned long ffi_arg; 78 | typedef signed long ffi_sarg; 79 | #endif 80 | #endif 81 | 82 | typedef enum ffi_abi { 83 | #if defined(X86_WIN64) 84 | FFI_FIRST_ABI = 0, 85 | FFI_WIN64, 86 | FFI_LAST_ABI, 87 | FFI_DEFAULT_ABI = FFI_WIN64 88 | 89 | #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN)) 90 | FFI_FIRST_ABI = 1, 91 | FFI_UNIX64, 92 | FFI_WIN64, 93 | FFI_EFI64 = FFI_WIN64, 94 | FFI_LAST_ABI, 95 | FFI_DEFAULT_ABI = FFI_UNIX64 96 | 97 | #elif defined(X86_WIN32) 98 | FFI_FIRST_ABI = 0, 99 | FFI_SYSV = 1, 100 | FFI_STDCALL = 2, 101 | FFI_THISCALL = 3, 102 | FFI_FASTCALL = 4, 103 | FFI_MS_CDECL = 5, 104 | FFI_PASCAL = 6, 105 | FFI_REGISTER = 7, 106 | FFI_LAST_ABI, 107 | FFI_DEFAULT_ABI = FFI_MS_CDECL 108 | #else 109 | FFI_FIRST_ABI = 0, 110 | FFI_SYSV = 1, 111 | FFI_THISCALL = 3, 112 | FFI_FASTCALL = 4, 113 | FFI_STDCALL = 5, 114 | FFI_PASCAL = 6, 115 | FFI_REGISTER = 7, 116 | FFI_MS_CDECL = 8, 117 | FFI_LAST_ABI, 118 | FFI_DEFAULT_ABI = FFI_SYSV 119 | #endif 120 | } ffi_abi; 121 | #endif 122 | 123 | /* ---- Definitions for closures ----------------------------------------- */ 124 | 125 | #define FFI_CLOSURES 1 126 | #define FFI_GO_CLOSURES 1 127 | 128 | #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1) 129 | #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2) 130 | #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3) 131 | #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4) 132 | 133 | #if defined (X86_64) || defined(X86_WIN64) \ 134 | || (defined (__x86_64__) && defined (X86_DARWIN)) 135 | # define FFI_TRAMPOLINE_SIZE 24 136 | # define FFI_NATIVE_RAW_API 0 137 | #else 138 | # define FFI_TRAMPOLINE_SIZE 12 139 | # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ 140 | #endif 141 | 142 | #endif 143 | 144 | 145 | 146 | #endif -------------------------------------------------------------------------------- /spa/Spa/libffi/libffi.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzfanfei/spa/1184d64e440ee85b050d7cedc8432110bb776b9d/spa/Spa/libffi/libffi.a -------------------------------------------------------------------------------- /spa/Spa/libffi/libffi_sim.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzfanfei/spa/1184d64e440ee85b050d7cedc8432110bb776b9d/spa/Spa/libffi/libffi_sim.a -------------------------------------------------------------------------------- /spa/Spa/lua/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /spa/Spa/lua/lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Auxiliary functions for building Lua libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lauxlib_h 9 | #define lauxlib_h 10 | 11 | 12 | #include 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | 18 | #if defined(LUA_COMPAT_GETN) 19 | LUALIB_API int (luaL_getn) (lua_State *L, int t); 20 | LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); 21 | #else 22 | #define luaL_getn(L,i) ((int)lua_objlen(L, i)) 23 | #define luaL_setn(L,i,j) ((void)0) /* no op! */ 24 | #endif 25 | 26 | #if defined(LUA_COMPAT_OPENLIB) 27 | #define luaI_openlib luaL_openlib 28 | #endif 29 | 30 | 31 | /* extra error code for `luaL_load' */ 32 | #define LUA_ERRFILE (LUA_ERRERR+1) 33 | 34 | 35 | typedef struct luaL_Reg { 36 | const char *name; 37 | lua_CFunction func; 38 | } luaL_Reg; 39 | 40 | 41 | 42 | LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, 43 | const luaL_Reg *l, int nup); 44 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, 45 | const luaL_Reg *l); 46 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 47 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 48 | LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); 49 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); 50 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, 51 | size_t *l); 52 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, 53 | const char *def, size_t *l); 54 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); 55 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); 56 | 57 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); 58 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, 59 | lua_Integer def); 60 | 61 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 62 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); 63 | LUALIB_API void (luaL_checkany) (lua_State *L, int narg); 64 | 65 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 66 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 67 | 68 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 69 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 70 | 71 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, 72 | const char *const lst[]); 73 | 74 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 75 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 76 | 77 | LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); 78 | LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, 79 | const char *name); 80 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 81 | 82 | LUALIB_API lua_State *(luaL_newstate) (void); 83 | 84 | 85 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 86 | const char *r); 87 | 88 | LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, 89 | const char *fname, int szhint); 90 | 91 | 92 | 93 | 94 | /* 95 | ** =============================================================== 96 | ** some useful macros 97 | ** =============================================================== 98 | */ 99 | 100 | #define luaL_argcheck(L, cond,numarg,extramsg) \ 101 | ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) 102 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 103 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 104 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 105 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 106 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 107 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 108 | 109 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 110 | 111 | #define luaL_dofile(L, fn) \ 112 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 113 | 114 | #define luaL_dostring(L, s) \ 115 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 116 | 117 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 118 | 119 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 120 | 121 | /* 122 | ** {====================================================== 123 | ** Generic Buffer manipulation 124 | ** ======================================================= 125 | */ 126 | 127 | 128 | 129 | typedef struct luaL_Buffer { 130 | char *p; /* current position in buffer */ 131 | int lvl; /* number of strings in the stack (level) */ 132 | lua_State *L; 133 | char buffer[LUAL_BUFFERSIZE]; 134 | } luaL_Buffer; 135 | 136 | #define luaL_addchar(B,c) \ 137 | ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ 138 | (*(B)->p++ = (char)(c))) 139 | 140 | /* compatibility only */ 141 | #define luaL_putchar(B,c) luaL_addchar(B,c) 142 | 143 | #define luaL_addsize(B,n) ((B)->p += (n)) 144 | 145 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 146 | LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); 147 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 148 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 149 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 150 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 151 | 152 | 153 | /* }====================================================== */ 154 | 155 | 156 | /* compatibility with ref system */ 157 | 158 | /* pre-defined references */ 159 | #define LUA_NOREF (-2) 160 | #define LUA_REFNIL (-1) 161 | 162 | #define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ 163 | (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) 164 | 165 | #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) 166 | 167 | #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) 168 | 169 | 170 | #define luaL_reg luaL_Reg 171 | 172 | #endif 173 | 174 | 175 | -------------------------------------------------------------------------------- /spa/Spa/lua/lcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Code generator for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lcode_h 8 | #define lcode_h 9 | 10 | #include "llex.h" 11 | #include "lobject.h" 12 | #include "lopcodes.h" 13 | #include "lparser.h" 14 | 15 | 16 | /* 17 | ** Marks the end of a patch list. It is an invalid value both as an absolute 18 | ** address, and as a list link (would link an element to itself). 19 | */ 20 | #define NO_JUMP (-1) 21 | 22 | 23 | /* 24 | ** grep "ORDER OPR" if you change these enums 25 | */ 26 | typedef enum BinOpr { 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, 28 | OPR_CONCAT, 29 | OPR_NE, OPR_EQ, 30 | OPR_LT, OPR_LE, OPR_GT, OPR_GE, 31 | OPR_AND, OPR_OR, 32 | OPR_NOBINOPR 33 | } BinOpr; 34 | 35 | 36 | typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 37 | 38 | 39 | #define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) 40 | 41 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) 42 | 43 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 44 | 45 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 46 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); 47 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 48 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 49 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 50 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 51 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); 52 | LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); 53 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 54 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 55 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 56 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 57 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 58 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 59 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 60 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 61 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 62 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 63 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 64 | LUAI_FUNC int luaK_jump (FuncState *fs); 65 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 66 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 67 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 68 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 69 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 70 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); 71 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 72 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); 73 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 74 | 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /spa/Spa/lua/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) 15 | 16 | #define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) 17 | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) 19 | 20 | 21 | LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, 22 | const char *opname); 23 | LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); 24 | LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, 25 | const TValue *p2); 26 | LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, 27 | const TValue *p2); 28 | LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); 29 | LUAI_FUNC void luaG_errormsg (lua_State *L); 30 | LUAI_FUNC int luaG_checkcode (const Proto *pt); 31 | LUAI_FUNC int luaG_checkopenop (Instruction i); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /spa/Spa/lua/ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Stack and Call structure of Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldo_h 8 | #define ldo_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | #include "lzio.h" 14 | 15 | 16 | #define luaD_checkstack(L,n) \ 17 | if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ 18 | luaD_growstack(L, n); \ 19 | else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); 20 | 21 | 22 | #define incr_top(L) {luaD_checkstack(L,1); L->top++;} 23 | 24 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 25 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 26 | 27 | #define saveci(L,p) ((char *)(p) - (char *)L->base_ci) 28 | #define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) 29 | 30 | 31 | /* results from luaD_precall */ 32 | #define PCRLUA 0 /* initiated a call to a Lua function */ 33 | #define PCRC 1 /* did a call to a C function */ 34 | #define PCRYIELD 2 /* C funtion yielded */ 35 | 36 | 37 | /* type of protected functions, to be ran by `runprotected' */ 38 | typedef void (*Pfunc) (lua_State *L, void *ud); 39 | 40 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); 41 | LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); 42 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); 43 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 44 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 45 | ptrdiff_t oldtop, ptrdiff_t ef); 46 | LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); 47 | LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize); 48 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); 49 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); 50 | 51 | LUAI_FUNC void luaD_throw (lua_State *L, int errcode); 52 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 53 | 54 | LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /spa/Spa/lua/ldump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** save precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | 9 | #define ldump_c 10 | #define LUA_CORE 11 | 12 | #include "lua.h" 13 | 14 | #include "lobject.h" 15 | #include "lstate.h" 16 | #include "lundump.h" 17 | 18 | typedef struct { 19 | lua_State* L; 20 | lua_Writer writer; 21 | void* data; 22 | int strip; 23 | int status; 24 | } DumpState; 25 | 26 | #define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) 27 | #define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) 28 | 29 | static void DumpBlock(const void* b, size_t size, DumpState* D) 30 | { 31 | if (D->status==0) 32 | { 33 | lua_unlock(D->L); 34 | D->status=(*D->writer)(D->L,b,size,D->data); 35 | lua_lock(D->L); 36 | } 37 | } 38 | 39 | static void DumpChar(int y, DumpState* D) 40 | { 41 | char x=(char)y; 42 | DumpVar(x,D); 43 | } 44 | 45 | static void DumpInt(int x, DumpState* D) 46 | { 47 | DumpVar(x,D); 48 | } 49 | 50 | static void DumpNumber(lua_Number x, DumpState* D) 51 | { 52 | DumpVar(x,D); 53 | } 54 | 55 | static void DumpVector(const void* b, int n, size_t size, DumpState* D) 56 | { 57 | DumpInt(n,D); 58 | DumpMem(b,n,size,D); 59 | } 60 | 61 | static void DumpString(const TString* s, DumpState* D) 62 | { 63 | if (s==NULL || getstr(s)==NULL) 64 | { 65 | size_t size=0; 66 | DumpVar(size,D); 67 | } 68 | else 69 | { 70 | size_t size=s->tsv.len+1; /* include trailing '\0' */ 71 | DumpVar(size,D); 72 | DumpBlock(getstr(s),size,D); 73 | } 74 | } 75 | 76 | #define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) 77 | 78 | static void DumpFunction(const Proto* f, const TString* p, DumpState* D); 79 | 80 | static void DumpConstants(const Proto* f, DumpState* D) 81 | { 82 | int i,n=f->sizek; 83 | DumpInt(n,D); 84 | for (i=0; ik[i]; 87 | DumpChar(ttype(o),D); 88 | switch (ttype(o)) 89 | { 90 | case LUA_TNIL: 91 | break; 92 | case LUA_TBOOLEAN: 93 | DumpChar(bvalue(o),D); 94 | break; 95 | case LUA_TNUMBER: 96 | DumpNumber(nvalue(o),D); 97 | break; 98 | case LUA_TSTRING: 99 | DumpString(rawtsvalue(o),D); 100 | break; 101 | default: 102 | lua_assert(0); /* cannot happen */ 103 | break; 104 | } 105 | } 106 | n=f->sizep; 107 | DumpInt(n,D); 108 | for (i=0; ip[i],f->source,D); 109 | } 110 | 111 | static void DumpDebug(const Proto* f, DumpState* D) 112 | { 113 | int i,n; 114 | n= (D->strip) ? 0 : f->sizelineinfo; 115 | DumpVector(f->lineinfo,n,sizeof(int),D); 116 | n= (D->strip) ? 0 : f->sizelocvars; 117 | DumpInt(n,D); 118 | for (i=0; ilocvars[i].varname,D); 121 | DumpInt(f->locvars[i].startpc,D); 122 | DumpInt(f->locvars[i].endpc,D); 123 | } 124 | n= (D->strip) ? 0 : f->sizeupvalues; 125 | DumpInt(n,D); 126 | for (i=0; iupvalues[i],D); 127 | } 128 | 129 | static void DumpFunction(const Proto* f, const TString* p, DumpState* D) 130 | { 131 | DumpString((f->source==p || D->strip) ? NULL : f->source,D); 132 | DumpInt(f->linedefined,D); 133 | DumpInt(f->lastlinedefined,D); 134 | DumpChar(f->nups,D); 135 | DumpChar(f->numparams,D); 136 | DumpChar(f->is_vararg,D); 137 | DumpChar(f->maxstacksize,D); 138 | DumpCode(f,D); 139 | DumpConstants(f,D); 140 | DumpDebug(f,D); 141 | } 142 | 143 | static void DumpHeader(DumpState* D) 144 | { 145 | char h[LUAC_HEADERSIZE]; 146 | luaU_header(h); 147 | DumpBlock(h,LUAC_HEADERSIZE,D); 148 | } 149 | 150 | /* 151 | ** dump Lua function as precompiled chunk 152 | */ 153 | int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) 154 | { 155 | DumpState D; 156 | D.L=L; 157 | D.writer=w; 158 | D.data=data; 159 | D.strip=strip; 160 | D.status=0; 161 | DumpHeader(&D); 162 | DumpFunction(f,NULL,&D); 163 | return D.status; 164 | } 165 | -------------------------------------------------------------------------------- /spa/Spa/lua/lfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lfunc_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "lfunc.h" 16 | #include "lgc.h" 17 | #include "lmem.h" 18 | #include "lobject.h" 19 | #include "lstate.h" 20 | 21 | 22 | 23 | Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { 24 | Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); 25 | luaC_link(L, obj2gco(c), LUA_TFUNCTION); 26 | c->c.isC = 1; 27 | c->c.env = e; 28 | c->c.nupvalues = cast_byte(nelems); 29 | return c; 30 | } 31 | 32 | 33 | Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { 34 | Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); 35 | luaC_link(L, obj2gco(c), LUA_TFUNCTION); 36 | c->l.isC = 0; 37 | c->l.env = e; 38 | c->l.nupvalues = cast_byte(nelems); 39 | while (nelems--) c->l.upvals[nelems] = NULL; 40 | return c; 41 | } 42 | 43 | 44 | UpVal *luaF_newupval (lua_State *L) { 45 | UpVal *uv = luaM_new(L, UpVal); 46 | luaC_link(L, obj2gco(uv), LUA_TUPVAL); 47 | uv->v = &uv->u.value; 48 | setnilvalue(uv->v); 49 | return uv; 50 | } 51 | 52 | 53 | UpVal *luaF_findupval (lua_State *L, StkId level) { 54 | global_State *g = G(L); 55 | GCObject **pp = &L->openupval; 56 | UpVal *p; 57 | UpVal *uv; 58 | while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { 59 | lua_assert(p->v != &p->u.value); 60 | if (p->v == level) { /* found a corresponding upvalue? */ 61 | if (isdead(g, obj2gco(p))) /* is it dead? */ 62 | changewhite(obj2gco(p)); /* ressurect it */ 63 | return p; 64 | } 65 | pp = &p->next; 66 | } 67 | uv = luaM_new(L, UpVal); /* not found: create a new one */ 68 | uv->tt = LUA_TUPVAL; 69 | uv->marked = luaC_white(g); 70 | uv->v = level; /* current value lives in the stack */ 71 | uv->next = *pp; /* chain it in the proper position */ 72 | *pp = obj2gco(uv); 73 | uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ 74 | uv->u.l.next = g->uvhead.u.l.next; 75 | uv->u.l.next->u.l.prev = uv; 76 | g->uvhead.u.l.next = uv; 77 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); 78 | return uv; 79 | } 80 | 81 | 82 | static void unlinkupval (UpVal *uv) { 83 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); 84 | uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ 85 | uv->u.l.prev->u.l.next = uv->u.l.next; 86 | } 87 | 88 | 89 | void luaF_freeupval (lua_State *L, UpVal *uv) { 90 | if (uv->v != &uv->u.value) /* is it open? */ 91 | unlinkupval(uv); /* remove from open list */ 92 | luaM_free(L, uv); /* free upvalue */ 93 | } 94 | 95 | 96 | void luaF_close (lua_State *L, StkId level) { 97 | UpVal *uv; 98 | global_State *g = G(L); 99 | while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { 100 | GCObject *o = obj2gco(uv); 101 | lua_assert(!isblack(o) && uv->v != &uv->u.value); 102 | L->openupval = uv->next; /* remove from `open' list */ 103 | if (isdead(g, o)) 104 | luaF_freeupval(L, uv); /* free upvalue */ 105 | else { 106 | unlinkupval(uv); 107 | setobj(L, &uv->u.value, uv->v); 108 | uv->v = &uv->u.value; /* now current value lives here */ 109 | luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ 110 | } 111 | } 112 | } 113 | 114 | 115 | Proto *luaF_newproto (lua_State *L) { 116 | Proto *f = luaM_new(L, Proto); 117 | luaC_link(L, obj2gco(f), LUA_TPROTO); 118 | f->k = NULL; 119 | f->sizek = 0; 120 | f->p = NULL; 121 | f->sizep = 0; 122 | f->code = NULL; 123 | f->sizecode = 0; 124 | f->sizelineinfo = 0; 125 | f->sizeupvalues = 0; 126 | f->nups = 0; 127 | f->upvalues = NULL; 128 | f->numparams = 0; 129 | f->is_vararg = 0; 130 | f->maxstacksize = 0; 131 | f->lineinfo = NULL; 132 | f->sizelocvars = 0; 133 | f->locvars = NULL; 134 | f->linedefined = 0; 135 | f->lastlinedefined = 0; 136 | f->source = NULL; 137 | return f; 138 | } 139 | 140 | 141 | void luaF_freeproto (lua_State *L, Proto *f) { 142 | luaM_freearray(L, f->code, f->sizecode, Instruction); 143 | luaM_freearray(L, f->p, f->sizep, Proto *); 144 | luaM_freearray(L, f->k, f->sizek, TValue); 145 | luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); 146 | luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); 147 | luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); 148 | luaM_free(L, f); 149 | } 150 | 151 | 152 | void luaF_freeclosure (lua_State *L, Closure *c) { 153 | int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : 154 | sizeLclosure(c->l.nupvalues); 155 | luaM_freemem(L, c, size); 156 | } 157 | 158 | 159 | /* 160 | ** Look for n-th local variable at line `line' in function `func'. 161 | ** Returns NULL if not found. 162 | */ 163 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 164 | int i; 165 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { 166 | if (pc < f->locvars[i].endpc) { /* is variable active? */ 167 | local_number--; 168 | if (local_number == 0) 169 | return getstr(f->locvars[i].varname); 170 | } 171 | } 172 | return NULL; /* not found */ 173 | } 174 | 175 | -------------------------------------------------------------------------------- /spa/Spa/lua/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ 15 | cast(int, sizeof(TValue)*((n)-1))) 16 | 17 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ 18 | cast(int, sizeof(TValue *)*((n)-1))) 19 | 20 | 21 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 22 | LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); 23 | LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); 24 | LUAI_FUNC UpVal *luaF_newupval (lua_State *L); 25 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 26 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); 27 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 28 | LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c); 29 | LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); 30 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 31 | int pc); 32 | 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /spa/Spa/lua/lgc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Garbage Collector 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lgc_h 8 | #define lgc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | /* 15 | ** Possible states of the Garbage Collector 16 | */ 17 | #define GCSpause 0 18 | #define GCSpropagate 1 19 | #define GCSsweepstring 2 20 | #define GCSsweep 3 21 | #define GCSfinalize 4 22 | 23 | 24 | /* 25 | ** some userful bit tricks 26 | */ 27 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) 28 | #define setbits(x,m) ((x) |= (m)) 29 | #define testbits(x,m) ((x) & (m)) 30 | #define bitmask(b) (1<<(b)) 31 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 32 | #define l_setbit(x,b) setbits(x, bitmask(b)) 33 | #define resetbit(x,b) resetbits(x, bitmask(b)) 34 | #define testbit(x,b) testbits(x, bitmask(b)) 35 | #define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) 36 | #define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) 37 | #define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) 38 | 39 | 40 | 41 | /* 42 | ** Layout for bit use in `marked' field: 43 | ** bit 0 - object is white (type 0) 44 | ** bit 1 - object is white (type 1) 45 | ** bit 2 - object is black 46 | ** bit 3 - for userdata: has been finalized 47 | ** bit 3 - for tables: has weak keys 48 | ** bit 4 - for tables: has weak values 49 | ** bit 5 - object is fixed (should not be collected) 50 | ** bit 6 - object is "super" fixed (only the main thread) 51 | */ 52 | 53 | 54 | #define WHITE0BIT 0 55 | #define WHITE1BIT 1 56 | #define BLACKBIT 2 57 | #define FINALIZEDBIT 3 58 | #define KEYWEAKBIT 3 59 | #define VALUEWEAKBIT 4 60 | #define FIXEDBIT 5 61 | #define SFIXEDBIT 6 62 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 63 | 64 | 65 | #define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) 66 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) 67 | #define isgray(x) (!isblack(x) && !iswhite(x)) 68 | 69 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) 70 | #define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) 71 | 72 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) 73 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) 74 | 75 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) 76 | 77 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) 78 | 79 | 80 | #define luaC_checkGC(L) { \ 81 | condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ 82 | if (G(L)->totalbytes >= G(L)->GCthreshold) \ 83 | luaC_step(L); } 84 | 85 | 86 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ 87 | luaC_barrierf(L,obj2gco(p),gcvalue(v)); } 88 | 89 | #define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ 90 | luaC_barrierback(L,t); } 91 | 92 | #define luaC_objbarrier(L,p,o) \ 93 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ 94 | luaC_barrierf(L,obj2gco(p),obj2gco(o)); } 95 | 96 | #define luaC_objbarriert(L,t,o) \ 97 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } 98 | 99 | LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); 100 | LUAI_FUNC void luaC_callGCTM (lua_State *L); 101 | LUAI_FUNC void luaC_freeall (lua_State *L); 102 | LUAI_FUNC void luaC_step (lua_State *L); 103 | LUAI_FUNC void luaC_fullgc (lua_State *L); 104 | LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); 105 | LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); 106 | LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); 107 | LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); 108 | 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /spa/Spa/lua/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Initialization of libraries for lua.c 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | #include "lua.h" 12 | 13 | #include "lualib.h" 14 | #include "lauxlib.h" 15 | 16 | 17 | static const luaL_Reg lualibs[] = { 18 | {"", luaopen_base}, 19 | {LUA_LOADLIBNAME, luaopen_package}, 20 | {LUA_TABLIBNAME, luaopen_table}, 21 | {LUA_IOLIBNAME, luaopen_io}, 22 | {LUA_OSLIBNAME, luaopen_os}, 23 | {LUA_STRLIBNAME, luaopen_string}, 24 | {LUA_MATHLIBNAME, luaopen_math}, 25 | {LUA_DBLIBNAME, luaopen_debug}, 26 | {NULL, NULL} 27 | }; 28 | 29 | 30 | LUALIB_API void luaL_openlibs (lua_State *L) { 31 | const luaL_Reg *lib = lualibs; 32 | for (; lib->func; lib++) { 33 | lua_pushcfunction(L, lib->func); 34 | lua_pushstring(L, lib->name); 35 | lua_call(L, 1, 0); 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /spa/Spa/lua/llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Lexical Analyzer 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llex_h 8 | #define llex_h 9 | 10 | #include "lobject.h" 11 | #include "lzio.h" 12 | 13 | 14 | #define FIRST_RESERVED 257 15 | 16 | /* maximum length of a reserved word */ 17 | #define TOKEN_LEN (sizeof("function")/sizeof(char)) 18 | 19 | 20 | /* 21 | * WARNING: if you change the order of this enumeration, 22 | * grep "ORDER RESERVED" 23 | */ 24 | enum RESERVED { 25 | /* terminal symbols denoted by reserved words */ 26 | TK_AND = FIRST_RESERVED, TK_BREAK, 27 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 28 | TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 29 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 30 | /* other terminal symbols */ 31 | TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, 32 | TK_NAME, TK_STRING, TK_EOS 33 | }; 34 | 35 | /* number of reserved words */ 36 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) 37 | 38 | 39 | /* array with token `names' */ 40 | LUAI_DATA const char *const luaX_tokens []; 41 | 42 | 43 | typedef union { 44 | lua_Number r; 45 | TString *ts; 46 | } SemInfo; /* semantics information */ 47 | 48 | 49 | typedef struct Token { 50 | int token; 51 | SemInfo seminfo; 52 | } Token; 53 | 54 | 55 | typedef struct LexState { 56 | int current; /* current character (charint) */ 57 | int linenumber; /* input line counter */ 58 | int lastline; /* line of last token `consumed' */ 59 | Token t; /* current token */ 60 | Token lookahead; /* look ahead token */ 61 | struct FuncState *fs; /* `FuncState' is private to the parser */ 62 | struct lua_State *L; 63 | ZIO *z; /* input stream */ 64 | Mbuffer *buff; /* buffer for tokens */ 65 | TString *source; /* current source name */ 66 | char decpoint; /* locale decimal point */ 67 | } LexState; 68 | 69 | 70 | LUAI_FUNC void luaX_init (lua_State *L); 71 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 72 | TString *source); 73 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 74 | LUAI_FUNC void luaX_next (LexState *ls); 75 | LUAI_FUNC void luaX_lookahead (LexState *ls); 76 | LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); 77 | LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s); 78 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /spa/Spa/lua/llimits.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Limits, basic types, and some other `installation-dependent' definitions 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llimits_h 8 | #define llimits_h 9 | 10 | 11 | #include 12 | #include 13 | 14 | 15 | #include "lua.h" 16 | #include 17 | 18 | typedef LUAI_UINT32 lu_int32; 19 | 20 | typedef LUAI_UMEM lu_mem; 21 | 22 | typedef LUAI_MEM l_mem; 23 | 24 | 25 | 26 | /* chars used as small naturals (so that `char' is reserved for characters) */ 27 | typedef unsigned char lu_byte; 28 | 29 | 30 | #define MAX_SIZET ((size_t)(~(size_t)0)-2) 31 | 32 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) 33 | 34 | 35 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ 36 | 37 | /* 38 | ** conversion of pointer to integer 39 | ** this is for hashing only; there is no problem if the integer 40 | ** cannot hold the whole pointer value 41 | */ 42 | #define IntPoint(p) ((unsigned int)(lu_mem)(p)) 43 | 44 | 45 | 46 | /* type to ensure maximum alignment */ 47 | typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; 48 | 49 | 50 | /* result of a `usual argument conversion' over lua_Number */ 51 | typedef LUAI_UACNUMBER l_uacNumber; 52 | 53 | 54 | /* internal assertions for in-house debugging */ 55 | #ifdef lua_assert 56 | 57 | #define check_exp(c,e) (lua_assert(c), (e)) 58 | #define api_check(l,e) lua_assert(e) 59 | 60 | #else 61 | 62 | #define lua_assert(c) ((void)0) 63 | #define check_exp(c,e) (e) 64 | #define api_check luai_apicheck 65 | 66 | #endif 67 | 68 | 69 | #ifndef UNUSED 70 | #define UNUSED(x) ((void)(x)) /* to avoid warnings */ 71 | #endif 72 | 73 | 74 | #ifndef cast 75 | #define cast(t, exp) ((t)(exp)) 76 | #endif 77 | 78 | #define cast_byte(i) cast(lu_byte, (i)) 79 | #define cast_num(i) cast(lua_Number, (i)) 80 | #define cast_int(i) cast(int, (i)) 81 | 82 | 83 | 84 | /* 85 | ** type for virtual-machine instructions 86 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) 87 | */ 88 | typedef lu_int32 Instruction; 89 | 90 | 91 | 92 | /* maximum stack for a Lua function */ 93 | #define MAXSTACK 250 94 | 95 | 96 | 97 | /* minimum size for the string table (must be power of 2) */ 98 | #ifndef MINSTRTABSIZE 99 | #define MINSTRTABSIZE 32 100 | #endif 101 | 102 | 103 | /* minimum size for string buffer */ 104 | #ifndef LUA_MINBUFFER 105 | #define LUA_MINBUFFER 32 106 | #endif 107 | 108 | #ifndef lua_lock 109 | //#define lua_lock(L) ((void) 0) 110 | //#define lua_unlock(L) ((void) 0) 111 | #define lua_lock(L) pthread_mutex_lock(&(G(L)->lock)); 112 | #define lua_unlock(L) pthread_mutex_unlock(&(G(L)->lock)); 113 | 114 | #endif 115 | 116 | #ifndef luai_threadyield 117 | #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} 118 | #endif 119 | 120 | 121 | /* 122 | ** macro to control inclusion of some hard tests on stack reallocation 123 | */ 124 | #ifndef HARDSTACKTESTS 125 | #define condhardstacktests(x) ((void)0) 126 | #else 127 | #define condhardstacktests(x) x 128 | #endif 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /spa/Spa/lua/lmathlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Standard mathematical library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | 11 | #define lmathlib_c 12 | #define LUA_LIB 13 | 14 | #include "lua.h" 15 | 16 | #include "lauxlib.h" 17 | #include "lualib.h" 18 | 19 | 20 | #undef PI 21 | #define PI (3.14159265358979323846) 22 | #define RADIANS_PER_DEGREE (PI/180.0) 23 | 24 | 25 | 26 | static int math_abs (lua_State *L) { 27 | lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); 28 | return 1; 29 | } 30 | 31 | static int math_sin (lua_State *L) { 32 | lua_pushnumber(L, sin(luaL_checknumber(L, 1))); 33 | return 1; 34 | } 35 | 36 | static int math_sinh (lua_State *L) { 37 | lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); 38 | return 1; 39 | } 40 | 41 | static int math_cos (lua_State *L) { 42 | lua_pushnumber(L, cos(luaL_checknumber(L, 1))); 43 | return 1; 44 | } 45 | 46 | static int math_cosh (lua_State *L) { 47 | lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); 48 | return 1; 49 | } 50 | 51 | static int math_tan (lua_State *L) { 52 | lua_pushnumber(L, tan(luaL_checknumber(L, 1))); 53 | return 1; 54 | } 55 | 56 | static int math_tanh (lua_State *L) { 57 | lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); 58 | return 1; 59 | } 60 | 61 | static int math_asin (lua_State *L) { 62 | lua_pushnumber(L, asin(luaL_checknumber(L, 1))); 63 | return 1; 64 | } 65 | 66 | static int math_acos (lua_State *L) { 67 | lua_pushnumber(L, acos(luaL_checknumber(L, 1))); 68 | return 1; 69 | } 70 | 71 | static int math_atan (lua_State *L) { 72 | lua_pushnumber(L, atan(luaL_checknumber(L, 1))); 73 | return 1; 74 | } 75 | 76 | static int math_atan2 (lua_State *L) { 77 | lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 78 | return 1; 79 | } 80 | 81 | static int math_ceil (lua_State *L) { 82 | lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); 83 | return 1; 84 | } 85 | 86 | static int math_floor (lua_State *L) { 87 | lua_pushnumber(L, floor(luaL_checknumber(L, 1))); 88 | return 1; 89 | } 90 | 91 | static int math_fmod (lua_State *L) { 92 | lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 93 | return 1; 94 | } 95 | 96 | static int math_modf (lua_State *L) { 97 | double ip; 98 | double fp = modf(luaL_checknumber(L, 1), &ip); 99 | lua_pushnumber(L, ip); 100 | lua_pushnumber(L, fp); 101 | return 2; 102 | } 103 | 104 | static int math_sqrt (lua_State *L) { 105 | lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); 106 | return 1; 107 | } 108 | 109 | static int math_pow (lua_State *L) { 110 | lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 111 | return 1; 112 | } 113 | 114 | static int math_log (lua_State *L) { 115 | lua_pushnumber(L, log(luaL_checknumber(L, 1))); 116 | return 1; 117 | } 118 | 119 | static int math_log10 (lua_State *L) { 120 | lua_pushnumber(L, log10(luaL_checknumber(L, 1))); 121 | return 1; 122 | } 123 | 124 | static int math_exp (lua_State *L) { 125 | lua_pushnumber(L, exp(luaL_checknumber(L, 1))); 126 | return 1; 127 | } 128 | 129 | static int math_deg (lua_State *L) { 130 | lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); 131 | return 1; 132 | } 133 | 134 | static int math_rad (lua_State *L) { 135 | lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); 136 | return 1; 137 | } 138 | 139 | static int math_frexp (lua_State *L) { 140 | int e; 141 | lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); 142 | lua_pushinteger(L, e); 143 | return 2; 144 | } 145 | 146 | static int math_ldexp (lua_State *L) { 147 | lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); 148 | return 1; 149 | } 150 | 151 | 152 | 153 | static int math_min (lua_State *L) { 154 | int n = lua_gettop(L); /* number of arguments */ 155 | lua_Number dmin = luaL_checknumber(L, 1); 156 | int i; 157 | for (i=2; i<=n; i++) { 158 | lua_Number d = luaL_checknumber(L, i); 159 | if (d < dmin) 160 | dmin = d; 161 | } 162 | lua_pushnumber(L, dmin); 163 | return 1; 164 | } 165 | 166 | 167 | static int math_max (lua_State *L) { 168 | int n = lua_gettop(L); /* number of arguments */ 169 | lua_Number dmax = luaL_checknumber(L, 1); 170 | int i; 171 | for (i=2; i<=n; i++) { 172 | lua_Number d = luaL_checknumber(L, i); 173 | if (d > dmax) 174 | dmax = d; 175 | } 176 | lua_pushnumber(L, dmax); 177 | return 1; 178 | } 179 | 180 | 181 | static int math_random (lua_State *L) { 182 | /* the `%' avoids the (rare) case of r==1, and is needed also because on 183 | some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ 184 | lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; 185 | switch (lua_gettop(L)) { /* check number of arguments */ 186 | case 0: { /* no arguments */ 187 | lua_pushnumber(L, r); /* Number between 0 and 1 */ 188 | break; 189 | } 190 | case 1: { /* only upper limit */ 191 | int u = luaL_checkint(L, 1); 192 | luaL_argcheck(L, 1<=u, 1, "interval is empty"); 193 | lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ 194 | break; 195 | } 196 | case 2: { /* lower and upper limits */ 197 | int l = luaL_checkint(L, 1); 198 | int u = luaL_checkint(L, 2); 199 | luaL_argcheck(L, l<=u, 2, "interval is empty"); 200 | lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ 201 | break; 202 | } 203 | default: return luaL_error(L, "wrong number of arguments"); 204 | } 205 | return 1; 206 | } 207 | 208 | 209 | static int math_randomseed (lua_State *L) { 210 | srand(luaL_checkint(L, 1)); 211 | return 0; 212 | } 213 | 214 | 215 | static const luaL_Reg mathlib[] = { 216 | {"abs", math_abs}, 217 | {"acos", math_acos}, 218 | {"asin", math_asin}, 219 | {"atan2", math_atan2}, 220 | {"atan", math_atan}, 221 | {"ceil", math_ceil}, 222 | {"cosh", math_cosh}, 223 | {"cos", math_cos}, 224 | {"deg", math_deg}, 225 | {"exp", math_exp}, 226 | {"floor", math_floor}, 227 | {"fmod", math_fmod}, 228 | {"frexp", math_frexp}, 229 | {"ldexp", math_ldexp}, 230 | {"log10", math_log10}, 231 | {"log", math_log}, 232 | {"max", math_max}, 233 | {"min", math_min}, 234 | {"modf", math_modf}, 235 | {"pow", math_pow}, 236 | {"rad", math_rad}, 237 | {"random", math_random}, 238 | {"randomseed", math_randomseed}, 239 | {"sinh", math_sinh}, 240 | {"sin", math_sin}, 241 | {"sqrt", math_sqrt}, 242 | {"tanh", math_tanh}, 243 | {"tan", math_tan}, 244 | {NULL, NULL} 245 | }; 246 | 247 | 248 | /* 249 | ** Open math library 250 | */ 251 | LUALIB_API int luaopen_math (lua_State *L) { 252 | luaL_register(L, LUA_MATHLIBNAME, mathlib); 253 | lua_pushnumber(L, PI); 254 | lua_setfield(L, -2, "pi"); 255 | lua_pushnumber(L, HUGE_VAL); 256 | lua_setfield(L, -2, "huge"); 257 | #if defined(LUA_COMPAT_MOD) 258 | lua_getfield(L, -1, "fmod"); 259 | lua_setfield(L, -2, "mod"); 260 | #endif 261 | return 1; 262 | } 263 | 264 | -------------------------------------------------------------------------------- /spa/Spa/lua/lmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lmem_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "ldebug.h" 16 | #include "ldo.h" 17 | #include "lmem.h" 18 | #include "lobject.h" 19 | #include "lstate.h" 20 | 21 | 22 | 23 | /* 24 | ** About the realloc function: 25 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 26 | ** (`osize' is the old size, `nsize' is the new size) 27 | ** 28 | ** Lua ensures that (ptr == NULL) iff (osize == 0). 29 | ** 30 | ** * frealloc(ud, NULL, 0, x) creates a new block of size `x' 31 | ** 32 | ** * frealloc(ud, p, x, 0) frees the block `p' 33 | ** (in this specific case, frealloc must return NULL). 34 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing 35 | ** (which is equivalent to free(NULL) in ANSI C) 36 | ** 37 | ** frealloc returns NULL if it cannot create or reallocate the area 38 | ** (any reallocation to an equal or smaller size cannot fail!) 39 | */ 40 | 41 | 42 | 43 | #define MINSIZEARRAY 4 44 | 45 | 46 | void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, 47 | int limit, const char *errormsg) { 48 | void *newblock; 49 | int newsize; 50 | if (*size >= limit/2) { /* cannot double it? */ 51 | if (*size >= limit) /* cannot grow even a little? */ 52 | luaG_runerror(L, errormsg); 53 | newsize = limit; /* still have at least one free place */ 54 | } 55 | else { 56 | newsize = (*size)*2; 57 | if (newsize < MINSIZEARRAY) 58 | newsize = MINSIZEARRAY; /* minimum size */ 59 | } 60 | newblock = luaM_reallocv(L, block, *size, newsize, size_elems); 61 | *size = newsize; /* update only when everything else is OK */ 62 | return newblock; 63 | } 64 | 65 | 66 | void *luaM_toobig (lua_State *L) { 67 | luaG_runerror(L, "memory allocation error: block too big"); 68 | return NULL; /* to avoid warnings */ 69 | } 70 | 71 | 72 | 73 | /* 74 | ** generic allocation routine. 75 | */ 76 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 77 | global_State *g = G(L); 78 | lua_assert((osize == 0) == (block == NULL)); 79 | block = (*g->frealloc)(g->ud, block, osize, nsize); 80 | if (block == NULL && nsize > 0) 81 | luaD_throw(L, LUA_ERRMEM); 82 | lua_assert((nsize == 0) == (block == NULL)); 83 | g->totalbytes = (g->totalbytes - osize) + nsize; 84 | return block; 85 | } 86 | 87 | -------------------------------------------------------------------------------- /spa/Spa/lua/lmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lmem_h 8 | #define lmem_h 9 | 10 | 11 | #include 12 | 13 | #include "llimits.h" 14 | #include "lua.h" 15 | 16 | #define MEMERRMSG "not enough memory" 17 | 18 | 19 | #define luaM_reallocv(L,b,on,n,e) \ 20 | ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ 21 | luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ 22 | luaM_toobig(L)) 23 | 24 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) 25 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) 26 | #define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) 27 | 28 | #define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) 29 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) 30 | #define luaM_newvector(L,n,t) \ 31 | cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) 32 | 33 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 34 | if ((nelems)+1 > (size)) \ 35 | ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) 36 | 37 | #define luaM_reallocvector(L, v,oldn,n,t) \ 38 | ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) 39 | 40 | 41 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 42 | size_t size); 43 | LUAI_FUNC void *luaM_toobig (lua_State *L); 44 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, 45 | size_t size_elem, int limit, 46 | const char *errormsg); 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /spa/Spa/lua/lobject.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Some generic functions over Lua objects 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define lobject_c 14 | #define LUA_CORE 15 | 16 | #include "lua.h" 17 | 18 | #include "ldo.h" 19 | #include "lmem.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | #include "lvm.h" 24 | 25 | 26 | 27 | const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; 28 | 29 | 30 | /* 31 | ** converts an integer to a "floating point byte", represented as 32 | ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if 33 | ** eeeee != 0 and (xxx) otherwise. 34 | */ 35 | int luaO_int2fb (unsigned int x) { 36 | int e = 0; /* expoent */ 37 | while (x >= 16) { 38 | x = (x+1) >> 1; 39 | e++; 40 | } 41 | if (x < 8) return x; 42 | else return ((e+1) << 3) | (cast_int(x) - 8); 43 | } 44 | 45 | 46 | /* converts back */ 47 | int luaO_fb2int (int x) { 48 | int e = (x >> 3) & 31; 49 | if (e == 0) return x; 50 | else return ((x & 7)+8) << (e - 1); 51 | } 52 | 53 | 54 | int luaO_log2 (unsigned int x) { 55 | static const lu_byte log_2[256] = { 56 | 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 57 | 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 58 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 59 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 60 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 61 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 62 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 63 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 64 | }; 65 | int l = -1; 66 | while (x >= 256) { l += 8; x >>= 8; } 67 | return l + log_2[x]; 68 | 69 | } 70 | 71 | 72 | int luaO_rawequalObj (const TValue *t1, const TValue *t2) { 73 | if (ttype(t1) != ttype(t2)) return 0; 74 | else switch (ttype(t1)) { 75 | case LUA_TNIL: 76 | return 1; 77 | case LUA_TNUMBER: 78 | return luai_numeq(nvalue(t1), nvalue(t2)); 79 | case LUA_TBOOLEAN: 80 | return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ 81 | case LUA_TLIGHTUSERDATA: 82 | return pvalue(t1) == pvalue(t2); 83 | default: 84 | lua_assert(iscollectable(t1)); 85 | return gcvalue(t1) == gcvalue(t2); 86 | } 87 | } 88 | 89 | 90 | int luaO_str2d (const char *s, lua_Number *result) { 91 | char *endptr; 92 | *result = lua_str2number(s, &endptr); 93 | if (endptr == s) return 0; /* conversion failed */ 94 | if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ 95 | *result = cast_num(strtoul(s, &endptr, 16)); 96 | if (*endptr == '\0') return 1; /* most common case */ 97 | while (isspace(cast(unsigned char, *endptr))) endptr++; 98 | if (*endptr != '\0') return 0; /* invalid trailing characters? */ 99 | return 1; 100 | } 101 | 102 | 103 | 104 | static void pushstr (lua_State *L, const char *str) { 105 | setsvalue2s(L, L->top, luaS_new(L, str)); 106 | incr_top(L); 107 | } 108 | 109 | 110 | /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ 111 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { 112 | int n = 1; 113 | pushstr(L, ""); 114 | for (;;) { 115 | const char *e = strchr(fmt, '%'); 116 | if (e == NULL) break; 117 | setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); 118 | incr_top(L); 119 | switch (*(e+1)) { 120 | case 's': { 121 | const char *s = va_arg(argp, char *); 122 | if (s == NULL) s = "(null)"; 123 | pushstr(L, s); 124 | break; 125 | } 126 | case 'c': { 127 | char buff[2]; 128 | buff[0] = cast(char, va_arg(argp, int)); 129 | buff[1] = '\0'; 130 | pushstr(L, buff); 131 | break; 132 | } 133 | case 'd': { 134 | setnvalue(L->top, cast_num(va_arg(argp, int))); 135 | incr_top(L); 136 | break; 137 | } 138 | case 'f': { 139 | setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); 140 | incr_top(L); 141 | break; 142 | } 143 | case 'p': { 144 | char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ 145 | sprintf(buff, "%p", va_arg(argp, void *)); 146 | pushstr(L, buff); 147 | break; 148 | } 149 | case '%': { 150 | pushstr(L, "%"); 151 | break; 152 | } 153 | default: { 154 | char buff[3]; 155 | buff[0] = '%'; 156 | buff[1] = *(e+1); 157 | buff[2] = '\0'; 158 | pushstr(L, buff); 159 | break; 160 | } 161 | } 162 | n += 2; 163 | fmt = e+2; 164 | } 165 | pushstr(L, fmt); 166 | luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); 167 | L->top -= n; 168 | return svalue(L->top - 1); 169 | } 170 | 171 | 172 | const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { 173 | const char *msg; 174 | va_list argp; 175 | va_start(argp, fmt); 176 | msg = luaO_pushvfstring(L, fmt, argp); 177 | va_end(argp); 178 | return msg; 179 | } 180 | 181 | 182 | void luaO_chunkid (char *out, const char *source, size_t bufflen) { 183 | if (*source == '=') { 184 | strncpy(out, source+1, bufflen); /* remove first char */ 185 | out[bufflen-1] = '\0'; /* ensures null termination */ 186 | } 187 | else { /* out = "source", or "...source" */ 188 | if (*source == '@') { 189 | size_t l; 190 | source++; /* skip the `@' */ 191 | bufflen -= sizeof(" '...' "); 192 | l = strlen(source); 193 | strcpy(out, ""); 194 | if (l > bufflen) { 195 | source += (l-bufflen); /* get last part of file name */ 196 | strcat(out, "..."); 197 | } 198 | strcat(out, source); 199 | } 200 | else { /* out = [string "string"] */ 201 | size_t len = strcspn(source, "\n\r"); /* stop at first newline */ 202 | bufflen -= sizeof(" [string \"...\"] "); 203 | if (len > bufflen) len = bufflen; 204 | strcpy(out, "[string \""); 205 | if (source[len] != '\0') { /* must truncate? */ 206 | strncat(out, source, len); 207 | strcat(out, "..."); 208 | } 209 | else 210 | strcat(out, source); 211 | strcat(out, "\"]"); 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /spa/Spa/lua/lopcodes.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** See Copyright Notice in lua.h 4 | */ 5 | 6 | 7 | #define lopcodes_c 8 | #define LUA_CORE 9 | 10 | 11 | #include "lopcodes.h" 12 | 13 | 14 | /* ORDER OP */ 15 | 16 | const char *const luaP_opnames[NUM_OPCODES+1] = { 17 | "MOVE", 18 | "LOADK", 19 | "LOADBOOL", 20 | "LOADNIL", 21 | "GETUPVAL", 22 | "GETGLOBAL", 23 | "GETTABLE", 24 | "SETGLOBAL", 25 | "SETUPVAL", 26 | "SETTABLE", 27 | "NEWTABLE", 28 | "SELF", 29 | "ADD", 30 | "SUB", 31 | "MUL", 32 | "DIV", 33 | "MOD", 34 | "POW", 35 | "UNM", 36 | "NOT", 37 | "LEN", 38 | "CONCAT", 39 | "JMP", 40 | "EQ", 41 | "LT", 42 | "LE", 43 | "TEST", 44 | "TESTSET", 45 | "CALL", 46 | "TAILCALL", 47 | "RETURN", 48 | "FORLOOP", 49 | "FORPREP", 50 | "TFORLOOP", 51 | "SETLIST", 52 | "CLOSE", 53 | "CLOSURE", 54 | "VARARG", 55 | NULL 56 | }; 57 | 58 | 59 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) 60 | 61 | const lu_byte luaP_opmodes[NUM_OPCODES] = { 62 | /* T A B C mode opcode */ 63 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ 64 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ 65 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ 66 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ 67 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ 68 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ 69 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ 70 | ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ 71 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ 72 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ 73 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ 74 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ 75 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ 76 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ 77 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ 78 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ 79 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ 80 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ 81 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ 82 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ 83 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ 84 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ 85 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ 86 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ 87 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ 88 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ 89 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ 90 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ 91 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ 92 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ 93 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ 94 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ 95 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ 96 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ 97 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ 98 | ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ 99 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 100 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ 101 | }; 102 | 103 | -------------------------------------------------------------------------------- /spa/Spa/lua/loslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ 3 | ** Standard Operating System library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define loslib_c 15 | #define LUA_LIB 16 | 17 | #include "lua.h" 18 | 19 | #include "lauxlib.h" 20 | #include "lualib.h" 21 | 22 | 23 | static int os_pushresult (lua_State *L, int i, const char *filename) { 24 | int en = errno; /* calls to Lua API may change this value */ 25 | if (i) { 26 | lua_pushboolean(L, 1); 27 | return 1; 28 | } 29 | else { 30 | lua_pushnil(L); 31 | lua_pushfstring(L, "%s: %s", filename, strerror(en)); 32 | lua_pushinteger(L, en); 33 | return 3; 34 | } 35 | } 36 | 37 | 38 | static int os_execute (lua_State *L) { 39 | #ifndef SPA_TARGET_OS_WATCH 40 | // lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); 41 | #endif 42 | return 1; 43 | } 44 | 45 | 46 | static int os_remove (lua_State *L) { 47 | const char *filename = luaL_checkstring(L, 1); 48 | return os_pushresult(L, remove(filename) == 0, filename); 49 | } 50 | 51 | 52 | static int os_rename (lua_State *L) { 53 | const char *fromname = luaL_checkstring(L, 1); 54 | const char *toname = luaL_checkstring(L, 2); 55 | return os_pushresult(L, rename(fromname, toname) == 0, fromname); 56 | } 57 | 58 | 59 | static int os_tmpname (lua_State *L) { 60 | char buff[LUA_TMPNAMBUFSIZE]; 61 | int err; 62 | lua_tmpnam(buff, err); 63 | if (err) 64 | return luaL_error(L, "unable to generate a unique filename"); 65 | lua_pushstring(L, buff); 66 | return 1; 67 | } 68 | 69 | 70 | static int os_getenv (lua_State *L) { 71 | lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ 72 | return 1; 73 | } 74 | 75 | 76 | static int os_clock (lua_State *L) { 77 | lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); 78 | return 1; 79 | } 80 | 81 | 82 | /* 83 | ** {====================================================== 84 | ** Time/Date operations 85 | ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, 86 | ** wday=%w+1, yday=%j, isdst=? } 87 | ** ======================================================= 88 | */ 89 | 90 | static void setfield (lua_State *L, const char *key, int value) { 91 | lua_pushinteger(L, value); 92 | lua_setfield(L, -2, key); 93 | } 94 | 95 | static void setboolfield (lua_State *L, const char *key, int value) { 96 | if (value < 0) /* undefined? */ 97 | return; /* does not set field */ 98 | lua_pushboolean(L, value); 99 | lua_setfield(L, -2, key); 100 | } 101 | 102 | static int getboolfield (lua_State *L, const char *key) { 103 | int res; 104 | lua_getfield(L, -1, key); 105 | res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); 106 | lua_pop(L, 1); 107 | return res; 108 | } 109 | 110 | 111 | static int getfield (lua_State *L, const char *key, int d) { 112 | int res; 113 | lua_getfield(L, -1, key); 114 | if (lua_isnumber(L, -1)) 115 | res = (int)lua_tointeger(L, -1); 116 | else { 117 | if (d < 0) 118 | return luaL_error(L, "field " LUA_QS " missing in date table", key); 119 | res = d; 120 | } 121 | lua_pop(L, 1); 122 | return res; 123 | } 124 | 125 | 126 | static int os_date (lua_State *L) { 127 | const char *s = luaL_optstring(L, 1, "%c"); 128 | time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); 129 | struct tm *stm; 130 | if (*s == '!') { /* UTC? */ 131 | stm = gmtime(&t); 132 | s++; /* skip `!' */ 133 | } 134 | else 135 | stm = localtime(&t); 136 | if (stm == NULL) /* invalid date? */ 137 | lua_pushnil(L); 138 | else if (strcmp(s, "*t") == 0) { 139 | lua_createtable(L, 0, 9); /* 9 = number of fields */ 140 | setfield(L, "sec", stm->tm_sec); 141 | setfield(L, "min", stm->tm_min); 142 | setfield(L, "hour", stm->tm_hour); 143 | setfield(L, "day", stm->tm_mday); 144 | setfield(L, "month", stm->tm_mon+1); 145 | setfield(L, "year", stm->tm_year+1900); 146 | setfield(L, "wday", stm->tm_wday+1); 147 | setfield(L, "yday", stm->tm_yday+1); 148 | setboolfield(L, "isdst", stm->tm_isdst); 149 | } 150 | else { 151 | char cc[3]; 152 | luaL_Buffer b; 153 | cc[0] = '%'; cc[2] = '\0'; 154 | luaL_buffinit(L, &b); 155 | for (; *s; s++) { 156 | if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ 157 | luaL_addchar(&b, *s); 158 | else { 159 | size_t reslen; 160 | char buff[200]; /* should be big enough for any conversion result */ 161 | cc[1] = *(++s); 162 | reslen = strftime(buff, sizeof(buff), cc, stm); 163 | luaL_addlstring(&b, buff, reslen); 164 | } 165 | } 166 | luaL_pushresult(&b); 167 | } 168 | return 1; 169 | } 170 | 171 | 172 | static int os_time (lua_State *L) { 173 | time_t t; 174 | if (lua_isnoneornil(L, 1)) /* called without args? */ 175 | t = time(NULL); /* get current time */ 176 | else { 177 | struct tm ts; 178 | luaL_checktype(L, 1, LUA_TTABLE); 179 | lua_settop(L, 1); /* make sure table is at the top */ 180 | ts.tm_sec = getfield(L, "sec", 0); 181 | ts.tm_min = getfield(L, "min", 0); 182 | ts.tm_hour = getfield(L, "hour", 12); 183 | ts.tm_mday = getfield(L, "day", -1); 184 | ts.tm_mon = getfield(L, "month", -1) - 1; 185 | ts.tm_year = getfield(L, "year", -1) - 1900; 186 | ts.tm_isdst = getboolfield(L, "isdst"); 187 | t = mktime(&ts); 188 | } 189 | if (t == (time_t)(-1)) 190 | lua_pushnil(L); 191 | else 192 | lua_pushnumber(L, (lua_Number)t); 193 | return 1; 194 | } 195 | 196 | 197 | static int os_difftime (lua_State *L) { 198 | lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), 199 | (time_t)(luaL_optnumber(L, 2, 0)))); 200 | return 1; 201 | } 202 | 203 | /* }====================================================== */ 204 | 205 | 206 | static int os_setlocale (lua_State *L) { 207 | static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, 208 | LC_NUMERIC, LC_TIME}; 209 | static const char *const catnames[] = {"all", "collate", "ctype", "monetary", 210 | "numeric", "time", NULL}; 211 | const char *l = luaL_optstring(L, 1, NULL); 212 | int op = luaL_checkoption(L, 2, "all", catnames); 213 | lua_pushstring(L, setlocale(cat[op], l)); 214 | return 1; 215 | } 216 | 217 | 218 | static int os_exit (lua_State *L) { 219 | exit(luaL_optint(L, 1, EXIT_SUCCESS)); 220 | } 221 | 222 | static const luaL_Reg syslib[] = { 223 | {"clock", os_clock}, 224 | {"date", os_date}, 225 | {"difftime", os_difftime}, 226 | {"execute", os_execute}, 227 | {"exit", os_exit}, 228 | {"getenv", os_getenv}, 229 | {"remove", os_remove}, 230 | {"rename", os_rename}, 231 | {"setlocale", os_setlocale}, 232 | {"time", os_time}, 233 | {"tmpname", os_tmpname}, 234 | {NULL, NULL} 235 | }; 236 | 237 | /* }====================================================== */ 238 | 239 | 240 | 241 | LUALIB_API int luaopen_os (lua_State *L) { 242 | luaL_register(L, LUA_OSLIBNAME, syslib); 243 | return 1; 244 | } 245 | 246 | -------------------------------------------------------------------------------- /spa/Spa/lua/lparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Lua Parser 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lparser_h 8 | #define lparser_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* 16 | ** Expression descriptor 17 | */ 18 | 19 | typedef enum { 20 | VVOID, /* no value */ 21 | VNIL, 22 | VTRUE, 23 | VFALSE, 24 | VK, /* info = index of constant in `k' */ 25 | VKNUM, /* nval = numerical value */ 26 | VLOCAL, /* info = local register */ 27 | VUPVAL, /* info = index of upvalue in `upvalues' */ 28 | VGLOBAL, /* info = index of table; aux = index of global name in `k' */ 29 | VINDEXED, /* info = table register; aux = index register (or `k') */ 30 | VJMP, /* info = instruction pc */ 31 | VRELOCABLE, /* info = instruction pc */ 32 | VNONRELOC, /* info = result register */ 33 | VCALL, /* info = instruction pc */ 34 | VVARARG /* info = instruction pc */ 35 | } expkind; 36 | 37 | typedef struct expdesc { 38 | expkind k; 39 | union { 40 | struct { int info, aux; } s; 41 | lua_Number nval; 42 | } u; 43 | int t; /* patch list of `exit when true' */ 44 | int f; /* patch list of `exit when false' */ 45 | } expdesc; 46 | 47 | 48 | typedef struct upvaldesc { 49 | lu_byte k; 50 | lu_byte info; 51 | } upvaldesc; 52 | 53 | 54 | struct BlockCnt; /* defined in lparser.c */ 55 | 56 | 57 | /* state needed to generate code for a given function */ 58 | typedef struct FuncState { 59 | Proto *f; /* current function header */ 60 | Table *h; /* table to find (and reuse) elements in `k' */ 61 | struct FuncState *prev; /* enclosing function */ 62 | struct LexState *ls; /* lexical state */ 63 | struct lua_State *L; /* copy of the Lua state */ 64 | struct BlockCnt *bl; /* chain of current blocks */ 65 | int pc; /* next position to code (equivalent to `ncode') */ 66 | int lasttarget; /* `pc' of last `jump target' */ 67 | int jpc; /* list of pending jumps to `pc' */ 68 | int freereg; /* first free register */ 69 | int nk; /* number of elements in `k' */ 70 | int np; /* number of elements in `p' */ 71 | short nlocvars; /* number of elements in `locvars' */ 72 | lu_byte nactvar; /* number of active local variables */ 73 | upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ 74 | unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ 75 | } FuncState; 76 | 77 | 78 | LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 79 | const char *name); 80 | 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /spa/Spa/lua/lstate.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ 3 | ** Global State 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lstate_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "ldebug.h" 16 | #include "ldo.h" 17 | #include "lfunc.h" 18 | #include "lgc.h" 19 | #include "llex.h" 20 | #include "lmem.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | #include "ltable.h" 24 | #include "ltm.h" 25 | 26 | 27 | #define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) 28 | #define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) 29 | #define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) 30 | 31 | 32 | /* 33 | ** Main thread combines a thread state and the global state 34 | */ 35 | typedef struct LG { 36 | lua_State l; 37 | global_State g; 38 | } LG; 39 | 40 | 41 | 42 | static void stack_init (lua_State *L1, lua_State *L) { 43 | /* initialize CallInfo array */ 44 | L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); 45 | L1->ci = L1->base_ci; 46 | L1->size_ci = BASIC_CI_SIZE; 47 | L1->end_ci = L1->base_ci + L1->size_ci - 1; 48 | /* initialize stack array */ 49 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); 50 | L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; 51 | L1->top = L1->stack; 52 | L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; 53 | /* initialize first ci */ 54 | L1->ci->func = L1->top; 55 | setnilvalue(L1->top++); /* `function' entry for this `ci' */ 56 | L1->base = L1->ci->base = L1->top; 57 | L1->ci->top = L1->top + LUA_MINSTACK; 58 | } 59 | 60 | 61 | static void freestack (lua_State *L, lua_State *L1) { 62 | luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); 63 | luaM_freearray(L, L1->stack, L1->stacksize, TValue); 64 | } 65 | 66 | 67 | /* 68 | ** open parts that may cause memory-allocation errors 69 | */ 70 | static void f_luaopen (lua_State *L, void *ud) { 71 | global_State *g = G(L); 72 | UNUSED(ud); 73 | stack_init(L, L); /* init stack */ 74 | sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ 75 | sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ 76 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 77 | luaT_init(L); 78 | luaX_init(L); 79 | luaS_fix(luaS_newliteral(L, MEMERRMSG)); 80 | g->GCthreshold = 4*g->totalbytes; 81 | } 82 | 83 | 84 | static void preinit_state (lua_State *L, global_State *g) { 85 | G(L) = g; 86 | L->stack = NULL; 87 | L->stacksize = 0; 88 | L->errorJmp = NULL; 89 | L->hook = NULL; 90 | L->hookmask = 0; 91 | L->basehookcount = 0; 92 | L->allowhook = 1; 93 | resethookcount(L); 94 | L->openupval = NULL; 95 | L->size_ci = 0; 96 | L->nCcalls = L->baseCcalls = 0; 97 | L->status = 0; 98 | L->base_ci = L->ci = NULL; 99 | L->savedpc = NULL; 100 | L->errfunc = 0; 101 | setnilvalue(gt(L)); 102 | } 103 | 104 | 105 | static void close_state (lua_State *L) { 106 | global_State *g = G(L); 107 | luaF_close(L, L->stack); /* close all upvalues for this thread */ 108 | luaC_freeall(L); /* collect all objects */ 109 | lua_assert(g->rootgc == obj2gco(L)); 110 | lua_assert(g->strt.nuse == 0); 111 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); 112 | luaZ_freebuffer(L, &g->buff); 113 | freestack(L, L); 114 | lua_assert(g->totalbytes == sizeof(LG)); 115 | pthread_mutex_unlock(&g->lock); 116 | pthread_mutex_destroy(&g->lock); 117 | (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); 118 | } 119 | 120 | 121 | lua_State *luaE_newthread (lua_State *L) { 122 | lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); 123 | luaC_link(L, obj2gco(L1), LUA_TTHREAD); 124 | preinit_state(L1, G(L)); 125 | stack_init(L1, L); /* init stack */ 126 | setobj2n(L, gt(L1), gt(L)); /* share table of globals */ 127 | L1->hookmask = L->hookmask; 128 | L1->basehookcount = L->basehookcount; 129 | L1->hook = L->hook; 130 | resethookcount(L1); 131 | lua_assert(iswhite(obj2gco(L1))); 132 | return L1; 133 | } 134 | 135 | 136 | void luaE_freethread (lua_State *L, lua_State *L1) { 137 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 138 | lua_assert(L1->openupval == NULL); 139 | luai_userstatefree(L1); 140 | freestack(L, L1); 141 | luaM_freemem(L, fromstate(L1), state_size(lua_State)); 142 | } 143 | 144 | 145 | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { 146 | int i; 147 | lua_State *L; 148 | global_State *g; 149 | void *l = (*f)(ud, NULL, 0, state_size(LG)); 150 | if (l == NULL) return NULL; 151 | L = tostate(l); 152 | g = &((LG *)L)->g; 153 | L->next = NULL; 154 | L->tt = LUA_TTHREAD; 155 | g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); 156 | L->marked = luaC_white(g); 157 | set2bits(L->marked, FIXEDBIT, SFIXEDBIT); 158 | preinit_state(L, g); 159 | g->frealloc = f; 160 | g->ud = ud; 161 | g->mainthread = L; 162 | g->uvhead.u.l.prev = &g->uvhead; 163 | g->uvhead.u.l.next = &g->uvhead; 164 | g->GCthreshold = 0; /* mark it as unfinished state */ 165 | g->strt.size = 0; 166 | g->strt.nuse = 0; 167 | g->strt.hash = NULL; 168 | setnilvalue(registry(L)); 169 | luaZ_initbuffer(L, &g->buff); 170 | g->panic = NULL; 171 | g->gcstate = GCSpause; 172 | g->rootgc = obj2gco(L); 173 | g->sweepstrgc = 0; 174 | g->sweepgc = &g->rootgc; 175 | g->gray = NULL; 176 | g->grayagain = NULL; 177 | g->weak = NULL; 178 | g->tmudata = NULL; 179 | g->totalbytes = sizeof(LG); 180 | g->gcpause = LUAI_GCPAUSE; 181 | g->gcstepmul = LUAI_GCMUL; 182 | g->gcdept = 0; 183 | pthread_mutex_init(&g->lock, NULL); 184 | for (i=0; imt[i] = NULL; 185 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { 186 | /* memory allocation error: free partial state */ 187 | close_state(L); 188 | L = NULL; 189 | } 190 | else 191 | luai_userstateopen(L); 192 | return L; 193 | } 194 | 195 | 196 | static void callallgcTM (lua_State *L, void *ud) { 197 | UNUSED(ud); 198 | luaC_callGCTM(L); /* call GC metamethods for all udata */ 199 | } 200 | 201 | 202 | LUA_API void lua_close (lua_State *L) { 203 | L = G(L)->mainthread; /* only the main thread can be closed */ 204 | lua_lock(L); 205 | luaF_close(L, L->stack); /* close all upvalues for this thread */ 206 | luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ 207 | L->errfunc = 0; /* no error function during GC metamethods */ 208 | do { /* repeat until no more errors */ 209 | L->ci = L->base_ci; 210 | L->base = L->top = L->ci->base; 211 | L->nCcalls = L->baseCcalls = 0; 212 | } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); 213 | lua_assert(G(L)->tmudata == NULL); 214 | luai_userstateclose(L); 215 | close_state(L); 216 | } 217 | 218 | -------------------------------------------------------------------------------- /spa/Spa/lua/lstate.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $ 3 | ** Global State 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstate_h 8 | #define lstate_h 9 | 10 | #include "lua.h" 11 | 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | #include "lzio.h" 15 | #include 16 | //#include 17 | 18 | 19 | struct lua_longjmp; /* defined in ldo.c */ 20 | 21 | 22 | /* table of globals */ 23 | #define gt(L) (&L->l_gt) 24 | 25 | /* registry */ 26 | #define registry(L) (&G(L)->l_registry) 27 | 28 | 29 | /* extra stack space to handle TM calls and some other extras */ 30 | #define EXTRA_STACK 5 31 | 32 | 33 | #define BASIC_CI_SIZE 8 34 | 35 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) 36 | 37 | 38 | 39 | typedef struct stringtable { 40 | GCObject **hash; 41 | lu_int32 nuse; /* number of elements */ 42 | int size; 43 | } stringtable; 44 | 45 | 46 | /* 47 | ** informations about a call 48 | */ 49 | typedef struct CallInfo { 50 | StkId base; /* base for this function */ 51 | StkId func; /* function index in the stack */ 52 | StkId top; /* top for this function */ 53 | const Instruction *savedpc; 54 | int nresults; /* expected number of results from this function */ 55 | int tailcalls; /* number of tail calls lost under this entry */ 56 | } CallInfo; 57 | 58 | 59 | 60 | #define curr_func(L) (clvalue(L->ci->func)) 61 | #define ci_func(ci) (clvalue((ci)->func)) 62 | #define f_isLua(ci) (!ci_func(ci)->c.isC) 63 | #define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) 64 | 65 | 66 | /* 67 | ** `global state', shared by all threads of this state 68 | */ 69 | typedef struct global_State { 70 | stringtable strt; /* hash table for strings */ 71 | lua_Alloc frealloc; /* function to reallocate memory */ 72 | void *ud; /* auxiliary data to `frealloc' */ 73 | lu_byte currentwhite; 74 | lu_byte gcstate; /* state of garbage collector */ 75 | int sweepstrgc; /* position of sweep in `strt' */ 76 | GCObject *rootgc; /* list of all collectable objects */ 77 | GCObject **sweepgc; /* position of sweep in `rootgc' */ 78 | GCObject *gray; /* list of gray objects */ 79 | GCObject *grayagain; /* list of objects to be traversed atomically */ 80 | GCObject *weak; /* list of weak tables (to be cleared) */ 81 | GCObject *tmudata; /* last element of list of userdata to be GC */ 82 | Mbuffer buff; /* temporary buffer for string concatentation */ 83 | lu_mem GCthreshold; 84 | lu_mem totalbytes; /* number of bytes currently allocated */ 85 | lu_mem estimate; /* an estimate of number of bytes actually in use */ 86 | lu_mem gcdept; /* how much GC is `behind schedule' */ 87 | int gcpause; /* size of pause between successive GCs */ 88 | int gcstepmul; /* GC `granularity' */ 89 | lua_CFunction panic; /* to be called in unprotected errors */ 90 | TValue l_registry; 91 | struct lua_State *mainthread; 92 | UpVal uvhead; /* head of double-linked list of all open upvalues */ 93 | struct Table *mt[NUM_TAGS]; /* metatables for basic types */ 94 | TString *tmname[TM_N]; /* array with tag-method names */ 95 | pthread_mutex_t lock; 96 | } global_State; 97 | 98 | 99 | /* 100 | ** `per thread' state 101 | */ 102 | struct lua_State { 103 | CommonHeader; 104 | lu_byte status; 105 | StkId top; /* first free slot in the stack */ 106 | StkId base; /* base of current function */ 107 | global_State *l_G; 108 | CallInfo *ci; /* call info for current function */ 109 | const Instruction *savedpc; /* `savedpc' of current function */ 110 | StkId stack_last; /* last free slot in the stack */ 111 | StkId stack; /* stack base */ 112 | CallInfo *end_ci; /* points after end of ci array*/ 113 | CallInfo *base_ci; /* array of CallInfo's */ 114 | int stacksize; 115 | int size_ci; /* size of array `base_ci' */ 116 | unsigned short nCcalls; /* number of nested C calls */ 117 | unsigned short baseCcalls; /* nested C calls when resuming coroutine */ 118 | lu_byte hookmask; 119 | lu_byte allowhook; 120 | int basehookcount; 121 | int hookcount; 122 | lua_Hook hook; 123 | TValue l_gt; /* table of globals */ 124 | TValue env; /* temporary place for environments */ 125 | GCObject *openupval; /* list of open upvalues in this stack */ 126 | GCObject *gclist; 127 | struct lua_longjmp *errorJmp; /* current error recover point */ 128 | ptrdiff_t errfunc; /* current error handling function (stack index) */ 129 | }; 130 | 131 | 132 | #define G(L) (L->l_G) 133 | 134 | 135 | /* 136 | ** Union of all collectable objects 137 | */ 138 | union GCObject { 139 | GCheader gch; 140 | union TString ts; 141 | union Udata u; 142 | union Closure cl; 143 | struct Table h; 144 | struct Proto p; 145 | struct UpVal uv; 146 | struct lua_State th; /* thread */ 147 | }; 148 | 149 | 150 | /* macros to convert a GCObject into a specific value */ 151 | #define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) 152 | #define gco2ts(o) (&rawgco2ts(o)->tsv) 153 | #define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) 154 | #define gco2u(o) (&rawgco2u(o)->uv) 155 | #define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) 156 | #define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) 157 | #define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) 158 | #define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) 159 | #define ngcotouv(o) \ 160 | check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) 161 | #define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) 162 | 163 | /* macro to convert any Lua object into a GCObject */ 164 | #define obj2gco(v) (cast(GCObject *, (v))) 165 | 166 | 167 | LUAI_FUNC lua_State *luaE_newthread (lua_State *L); 168 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 169 | 170 | #endif 171 | 172 | -------------------------------------------------------------------------------- /spa/Spa/lua/lstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** String table (keeps all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lstring_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "lmem.h" 16 | #include "lobject.h" 17 | #include "lstate.h" 18 | #include "lstring.h" 19 | 20 | 21 | 22 | void luaS_resize (lua_State *L, int newsize) { 23 | GCObject **newhash; 24 | stringtable *tb; 25 | int i; 26 | if (G(L)->gcstate == GCSsweepstring) 27 | return; /* cannot resize during GC traverse */ 28 | newhash = luaM_newvector(L, newsize, GCObject *); 29 | tb = &G(L)->strt; 30 | for (i=0; isize; i++) { 33 | GCObject *p = tb->hash[i]; 34 | while (p) { /* for each node in the list */ 35 | GCObject *next = p->gch.next; /* save next */ 36 | unsigned int h = gco2ts(p)->hash; 37 | int h1 = lmod(h, newsize); /* new position */ 38 | lua_assert(cast_int(h%newsize) == lmod(h, newsize)); 39 | p->gch.next = newhash[h1]; /* chain it */ 40 | newhash[h1] = p; 41 | p = next; 42 | } 43 | } 44 | luaM_freearray(L, tb->hash, tb->size, TString *); 45 | tb->size = newsize; 46 | tb->hash = newhash; 47 | } 48 | 49 | 50 | static TString *newlstr (lua_State *L, const char *str, size_t l, 51 | unsigned int h) { 52 | TString *ts; 53 | stringtable *tb; 54 | if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) 55 | luaM_toobig(L); 56 | ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); 57 | ts->tsv.len = l; 58 | ts->tsv.hash = h; 59 | ts->tsv.marked = luaC_white(G(L)); 60 | ts->tsv.tt = LUA_TSTRING; 61 | ts->tsv.reserved = 0; 62 | memcpy(ts+1, str, l*sizeof(char)); 63 | ((char *)(ts+1))[l] = '\0'; /* ending 0 */ 64 | tb = &G(L)->strt; 65 | h = lmod(h, tb->size); 66 | ts->tsv.next = tb->hash[h]; /* chain new entry */ 67 | tb->hash[h] = obj2gco(ts); 68 | tb->nuse++; 69 | if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) 70 | luaS_resize(L, tb->size*2); /* too crowded */ 71 | return ts; 72 | } 73 | 74 | 75 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { 76 | GCObject *o; 77 | unsigned int h = cast(unsigned int, l); /* seed */ 78 | size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ 79 | size_t l1; 80 | for (l1=l; l1>=step; l1-=step) /* compute hash */ 81 | h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); 82 | for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; 83 | o != NULL; 84 | o = o->gch.next) { 85 | TString *ts = rawgco2ts(o); 86 | if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { 87 | /* string may be dead */ 88 | if (isdead(G(L), o)) changewhite(o); 89 | return ts; 90 | } 91 | } 92 | return newlstr(L, str, l, h); /* not found */ 93 | } 94 | 95 | 96 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { 97 | Udata *u; 98 | if (s > MAX_SIZET - sizeof(Udata)) 99 | luaM_toobig(L); 100 | u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); 101 | u->uv.marked = luaC_white(G(L)); /* is not finalized */ 102 | u->uv.tt = LUA_TUSERDATA; 103 | u->uv.len = s; 104 | u->uv.metatable = NULL; 105 | u->uv.env = e; 106 | /* chain it on udata list (after main thread) */ 107 | u->uv.next = G(L)->mainthread->next; 108 | G(L)->mainthread->next = obj2gco(u); 109 | return u; 110 | } 111 | 112 | -------------------------------------------------------------------------------- /spa/Spa/lua/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | 11 | #include "lgc.h" 12 | #include "lobject.h" 13 | #include "lstate.h" 14 | 15 | 16 | #define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) 17 | 18 | #define sizeudata(u) (sizeof(union Udata)+(u)->len) 19 | 20 | #define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) 21 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 22 | (sizeof(s)/sizeof(char))-1)) 23 | 24 | #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) 25 | 26 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 27 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); 28 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 29 | 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /spa/Spa/lua/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gkey(n) (&(n)->i_key.nk) 15 | #define gval(n) (&(n)->i_val) 16 | #define gnext(n) ((n)->i_key.nk.next) 17 | 18 | #define key2tval(n) (&(n)->i_key.tvk) 19 | 20 | 21 | LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); 22 | LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); 23 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 24 | LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); 25 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 26 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 27 | LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); 28 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); 29 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 30 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 31 | LUAI_FUNC int luaH_getn (Table *t); 32 | 33 | 34 | #if defined(LUA_DEBUG) 35 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 36 | LUAI_FUNC int luaH_isdummy (Node *n); 37 | #endif 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /spa/Spa/lua/ltm.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define ltm_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "lobject.h" 16 | #include "lstate.h" 17 | #include "lstring.h" 18 | #include "ltable.h" 19 | #include "ltm.h" 20 | 21 | 22 | 23 | const char *const luaT_typenames[] = { 24 | "nil", "boolean", "userdata", "number", 25 | "string", "table", "function", "userdata", "thread", 26 | "proto", "upval" 27 | }; 28 | 29 | 30 | void luaT_init (lua_State *L) { 31 | static const char *const luaT_eventname[] = { /* ORDER TM */ 32 | "__index", "__newindex", 33 | "__gc", "__mode", "__eq", 34 | "__add", "__sub", "__mul", "__div", "__mod", 35 | "__pow", "__unm", "__len", "__lt", "__le", 36 | "__concat", "__call" 37 | }; 38 | int i; 39 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); 41 | luaS_fix(G(L)->tmname[i]); /* never collect these names */ 42 | } 43 | } 44 | 45 | 46 | /* 47 | ** function to be used with macro "fasttm": optimized for absence of 48 | ** tag methods 49 | */ 50 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 51 | const TValue *tm = luaH_getstr(events, ename); 52 | lua_assert(event <= TM_EQ); 53 | if (ttisnil(tm)) { /* no tag method? */ 54 | events->flags |= cast_byte(1u<metatable; 66 | break; 67 | case LUA_TUSERDATA: 68 | mt = uvalue(o)->metatable; 69 | break; 70 | default: 71 | mt = G(L)->mt[ttype(o)]; 72 | } 73 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); 74 | } 75 | 76 | -------------------------------------------------------------------------------- /spa/Spa/lua/ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltm_h 8 | #define ltm_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | /* 15 | * WARNING: if you change the order of this enumeration, 16 | * grep "ORDER TM" 17 | */ 18 | typedef enum { 19 | TM_INDEX, 20 | TM_NEWINDEX, 21 | TM_GC, 22 | TM_MODE, 23 | TM_EQ, /* last tag method with `fast' access */ 24 | TM_ADD, 25 | TM_SUB, 26 | TM_MUL, 27 | TM_DIV, 28 | TM_MOD, 29 | TM_POW, 30 | TM_UNM, 31 | TM_LEN, 32 | TM_LT, 33 | TM_LE, 34 | TM_CONCAT, 35 | TM_CALL, 36 | TM_N /* number of elements in the enum */ 37 | } TMS; 38 | 39 | 40 | 41 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 42 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 43 | 44 | #define fasttm(l,et,e) gfasttm(G(l), et, e) 45 | 46 | LUAI_DATA const char *const luaT_typenames[]; 47 | 48 | 49 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 50 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 51 | TMS event); 52 | LUAI_FUNC void luaT_init (lua_State *L); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /spa/Spa/lua/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* Key to file-handle type */ 15 | #define LUA_FILEHANDLE "FILE*" 16 | 17 | 18 | #define LUA_COLIBNAME "coroutine" 19 | LUALIB_API int (luaopen_base) (lua_State *L); 20 | 21 | #define LUA_TABLIBNAME "table" 22 | LUALIB_API int (luaopen_table) (lua_State *L); 23 | 24 | #define LUA_IOLIBNAME "io" 25 | LUALIB_API int (luaopen_io) (lua_State *L); 26 | 27 | #define LUA_OSLIBNAME "os" 28 | LUALIB_API int (luaopen_os) (lua_State *L); 29 | 30 | #define LUA_STRLIBNAME "string" 31 | LUALIB_API int (luaopen_string) (lua_State *L); 32 | 33 | #define LUA_MATHLIBNAME "math" 34 | LUALIB_API int (luaopen_math) (lua_State *L); 35 | 36 | #define LUA_DBLIBNAME "debug" 37 | LUALIB_API int (luaopen_debug) (lua_State *L); 38 | 39 | #define LUA_LOADLIBNAME "package" 40 | LUALIB_API int (luaopen_package) (lua_State *L); 41 | 42 | 43 | /* open all previous libraries */ 44 | LUALIB_API void (luaL_openlibs) (lua_State *L); 45 | 46 | 47 | 48 | #ifndef lua_assert 49 | #define lua_assert(x) ((void)0) 50 | #endif 51 | 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /spa/Spa/lua/lundump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | 9 | #define lundump_c 10 | #define LUA_CORE 11 | 12 | #include "lua.h" 13 | 14 | #include "ldebug.h" 15 | #include "ldo.h" 16 | #include "lfunc.h" 17 | #include "lmem.h" 18 | #include "lobject.h" 19 | #include "lstring.h" 20 | #include "lundump.h" 21 | #include "lzio.h" 22 | 23 | typedef struct { 24 | lua_State* L; 25 | ZIO* Z; 26 | Mbuffer* b; 27 | const char* name; 28 | } LoadState; 29 | 30 | #ifdef LUAC_TRUST_BINARIES 31 | #define IF(c,s) 32 | #define error(S,s) 33 | #else 34 | #define IF(c,s) if (c) error(S,s) 35 | 36 | static void error(LoadState* S, const char* why) 37 | { 38 | luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); 39 | luaD_throw(S->L,LUA_ERRSYNTAX); 40 | } 41 | #endif 42 | 43 | #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) 44 | #define LoadByte(S) (lu_byte)LoadChar(S) 45 | #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) 46 | #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) 47 | 48 | static void LoadBlock(LoadState* S, void* b, size_t size) 49 | { 50 | size_t r=luaZ_read(S->Z,b,size); 51 | IF (r!=0, "unexpected end"); 52 | } 53 | 54 | static int LoadChar(LoadState* S) 55 | { 56 | char x; 57 | LoadVar(S,x); 58 | return x; 59 | } 60 | 61 | static int LoadInt(LoadState* S) 62 | { 63 | int x; 64 | LoadVar(S,x); 65 | IF (x<0, "bad integer"); 66 | return x; 67 | } 68 | 69 | static lua_Number LoadNumber(LoadState* S) 70 | { 71 | lua_Number x; 72 | LoadVar(S,x); 73 | return x; 74 | } 75 | 76 | static TString* LoadString(LoadState* S) 77 | { 78 | size_t size; 79 | LoadVar(S,size); 80 | if (size==0) 81 | return NULL; 82 | else 83 | { 84 | char* s=luaZ_openspace(S->L,S->b,size); 85 | LoadBlock(S,s,size); 86 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ 87 | } 88 | } 89 | 90 | static void LoadCode(LoadState* S, Proto* f) 91 | { 92 | int n=LoadInt(S); 93 | f->code=luaM_newvector(S->L,n,Instruction); 94 | f->sizecode=n; 95 | LoadVector(S,f->code,n,sizeof(Instruction)); 96 | } 97 | 98 | static Proto* LoadFunction(LoadState* S, TString* p); 99 | 100 | static void LoadConstants(LoadState* S, Proto* f) 101 | { 102 | int i,n; 103 | n=LoadInt(S); 104 | f->k=luaM_newvector(S->L,n,TValue); 105 | f->sizek=n; 106 | for (i=0; ik[i]); 107 | for (i=0; ik[i]; 110 | int t=LoadChar(S); 111 | switch (t) 112 | { 113 | case LUA_TNIL: 114 | setnilvalue(o); 115 | break; 116 | case LUA_TBOOLEAN: 117 | setbvalue(o,LoadChar(S)!=0); 118 | break; 119 | case LUA_TNUMBER: 120 | setnvalue(o,LoadNumber(S)); 121 | break; 122 | case LUA_TSTRING: 123 | setsvalue2n(S->L,o,LoadString(S)); 124 | break; 125 | default: 126 | error(S,"bad constant"); 127 | break; 128 | } 129 | } 130 | n=LoadInt(S); 131 | f->p=luaM_newvector(S->L,n,Proto*); 132 | f->sizep=n; 133 | for (i=0; ip[i]=NULL; 134 | for (i=0; ip[i]=LoadFunction(S,f->source); 135 | } 136 | 137 | static void LoadDebug(LoadState* S, Proto* f) 138 | { 139 | int i,n; 140 | n=LoadInt(S); 141 | f->lineinfo=luaM_newvector(S->L,n,int); 142 | f->sizelineinfo=n; 143 | LoadVector(S,f->lineinfo,n,sizeof(int)); 144 | n=LoadInt(S); 145 | f->locvars=luaM_newvector(S->L,n,LocVar); 146 | f->sizelocvars=n; 147 | for (i=0; ilocvars[i].varname=NULL; 148 | for (i=0; ilocvars[i].varname=LoadString(S); 151 | f->locvars[i].startpc=LoadInt(S); 152 | f->locvars[i].endpc=LoadInt(S); 153 | } 154 | n=LoadInt(S); 155 | f->upvalues=luaM_newvector(S->L,n,TString*); 156 | f->sizeupvalues=n; 157 | for (i=0; iupvalues[i]=NULL; 158 | for (i=0; iupvalues[i]=LoadString(S); 159 | } 160 | 161 | static Proto* LoadFunction(LoadState* S, TString* p) 162 | { 163 | Proto* f; 164 | if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); 165 | f=luaF_newproto(S->L); 166 | setptvalue2s(S->L,S->L->top,f); incr_top(S->L); 167 | f->source=LoadString(S); if (f->source==NULL) f->source=p; 168 | f->linedefined=LoadInt(S); 169 | f->lastlinedefined=LoadInt(S); 170 | f->nups=LoadByte(S); 171 | f->numparams=LoadByte(S); 172 | f->is_vararg=LoadByte(S); 173 | f->maxstacksize=LoadByte(S); 174 | LoadCode(S,f); 175 | LoadConstants(S,f); 176 | LoadDebug(S,f); 177 | IF (!luaG_checkcode(f), "bad code"); 178 | S->L->top--; 179 | S->L->nCcalls--; 180 | return f; 181 | } 182 | 183 | static void LoadHeader(LoadState* S) 184 | { 185 | char h[LUAC_HEADERSIZE]; 186 | char s[LUAC_HEADERSIZE]; 187 | luaU_header(h); 188 | LoadBlock(S,s,LUAC_HEADERSIZE); 189 | IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); 190 | } 191 | 192 | /* 193 | ** load precompiled chunk 194 | */ 195 | Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) 196 | { 197 | LoadState S; 198 | if (*name=='@' || *name=='=') 199 | S.name=name+1; 200 | else if (*name==LUA_SIGNATURE[0]) 201 | S.name="binary string"; 202 | else 203 | S.name=name; 204 | S.L=L; 205 | S.Z=Z; 206 | S.b=buff; 207 | LoadHeader(&S); 208 | return LoadFunction(&S,luaS_newliteral(L,"=?")); 209 | } 210 | 211 | /* 212 | * make header 213 | */ 214 | void luaU_header (char* h) 215 | { 216 | int x=1; 217 | memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); 218 | h+=sizeof(LUA_SIGNATURE)-1; 219 | *h++=(char)LUAC_VERSION; 220 | *h++=(char)LUAC_FORMAT; 221 | *h++=(char)*(char*)&x; /* endianness */ 222 | *h++=(char)sizeof(int); 223 | *h++=(char)sizeof(size_t); 224 | *h++=(char)sizeof(Instruction); 225 | *h++=(char)sizeof(lua_Number); 226 | *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ 227 | } 228 | -------------------------------------------------------------------------------- /spa/Spa/lua/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "lobject.h" 11 | #include "lzio.h" 12 | 13 | /* load one chunk; from lundump.c */ 14 | LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); 15 | 16 | /* make header; from lundump.c */ 17 | LUAI_FUNC void luaU_header (char* h); 18 | 19 | /* dump one chunk; from ldump.c */ 20 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); 21 | 22 | #ifdef luac_c 23 | /* print one chunk; from print.c */ 24 | LUAI_FUNC void luaU_print (const Proto* f, int full); 25 | #endif 26 | 27 | /* for header of binary files -- this is Lua 5.1 */ 28 | #define LUAC_VERSION 0x51 29 | 30 | /* for header of binary files -- this is the official format */ 31 | #define LUAC_FORMAT 0 32 | 33 | /* size of header of binary files */ 34 | #define LUAC_HEADERSIZE 12 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /spa/Spa/lua/lvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lvm_h 8 | #define lvm_h 9 | 10 | 11 | #include "ldo.h" 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | 15 | 16 | #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) 17 | 18 | #define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ 19 | (((o) = luaV_tonumber(o,n)) != NULL)) 20 | 21 | #define equalobj(L,o1,o2) \ 22 | (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) 23 | 24 | 25 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 26 | LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); 27 | LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); 28 | LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); 29 | LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, 30 | StkId val); 31 | LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, 32 | StkId val); 33 | LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); 34 | LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /spa/Spa/lua/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** a generic input stream interface 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lzio_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "llimits.h" 16 | #include "lmem.h" 17 | #include "lstate.h" 18 | #include "lzio.h" 19 | 20 | 21 | int luaZ_fill (ZIO *z) { 22 | size_t size; 23 | lua_State *L = z->L; 24 | const char *buff; 25 | lua_unlock(L); 26 | buff = z->reader(L, z->data, &size); 27 | lua_lock(L); 28 | if (buff == NULL || size == 0) return EOZ; 29 | z->n = size - 1; 30 | z->p = buff; 31 | return char2int(*(z->p++)); 32 | } 33 | 34 | 35 | int luaZ_lookahead (ZIO *z) { 36 | if (z->n == 0) { 37 | if (luaZ_fill(z) == EOZ) 38 | return EOZ; 39 | else { 40 | z->n++; /* luaZ_fill removed first byte; put back it */ 41 | z->p--; 42 | } 43 | } 44 | return char2int(*z->p); 45 | } 46 | 47 | 48 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 49 | z->L = L; 50 | z->reader = reader; 51 | z->data = data; 52 | z->n = 0; 53 | z->p = NULL; 54 | } 55 | 56 | 57 | /* --------------------------------------------------------------- read --- */ 58 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 59 | while (n) { 60 | size_t m; 61 | if (luaZ_lookahead(z) == EOZ) 62 | return n; /* return number of missing bytes */ 63 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 64 | memcpy(b, z->p, m); 65 | z->n -= m; 66 | z->p += m; 67 | b = (char *)b + m; 68 | n -= m; 69 | } 70 | return 0; 71 | } 72 | 73 | /* ------------------------------------------------------------------------ */ 74 | char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { 75 | if (n > buff->buffsize) { 76 | if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; 77 | luaZ_resizebuffer(L, buff, n); 78 | } 79 | return buff->buffer; 80 | } 81 | 82 | 83 | -------------------------------------------------------------------------------- /spa/Spa/lua/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define char2int(c) cast(int, cast(unsigned char, (c))) 21 | 22 | #define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) 23 | 24 | typedef struct Mbuffer { 25 | char *buffer; 26 | size_t n; 27 | size_t buffsize; 28 | } Mbuffer; 29 | 30 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 31 | 32 | #define luaZ_buffer(buff) ((buff)->buffer) 33 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 34 | #define luaZ_bufflen(buff) ((buff)->n) 35 | 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ 41 | (buff)->buffsize = size) 42 | 43 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 44 | 45 | 46 | LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ 50 | LUAI_FUNC int luaZ_lookahead (ZIO *z); 51 | 52 | 53 | 54 | /* --------- Private Part ------------------ */ 55 | 56 | struct Zio { 57 | size_t n; /* bytes still unread */ 58 | const char *p; /* current position in buffer */ 59 | lua_Reader reader; 60 | void* data; /* additional data */ 61 | lua_State *L; /* Lua state (for reader) */ 62 | }; 63 | 64 | 65 | LUAI_FUNC int luaZ_fill (ZIO *z); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /spa/Spa/lua/print.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $ 3 | ** print bytecodes 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #define luac_c 11 | #define LUA_CORE 12 | 13 | #include "ldebug.h" 14 | #include "lobject.h" 15 | #include "lopcodes.h" 16 | #include "lundump.h" 17 | 18 | #define PrintFunction luaU_print 19 | 20 | #define Sizeof(x) ((int)sizeof(x)) 21 | #define VOID(p) ((const void*)(p)) 22 | 23 | static void PrintString(const TString* ts) 24 | { 25 | const char* s=getstr(ts); 26 | size_t i,n=ts->tsv.len; 27 | putchar('"'); 28 | for (i=0; ik[i]; 54 | switch (ttype(o)) 55 | { 56 | case LUA_TNIL: 57 | printf("nil"); 58 | break; 59 | case LUA_TBOOLEAN: 60 | printf(bvalue(o) ? "true" : "false"); 61 | break; 62 | case LUA_TNUMBER: 63 | printf(LUA_NUMBER_FMT,nvalue(o)); 64 | break; 65 | case LUA_TSTRING: 66 | PrintString(rawtsvalue(o)); 67 | break; 68 | default: /* cannot happen */ 69 | printf("? type=%d",ttype(o)); 70 | break; 71 | } 72 | } 73 | 74 | static void PrintCode(const Proto* f) 75 | { 76 | const Instruction* code=f->code; 77 | int pc,n=f->sizecode; 78 | for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); 90 | printf("%-9s\t",luaP_opnames[o]); 91 | switch (getOpMode(o)) 92 | { 93 | case iABC: 94 | printf("%d",a); 95 | if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); 96 | if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); 97 | break; 98 | case iABx: 99 | if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); 100 | break; 101 | case iAsBx: 102 | if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); 103 | break; 104 | } 105 | switch (o) 106 | { 107 | case OP_LOADK: 108 | printf("\t; "); PrintConstant(f,bx); 109 | break; 110 | case OP_GETUPVAL: 111 | case OP_SETUPVAL: 112 | printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-"); 113 | break; 114 | case OP_GETGLOBAL: 115 | case OP_SETGLOBAL: 116 | printf("\t; %s",svalue(&f->k[bx])); 117 | break; 118 | case OP_GETTABLE: 119 | case OP_SELF: 120 | if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } 121 | break; 122 | case OP_SETTABLE: 123 | case OP_ADD: 124 | case OP_SUB: 125 | case OP_MUL: 126 | case OP_DIV: 127 | case OP_POW: 128 | case OP_EQ: 129 | case OP_LT: 130 | case OP_LE: 131 | if (ISK(b) || ISK(c)) 132 | { 133 | printf("\t; "); 134 | if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); 135 | printf(" "); 136 | if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); 137 | } 138 | break; 139 | case OP_JMP: 140 | case OP_FORLOOP: 141 | case OP_FORPREP: 142 | printf("\t; to %d",sbx+pc+2); 143 | break; 144 | case OP_CLOSURE: 145 | printf("\t; %p",VOID(f->p[bx])); 146 | break; 147 | case OP_SETLIST: 148 | if (c==0) printf("\t; %d",(int)code[++pc]); 149 | else printf("\t; %d",c); 150 | break; 151 | default: 152 | break; 153 | } 154 | printf("\n"); 155 | } 156 | } 157 | 158 | #define SS(x) (x==1)?"":"s" 159 | #define S(x) x,SS(x) 160 | 161 | static void PrintHeader(const Proto* f) 162 | { 163 | const char* s=getstr(f->source); 164 | if (*s=='@' || *s=='=') 165 | s++; 166 | else if (*s==LUA_SIGNATURE[0]) 167 | s="(bstring)"; 168 | else 169 | s="(string)"; 170 | printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", 171 | (f->linedefined==0)?"main":"function",s, 172 | f->linedefined,f->lastlinedefined, 173 | S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); 174 | printf("%d%s param%s, %d slot%s, %d upvalue%s, ", 175 | f->numparams,f->is_vararg?"+":"",SS(f->numparams), 176 | S(f->maxstacksize),S(f->nups)); 177 | printf("%d local%s, %d constant%s, %d function%s\n", 178 | S(f->sizelocvars),S(f->sizek),S(f->sizep)); 179 | } 180 | 181 | static void PrintConstants(const Proto* f) 182 | { 183 | int i,n=f->sizek; 184 | printf("constants (%d) for %p:\n",n,VOID(f)); 185 | for (i=0; isizelocvars; 196 | printf("locals (%d) for %p:\n",n,VOID(f)); 197 | for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); 201 | } 202 | } 203 | 204 | static void PrintUpvalues(const Proto* f) 205 | { 206 | int i,n=f->sizeupvalues; 207 | printf("upvalues (%d) for %p:\n",n,VOID(f)); 208 | if (f->upvalues==NULL) return; 209 | for (i=0; iupvalues[i])); 212 | } 213 | } 214 | 215 | void PrintFunction(const Proto* f, int full) 216 | { 217 | int i,n=f->sizep; 218 | PrintHeader(f); 219 | PrintCode(f); 220 | if (full) 221 | { 222 | PrintConstants(f); 223 | PrintLocals(f); 224 | PrintUpvalues(f); 225 | } 226 | for (i=0; ip[i],full); 227 | } 228 | -------------------------------------------------------------------------------- /spa/Spa/stdlib/class.lua: -------------------------------------------------------------------------------- 1 | function spa_class(class_name) 2 | local class_userdata = spa.class.create(class_name) 3 | 4 | local _M = {self = class_userdata} 5 | 6 | setmetatable(_M, { 7 | __newindex = function(self, key, value) 8 | class_userdata[key] = value 9 | end, 10 | 11 | __index = function(self, key) 12 | return spa.class.create(key) or class_userdata[key] or _G[key] 13 | end, 14 | }) 15 | 16 | setfenv(2, _M) 17 | 18 | return class_userdata 19 | end 20 | 21 | function class_in(class_name, func_name, func) 22 | spa.setCSToTls(class_name, func_name) 23 | spa_class(class_name) 24 | self[func_name] = function(self, ...) 25 | local cls, sel = spa.getCSFromTls() 26 | if (cls == class_name and sel == func_name) then 27 | return func(...) 28 | else 29 | return self["ORIG" .. func_name](self, ...) 30 | end 31 | end 32 | end 33 | 34 | function class_out(class_name, func_name) 35 | spa.class.recoverMethod(class_name, func_name) 36 | spa.removeKeyFromTls() 37 | end 38 | 39 | function class_deep(class_name, func_name, class_name_in, func_name_in, func) 40 | spa_class(class_name)[func_name] = function (self, ...) 41 | class_in(class_name_in, func_name_in, func) 42 | local result = self["ORIG" .. func_name](self, ...) 43 | class_out(class_name_in, func_name_in) 44 | return result 45 | end 46 | end 47 | 48 | function block(func, r_type, args_t) 49 | local _M = {return_type=r_type, args_type=args_t} 50 | setmetatable(_M, {__index = _G}) 51 | setfenv(func, _M) 52 | return func 53 | end 54 | -------------------------------------------------------------------------------- /spa/Spa/stdlib/init.lua: -------------------------------------------------------------------------------- 1 | require "spa.class" 2 | require "spa.trace" 3 | -------------------------------------------------------------------------------- /spa/Spa/stdlib/trace.lua: -------------------------------------------------------------------------------- 1 | require "spa.class" 2 | 3 | spa_watchFunction = function (self, ...) 4 | local class_name, func_name = unpack(getfenv(1)) 5 | 6 | local args = spa.toLuaString(spa.toId({...})) 7 | local start_time = os.time() 8 | local r = self["ORIG" .. func_name](self, ...) 9 | local end_time = os.time() 10 | 11 | local log = "\n=================================\n" 12 | log = log .. "| " .. class_name .. "|" .. func_name .. "\n" 13 | log = log .. "| watch report |\n" 14 | log = log .. "---------------------------------\n" 15 | log = log .. "args: \n" 16 | log = log .. args 17 | log = log .. "\n---------------------------------\n" 18 | log = log .. "start time: " .. tostring(start_time) 19 | log = log .. "\n" 20 | log = log .. "end time : " .. tostring(end_time) 21 | log = log .. "\n---------------------------------\n" 22 | log = log .. "return value: \n" 23 | if (r ~= nil) then 24 | log = log .. spa.toLuaString(spa.toId(r)) 25 | else 26 | log = log .. "### no result value ###" 27 | end 28 | log = log .. "\n=================================\n" 29 | spa.log(log) 30 | spa.class.recoverMethod(class_name, func_name) 31 | return r 32 | end 33 | 34 | function watch(class_name, func_name) 35 | spa_class(class_name) 36 | local _M = {class_name, func_name} 37 | setmetatable(_M, {__index = _G}) 38 | setfenv(spa_watchFunction, _M) 39 | self[func_name] = spa_watchFunction 40 | end 41 | 42 | function watch_in(class_name, func_name) 43 | spa.setCSToTls(class_name, func_name) 44 | spa_class(class_name) 45 | self[func_name] = function(self, ...) 46 | local cls, sel = spa.getCSFromTls() 47 | if (cls == class_name and sel == func_name) then 48 | local _M = {class_name, func_name} 49 | setmetatable(_M, {__index = _G}) 50 | setfenv(spa_watchFunction, _M) 51 | spa_watchFunction(self, ...) 52 | else 53 | self["ORIG" .. func_name](self, ...) 54 | end 55 | end 56 | end 57 | 58 | function watch_out(class_name, func_name) 59 | spa.class.recoverMethod(class_name, func_name) 60 | spa.removeKeyFromTls() 61 | end 62 | 63 | function watch_deep(class_name, func_name, class_name_in, func_name_in) 64 | spa_class(class_name)[func_name] = function (self, ...) 65 | watch_in(class_name_in, func_name_in) 66 | self["ORIG" .. func_name](self, ...) 67 | watch_out(class_name_in, func_name_in) 68 | spa.class.recoverMethod(class_name, func_name) 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /spa/SpaDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /spa/SpaDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /spa/SpaDemo.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /spa/SpaDemo.xcodeproj/project.xcworkspace/xcuserdata/familyfan.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzfanfei/spa/1184d64e440ee85b050d7cedc8432110bb776b9d/spa/SpaDemo.xcodeproj/project.xcworkspace/xcuserdata/familyfan.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /spa/SpaDemo.xcodeproj/project.xcworkspace/xcuserdata/familyfan.xcuserdatad/xcdebugger/Expressions.xcexplist: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /spa/SpaDemo.xcodeproj/xcshareddata/xcschemes/Spa.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /spa/SpaDemo.xcodeproj/xcuserdata/familyfan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /spa/SpaDemo.xcodeproj/xcuserdata/familyfan.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Spa.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 1 11 | 12 | SpaDemo.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /spa/SpaDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // SpaDemo 4 | // 5 | // Created by Family Fan on 2018/11/29. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /spa/SpaDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // SpaDemo 4 | // 5 | // Created by Family Fan on 2018/11/29. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "Spa.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | 25 | } 26 | 27 | - (void)applicationDidEnterBackground:(UIApplication *)application { 28 | 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application { 32 | } 33 | 34 | 35 | - (void)applicationDidBecomeActive:(UIApplication *)application { 36 | } 37 | 38 | - (void)applicationWillTerminate:(UIApplication *)application { 39 | } 40 | 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /spa/SpaDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /spa/SpaDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /spa/SpaDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /spa/SpaDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /spa/SpaDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /spa/SpaDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // SpaDemo 4 | // 5 | // Created by Family Fan on 2018/11/29. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /spa/SpaDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // SpaDemo 4 | // 5 | // Created by Family Fan on 2018/11/29. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "Spa.h" 11 | 12 | typedef struct SPA_POINT { 13 | char *s; 14 | }SPA_POINT; 15 | 16 | @interface OCPoint : NSObject 17 | 18 | @property (nonatomic) char *s; 19 | 20 | @end 21 | 22 | @implementation OCPoint 23 | 24 | 25 | @end 26 | 27 | @interface Persion1 : NSObject 28 | 29 | @property (nonatomic) NSString* name; 30 | @property (nonatomic) int age; 31 | 32 | @end 33 | 34 | @implementation Persion1 35 | 36 | @end 37 | 38 | 39 | @interface ViewController () 40 | 41 | @end 42 | 43 | @implementation ViewController 44 | 45 | - (void)viewDidLoad { 46 | [super viewDidLoad]; 47 | [[Spa sharedInstace] setLogBlock:^(NSString *log) { 48 | printf("%s", log.UTF8String); 49 | }]; 50 | NSString* script = @"spa.log('trace script'); spa.trace.start('www.baidu.com') \n"; 51 | [[Spa sharedInstace] usePatch:script]; 52 | } 53 | 54 | - (IBAction)usePatch:(id)sender { 55 | NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://127.0.0.1:8088"]]; 56 | NSURLResponse * response = nil; 57 | NSError * error = nil; 58 | NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest 59 | returningResponse:&response 60 | error:&error]; 61 | if (error == nil) { 62 | NSString* patchString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 63 | [[Spa sharedInstace] usePatch:patchString]; 64 | 65 | [self doSomeThing]; 66 | } 67 | } 68 | 69 | - (void)doSomeThing 70 | { 71 | 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /spa/SpaDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SpaDemo 4 | // 5 | // Created by Family Fan on 2018/11/29. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /spa/SpaDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /spa/SpaDemoTests/SpaBlockFunctionTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // SpaBlockFunctionTest.m 3 | // SpaDemoTests 4 | // 5 | // Created by Family Fan on 2018/12/18. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SpaBlockFunctionTest : XCTestCase 13 | 14 | @property (nonatomic) int index; 15 | 16 | @end 17 | 18 | @implementation SpaBlockFunctionTest 19 | 20 | - (void)blkVoidVoid:(void(^)(void))block 21 | { 22 | block(); 23 | } 24 | 25 | - (void)blkVoidArg:(void(^)(int i))block 26 | { 27 | block(5); 28 | } 29 | 30 | - (void)blkOneVoid:(int(^)(void))block 31 | { 32 | self.index = block(); 33 | } 34 | 35 | - (void)blkOneArg:(int(^)(int i))block 36 | { 37 | self.index = block(11); 38 | } 39 | 40 | - (void)blkVoidArgs:(void(^)(int w1, int w2, int w3, int w4, int w5, int w6, int w7, int w8, int w9))block 41 | { 42 | block(1, 2, 3, 4, 5, 6, 7, 8, 9); 43 | } 44 | 45 | 46 | - (void)setUp { 47 | [[Spa sharedInstace] setLogBlock:^(NSString *log) { 48 | NSLog(@"%s", log.UTF8String); 49 | }]; 50 | } 51 | 52 | - (void)tearDown { 53 | // Put teardown code here. This method is called after the invocation of each test method in the class. 54 | } 55 | 56 | - (void)testExample { 57 | 58 | 59 | // no args no result 60 | [self blkVoidVoid:^{ 61 | self.index ++; 62 | }]; 63 | XCTAssert(self.index == 1); 64 | 65 | NSString* script = @"\ 66 | spa_class(\"SpaBlockFunctionTest\") \n \ 67 | function blkVoidVoid_(self, blk) \n \ 68 | blk() \n \ 69 | self:setIndex_(self:index() + 1) \n \ 70 | end \n"; 71 | [[Spa sharedInstace] usePatch:script]; 72 | [self blkVoidVoid:^{ 73 | self.index ++; 74 | }]; 75 | XCTAssert(self.index == 3); 76 | 77 | // one arg no result 78 | [self blkVoidArg:^(int i) { 79 | self.index = i; 80 | }]; 81 | XCTAssert(self.index == 5); 82 | script = @"\ 83 | spa_class(\"SpaBlockFunctionTest\") \n \ 84 | function blkVoidArg_(self, blk) \n \ 85 | blk(6) \n \ 86 | end \n"; 87 | [[Spa sharedInstace] usePatch:script]; 88 | [self blkVoidArg:^(int i) { 89 | self.index = i; 90 | }]; 91 | XCTAssert(self.index == 6); 92 | 93 | // one result 94 | [self blkOneVoid:^int{ 95 | return 9; 96 | }]; 97 | XCTAssert(self.index == 9); 98 | script = @"\ 99 | spa_class(\"SpaBlockFunctionTest\") \n \ 100 | function blkOneVoid_(self, blk) \n \ 101 | self:setIndex_(blk()) \n \ 102 | self:setIndex_(self:index() + 1) \n \ 103 | end \n"; 104 | [[Spa sharedInstace] usePatch:script]; 105 | [self blkOneVoid:^int{ 106 | return 9; 107 | }]; 108 | XCTAssert(self.index == 10); 109 | 110 | // one result one args 111 | [self blkOneArg:^int(int i) { 112 | return i; 113 | }]; 114 | XCTAssert(self.index == 11); 115 | script = @"\ 116 | spa_class(\"SpaBlockFunctionTest\") \n \ 117 | function blkOneArg_(self, blk) \n \ 118 | self:setIndex_(blk(12)) \n \ 119 | end \n"; 120 | [[Spa sharedInstace] usePatch:script]; 121 | [self blkOneArg:^int(int i) { 122 | return i; 123 | }]; 124 | XCTAssert(self.index == 12); 125 | 126 | 127 | // many many args 128 | [self blkVoidArgs:^(int w1, int w2, int w3, int w4, int w5, int w6, int w7, int w8, int w9) { 129 | self.index = w1 + w2 + w3 + w4 + w5 + w6 + w7 + w8 + w9; 130 | }]; 131 | XCTAssert(self.index == 45); 132 | script = @"\ 133 | spa_class(\"SpaBlockFunctionTest\") \n \ 134 | function blkVoidArgs_(self, blk) \n \ 135 | blk(1, 1, 1, 1, 1, 1, 1, 1, 1) \n \ 136 | end \n"; 137 | [[Spa sharedInstace] usePatch:script]; 138 | [self blkVoidArgs:^(int w1, int w2, int w3, int w4, int w5, int w6, int w7, int w8, int w9) { 139 | self.index = w1 + w2 + w3 + w4 + w5 + w6 + w7 + w8 + w9; 140 | }]; 141 | XCTAssert(self.index == 9); 142 | } 143 | 144 | - (void)testPerformanceExample { 145 | // This is an example of a performance test case. 146 | [self measureBlock:^{ 147 | // Put the code you want to measure the time of here. 148 | }]; 149 | } 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /spa/SpaDemoTests/SpaCreateTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // SpaCreateTest.m 3 | // SpaDemoTests 4 | // 5 | // Created by Family Fan on 2018/12/18. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface Persion2 : NSObject 13 | 14 | @property (nonatomic) NSString* name; 15 | @property (nonatomic) NSNumber* age; 16 | 17 | @end 18 | 19 | @implementation Persion2 20 | 21 | @end 22 | 23 | typedef struct _XPoint2 24 | { 25 | int x; 26 | int y; 27 | }XPoint2; 28 | 29 | @interface SpaCreateTest : XCTestCase 30 | 31 | @end 32 | 33 | @implementation SpaCreateTest 34 | 35 | - (char)argInChar 36 | { 37 | return 'c'; 38 | } 39 | 40 | - (int)argInInt 41 | { 42 | return 9; 43 | } 44 | 45 | - (short)argInShort 46 | { 47 | return 9; 48 | } 49 | 50 | - (long)argInLong 51 | { 52 | return 9; 53 | } 54 | 55 | - (long long)argInLongLong 56 | { 57 | return 9; 58 | } 59 | 60 | - (float)argInFloat 61 | { 62 | return 3.14f; 63 | } 64 | 65 | - (double)argInDouble 66 | { 67 | return 3.14f; 68 | } 69 | 70 | - (bool)argInBool 71 | { 72 | return true; 73 | } 74 | 75 | - (char *)argInCharX 76 | { 77 | return "string"; 78 | } 79 | 80 | - (NSString *)argInString 81 | { 82 | return @"NSString"; 83 | } 84 | 85 | - (NSNumber *)argInNSNumber 86 | { 87 | return @9; 88 | } 89 | 90 | - (NSArray *)argInNSArray 91 | { 92 | return @[@1, @2]; 93 | } 94 | 95 | - (NSDictionary *)argInNSDictionary 96 | { 97 | return @{@"key1":@1, @"key2":@2}; 98 | } 99 | 100 | - (Persion2 *)argInPersion 101 | { 102 | Persion2* p = [[Persion2 alloc] init]; 103 | p.name = @"joy"; 104 | p.age = @18; 105 | return p; 106 | } 107 | 108 | - (XPoint2)argInXPoint 109 | { 110 | XPoint2 p; 111 | p.x = 3; 112 | p.y = 4; 113 | return p; 114 | } 115 | 116 | - (SEL)argInSel 117 | { 118 | return @selector(argInSel); 119 | } 120 | 121 | - (void)setUp { 122 | [[Spa sharedInstace] setLogBlock:^(NSString *log) { 123 | NSLog(@"%s", log.UTF8String); 124 | }]; 125 | } 126 | 127 | - (void)tearDown { 128 | // Put teardown code here. This method is called after the invocation of each test method in the class. 129 | } 130 | 131 | - (void)testExample { 132 | NSString* script = @"\ 133 | spa_class(\"SpaCreateTest\") \n \ 134 | function argInXPoint() \n \ 135 | return {3,4} \n \ 136 | end \n"; 137 | [[Spa sharedInstace] usePatch:script]; 138 | 139 | XCTAssert([self argInXPoint].x == 3); 140 | XCTAssert([self argInXPoint].y == 4); 141 | 142 | script = @"\ 143 | spa_class(\"SpaCreateTest\") \n \ 144 | function argInChar() \n \ 145 | return 'c' \n \ 146 | end \n"; 147 | [[Spa sharedInstace] usePatch:script]; 148 | XCTAssert([self argInChar] == 'c'); 149 | 150 | script = @"\ 151 | spa_class(\"SpaCreateTest\") \n \ 152 | function argInInt() \n \ 153 | return 9 \n \ 154 | end \n"; 155 | [[Spa sharedInstace] usePatch:script]; 156 | XCTAssert([self argInInt] == 9); 157 | 158 | script = @"\ 159 | spa_class(\"SpaCreateTest\") \n \ 160 | function argInShort() \n \ 161 | return 9 \n \ 162 | end \n"; 163 | [[Spa sharedInstace] usePatch:script]; 164 | XCTAssert([self argInShort] == 9); 165 | 166 | script = @"\ 167 | spa_class(\"SpaCreateTest\") \n \ 168 | function argInLong() \n \ 169 | return 9 \n \ 170 | end \n"; 171 | [[Spa sharedInstace] usePatch:script]; 172 | XCTAssert([self argInLong] == 9); 173 | 174 | script = @"\ 175 | spa_class(\"SpaCreateTest\") \n \ 176 | function argInLongLong() \n \ 177 | return 9 \n \ 178 | end \n"; 179 | [[Spa sharedInstace] usePatch:script]; 180 | XCTAssert([self argInLongLong] == 9); 181 | 182 | script = @"\ 183 | spa_class(\"SpaCreateTest\") \n \ 184 | function argInFloat() \n \ 185 | return 9 \n \ 186 | end \n"; 187 | [[Spa sharedInstace] usePatch:script]; 188 | XCTAssert([self argInFloat] == 9); 189 | 190 | script = @"\ 191 | spa_class(\"SpaCreateTest\") \n \ 192 | function argInDouble() \n \ 193 | return 9 \n \ 194 | end \n"; 195 | [[Spa sharedInstace] usePatch:script]; 196 | XCTAssert([self argInDouble] == 9); 197 | 198 | script = @"\ 199 | spa_class(\"SpaCreateTest\") \n \ 200 | function argInBool() \n \ 201 | return 9 \n \ 202 | end \n"; 203 | [[Spa sharedInstace] usePatch:script]; 204 | XCTAssert([self argInBool] == true); 205 | 206 | script = @"\ 207 | spa_class(\"SpaCreateTest\") \n \ 208 | function argInCharX() \n \ 209 | return 'string' \n \ 210 | end \n"; 211 | [[Spa sharedInstace] usePatch:script]; 212 | XCTAssert(strcmp([self argInCharX], "string") == 0); 213 | 214 | script = @"\ 215 | spa_class(\"SpaCreateTest\") \n \ 216 | function argInString() \n \ 217 | return 'NSString' \n \ 218 | end \n"; 219 | [[Spa sharedInstace] usePatch:script]; 220 | XCTAssert([[self argInString] isEqualToString:@"NSString"]); 221 | 222 | script = @"\ 223 | spa_class(\"SpaCreateTest\") \n \ 224 | function argInNSNumber() \n \ 225 | return 9 \n \ 226 | end \n"; 227 | [[Spa sharedInstace] usePatch:script]; 228 | XCTAssert([[self argInNSNumber] isEqualToNumber:@9]); 229 | 230 | script = @"\ 231 | spa_class(\"SpaCreateTest\") \n \ 232 | function argInNSArray() \n \ 233 | return {1, 2} \n \ 234 | end \n"; 235 | [[Spa sharedInstace] usePatch:script]; 236 | XCTAssert([[[self argInNSArray] objectAtIndex:0] isEqualToNumber:@1]); 237 | XCTAssert([[[self argInNSArray] objectAtIndex:1] isEqualToNumber:@2]); 238 | 239 | script = @"\ 240 | spa_class(\"SpaCreateTest\") \n \ 241 | function argInNSDictionary() \n \ 242 | return {key1=1, key2=2} \n \ 243 | end \n"; 244 | [[Spa sharedInstace] usePatch:script]; 245 | XCTAssert([[[self argInNSDictionary] objectForKey:@"key1"] isEqualToNumber:@1]); 246 | XCTAssert([[[self argInNSDictionary] objectForKey:@"key2"] isEqualToNumber:@2]); 247 | 248 | script = @"\ 249 | spa_class(\"SpaCreateTest\") \n \ 250 | function argInPersion() \n \ 251 | local p = Persion2:alloc():init() \n \ 252 | p:setName_('joy') \n \ 253 | p:setAge_(18) \n \ 254 | return p \n \ 255 | end \n"; 256 | [[Spa sharedInstace] usePatch:script]; 257 | XCTAssert([[self argInPersion].name isEqualToString:@"joy"]); 258 | XCTAssert([[self argInPersion].age isEqualToNumber:@18]); 259 | 260 | script = @"\ 261 | spa_class(\"SpaCreateTest\") \n \ 262 | function argInSel() \n \ 263 | return 'argInSel:' \n \ 264 | end \n"; 265 | [[Spa sharedInstace] usePatch:script]; 266 | XCTAssert([self argInSel] == @selector(argInSel:)); 267 | } 268 | 269 | - (void)testPerformanceExample { 270 | // This is an example of a performance test case. 271 | [self measureBlock:^{ 272 | // Put the code you want to measure the time of here. 273 | }]; 274 | } 275 | 276 | @end 277 | -------------------------------------------------------------------------------- /spa/SpaDemoTests/SpaDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SpaDemoTests.m 3 | // SpaDemoTests 4 | // 5 | // Created by Family Fan on 2018/12/14. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SpaDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation SpaDemoTests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | } 20 | 21 | - (void)tearDown { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | - (void)testExample { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | } 29 | 30 | - (void)testPerformanceExample { 31 | // This is an example of a performance test case. 32 | [self measureBlock:^{ 33 | // Put the code you want to measure the time of here. 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /spa/SpaDemoTests/SpaFunctionTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // SpaFunctionTest.m 3 | // SpaDemoTests 4 | // 5 | // Created by Family Fan on 2018/12/14. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SpaFunctionTest : XCTestCase 13 | 14 | @property (nonatomic) NSString* world; 15 | 16 | @end 17 | 18 | @implementation SpaFunctionTest 19 | 20 | - (void)command 21 | { 22 | self.world = @"dark"; 23 | } 24 | 25 | - (void)command:(NSString *)words 26 | { 27 | self.world = words; 28 | } 29 | 30 | - (NSString *)front 31 | { 32 | return @"back"; 33 | } 34 | 35 | - (NSString *)weAreSame:(NSString *)words 36 | { 37 | return @"not same"; 38 | } 39 | 40 | - (NSString *)worried:(NSString *)w1 w2:(NSString *)w2 w3:(NSString *)w3 w4:(NSString *)w4 w5:(NSString *)w5 w6:(NSString *)w6 w7:(NSString *)w7 w8:(NSString *)w8 w9:(NSString *)w9 41 | { 42 | return [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@", w1, w2, w3, w4, w5, w6, w7, w8, w9]; 43 | } 44 | 45 | - (void)setUp { 46 | [[Spa sharedInstace] setLogBlock:^(NSString *log) { 47 | NSLog(@"%s", log.UTF8String); 48 | }]; 49 | } 50 | 51 | - (void)tearDown { 52 | // Put teardown code here. This method is called after the invocation of each test method in the class. 53 | } 54 | 55 | - (void)testExample { 56 | 57 | // no args no result 58 | NSString* script = @"\ 59 | spa_class(\"SpaFunctionTest\") \n \ 60 | function command(self) \n \ 61 | self:setWorld_(\"light\") \n \ 62 | end \n"; 63 | [self command]; 64 | XCTAssertEqualObjects(self.world, @"dark"); 65 | [[Spa sharedInstace] usePatch:script]; 66 | [self command]; 67 | XCTAssertEqualObjects(self.world, @"light"); 68 | 69 | // one arg no result 70 | [self command:@"You cann't"]; 71 | XCTAssertEqualObjects(self.world, @"You cann't"); 72 | script = @"\ 73 | spa_class(\"SpaFunctionTest\") \n \ 74 | function command_(self, words) \n \ 75 | self:setWorld_(\"You can\") \n \ 76 | end \n"; 77 | [[Spa sharedInstace] usePatch:script]; 78 | [self command:@"You cann't"]; 79 | XCTAssertEqualObjects(self.world, @"You can"); 80 | 81 | // one result 82 | XCTAssertEqualObjects([self front], @"back"); 83 | script = @"\ 84 | spa_class(\"SpaFunctionTest\") \n \ 85 | function front() \n \ 86 | return \"front\" \n \ 87 | end \n"; 88 | [[Spa sharedInstace] usePatch:script]; 89 | XCTAssertEqualObjects([self front], @"front"); 90 | 91 | // one result one args 92 | XCTAssertEqualObjects([self weAreSame:@"same"], @"not same"); 93 | script = @"\ 94 | spa_class(\"SpaFunctionTest\") \n \ 95 | function weAreSame_(self, same) \n \ 96 | return same \n \ 97 | end \n"; 98 | [[Spa sharedInstace] usePatch:script]; 99 | XCTAssertEqualObjects([self weAreSame:@"same"], @"same"); 100 | 101 | // many many args 102 | XCTAssertEqualObjects([self worried:@"w1" w2:@"w2" w3:@"w3" w4:@"w4" w5:@"w5" w6:@"w6" w7:@"w7" w8:@"w8" w9:@"w9"], @"w1w2w3w4w5w6w7w8w9"); 103 | script = @"\ 104 | spa_class(\"SpaFunctionTest\") \n \ 105 | function worried_w2_w3_w4_w5_w6_w7_w8_w9_(self, w1, w2, w3, w4, w5, w6, w7, w8, w9) \n \ 106 | return \"---------\" .. w1 .. w2 .. w3 .. w4 .. w5 .. w6 .. w7 .. w8 .. w9 \n \ 107 | end \n"; 108 | [[Spa sharedInstace] usePatch:script]; 109 | XCTAssertEqualObjects([self worried:@"w1" w2:@"w2" w3:@"w3" w4:@"w4" w5:@"w5" w6:@"w6" w7:@"w7" w8:@"w8" w9:@"w9"], @"---------w1w2w3w4w5w6w7w8w9"); 110 | } 111 | 112 | - (void)testPerformanceExample { 113 | // This is an example of a performance test case. 114 | [self measureBlock:^{ 115 | // Put the code you want to measure the time of here. 116 | }]; 117 | } 118 | 119 | @end 120 | -------------------------------------------------------------------------------- /spa/SpaDemoTests/SpaInvokeTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // SpaInvokeTest.m 3 | // SpaDemoTests 4 | // 5 | // Created by Family Fan on 2018/12/18. 6 | // Copyright © 2018 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SpaInvokeTest : XCTestCase 13 | 14 | @end 15 | 16 | @interface SpaInvokeTestSubClass : SpaInvokeTest 17 | 18 | @end 19 | 20 | @implementation SpaInvokeTestSubClass 21 | 22 | - (NSString *)getString 23 | { 24 | return @"sub static"; 25 | } 26 | 27 | - (void)testExample 28 | { 29 | // super test 30 | NSString* script = @"\ 31 | spa_class(\"SpaInvokeTestSubClass\") \n \ 32 | function getString(self) \n \ 33 | return self:SUPERgetString() \n \ 34 | end \n"; 35 | [[Spa sharedInstace] usePatch:script]; 36 | 37 | XCTAssert([[self getString] isEqualToString:@"static"]); 38 | 39 | // origin test 40 | script = @"\ 41 | spa_class(\"SpaInvokeTestSubClass\") \n \ 42 | function getString(self) \n \ 43 | return self:ORIGgetString() \n \ 44 | end \n"; 45 | [[Spa sharedInstace] usePatch:script]; 46 | 47 | XCTAssert([[self getString] isEqualToString:@"sub static"]); 48 | } 49 | 50 | @end 51 | 52 | 53 | @implementation SpaInvokeTest 54 | 55 | + (NSString *)getString 56 | { 57 | return @"dy"; 58 | } 59 | 60 | - (NSString *)getString 61 | { 62 | return @"static"; 63 | } 64 | 65 | + (NSString *)getStringStatic 66 | { 67 | return @"dy"; 68 | } 69 | 70 | - (void)setUp { 71 | [[Spa sharedInstace] setLogBlock:^(NSString *log) { 72 | NSLog(@"%s", log.UTF8String); 73 | }]; 74 | } 75 | 76 | - (void)tearDown { 77 | // Put teardown code here. This method is called after the invocation of each test method in the class. 78 | } 79 | 80 | - (void)testExample { 81 | 82 | // static and dy 83 | NSString* script = @"\ 84 | spa_class(\"SpaInvokeTest\") \n \ 85 | function STATICgetString(self) \n \ 86 | return 'static' \n \ 87 | end \n \ 88 | function getString(self) \n \ 89 | return 'dy' \n \ 90 | end \n"; 91 | [[Spa sharedInstace] usePatch:script]; 92 | 93 | XCTAssert([[self getString] isEqualToString:@"dy"]); 94 | XCTAssert([[SpaInvokeTest getString] isEqualToString:@"static"]); 95 | 96 | // dy 97 | script = @"\ 98 | spa_class(\"SpaInvokeTest\") \n \ 99 | function getString(self) \n \ 100 | return 'dy' \n \ 101 | end \n"; 102 | [[Spa sharedInstace] usePatch:script]; 103 | 104 | XCTAssert([[self getString] isEqualToString:@"dy"]); 105 | 106 | script = @"\ 107 | spa_class(\"SpaInvokeTest\") \n \ 108 | function getStringStatic(self) \n \ 109 | return 'static' \n \ 110 | end \n"; 111 | [[Spa sharedInstace] usePatch:script]; 112 | 113 | XCTAssert([[SpaInvokeTest getStringStatic] isEqualToString:@"static"]); 114 | } 115 | 116 | - (void)testPerformanceExample { 117 | // This is an example of a performance test case. 118 | [self measureBlock:^{ 119 | // Put the code you want to measure the time of here. 120 | }]; 121 | } 122 | 123 | @end 124 | -------------------------------------------------------------------------------- /spa/SpaDemoTests/SpaOtherTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // SpaOtherTest.m 3 | // SpaDemoTests 4 | // 5 | // Created by FanFamily on 2018/12/22. 6 | // Copyright © 2018年 Family Fan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SpaOtherTest : XCTestCase 13 | 14 | @property (nonatomic) int index; 15 | 16 | @end 17 | 18 | @implementation SpaOtherTest 19 | 20 | - (NSString *)getString 21 | { 22 | return nil; 23 | } 24 | 25 | - (NSString *)deep 26 | { 27 | NSString* s1 = @"start"; 28 | NSString* s2 = [self center]; 29 | NSString* s3 = @"end"; 30 | 31 | return [NSString stringWithFormat:@"%@ %@ %@", s1, s2, s3]; 32 | } 33 | 34 | - (NSString *)center 35 | { 36 | return @"center"; 37 | } 38 | 39 | - (void)dispatchAfter 40 | { 41 | 42 | } 43 | 44 | - (void)setUp { 45 | // Put setup code here. This method is called before the invocation of each test method in the class. 46 | } 47 | 48 | - (void)tearDown { 49 | // Put teardown code here. This method is called after the invocation of each test method in the class. 50 | } 51 | 52 | - (void)testExample { 53 | // toId 54 | NSString* script = @"\ 55 | spa_class(\"SpaOtherTest\") \n \ 56 | function getString(self) \n \ 57 | return spa.toId('come back'):substringToIndex_(4) \n \ 58 | end \n"; 59 | [[Spa sharedInstace] usePatch:script]; 60 | 61 | XCTAssert([[self getString] isEqualToString:@"come"]); 62 | 63 | // toLuaString 64 | script = @"\ 65 | spa_class(\"SpaOtherTest\") \n \ 66 | function getString(self) \n \ 67 | return spa.toLuaString(spa.toId('co')) .. 'me' \n \ 68 | end \n"; 69 | [[Spa sharedInstace] usePatch:script]; 70 | 71 | XCTAssert([[self getString] isEqualToString:@"come"]); 72 | 73 | // deep 74 | script = @"class_deep('SpaOtherTest', 'deep', 'SpaOtherTest', 'center', function () return 'cen' end) \n"; 75 | [[Spa sharedInstace] usePatch:script]; 76 | XCTAssert([[self deep] isEqualToString:@"start cen end"]); 77 | XCTAssert([[self center] isEqualToString:@"center"]); 78 | 79 | // create id 80 | 81 | 82 | // dispatch after 83 | script = @"spa_class('SpaOtherTest').dispatchAfter = function (self) spa.dispatch_after(function () self.index = 2 end, 2) end \n"; 84 | [[Spa sharedInstace] usePatch:script]; 85 | 86 | [self dispatchAfter]; 87 | XCTAssert(self.index == 0); 88 | XCTestExpectation *exp = [self expectationWithDescription:@""]; 89 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 90 | XCTAssert(self.index == 2); 91 | [exp fulfill]; 92 | }); 93 | 94 | [Spa performSelectorOnMainThread:@selector(logCurrentStack) withObject:nil waitUntilDone:YES]; 95 | 96 | [self waitForExpectationsWithTimeout:10 handler:nil]; 97 | } 98 | 99 | 100 | 101 | - (void)testPerformanceExample { 102 | // This is an example of a performance test case. 103 | [self measureBlock:^{ 104 | // Put the code you want to measure the time of here. 105 | }]; 106 | } 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /spa/serverSample/patch.lua: -------------------------------------------------------------------------------- 1 | spa_class("ViewController") 2 | 3 | function doSomeThing(self) 4 | self:view():setBackgroundColor_(UIColor:grayColor()) 5 | end 6 | -------------------------------------------------------------------------------- /spa/serverSample/server.js: -------------------------------------------------------------------------------- 1 | var http = require("http"); 2 | var fs = require("fs") 3 | 4 | http.createServer(function (request, response) { 5 | 6 | fs.readFile('patch.lua', function (err, data) { 7 | if (err) { 8 | return console.error(err); 9 | } 10 | response.end(data); 11 | }); 12 | // Send the response body as "Hello World" 13 | 14 | }).listen(8088); 15 | 16 | console.log('patch you can download on port 8088'); 17 | --------------------------------------------------------------------------------