From 38bd13b46bff35e93d6b764d91b25e858a25afa5 Mon Sep 17 00:00:00 2001 From: Xuan Sang LE Date: Wed, 19 Sep 2018 15:08:49 +0200 Subject: [PATCH] mimgrating from another repo --- 3rd/jsmn/LICENSE | 20 + 3rd/jsmn/Makefile | 41 + 3rd/jsmn/README.md | 167 + 3rd/jsmn/example/jsondump.c | 126 + 3rd/jsmn/example/simple.c | 76 + 3rd/jsmn/jsmn.c | 314 + 3rd/jsmn/jsmn.h | 76 + 3rd/jsmn/library.json | 16 + 3rd/jsmn/test/test.h | 27 + 3rd/jsmn/test/tests.c | 398 + 3rd/jsmn/test/testutil.h | 94 + 3rd/lua-5.3.4/Makefile | 197 + 3rd/lua-5.3.4/lapi.c | 1298 + 3rd/lua-5.3.4/lapi.h | 24 + 3rd/lua-5.3.4/lauxlib.c | 1043 + 3rd/lua-5.3.4/lauxlib.h | 264 + 3rd/lua-5.3.4/lbaselib.c | 498 + 3rd/lua-5.3.4/lbitlib.c | 233 + 3rd/lua-5.3.4/lcode.c | 1203 + 3rd/lua-5.3.4/lcode.h | 88 + 3rd/lua-5.3.4/lcorolib.c | 168 + 3rd/lua-5.3.4/lctype.c | 55 + 3rd/lua-5.3.4/lctype.h | 95 + 3rd/lua-5.3.4/ldblib.c | 456 + 3rd/lua-5.3.4/ldebug.c | 698 + 3rd/lua-5.3.4/ldebug.h | 39 + 3rd/lua-5.3.4/ldo.c | 802 + 3rd/lua-5.3.4/ldo.h | 58 + 3rd/lua-5.3.4/ldump.c | 215 + 3rd/lua-5.3.4/lfunc.c | 151 + 3rd/lua-5.3.4/lfunc.h | 61 + 3rd/lua-5.3.4/lgc.c | 1178 + 3rd/lua-5.3.4/lgc.h | 147 + 3rd/lua-5.3.4/linit.c | 68 + 3rd/lua-5.3.4/liolib.c | 771 + 3rd/lua-5.3.4/llex.c | 565 + 3rd/lua-5.3.4/llex.h | 85 + 3rd/lua-5.3.4/llimits.h | 323 + 3rd/lua-5.3.4/lmathlib.c | 410 + 3rd/lua-5.3.4/lmem.c | 100 + 3rd/lua-5.3.4/lmem.h | 69 + 3rd/lua-5.3.4/loadlib.c | 790 + 3rd/lua-5.3.4/lobject.c | 521 + 3rd/lua-5.3.4/lobject.h | 549 + 3rd/lua-5.3.4/lopcodes.c | 124 + 3rd/lua-5.3.4/lopcodes.h | 297 + 3rd/lua-5.3.4/loslib.c | 407 + 3rd/lua-5.3.4/lparser.c | 1650 ++ 3rd/lua-5.3.4/lparser.h | 133 + 3rd/lua-5.3.4/lprefix.h | 45 + 3rd/lua-5.3.4/lstate.c | 347 + 3rd/lua-5.3.4/lstate.h | 235 + 3rd/lua-5.3.4/lstring.c | 248 + 3rd/lua-5.3.4/lstring.h | 49 + 3rd/lua-5.3.4/lstrlib.c | 1584 ++ 3rd/lua-5.3.4/ltable.c | 669 + 3rd/lua-5.3.4/ltable.h | 66 + 3rd/lua-5.3.4/ltablib.c | 450 + 3rd/lua-5.3.4/ltm.c | 165 + 3rd/lua-5.3.4/ltm.h | 76 + 3rd/lua-5.3.4/lua | Bin 0 -> 1084992 bytes 3rd/lua-5.3.4/lua.c | 612 + 3rd/lua-5.3.4/lua.h | 486 + 3rd/lua-5.3.4/lua.hpp | 9 + 3rd/lua-5.3.4/luac | Bin 0 -> 772024 bytes 3rd/lua-5.3.4/luac.c | 449 + 3rd/lua-5.3.4/luaconf.h | 783 + 3rd/lua-5.3.4/lualib.h | 61 + 3rd/lua-5.3.4/lundump.c | 279 + 3rd/lua-5.3.4/lundump.h | 32 + 3rd/lua-5.3.4/lutf8lib.c | 256 + 3rd/lua-5.3.4/lvm.c | 1322 + 3rd/lua-5.3.4/lvm.h | 113 + 3rd/lua-5.3.4/lzio.c | 68 + 3rd/lua-5.3.4/lzio.h | 66 + APIs/OOP.lua | 40 + APIs/api.lua | 145 + APIs/bugbot.lua | 90 + APIs/extra_mime.lua | 43 + APIs/sqlite.lua | 157 + APIs/std.lua | 122 + APIs/utils.lua | 137 + APIs/web.lua | 74 + Makefile | 75 + README.md | 10 +- array-wrapper.c | 191 + db-wrapper.c | 113 + example-app/mimes.json | 18 + example-app/os/apigateway.lua | 97 + example-app/os/db/delete.lua | 29 + example-app/os/db/get.lua | 19 + example-app/os/db/model.lua | 20 + example-app/os/db/save.lua | 24 + example-app/os/db/select.lua | 20 + example-app/os/fs/delete.lua | 15 + example-app/os/fs/exists.lua | 10 + example-app/os/fs/fileinfo.lua | 8 + example-app/os/fs/fsconf.lua.tpl | 6 + example-app/os/fs/fsh.lua | 14 + example-app/os/fs/get.lua | 40 + example-app/os/fs/mkdir.lua | 11 + example-app/os/fs/move.lua | 13 + example-app/os/fs/publish.lua | 36 + example-app/os/fs/scandir.lua | 10 + example-app/os/fs/shared.lua | 52 + example-app/os/fs/upload.lua | 8 + example-app/os/fs/vfs.lua | 203 + example-app/os/fs/write.lua | 13 + example-app/os/index.lua | 1 + example-app/os/router.lua | 10 + example-app/os/system/application.lua | 24 + example-app/os/system/auth.lua | 3 + example-app/os/system/curl.lua | 17 + example-app/os/system/login.lua | 39 + example-app/os/system/logout.lua | 17 + example-app/os/system/packages.json | 21 + example-app/os/system/packages.json.tpl | 588 + example-app/os/system/packages.lua | 140 + example-app/os/system/settings.lua | 19 + example-app/os/system/uman.lua | 27 + example-app/os/system/users.lua | 23 + example-app/os/test.ls | 28 + example-app/os/ws/filestream.lua | 62 + example-app/os/ws/sock.lua | 33 + example-app/proc.lua | 17 + example-app/router.lua | 82 + json-wrapper.c | 208 + lib.mk | 17 + lib/ann/Makefile | 11 + lib/ann/ann.c | 266 + lib/ann/data.c | 255 + lib/ann/examples/cascade/test.lua | 14 + lib/ann/examples/cascade/train.data | 9 + lib/ann/examples/cascade/train.lua | 13 + lib/ann/examples/rpg/test.lua | 86 + lib/ann/examples/rpg/train.data | 53 + lib/ann/examples/rpg/train.lua | 24 + lib/ann/examples/xor/test.lua | 41 + lib/ann/examples/xor/train.data | 9 + lib/ann/examples/xor/train.lua | 17 + lib/ann/extension.c | 309 + lib/ann/fann/.gitignore | 36 + lib/ann/fann/.idea/encodings.xml | 6 + lib/ann/fann/.idea/fann.iml | 400 + lib/ann/fann/.idea/misc.xml | 4 + lib/ann/fann/.idea/modules.xml | 8 + .../fann/.idea/runConfigurations/Tests.xml | 6 + lib/ann/fann/.idea/vcs.xml | 6 + lib/ann/fann/.travis.yml | 27 + lib/ann/fann/CMakeLists.txt | 148 + lib/ann/fann/LICENSE.md | 504 + lib/ann/fann/README.md | 63 + lib/ann/fann/biicode.conf | 45 + lib/ann/fann/bin/.gitignore | 4 + lib/ann/fann/bin/Guitar.exe.config | 10 + lib/ann/fann/bin/Win32/xor.data | 9 + lib/ann/fann/bin/x64/xor.data | 9 + .../Modules/DefineInstallationPaths.cmake | 141 + lib/ann/fann/cmake/config.h.in | 8 + lib/ann/fann/cmake/fann-config.cmake.in | 38 + lib/ann/fann/cmake/fann-use.cmake | 9 + lib/ann/fann/cmake/fann.pc.cmake | 10 + lib/ann/fann/datasets/abelone.test | 4179 +++ lib/ann/fann/datasets/abelone.train | 4177 +++ lib/ann/fann/datasets/bank32fm.test | 4097 +++ lib/ann/fann/datasets/bank32fm.train | 4097 +++ lib/ann/fann/datasets/bank32nh.test | 4097 +++ lib/ann/fann/datasets/bank32nh.train | 4097 +++ lib/ann/fann/datasets/building.test | 4209 +++ lib/ann/fann/datasets/building.train | 4209 +++ lib/ann/fann/datasets/census-house.test | 22785 ++++++++++++++++ lib/ann/fann/datasets/census-house.train | 22785 ++++++++++++++++ lib/ann/fann/datasets/diabetes.test | 769 + lib/ann/fann/datasets/diabetes.train | 769 + lib/ann/fann/datasets/gene.test | 3175 +++ lib/ann/fann/datasets/gene.train | 3177 +++ lib/ann/fann/datasets/kin32fm.test | 4097 +++ lib/ann/fann/datasets/kin32fm.train | 4097 +++ lib/ann/fann/datasets/mushroom.test | 8125 ++++++ lib/ann/fann/datasets/mushroom.train | 8125 ++++++ lib/ann/fann/datasets/parity13.test | 16385 +++++++++++ lib/ann/fann/datasets/parity13.train | 16385 +++++++++++ lib/ann/fann/datasets/parity8.test | 513 + lib/ann/fann/datasets/parity8.train | 513 + lib/ann/fann/datasets/pumadyn-32fm.test | 1025 + lib/ann/fann/datasets/pumadyn-32fm.train | 1025 + lib/ann/fann/datasets/robot.test | 1189 + lib/ann/fann/datasets/robot.train | 749 + lib/ann/fann/datasets/scaling.data | 2001 ++ lib/ann/fann/datasets/soybean.test | 683 + lib/ann/fann/datasets/soybean.train | 685 + lib/ann/fann/datasets/thyroid.test | 7201 +++++ lib/ann/fann/datasets/thyroid.train | 7201 +++++ lib/ann/fann/datasets/two-spiral.test | 387 + lib/ann/fann/datasets/two-spiral.train | 387 + .../NaturalDocs-1.52/Config/Languages.txt | 286 + .../docs/NaturalDocs-1.52/Config/Topics.txt | 382 + .../Help/customizinglanguages.html | 52 + .../Help/customizingtopics.html | 74 + .../NaturalDocs-1.52/Help/documenting.html | 58 + .../Help/documenting/reference.html | 147 + .../Help/documenting/walkthrough.html | 181 + .../NaturalDocs-1.52/Help/example/Default.css | 528 + .../Help/example/NaturalDocs.js | 204 + .../NaturalDocs-1.52/Help/example/Roman.css | 507 + .../NaturalDocs-1.52/Help/example/Small.css | 507 + .../Help/example/showstyle.html | 43 + .../docs/NaturalDocs-1.52/Help/examples.css | 90 + .../Help/images/header/background.png | Bin 0 -> 229 bytes .../Help/images/header/leftside.png | Bin 0 -> 1215 bytes .../Help/images/header/logo.png | Bin 0 -> 12146 bytes .../Help/images/header/overbody.png | Bin 0 -> 283 bytes .../Help/images/header/overbodybg.png | Bin 0 -> 141 bytes .../Help/images/header/overleftmargin.png | Bin 0 -> 188 bytes .../Help/images/header/overmenu.png | Bin 0 -> 244 bytes .../Help/images/header/overmenubg.png | Bin 0 -> 141 bytes .../Help/images/header/rightside.png | Bin 0 -> 1186 bytes .../Help/images/menu/about.png | Bin 0 -> 397 bytes .../Help/images/menu/background.png | Bin 0 -> 187 bytes .../Help/images/menu/bottomleft.png | Bin 0 -> 235 bytes .../Help/images/menu/bottomright.png | Bin 0 -> 234 bytes .../Help/images/menu/community.png | Bin 0 -> 507 bytes .../Help/images/menu/customizing.png | Bin 0 -> 575 bytes .../Help/images/menu/using.png | Bin 0 -> 390 bytes .../docs/NaturalDocs-1.52/Help/index.html | 9 + .../Help/javascript/BrowserStyles.js | 77 + .../Help/javascript/PNGHandling.js | 72 + .../docs/NaturalDocs-1.52/Help/keywords.html | 38 + .../docs/NaturalDocs-1.52/Help/languages.html | 32 + .../fann/docs/NaturalDocs-1.52/Help/menu.html | 79 + .../docs/NaturalDocs-1.52/Help/output.html | 84 + .../docs/NaturalDocs-1.52/Help/running.html | 40 + .../docs/NaturalDocs-1.52/Help/styles.css | 292 + .../docs/NaturalDocs-1.52/Help/styles.html | 52 + .../Help/troubleshooting.html | 18 + .../docs/NaturalDocs-1.52/Info/CSSGuide.txt | 947 + .../NaturalDocs-1.52/Info/File Parsing.txt | 83 + .../NaturalDocs-1.52/Info/HTMLTestCases.pm | 270 + .../docs/NaturalDocs-1.52/Info/Languages.txt | 107 + .../docs/NaturalDocs-1.52/Info/NDMarkup.txt | 92 + .../Info/Symbol Management.txt | 59 + .../NaturalDocs-1.52/Info/images/Logo.png | Bin 0 -> 12405 bytes .../JavaScript/GooglePrettify.js | 1526 ++ .../JavaScript/NaturalDocs.js | 841 + .../fann/docs/NaturalDocs-1.52/License.txt | 275 + .../Modules/NaturalDocs/BinaryFile.pm | 337 + .../Modules/NaturalDocs/Builder.pm | 281 + .../Modules/NaturalDocs/Builder/Base.pm | 349 + .../Modules/NaturalDocs/Builder/FramedHTML.pm | 354 + .../Modules/NaturalDocs/Builder/HTML.pm | 414 + .../Modules/NaturalDocs/Builder/HTMLBase.pm | 3745 +++ .../Modules/NaturalDocs/ClassHierarchy.pm | 869 + .../NaturalDocs/ClassHierarchy/Class.pm | 413 + .../NaturalDocs/ClassHierarchy/File.pm | 158 + .../Modules/NaturalDocs/ConfigFile.pm | 508 + .../Modules/NaturalDocs/Constants.pm | 166 + .../Modules/NaturalDocs/DefineMembers.pm | 101 + .../Modules/NaturalDocs/Error.pm | 306 + .../Modules/NaturalDocs/File.pm | 541 + .../NaturalDocs/ImageReferenceTable.pm | 398 + .../ImageReferenceTable/Reference.pm | 45 + .../NaturalDocs/ImageReferenceTable/String.pm | 111 + .../Modules/NaturalDocs/Languages.pm | 1481 + .../NaturalDocs/Languages/ActionScript.pm | 1487 + .../Modules/NaturalDocs/Languages/Ada.pm | 39 + .../Modules/NaturalDocs/Languages/Advanced.pm | 817 + .../NaturalDocs/Languages/Advanced/Scope.pm | 96 + .../Languages/Advanced/ScopeChange.pm | 71 + .../Modules/NaturalDocs/Languages/Base.pm | 833 + .../Modules/NaturalDocs/Languages/CSharp.pm | 1552 ++ .../Modules/NaturalDocs/Languages/PLSQL.pm | 320 + .../Modules/NaturalDocs/Languages/Pascal.pm | 144 + .../Modules/NaturalDocs/Languages/Perl.pm | 1371 + .../NaturalDocs/Languages/Prototype.pm | 93 + .../Languages/Prototype/Parameter.pm | 88 + .../Modules/NaturalDocs/Languages/Simple.pm | 487 + .../Modules/NaturalDocs/Languages/Tcl.pm | 220 + .../Modules/NaturalDocs/LineReader.pm | 192 + .../Modules/NaturalDocs/Menu.pm | 3430 +++ .../Modules/NaturalDocs/Menu/Entry.pm | 202 + .../Modules/NaturalDocs/NDMarkup.pm | 77 + .../Modules/NaturalDocs/Parser.pm | 1335 + .../Modules/NaturalDocs/Parser/JavaDoc.pm | 465 + .../Modules/NaturalDocs/Parser/Native.pm | 1073 + .../Modules/NaturalDocs/Parser/ParsedTopic.pm | 254 + .../Modules/NaturalDocs/Project.pm | 1406 + .../Modules/NaturalDocs/Project/ImageFile.pm | 161 + .../Modules/NaturalDocs/Project/SourceFile.pm | 114 + .../Modules/NaturalDocs/ReferenceString.pm | 345 + .../Modules/NaturalDocs/Settings.pm | 1484 + .../NaturalDocs/Settings/BuildTarget.pm | 67 + .../Modules/NaturalDocs/SourceDB.pm | 679 + .../Modules/NaturalDocs/SourceDB/Extension.pm | 85 + .../Modules/NaturalDocs/SourceDB/File.pm | 130 + .../Modules/NaturalDocs/SourceDB/Item.pm | 202 + .../NaturalDocs/SourceDB/ItemDefinition.pm | 46 + .../SourceDB/WatchedFileDefinitions.pm | 160 + .../Modules/NaturalDocs/StatusMessage.pm | 103 + .../Modules/NaturalDocs/SymbolString.pm | 217 + .../Modules/NaturalDocs/SymbolTable.pm | 2016 ++ .../Modules/NaturalDocs/SymbolTable/File.pm | 187 + .../NaturalDocs/SymbolTable/IndexElement.pm | 523 + .../NaturalDocs/SymbolTable/Reference.pm | 274 + .../SymbolTable/ReferenceTarget.pm | 98 + .../Modules/NaturalDocs/SymbolTable/Symbol.pm | 429 + .../SymbolTable/SymbolDefinition.pm | 97 + .../Modules/NaturalDocs/Topics.pm | 1321 + .../Modules/NaturalDocs/Topics/Type.pm | 152 + .../Modules/NaturalDocs/Version.pm | 361 + .../fann/docs/NaturalDocs-1.52/NaturalDocs | 367 + .../docs/NaturalDocs-1.52/NaturalDocs.bat | 17 + .../docs/NaturalDocs-1.52/Styles/Default.css | 828 + .../docs/NaturalDocs-1.52/Styles/Roman.css | 826 + .../docs/NaturalDocs-1.52/Styles/Small.css | 824 + lib/ann/fann/docs/generate_docs.sh | 5 + lib/ann/fann/docs/prj/Languages.txt | 113 + lib/ann/fann/docs/prj/Menu.txt | 72 + lib/ann/fann/docs/prj/Topics.txt | 81 + lib/ann/fann/docs/publish_docs.sh | 11 + lib/ann/fann/examples/.gitignore | 18 + lib/ann/fann/examples/cascade_train.c | 116 + lib/ann/fann/examples/momentums.c | 59 + lib/ann/fann/examples/mushroom.c | 74 + lib/ann/fann/examples/parallel_train.c | 54 + lib/ann/fann/examples/robot.c | 69 + lib/ann/fann/examples/scaling_test.c | 36 + lib/ann/fann/examples/scaling_train.c | 33 + lib/ann/fann/examples/simple_test.c | 38 + lib/ann/fann/examples/simple_train.c | 44 + lib/ann/fann/examples/steepness_train.c | 116 + lib/ann/fann/examples/xor.data | 9 + lib/ann/fann/examples/xor_sample.cpp | 152 + lib/ann/fann/examples/xor_test.c | 84 + lib/ann/fann/examples/xor_train.c | 91 + lib/ann/fann/ignore.bii | 4 + lib/ann/fann/lib/googletest/CHANGES | 157 + lib/ann/fann/lib/googletest/CMakeLists.txt | 270 + lib/ann/fann/lib/googletest/CONTRIBUTORS | 37 + lib/ann/fann/lib/googletest/LICENSE | 28 + lib/ann/fann/lib/googletest/Makefile.am | 310 + lib/ann/fann/lib/googletest/README.md | 280 + lib/ann/fann/lib/googletest/build-aux/.keep | 0 .../lib/googletest/cmake/internal_utils.cmake | 242 + .../fann/lib/googletest/codegear/gtest.cbproj | 138 + .../lib/googletest/codegear/gtest.groupproj | 54 + .../fann/lib/googletest/codegear/gtest_all.cc | 38 + .../lib/googletest/codegear/gtest_link.cc | 40 + .../lib/googletest/codegear/gtest_main.cbproj | 82 + .../googletest/codegear/gtest_unittest.cbproj | 88 + lib/ann/fann/lib/googletest/configure.ac | 68 + .../fann/lib/googletest/docs/AdvancedGuide.md | 2183 ++ lib/ann/fann/lib/googletest/docs/DevGuide.md | 139 + .../fann/lib/googletest/docs/Documentation.md | 14 + lib/ann/fann/lib/googletest/docs/FAQ.md | 1087 + lib/ann/fann/lib/googletest/docs/Primer.md | 502 + .../fann/lib/googletest/docs/PumpManual.md | 177 + lib/ann/fann/lib/googletest/docs/Samples.md | 14 + .../lib/googletest/docs/V1_5_AdvancedGuide.md | 2096 ++ .../lib/googletest/docs/V1_5_Documentation.md | 12 + lib/ann/fann/lib/googletest/docs/V1_5_FAQ.md | 885 + .../fann/lib/googletest/docs/V1_5_Primer.md | 497 + .../lib/googletest/docs/V1_5_PumpManual.md | 177 + .../lib/googletest/docs/V1_5_XcodeGuide.md | 93 + .../lib/googletest/docs/V1_6_AdvancedGuide.md | 2178 ++ .../lib/googletest/docs/V1_6_Documentation.md | 14 + lib/ann/fann/lib/googletest/docs/V1_6_FAQ.md | 1037 + .../fann/lib/googletest/docs/V1_6_Primer.md | 501 + .../lib/googletest/docs/V1_6_PumpManual.md | 177 + .../fann/lib/googletest/docs/V1_6_Samples.md | 14 + .../lib/googletest/docs/V1_6_XcodeGuide.md | 93 + .../lib/googletest/docs/V1_7_AdvancedGuide.md | 2181 ++ .../lib/googletest/docs/V1_7_Documentation.md | 14 + lib/ann/fann/lib/googletest/docs/V1_7_FAQ.md | 1081 + .../fann/lib/googletest/docs/V1_7_Primer.md | 501 + .../lib/googletest/docs/V1_7_PumpManual.md | 177 + .../fann/lib/googletest/docs/V1_7_Samples.md | 14 + .../lib/googletest/docs/V1_7_XcodeGuide.md | 93 + .../fann/lib/googletest/docs/XcodeGuide.md | 93 + .../include/gtest/gtest-death-test.h | 294 + .../googletest/include/gtest/gtest-message.h | 250 + .../include/gtest/gtest-param-test.h | 1444 + .../include/gtest/gtest-param-test.h.pump | 510 + .../googletest/include/gtest/gtest-printers.h | 993 + .../lib/googletest/include/gtest/gtest-spi.h | 232 + .../include/gtest/gtest-test-part.h | 179 + .../include/gtest/gtest-typed-test.h | 263 + .../fann/lib/googletest/include/gtest/gtest.h | 2240 ++ .../include/gtest/gtest_pred_impl.h | 358 + .../lib/googletest/include/gtest/gtest_prod.h | 58 + .../gtest/internal/custom/gtest-port.h | 69 + .../gtest/internal/custom/gtest-printers.h | 42 + .../include/gtest/internal/custom/gtest.h | 41 + .../internal/gtest-death-test-internal.h | 319 + .../include/gtest/internal/gtest-filepath.h | 206 + .../include/gtest/internal/gtest-internal.h | 1238 + .../include/gtest/internal/gtest-linked_ptr.h | 243 + .../internal/gtest-param-util-generated.h | 5146 ++++ .../gtest-param-util-generated.h.pump | 286 + .../include/gtest/internal/gtest-param-util.h | 731 + .../include/gtest/internal/gtest-port-arch.h | 93 + .../include/gtest/internal/gtest-port.h | 2559 ++ .../include/gtest/internal/gtest-string.h | 167 + .../include/gtest/internal/gtest-tuple.h | 1020 + .../include/gtest/internal/gtest-tuple.h.pump | 347 + .../include/gtest/internal/gtest-type-util.h | 3331 +++ .../gtest/internal/gtest-type-util.h.pump | 297 + lib/ann/fann/lib/googletest/m4/acx_pthread.m4 | 363 + lib/ann/fann/lib/googletest/m4/gtest.m4 | 74 + .../fann/lib/googletest/msvc/gtest-md.vcproj | 126 + lib/ann/fann/lib/googletest/msvc/gtest.vcproj | 126 + .../lib/googletest/msvc/gtest_main-md.vcproj | 129 + .../lib/googletest/msvc/gtest_main.vcproj | 129 + .../googletest/msvc/gtest_prod_test-md.vcproj | 164 + .../googletest/msvc/gtest_prod_test.vcproj | 164 + .../googletest/msvc/gtest_unittest-md.vcproj | 147 + .../lib/googletest/msvc/gtest_unittest.vcproj | 147 + .../lib/googletest/samples/prime_tables.h | 123 + .../fann/lib/googletest/samples/sample1.cc | 68 + lib/ann/fann/lib/googletest/samples/sample1.h | 43 + .../googletest/samples/sample10_unittest.cc | 144 + .../googletest/samples/sample1_unittest.cc | 153 + .../fann/lib/googletest/samples/sample2.cc | 56 + lib/ann/fann/lib/googletest/samples/sample2.h | 85 + .../googletest/samples/sample2_unittest.cc | 109 + .../fann/lib/googletest/samples/sample3-inl.h | 172 + .../googletest/samples/sample3_unittest.cc | 151 + .../fann/lib/googletest/samples/sample4.cc | 46 + lib/ann/fann/lib/googletest/samples/sample4.h | 53 + .../googletest/samples/sample4_unittest.cc | 45 + .../googletest/samples/sample5_unittest.cc | 199 + .../googletest/samples/sample6_unittest.cc | 224 + .../googletest/samples/sample7_unittest.cc | 130 + .../googletest/samples/sample8_unittest.cc | 173 + .../googletest/samples/sample9_unittest.cc | 160 + lib/ann/fann/lib/googletest/scripts/common.py | 83 + .../googletest/scripts/fuse_gtest_files.py | 250 + .../googletest/scripts/gen_gtest_pred_impl.py | 730 + .../lib/googletest/scripts/gtest-config.in | 274 + lib/ann/fann/lib/googletest/scripts/pump.py | 855 + .../lib/googletest/scripts/release_docs.py | 158 + lib/ann/fann/lib/googletest/scripts/upload.py | 1387 + .../lib/googletest/scripts/upload_gtest.py | 78 + lib/ann/fann/lib/googletest/src/gtest-all.cc | 48 + .../lib/googletest/src/gtest-death-test.cc | 1342 + .../fann/lib/googletest/src/gtest-filepath.cc | 387 + .../lib/googletest/src/gtest-internal-inl.h | 1183 + lib/ann/fann/lib/googletest/src/gtest-port.cc | 1221 + .../fann/lib/googletest/src/gtest-printers.cc | 373 + .../lib/googletest/src/gtest-test-part.cc | 110 + .../lib/googletest/src/gtest-typed-test.cc | 118 + lib/ann/fann/lib/googletest/src/gtest.cc | 5386 ++++ lib/ann/fann/lib/googletest/src/gtest_main.cc | 38 + .../test/gtest-death-test_ex_test.cc | 93 + .../googletest/test/gtest-death-test_test.cc | 1427 + .../googletest/test/gtest-filepath_test.cc | 662 + .../googletest/test/gtest-linked_ptr_test.cc | 154 + .../googletest/test/gtest-listener_test.cc | 311 + .../lib/googletest/test/gtest-message_test.cc | 159 + .../lib/googletest/test/gtest-options_test.cc | 215 + .../googletest/test/gtest-param-test2_test.cc | 65 + .../googletest/test/gtest-param-test_test.cc | 1055 + .../googletest/test/gtest-param-test_test.h | 57 + .../lib/googletest/test/gtest-port_test.cc | 1304 + .../googletest/test/gtest-printers_test.cc | 1635 ++ .../googletest/test/gtest-test-part_test.cc | 208 + .../lib/googletest/test/gtest-tuple_test.cc | 320 + .../googletest/test/gtest-typed-test2_test.cc | 45 + .../googletest/test/gtest-typed-test_test.cc | 380 + .../googletest/test/gtest-typed-test_test.h | 66 + .../test/gtest-unittest-api_test.cc | 341 + .../lib/googletest/test/gtest_all_test.cc | 47 + .../test/gtest_break_on_failure_unittest.py | 212 + .../test/gtest_break_on_failure_unittest_.cc | 88 + .../test/gtest_catch_exceptions_test.py | 237 + .../test/gtest_catch_exceptions_test_.cc | 311 + .../lib/googletest/test/gtest_color_test.py | 130 + .../lib/googletest/test/gtest_color_test_.cc | 71 + .../lib/googletest/test/gtest_env_var_test.py | 103 + .../googletest/test/gtest_env_var_test_.cc | 126 + .../googletest/test/gtest_environment_test.cc | 192 + .../googletest/test/gtest_filter_unittest.py | 633 + .../googletest/test/gtest_filter_unittest_.cc | 140 + .../lib/googletest/test/gtest_help_test.py | 172 + .../lib/googletest/test/gtest_help_test_.cc | 46 + .../test/gtest_list_tests_unittest.py | 207 + .../test/gtest_list_tests_unittest_.cc | 157 + .../googletest/test/gtest_main_unittest.cc | 45 + .../googletest/test/gtest_no_test_unittest.cc | 56 + .../lib/googletest/test/gtest_output_test.py | 340 + .../lib/googletest/test/gtest_output_test_.cc | 1062 + .../test/gtest_output_test_golden_lin.txt | 743 + .../test/gtest_pred_impl_unittest.cc | 2427 ++ .../test/gtest_premature_exit_test.cc | 127 + .../lib/googletest/test/gtest_prod_test.cc | 57 + .../lib/googletest/test/gtest_repeat_test.cc | 253 + .../lib/googletest/test/gtest_shuffle_test.py | 325 + .../googletest/test/gtest_shuffle_test_.cc | 103 + .../googletest/test/gtest_sole_header_test.cc | 57 + .../lib/googletest/test/gtest_stress_test.cc | 256 + .../lib/googletest/test/gtest_test_utils.py | 320 + .../test/gtest_throw_on_failure_ex_test.cc | 92 + .../test/gtest_throw_on_failure_test.py | 171 + .../test/gtest_throw_on_failure_test_.cc | 72 + .../test/gtest_uninitialized_test.py | 70 + .../test/gtest_uninitialized_test_.cc | 43 + .../lib/googletest/test/gtest_unittest.cc | 7699 ++++++ .../test/gtest_xml_outfile1_test_.cc | 49 + .../test/gtest_xml_outfile2_test_.cc | 49 + .../test/gtest_xml_outfiles_test.py | 132 + .../test/gtest_xml_output_unittest.py | 307 + .../test/gtest_xml_output_unittest_.cc | 181 + .../googletest/test/gtest_xml_test_utils.py | 194 + .../fann/lib/googletest/test/production.cc | 36 + lib/ann/fann/lib/googletest/test/production.h | 55 + .../xcode/Config/DebugProject.xcconfig | 30 + .../xcode/Config/FrameworkTarget.xcconfig | 17 + .../googletest/xcode/Config/General.xcconfig | 41 + .../xcode/Config/ReleaseProject.xcconfig | 32 + .../xcode/Config/StaticLibraryTarget.xcconfig | 18 + .../xcode/Config/TestTarget.xcconfig | 8 + .../lib/googletest/xcode/Resources/Info.plist | 30 + .../xcode/Samples/FrameworkSample/Info.plist | 28 + .../WidgetFramework.xcodeproj/project.pbxproj | 457 + .../xcode/Samples/FrameworkSample/runtests.sh | 62 + .../xcode/Samples/FrameworkSample/widget.cc | 63 + .../xcode/Samples/FrameworkSample/widget.h | 59 + .../Samples/FrameworkSample/widget_test.cc | 68 + .../lib/googletest/xcode/Scripts/runtests.sh | 65 + .../xcode/Scripts/versiongenerate.py | 100 + .../xcode/gtest.xcodeproj/project.pbxproj | 1135 + lib/ann/fann/src/CMakeLists.txt | 99 + lib/ann/fann/src/doublefann.c | 31 + lib/ann/fann/src/fann.c | 1868 ++ lib/ann/fann/src/fann_cascade.c | 1047 + lib/ann/fann/src/fann_error.c | 227 + lib/ann/fann/src/fann_io.c | 803 + lib/ann/fann/src/fann_train.c | 1047 + lib/ann/fann/src/fann_train_data.c | 1341 + lib/ann/fann/src/fixedfann.c | 30 + lib/ann/fann/src/floatfann.c | 31 + lib/ann/fann/src/include/CMakeLists.txt | 10 + lib/ann/fann/src/include/config.h | 8 + lib/ann/fann/src/include/doublefann.h | 33 + lib/ann/fann/src/include/fann.h | 669 + lib/ann/fann/src/include/fann_activation.h | 144 + lib/ann/fann/src/include/fann_cascade.h | 561 + lib/ann/fann/src/include/fann_cpp.h | 2946 ++ lib/ann/fann/src/include/fann_data.h | 826 + lib/ann/fann/src/include/fann_data_cpp.h | 303 + lib/ann/fann/src/include/fann_error.h | 167 + lib/ann/fann/src/include/fann_internal.h | 155 + lib/ann/fann/src/include/fann_io.h | 100 + lib/ann/fann/src/include/fann_train.h | 1425 + .../fann/src/include/fann_training_data_cpp.h | 561 + lib/ann/fann/src/include/fixedfann.h | 33 + lib/ann/fann/src/include/floatfann.h | 33 + lib/ann/fann/src/include/parallel_fann.h | 45 + lib/ann/fann/src/include/parallel_fann.hpp | 39 + lib/ann/fann/src/parallel_doublefann_cpp.cpp | 27 + lib/ann/fann/src/parallel_fann.c | 511 + lib/ann/fann/src/parallel_fann_cpp.cpp | 1113 + lib/ann/fann/src/parallel_floatfann_cpp.cpp | 27 + lib/ann/fann/tests/CMakeLists.txt | 25 + lib/ann/fann/tests/fann_test.cpp | 168 + lib/ann/fann/tests/fann_test.h | 29 + lib/ann/fann/tests/fann_test_data.cpp | 166 + lib/ann/fann/tests/fann_test_data.h | 34 + lib/ann/fann/tests/fann_test_train.cpp | 35 + lib/ann/fann/tests/fann_test_train.h | 24 + lib/ann/fann/tests/main.cpp | 6 + lib/ann/lfann.h | 48 + lib/ann/net.c | 1833 ++ lib/ann/tests/callback.lua | 30 + lib/ann/tests/cascade.lua | 64 + lib/ann/tests/creation.lua | 72 + lib/ann/tests/data.lua | 64 + lib/ann/tests/params.lua | 44 + lib/ann/tests/run.lua | 17 + lib/ann/tests/scale.lua | 59 + lib/ann/tests/train.data | 9 + lib/ann/tests/xor.net | 36 + lib/ann/tests/xor.test | 36 + lib/curl | Bin 0 -> 294968 bytes lib/lualib.h | 14 + lib/pibot/Makefile | 6 + lib/pibot/pibot.c | 260 + lib/stmr/Makefile | 7 + lib/stmr/stmr.c | 704 + lib/ulib/3rd/zip/main.c | 50 + lib/ulib/3rd/zip/miniz.c | 4916 ++++ lib/ulib/3rd/zip/zip.c | 471 + lib/ulib/3rd/zip/zip.h | 90 + lib/ulib/Makefile | 7 + lib/ulib/ulib.c | 631 + lib/wurl/Makefile | 8 + lib/wurl/test.c | 539 + lib/wurl/wurl.c | 627 + lua-api.c | 121 + lua-api.h | 33 + plugin-wrapper.c | 526 + 600 files changed, 362490 insertions(+), 1 deletion(-) create mode 100755 3rd/jsmn/LICENSE create mode 100755 3rd/jsmn/Makefile create mode 100755 3rd/jsmn/README.md create mode 100755 3rd/jsmn/example/jsondump.c create mode 100755 3rd/jsmn/example/simple.c create mode 100755 3rd/jsmn/jsmn.c create mode 100755 3rd/jsmn/jsmn.h create mode 100755 3rd/jsmn/library.json create mode 100755 3rd/jsmn/test/test.h create mode 100755 3rd/jsmn/test/tests.c create mode 100755 3rd/jsmn/test/testutil.h create mode 100644 3rd/lua-5.3.4/Makefile create mode 100644 3rd/lua-5.3.4/lapi.c create mode 100644 3rd/lua-5.3.4/lapi.h create mode 100644 3rd/lua-5.3.4/lauxlib.c create mode 100644 3rd/lua-5.3.4/lauxlib.h create mode 100644 3rd/lua-5.3.4/lbaselib.c create mode 100644 3rd/lua-5.3.4/lbitlib.c create mode 100644 3rd/lua-5.3.4/lcode.c create mode 100644 3rd/lua-5.3.4/lcode.h create mode 100644 3rd/lua-5.3.4/lcorolib.c create mode 100644 3rd/lua-5.3.4/lctype.c create mode 100644 3rd/lua-5.3.4/lctype.h create mode 100644 3rd/lua-5.3.4/ldblib.c create mode 100644 3rd/lua-5.3.4/ldebug.c create mode 100644 3rd/lua-5.3.4/ldebug.h create mode 100644 3rd/lua-5.3.4/ldo.c create mode 100644 3rd/lua-5.3.4/ldo.h create mode 100644 3rd/lua-5.3.4/ldump.c create mode 100644 3rd/lua-5.3.4/lfunc.c create mode 100644 3rd/lua-5.3.4/lfunc.h create mode 100644 3rd/lua-5.3.4/lgc.c create mode 100644 3rd/lua-5.3.4/lgc.h create mode 100644 3rd/lua-5.3.4/linit.c create mode 100644 3rd/lua-5.3.4/liolib.c create mode 100644 3rd/lua-5.3.4/llex.c create mode 100644 3rd/lua-5.3.4/llex.h create mode 100644 3rd/lua-5.3.4/llimits.h create mode 100644 3rd/lua-5.3.4/lmathlib.c create mode 100644 3rd/lua-5.3.4/lmem.c create mode 100644 3rd/lua-5.3.4/lmem.h create mode 100644 3rd/lua-5.3.4/loadlib.c create mode 100644 3rd/lua-5.3.4/lobject.c create mode 100644 3rd/lua-5.3.4/lobject.h create mode 100644 3rd/lua-5.3.4/lopcodes.c create mode 100644 3rd/lua-5.3.4/lopcodes.h create mode 100644 3rd/lua-5.3.4/loslib.c create mode 100644 3rd/lua-5.3.4/lparser.c create mode 100644 3rd/lua-5.3.4/lparser.h create mode 100644 3rd/lua-5.3.4/lprefix.h create mode 100644 3rd/lua-5.3.4/lstate.c create mode 100644 3rd/lua-5.3.4/lstate.h create mode 100644 3rd/lua-5.3.4/lstring.c create mode 100644 3rd/lua-5.3.4/lstring.h create mode 100644 3rd/lua-5.3.4/lstrlib.c create mode 100644 3rd/lua-5.3.4/ltable.c create mode 100644 3rd/lua-5.3.4/ltable.h create mode 100644 3rd/lua-5.3.4/ltablib.c create mode 100644 3rd/lua-5.3.4/ltm.c create mode 100644 3rd/lua-5.3.4/ltm.h create mode 100755 3rd/lua-5.3.4/lua create mode 100644 3rd/lua-5.3.4/lua.c create mode 100644 3rd/lua-5.3.4/lua.h create mode 100644 3rd/lua-5.3.4/lua.hpp create mode 100755 3rd/lua-5.3.4/luac create mode 100644 3rd/lua-5.3.4/luac.c create mode 100644 3rd/lua-5.3.4/luaconf.h create mode 100644 3rd/lua-5.3.4/lualib.h create mode 100644 3rd/lua-5.3.4/lundump.c create mode 100644 3rd/lua-5.3.4/lundump.h create mode 100644 3rd/lua-5.3.4/lutf8lib.c create mode 100644 3rd/lua-5.3.4/lvm.c create mode 100644 3rd/lua-5.3.4/lvm.h create mode 100644 3rd/lua-5.3.4/lzio.c create mode 100644 3rd/lua-5.3.4/lzio.h create mode 100644 APIs/OOP.lua create mode 100644 APIs/api.lua create mode 100644 APIs/bugbot.lua create mode 100644 APIs/extra_mime.lua create mode 100644 APIs/sqlite.lua create mode 100644 APIs/std.lua create mode 100644 APIs/utils.lua create mode 100644 APIs/web.lua create mode 100644 Makefile create mode 100644 array-wrapper.c create mode 100644 db-wrapper.c create mode 100644 example-app/mimes.json create mode 100644 example-app/os/apigateway.lua create mode 100644 example-app/os/db/delete.lua create mode 100644 example-app/os/db/get.lua create mode 100644 example-app/os/db/model.lua create mode 100644 example-app/os/db/save.lua create mode 100644 example-app/os/db/select.lua create mode 100644 example-app/os/fs/delete.lua create mode 100644 example-app/os/fs/exists.lua create mode 100644 example-app/os/fs/fileinfo.lua create mode 100644 example-app/os/fs/fsconf.lua.tpl create mode 100644 example-app/os/fs/fsh.lua create mode 100644 example-app/os/fs/get.lua create mode 100644 example-app/os/fs/mkdir.lua create mode 100644 example-app/os/fs/move.lua create mode 100644 example-app/os/fs/publish.lua create mode 100644 example-app/os/fs/scandir.lua create mode 100644 example-app/os/fs/shared.lua create mode 100644 example-app/os/fs/upload.lua create mode 100644 example-app/os/fs/vfs.lua create mode 100644 example-app/os/fs/write.lua create mode 100644 example-app/os/index.lua create mode 100644 example-app/os/router.lua create mode 100644 example-app/os/system/application.lua create mode 100644 example-app/os/system/auth.lua create mode 100644 example-app/os/system/curl.lua create mode 100644 example-app/os/system/login.lua create mode 100644 example-app/os/system/logout.lua create mode 100644 example-app/os/system/packages.json create mode 100644 example-app/os/system/packages.json.tpl create mode 100644 example-app/os/system/packages.lua create mode 100644 example-app/os/system/settings.lua create mode 100644 example-app/os/system/uman.lua create mode 100644 example-app/os/system/users.lua create mode 100644 example-app/os/test.ls create mode 100644 example-app/os/ws/filestream.lua create mode 100644 example-app/os/ws/sock.lua create mode 100644 example-app/proc.lua create mode 100644 example-app/router.lua create mode 100644 json-wrapper.c create mode 100644 lib.mk create mode 100644 lib/ann/Makefile create mode 100644 lib/ann/ann.c create mode 100644 lib/ann/data.c create mode 100755 lib/ann/examples/cascade/test.lua create mode 100644 lib/ann/examples/cascade/train.data create mode 100755 lib/ann/examples/cascade/train.lua create mode 100755 lib/ann/examples/rpg/test.lua create mode 100644 lib/ann/examples/rpg/train.data create mode 100755 lib/ann/examples/rpg/train.lua create mode 100755 lib/ann/examples/xor/test.lua create mode 100644 lib/ann/examples/xor/train.data create mode 100755 lib/ann/examples/xor/train.lua create mode 100644 lib/ann/extension.c create mode 100644 lib/ann/fann/.gitignore create mode 100644 lib/ann/fann/.idea/encodings.xml create mode 100644 lib/ann/fann/.idea/fann.iml create mode 100644 lib/ann/fann/.idea/misc.xml create mode 100644 lib/ann/fann/.idea/modules.xml create mode 100644 lib/ann/fann/.idea/runConfigurations/Tests.xml create mode 100644 lib/ann/fann/.idea/vcs.xml create mode 100644 lib/ann/fann/.travis.yml create mode 100644 lib/ann/fann/CMakeLists.txt create mode 100644 lib/ann/fann/LICENSE.md create mode 100644 lib/ann/fann/README.md create mode 100644 lib/ann/fann/biicode.conf create mode 100644 lib/ann/fann/bin/.gitignore create mode 100644 lib/ann/fann/bin/Guitar.exe.config create mode 100644 lib/ann/fann/bin/Win32/xor.data create mode 100644 lib/ann/fann/bin/x64/xor.data create mode 100644 lib/ann/fann/cmake/Modules/DefineInstallationPaths.cmake create mode 100644 lib/ann/fann/cmake/config.h.in create mode 100644 lib/ann/fann/cmake/fann-config.cmake.in create mode 100644 lib/ann/fann/cmake/fann-use.cmake create mode 100644 lib/ann/fann/cmake/fann.pc.cmake create mode 100644 lib/ann/fann/datasets/abelone.test create mode 100644 lib/ann/fann/datasets/abelone.train create mode 100644 lib/ann/fann/datasets/bank32fm.test create mode 100644 lib/ann/fann/datasets/bank32fm.train create mode 100644 lib/ann/fann/datasets/bank32nh.test create mode 100644 lib/ann/fann/datasets/bank32nh.train create mode 100644 lib/ann/fann/datasets/building.test create mode 100644 lib/ann/fann/datasets/building.train create mode 100644 lib/ann/fann/datasets/census-house.test create mode 100644 lib/ann/fann/datasets/census-house.train create mode 100644 lib/ann/fann/datasets/diabetes.test create mode 100644 lib/ann/fann/datasets/diabetes.train create mode 100644 lib/ann/fann/datasets/gene.test create mode 100644 lib/ann/fann/datasets/gene.train create mode 100644 lib/ann/fann/datasets/kin32fm.test create mode 100644 lib/ann/fann/datasets/kin32fm.train create mode 100644 lib/ann/fann/datasets/mushroom.test create mode 100644 lib/ann/fann/datasets/mushroom.train create mode 100644 lib/ann/fann/datasets/parity13.test create mode 100644 lib/ann/fann/datasets/parity13.train create mode 100644 lib/ann/fann/datasets/parity8.test create mode 100644 lib/ann/fann/datasets/parity8.train create mode 100644 lib/ann/fann/datasets/pumadyn-32fm.test create mode 100644 lib/ann/fann/datasets/pumadyn-32fm.train create mode 100644 lib/ann/fann/datasets/robot.test create mode 100644 lib/ann/fann/datasets/robot.train create mode 100644 lib/ann/fann/datasets/scaling.data create mode 100644 lib/ann/fann/datasets/soybean.test create mode 100644 lib/ann/fann/datasets/soybean.train create mode 100644 lib/ann/fann/datasets/thyroid.test create mode 100644 lib/ann/fann/datasets/thyroid.train create mode 100644 lib/ann/fann/datasets/two-spiral.test create mode 100644 lib/ann/fann/datasets/two-spiral.train create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Config/Languages.txt create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Config/Topics.txt create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/customizinglanguages.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/customizingtopics.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/documenting.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/documenting/reference.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/documenting/walkthrough.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/example/Default.css create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/example/NaturalDocs.js create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/example/Roman.css create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/example/Small.css create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/example/showstyle.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/examples.css create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/header/background.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/header/leftside.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/header/logo.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/header/overbody.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/header/overbodybg.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/header/overleftmargin.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/header/overmenu.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/header/overmenubg.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/header/rightside.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/menu/about.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/menu/background.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/menu/bottomleft.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/menu/bottomright.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/menu/community.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/menu/customizing.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/images/menu/using.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/index.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/javascript/BrowserStyles.js create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/javascript/PNGHandling.js create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/keywords.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/languages.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/menu.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/output.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/running.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/styles.css create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/styles.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Help/troubleshooting.html create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Info/CSSGuide.txt create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Info/File Parsing.txt create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Info/HTMLTestCases.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Info/Languages.txt create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Info/NDMarkup.txt create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Info/Symbol Management.txt create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Info/images/Logo.png create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/JavaScript/GooglePrettify.js create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/JavaScript/NaturalDocs.js create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/License.txt create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/BinaryFile.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder/Base.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder/FramedHTML.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder/HTML.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder/HTMLBase.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ClassHierarchy.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ClassHierarchy/Class.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ClassHierarchy/File.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ConfigFile.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Constants.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/DefineMembers.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Error.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/File.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ImageReferenceTable.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ImageReferenceTable/Reference.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ImageReferenceTable/String.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/ActionScript.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Ada.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Advanced.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Advanced/Scope.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Base.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/CSharp.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/PLSQL.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Pascal.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Perl.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Prototype.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Prototype/Parameter.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Simple.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Tcl.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/LineReader.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Menu.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Menu/Entry.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/NDMarkup.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Parser.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Parser/JavaDoc.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Parser/Native.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Parser/ParsedTopic.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Project.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Project/ImageFile.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Project/SourceFile.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ReferenceString.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Settings.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Settings/BuildTarget.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB/Extension.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB/File.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB/Item.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB/ItemDefinition.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/StatusMessage.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolString.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable/File.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable/IndexElement.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable/Reference.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable/Symbol.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Topics.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Topics/Type.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Version.pm create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/NaturalDocs create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/NaturalDocs.bat create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Styles/Default.css create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Styles/Roman.css create mode 100755 lib/ann/fann/docs/NaturalDocs-1.52/Styles/Small.css create mode 100755 lib/ann/fann/docs/generate_docs.sh create mode 100644 lib/ann/fann/docs/prj/Languages.txt create mode 100644 lib/ann/fann/docs/prj/Menu.txt create mode 100644 lib/ann/fann/docs/prj/Topics.txt create mode 100755 lib/ann/fann/docs/publish_docs.sh create mode 100644 lib/ann/fann/examples/.gitignore create mode 100644 lib/ann/fann/examples/cascade_train.c create mode 100644 lib/ann/fann/examples/momentums.c create mode 100644 lib/ann/fann/examples/mushroom.c create mode 100644 lib/ann/fann/examples/parallel_train.c create mode 100644 lib/ann/fann/examples/robot.c create mode 100644 lib/ann/fann/examples/scaling_test.c create mode 100644 lib/ann/fann/examples/scaling_train.c create mode 100644 lib/ann/fann/examples/simple_test.c create mode 100644 lib/ann/fann/examples/simple_train.c create mode 100644 lib/ann/fann/examples/steepness_train.c create mode 100644 lib/ann/fann/examples/xor.data create mode 100644 lib/ann/fann/examples/xor_sample.cpp create mode 100644 lib/ann/fann/examples/xor_test.c create mode 100644 lib/ann/fann/examples/xor_train.c create mode 100644 lib/ann/fann/ignore.bii create mode 100644 lib/ann/fann/lib/googletest/CHANGES create mode 100644 lib/ann/fann/lib/googletest/CMakeLists.txt create mode 100644 lib/ann/fann/lib/googletest/CONTRIBUTORS create mode 100644 lib/ann/fann/lib/googletest/LICENSE create mode 100644 lib/ann/fann/lib/googletest/Makefile.am create mode 100644 lib/ann/fann/lib/googletest/README.md create mode 100644 lib/ann/fann/lib/googletest/build-aux/.keep create mode 100644 lib/ann/fann/lib/googletest/cmake/internal_utils.cmake create mode 100644 lib/ann/fann/lib/googletest/codegear/gtest.cbproj create mode 100644 lib/ann/fann/lib/googletest/codegear/gtest.groupproj create mode 100644 lib/ann/fann/lib/googletest/codegear/gtest_all.cc create mode 100644 lib/ann/fann/lib/googletest/codegear/gtest_link.cc create mode 100644 lib/ann/fann/lib/googletest/codegear/gtest_main.cbproj create mode 100644 lib/ann/fann/lib/googletest/codegear/gtest_unittest.cbproj create mode 100644 lib/ann/fann/lib/googletest/configure.ac create mode 100644 lib/ann/fann/lib/googletest/docs/AdvancedGuide.md create mode 100644 lib/ann/fann/lib/googletest/docs/DevGuide.md create mode 100644 lib/ann/fann/lib/googletest/docs/Documentation.md create mode 100644 lib/ann/fann/lib/googletest/docs/FAQ.md create mode 100644 lib/ann/fann/lib/googletest/docs/Primer.md create mode 100644 lib/ann/fann/lib/googletest/docs/PumpManual.md create mode 100644 lib/ann/fann/lib/googletest/docs/Samples.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_5_AdvancedGuide.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_5_Documentation.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_5_FAQ.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_5_Primer.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_5_PumpManual.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_5_XcodeGuide.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_6_AdvancedGuide.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_6_Documentation.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_6_FAQ.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_6_Primer.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_6_PumpManual.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_6_Samples.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_6_XcodeGuide.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_7_AdvancedGuide.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_7_Documentation.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_7_FAQ.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_7_Primer.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_7_PumpManual.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_7_Samples.md create mode 100644 lib/ann/fann/lib/googletest/docs/V1_7_XcodeGuide.md create mode 100644 lib/ann/fann/lib/googletest/docs/XcodeGuide.md create mode 100644 lib/ann/fann/lib/googletest/include/gtest/gtest-death-test.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/gtest-message.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/gtest-param-test.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/gtest-param-test.h.pump create mode 100644 lib/ann/fann/lib/googletest/include/gtest/gtest-printers.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/gtest-spi.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/gtest-test-part.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/gtest-typed-test.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/gtest.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/gtest_pred_impl.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/gtest_prod.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/custom/gtest-port.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/custom/gtest-printers.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/custom/gtest.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-death-test-internal.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-filepath.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-internal.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-linked_ptr.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-param-util-generated.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-param-util-generated.h.pump create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-param-util.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-port-arch.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-port.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-string.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-tuple.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-tuple.h.pump create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-type-util.h create mode 100644 lib/ann/fann/lib/googletest/include/gtest/internal/gtest-type-util.h.pump create mode 100644 lib/ann/fann/lib/googletest/m4/acx_pthread.m4 create mode 100644 lib/ann/fann/lib/googletest/m4/gtest.m4 create mode 100644 lib/ann/fann/lib/googletest/msvc/gtest-md.vcproj create mode 100644 lib/ann/fann/lib/googletest/msvc/gtest.vcproj create mode 100644 lib/ann/fann/lib/googletest/msvc/gtest_main-md.vcproj create mode 100644 lib/ann/fann/lib/googletest/msvc/gtest_main.vcproj create mode 100644 lib/ann/fann/lib/googletest/msvc/gtest_prod_test-md.vcproj create mode 100644 lib/ann/fann/lib/googletest/msvc/gtest_prod_test.vcproj create mode 100644 lib/ann/fann/lib/googletest/msvc/gtest_unittest-md.vcproj create mode 100644 lib/ann/fann/lib/googletest/msvc/gtest_unittest.vcproj create mode 100644 lib/ann/fann/lib/googletest/samples/prime_tables.h create mode 100644 lib/ann/fann/lib/googletest/samples/sample1.cc create mode 100644 lib/ann/fann/lib/googletest/samples/sample1.h create mode 100644 lib/ann/fann/lib/googletest/samples/sample10_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/samples/sample1_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/samples/sample2.cc create mode 100644 lib/ann/fann/lib/googletest/samples/sample2.h create mode 100644 lib/ann/fann/lib/googletest/samples/sample2_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/samples/sample3-inl.h create mode 100644 lib/ann/fann/lib/googletest/samples/sample3_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/samples/sample4.cc create mode 100644 lib/ann/fann/lib/googletest/samples/sample4.h create mode 100644 lib/ann/fann/lib/googletest/samples/sample4_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/samples/sample5_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/samples/sample6_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/samples/sample7_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/samples/sample8_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/samples/sample9_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/scripts/common.py create mode 100755 lib/ann/fann/lib/googletest/scripts/fuse_gtest_files.py create mode 100755 lib/ann/fann/lib/googletest/scripts/gen_gtest_pred_impl.py create mode 100755 lib/ann/fann/lib/googletest/scripts/gtest-config.in create mode 100755 lib/ann/fann/lib/googletest/scripts/pump.py create mode 100755 lib/ann/fann/lib/googletest/scripts/release_docs.py create mode 100755 lib/ann/fann/lib/googletest/scripts/upload.py create mode 100755 lib/ann/fann/lib/googletest/scripts/upload_gtest.py create mode 100644 lib/ann/fann/lib/googletest/src/gtest-all.cc create mode 100644 lib/ann/fann/lib/googletest/src/gtest-death-test.cc create mode 100644 lib/ann/fann/lib/googletest/src/gtest-filepath.cc create mode 100644 lib/ann/fann/lib/googletest/src/gtest-internal-inl.h create mode 100644 lib/ann/fann/lib/googletest/src/gtest-port.cc create mode 100644 lib/ann/fann/lib/googletest/src/gtest-printers.cc create mode 100644 lib/ann/fann/lib/googletest/src/gtest-test-part.cc create mode 100644 lib/ann/fann/lib/googletest/src/gtest-typed-test.cc create mode 100644 lib/ann/fann/lib/googletest/src/gtest.cc create mode 100644 lib/ann/fann/lib/googletest/src/gtest_main.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-death-test_ex_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-death-test_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-filepath_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-linked_ptr_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-listener_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-message_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-options_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-param-test2_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-param-test_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-param-test_test.h create mode 100644 lib/ann/fann/lib/googletest/test/gtest-port_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-printers_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-test-part_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-tuple_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-typed-test2_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-typed-test_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest-typed-test_test.h create mode 100644 lib/ann/fann/lib/googletest/test/gtest-unittest-api_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_all_test.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_break_on_failure_unittest.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_break_on_failure_unittest_.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_catch_exceptions_test.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_catch_exceptions_test_.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_color_test.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_color_test_.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_env_var_test.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_env_var_test_.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_environment_test.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_filter_unittest.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_filter_unittest_.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_help_test.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_help_test_.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_list_tests_unittest.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_list_tests_unittest_.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_main_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_no_test_unittest.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_output_test.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_output_test_.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_output_test_golden_lin.txt create mode 100644 lib/ann/fann/lib/googletest/test/gtest_pred_impl_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_premature_exit_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_prod_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_repeat_test.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_shuffle_test.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_shuffle_test_.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_sole_header_test.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_stress_test.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_test_utils.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_throw_on_failure_ex_test.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_throw_on_failure_test.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_throw_on_failure_test_.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_uninitialized_test.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_uninitialized_test_.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_unittest.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_xml_outfile1_test_.cc create mode 100644 lib/ann/fann/lib/googletest/test/gtest_xml_outfile2_test_.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_xml_outfiles_test.py create mode 100755 lib/ann/fann/lib/googletest/test/gtest_xml_output_unittest.py create mode 100644 lib/ann/fann/lib/googletest/test/gtest_xml_output_unittest_.cc create mode 100755 lib/ann/fann/lib/googletest/test/gtest_xml_test_utils.py create mode 100644 lib/ann/fann/lib/googletest/test/production.cc create mode 100644 lib/ann/fann/lib/googletest/test/production.h create mode 100644 lib/ann/fann/lib/googletest/xcode/Config/DebugProject.xcconfig create mode 100644 lib/ann/fann/lib/googletest/xcode/Config/FrameworkTarget.xcconfig create mode 100644 lib/ann/fann/lib/googletest/xcode/Config/General.xcconfig create mode 100644 lib/ann/fann/lib/googletest/xcode/Config/ReleaseProject.xcconfig create mode 100644 lib/ann/fann/lib/googletest/xcode/Config/StaticLibraryTarget.xcconfig create mode 100644 lib/ann/fann/lib/googletest/xcode/Config/TestTarget.xcconfig create mode 100644 lib/ann/fann/lib/googletest/xcode/Resources/Info.plist create mode 100644 lib/ann/fann/lib/googletest/xcode/Samples/FrameworkSample/Info.plist create mode 100644 lib/ann/fann/lib/googletest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj create mode 100644 lib/ann/fann/lib/googletest/xcode/Samples/FrameworkSample/runtests.sh create mode 100644 lib/ann/fann/lib/googletest/xcode/Samples/FrameworkSample/widget.cc create mode 100644 lib/ann/fann/lib/googletest/xcode/Samples/FrameworkSample/widget.h create mode 100644 lib/ann/fann/lib/googletest/xcode/Samples/FrameworkSample/widget_test.cc create mode 100644 lib/ann/fann/lib/googletest/xcode/Scripts/runtests.sh create mode 100755 lib/ann/fann/lib/googletest/xcode/Scripts/versiongenerate.py create mode 100644 lib/ann/fann/lib/googletest/xcode/gtest.xcodeproj/project.pbxproj create mode 100644 lib/ann/fann/src/CMakeLists.txt create mode 100644 lib/ann/fann/src/doublefann.c create mode 100644 lib/ann/fann/src/fann.c create mode 100644 lib/ann/fann/src/fann_cascade.c create mode 100644 lib/ann/fann/src/fann_error.c create mode 100644 lib/ann/fann/src/fann_io.c create mode 100644 lib/ann/fann/src/fann_train.c create mode 100644 lib/ann/fann/src/fann_train_data.c create mode 100644 lib/ann/fann/src/fixedfann.c create mode 100644 lib/ann/fann/src/floatfann.c create mode 100644 lib/ann/fann/src/include/CMakeLists.txt create mode 100644 lib/ann/fann/src/include/config.h create mode 100644 lib/ann/fann/src/include/doublefann.h create mode 100644 lib/ann/fann/src/include/fann.h create mode 100644 lib/ann/fann/src/include/fann_activation.h create mode 100644 lib/ann/fann/src/include/fann_cascade.h create mode 100644 lib/ann/fann/src/include/fann_cpp.h create mode 100644 lib/ann/fann/src/include/fann_data.h create mode 100644 lib/ann/fann/src/include/fann_data_cpp.h create mode 100644 lib/ann/fann/src/include/fann_error.h create mode 100644 lib/ann/fann/src/include/fann_internal.h create mode 100644 lib/ann/fann/src/include/fann_io.h create mode 100644 lib/ann/fann/src/include/fann_train.h create mode 100644 lib/ann/fann/src/include/fann_training_data_cpp.h create mode 100644 lib/ann/fann/src/include/fixedfann.h create mode 100644 lib/ann/fann/src/include/floatfann.h create mode 100644 lib/ann/fann/src/include/parallel_fann.h create mode 100644 lib/ann/fann/src/include/parallel_fann.hpp create mode 100644 lib/ann/fann/src/parallel_doublefann_cpp.cpp create mode 100644 lib/ann/fann/src/parallel_fann.c create mode 100644 lib/ann/fann/src/parallel_fann_cpp.cpp create mode 100644 lib/ann/fann/src/parallel_floatfann_cpp.cpp create mode 100644 lib/ann/fann/tests/CMakeLists.txt create mode 100644 lib/ann/fann/tests/fann_test.cpp create mode 100644 lib/ann/fann/tests/fann_test.h create mode 100644 lib/ann/fann/tests/fann_test_data.cpp create mode 100644 lib/ann/fann/tests/fann_test_data.h create mode 100644 lib/ann/fann/tests/fann_test_train.cpp create mode 100644 lib/ann/fann/tests/fann_test_train.h create mode 100644 lib/ann/fann/tests/main.cpp create mode 100644 lib/ann/lfann.h create mode 100644 lib/ann/net.c create mode 100755 lib/ann/tests/callback.lua create mode 100755 lib/ann/tests/cascade.lua create mode 100755 lib/ann/tests/creation.lua create mode 100755 lib/ann/tests/data.lua create mode 100755 lib/ann/tests/params.lua create mode 100755 lib/ann/tests/run.lua create mode 100755 lib/ann/tests/scale.lua create mode 100644 lib/ann/tests/train.data create mode 100644 lib/ann/tests/xor.net create mode 100644 lib/ann/tests/xor.test create mode 100755 lib/curl create mode 100644 lib/lualib.h create mode 100644 lib/pibot/Makefile create mode 100644 lib/pibot/pibot.c create mode 100644 lib/stmr/Makefile create mode 100644 lib/stmr/stmr.c create mode 100644 lib/ulib/3rd/zip/main.c create mode 100755 lib/ulib/3rd/zip/miniz.c create mode 100755 lib/ulib/3rd/zip/zip.c create mode 100755 lib/ulib/3rd/zip/zip.h create mode 100644 lib/ulib/Makefile create mode 100644 lib/ulib/ulib.c create mode 100644 lib/wurl/Makefile create mode 100644 lib/wurl/test.c create mode 100644 lib/wurl/wurl.c create mode 100644 lua-api.c create mode 100644 lua-api.h create mode 100644 plugin-wrapper.c diff --git a/3rd/jsmn/LICENSE b/3rd/jsmn/LICENSE new file mode 100755 index 0000000..c84fb2e --- /dev/null +++ b/3rd/jsmn/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2010 Serge A. Zaitsev + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/3rd/jsmn/Makefile b/3rd/jsmn/Makefile new file mode 100755 index 0000000..f89701f --- /dev/null +++ b/3rd/jsmn/Makefile @@ -0,0 +1,41 @@ +# You can put your build options here +-include config.mk + +all: libjsmn.a + +libjsmn.a: jsmn.o + $(AR) rc $@ $^ + +%.o: %.c jsmn.h + $(CC) -c $(CFLAGS) $< -o $@ + +test: test_default test_strict test_links test_strict_links +test_default: test/tests.c + $(CC) $(CFLAGS) $(LDFLAGS) $< -o test/$@ + ./test/$@ +test_strict: test/tests.c + $(CC) -DJSMN_STRICT=1 $(CFLAGS) $(LDFLAGS) $< -o test/$@ + ./test/$@ +test_links: test/tests.c + $(CC) -DJSMN_PARENT_LINKS=1 $(CFLAGS) $(LDFLAGS) $< -o test/$@ + ./test/$@ +test_strict_links: test/tests.c + $(CC) -DJSMN_STRICT=1 -DJSMN_PARENT_LINKS=1 $(CFLAGS) $(LDFLAGS) $< -o test/$@ + ./test/$@ + +jsmn_test.o: jsmn_test.c libjsmn.a + +simple_example: example/simple.o libjsmn.a + $(CC) $(LDFLAGS) $^ -o $@ + +jsondump: example/jsondump.o libjsmn.a + $(CC) $(LDFLAGS) $^ -o $@ + +clean: + rm -f *.o example/*.o + rm -f *.a *.so + rm -f simple_example + rm -f jsondump + +.PHONY: all clean test + diff --git a/3rd/jsmn/README.md b/3rd/jsmn/README.md new file mode 100755 index 0000000..105897b --- /dev/null +++ b/3rd/jsmn/README.md @@ -0,0 +1,167 @@ + +JSMN +==== + +jsmn (pronounced like 'jasmine') is a minimalistic JSON parser in C. It can be +easily integrated into resource-limited or embedded projects. + +You can find more information about JSON format at [json.org][1] + +Library sources are available at https://github.com/zserge/jsmn + +The web page with some information about jsmn can be found at +[http://zserge.com/jsmn.html][2] + +Philosophy +---------- + +Most JSON parsers offer you a bunch of functions to load JSON data, parse it +and extract any value by its name. jsmn proves that checking the correctness of +every JSON packet or allocating temporary objects to store parsed JSON fields +often is an overkill. + +JSON format itself is extremely simple, so why should we complicate it? + +jsmn is designed to be **robust** (it should work fine even with erroneous +data), **fast** (it should parse data on the fly), **portable** (no superfluous +dependencies or non-standard C extensions). And of course, **simplicity** is a +key feature - simple code style, simple algorithm, simple integration into +other projects. + +Features +-------- + +* compatible with C89 +* no dependencies (even libc!) +* highly portable (tested on x86/amd64, ARM, AVR) +* about 200 lines of code +* extremely small code footprint +* API contains only 2 functions +* no dynamic memory allocation +* incremental single-pass parsing +* library code is covered with unit-tests + +Design +------ + +The rudimentary jsmn object is a **token**. Let's consider a JSON string: + + '{ "name" : "Jack", "age" : 27 }' + +It holds the following tokens: + +* Object: `{ "name" : "Jack", "age" : 27}` (the whole object) +* Strings: `"name"`, `"Jack"`, `"age"` (keys and some values) +* Number: `27` + +In jsmn, tokens do not hold any data, but point to token boundaries in JSON +string instead. In the example above jsmn will create tokens like: Object +[0..31], String [3..7], String [12..16], String [20..23], Number [27..29]. + +Every jsmn token has a type, which indicates the type of corresponding JSON +token. jsmn supports the following token types: + +* Object - a container of key-value pairs, e.g.: + `{ "foo":"bar", "x":0.3 }` +* Array - a sequence of values, e.g.: + `[ 1, 2, 3 ]` +* String - a quoted sequence of chars, e.g.: `"foo"` +* Primitive - a number, a boolean (`true`, `false`) or `null` + +Besides start/end positions, jsmn tokens for complex types (like arrays +or objects) also contain a number of child items, so you can easily follow +object hierarchy. + +This approach provides enough information for parsing any JSON data and makes +it possible to use zero-copy techniques. + +Install +------- + +To clone the repository you should have Git installed. Just run: + + $ git clone https://github.com/zserge/jsmn + +Repository layout is simple: jsmn.c and jsmn.h are library files, tests are in +the jsmn\_test.c, you will also find README, LICENSE and Makefile files inside. + +To build the library, run `make`. It is also recommended to run `make test`. +Let me know, if some tests fail. + +If build was successful, you should get a `libjsmn.a` library. +The header file you should include is called `"jsmn.h"`. + +API +--- + +Token types are described by `jsmntype_t`: + + typedef enum { + JSMN_UNDEFINED = 0, + JSMN_OBJECT = 1, + JSMN_ARRAY = 2, + JSMN_STRING = 3, + JSMN_PRIMITIVE = 4 + } jsmntype_t; + +**Note:** Unlike JSON data types, primitive tokens are not divided into +numbers, booleans and null, because one can easily tell the type using the +first character: + +* 't', 'f' - boolean +* 'n' - null +* '-', '0'..'9' - number + +Token is an object of `jsmntok_t` type: + + typedef struct { + jsmntype_t type; // Token type + int start; // Token start position + int end; // Token end position + int size; // Number of child (nested) tokens + } jsmntok_t; + +**Note:** string tokens point to the first character after +the opening quote and the previous symbol before final quote. This was made +to simplify string extraction from JSON data. + +All job is done by `jsmn_parser` object. You can initialize a new parser using: + + jsmn_parser parser; + jsmntok_t tokens[10]; + + jsmn_init(&parser); + + // js - pointer to JSON string + // tokens - an array of tokens available + // 10 - number of tokens available + jsmn_parse(&parser, js, strlen(js), tokens, 10); + +This will create a parser, and then it tries to parse up to 10 JSON tokens from +the `js` string. + +A non-negative return value of `jsmn_parse` is the number of tokens actually +used by the parser. +Passing NULL instead of the tokens array would not store parsing results, but +instead the function will return the value of tokens needed to parse the given +string. This can be useful if you don't know yet how many tokens to allocate. + +If something goes wrong, you will get an error. Error will be one of these: + +* `JSMN_ERROR_INVAL` - bad token, JSON string is corrupted +* `JSMN_ERROR_NOMEM` - not enough tokens, JSON string is too large +* `JSMN_ERROR_PART` - JSON string is too short, expecting more JSON data + +If you get `JSON_ERROR_NOMEM`, you can re-allocate more tokens and call +`jsmn_parse` once more. If you read json data from the stream, you can +periodically call `jsmn_parse` and check if return value is `JSON_ERROR_PART`. +You will get this error until you reach the end of JSON data. + +Other info +---------- + +This software is distributed under [MIT license](http://www.opensource.org/licenses/mit-license.php), + so feel free to integrate it in your commercial products. + +[1]: http://www.json.org/ +[2]: http://zserge.com/jsmn.html diff --git a/3rd/jsmn/example/jsondump.c b/3rd/jsmn/example/jsondump.c new file mode 100755 index 0000000..4fb10fd --- /dev/null +++ b/3rd/jsmn/example/jsondump.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include "../jsmn.h" + +/* Function realloc_it() is a wrapper function for standart realloc() + * with one difference - it frees old memory pointer in case of realloc + * failure. Thus, DO NOT use old data pointer in anyway after call to + * realloc_it(). If your code has some kind of fallback algorithm if + * memory can't be re-allocated - use standart realloc() instead. + */ +static inline void *realloc_it(void *ptrmem, size_t size) { + void *p = realloc(ptrmem, size); + if (!p) { + free (ptrmem); + fprintf(stderr, "realloc(): errno=%d\n", errno); + } + return p; +} + +/* + * An example of reading JSON from stdin and printing its content to stdout. + * The output looks like YAML, but I'm not sure if it's really compatible. + */ + +static int dump(const char *js, jsmntok_t *t, size_t count, int indent) { + int i, j, k; + if (count == 0) { + return 0; + } + if (t->type == JSMN_PRIMITIVE) { + printf("%.*s", t->end - t->start, js+t->start); + return 1; + } else if (t->type == JSMN_STRING) { + printf("'%.*s'", t->end - t->start, js+t->start); + return 1; + } else if (t->type == JSMN_OBJECT) { + printf("\n"); + j = 0; + for (i = 0; i < t->size; i++) { + for (k = 0; k < indent; k++) printf(" "); + j += dump(js, t+1+j, count-j, indent+1); + printf(": "); + j += dump(js, t+1+j, count-j, indent+1); + printf("\n"); + } + return j+1; + } else if (t->type == JSMN_ARRAY) { + j = 0; + printf("\n"); + for (i = 0; i < t->size; i++) { + for (k = 0; k < indent-1; k++) printf(" "); + printf(" - "); + j += dump(js, t+1+j, count-j, indent+1); + printf("\n"); + } + return j+1; + } + return 0; +} + +int main() { + int r; + int eof_expected = 0; + char *js = NULL; + size_t jslen = 0; + char buf[BUFSIZ]; + + jsmn_parser p; + jsmntok_t *tok; + size_t tokcount = 2; + + /* Prepare parser */ + jsmn_init(&p); + + /* Allocate some tokens as a start */ + tok = malloc(sizeof(*tok) * tokcount); + if (tok == NULL) { + fprintf(stderr, "malloc(): errno=%d\n", errno); + return 3; + } + + for (;;) { + /* Read another chunk */ + r = fread(buf, 1, sizeof(buf), stdin); + if (r < 0) { + fprintf(stderr, "fread(): %d, errno=%d\n", r, errno); + return 1; + } + if (r == 0) { + if (eof_expected != 0) { + return 0; + } else { + fprintf(stderr, "fread(): unexpected EOF\n"); + return 2; + } + } + + js = realloc_it(js, jslen + r + 1); + if (js == NULL) { + return 3; + } + strncpy(js + jslen, buf, r); + jslen = jslen + r; + +again: + r = jsmn_parse(&p, js, jslen, tok, tokcount); + if (r < 0) { + if (r == JSMN_ERROR_NOMEM) { + tokcount = tokcount * 2; + tok = realloc_it(tok, sizeof(*tok) * tokcount); + if (tok == NULL) { + return 3; + } + goto again; + } + } else { + dump(js, tok, p.toknext, 0); + eof_expected = 1; + } + } + + return EXIT_SUCCESS; +} diff --git a/3rd/jsmn/example/simple.c b/3rd/jsmn/example/simple.c new file mode 100755 index 0000000..aeb9cf4 --- /dev/null +++ b/3rd/jsmn/example/simple.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include "../jsmn.h" + +/* + * A small example of jsmn parsing when JSON structure is known and number of + * tokens is predictable. + */ + +static const char *JSON_STRING = + "{\"user\": \"johndoe\", \"admin\": false, \"uid\": 1000,\n " + "\"groups\": [\"users\", \"wheel\", \"audio\", \"video\"]}"; + +static int jsoneq(const char *json, jsmntok_t *tok, const char *s) { + if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start && + strncmp(json + tok->start, s, tok->end - tok->start) == 0) { + return 0; + } + return -1; +} + +int main() { + int i; + int r; + jsmn_parser p; + jsmntok_t t[128]; /* We expect no more than 128 tokens */ + + jsmn_init(&p); + r = jsmn_parse(&p, JSON_STRING, strlen(JSON_STRING), t, sizeof(t)/sizeof(t[0])); + if (r < 0) { + printf("Failed to parse JSON: %d\n", r); + return 1; + } + + /* Assume the top-level element is an object */ + if (r < 1 || t[0].type != JSMN_OBJECT) { + printf("Object expected\n"); + return 1; + } + + /* Loop over all keys of the root object */ + for (i = 1; i < r; i++) { + if (jsoneq(JSON_STRING, &t[i], "user") == 0) { + /* We may use strndup() to fetch string value */ + printf("- User: %.*s\n", t[i+1].end-t[i+1].start, + JSON_STRING + t[i+1].start); + i++; + } else if (jsoneq(JSON_STRING, &t[i], "admin") == 0) { + /* We may additionally check if the value is either "true" or "false" */ + printf("- Admin: %.*s\n", t[i+1].end-t[i+1].start, + JSON_STRING + t[i+1].start); + i++; + } else if (jsoneq(JSON_STRING, &t[i], "uid") == 0) { + /* We may want to do strtol() here to get numeric value */ + printf("- UID: %.*s\n", t[i+1].end-t[i+1].start, + JSON_STRING + t[i+1].start); + i++; + } else if (jsoneq(JSON_STRING, &t[i], "groups") == 0) { + int j; + printf("- Groups:\n"); + if (t[i+1].type != JSMN_ARRAY) { + continue; /* We expect groups to be an array of strings */ + } + for (j = 0; j < t[i+1].size; j++) { + jsmntok_t *g = &t[i+j+2]; + printf(" * %.*s\n", g->end - g->start, JSON_STRING + g->start); + } + i += t[i+1].size + 1; + } else { + printf("Unexpected key: %.*s\n", t[i].end-t[i].start, + JSON_STRING + t[i].start); + } + } + return EXIT_SUCCESS; +} diff --git a/3rd/jsmn/jsmn.c b/3rd/jsmn/jsmn.c new file mode 100755 index 0000000..bcd6392 --- /dev/null +++ b/3rd/jsmn/jsmn.c @@ -0,0 +1,314 @@ +#include "jsmn.h" + +/** + * Allocates a fresh unused token from the token pull. + */ +static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, + jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *tok; + if (parser->toknext >= num_tokens) { + return NULL; + } + tok = &tokens[parser->toknext++]; + tok->start = tok->end = -1; + tok->size = 0; +#ifdef JSMN_PARENT_LINKS + tok->parent = -1; +#endif + return tok; +} + +/** + * Fills token type and boundaries. + */ +static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type, + int start, int end) { + token->type = type; + token->start = start; + token->end = end; + token->size = 0; +} + +/** + * Fills next available token with JSON primitive. + */ +static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, + size_t len, jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *token; + int start; + + start = parser->pos; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + switch (js[parser->pos]) { +#ifndef JSMN_STRICT + /* In strict mode primitive must be followed by "," or "}" or "]" */ + case ':': +#endif + case '\t' : case '\r' : case '\n' : case ' ' : + case ',' : case ']' : case '}' : + goto found; + } + if (js[parser->pos] < 32 || js[parser->pos] >= 127) { + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } +#ifdef JSMN_STRICT + /* In strict mode primitive must be followed by a comma/object/array */ + parser->pos = start; + return JSMN_ERROR_PART; +#endif + +found: + if (tokens == NULL) { + parser->pos--; + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + parser->pos--; + return 0; +} + +/** + * Fills next token with JSON string. + */ +static int jsmn_parse_string(jsmn_parser *parser, const char *js, + size_t len, jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *token; + + int start = parser->pos; + + parser->pos++; + + /* Skip starting quote */ + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c = js[parser->pos]; + + /* Quote: end of string */ + if (c == '\"') { + if (tokens == NULL) { + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos); +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + return 0; + } + + /* Backslash: Quoted symbol expected */ + if (c == '\\' && parser->pos + 1 < len) { + int i; + parser->pos++; + switch (js[parser->pos]) { + /* Allowed escaped symbols */ + case '\"': case '/' : case '\\' : case 'b' : + case 'f' : case 'r' : case 'n' : case 't' : + break; + /* Allows escaped symbol \uXXXX */ + case 'u': + parser->pos++; + for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) { + /* If it isn't a hex character we have an error */ + if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ + (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ + (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ + parser->pos = start; + return JSMN_ERROR_INVAL; + } + parser->pos++; + } + parser->pos--; + break; + /* Unexpected symbol */ + default: + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } + } + parser->pos = start; + return JSMN_ERROR_PART; +} + +/** + * Parse JSON string and fill tokens. + */ +int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, + jsmntok_t *tokens, unsigned int num_tokens) { + int r; + int i; + jsmntok_t *token; + int count = parser->toknext; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c; + jsmntype_t type; + + c = js[parser->pos]; + switch (c) { + case '{': case '[': + count++; + if (tokens == NULL) { + break; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) + return JSMN_ERROR_NOMEM; + if (parser->toksuper != -1) { + tokens[parser->toksuper].size++; +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + } + token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); + token->start = parser->pos; + parser->toksuper = parser->toknext - 1; + break; + case '}': case ']': + if (tokens == NULL) + break; + type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); +#ifdef JSMN_PARENT_LINKS + if (parser->toknext < 1) { + return JSMN_ERROR_INVAL; + } + token = &tokens[parser->toknext - 1]; + for (;;) { + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + token->end = parser->pos + 1; + parser->toksuper = token->parent; + break; + } + if (token->parent == -1) { + if(token->type != type || parser->toksuper == -1) { + return JSMN_ERROR_INVAL; + } + break; + } + token = &tokens[token->parent]; + } +#else + for (i = parser->toknext - 1; i >= 0; i--) { + token = &tokens[i]; + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + parser->toksuper = -1; + token->end = parser->pos + 1; + break; + } + } + /* Error if unmatched closing bracket */ + if (i == -1) return JSMN_ERROR_INVAL; + for (; i >= 0; i--) { + token = &tokens[i]; + if (token->start != -1 && token->end == -1) { + parser->toksuper = i; + break; + } + } +#endif + break; + case '\"': + r = jsmn_parse_string(parser, js, len, tokens, num_tokens); + if (r < 0) return r; + count++; + if (parser->toksuper != -1 && tokens != NULL) + tokens[parser->toksuper].size++; + break; + case '\t' : case '\r' : case '\n' : case ' ': + break; + case ':': + parser->toksuper = parser->toknext - 1; + break; + case ',': + if (tokens != NULL && parser->toksuper != -1 && + tokens[parser->toksuper].type != JSMN_ARRAY && + tokens[parser->toksuper].type != JSMN_OBJECT) { +#ifdef JSMN_PARENT_LINKS + parser->toksuper = tokens[parser->toksuper].parent; +#else + for (i = parser->toknext - 1; i >= 0; i--) { + if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) { + if (tokens[i].start != -1 && tokens[i].end == -1) { + parser->toksuper = i; + break; + } + } + } +#endif + } + break; +#ifdef JSMN_STRICT + /* In strict mode primitives are: numbers and booleans */ + case '-': case '0': case '1' : case '2': case '3' : case '4': + case '5': case '6': case '7' : case '8': case '9': + case 't': case 'f': case 'n' : + /* And they must not be keys of the object */ + if (tokens != NULL && parser->toksuper != -1) { + jsmntok_t *t = &tokens[parser->toksuper]; + if (t->type == JSMN_OBJECT || + (t->type == JSMN_STRING && t->size != 0)) { + return JSMN_ERROR_INVAL; + } + } +#else + /* In non-strict mode every unquoted value is a primitive */ + default: +#endif + r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); + if (r < 0) return r; + count++; + if (parser->toksuper != -1 && tokens != NULL) + tokens[parser->toksuper].size++; + break; + +#ifdef JSMN_STRICT + /* Unexpected char in strict mode */ + default: + return JSMN_ERROR_INVAL; +#endif + } + } + + if (tokens != NULL) { + for (i = parser->toknext - 1; i >= 0; i--) { + /* Unmatched opened object or array */ + if (tokens[i].start != -1 && tokens[i].end == -1) { + return JSMN_ERROR_PART; + } + } + } + + return count; +} + +/** + * Creates a new parser based over a given buffer with an array of tokens + * available. + */ +void jsmn_init(jsmn_parser *parser) { + parser->pos = 0; + parser->toknext = 0; + parser->toksuper = -1; +} + diff --git a/3rd/jsmn/jsmn.h b/3rd/jsmn/jsmn.h new file mode 100755 index 0000000..5a5200e --- /dev/null +++ b/3rd/jsmn/jsmn.h @@ -0,0 +1,76 @@ +#ifndef __JSMN_H_ +#define __JSMN_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * JSON type identifier. Basic types are: + * o Object + * o Array + * o String + * o Other primitive: number, boolean (true/false) or null + */ +typedef enum { + JSMN_UNDEFINED = 0, + JSMN_OBJECT = 1, + JSMN_ARRAY = 2, + JSMN_STRING = 3, + JSMN_PRIMITIVE = 4 +} jsmntype_t; + +enum jsmnerr { + /* Not enough tokens were provided */ + JSMN_ERROR_NOMEM = -1, + /* Invalid character inside JSON string */ + JSMN_ERROR_INVAL = -2, + /* The string is not a full JSON packet, more bytes expected */ + JSMN_ERROR_PART = -3 +}; + +/** + * JSON token description. + * type type (object, array, string etc.) + * start start position in JSON data string + * end end position in JSON data string + */ +typedef struct { + jsmntype_t type; + int start; + int end; + int size; +#ifdef JSMN_PARENT_LINKS + int parent; +#endif +} jsmntok_t; + +/** + * JSON parser. Contains an array of token blocks available. Also stores + * the string being parsed now and current position in that string + */ +typedef struct { + unsigned int pos; /* offset in the JSON string */ + unsigned int toknext; /* next token to allocate */ + int toksuper; /* superior token node, e.g parent object or array */ +} jsmn_parser; + +/** + * Create JSON parser over an array of tokens + */ +void jsmn_init(jsmn_parser *parser); + +/** + * Run JSON parser. It parses a JSON data string into and array of tokens, each describing + * a single JSON object. + */ +int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, + jsmntok_t *tokens, unsigned int num_tokens); + +#ifdef __cplusplus +} +#endif + +#endif /* __JSMN_H_ */ diff --git a/3rd/jsmn/library.json b/3rd/jsmn/library.json new file mode 100755 index 0000000..8e2f5c2 --- /dev/null +++ b/3rd/jsmn/library.json @@ -0,0 +1,16 @@ +{ + "name": "jsmn", + "keywords": "json", + "description": "Minimalistic JSON parser/tokenizer in C. It can be easily integrated into resource-limited or embedded projects", + "repository": + { + "type": "git", + "url": "https://github.com/zserge/jsmn.git" + }, + "frameworks": "*", + "platforms": "*", + "examples": [ + "example/*.c" + ], + "exclude": "test" +} diff --git a/3rd/jsmn/test/test.h b/3rd/jsmn/test/test.h new file mode 100755 index 0000000..35f704f --- /dev/null +++ b/3rd/jsmn/test/test.h @@ -0,0 +1,27 @@ +#ifndef __TEST_H__ +#define __TEST_H__ + +static int test_passed = 0; +static int test_failed = 0; + +/* Terminate current test with error */ +#define fail() return __LINE__ + +/* Successful end of the test case */ +#define done() return 0 + +/* Check single condition */ +#define check(cond) do { if (!(cond)) fail(); } while (0) + +/* Test runner */ +static void test(int (*func)(void), const char *name) { + int r = func(); + if (r == 0) { + test_passed++; + } else { + test_failed++; + printf("FAILED: %s (at line %d)\n", name, r); + } +} + +#endif /* __TEST_H__ */ diff --git a/3rd/jsmn/test/tests.c b/3rd/jsmn/test/tests.c new file mode 100755 index 0000000..d5f0c53 --- /dev/null +++ b/3rd/jsmn/test/tests.c @@ -0,0 +1,398 @@ +#include +#include +#include +#include + +#include "test.h" +#include "testutil.h" + +int test_empty(void) { + check(parse("{}", 1, 1, + JSMN_OBJECT, 0, 2, 0)); + check(parse("[]", 1, 1, + JSMN_ARRAY, 0, 2, 0)); + check(parse("[{},{}]", 3, 3, + JSMN_ARRAY, 0, 7, 2, + JSMN_OBJECT, 1, 3, 0, + JSMN_OBJECT, 4, 6, 0)); + return 0; +} + +int test_object(void) { + check(parse("{\"a\":0}", 3, 3, + JSMN_OBJECT, 0, 7, 1, + JSMN_STRING, "a", 1, + JSMN_PRIMITIVE, "0")); + check(parse("{\"a\":[]}", 3, 3, + JSMN_OBJECT, 0, 8, 1, + JSMN_STRING, "a", 1, + JSMN_ARRAY, 5, 7, 0)); + check(parse("{\"a\":{},\"b\":{}}", 5, 5, + JSMN_OBJECT, -1, -1, 2, + JSMN_STRING, "a", 1, + JSMN_OBJECT, -1, -1, 0, + JSMN_STRING, "b", 1, + JSMN_OBJECT, -1, -1, 0)); + check(parse("{\n \"Day\": 26,\n \"Month\": 9,\n \"Year\": 12\n }", 7, 7, + JSMN_OBJECT, -1, -1, 3, + JSMN_STRING, "Day", 1, + JSMN_PRIMITIVE, "26", + JSMN_STRING, "Month", 1, + JSMN_PRIMITIVE, "9", + JSMN_STRING, "Year", 1, + JSMN_PRIMITIVE, "12")); + check(parse("{\"a\": 0, \"b\": \"c\"}", 5, 5, + JSMN_OBJECT, -1, -1, 2, + JSMN_STRING, "a", 1, + JSMN_PRIMITIVE, "0", + JSMN_STRING, "b", 1, + JSMN_STRING, "c", 0)); + +#ifdef JSMN_STRICT + check(parse("{\"a\"\n0}", JSMN_ERROR_INVAL, 3)); + check(parse("{\"a\", 0}", JSMN_ERROR_INVAL, 3)); + check(parse("{\"a\": {2}}", JSMN_ERROR_INVAL, 3)); + check(parse("{\"a\": {2: 3}}", JSMN_ERROR_INVAL, 3)); + check(parse("{\"a\": {\"a\": 2 3}}", JSMN_ERROR_INVAL, 5)); + /* FIXME */ + /*check(parse("{\"a\"}", JSMN_ERROR_INVAL, 2));*/ + /*check(parse("{\"a\": 1, \"b\"}", JSMN_ERROR_INVAL, 4));*/ + /*check(parse("{\"a\",\"b\":1}", JSMN_ERROR_INVAL, 4));*/ + /*check(parse("{\"a\":1,}", JSMN_ERROR_INVAL, 4));*/ + /*check(parse("{\"a\":\"b\":\"c\"}", JSMN_ERROR_INVAL, 4));*/ + /*check(parse("{,}", JSMN_ERROR_INVAL, 4));*/ +#endif + return 0; +} + +int test_array(void) { + /* FIXME */ + /*check(parse("[10}", JSMN_ERROR_INVAL, 3));*/ + /*check(parse("[1,,3]", JSMN_ERROR_INVAL, 3)*/ + check(parse("[10]", 2, 2, + JSMN_ARRAY, -1, -1, 1, + JSMN_PRIMITIVE, "10")); + check(parse("{\"a\": 1]", JSMN_ERROR_INVAL, 3)); + /* FIXME */ + /*check(parse("[\"a\": 1]", JSMN_ERROR_INVAL, 3));*/ + return 0; +} + +int test_primitive(void) { + check(parse("{\"boolVar\" : true }", 3, 3, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "boolVar", 1, + JSMN_PRIMITIVE, "true")); + check(parse("{\"boolVar\" : false }", 3, 3, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "boolVar", 1, + JSMN_PRIMITIVE, "false")); + check(parse("{\"nullVar\" : null }", 3, 3, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "nullVar", 1, + JSMN_PRIMITIVE, "null")); + check(parse("{\"intVar\" : 12}", 3, 3, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "intVar", 1, + JSMN_PRIMITIVE, "12")); + check(parse("{\"floatVar\" : 12.345}", 3, 3, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "floatVar", 1, + JSMN_PRIMITIVE, "12.345")); + return 0; +} + +int test_string(void) { + check(parse("{\"strVar\" : \"hello world\"}", 3, 3, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "strVar", 1, + JSMN_STRING, "hello world", 0)); + check(parse("{\"strVar\" : \"escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\\"}", 3, 3, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "strVar", 1, + JSMN_STRING, "escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\", 0)); + check(parse("{\"strVar\": \"\"}", 3, 3, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "strVar", 1, + JSMN_STRING, "", 0)); + check(parse("{\"a\":\"\\uAbcD\"}", 3, 3, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "a", 1, + JSMN_STRING, "\\uAbcD", 0)); + check(parse("{\"a\":\"str\\u0000\"}", 3, 3, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "a", 1, + JSMN_STRING, "str\\u0000", 0)); + check(parse("{\"a\":\"\\uFFFFstr\"}", 3, 3, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "a", 1, + JSMN_STRING, "\\uFFFFstr", 0)); + check(parse("{\"a\":[\"\\u0280\"]}", 4, 4, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "a", 1, + JSMN_ARRAY, -1, -1, 1, + JSMN_STRING, "\\u0280", 0)); + + check(parse("{\"a\":\"str\\uFFGFstr\"}", JSMN_ERROR_INVAL, 3)); + check(parse("{\"a\":\"str\\u@FfF\"}", JSMN_ERROR_INVAL, 3)); + check(parse("{{\"a\":[\"\\u028\"]}", JSMN_ERROR_INVAL, 4)); + return 0; +} + +int test_partial_string(void) { + int i; + int r; + jsmn_parser p; + jsmntok_t tok[5]; + const char *js = "{\"x\": \"va\\\\ue\", \"y\": \"value y\"}"; + + jsmn_init(&p); + for (i = 1; i <= strlen(js); i++) { + r = jsmn_parse(&p, js, i, tok, sizeof(tok)/sizeof(tok[0])); + if (i == strlen(js)) { + check(r == 5); + check(tokeq(js, tok, 5, + JSMN_OBJECT, -1, -1, 2, + JSMN_STRING, "x", 1, + JSMN_STRING, "va\\\\ue", 0, + JSMN_STRING, "y", 1, + JSMN_STRING, "value y", 0)); + } else { + check(r == JSMN_ERROR_PART); + } + } + return 0; +} + +int test_partial_array(void) { +#ifdef JSMN_STRICT + int r; + int i; + jsmn_parser p; + jsmntok_t tok[10]; + const char *js = "[ 1, true, [123, \"hello\"]]"; + + jsmn_init(&p); + for (i = 1; i <= strlen(js); i++) { + r = jsmn_parse(&p, js, i, tok, sizeof(tok)/sizeof(tok[0])); + if (i == strlen(js)) { + check(r == 6); + check(tokeq(js, tok, 6, + JSMN_ARRAY, -1, -1, 3, + JSMN_PRIMITIVE, "1", + JSMN_PRIMITIVE, "true", + JSMN_ARRAY, -1, -1, 2, + JSMN_PRIMITIVE, "123", + JSMN_STRING, "hello", 0)); + } else { + check(r == JSMN_ERROR_PART); + } + } +#endif + return 0; +} + +int test_array_nomem(void) { + int i; + int r; + jsmn_parser p; + jsmntok_t toksmall[10], toklarge[10]; + const char *js; + + js = " [ 1, true, [123, \"hello\"]]"; + + for (i = 0; i < 6; i++) { + jsmn_init(&p); + memset(toksmall, 0, sizeof(toksmall)); + memset(toklarge, 0, sizeof(toklarge)); + r = jsmn_parse(&p, js, strlen(js), toksmall, i); + check(r == JSMN_ERROR_NOMEM); + + memcpy(toklarge, toksmall, sizeof(toksmall)); + + r = jsmn_parse(&p, js, strlen(js), toklarge, 10); + check(r >= 0); + check(tokeq(js, toklarge, 4, + JSMN_ARRAY, -1, -1, 3, + JSMN_PRIMITIVE, "1", + JSMN_PRIMITIVE, "true", + JSMN_ARRAY, -1, -1, 2, + JSMN_PRIMITIVE, "123", + JSMN_STRING, "hello", 0)); + } + return 0; +} + +int test_unquoted_keys(void) { +#ifndef JSMN_STRICT + int r; + jsmn_parser p; + jsmntok_t tok[10]; + const char *js; + + jsmn_init(&p); + js = "key1: \"value\"\nkey2 : 123"; + + r = jsmn_parse(&p, js, strlen(js), tok, 10); + check(r >= 0); + check(tokeq(js, tok, 4, + JSMN_PRIMITIVE, "key1", + JSMN_STRING, "value", 0, + JSMN_PRIMITIVE, "key2", + JSMN_PRIMITIVE, "123")); +#endif + return 0; +} + +int test_issue_22(void) { + int r; + jsmn_parser p; + jsmntok_t tokens[128]; + const char *js; + + js = "{ \"height\":10, \"layers\":[ { \"data\":[6,6], \"height\":10, " + "\"name\":\"Calque de Tile 1\", \"opacity\":1, \"type\":\"tilelayer\", " + "\"visible\":true, \"width\":10, \"x\":0, \"y\":0 }], " + "\"orientation\":\"orthogonal\", \"properties\": { }, \"tileheight\":32, " + "\"tilesets\":[ { \"firstgid\":1, \"image\":\"..\\/images\\/tiles.png\", " + "\"imageheight\":64, \"imagewidth\":160, \"margin\":0, \"name\":\"Tiles\", " + "\"properties\":{}, \"spacing\":0, \"tileheight\":32, \"tilewidth\":32 }], " + "\"tilewidth\":32, \"version\":1, \"width\":10 }"; + jsmn_init(&p); + r = jsmn_parse(&p, js, strlen(js), tokens, 128); + check(r >= 0); + return 0; +} + +int test_issue_27(void) { + const char *js = + "{ \"name\" : \"Jack\", \"age\" : 27 } { \"name\" : \"Anna\", "; + check(parse(js, JSMN_ERROR_PART, 8)); + return 0; +} + +int test_input_length(void) { + const char *js; + int r; + jsmn_parser p; + jsmntok_t tokens[10]; + + js = "{\"a\": 0}garbage"; + + jsmn_init(&p); + r = jsmn_parse(&p, js, 8, tokens, 10); + check(r == 3); + check(tokeq(js, tokens, 3, + JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "a", 1, + JSMN_PRIMITIVE, "0")); + return 0; +} + +int test_count(void) { + jsmn_parser p; + const char *js; + + js = "{}"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1); + + js = "[]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1); + + js = "[[]]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 2); + + js = "[[], []]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3); + + js = "[[], []]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3); + + js = "[[], [[]], [[], []]]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7); + + js = "[\"a\", [[], []]]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5); + + js = "[[], \"[], [[]]\", [[]]]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5); + + js = "[1, 2, 3]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 4); + + js = "[1, 2, [3, \"a\"], null]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7); + + return 0; +} + + +int test_nonstrict(void) { +#ifndef JSMN_STRICT + const char *js; + js = "a: 0garbage"; + check(parse(js, 2, 2, + JSMN_PRIMITIVE, "a", + JSMN_PRIMITIVE, "0garbage")); + + js = "Day : 26\nMonth : Sep\n\nYear: 12"; + check(parse(js, 6, 6, + JSMN_PRIMITIVE, "Day", + JSMN_PRIMITIVE, "26", + JSMN_PRIMITIVE, "Month", + JSMN_PRIMITIVE, "Sep", + JSMN_PRIMITIVE, "Year", + JSMN_PRIMITIVE, "12")); +#endif + return 0; +} + +int test_unmatched_brackets(void) { + const char *js; + js = "\"key 1\": 1234}"; + check(parse(js, JSMN_ERROR_INVAL, 2)); + js = "{\"key 1\": 1234"; + check(parse(js, JSMN_ERROR_PART, 3)); + js = "{\"key 1\": 1234}}"; + check(parse(js, JSMN_ERROR_INVAL, 3)); + js = "\"key 1\"}: 1234"; + check(parse(js, JSMN_ERROR_INVAL, 3)); + js = "\"key {1\": 1234"; + check(parse(js, 2, 2, + JSMN_STRING, "key {1", 1, + JSMN_PRIMITIVE, "1234")); + js = "{{\"key 1\": 1234}"; + check(parse(js, JSMN_ERROR_PART, 4)); + return 0; +} + +int main(void) { + test(test_empty, "test for a empty JSON objects/arrays"); + test(test_object, "test for a JSON objects"); + test(test_array, "test for a JSON arrays"); + test(test_primitive, "test primitive JSON data types"); + test(test_string, "test string JSON data types"); + + test(test_partial_string, "test partial JSON string parsing"); + test(test_partial_array, "test partial array reading"); + test(test_array_nomem, "test array reading with a smaller number of tokens"); + test(test_unquoted_keys, "test unquoted keys (like in JavaScript)"); + test(test_input_length, "test strings that are not null-terminated"); + test(test_issue_22, "test issue #22"); + test(test_issue_27, "test issue #27"); + test(test_count, "test tokens count estimation"); + test(test_nonstrict, "test for non-strict mode"); + test(test_unmatched_brackets, "test for unmatched brackets"); + printf("\nPASSED: %d\nFAILED: %d\n", test_passed, test_failed); + return (test_failed > 0); +} diff --git a/3rd/jsmn/test/testutil.h b/3rd/jsmn/test/testutil.h new file mode 100755 index 0000000..9a1eb2d --- /dev/null +++ b/3rd/jsmn/test/testutil.h @@ -0,0 +1,94 @@ +#ifndef __TEST_UTIL_H__ +#define __TEST_UTIL_H__ + +#include "../jsmn.c" + +static int vtokeq(const char *s, jsmntok_t *t, int numtok, va_list ap) { + if (numtok > 0) { + int i, start, end, size; + int type; + char *value; + + size = -1; + value = NULL; + for (i = 0; i < numtok; i++) { + type = va_arg(ap, int); + if (type == JSMN_STRING) { + value = va_arg(ap, char *); + size = va_arg(ap, int); + start = end = -1; + } else if (type == JSMN_PRIMITIVE) { + value = va_arg(ap, char *); + start = end = size = -1; + } else { + start = va_arg(ap, int); + end = va_arg(ap, int); + size = va_arg(ap, int); + value = NULL; + } + if (t[i].type != type) { + printf("token %d type is %d, not %d\n", i, t[i].type, type); + return 0; + } + if (start != -1 && end != -1) { + if (t[i].start != start) { + printf("token %d start is %d, not %d\n", i, t[i].start, start); + return 0; + } + if (t[i].end != end ) { + printf("token %d end is %d, not %d\n", i, t[i].end, end); + return 0; + } + } + if (size != -1 && t[i].size != size) { + printf("token %d size is %d, not %d\n", i, t[i].size, size); + return 0; + } + + if (s != NULL && value != NULL) { + const char *p = s + t[i].start; + if (strlen(value) != t[i].end - t[i].start || + strncmp(p, value, t[i].end - t[i].start) != 0) { + printf("token %d value is %.*s, not %s\n", i, t[i].end-t[i].start, + s+t[i].start, value); + return 0; + } + } + } + } + return 1; +} + +static int tokeq(const char *s, jsmntok_t *tokens, int numtok, ...) { + int ok; + va_list args; + va_start(args, numtok); + ok = vtokeq(s, tokens, numtok, args); + va_end(args); + return ok; +} + +static int parse(const char *s, int status, int numtok, ...) { + int r; + int ok = 1; + va_list args; + jsmn_parser p; + jsmntok_t *t = malloc(numtok * sizeof(jsmntok_t)); + + jsmn_init(&p); + r = jsmn_parse(&p, s, strlen(s), t, numtok); + if (r != status) { + printf("status is %d, not %d\n", r, status); + return 0; + } + + if (status >= 0) { + va_start(args, numtok); + ok = vtokeq(s, t, numtok, args); + va_end(args); + } + free(t); + return ok; +} + +#endif /* __TEST_UTIL_H__ */ diff --git a/3rd/lua-5.3.4/Makefile b/3rd/lua-5.3.4/Makefile new file mode 100644 index 0000000..7288746 --- /dev/null +++ b/3rd/lua-5.3.4/Makefile @@ -0,0 +1,197 @@ +# Makefile for building Lua +# See ../doc/readme.html for installation and customization instructions. + +# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= + +# Your platform. See PLATS for possible values. +PLAT= none + +CC= gcc -std=gnu99 +CFLAGS= -O2 -g -Wall -Wextra -DLUA_COMPAT_5_2 -fPIC $(SYSCFLAGS) $(MYCFLAGS) +LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) +LIBS= -lm $(SYSLIBS) $(MYLIBS) + +AR= ar rcu +RANLIB= ranlib +RM= rm -f + +SYSCFLAGS= +SYSLDFLAGS= +SYSLIBS= + +MYCFLAGS= +MYLDFLAGS= +MYLIBS= +MYOBJS= + +# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= + +PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris + +LUA_A= liblua.a +CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ + lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ + ltm.o lundump.o lvm.o lzio.o +LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ + lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o +BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) + +LUA_T= lua +LUA_O= lua.o + +LUAC_T= luac +LUAC_O= luac.o + +ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O) +ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) +ALL_A= $(LUA_A) + +# Targets start here. +default: $(PLAT) + +all: $(ALL_T) + +o: $(ALL_O) + +a: $(ALL_A) + +$(LUA_A): $(BASE_O) + $(AR) $@ $(BASE_O) + $(RANLIB) $@ + +$(LUA_T): $(LUA_O) $(LUA_A) + $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) + +$(LUAC_T): $(LUAC_O) $(LUA_A) + $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) + +clean: + $(RM) $(ALL_T) $(ALL_O) + +depend: + @$(CC) $(CFLAGS) -MM l*.c + +echo: + @echo "PLAT= $(PLAT)" + @echo "CC= $(CC)" + @echo "CFLAGS= $(CFLAGS)" + @echo "LDFLAGS= $(SYSLDFLAGS)" + @echo "LIBS= $(LIBS)" + @echo "AR= $(AR)" + @echo "RANLIB= $(RANLIB)" + @echo "RM= $(RM)" + +# Convenience targets for popular platforms +ALL= all + +none: + @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" + @echo " $(PLATS)" + +aix: + $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" + +bsd: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" + +c89: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_C89" CC="gcc -std=c89" + @echo '' + @echo '*** C89 does not guarantee 64-bit integers for Lua.' + @echo '' + + +freebsd: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline" + +generic: $(ALL) + +linux: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline" + +macosx: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" CC=cc + +mingw: + $(MAKE) "LUA_A=lua53.dll" "LUA_T=lua.exe" \ + "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ + "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe + $(MAKE) "LUAC_T=luac.exe" luac.exe + +posix: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" + +solaris: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN -D_REENTRANT" SYSLIBS="-ldl" + +# list targets that do not create files (but not all makes understand .PHONY) +.PHONY: all $(PLATS) default o a clean depend echo none + +# DO NOT DELETE + +lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ + lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \ + ltable.h lundump.h lvm.h +lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h +lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ + llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ + ldo.h lgc.h lstring.h ltable.h lvm.h +lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h +ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ + lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \ + ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h +ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ + lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \ + lparser.h lstring.h ltable.h lundump.h lvm.h +ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \ + ltm.h lzio.h lmem.h lundump.h +lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \ + lgc.h lstate.h ltm.h lzio.h lmem.h +lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h +linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h +liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \ + lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \ + lstring.h ltable.h +lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h +loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \ + ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \ + lvm.h +lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h +loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ + llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ + ldo.h lfunc.h lstring.h lgc.h ltable.h +lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ + lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \ + lstring.h ltable.h +lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ + lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h +lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h +ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h +lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h lobject.h llimits.h \ + lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h +lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ + lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \ + lundump.h +lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \ + ltable.h lvm.h +lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \ + lobject.h ltm.h lzio.h + +# (end of Makefile) diff --git a/3rd/lua-5.3.4/lapi.c b/3rd/lua-5.3.4/lapi.c new file mode 100644 index 0000000..c9455a5 --- /dev/null +++ b/3rd/lua-5.3.4/lapi.c @@ -0,0 +1,1298 @@ +/* +** $Id: lapi.c,v 2.259 2016/02/29 14:27:14 roberto Exp $ +** Lua API +** See Copyright Notice in lua.h +*/ + +#define lapi_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" + + + +const char lua_ident[] = + "$LuaVersion: " LUA_COPYRIGHT " $" + "$LuaAuthors: " LUA_AUTHORS " $"; + + +/* value at a non-valid index */ +#define NONVALIDVALUE cast(TValue *, luaO_nilobject) + +/* corresponding test */ +#define isvalid(o) ((o) != luaO_nilobject) + +/* test for pseudo index */ +#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) + +/* test for upvalue */ +#define isupvalue(i) ((i) < LUA_REGISTRYINDEX) + +/* test for valid but not pseudo index */ +#define isstackindex(i, o) (isvalid(o) && !ispseudo(i)) + +#define api_checkvalidindex(l,o) api_check(l, isvalid(o), "invalid index") + +#define api_checkstackindex(l, i, o) \ + api_check(l, isstackindex(i, o), "index not in the stack") + + +static TValue *index2addr (lua_State *L, int idx) { + CallInfo *ci = L->ci; + if (idx > 0) { + TValue *o = ci->func + idx; + api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index"); + if (o >= L->top) return NONVALIDVALUE; + else return o; + } + else if (!ispseudo(idx)) { /* negative index */ + api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); + return L->top + idx; + } + else if (idx == LUA_REGISTRYINDEX) + return &G(L)->l_registry; + else { /* upvalues */ + idx = LUA_REGISTRYINDEX - idx; + api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); + if (ttislcf(ci->func)) /* light C function? */ + return NONVALIDVALUE; /* it has no upvalues */ + else { + CClosure *func = clCvalue(ci->func); + return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE; + } + } +} + + +/* +** to be called by 'lua_checkstack' in protected mode, to grow stack +** capturing memory errors +*/ +static void growstack (lua_State *L, void *ud) { + int size = *(int *)ud; + luaD_growstack(L, size); +} + + +LUA_API int lua_checkstack (lua_State *L, int n) { + int res; + CallInfo *ci = L->ci; + lua_lock(L); + api_check(L, n >= 0, "negative 'n'"); + if (L->stack_last - L->top > n) /* stack large enough? */ + res = 1; /* yes; check is OK */ + else { /* no; need to grow stack */ + int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; + if (inuse > LUAI_MAXSTACK - n) /* can grow without overflow? */ + res = 0; /* no */ + else /* try to grow stack */ + res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK); + } + if (res && ci->top < L->top + n) + ci->top = L->top + n; /* adjust frame top */ + lua_unlock(L); + return res; +} + + +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { + int i; + if (from == to) return; + lua_lock(to); + api_checknelems(from, n); + api_check(from, G(from) == G(to), "moving among independent states"); + api_check(from, to->ci->top - to->top >= n, "stack overflow"); + from->top -= n; + for (i = 0; i < n; i++) { + setobj2s(to, to->top, from->top + i); + to->top++; /* stack already checked by previous 'api_check' */ + } + lua_unlock(to); +} + + +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; +} + + +LUA_API const lua_Number *lua_version (lua_State *L) { + static const lua_Number version = LUA_VERSION_NUM; + if (L == NULL) return &version; + else return G(L)->version; +} + + + +/* +** basic stack manipulation +*/ + + +/* +** convert an acceptable stack index into an absolute index +*/ +LUA_API int lua_absindex (lua_State *L, int idx) { + return (idx > 0 || ispseudo(idx)) + ? idx + : cast_int(L->top - L->ci->func) + idx; +} + + +LUA_API int lua_gettop (lua_State *L) { + return cast_int(L->top - (L->ci->func + 1)); +} + + +LUA_API void lua_settop (lua_State *L, int idx) { + StkId func = L->ci->func; + lua_lock(L); + if (idx >= 0) { + api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); + while (L->top < (func + 1) + idx) + setnilvalue(L->top++); + L->top = (func + 1) + idx; + } + else { + api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top"); + L->top += idx+1; /* 'subtract' index (index is negative) */ + } + lua_unlock(L); +} + + +/* +** Reverse the stack segment from 'from' to 'to' +** (auxiliary to 'lua_rotate') +*/ +static void reverse (lua_State *L, StkId from, StkId to) { + for (; from < to; from++, to--) { + TValue temp; + setobj(L, &temp, from); + setobjs2s(L, from, to); + setobj2s(L, to, &temp); + } +} + + +/* +** Let x = AB, where A is a prefix of length 'n'. Then, +** rotate x n == BA. But BA == (A^r . B^r)^r. +*/ +LUA_API void lua_rotate (lua_State *L, int idx, int n) { + StkId p, t, m; + lua_lock(L); + t = L->top - 1; /* end of stack segment being rotated */ + p = index2addr(L, idx); /* start of segment */ + api_checkstackindex(L, idx, p); + api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'"); + m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */ + reverse(L, p, m); /* reverse the prefix with length 'n' */ + reverse(L, m + 1, t); /* reverse the suffix */ + reverse(L, p, t); /* reverse the entire segment */ + lua_unlock(L); +} + + +LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { + TValue *fr, *to; + lua_lock(L); + fr = index2addr(L, fromidx); + to = index2addr(L, toidx); + api_checkvalidindex(L, to); + setobj(L, to, fr); + if (isupvalue(toidx)) /* function upvalue? */ + luaC_barrier(L, clCvalue(L->ci->func), fr); + /* LUA_REGISTRYINDEX does not need gc barrier + (collector revisits it before finishing collection) */ + lua_unlock(L); +} + + +LUA_API void lua_pushvalue (lua_State *L, int idx) { + lua_lock(L); + setobj2s(L, L->top, index2addr(L, idx)); + api_incr_top(L); + lua_unlock(L); +} + + + +/* +** access functions (stack -> C) +*/ + + +LUA_API int lua_type (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + return (isvalid(o) ? ttnov(o) : LUA_TNONE); +} + + +LUA_API const char *lua_typename (lua_State *L, int t) { + UNUSED(L); + api_check(L, LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag"); + return ttypename(t); +} + + +LUA_API int lua_iscfunction (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + return (ttislcf(o) || (ttisCclosure(o))); +} + + +LUA_API int lua_isinteger (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + return ttisinteger(o); +} + + +LUA_API int lua_isnumber (lua_State *L, int idx) { + lua_Number n; + const TValue *o = index2addr(L, idx); + return tonumber(o, &n); +} + + +LUA_API int lua_isstring (lua_State *L, int idx) { + const TValue *o = index2addr(L, idx); + return (ttisstring(o) || cvt2str(o)); +} + + +LUA_API int lua_isuserdata (lua_State *L, int idx) { + const TValue *o = index2addr(L, idx); + return (ttisfulluserdata(o) || ttislightuserdata(o)); +} + + +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { + StkId o1 = index2addr(L, index1); + StkId o2 = index2addr(L, index2); + return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0; +} + + +LUA_API void lua_arith (lua_State *L, int op) { + lua_lock(L); + if (op != LUA_OPUNM && op != LUA_OPBNOT) + api_checknelems(L, 2); /* all other operations expect two operands */ + else { /* for unary operations, add fake 2nd operand */ + api_checknelems(L, 1); + setobjs2s(L, L->top, L->top - 1); + api_incr_top(L); + } + /* first operand at top - 2, second at top - 1; result go to top - 2 */ + luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2); + L->top--; /* remove second operand */ + lua_unlock(L); +} + + +LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { + StkId o1, o2; + int i = 0; + lua_lock(L); /* may call tag method */ + o1 = index2addr(L, index1); + o2 = index2addr(L, index2); + if (isvalid(o1) && isvalid(o2)) { + switch (op) { + case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break; + case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break; + case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break; + default: api_check(L, 0, "invalid option"); + } + } + lua_unlock(L); + return i; +} + + +LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) { + size_t sz = luaO_str2num(s, L->top); + if (sz != 0) + api_incr_top(L); + return sz; +} + + +LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) { + lua_Number n; + const TValue *o = index2addr(L, idx); + int isnum = tonumber(o, &n); + if (!isnum) + n = 0; /* call to 'tonumber' may change 'n' even if it fails */ + if (pisnum) *pisnum = isnum; + return n; +} + + +LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) { + lua_Integer res; + const TValue *o = index2addr(L, idx); + int isnum = tointeger(o, &res); + if (!isnum) + res = 0; /* call to 'tointeger' may change 'n' even if it fails */ + if (pisnum) *pisnum = isnum; + return res; +} + + +LUA_API int lua_toboolean (lua_State *L, int idx) { + const TValue *o = index2addr(L, idx); + return !l_isfalse(o); +} + + +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { + StkId o = index2addr(L, idx); + if (!ttisstring(o)) { + if (!cvt2str(o)) { /* not convertible? */ + if (len != NULL) *len = 0; + return NULL; + } + lua_lock(L); /* 'luaO_tostring' may create a new string */ + luaO_tostring(L, o); + luaC_checkGC(L); + o = index2addr(L, idx); /* previous call may reallocate the stack */ + lua_unlock(L); + } + if (len != NULL) + *len = vslen(o); + return svalue(o); +} + + +LUA_API size_t lua_rawlen (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + switch (ttype(o)) { + case LUA_TSHRSTR: return tsvalue(o)->shrlen; + case LUA_TLNGSTR: return tsvalue(o)->u.lnglen; + case LUA_TUSERDATA: return uvalue(o)->len; + case LUA_TTABLE: return luaH_getn(hvalue(o)); + default: return 0; + } +} + + +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + if (ttislcf(o)) return fvalue(o); + else if (ttisCclosure(o)) + return clCvalue(o)->f; + else return NULL; /* not a C function */ +} + + +LUA_API void *lua_touserdata (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + switch (ttnov(o)) { + case LUA_TUSERDATA: return getudatamem(uvalue(o)); + case LUA_TLIGHTUSERDATA: return pvalue(o); + default: return NULL; + } +} + + +LUA_API lua_State *lua_tothread (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); +} + + +LUA_API const void *lua_topointer (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + switch (ttype(o)) { + case LUA_TTABLE: return hvalue(o); + case LUA_TLCL: return clLvalue(o); + case LUA_TCCL: return clCvalue(o); + case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); + case LUA_TTHREAD: return thvalue(o); + case LUA_TUSERDATA: return getudatamem(uvalue(o)); + case LUA_TLIGHTUSERDATA: return pvalue(o); + default: return NULL; + } +} + + + +/* +** push functions (C -> stack) +*/ + + +LUA_API void lua_pushnil (lua_State *L) { + lua_lock(L); + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { + lua_lock(L); + setfltvalue(L->top, n); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { + lua_lock(L); + setivalue(L->top, n); + api_incr_top(L); + lua_unlock(L); +} + + +/* +** Pushes on the stack a string with given length. Avoid using 's' when +** 'len' == 0 (as 's' can be NULL in that case), due to later use of +** 'memcmp' and 'memcpy'. +*/ +LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { + TString *ts; + lua_lock(L); + ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len); + setsvalue2s(L, L->top, ts); + api_incr_top(L); + luaC_checkGC(L); + lua_unlock(L); + return getstr(ts); +} + + +LUA_API const char *lua_pushstring (lua_State *L, const char *s) { + lua_lock(L); + if (s == NULL) + setnilvalue(L->top); + else { + TString *ts; + ts = luaS_new(L, s); + setsvalue2s(L, L->top, ts); + s = getstr(ts); /* internal copy's address */ + } + api_incr_top(L); + luaC_checkGC(L); + lua_unlock(L); + return s; +} + + +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, + va_list argp) { + const char *ret; + lua_lock(L); + ret = luaO_pushvfstring(L, fmt, argp); + luaC_checkGC(L); + lua_unlock(L); + return ret; +} + + +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { + const char *ret; + va_list argp; + lua_lock(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + luaC_checkGC(L); + lua_unlock(L); + return ret; +} + + +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { + lua_lock(L); + if (n == 0) { + setfvalue(L->top, fn); + } + else { + CClosure *cl; + api_checknelems(L, n); + api_check(L, n <= MAXUPVAL, "upvalue index too large"); + cl = luaF_newCclosure(L, n); + cl->f = fn; + L->top -= n; + while (n--) { + setobj2n(L, &cl->upvalue[n], L->top + n); + /* does not need barrier because closure is white */ + } + setclCvalue(L, L->top, cl); + } + api_incr_top(L); + luaC_checkGC(L); + lua_unlock(L); +} + + +LUA_API void lua_pushboolean (lua_State *L, int b) { + lua_lock(L); + setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { + lua_lock(L); + setpvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_pushthread (lua_State *L) { + lua_lock(L); + setthvalue(L, L->top, L); + api_incr_top(L); + lua_unlock(L); + return (G(L)->mainthread == L); +} + + + +/* +** get functions (Lua -> stack) +*/ + + +static int auxgetstr (lua_State *L, const TValue *t, const char *k) { + const TValue *slot; + TString *str = luaS_new(L, k); + if (luaV_fastget(L, t, str, slot, luaH_getstr)) { + setobj2s(L, L->top, slot); + api_incr_top(L); + } + else { + setsvalue2s(L, L->top, str); + api_incr_top(L); + luaV_finishget(L, t, L->top - 1, L->top - 1, slot); + } + lua_unlock(L); + return ttnov(L->top - 1); +} + + +LUA_API int lua_getglobal (lua_State *L, const char *name) { + Table *reg = hvalue(&G(L)->l_registry); + lua_lock(L); + return auxgetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name); +} + + +LUA_API int lua_gettable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); + return ttnov(L->top - 1); +} + + +LUA_API int lua_getfield (lua_State *L, int idx, const char *k) { + lua_lock(L); + return auxgetstr(L, index2addr(L, idx), k); +} + + +LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { + StkId t; + const TValue *slot; + lua_lock(L); + t = index2addr(L, idx); + if (luaV_fastget(L, t, n, slot, luaH_getint)) { + setobj2s(L, L->top, slot); + api_incr_top(L); + } + else { + setivalue(L->top, n); + api_incr_top(L); + luaV_finishget(L, t, L->top - 1, L->top - 1, slot); + } + lua_unlock(L); + return ttnov(L->top - 1); +} + + +LUA_API int lua_rawget (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); + lua_unlock(L); + return ttnov(L->top - 1); +} + + +LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setobj2s(L, L->top, luaH_getint(hvalue(t), n)); + api_incr_top(L); + lua_unlock(L); + return ttnov(L->top - 1); +} + + +LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) { + StkId t; + TValue k; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setpvalue(&k, cast(void *, p)); + setobj2s(L, L->top, luaH_get(hvalue(t), &k)); + api_incr_top(L); + lua_unlock(L); + return ttnov(L->top - 1); +} + + +LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { + Table *t; + lua_lock(L); + t = luaH_new(L); + sethvalue(L, L->top, t); + api_incr_top(L); + if (narray > 0 || nrec > 0) + luaH_resize(L, t, narray, nrec); + luaC_checkGC(L); + lua_unlock(L); +} + + +LUA_API int lua_getmetatable (lua_State *L, int objindex) { + const TValue *obj; + Table *mt; + int res = 0; + lua_lock(L); + obj = index2addr(L, objindex); + switch (ttnov(obj)) { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + default: + mt = G(L)->mt[ttnov(obj)]; + break; + } + if (mt != NULL) { + sethvalue(L, L->top, mt); + api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API int lua_getuservalue (lua_State *L, int idx) { + StkId o; + lua_lock(L); + o = index2addr(L, idx); + api_check(L, ttisfulluserdata(o), "full userdata expected"); + getuservalue(L, uvalue(o), L->top); + api_incr_top(L); + lua_unlock(L); + return ttnov(L->top - 1); +} + + +/* +** set functions (stack -> Lua) +*/ + +/* +** t[k] = value at the top of the stack (where 'k' is a string) +*/ +static void auxsetstr (lua_State *L, const TValue *t, const char *k) { + const TValue *slot; + TString *str = luaS_new(L, k); + api_checknelems(L, 1); + if (luaV_fastset(L, t, str, slot, luaH_getstr, L->top - 1)) + L->top--; /* pop value */ + else { + setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */ + api_incr_top(L); + luaV_finishset(L, t, L->top - 1, L->top - 2, slot); + L->top -= 2; /* pop value and key */ + } + lua_unlock(L); /* lock done by caller */ +} + + +LUA_API void lua_setglobal (lua_State *L, const char *name) { + Table *reg = hvalue(&G(L)->l_registry); + lua_lock(L); /* unlock done in 'auxsetstr' */ + auxsetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name); +} + + +LUA_API void lua_settable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2addr(L, idx); + luaV_settable(L, t, L->top - 2, L->top - 1); + L->top -= 2; /* pop index and value */ + lua_unlock(L); +} + + +LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { + lua_lock(L); /* unlock done in 'auxsetstr' */ + auxsetstr(L, index2addr(L, idx), k); +} + + +LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { + StkId t; + const TValue *slot; + lua_lock(L); + api_checknelems(L, 1); + t = index2addr(L, idx); + if (luaV_fastset(L, t, n, slot, luaH_getint, L->top - 1)) + L->top--; /* pop value */ + else { + setivalue(L->top, n); + api_incr_top(L); + luaV_finishset(L, t, L->top - 1, L->top - 2, slot); + L->top -= 2; /* pop value and key */ + } + lua_unlock(L); +} + + +LUA_API void lua_rawset (lua_State *L, int idx) { + StkId o; + TValue *slot; + lua_lock(L); + api_checknelems(L, 2); + o = index2addr(L, idx); + api_check(L, ttistable(o), "table expected"); + slot = luaH_set(L, hvalue(o), L->top - 2); + setobj2t(L, slot, L->top - 1); + invalidateTMcache(hvalue(o)); + luaC_barrierback(L, hvalue(o), L->top-1); + L->top -= 2; + lua_unlock(L); +} + + +LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) { + StkId o; + lua_lock(L); + api_checknelems(L, 1); + o = index2addr(L, idx); + api_check(L, ttistable(o), "table expected"); + luaH_setint(L, hvalue(o), n, L->top - 1); + luaC_barrierback(L, hvalue(o), L->top-1); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { + StkId o; + TValue k, *slot; + lua_lock(L); + api_checknelems(L, 1); + o = index2addr(L, idx); + api_check(L, ttistable(o), "table expected"); + setpvalue(&k, cast(void *, p)); + slot = luaH_set(L, hvalue(o), &k); + setobj2t(L, slot, L->top - 1); + luaC_barrierback(L, hvalue(o), L->top - 1); + L->top--; + lua_unlock(L); +} + + +LUA_API int lua_setmetatable (lua_State *L, int objindex) { + TValue *obj; + Table *mt; + lua_lock(L); + api_checknelems(L, 1); + obj = index2addr(L, objindex); + if (ttisnil(L->top - 1)) + mt = NULL; + else { + api_check(L, ttistable(L->top - 1), "table expected"); + mt = hvalue(L->top - 1); + } + switch (ttnov(obj)) { + case LUA_TTABLE: { + hvalue(obj)->metatable = mt; + if (mt) { + luaC_objbarrier(L, gcvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } + break; + } + case LUA_TUSERDATA: { + uvalue(obj)->metatable = mt; + if (mt) { + luaC_objbarrier(L, uvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } + break; + } + default: { + G(L)->mt[ttnov(obj)] = mt; + break; + } + } + L->top--; + lua_unlock(L); + return 1; +} + + +LUA_API void lua_setuservalue (lua_State *L, int idx) { + StkId o; + lua_lock(L); + api_checknelems(L, 1); + o = index2addr(L, idx); + api_check(L, ttisfulluserdata(o), "full userdata expected"); + setuservalue(L, uvalue(o), L->top - 1); + luaC_barrier(L, gcvalue(o), L->top - 1); + L->top--; + lua_unlock(L); +} + + +/* +** 'load' and 'call' functions (run Lua code) +*/ + + +#define checkresults(L,na,nr) \ + api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \ + "results from function overflow current stack size") + + +LUA_API void lua_callk (lua_State *L, int nargs, int nresults, + lua_KContext ctx, lua_KFunction k) { + StkId func; + lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); + api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); + func = L->top - (nargs+1); + if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ + L->ci->u.c.k = k; /* save continuation */ + L->ci->u.c.ctx = ctx; /* save context */ + luaD_call(L, func, nresults); /* do the call */ + } + else /* no continuation or no yieldable */ + luaD_callnoyield(L, func, nresults); /* just do the call */ + adjustresults(L, nresults); + lua_unlock(L); +} + + + +/* +** Execute a protected call. +*/ +struct CallS { /* data to 'f_call' */ + StkId func; + int nresults; +}; + + +static void f_call (lua_State *L, void *ud) { + struct CallS *c = cast(struct CallS *, ud); + luaD_callnoyield(L, c->func, c->nresults); +} + + + +LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, + lua_KContext ctx, lua_KFunction k) { + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); + api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); + if (errfunc == 0) + func = 0; + else { + StkId o = index2addr(L, errfunc); + api_checkstackindex(L, errfunc, o); + func = savestack(L, o); + } + c.func = L->top - (nargs+1); /* function to be called */ + if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */ + c.nresults = nresults; /* do a 'conventional' protected call */ + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + } + else { /* prepare continuation (call is already protected by 'resume') */ + CallInfo *ci = L->ci; + ci->u.c.k = k; /* save continuation */ + ci->u.c.ctx = ctx; /* save context */ + /* save information for error recovery */ + ci->extra = savestack(L, c.func); + ci->u.c.old_errfunc = L->errfunc; + L->errfunc = func; + setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */ + ci->callstatus |= CIST_YPCALL; /* function can do error recovery */ + luaD_call(L, c.func, nresults); /* do the call */ + ci->callstatus &= ~CIST_YPCALL; + L->errfunc = ci->u.c.old_errfunc; + status = LUA_OK; /* if it is here, there were no errors */ + } + adjustresults(L, nresults); + lua_unlock(L); + return status; +} + + +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, + const char *chunkname, const char *mode) { + ZIO z; + int status; + lua_lock(L); + if (!chunkname) chunkname = "?"; + luaZ_init(L, &z, reader, data); + status = luaD_protectedparser(L, &z, chunkname, mode); + if (status == LUA_OK) { /* no errors? */ + LClosure *f = clLvalue(L->top - 1); /* get newly created function */ + if (f->nupvalues >= 1) { /* does it have an upvalue? */ + /* get global table from registry */ + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ + setobj(L, f->upvals[0]->v, gt); + luaC_upvalbarrier(L, f->upvals[0]); + } + } + lua_unlock(L); + return status; +} + + +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { + int status; + TValue *o; + lua_lock(L); + api_checknelems(L, 1); + o = L->top - 1; + if (isLfunction(o)) + status = luaU_dump(L, getproto(o), writer, data, strip); + else + status = 1; + lua_unlock(L); + return status; +} + + +LUA_API int lua_status (lua_State *L) { + return L->status; +} + + +/* +** Garbage-collection function +*/ + +LUA_API int lua_gc (lua_State *L, int what, int data) { + int res = 0; + global_State *g; + lua_lock(L); + g = G(L); + switch (what) { + case LUA_GCSTOP: { + g->gcrunning = 0; + break; + } + case LUA_GCRESTART: { + luaE_setdebt(g, 0); + g->gcrunning = 1; + break; + } + case LUA_GCCOLLECT: { + luaC_fullgc(L, 0); + break; + } + case LUA_GCCOUNT: { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + res = cast_int(gettotalbytes(g) >> 10); + break; + } + case LUA_GCCOUNTB: { + res = cast_int(gettotalbytes(g) & 0x3ff); + break; + } + case LUA_GCSTEP: { + l_mem debt = 1; /* =1 to signal that it did an actual step */ + lu_byte oldrunning = g->gcrunning; + g->gcrunning = 1; /* allow GC to run */ + if (data == 0) { + luaE_setdebt(g, -GCSTEPSIZE); /* to do a "small" step */ + luaC_step(L); + } + else { /* add 'data' to total debt */ + debt = cast(l_mem, data) * 1024 + g->GCdebt; + luaE_setdebt(g, debt); + luaC_checkGC(L); + } + g->gcrunning = oldrunning; /* restore previous state */ + if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */ + res = 1; /* signal it */ + break; + } + case LUA_GCSETPAUSE: { + res = g->gcpause; + g->gcpause = data; + break; + } + case LUA_GCSETSTEPMUL: { + res = g->gcstepmul; + if (data < 40) data = 40; /* avoid ridiculous low values (and 0) */ + g->gcstepmul = data; + break; + } + case LUA_GCISRUNNING: { + res = g->gcrunning; + break; + } + default: res = -1; /* invalid option */ + } + lua_unlock(L); + return res; +} + + + +/* +** miscellaneous functions +*/ + + +LUA_API int lua_error (lua_State *L) { + lua_lock(L); + api_checknelems(L, 1); + luaG_errormsg(L); + /* code unreachable; will unlock when control actually leaves the kernel */ + return 0; /* to avoid warnings */ +} + + +LUA_API int lua_next (lua_State *L, int idx) { + StkId t; + int more; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + more = luaH_next(L, hvalue(t), L->top - 1); + if (more) { + api_incr_top(L); + } + else /* no more elements */ + L->top -= 1; /* remove key */ + lua_unlock(L); + return more; +} + + +LUA_API void lua_concat (lua_State *L, int n) { + lua_lock(L); + api_checknelems(L, n); + if (n >= 2) { + luaV_concat(L, n); + } + else if (n == 0) { /* push empty string */ + setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); + api_incr_top(L); + } + /* else n == 1; nothing to do */ + luaC_checkGC(L); + lua_unlock(L); +} + + +LUA_API void lua_len (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + luaV_objlen(L, L->top, t); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { + lua_Alloc f; + lua_lock(L); + if (ud) *ud = G(L)->ud; + f = G(L)->frealloc; + lua_unlock(L); + return f; +} + + +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { + lua_lock(L); + G(L)->ud = ud; + G(L)->frealloc = f; + lua_unlock(L); +} + + +LUA_API void *lua_newuserdata (lua_State *L, size_t size) { + Udata *u; + lua_lock(L); + u = luaS_newudata(L, size); + setuvalue(L, L->top, u); + api_incr_top(L); + luaC_checkGC(L); + lua_unlock(L); + return getudatamem(u); +} + + + +static const char *aux_upvalue (StkId fi, int n, TValue **val, + CClosure **owner, UpVal **uv) { + switch (ttype(fi)) { + case LUA_TCCL: { /* C closure */ + CClosure *f = clCvalue(fi); + if (!(1 <= n && n <= f->nupvalues)) return NULL; + *val = &f->upvalue[n-1]; + if (owner) *owner = f; + return ""; + } + case LUA_TLCL: { /* Lua closure */ + LClosure *f = clLvalue(fi); + TString *name; + Proto *p = f->p; + if (!(1 <= n && n <= p->sizeupvalues)) return NULL; + *val = f->upvals[n-1]->v; + if (uv) *uv = f->upvals[n - 1]; + name = p->upvalues[n-1].name; + return (name == NULL) ? "(*no name)" : getstr(name); + } + default: return NULL; /* not a closure */ + } +} + + +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val = NULL; /* to avoid warnings */ + lua_lock(L); + name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL); + if (name) { + setobj2s(L, L->top, val); + api_incr_top(L); + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val = NULL; /* to avoid warnings */ + CClosure *owner = NULL; + UpVal *uv = NULL; + StkId fi; + lua_lock(L); + fi = index2addr(L, funcindex); + api_checknelems(L, 1); + name = aux_upvalue(fi, n, &val, &owner, &uv); + if (name) { + L->top--; + setobj(L, val, L->top); + if (owner) { luaC_barrier(L, owner, L->top); } + else if (uv) { luaC_upvalbarrier(L, uv); } + } + lua_unlock(L); + return name; +} + + +static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { + LClosure *f; + StkId fi = index2addr(L, fidx); + api_check(L, ttisLclosure(fi), "Lua function expected"); + f = clLvalue(fi); + api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); + if (pf) *pf = f; + return &f->upvals[n - 1]; /* get its upvalue pointer */ +} + + +LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { + StkId fi = index2addr(L, fidx); + switch (ttype(fi)) { + case LUA_TLCL: { /* lua closure */ + return *getupvalref(L, fidx, n, NULL); + } + case LUA_TCCL: { /* C closure */ + CClosure *f = clCvalue(fi); + api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); + return &f->upvalue[n - 1]; + } + default: { + api_check(L, 0, "closure expected"); + return NULL; + } + } +} + + +LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, + int fidx2, int n2) { + LClosure *f1; + UpVal **up1 = getupvalref(L, fidx1, n1, &f1); + UpVal **up2 = getupvalref(L, fidx2, n2, NULL); + luaC_upvdeccount(L, *up1); + *up1 = *up2; + (*up1)->refcount++; + if (upisopen(*up1)) (*up1)->u.open.touched = 1; + luaC_upvalbarrier(L, *up1); +} + + diff --git a/3rd/lua-5.3.4/lapi.h b/3rd/lua-5.3.4/lapi.h new file mode 100644 index 0000000..6d36dee --- /dev/null +++ b/3rd/lua-5.3.4/lapi.h @@ -0,0 +1,24 @@ +/* +** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "llimits.h" +#include "lstate.h" + +#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ + "stack overflow");} + +#define adjustresults(L,nres) \ + { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } + +#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ + "not enough elements in the stack") + + +#endif diff --git a/3rd/lua-5.3.4/lauxlib.c b/3rd/lua-5.3.4/lauxlib.c new file mode 100644 index 0000000..f7a3836 --- /dev/null +++ b/3rd/lua-5.3.4/lauxlib.c @@ -0,0 +1,1043 @@ +/* +** $Id: lauxlib.c,v 1.289 2016/12/20 18:37:00 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + +#define lauxlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include +#include + + +/* +** This file uses only the official API of Lua. +** Any function declared here could be written as an application function. +*/ + +#include "lua.h" + +#include "lauxlib.h" + + +/* +** {====================================================== +** Traceback +** ======================================================= +*/ + + +#define LEVELS1 10 /* size of the first part of the stack */ +#define LEVELS2 11 /* size of the second part of the stack */ + + + +/* +** search for 'objidx' in table at index -1. +** return 1 + string at top if find a good name. +*/ +static int findfield (lua_State *L, int objidx, int level) { + if (level == 0 || !lua_istable(L, -1)) + return 0; /* not found */ + lua_pushnil(L); /* start 'next' loop */ + while (lua_next(L, -2)) { /* for each pair in table */ + if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */ + if (lua_rawequal(L, objidx, -1)) { /* found object? */ + lua_pop(L, 1); /* remove value (but keep name) */ + return 1; + } + else if (findfield(L, objidx, level - 1)) { /* try recursively */ + lua_remove(L, -2); /* remove table (but keep name) */ + lua_pushliteral(L, "."); + lua_insert(L, -2); /* place '.' between the two names */ + lua_concat(L, 3); + return 1; + } + } + lua_pop(L, 1); /* remove value */ + } + return 0; /* not found */ +} + + +/* +** Search for a name for a function in all loaded modules +*/ +static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { + int top = lua_gettop(L); + lua_getinfo(L, "f", ar); /* push function */ + lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + if (findfield(L, top + 1, 2)) { + const char *name = lua_tostring(L, -1); + if (strncmp(name, "_G.", 3) == 0) { /* name start with '_G.'? */ + lua_pushstring(L, name + 3); /* push name without prefix */ + lua_remove(L, -2); /* remove original name */ + } + lua_copy(L, -1, top + 1); /* move name to proper place */ + lua_pop(L, 2); /* remove pushed values */ + return 1; + } + else { + lua_settop(L, top); /* remove function and global table */ + return 0; + } +} + + +static void pushfuncname (lua_State *L, lua_Debug *ar) { + if (pushglobalfuncname(L, ar)) { /* try first a global name */ + lua_pushfstring(L, "function '%s'", lua_tostring(L, -1)); + lua_remove(L, -2); /* remove name */ + } + else if (*ar->namewhat != '\0') /* is there a name from code? */ + lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name); /* use it */ + else if (*ar->what == 'm') /* main? */ + lua_pushliteral(L, "main chunk"); + else if (*ar->what != 'C') /* for Lua functions, use */ + lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); + else /* nothing left... */ + lua_pushliteral(L, "?"); +} + + +static int lastlevel (lua_State *L) { + lua_Debug ar; + int li = 1, le = 1; + /* find an upper bound */ + while (lua_getstack(L, le, &ar)) { li = le; le *= 2; } + /* do a binary search */ + while (li < le) { + int m = (li + le)/2; + if (lua_getstack(L, m, &ar)) li = m + 1; + else le = m; + } + return le - 1; +} + + +LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, + const char *msg, int level) { + lua_Debug ar; + int top = lua_gettop(L); + int last = lastlevel(L1); + int n1 = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1; + if (msg) + lua_pushfstring(L, "%s\n", msg); + luaL_checkstack(L, 10, NULL); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (n1-- == 0) { /* too many levels? */ + lua_pushliteral(L, "\n\t..."); /* add a '...' */ + level = last - LEVELS2 + 1; /* and skip to last ones */ + } + else { + lua_getinfo(L1, "Slnt", &ar); + lua_pushfstring(L, "\n\t%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + lua_pushliteral(L, " in "); + pushfuncname(L, &ar); + if (ar.istailcall) + lua_pushliteral(L, "\n\t(...tail calls...)"); + lua_concat(L, lua_gettop(L) - top); + } + } + lua_concat(L, lua_gettop(L) - top); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Error-report functions +** ======================================================= +*/ + +LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) { + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ + return luaL_error(L, "bad argument #%d (%s)", arg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) { + arg--; /* do not count 'self' */ + if (arg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling '%s' on bad self (%s)", + ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; + return luaL_error(L, "bad argument #%d to '%s' (%s)", + arg, ar.name, extramsg); +} + + +static int typeerror (lua_State *L, int arg, const char *tname) { + const char *msg; + const char *typearg; /* name for the type of the actual argument */ + if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING) + typearg = lua_tostring(L, -1); /* use the given type name */ + else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA) + typearg = "light userdata"; /* special name for messages */ + else + typearg = luaL_typename(L, arg); /* standard name */ + msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg); + return luaL_argerror(L, arg, msg); +} + + +static void tag_error (lua_State *L, int arg, int tag) { + typeerror(L, arg, lua_typename(L, tag)); +} + + +/* +** The use of 'lua_pushfstring' ensures this function does not +** need reserved stack space when called. +*/ +LUALIB_API void luaL_where (lua_State *L, int level) { + lua_Debug ar; + if (lua_getstack(L, level, &ar)) { /* check function at level */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ + if (ar.currentline > 0) { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + } + lua_pushfstring(L, ""); /* else, no information available... */ +} + + +/* +** Again, the use of 'lua_pushvfstring' ensures this function does +** not need reserved stack space when called. (At worst, it generates +** an error with "stack overflow" instead of the given message.) +*/ +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} + + +LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { + int en = errno; /* calls to Lua API may change this value */ + if (stat) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + if (fname) + lua_pushfstring(L, "%s: %s", fname, strerror(en)); + else + lua_pushstring(L, strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +#if !defined(l_inspectstat) /* { */ + +#if defined(LUA_USE_POSIX) + +#include + +/* +** use appropriate macros to interpret 'pclose' return status +*/ +#define l_inspectstat(stat,what) \ + if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ + else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } + +#else + +#define l_inspectstat(stat,what) /* no op */ + +#endif + +#endif /* } */ + + +LUALIB_API int luaL_execresult (lua_State *L, int stat) { + const char *what = "exit"; /* type of termination */ + if (stat == -1) /* error? */ + return luaL_fileresult(L, 0, NULL); + else { + l_inspectstat(stat, what); /* interpret result */ + if (*what == 'e' && stat == 0) /* successful termination? */ + lua_pushboolean(L, 1); + else + lua_pushnil(L); + lua_pushstring(L, what); + lua_pushinteger(L, stat); + return 3; /* return true/nil,what,code */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Userdata's metatable manipulation +** ======================================================= +*/ + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { + if (luaL_getmetatable(L, tname) != LUA_TNIL) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_createtable(L, 0, 2); /* create metatable */ + lua_pushstring(L, tname); + lua_setfield(L, -2, "__name"); /* metatable.__name = tname */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; +} + + +LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) { + luaL_getmetatable(L, tname); + lua_setmetatable(L, -2); +} + + +LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) { + void *p = lua_touserdata(L, ud); + if (p != NULL) { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ + luaL_getmetatable(L, tname); /* get correct metatable */ + if (!lua_rawequal(L, -1, -2)) /* not the same? */ + p = NULL; /* value is a userdata with wrong metatable */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + return NULL; /* value is not a userdata with a metatable */ +} + + +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + void *p = luaL_testudata(L, ud, tname); + if (p == NULL) typeerror(L, ud, tname); + return p; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Argument check functions +** ======================================================= +*/ + +LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def, + const char *const lst[]) { + const char *name = (def) ? luaL_optstring(L, arg, def) : + luaL_checkstring(L, arg); + int i; + for (i=0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + return luaL_argerror(L, arg, + lua_pushfstring(L, "invalid option '%s'", name)); +} + + +/* +** Ensures the stack has at least 'space' extra slots, raising an error +** if it cannot fulfill the request. (The error handling needs a few +** extra slots to format the error message. In case of an error without +** this extra space, Lua will generate the same 'stack overflow' error, +** but without 'msg'.) +*/ +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { + if (!lua_checkstack(L, space)) { + if (msg) + luaL_error(L, "stack overflow (%s)", msg); + else + luaL_error(L, "stack overflow"); + } +} + + +LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) { + if (lua_type(L, arg) != t) + tag_error(L, arg, t); +} + + +LUALIB_API void luaL_checkany (lua_State *L, int arg) { + if (lua_type(L, arg) == LUA_TNONE) + luaL_argerror(L, arg, "value expected"); +} + + +LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) { + const char *s = lua_tolstring(L, arg, len); + if (!s) tag_error(L, arg, LUA_TSTRING); + return s; +} + + +LUALIB_API const char *luaL_optlstring (lua_State *L, int arg, + const char *def, size_t *len) { + if (lua_isnoneornil(L, arg)) { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else return luaL_checklstring(L, arg, len); +} + + +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) { + int isnum; + lua_Number d = lua_tonumberx(L, arg, &isnum); + if (!isnum) + tag_error(L, arg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) { + return luaL_opt(L, luaL_checknumber, arg, def); +} + + +static void interror (lua_State *L, int arg) { + if (lua_isnumber(L, arg)) + luaL_argerror(L, arg, "number has no integer representation"); + else + tag_error(L, arg, LUA_TNUMBER); +} + + +LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) { + int isnum; + lua_Integer d = lua_tointegerx(L, arg, &isnum); + if (!isnum) { + interror(L, arg); + } + return d; +} + + +LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg, + lua_Integer def) { + return luaL_opt(L, luaL_checkinteger, arg, def); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +/* userdata to box arbitrary data */ +typedef struct UBox { + void *box; + size_t bsize; +} UBox; + + +static void *resizebox (lua_State *L, int idx, size_t newsize) { + void *ud; + lua_Alloc allocf = lua_getallocf(L, &ud); + UBox *box = (UBox *)lua_touserdata(L, idx); + void *temp = allocf(ud, box->box, box->bsize, newsize); + if (temp == NULL && newsize > 0) { /* allocation error? */ + resizebox(L, idx, 0); /* free buffer */ + luaL_error(L, "not enough memory for buffer allocation"); + } + box->box = temp; + box->bsize = newsize; + return temp; +} + + +static int boxgc (lua_State *L) { + resizebox(L, 1, 0); + return 0; +} + + +static void *newbox (lua_State *L, size_t newsize) { + UBox *box = (UBox *)lua_newuserdata(L, sizeof(UBox)); + box->box = NULL; + box->bsize = 0; + if (luaL_newmetatable(L, "LUABOX")) { /* creating metatable? */ + lua_pushcfunction(L, boxgc); + lua_setfield(L, -2, "__gc"); /* metatable.__gc = boxgc */ + } + lua_setmetatable(L, -2); + return resizebox(L, -1, newsize); +} + + +/* +** check whether buffer is using a userdata on the stack as a temporary +** buffer +*/ +#define buffonstack(B) ((B)->b != (B)->initb) + + +/* +** returns a pointer to a free area with at least 'sz' bytes +*/ +LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { + lua_State *L = B->L; + if (B->size - B->n < sz) { /* not enough space? */ + char *newbuff; + size_t newsize = B->size * 2; /* double buffer size */ + if (newsize - B->n < sz) /* not big enough? */ + newsize = B->n + sz; + if (newsize < B->n || newsize - B->n < sz) + luaL_error(L, "buffer too large"); + /* create larger buffer */ + if (buffonstack(B)) + newbuff = (char *)resizebox(L, -1, newsize); + else { /* no buffer yet */ + newbuff = (char *)newbox(L, newsize); + memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */ + } + B->b = newbuff; + B->size = newsize; + } + return &B->b[B->n]; +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + if (l > 0) { /* avoid 'memcpy' when 's' can be NULL */ + char *b = luaL_prepbuffsize(B, l); + memcpy(b, s, l * sizeof(char)); + luaL_addsize(B, l); + } +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + lua_State *L = B->L; + lua_pushlstring(L, B->b, B->n); + if (buffonstack(B)) { + resizebox(L, -2, 0); /* delete old buffer */ + lua_remove(L, -2); /* remove its header from the stack */ + } +} + + +LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) { + luaL_addsize(B, sz); + luaL_pushresult(B); +} + + +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t l; + const char *s = lua_tolstring(L, -1, &l); + if (buffonstack(B)) + lua_insert(L, -2); /* put value below buffer */ + luaL_addlstring(B, s, l); + lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */ +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->b = B->initb; + B->n = 0; + B->size = LUAL_BUFFERSIZE; +} + + +LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { + luaL_buffinit(L, B); + return luaL_prepbuffsize(B, sz); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Reference system +** ======================================================= +*/ + +/* index of free-list header */ +#define freelist 0 + + +LUALIB_API int luaL_ref (lua_State *L, int t) { + int ref; + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* 'nil' has a unique fixed reference */ + } + t = lua_absindex(L, t); + lua_rawgeti(L, t, freelist); /* get first free element */ + ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ + lua_pop(L, 1); /* remove it from stack */ + if (ref != 0) { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ + } + else /* no free elements */ + ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ + lua_rawseti(L, t, ref); + return ref; +} + + +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { + if (ref >= 0) { + t = lua_absindex(L, t); + lua_rawgeti(L, t, freelist); + lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, freelist); /* t[freelist] = ref */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Load functions +** ======================================================= +*/ + +typedef struct LoadF { + int n; /* number of pre-read characters */ + FILE *f; /* file being read */ + char buff[BUFSIZ]; /* area for reading file */ +} LoadF; + + +static const char *getF (lua_State *L, void *ud, size_t *size) { + LoadF *lf = (LoadF *)ud; + (void)L; /* not used */ + if (lf->n > 0) { /* are there pre-read characters to be read? */ + *size = lf->n; /* return them (chars already in buffer) */ + lf->n = 0; /* no more pre-read characters */ + } + else { /* read a block from file */ + /* 'fread' can return > 0 *and* set the EOF flag. If next call to + 'getF' called 'fread', it might still wait for user input. + The next check avoids this problem. */ + if (feof(lf->f)) return NULL; + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */ + } + return lf->buff; +} + + +static int errfile (lua_State *L, const char *what, int fnameindex) { + const char *serr = strerror(errno); + const char *filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + + +static int skipBOM (LoadF *lf) { + const char *p = "\xEF\xBB\xBF"; /* UTF-8 BOM mark */ + int c; + lf->n = 0; + do { + c = getc(lf->f); + if (c == EOF || c != *(const unsigned char *)p++) return c; + lf->buff[lf->n++] = c; /* to be read by the parser */ + } while (*p != '\0'); + lf->n = 0; /* prefix matched; discard it */ + return getc(lf->f); /* return next character */ +} + + +/* +** reads the first character of file 'f' and skips an optional BOM mark +** in its beginning plus its first line if it starts with '#'. Returns +** true if it skipped the first line. In any case, '*cp' has the +** first "valid" character of the file (after the optional BOM and +** a first-line comment). +*/ +static int skipcomment (LoadF *lf, int *cp) { + int c = *cp = skipBOM(lf); + if (c == '#') { /* first line is a comment (Unix exec. file)? */ + do { /* skip first line */ + c = getc(lf->f); + } while (c != EOF && c != '\n'); + *cp = getc(lf->f); /* skip end-of-line, if present */ + return 1; /* there was a comment */ + } + else return 0; /* no comment */ +} + + +LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, + const char *mode) { + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + if (filename == NULL) { + lua_pushliteral(L, "=stdin"); + lf.f = stdin; + } + else { + lua_pushfstring(L, "@%s", filename); + lf.f = fopen(filename, "r"); + if (lf.f == NULL) return errfile(L, "open", fnameindex); + } + if (skipcomment(&lf, &c)) /* read initial portion */ + lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ + if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ + if (lf.f == NULL) return errfile(L, "reopen", fnameindex); + skipcomment(&lf, &c); /* re-read initial portion */ + } + if (c != EOF) + lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ + status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); + readstatus = ferror(lf.f); + if (filename) fclose(lf.f); /* close file (even in case of errors) */ + if (readstatus) { + lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ + return errfile(L, "read", fnameindex); + } + lua_remove(L, fnameindex); + return status; +} + + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + + +static const char *getS (lua_State *L, void *ud, size_t *size) { + LoadS *ls = (LoadS *)ud; + (void)L; /* not used */ + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; +} + + +LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size, + const char *name, const char *mode) { + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name, mode); +} + + +LUALIB_API int luaL_loadstring (lua_State *L, const char *s) { + return luaL_loadbuffer(L, s, strlen(s), s); +} + +/* }====================================================== */ + + + +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return LUA_TNIL; + else { + int tt; + lua_pushstring(L, event); + tt = lua_rawget(L, -2); + if (tt == LUA_TNIL) /* is metafield nil? */ + lua_pop(L, 2); /* remove metatable and metafield */ + else + lua_remove(L, -2); /* remove only metatable */ + return tt; /* return metafield type */ + } +} + + +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { + obj = lua_absindex(L, obj); + if (luaL_getmetafield(L, obj, event) == LUA_TNIL) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; +} + + +LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) { + lua_Integer l; + int isnum; + lua_len(L, idx); + l = lua_tointegerx(L, -1, &isnum); + if (!isnum) + luaL_error(L, "object length is not an integer"); + lua_pop(L, 1); /* remove object */ + return l; +} + + +LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { + if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */ + if (!lua_isstring(L, -1)) + luaL_error(L, "'__tostring' must return a string"); + } + else { + switch (lua_type(L, idx)) { + case LUA_TNUMBER: { + if (lua_isinteger(L, idx)) + lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx)); + else + lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx)); + break; + } + case LUA_TSTRING: + lua_pushvalue(L, idx); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: { + int tt = luaL_getmetafield(L, idx, "__name"); /* try name */ + const char *kind = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : + luaL_typename(L, idx); + lua_pushfstring(L, "%s: %p", kind, lua_topointer(L, idx)); + if (tt != LUA_TNIL) + lua_remove(L, -2); /* remove '__name' */ + break; + } + } + } + return lua_tolstring(L, -1, len); +} + + +/* +** {====================================================== +** Compatibility with 5.1 module functions +** ======================================================= +*/ +#if defined(LUA_COMPAT_MODULE) + +static const char *luaL_findtable (lua_State *L, int idx, + const char *fname, int szhint) { + const char *e; + if (idx) lua_pushvalue(L, idx); + do { + e = strchr(fname, '.'); + if (e == NULL) e = fname + strlen(fname); + lua_pushlstring(L, fname, e - fname); + if (lua_rawget(L, -2) == LUA_TNIL) { /* no such field? */ + lua_pop(L, 1); /* remove this nil */ + lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); /* set new table into field */ + } + else if (!lua_istable(L, -1)) { /* field has a non-table value? */ + lua_pop(L, 2); /* remove table and value */ + return fname; /* return problematic part of the name */ + } + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + } while (*e == '.'); + return NULL; +} + + +/* +** Count number of elements in a luaL_Reg list. +*/ +static int libsize (const luaL_Reg *l) { + int size = 0; + for (; l && l->name; l++) size++; + return size; +} + + +/* +** Find or create a module table with a given name. The function +** first looks at the LOADED table and, if that fails, try a +** global variable with that name. In any case, leaves on the stack +** the module table. +*/ +LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, + int sizehint) { + luaL_findtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE, 1); + if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no LOADED[modname]? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + lua_pushglobaltable(L); + if (luaL_findtable(L, 0, modname, sizehint) != NULL) + luaL_error(L, "name conflict for module '%s'", modname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, modname); /* LOADED[modname] = new table */ + } + lua_remove(L, -2); /* remove LOADED table */ +} + + +LUALIB_API void luaL_openlib (lua_State *L, const char *libname, + const luaL_Reg *l, int nup) { + luaL_checkversion(L); + if (libname) { + luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */ + lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ + } + if (l) + luaL_setfuncs(L, l, nup); + else + lua_pop(L, nup); /* remove upvalues */ +} + +#endif +/* }====================================================== */ + +/* +** set functions from list 'l' into table at top - 'nup'; each +** function gets the 'nup' elements at the top as upvalues. +** Returns with only the table at the stack. +*/ +LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { + luaL_checkstack(L, nup, "too many upvalues"); + for (; l->name != NULL; l++) { /* fill the table with given functions */ + int i; + for (i = 0; i < nup; i++) /* copy upvalues to the top */ + lua_pushvalue(L, -nup); + lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ + lua_setfield(L, -(nup + 2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ +} + + +/* +** ensure that stack[idx][fname] has a table and push that table +** into the stack +*/ +LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { + if (lua_getfield(L, idx, fname) == LUA_TTABLE) + return 1; /* table already there */ + else { + lua_pop(L, 1); /* remove previous result */ + idx = lua_absindex(L, idx); + lua_newtable(L); + lua_pushvalue(L, -1); /* copy to be left at top */ + lua_setfield(L, idx, fname); /* assign new table to field */ + return 0; /* false, because did not find table there */ + } +} + + +/* +** Stripped-down 'require': After checking "loaded" table, calls 'openf' +** to open a module, registers the result in 'package.loaded' table and, +** if 'glb' is true, also registers the result in the global table. +** Leaves resulting module on the top. +*/ +LUALIB_API void luaL_requiref (lua_State *L, const char *modname, + lua_CFunction openf, int glb) { + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_getfield(L, -1, modname); /* LOADED[modname] */ + if (!lua_toboolean(L, -1)) { /* package not already loaded? */ + lua_pop(L, 1); /* remove field */ + lua_pushcfunction(L, openf); + lua_pushstring(L, modname); /* argument to open function */ + lua_call(L, 1, 1); /* call 'openf' to open module */ + lua_pushvalue(L, -1); /* make copy of module (call result) */ + lua_setfield(L, -3, modname); /* LOADED[modname] = module */ + } + lua_remove(L, -2); /* remove LOADED table */ + if (glb) { + lua_pushvalue(L, -1); /* copy of module */ + lua_setglobal(L, modname); /* _G[modname] = module */ + } +} + + +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, + const char *r) { + const char *wild; + size_t l = strlen(p); + luaL_Buffer b; + luaL_buffinit(L, &b); + while ((wild = strstr(s, p)) != NULL) { + luaL_addlstring(&b, s, wild - s); /* push prefix */ + luaL_addstring(&b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after 'p' */ + } + luaL_addstring(&b, s); /* push last suffix */ + luaL_pushresult(&b); + return lua_tostring(L, -1); +} + + +static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { + (void)ud; (void)osize; /* not used */ + if (nsize == 0) { + free(ptr); + return NULL; + } + else + return realloc(ptr, nsize); +} + + +static int panic (lua_State *L) { + lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", + lua_tostring(L, -1)); + return 0; /* return to Lua to abort */ +} + + +LUALIB_API lua_State *luaL_newstate (void) { + lua_State *L = lua_newstate(l_alloc, NULL); + if (L) lua_atpanic(L, &panic); + return L; +} + + +LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) { + const lua_Number *v = lua_version(L); + if (sz != LUAL_NUMSIZES) /* check numeric types */ + luaL_error(L, "core and library have incompatible numeric types"); + if (v != lua_version(NULL)) + luaL_error(L, "multiple Lua VMs detected"); + else if (*v != ver) + luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", + (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)*v); +} + diff --git a/3rd/lua-5.3.4/lauxlib.h b/3rd/lua-5.3.4/lauxlib.h new file mode 100644 index 0000000..9a2e66a --- /dev/null +++ b/3rd/lua-5.3.4/lauxlib.h @@ -0,0 +1,264 @@ +/* +** $Id: lauxlib.h,v 1.131 2016/12/06 14:54:31 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "lua.h" + + + +/* extra error code for 'luaL_loadfilex' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +/* key, in the registry, for table of loaded modules */ +#define LUA_LOADED_TABLE "_LOADED" + + +/* key, in the registry, for table of preloaded loaders */ +#define LUA_PRELOAD_TABLE "_PRELOAD" + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + +#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number)) + +LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz); +#define luaL_checkversion(L) \ + luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES) + +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); +LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int arg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); +LUALIB_API int (luaL_execresult) (lua_State *L, int stat); + +/* predefined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, + const char *mode); + +#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) + +LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, + const char *name, const char *mode); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + +LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); + +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, + const char *r); + +LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); + +LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); + +LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, + const char *msg, int level); + +LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, + lua_CFunction openf, int glb); + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + + +#define luaL_newlibtable(L,l) \ + lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) + +#define luaL_newlib(L,l) \ + (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) + +#define luaL_argcheck(L, cond,arg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +typedef struct luaL_Buffer { + char *b; /* buffer address */ + size_t size; /* buffer size */ + size_t n; /* number of characters in buffer */ + lua_State *L; + char initb[LUAL_BUFFERSIZE]; /* initial buffer */ +} luaL_Buffer; + + +#define luaL_addchar(B,c) \ + ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ + ((B)->b[(B)->n++] = (c))) + +#define luaL_addsize(B,s) ((B)->n += (s)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); +LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); + +#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) + +/* }====================================================== */ + + + +/* +** {====================================================== +** File handles for IO library +** ======================================================= +*/ + +/* +** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and +** initial structure 'luaL_Stream' (it may contain other fields +** after that initial structure). +*/ + +#define LUA_FILEHANDLE "FILE*" + + +typedef struct luaL_Stream { + FILE *f; /* stream (NULL for incompletely created streams) */ + lua_CFunction closef; /* to close stream (NULL for closed streams) */ +} luaL_Stream; + +/* }====================================================== */ + + + +/* compatibility with old module system */ +#if defined(LUA_COMPAT_MODULE) + +LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, + int sizehint); +LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); + +#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) + +#endif + + +/* +** {================================================================== +** "Abstraction Layer" for basic report of messages and errors +** =================================================================== +*/ + +/* print a string */ +#if !defined(lua_writestring) +#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) +#endif + +/* print a newline and flush the output */ +#if !defined(lua_writeline) +#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) +#endif + +/* print an error message */ +#if !defined(lua_writestringerror) +#define lua_writestringerror(s,p) \ + (fprintf(stderr, (s), (p)), fflush(stderr)) +#endif + +/* }================================================================== */ + + +/* +** {============================================================ +** Compatibility with deprecated conversions +** ============================================================= +*/ +#if defined(LUA_COMPAT_APIINTCASTS) + +#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) +#define luaL_optunsigned(L,a,d) \ + ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d))) + +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) + +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#endif +/* }============================================================ */ + + + +#endif + + diff --git a/3rd/lua-5.3.4/lbaselib.c b/3rd/lua-5.3.4/lbaselib.c new file mode 100644 index 0000000..08523e6 --- /dev/null +++ b/3rd/lua-5.3.4/lbaselib.c @@ -0,0 +1,498 @@ +/* +** $Id: lbaselib.c,v 1.314 2016/09/05 19:06:34 roberto Exp $ +** Basic library +** See Copyright Notice in lua.h +*/ + +#define lbaselib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + lua_getglobal(L, "tostring"); + for (i=1; i<=n; i++) { + const char *s; + size_t l; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + s = lua_tolstring(L, -1, &l); /* get result */ + if (s == NULL) + return luaL_error(L, "'tostring' must return a string to 'print'"); + if (i>1) lua_writestring("\t", 1); + lua_writestring(s, l); + lua_pop(L, 1); /* pop result */ + } + lua_writeline(); + return 0; +} + + +#define SPACECHARS " \f\n\r\t\v" + +static const char *b_str2int (const char *s, int base, lua_Integer *pn) { + lua_Unsigned n = 0; + int neg = 0; + s += strspn(s, SPACECHARS); /* skip initial spaces */ + if (*s == '-') { s++; neg = 1; } /* handle signal */ + else if (*s == '+') s++; + if (!isalnum((unsigned char)*s)) /* no digit? */ + return NULL; + do { + int digit = (isdigit((unsigned char)*s)) ? *s - '0' + : (toupper((unsigned char)*s) - 'A') + 10; + if (digit >= base) return NULL; /* invalid numeral */ + n = n * base + digit; + s++; + } while (isalnum((unsigned char)*s)); + s += strspn(s, SPACECHARS); /* skip trailing spaces */ + *pn = (lua_Integer)((neg) ? (0u - n) : n); + return s; +} + + +static int luaB_tonumber (lua_State *L) { + if (lua_isnoneornil(L, 2)) { /* standard conversion? */ + luaL_checkany(L, 1); + if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */ + lua_settop(L, 1); /* yes; return it */ + return 1; + } + else { + size_t l; + const char *s = lua_tolstring(L, 1, &l); + if (s != NULL && lua_stringtonumber(L, s) == l + 1) + return 1; /* successful conversion to number */ + /* else not a number */ + } + } + else { + size_t l; + const char *s; + lua_Integer n = 0; /* to avoid warnings */ + lua_Integer base = luaL_checkinteger(L, 2); + luaL_checktype(L, 1, LUA_TSTRING); /* no numbers as strings */ + s = lua_tolstring(L, 1, &l); + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + if (b_str2int(s, (int)base, &n) == s + l) { + lua_pushinteger(L, n); + return 1; + } /* else not a number */ + } /* else not a number */ + lua_pushnil(L); /* not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + int level = (int)luaL_optinteger(L, 2, 1); + lua_settop(L, 1); + if (lua_type(L, 1) == LUA_TSTRING && level > 0) { + luaL_where(L, level); /* add extra information */ + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); +} + + +static int luaB_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ +} + + +static int luaB_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL) + return luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; +} + + +static int luaB_rawequal (lua_State *L) { + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; +} + + +static int luaB_rawlen (lua_State *L) { + int t = lua_type(L, 1); + luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, + "table or string expected"); + lua_pushinteger(L, lua_rawlen(L, 1)); + return 1; +} + + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; +} + + +static int luaB_collectgarbage (lua_State *L) { + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setpause", "setstepmul", + "isrunning", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, + LUA_GCISRUNNING}; + int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; + int ex = (int)luaL_optinteger(L, 2, 0); + int res = lua_gc(L, o, ex); + switch (o) { + case LUA_GCCOUNT: { + int b = lua_gc(L, LUA_GCCOUNTB, 0); + lua_pushnumber(L, (lua_Number)res + ((lua_Number)b/1024)); + return 1; + } + case LUA_GCSTEP: case LUA_GCISRUNNING: { + lua_pushboolean(L, res); + return 1; + } + default: { + lua_pushinteger(L, res); + return 1; + } + } +} + + +static int luaB_type (lua_State *L) { + int t = lua_type(L, 1); + luaL_argcheck(L, t != LUA_TNONE, 1, "value expected"); + lua_pushstring(L, lua_typename(L, t)); + return 1; +} + + +static int pairsmeta (lua_State *L, const char *method, int iszero, + lua_CFunction iter) { + luaL_checkany(L, 1); + if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */ + lua_pushcfunction(L, iter); /* will return generator, */ + lua_pushvalue(L, 1); /* state, */ + if (iszero) lua_pushinteger(L, 0); /* and initial value */ + else lua_pushnil(L); + } + else { + lua_pushvalue(L, 1); /* argument 'self' to metamethod */ + lua_call(L, 1, 3); /* get 3 values from metamethod */ + } + return 3; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int luaB_pairs (lua_State *L) { + return pairsmeta(L, "__pairs", 0, luaB_next); +} + + +/* +** Traversal function for 'ipairs' +*/ +static int ipairsaux (lua_State *L) { + lua_Integer i = luaL_checkinteger(L, 2) + 1; + lua_pushinteger(L, i); + return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2; +} + + +/* +** 'ipairs' function. Returns 'ipairsaux', given "table", 0. +** (The given "table" may not be a table.) +*/ +static int luaB_ipairs (lua_State *L) { +#if defined(LUA_COMPAT_IPAIRS) + return pairsmeta(L, "__ipairs", 1, ipairsaux); +#else + luaL_checkany(L, 1); + lua_pushcfunction(L, ipairsaux); /* iteration function */ + lua_pushvalue(L, 1); /* state */ + lua_pushinteger(L, 0); /* initial value */ + return 3; +#endif +} + + +static int load_aux (lua_State *L, int status, int envidx) { + if (status == LUA_OK) { + if (envidx != 0) { /* 'env' parameter? */ + lua_pushvalue(L, envidx); /* environment for loaded function */ + if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */ + lua_pop(L, 1); /* remove 'env' if not used by previous call */ + } + return 1; + } + else { /* error (message is on top of the stack) */ + lua_pushnil(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return nil plus error message */ + } +} + + +static int luaB_loadfile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + const char *mode = luaL_optstring(L, 2, NULL); + int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */ + int status = luaL_loadfilex(L, fname, mode); + return load_aux(L, status, env); +} + + +/* +** {====================================================== +** Generic Read function +** ======================================================= +*/ + + +/* +** reserved slot, above all arguments, to hold a copy of the returned +** string to avoid it being collected while parsed. 'load' has four +** optional arguments (chunk, source name, mode, and environment). +*/ +#define RESERVEDSLOT 5 + + +/* +** Reader for generic 'load' function: 'lua_load' uses the +** stack for internal stuff, so the reader cannot change the +** stack top. Instead, it keeps its resulting string in a +** reserved slot inside the stack. +*/ +static const char *generic_reader (lua_State *L, void *ud, size_t *size) { + (void)(ud); /* not used */ + luaL_checkstack(L, 2, "too many nested functions"); + lua_pushvalue(L, 1); /* get function */ + lua_call(L, 0, 1); /* call it */ + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* pop result */ + *size = 0; + return NULL; + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "reader function must return a string"); + lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ + return lua_tolstring(L, RESERVEDSLOT, size); +} + + +static int luaB_load (lua_State *L) { + int status; + size_t l; + const char *s = lua_tolstring(L, 1, &l); + const char *mode = luaL_optstring(L, 3, "bt"); + int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */ + if (s != NULL) { /* loading a string? */ + const char *chunkname = luaL_optstring(L, 2, s); + status = luaL_loadbufferx(L, s, l, chunkname, mode); + } + else { /* loading from a reader function */ + const char *chunkname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, RESERVEDSLOT); /* create reserved slot */ + status = lua_load(L, generic_reader, NULL, chunkname, mode); + } + return load_aux(L, status, env); +} + +/* }====================================================== */ + + +static int dofilecont (lua_State *L, int d1, lua_KContext d2) { + (void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */ + return lua_gettop(L) - 1; +} + + +static int luaB_dofile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + lua_settop(L, 1); + if (luaL_loadfile(L, fname) != LUA_OK) + return lua_error(L); + lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); + return dofilecont(L, 0, 0); +} + + +static int luaB_assert (lua_State *L) { + if (lua_toboolean(L, 1)) /* condition is true? */ + return lua_gettop(L); /* return all arguments */ + else { /* error */ + luaL_checkany(L, 1); /* there must be a condition */ + lua_remove(L, 1); /* remove it */ + lua_pushliteral(L, "assertion failed!"); /* default message */ + lua_settop(L, 1); /* leave only message (default if no other one) */ + return luaB_error(L); /* call 'error' */ + } +} + + +static int luaB_select (lua_State *L) { + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { + lua_pushinteger(L, n-1); + return 1; + } + else { + lua_Integer i = luaL_checkinteger(L, 1); + if (i < 0) i = n + i; + else if (i > n) i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - (int)i; + } +} + + +/* +** Continuation function for 'pcall' and 'xpcall'. Both functions +** already pushed a 'true' before doing the call, so in case of success +** 'finishpcall' only has to return everything in the stack minus +** 'extra' values (where 'extra' is exactly the number of items to be +** ignored). +*/ +static int finishpcall (lua_State *L, int status, lua_KContext extra) { + if (status != LUA_OK && status != LUA_YIELD) { /* error? */ + lua_pushboolean(L, 0); /* first result (false) */ + lua_pushvalue(L, -2); /* error message */ + return 2; /* return false, msg */ + } + else + return lua_gettop(L) - (int)extra; /* return all results */ +} + + +static int luaB_pcall (lua_State *L) { + int status; + luaL_checkany(L, 1); + lua_pushboolean(L, 1); /* first result if no errors */ + lua_insert(L, 1); /* put it in place */ + status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall); + return finishpcall(L, status, 0); +} + + +/* +** Do a protected call with error handling. After 'lua_rotate', the +** stack will have ; so, the function passes +** 2 to 'finishpcall' to skip the 2 first values when returning results. +*/ +static int luaB_xpcall (lua_State *L) { + int status; + int n = lua_gettop(L); + luaL_checktype(L, 2, LUA_TFUNCTION); /* check error function */ + lua_pushboolean(L, 1); /* first result */ + lua_pushvalue(L, 1); /* function */ + lua_rotate(L, 3, 2); /* move them below function's arguments */ + status = lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall); + return finishpcall(L, status, 2); +} + + +static int luaB_tostring (lua_State *L) { + luaL_checkany(L, 1); + luaL_tolstring(L, 1, NULL); + return 1; +} + + +static const luaL_Reg base_funcs[] = { + {"assert", luaB_assert}, + {"collectgarbage", luaB_collectgarbage}, + {"dofile", luaB_dofile}, + {"error", luaB_error}, + {"getmetatable", luaB_getmetatable}, + {"ipairs", luaB_ipairs}, + {"loadfile", luaB_loadfile}, + {"load", luaB_load}, +#if defined(LUA_COMPAT_LOADSTRING) + {"loadstring", luaB_load}, +#endif + {"next", luaB_next}, + {"pairs", luaB_pairs}, + {"pcall", luaB_pcall}, + {"print", luaB_print}, + {"rawequal", luaB_rawequal}, + {"rawlen", luaB_rawlen}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"select", luaB_select}, + {"setmetatable", luaB_setmetatable}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {"xpcall", luaB_xpcall}, + /* placeholders */ + {"_G", NULL}, + {"_VERSION", NULL}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_base (lua_State *L) { + /* open lib into global table */ + lua_pushglobaltable(L); + luaL_setfuncs(L, base_funcs, 0); + /* set global _G */ + lua_pushvalue(L, -1); + lua_setfield(L, -2, "_G"); + /* set global _VERSION */ + lua_pushliteral(L, LUA_VERSION); + lua_setfield(L, -2, "_VERSION"); + return 1; +} + diff --git a/3rd/lua-5.3.4/lbitlib.c b/3rd/lua-5.3.4/lbitlib.c new file mode 100644 index 0000000..1cb1d5b --- /dev/null +++ b/3rd/lua-5.3.4/lbitlib.c @@ -0,0 +1,233 @@ +/* +** $Id: lbitlib.c,v 1.30 2015/11/11 19:08:09 roberto Exp $ +** Standard library for bitwise operations +** See Copyright Notice in lua.h +*/ + +#define lbitlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#if defined(LUA_COMPAT_BITLIB) /* { */ + + +#define pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) +#define checkunsigned(L,i) ((lua_Unsigned)luaL_checkinteger(L,i)) + + +/* number of bits to consider in a number */ +#if !defined(LUA_NBITS) +#define LUA_NBITS 32 +#endif + + +/* +** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must +** be made in two parts to avoid problems when LUA_NBITS is equal to the +** number of bits in a lua_Unsigned.) +*/ +#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) + + +/* macro to trim extra bits */ +#define trim(x) ((x) & ALLONES) + + +/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ +#define mask(n) (~((ALLONES << 1) << ((n) - 1))) + + + +static lua_Unsigned andaux (lua_State *L) { + int i, n = lua_gettop(L); + lua_Unsigned r = ~(lua_Unsigned)0; + for (i = 1; i <= n; i++) + r &= checkunsigned(L, i); + return trim(r); +} + + +static int b_and (lua_State *L) { + lua_Unsigned r = andaux(L); + pushunsigned(L, r); + return 1; +} + + +static int b_test (lua_State *L) { + lua_Unsigned r = andaux(L); + lua_pushboolean(L, r != 0); + return 1; +} + + +static int b_or (lua_State *L) { + int i, n = lua_gettop(L); + lua_Unsigned r = 0; + for (i = 1; i <= n; i++) + r |= checkunsigned(L, i); + pushunsigned(L, trim(r)); + return 1; +} + + +static int b_xor (lua_State *L) { + int i, n = lua_gettop(L); + lua_Unsigned r = 0; + for (i = 1; i <= n; i++) + r ^= checkunsigned(L, i); + pushunsigned(L, trim(r)); + return 1; +} + + +static int b_not (lua_State *L) { + lua_Unsigned r = ~checkunsigned(L, 1); + pushunsigned(L, trim(r)); + return 1; +} + + +static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) { + if (i < 0) { /* shift right? */ + i = -i; + r = trim(r); + if (i >= LUA_NBITS) r = 0; + else r >>= i; + } + else { /* shift left */ + if (i >= LUA_NBITS) r = 0; + else r <<= i; + r = trim(r); + } + pushunsigned(L, r); + return 1; +} + + +static int b_lshift (lua_State *L) { + return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2)); +} + + +static int b_rshift (lua_State *L) { + return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2)); +} + + +static int b_arshift (lua_State *L) { + lua_Unsigned r = checkunsigned(L, 1); + lua_Integer i = luaL_checkinteger(L, 2); + if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1)))) + return b_shift(L, r, -i); + else { /* arithmetic shift for 'negative' number */ + if (i >= LUA_NBITS) r = ALLONES; + else + r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */ + pushunsigned(L, r); + return 1; + } +} + + +static int b_rot (lua_State *L, lua_Integer d) { + lua_Unsigned r = checkunsigned(L, 1); + int i = d & (LUA_NBITS - 1); /* i = d % NBITS */ + r = trim(r); + if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ + r = (r << i) | (r >> (LUA_NBITS - i)); + pushunsigned(L, trim(r)); + return 1; +} + + +static int b_lrot (lua_State *L) { + return b_rot(L, luaL_checkinteger(L, 2)); +} + + +static int b_rrot (lua_State *L) { + return b_rot(L, -luaL_checkinteger(L, 2)); +} + + +/* +** get field and width arguments for field-manipulation functions, +** checking whether they are valid. +** ('luaL_error' called without 'return' to avoid later warnings about +** 'width' being used uninitialized.) +*/ +static int fieldargs (lua_State *L, int farg, int *width) { + lua_Integer f = luaL_checkinteger(L, farg); + lua_Integer w = luaL_optinteger(L, farg + 1, 1); + luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); + luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); + if (f + w > LUA_NBITS) + luaL_error(L, "trying to access non-existent bits"); + *width = (int)w; + return (int)f; +} + + +static int b_extract (lua_State *L) { + int w; + lua_Unsigned r = trim(checkunsigned(L, 1)); + int f = fieldargs(L, 2, &w); + r = (r >> f) & mask(w); + pushunsigned(L, r); + return 1; +} + + +static int b_replace (lua_State *L) { + int w; + lua_Unsigned r = trim(checkunsigned(L, 1)); + lua_Unsigned v = trim(checkunsigned(L, 2)); + int f = fieldargs(L, 3, &w); + lua_Unsigned m = mask(w); + r = (r & ~(m << f)) | ((v & m) << f); + pushunsigned(L, r); + return 1; +} + + +static const luaL_Reg bitlib[] = { + {"arshift", b_arshift}, + {"band", b_and}, + {"bnot", b_not}, + {"bor", b_or}, + {"bxor", b_xor}, + {"btest", b_test}, + {"extract", b_extract}, + {"lrotate", b_lrot}, + {"lshift", b_lshift}, + {"replace", b_replace}, + {"rrotate", b_rrot}, + {"rshift", b_rshift}, + {NULL, NULL} +}; + + + +LUAMOD_API int luaopen_bit32 (lua_State *L) { + luaL_newlib(L, bitlib); + return 1; +} + + +#else /* }{ */ + + +LUAMOD_API int luaopen_bit32 (lua_State *L) { + return luaL_error(L, "library 'bit32' has been deprecated"); +} + +#endif /* } */ diff --git a/3rd/lua-5.3.4/lcode.c b/3rd/lua-5.3.4/lcode.c new file mode 100644 index 0000000..0bb4142 --- /dev/null +++ b/3rd/lua-5.3.4/lcode.c @@ -0,0 +1,1203 @@ +/* +** $Id: lcode.c,v 2.112 2016/12/22 13:08:50 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#define lcode_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstring.h" +#include "ltable.h" +#include "lvm.h" + + +/* Maximum number of registers in a Lua function (must fit in 8 bits) */ +#define MAXREGS 255 + + +#define hasjumps(e) ((e)->t != (e)->f) + + +/* +** If expression is a numeric constant, fills 'v' with its value +** and returns 1. Otherwise, returns 0. +*/ +static int tonumeral(const expdesc *e, TValue *v) { + if (hasjumps(e)) + return 0; /* not a numeral */ + switch (e->k) { + case VKINT: + if (v) setivalue(v, e->u.ival); + return 1; + case VKFLT: + if (v) setfltvalue(v, e->u.nval); + return 1; + default: return 0; + } +} + + +/* +** Create a OP_LOADNIL instruction, but try to optimize: if the previous +** instruction is also OP_LOADNIL and ranges are compatible, adjust +** range of previous instruction instead of emitting a new one. (For +** instance, 'local a; local b' will generate a single opcode.) +*/ +void luaK_nil (FuncState *fs, int from, int n) { + Instruction *previous; + int l = from + n - 1; /* last register to set nil */ + if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ + previous = &fs->f->code[fs->pc-1]; + if (GET_OPCODE(*previous) == OP_LOADNIL) { /* previous is LOADNIL? */ + int pfrom = GETARG_A(*previous); /* get previous range */ + int pl = pfrom + GETARG_B(*previous); + if ((pfrom <= from && from <= pl + 1) || + (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ + if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ + if (pl > l) l = pl; /* l = max(l, pl) */ + SETARG_A(*previous, from); + SETARG_B(*previous, l - from); + return; + } + } /* else go through */ + } + luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ +} + + +/* +** Gets the destination address of a jump instruction. Used to traverse +** a list of jumps. +*/ +static int getjump (FuncState *fs, int pc) { + int offset = GETARG_sBx(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +/* +** Fix jump instruction at position 'pc' to jump to 'dest'. +** (Jump addresses are relative in Lua) +*/ +static void fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest - (pc + 1); + lua_assert(dest != NO_JUMP); + if (abs(offset) > MAXARG_sBx) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_sBx(*jmp, offset); +} + + +/* +** Concatenate jump-list 'l2' into jump-list 'l1' +*/ +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (l2 == NO_JUMP) return; /* nothing to concatenate? */ + else if (*l1 == NO_JUMP) /* no original list? */ + *l1 = l2; /* 'l1' points to 'l2' */ + else { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); /* last element links to 'l2' */ + } +} + + +/* +** Create a jump instruction and return its position, so its destination +** can be fixed later (with 'fixjump'). If there are jumps to +** this position (kept in 'jpc'), link them all together so that +** 'patchlistaux' will fix all them directly to the final destination. +*/ +int luaK_jump (FuncState *fs) { + int jpc = fs->jpc; /* save list of jumps to here */ + int j; + fs->jpc = NO_JUMP; /* no more jumps to here */ + j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); + luaK_concat(fs, &j, jpc); /* keep them on hold */ + return j; +} + + +/* +** Code a 'return' instruction +*/ +void luaK_ret (FuncState *fs, int first, int nret) { + luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); +} + + +/* +** Code a "conditional jump", that is, a test or comparison opcode +** followed by a jump. Return jump position. +*/ +static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { + luaK_codeABC(fs, op, A, B, C); + return luaK_jump(fs); +} + + +/* +** returns current 'pc' and marks it as a jump target (to avoid wrong +** optimizations with consecutive instructions not in the same basic block). +*/ +int luaK_getlabel (FuncState *fs) { + fs->lasttarget = fs->pc; + return fs->pc; +} + + +/* +** Returns the position of the instruction "controlling" a given +** jump (that is, its condition), or the jump itself if it is +** unconditional. +*/ +static Instruction *getjumpcontrol (FuncState *fs, int pc) { + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) + return pi-1; + else + return pi; +} + + +/* +** Patch destination register for a TESTSET instruction. +** If instruction in position 'node' is not a TESTSET, return 0 ("fails"). +** Otherwise, if 'reg' is not 'NO_REG', set it as the destination +** register. Otherwise, change instruction to a simple 'TEST' (produces +** no register value) +*/ +static int patchtestreg (FuncState *fs, int node, int reg) { + Instruction *i = getjumpcontrol(fs, node); + if (GET_OPCODE(*i) != OP_TESTSET) + return 0; /* cannot patch other instructions */ + if (reg != NO_REG && reg != GETARG_B(*i)) + SETARG_A(*i, reg); + else { + /* no register to put value or register already has the value; + change instruction to simple test */ + *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); + } + return 1; +} + + +/* +** Traverse a list of tests ensuring no one produces a value +*/ +static void removevalues (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) + patchtestreg(fs, list, NO_REG); +} + + +/* +** Traverse a list of tests, patching their destination address and +** registers: tests producing values jump to 'vtarget' (and put their +** values in 'reg'), other tests jump to 'dtarget'. +*/ +static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, + int dtarget) { + while (list != NO_JUMP) { + int next = getjump(fs, list); + if (patchtestreg(fs, list, reg)) + fixjump(fs, list, vtarget); + else + fixjump(fs, list, dtarget); /* jump to default target */ + list = next; + } +} + + +/* +** Ensure all pending jumps to current position are fixed (jumping +** to current position with no values) and reset list of pending +** jumps +*/ +static void dischargejpc (FuncState *fs) { + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); + fs->jpc = NO_JUMP; +} + + +/* +** Add elements in 'list' to list of pending jumps to "here" +** (current position) +*/ +void luaK_patchtohere (FuncState *fs, int list) { + luaK_getlabel(fs); /* mark "here" as a jump target */ + luaK_concat(fs, &fs->jpc, list); +} + + +/* +** Path all jumps in 'list' to jump to 'target'. +** (The assert means that we cannot fix a jump to a forward address +** because we only know addresses once code is generated.) +*/ +void luaK_patchlist (FuncState *fs, int list, int target) { + if (target == fs->pc) /* 'target' is current position? */ + luaK_patchtohere(fs, list); /* add list to pending jumps */ + else { + lua_assert(target < fs->pc); + patchlistaux(fs, list, target, NO_REG, target); + } +} + + +/* +** Path all jumps in 'list' to close upvalues up to given 'level' +** (The assertion checks that jumps either were closing nothing +** or were closing higher levels, from inner blocks.) +*/ +void luaK_patchclose (FuncState *fs, int list, int level) { + level++; /* argument is +1 to reserve 0 as non-op */ + for (; list != NO_JUMP; list = getjump(fs, list)) { + lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && + (GETARG_A(fs->f->code[list]) == 0 || + GETARG_A(fs->f->code[list]) >= level)); + SETARG_A(fs->f->code[list], level); + } +} + + +/* +** Emit instruction 'i', checking for array sizes and saving also its +** line information. Return 'i' position. +*/ +static int luaK_code (FuncState *fs, Instruction i) { + Proto *f = fs->f; + dischargejpc(fs); /* 'pc' will change */ + /* put new instruction in code array */ + luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "opcodes"); + f->code[fs->pc] = i; + /* save corresponding line information */ + luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int, + MAX_INT, "opcodes"); + f->lineinfo[fs->pc] = fs->ls->lastline; + return fs->pc++; +} + + +/* +** Format and emit an 'iABC' instruction. (Assertions check consistency +** of parameters versus opcode.) +*/ +int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { + lua_assert(getOpMode(o) == iABC); + lua_assert(getBMode(o) != OpArgN || b == 0); + lua_assert(getCMode(o) != OpArgN || c == 0); + lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); + return luaK_code(fs, CREATE_ABC(o, a, b, c)); +} + + +/* +** Format and emit an 'iABx' instruction. +*/ +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); + lua_assert(getCMode(o) == OpArgN); + lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); + return luaK_code(fs, CREATE_ABx(o, a, bc)); +} + + +/* +** Emit an "extra argument" instruction (format 'iAx') +*/ +static int codeextraarg (FuncState *fs, int a) { + lua_assert(a <= MAXARG_Ax); + return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); +} + + +/* +** Emit a "load constant" instruction, using either 'OP_LOADK' +** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX' +** instruction with "extra argument". +*/ +int luaK_codek (FuncState *fs, int reg, int k) { + if (k <= MAXARG_Bx) + return luaK_codeABx(fs, OP_LOADK, reg, k); + else { + int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); + codeextraarg(fs, k); + return p; + } +} + + +/* +** Check register-stack level, keeping track of its maximum size +** in field 'maxstacksize' +*/ +void luaK_checkstack (FuncState *fs, int n) { + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) { + if (newstack >= MAXREGS) + luaX_syntaxerror(fs->ls, + "function or expression needs too many registers"); + fs->f->maxstacksize = cast_byte(newstack); + } +} + + +/* +** Reserve 'n' registers in register stack +*/ +void luaK_reserveregs (FuncState *fs, int n) { + luaK_checkstack(fs, n); + fs->freereg += n; +} + + +/* +** Free register 'reg', if it is neither a constant index nor +** a local variable. +) +*/ +static void freereg (FuncState *fs, int reg) { + if (!ISK(reg) && reg >= fs->nactvar) { + fs->freereg--; + lua_assert(reg == fs->freereg); + } +} + + +/* +** Free register used by expression 'e' (if any) +*/ +static void freeexp (FuncState *fs, expdesc *e) { + if (e->k == VNONRELOC) + freereg(fs, e->u.info); +} + + +/* +** Free registers used by expressions 'e1' and 'e2' (if any) in proper +** order. +*/ +static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) { + int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1; + int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1; + if (r1 > r2) { + freereg(fs, r1); + freereg(fs, r2); + } + else { + freereg(fs, r2); + freereg(fs, r1); + } +} + + +/* +** Add constant 'v' to prototype's list of constants (field 'k'). +** Use scanner's table to cache position of constants in constant list +** and try to reuse constants. Because some values should not be used +** as keys (nil cannot be a key, integer keys can collapse with float +** keys), the caller must provide a useful 'key' for indexing the cache. +*/ +static int addk (FuncState *fs, TValue *key, TValue *v) { + lua_State *L = fs->ls->L; + Proto *f = fs->f; + TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */ + int k, oldsize; + if (ttisinteger(idx)) { /* is there an index there? */ + k = cast_int(ivalue(idx)); + /* correct value? (warning: must distinguish floats from integers!) */ + if (k < fs->nk && ttype(&f->k[k]) == ttype(v) && + luaV_rawequalobj(&f->k[k], v)) + return k; /* reuse index */ + } + /* constant not found; create a new entry */ + oldsize = f->sizek; + k = fs->nk; + /* numerical value does not need GC barrier; + table has no metatable, so it does not need to invalidate cache */ + setivalue(idx, k); + luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[k], v); + fs->nk++; + luaC_barrier(L, f, v); + return k; +} + + +/* +** Add a string to list of constants and return its index. +*/ +int luaK_stringK (FuncState *fs, TString *s) { + TValue o; + setsvalue(fs->ls->L, &o, s); + return addk(fs, &o, &o); /* use string itself as key */ +} + + +/* +** Add an integer to list of constants and return its index. +** Integers use userdata as keys to avoid collision with floats with +** same value; conversion to 'void*' is used only for hashing, so there +** are no "precision" problems. +*/ +int luaK_intK (FuncState *fs, lua_Integer n) { + TValue k, o; + setpvalue(&k, cast(void*, cast(size_t, n))); + setivalue(&o, n); + return addk(fs, &k, &o); +} + +/* +** Add a float to list of constants and return its index. +*/ +static int luaK_numberK (FuncState *fs, lua_Number r) { + TValue o; + setfltvalue(&o, r); + return addk(fs, &o, &o); /* use number itself as key */ +} + + +/* +** Add a boolean to list of constants and return its index. +*/ +static int boolK (FuncState *fs, int b) { + TValue o; + setbvalue(&o, b); + return addk(fs, &o, &o); /* use boolean itself as key */ +} + + +/* +** Add nil to list of constants and return its index. +*/ +static int nilK (FuncState *fs) { + TValue k, v; + setnilvalue(&v); + /* cannot use nil as key; instead use table itself to represent nil */ + sethvalue(fs->ls->L, &k, fs->ls->h); + return addk(fs, &k, &v); +} + + +/* +** Fix an expression to return the number of results 'nresults'. +** Either 'e' is a multi-ret expression (function call or vararg) +** or 'nresults' is LUA_MULTRET (as any expression can satisfy that). +*/ +void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { + if (e->k == VCALL) { /* expression is an open function call? */ + SETARG_C(getinstruction(fs, e), nresults + 1); + } + else if (e->k == VVARARG) { + Instruction *pc = &getinstruction(fs, e); + SETARG_B(*pc, nresults + 1); + SETARG_A(*pc, fs->freereg); + luaK_reserveregs(fs, 1); + } + else lua_assert(nresults == LUA_MULTRET); +} + + +/* +** Fix an expression to return one result. +** If expression is not a multi-ret expression (function call or +** vararg), it already returns one result, so nothing needs to be done. +** Function calls become VNONRELOC expressions (as its result comes +** fixed in the base register of the call), while vararg expressions +** become VRELOCABLE (as OP_VARARG puts its results where it wants). +** (Calls are created returning one result, so that does not need +** to be fixed.) +*/ +void luaK_setoneret (FuncState *fs, expdesc *e) { + if (e->k == VCALL) { /* expression is an open function call? */ + /* already returns 1 value */ + lua_assert(GETARG_C(getinstruction(fs, e)) == 2); + e->k = VNONRELOC; /* result has fixed position */ + e->u.info = GETARG_A(getinstruction(fs, e)); + } + else if (e->k == VVARARG) { + SETARG_B(getinstruction(fs, e), 2); + e->k = VRELOCABLE; /* can relocate its simple result */ + } +} + + +/* +** Ensure that expression 'e' is not a variable. +*/ +void luaK_dischargevars (FuncState *fs, expdesc *e) { + switch (e->k) { + case VLOCAL: { /* already in a register */ + e->k = VNONRELOC; /* becomes a non-relocatable value */ + break; + } + case VUPVAL: { /* move value to some (pending) register */ + e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); + e->k = VRELOCABLE; + break; + } + case VINDEXED: { + OpCode op; + freereg(fs, e->u.ind.idx); + if (e->u.ind.vt == VLOCAL) { /* is 't' in a register? */ + freereg(fs, e->u.ind.t); + op = OP_GETTABLE; + } + else { + lua_assert(e->u.ind.vt == VUPVAL); + op = OP_GETTABUP; /* 't' is in an upvalue */ + } + e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx); + e->k = VRELOCABLE; + break; + } + case VVARARG: case VCALL: { + luaK_setoneret(fs, e); + break; + } + default: break; /* there is one value available (somewhere) */ + } +} + + +/* +** Ensures expression value is in register 'reg' (and therefore +** 'e' will become a non-relocatable expression). +*/ +static void discharge2reg (FuncState *fs, expdesc *e, int reg) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: case VTRUE: { + luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); + break; + } + case VK: { + luaK_codek(fs, reg, e->u.info); + break; + } + case VKFLT: { + luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval)); + break; + } + case VKINT: { + luaK_codek(fs, reg, luaK_intK(fs, e->u.ival)); + break; + } + case VRELOCABLE: { + Instruction *pc = &getinstruction(fs, e); + SETARG_A(*pc, reg); /* instruction will put result in 'reg' */ + break; + } + case VNONRELOC: { + if (reg != e->u.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); + break; + } + default: { + lua_assert(e->k == VJMP); + return; /* nothing to do... */ + } + } + e->u.info = reg; + e->k = VNONRELOC; +} + + +/* +** Ensures expression value is in any register. +*/ +static void discharge2anyreg (FuncState *fs, expdesc *e) { + if (e->k != VNONRELOC) { /* no fixed register yet? */ + luaK_reserveregs(fs, 1); /* get a register */ + discharge2reg(fs, e, fs->freereg-1); /* put value there */ + } +} + + +static int code_loadbool (FuncState *fs, int A, int b, int jump) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); +} + + +/* +** check whether list has any jump that do not produce a value +** or produce an inverted value +*/ +static int need_value (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) return 1; + } + return 0; /* not found */ +} + + +/* +** Ensures final expression result (including results from its jump +** lists) is in register 'reg'. +** If expression has jumps, need to patch these jumps either to +** its final position or to "load" instructions (for those tests +** that do not produce values). +*/ +static void exp2reg (FuncState *fs, expdesc *e, int reg) { + discharge2reg(fs, e, reg); + if (e->k == VJMP) /* expression itself is a test? */ + luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */ + if (hasjumps(e)) { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t) || need_value(fs, e->f)) { + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); + p_f = code_loadbool(fs, reg, 0, 1); + p_t = code_loadbool(fs, reg, 1, 0); + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + patchlistaux(fs, e->f, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t); + } + e->f = e->t = NO_JUMP; + e->u.info = reg; + e->k = VNONRELOC; +} + + +/* +** Ensures final expression result (including results from its jump +** lists) is in next available register. +*/ +void luaK_exp2nextreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + freeexp(fs, e); + luaK_reserveregs(fs, 1); + exp2reg(fs, e, fs->freereg - 1); +} + + +/* +** Ensures final expression result (including results from its jump +** lists) is in some (any) register and return that register. +*/ +int luaK_exp2anyreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) { /* expression already has a register? */ + if (!hasjumps(e)) /* no jumps? */ + return e->u.info; /* result is already in a register */ + if (e->u.info >= fs->nactvar) { /* reg. is not a local? */ + exp2reg(fs, e, e->u.info); /* put final result in it */ + return e->u.info; + } + } + luaK_exp2nextreg(fs, e); /* otherwise, use next available register */ + return e->u.info; +} + + +/* +** Ensures final expression result is either in a register or in an +** upvalue. +*/ +void luaK_exp2anyregup (FuncState *fs, expdesc *e) { + if (e->k != VUPVAL || hasjumps(e)) + luaK_exp2anyreg(fs, e); +} + + +/* +** Ensures final expression result is either in a register or it is +** a constant. +*/ +void luaK_exp2val (FuncState *fs, expdesc *e) { + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); +} + + +/* +** Ensures final expression result is in a valid R/K index +** (that is, it is either in a register or in 'k' with an index +** in the range of R/K indices). +** Returns R/K index. +*/ +int luaK_exp2RK (FuncState *fs, expdesc *e) { + luaK_exp2val(fs, e); + switch (e->k) { /* move constants to 'k' */ + case VTRUE: e->u.info = boolK(fs, 1); goto vk; + case VFALSE: e->u.info = boolK(fs, 0); goto vk; + case VNIL: e->u.info = nilK(fs); goto vk; + case VKINT: e->u.info = luaK_intK(fs, e->u.ival); goto vk; + case VKFLT: e->u.info = luaK_numberK(fs, e->u.nval); goto vk; + case VK: + vk: + e->k = VK; + if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */ + return RKASK(e->u.info); + else break; + default: break; + } + /* not a constant in the right range: put it in a register */ + return luaK_exp2anyreg(fs, e); +} + + +/* +** Generate code to store result of expression 'ex' into variable 'var'. +*/ +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { + switch (var->k) { + case VLOCAL: { + freeexp(fs, ex); + exp2reg(fs, ex, var->u.info); /* compute 'ex' into proper place */ + return; + } + case VUPVAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); + break; + } + case VINDEXED: { + OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP; + int e = luaK_exp2RK(fs, ex); + luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e); + break; + } + default: lua_assert(0); /* invalid var kind to store */ + } + freeexp(fs, ex); +} + + +/* +** Emit SELF instruction (convert expression 'e' into 'e:key(e,'). +*/ +void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { + int ereg; + luaK_exp2anyreg(fs, e); + ereg = e->u.info; /* register where 'e' was placed */ + freeexp(fs, e); + e->u.info = fs->freereg; /* base register for op_self */ + e->k = VNONRELOC; /* self expression has a fixed register */ + luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ + luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); + freeexp(fs, key); +} + + +/* +** Negate condition 'e' (where 'e' is a comparison). +*/ +static void negatecondition (FuncState *fs, expdesc *e) { + Instruction *pc = getjumpcontrol(fs, e->u.info); + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && + GET_OPCODE(*pc) != OP_TEST); + SETARG_A(*pc, !(GETARG_A(*pc))); +} + + +/* +** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond' +** is true, code will jump if 'e' is true.) Return jump position. +** Optimize when 'e' is 'not' something, inverting the condition +** and removing the 'not'. +*/ +static int jumponcond (FuncState *fs, expdesc *e, int cond) { + if (e->k == VRELOCABLE) { + Instruction ie = getinstruction(fs, e); + if (GET_OPCODE(ie) == OP_NOT) { + fs->pc--; /* remove previous OP_NOT */ + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); + } + /* else go through */ + } + discharge2anyreg(fs, e); + freeexp(fs, e); + return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); +} + + +/* +** Emit code to go through if 'e' is true, jump otherwise. +*/ +void luaK_goiftrue (FuncState *fs, expdesc *e) { + int pc; /* pc of new jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VJMP: { /* condition? */ + negatecondition(fs, e); /* jump when it is false */ + pc = e->u.info; /* save jump position */ + break; + } + case VK: case VKFLT: case VKINT: case VTRUE: { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + default: { + pc = jumponcond(fs, e, 0); /* jump when false */ + break; + } + } + luaK_concat(fs, &e->f, pc); /* insert new jump in false list */ + luaK_patchtohere(fs, e->t); /* true list jumps to here (to go through) */ + e->t = NO_JUMP; +} + + +/* +** Emit code to go through if 'e' is false, jump otherwise. +*/ +void luaK_goiffalse (FuncState *fs, expdesc *e) { + int pc; /* pc of new jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VJMP: { + pc = e->u.info; /* already jump if true */ + break; + } + case VNIL: case VFALSE: { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + default: { + pc = jumponcond(fs, e, 1); /* jump if true */ + break; + } + } + luaK_concat(fs, &e->t, pc); /* insert new jump in 't' list */ + luaK_patchtohere(fs, e->f); /* false list jumps to here (to go through) */ + e->f = NO_JUMP; +} + + +/* +** Code 'not e', doing constant folding. +*/ +static void codenot (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + e->k = VTRUE; /* true == not nil == not false */ + break; + } + case VK: case VKFLT: case VKINT: case VTRUE: { + e->k = VFALSE; /* false == not "x" == not 0.5 == not 1 == not true */ + break; + } + case VJMP: { + negatecondition(fs, e); + break; + } + case VRELOCABLE: + case VNONRELOC: { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); + e->k = VRELOCABLE; + break; + } + default: lua_assert(0); /* cannot happen */ + } + /* interchange true and false lists */ + { int temp = e->f; e->f = e->t; e->t = temp; } + removevalues(fs, e->f); /* values are useless when negated */ + removevalues(fs, e->t); +} + + +/* +** Create expression 't[k]'. 't' must have its final result already in a +** register or upvalue. +*/ +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { + lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL)); + t->u.ind.t = t->u.info; /* register or upvalue index */ + t->u.ind.idx = luaK_exp2RK(fs, k); /* R/K index for key */ + t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL; + t->k = VINDEXED; +} + + +/* +** Return false if folding can raise an error. +** Bitwise operations need operands convertible to integers; division +** operations cannot have 0 as divisor. +*/ +static int validop (int op, TValue *v1, TValue *v2) { + switch (op) { + case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: + case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */ + lua_Integer i; + return (tointeger(v1, &i) && tointeger(v2, &i)); + } + case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */ + return (nvalue(v2) != 0); + default: return 1; /* everything else is valid */ + } +} + + +/* +** Try to "constant-fold" an operation; return 1 iff successful. +** (In this case, 'e1' has the final result.) +*/ +static int constfolding (FuncState *fs, int op, expdesc *e1, + const expdesc *e2) { + TValue v1, v2, res; + if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) + return 0; /* non-numeric operands or not safe to fold */ + luaO_arith(fs->ls->L, op, &v1, &v2, &res); /* does operation */ + if (ttisinteger(&res)) { + e1->k = VKINT; + e1->u.ival = ivalue(&res); + } + else { /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */ + lua_Number n = fltvalue(&res); + if (luai_numisnan(n) || n == 0) + return 0; + e1->k = VKFLT; + e1->u.nval = n; + } + return 1; +} + + +/* +** Emit code for unary expressions that "produce values" +** (everything but 'not'). +** Expression to produce final result will be encoded in 'e'. +*/ +static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { + int r = luaK_exp2anyreg(fs, e); /* opcodes operate only on registers */ + freeexp(fs, e); + e->u.info = luaK_codeABC(fs, op, 0, r, 0); /* generate opcode */ + e->k = VRELOCABLE; /* all those operations are relocatable */ + luaK_fixline(fs, line); +} + + +/* +** Emit code for binary expressions that "produce values" +** (everything but logical operators 'and'/'or' and comparison +** operators). +** Expression to produce final result will be encoded in 'e1'. +** Because 'luaK_exp2RK' can free registers, its calls must be +** in "stack order" (that is, first on 'e2', which may have more +** recent registers to be released). +*/ +static void codebinexpval (FuncState *fs, OpCode op, + expdesc *e1, expdesc *e2, int line) { + int rk2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */ + int rk1 = luaK_exp2RK(fs, e1); + freeexps(fs, e1, e2); + e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2); /* generate opcode */ + e1->k = VRELOCABLE; /* all those operations are relocatable */ + luaK_fixline(fs, line); +} + + +/* +** Emit code for comparisons. +** 'e1' was already put in R/K form by 'luaK_infix'. +*/ +static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { + int rk1 = (e1->k == VK) ? RKASK(e1->u.info) + : check_exp(e1->k == VNONRELOC, e1->u.info); + int rk2 = luaK_exp2RK(fs, e2); + freeexps(fs, e1, e2); + switch (opr) { + case OPR_NE: { /* '(a ~= b)' ==> 'not (a == b)' */ + e1->u.info = condjump(fs, OP_EQ, 0, rk1, rk2); + break; + } + case OPR_GT: case OPR_GE: { + /* '(a > b)' ==> '(b < a)'; '(a >= b)' ==> '(b <= a)' */ + OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ); + e1->u.info = condjump(fs, op, 1, rk2, rk1); /* invert operands */ + break; + } + default: { /* '==', '<', '<=' use their own opcodes */ + OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ); + e1->u.info = condjump(fs, op, 1, rk1, rk2); + break; + } + } + e1->k = VJMP; +} + + +/* +** Aplly prefix operation 'op' to expression 'e'. +*/ +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { + static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; + switch (op) { + case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */ + if (constfolding(fs, op + LUA_OPUNM, e, &ef)) + break; + /* FALLTHROUGH */ + case OPR_LEN: + codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line); + break; + case OPR_NOT: codenot(fs, e); break; + default: lua_assert(0); + } +} + + +/* +** Process 1st operand 'v' of binary operation 'op' before reading +** 2nd operand. +*/ +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { + switch (op) { + case OPR_AND: { + luaK_goiftrue(fs, v); /* go ahead only if 'v' is true */ + break; + } + case OPR_OR: { + luaK_goiffalse(fs, v); /* go ahead only if 'v' is false */ + break; + } + case OPR_CONCAT: { + luaK_exp2nextreg(fs, v); /* operand must be on the 'stack' */ + break; + } + case OPR_ADD: case OPR_SUB: + case OPR_MUL: case OPR_DIV: case OPR_IDIV: + case OPR_MOD: case OPR_POW: + case OPR_BAND: case OPR_BOR: case OPR_BXOR: + case OPR_SHL: case OPR_SHR: { + if (!tonumeral(v, NULL)) + luaK_exp2RK(fs, v); + /* else keep numeral, which may be folded with 2nd operand */ + break; + } + default: { + luaK_exp2RK(fs, v); + break; + } + } +} + + +/* +** Finalize code for binary operation, after reading 2nd operand. +** For '(a .. b .. c)' (which is '(a .. (b .. c))', because +** concatenation is right associative), merge second CONCAT into first +** one. +*/ +void luaK_posfix (FuncState *fs, BinOpr op, + expdesc *e1, expdesc *e2, int line) { + switch (op) { + case OPR_AND: { + lua_assert(e1->t == NO_JUMP); /* list closed by 'luK_infix' */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->f, e1->f); + *e1 = *e2; + break; + } + case OPR_OR: { + lua_assert(e1->f == NO_JUMP); /* list closed by 'luK_infix' */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->t, e1->t); + *e1 = *e2; + break; + } + case OPR_CONCAT: { + luaK_exp2val(fs, e2); + if (e2->k == VRELOCABLE && + GET_OPCODE(getinstruction(fs, e2)) == OP_CONCAT) { + lua_assert(e1->u.info == GETARG_B(getinstruction(fs, e2))-1); + freeexp(fs, e1); + SETARG_B(getinstruction(fs, e2), e1->u.info); + e1->k = VRELOCABLE; e1->u.info = e2->u.info; + } + else { + luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ + codebinexpval(fs, OP_CONCAT, e1, e2, line); + } + break; + } + case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: + case OPR_IDIV: case OPR_MOD: case OPR_POW: + case OPR_BAND: case OPR_BOR: case OPR_BXOR: + case OPR_SHL: case OPR_SHR: { + if (!constfolding(fs, op + LUA_OPADD, e1, e2)) + codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line); + break; + } + case OPR_EQ: case OPR_LT: case OPR_LE: + case OPR_NE: case OPR_GT: case OPR_GE: { + codecomp(fs, op, e1, e2); + break; + } + default: lua_assert(0); + } +} + + +/* +** Change line information associated with current position. +*/ +void luaK_fixline (FuncState *fs, int line) { + fs->f->lineinfo[fs->pc - 1] = line; +} + + +/* +** Emit a SETLIST instruction. +** 'base' is register that keeps table; +** 'nelems' is #table plus those to be stored now; +** 'tostore' is number of values (in registers 'base + 1',...) to add to +** table (or LUA_MULTRET to add up to stack top). +*/ +void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { + int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; + int b = (tostore == LUA_MULTRET) ? 0 : tostore; + lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH); + if (c <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, b, c); + else if (c <= MAXARG_Ax) { + luaK_codeABC(fs, OP_SETLIST, base, b, 0); + codeextraarg(fs, c); + } + else + luaX_syntaxerror(fs->ls, "constructor too long"); + fs->freereg = base + 1; /* free registers with list values */ +} + diff --git a/3rd/lua-5.3.4/lcode.h b/3rd/lua-5.3.4/lcode.h new file mode 100644 index 0000000..cd306d5 --- /dev/null +++ b/3rd/lua-5.3.4/lcode.h @@ -0,0 +1,88 @@ +/* +** $Id: lcode.h,v 1.64 2016/01/05 16:22:37 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums (ORDER OP) +*/ +typedef enum BinOpr { + OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, + OPR_DIV, + OPR_IDIV, + OPR_BAND, OPR_BOR, OPR_BXOR, + OPR_SHL, OPR_SHR, + OPR_CONCAT, + OPR_EQ, OPR_LT, OPR_LE, + OPR_NE, OPR_GT, OPR_GE, + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + + +typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; + + +/* get (pointer to) instruction of given 'expdesc' */ +#define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) + +#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) + +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) + +#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) + +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); +LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); +LUAI_FUNC void luaK_fixline (FuncState *fs, int line); +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); +LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); +LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n); +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump (FuncState *fs); +LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); +LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); +LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); +LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); +LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); +LUAI_FUNC int luaK_getlabel (FuncState *fs); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, + expdesc *v2, int line); +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); + + +#endif diff --git a/3rd/lua-5.3.4/lcorolib.c b/3rd/lua-5.3.4/lcorolib.c new file mode 100644 index 0000000..2303429 --- /dev/null +++ b/3rd/lua-5.3.4/lcorolib.c @@ -0,0 +1,168 @@ +/* +** $Id: lcorolib.c,v 1.10 2016/04/11 19:19:55 roberto Exp $ +** Coroutine Library +** See Copyright Notice in lua.h +*/ + +#define lcorolib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static lua_State *getco (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "thread expected"); + return co; +} + + +static int auxresume (lua_State *L, lua_State *co, int narg) { + int status; + if (!lua_checkstack(co, narg)) { + lua_pushliteral(L, "too many arguments to resume"); + return -1; /* error flag */ + } + if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { + lua_pushliteral(L, "cannot resume dead coroutine"); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + status = lua_resume(co, L, narg); + if (status == LUA_OK || status == LUA_YIELD) { + int nres = lua_gettop(co); + if (!lua_checkstack(L, nres + 1)) { + lua_pop(co, nres); /* remove results anyway */ + lua_pushliteral(L, "too many results to resume"); + return -1; /* error flag */ + } + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } +} + + +static int luaB_coresume (lua_State *L) { + lua_State *co = getco(L); + int r; + r = auxresume(L, co, lua_gettop(L) - 1); + if (r < 0) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + 'resume' returns */ + } +} + + +static int luaB_auxwrap (lua_State *L) { + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (r < 0) { + if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); + } + return lua_error(L); /* propagate error */ + } + return r; +} + + +static int luaB_cocreate (lua_State *L) { + lua_State *NL; + luaL_checktype(L, 1, LUA_TFUNCTION); + NL = lua_newthread(L); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} + + +static int luaB_cowrap (lua_State *L) { + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; +} + + +static int luaB_yield (lua_State *L) { + return lua_yield(L, lua_gettop(L)); +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = getco(L); + if (L == co) lua_pushliteral(L, "running"); + else { + switch (lua_status(co)) { + case LUA_YIELD: + lua_pushliteral(L, "suspended"); + break; + case LUA_OK: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + lua_pushliteral(L, "normal"); /* it is running */ + else if (lua_gettop(co) == 0) + lua_pushliteral(L, "dead"); + else + lua_pushliteral(L, "suspended"); /* initial state */ + break; + } + default: /* some error occurred */ + lua_pushliteral(L, "dead"); + break; + } + } + return 1; +} + + +static int luaB_yieldable (lua_State *L) { + lua_pushboolean(L, lua_isyieldable(L)); + return 1; +} + + +static int luaB_corunning (lua_State *L) { + int ismain = lua_pushthread(L); + lua_pushboolean(L, ismain); + return 2; +} + + +static const luaL_Reg co_funcs[] = { + {"create", luaB_cocreate}, + {"resume", luaB_coresume}, + {"running", luaB_corunning}, + {"status", luaB_costatus}, + {"wrap", luaB_cowrap}, + {"yield", luaB_yield}, + {"isyieldable", luaB_yieldable}, + {NULL, NULL} +}; + + + +LUAMOD_API int luaopen_coroutine (lua_State *L) { + luaL_newlib(L, co_funcs); + return 1; +} + diff --git a/3rd/lua-5.3.4/lctype.c b/3rd/lua-5.3.4/lctype.c new file mode 100644 index 0000000..ae9367e --- /dev/null +++ b/3rd/lua-5.3.4/lctype.c @@ -0,0 +1,55 @@ +/* +** $Id: lctype.c,v 1.12 2014/11/02 19:19:04 roberto Exp $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#define lctype_c +#define LUA_CORE + +#include "lprefix.h" + + +#include "lctype.h" + +#if !LUA_USE_CTYPE /* { */ + +#include + +LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { + 0x00, /* EOZ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ + 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, + 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#endif /* } */ diff --git a/3rd/lua-5.3.4/lctype.h b/3rd/lua-5.3.4/lctype.h new file mode 100644 index 0000000..99c7d12 --- /dev/null +++ b/3rd/lua-5.3.4/lctype.h @@ -0,0 +1,95 @@ +/* +** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lctype_h +#define lctype_h + +#include "lua.h" + + +/* +** WARNING: the functions defined here do not necessarily correspond +** to the similar functions in the standard C ctype.h. They are +** optimized for the specific needs of Lua +*/ + +#if !defined(LUA_USE_CTYPE) + +#if 'A' == 65 && '0' == 48 +/* ASCII case: can use its own tables; faster and fixed */ +#define LUA_USE_CTYPE 0 +#else +/* must use standard C ctype */ +#define LUA_USE_CTYPE 1 +#endif + +#endif + + +#if !LUA_USE_CTYPE /* { */ + +#include + +#include "llimits.h" + + +#define ALPHABIT 0 +#define DIGITBIT 1 +#define PRINTBIT 2 +#define SPACEBIT 3 +#define XDIGITBIT 4 + + +#define MASK(B) (1 << (B)) + + +/* +** add 1 to char to allow index -1 (EOZ) +*/ +#define testprop(c,p) (luai_ctype_[(c)+1] & (p)) + +/* +** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' +*/ +#define lislalpha(c) testprop(c, MASK(ALPHABIT)) +#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) +#define lisdigit(c) testprop(c, MASK(DIGITBIT)) +#define lisspace(c) testprop(c, MASK(SPACEBIT)) +#define lisprint(c) testprop(c, MASK(PRINTBIT)) +#define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) + +/* +** this 'ltolower' only works for alphabetic characters +*/ +#define ltolower(c) ((c) | ('A' ^ 'a')) + + +/* two more entries for 0 and -1 (EOZ) */ +LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; + + +#else /* }{ */ + +/* +** use standard C ctypes +*/ + +#include + + +#define lislalpha(c) (isalpha(c) || (c) == '_') +#define lislalnum(c) (isalnum(c) || (c) == '_') +#define lisdigit(c) (isdigit(c)) +#define lisspace(c) (isspace(c)) +#define lisprint(c) (isprint(c)) +#define lisxdigit(c) (isxdigit(c)) + +#define ltolower(c) (tolower(c)) + +#endif /* } */ + +#endif + diff --git a/3rd/lua-5.3.4/ldblib.c b/3rd/lua-5.3.4/ldblib.c new file mode 100644 index 0000000..786f6cd --- /dev/null +++ b/3rd/lua-5.3.4/ldblib.c @@ -0,0 +1,456 @@ +/* +** $Id: ldblib.c,v 1.151 2015/11/23 11:29:43 roberto Exp $ +** Interface from Lua to its debug API +** See Copyright Notice in lua.h +*/ + +#define ldblib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** The hook table at registry[&HOOKKEY] maps threads to their current +** hook function. (We only need the unique address of 'HOOKKEY'.) +*/ +static const int HOOKKEY = 0; + + +/* +** If L1 != L, L1 can be in any state, and therefore there are no +** guarantees about its stack space; any push in L1 must be +** checked. +*/ +static void checkstack (lua_State *L, lua_State *L1, int n) { + if (L != L1 && !lua_checkstack(L1, n)) + luaL_error(L, "stack overflow"); +} + + +static int db_getregistry (lua_State *L) { + lua_pushvalue(L, LUA_REGISTRYINDEX); + return 1; +} + + +static int db_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); /* no metatable */ + } + return 1; +} + + +static int db_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; /* return 1st argument */ +} + + +static int db_getuservalue (lua_State *L) { + if (lua_type(L, 1) != LUA_TUSERDATA) + lua_pushnil(L); + else + lua_getuservalue(L, 1); + return 1; +} + + +static int db_setuservalue (lua_State *L) { + luaL_checktype(L, 1, LUA_TUSERDATA); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_setuservalue(L, 1); + return 1; +} + + +/* +** Auxiliary function used by several library functions: check for +** an optional thread as function's first argument and set 'arg' with +** 1 if this argument is present (so that functions can skip it to +** access their other arguments) +*/ +static lua_State *getthread (lua_State *L, int *arg) { + if (lua_isthread(L, 1)) { + *arg = 1; + return lua_tothread(L, 1); + } + else { + *arg = 0; + return L; /* function will operate over current thread */ + } +} + + +/* +** Variations of 'lua_settable', used by 'db_getinfo' to put results +** from 'lua_getinfo' into result table. Key is always a string; +** value can be a string, an int, or a boolean. +*/ +static void settabss (lua_State *L, const char *k, const char *v) { + lua_pushstring(L, v); + lua_setfield(L, -2, k); +} + +static void settabsi (lua_State *L, const char *k, int v) { + lua_pushinteger(L, v); + lua_setfield(L, -2, k); +} + +static void settabsb (lua_State *L, const char *k, int v) { + lua_pushboolean(L, v); + lua_setfield(L, -2, k); +} + + +/* +** In function 'db_getinfo', the call to 'lua_getinfo' may push +** results on the stack; later it creates the result table to put +** these objects. Function 'treatstackoption' puts the result from +** 'lua_getinfo' on top of the result table so that it can call +** 'lua_setfield'. +*/ +static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { + if (L == L1) + lua_rotate(L, -2, 1); /* exchange object and table */ + else + lua_xmove(L1, L, 1); /* move object to the "main" stack */ + lua_setfield(L, -2, fname); /* put object into table */ +} + + +/* +** Calls 'lua_getinfo' and collects all results in a new table. +** L1 needs stack space for an optional input (function) plus +** two optional outputs (function and line table) from function +** 'lua_getinfo'. +*/ +static int db_getinfo (lua_State *L) { + lua_Debug ar; + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg+2, "flnStu"); + checkstack(L, L1, 3); + if (lua_isfunction(L, arg + 1)) { /* info about a function? */ + options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */ + lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */ + lua_xmove(L, L1, 1); + } + else { /* stack level */ + if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) { + lua_pushnil(L); /* level out of range */ + return 1; + } + } + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg+2, "invalid option"); + lua_newtable(L); /* table to collect results */ + if (strchr(options, 'S')) { + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) { + settabsi(L, "nups", ar.nups); + settabsi(L, "nparams", ar.nparams); + settabsb(L, "isvararg", ar.isvararg); + } + if (strchr(options, 'n')) { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 't')) + settabsb(L, "istailcall", ar.istailcall); + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); + return 1; /* return table */ +} + + +static int db_getlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + const char *name; + int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */ + if (lua_isfunction(L, arg + 1)) { /* function argument? */ + lua_pushvalue(L, arg + 1); /* push function */ + lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */ + return 1; /* return only name (there is no value) */ + } + else { /* stack-level argument */ + int level = (int)luaL_checkinteger(L, arg + 1); + if (!lua_getstack(L1, level, &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + checkstack(L, L1, 1); + name = lua_getlocal(L1, &ar, nvar); + if (name) { + lua_xmove(L1, L, 1); /* move local value */ + lua_pushstring(L, name); /* push name */ + lua_rotate(L, -2, 1); /* re-order */ + return 2; + } + else { + lua_pushnil(L); /* no name (nor value) */ + return 1; + } + } +} + + +static int db_setlocal (lua_State *L) { + int arg; + const char *name; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + int level = (int)luaL_checkinteger(L, arg + 1); + int nvar = (int)luaL_checkinteger(L, arg + 2); + if (!lua_getstack(L1, level, &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + luaL_checkany(L, arg+3); + lua_settop(L, arg+3); + checkstack(L, L1, 1); + lua_xmove(L, L1, 1); + name = lua_setlocal(L1, &ar, nvar); + if (name == NULL) + lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */ + lua_pushstring(L, name); + return 1; +} + + +/* +** get (if 'get' is true) or set an upvalue from a closure +*/ +static int auxupvalue (lua_State *L, int get) { + const char *name; + int n = (int)luaL_checkinteger(L, 2); /* upvalue index */ + luaL_checktype(L, 1, LUA_TFUNCTION); /* closure */ + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + lua_insert(L, -(get+1)); /* no-op if get is false */ + return get + 1; +} + + +static int db_getupvalue (lua_State *L) { + return auxupvalue(L, 1); +} + + +static int db_setupvalue (lua_State *L) { + luaL_checkany(L, 3); + return auxupvalue(L, 0); +} + + +/* +** Check whether a given upvalue from a given closure exists and +** returns its index +*/ +static int checkupval (lua_State *L, int argf, int argnup) { + int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */ + luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */ + luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup, + "invalid upvalue index"); + return nup; +} + + +static int db_upvalueid (lua_State *L) { + int n = checkupval(L, 1, 2); + lua_pushlightuserdata(L, lua_upvalueid(L, 1, n)); + return 1; +} + + +static int db_upvaluejoin (lua_State *L) { + int n1 = checkupval(L, 1, 2); + int n2 = checkupval(L, 3, 4); + luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected"); + luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected"); + lua_upvaluejoin(L, 1, n1, 3, n2); + return 0; +} + + +/* +** Call hook function registered at hook table for the current +** thread (if there is one) +*/ +static void hookf (lua_State *L, lua_Debug *ar) { + static const char *const hooknames[] = + {"call", "return", "line", "count", "tail call"}; + lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY); + lua_pushthread(L); + if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */ + lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */ + if (ar->currentline >= 0) + lua_pushinteger(L, ar->currentline); /* push current line */ + else lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); /* call hook function */ + } +} + + +/* +** Convert a string mask (for 'sethook') into a bit mask +*/ +static int makemask (const char *smask, int count) { + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + return mask; +} + + +/* +** Convert a bit mask (for 'gethook') into a string mask +*/ +static char *unmakemask (int mask, char *smask) { + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; +} + + +static int db_sethook (lua_State *L) { + int arg, mask, count; + lua_Hook func; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg+1)) { /* no hook? */ + lua_settop(L, arg+1); + func = NULL; mask = 0; count = 0; /* turn off hooks */ + } + else { + const char *smask = luaL_checkstring(L, arg+2); + luaL_checktype(L, arg+1, LUA_TFUNCTION); + count = (int)luaL_optinteger(L, arg + 3, 0); + func = hookf; mask = makemask(smask, count); + } + if (lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY) == LUA_TNIL) { + lua_createtable(L, 0, 2); /* create a hook table */ + lua_pushvalue(L, -1); + lua_rawsetp(L, LUA_REGISTRYINDEX, &HOOKKEY); /* set it in position */ + lua_pushstring(L, "k"); + lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ + lua_pushvalue(L, -1); + lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ + } + checkstack(L, L1, 1); + lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */ + lua_pushvalue(L, arg + 1); /* value (hook function) */ + lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */ + lua_sethook(L1, func, mask, count); + return 0; +} + + +static int db_gethook (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + char buff[5]; + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); + if (hook == NULL) /* no hook? */ + lua_pushnil(L); + else if (hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else { /* hook table must exist */ + lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY); + checkstack(L, L1, 1); + lua_pushthread(L1); lua_xmove(L1, L, 1); + lua_rawget(L, -2); /* 1st result = hooktable[L1] */ + lua_remove(L, -2); /* remove hook table */ + } + lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */ + lua_pushinteger(L, lua_gethookcount(L1)); /* 3rd result = count */ + return 3; +} + + +static int db_debug (lua_State *L) { + for (;;) { + char buffer[250]; + lua_writestringerror("%s", "lua_debug> "); + if (fgets(buffer, sizeof(buffer), stdin) == 0 || + strcmp(buffer, "cont\n") == 0) + return 0; + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || + lua_pcall(L, 0, 0, 0)) + lua_writestringerror("%s\n", lua_tostring(L, -1)); + lua_settop(L, 0); /* remove eventual returns */ + } +} + + +static int db_traceback (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + const char *msg = lua_tostring(L, arg + 1); + if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */ + lua_pushvalue(L, arg + 1); /* return it untouched */ + else { + int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0); + luaL_traceback(L, L1, msg, level); + } + return 1; +} + + +static const luaL_Reg dblib[] = { + {"debug", db_debug}, + {"getuservalue", db_getuservalue}, + {"gethook", db_gethook}, + {"getinfo", db_getinfo}, + {"getlocal", db_getlocal}, + {"getregistry", db_getregistry}, + {"getmetatable", db_getmetatable}, + {"getupvalue", db_getupvalue}, + {"upvaluejoin", db_upvaluejoin}, + {"upvalueid", db_upvalueid}, + {"setuservalue", db_setuservalue}, + {"sethook", db_sethook}, + {"setlocal", db_setlocal}, + {"setmetatable", db_setmetatable}, + {"setupvalue", db_setupvalue}, + {"traceback", db_traceback}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_debug (lua_State *L) { + luaL_newlib(L, dblib); + return 1; +} + diff --git a/3rd/lua-5.3.4/ldebug.c b/3rd/lua-5.3.4/ldebug.c new file mode 100644 index 0000000..239affb --- /dev/null +++ b/3rd/lua-5.3.4/ldebug.c @@ -0,0 +1,698 @@ +/* +** $Id: ldebug.c,v 2.121 2016/10/19 12:32:10 roberto Exp $ +** Debug Interface +** See Copyright Notice in lua.h +*/ + +#define ldebug_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) + + +/* Active Lua function (given call info) */ +#define ci_func(ci) (clLvalue((ci)->func)) + + +static const char *funcnamefromcode (lua_State *L, CallInfo *ci, + const char **name); + + +static int currentpc (CallInfo *ci) { + lua_assert(isLua(ci)); + return pcRel(ci->u.l.savedpc, ci_func(ci)->p); +} + + +static int currentline (CallInfo *ci) { + return getfuncline(ci_func(ci)->p, currentpc(ci)); +} + + +/* +** If function yielded, its 'func' can be in the 'extra' field. The +** next function restores 'func' to its correct value for debugging +** purposes. (It exchanges 'func' and 'extra'; so, when called again, +** after debugging, it also "re-restores" ** 'func' to its altered value. +*/ +static void swapextra (lua_State *L) { + if (L->status == LUA_YIELD) { + CallInfo *ci = L->ci; /* get function that yielded */ + StkId temp = ci->func; /* exchange its 'func' and 'extra' values */ + ci->func = restorestack(L, ci->extra); + ci->extra = savestack(L, temp); + } +} + + +/* +** This function can be called asynchronously (e.g. during a signal). +** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by +** 'resethookcount') are for debug only, and it is no problem if they +** get arbitrary values (causes at most one wrong hook call). 'hookmask' +** is an atomic value. We assume that pointers are atomic too (e.g., gcc +** ensures that for all platforms where it runs). Moreover, 'hook' is +** always checked before being called (see 'luaD_hook'). +*/ +LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { + if (func == NULL || mask == 0) { /* turn off hooks? */ + mask = 0; + func = NULL; + } + if (isLua(L->ci)) + L->oldpc = L->ci->u.l.savedpc; + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast_byte(mask); +} + + +LUA_API lua_Hook lua_gethook (lua_State *L) { + return L->hook; +} + + +LUA_API int lua_gethookmask (lua_State *L) { + return L->hookmask; +} + + +LUA_API int lua_gethookcount (lua_State *L) { + return L->basehookcount; +} + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { + int status; + CallInfo *ci; + if (level < 0) return 0; /* invalid (negative) level */ + lua_lock(L); + for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) + level--; + if (level == 0 && ci != &L->base_ci) { /* level found? */ + status = 1; + ar->i_ci = ci; + } + else status = 0; /* no such level */ + lua_unlock(L); + return status; +} + + +static const char *upvalname (Proto *p, int uv) { + TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); + if (s == NULL) return "?"; + else return getstr(s); +} + + +static const char *findvararg (CallInfo *ci, int n, StkId *pos) { + int nparams = clLvalue(ci->func)->p->numparams; + if (n >= cast_int(ci->u.l.base - ci->func) - nparams) + return NULL; /* no such vararg */ + else { + *pos = ci->func + nparams + n; + return "(*vararg)"; /* generic name for any vararg */ + } +} + + +static const char *findlocal (lua_State *L, CallInfo *ci, int n, + StkId *pos) { + const char *name = NULL; + StkId base; + if (isLua(ci)) { + if (n < 0) /* access to vararg values? */ + return findvararg(ci, -n, pos); + else { + base = ci->u.l.base; + name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); + } + } + else + base = ci->func + 1; + if (name == NULL) { /* no 'standard' name? */ + StkId limit = (ci == L->ci) ? L->top : ci->next->func; + if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ + name = "(*temporary)"; /* generic name for any valid slot */ + else + return NULL; /* no name */ + } + *pos = base + (n - 1); + return name; +} + + +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { + const char *name; + lua_lock(L); + swapextra(L); + if (ar == NULL) { /* information about non-active function? */ + if (!isLfunction(L->top - 1)) /* not a Lua function? */ + name = NULL; + else /* consider live variables at function start (parameters) */ + name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0); + } + else { /* active function; get information through 'ar' */ + StkId pos = NULL; /* to avoid warnings */ + name = findlocal(L, ar->i_ci, n, &pos); + if (name) { + setobj2s(L, L->top, pos); + api_incr_top(L); + } + } + swapextra(L); + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { + StkId pos = NULL; /* to avoid warnings */ + const char *name; + lua_lock(L); + swapextra(L); + name = findlocal(L, ar->i_ci, n, &pos); + if (name) { + setobjs2s(L, pos, L->top - 1); + L->top--; /* pop value */ + } + swapextra(L); + lua_unlock(L); + return name; +} + + +static void funcinfo (lua_Debug *ar, Closure *cl) { + if (noLuaClosure(cl)) { + ar->source = "=[C]"; + ar->linedefined = -1; + ar->lastlinedefined = -1; + ar->what = "C"; + } + else { + Proto *p = cl->l.p; + ar->source = p->source ? getstr(p->source) : "=?"; + ar->linedefined = p->linedefined; + ar->lastlinedefined = p->lastlinedefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); +} + + +static void collectvalidlines (lua_State *L, Closure *f) { + if (noLuaClosure(f)) { + setnilvalue(L->top); + api_incr_top(L); + } + else { + int i; + TValue v; + int *lineinfo = f->l.p->lineinfo; + Table *t = luaH_new(L); /* new table to store active lines */ + sethvalue(L, L->top, t); /* push it on stack */ + api_incr_top(L); + setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ + for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */ + luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */ + } +} + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { + if (ci == NULL) /* no 'ci'? */ + return NULL; /* no info */ + else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */ + *name = "__gc"; + return "metamethod"; /* report it as such */ + } + /* calling function is a known Lua function? */ + else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) + return funcnamefromcode(L, ci->previous, name); + else return NULL; /* no way to find a name */ +} + + +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, + Closure *f, CallInfo *ci) { + int status = 1; + for (; *what; what++) { + switch (*what) { + case 'S': { + funcinfo(ar, f); + break; + } + case 'l': { + ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1; + break; + } + case 'u': { + ar->nups = (f == NULL) ? 0 : f->c.nupvalues; + if (noLuaClosure(f)) { + ar->isvararg = 1; + ar->nparams = 0; + } + else { + ar->isvararg = f->l.p->is_vararg; + ar->nparams = f->l.p->numparams; + } + break; + } + case 't': { + ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; + break; + } + case 'n': { + ar->namewhat = getfuncname(L, ci, &ar->name); + if (ar->namewhat == NULL) { + ar->namewhat = ""; /* not found */ + ar->name = NULL; + } + break; + } + case 'L': + case 'f': /* handled by lua_getinfo */ + break; + default: status = 0; /* invalid option */ + } + } + return status; +} + + +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + int status; + Closure *cl; + CallInfo *ci; + StkId func; + lua_lock(L); + swapextra(L); + if (*what == '>') { + ci = NULL; + func = L->top - 1; + api_check(L, ttisfunction(func), "function expected"); + what++; /* skip the '>' */ + L->top--; /* pop function */ + } + else { + ci = ar->i_ci; + func = ci->func; + lua_assert(ttisfunction(ci->func)); + } + cl = ttisclosure(func) ? clvalue(func) : NULL; + status = auxgetinfo(L, what, ar, cl, ci); + if (strchr(what, 'f')) { + setobjs2s(L, L->top, func); + api_incr_top(L); + } + swapextra(L); /* correct before option 'L', which can raise a mem. error */ + if (strchr(what, 'L')) + collectvalidlines(L, cl); + lua_unlock(L); + return status; +} + + +/* +** {====================================================== +** Symbolic Execution +** ======================================================= +*/ + +static const char *getobjname (Proto *p, int lastpc, int reg, + const char **name); + + +/* +** find a "name" for the RK value 'c' +*/ +static void kname (Proto *p, int pc, int c, const char **name) { + if (ISK(c)) { /* is 'c' a constant? */ + TValue *kvalue = &p->k[INDEXK(c)]; + if (ttisstring(kvalue)) { /* literal constant? */ + *name = svalue(kvalue); /* it is its own name */ + return; + } + /* else no reasonable name found */ + } + else { /* 'c' is a register */ + const char *what = getobjname(p, pc, c, name); /* search for 'c' */ + if (what && *what == 'c') { /* found a constant name? */ + return; /* 'name' already filled */ + } + /* else no reasonable name found */ + } + *name = "?"; /* no reasonable name found */ +} + + +static int filterpc (int pc, int jmptarget) { + if (pc < jmptarget) /* is code conditional (inside a jump)? */ + return -1; /* cannot know who sets that register */ + else return pc; /* current position sets that register */ +} + + +/* +** try to find last instruction before 'lastpc' that modified register 'reg' +*/ +static int findsetreg (Proto *p, int lastpc, int reg) { + int pc; + int setreg = -1; /* keep last instruction that changed 'reg' */ + int jmptarget = 0; /* any code before this address is conditional */ + for (pc = 0; pc < lastpc; pc++) { + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + switch (op) { + case OP_LOADNIL: { + int b = GETARG_B(i); + if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ + setreg = filterpc(pc, jmptarget); + break; + } + case OP_TFORCALL: { + if (reg >= a + 2) /* affect all regs above its base */ + setreg = filterpc(pc, jmptarget); + break; + } + case OP_CALL: + case OP_TAILCALL: { + if (reg >= a) /* affect all registers above base */ + setreg = filterpc(pc, jmptarget); + break; + } + case OP_JMP: { + int b = GETARG_sBx(i); + int dest = pc + 1 + b; + /* jump is forward and do not skip 'lastpc'? */ + if (pc < dest && dest <= lastpc) { + if (dest > jmptarget) + jmptarget = dest; /* update 'jmptarget' */ + } + break; + } + default: + if (testAMode(op) && reg == a) /* any instruction that set A */ + setreg = filterpc(pc, jmptarget); + break; + } + } + return setreg; +} + + +static const char *getobjname (Proto *p, int lastpc, int reg, + const char **name) { + int pc; + *name = luaF_getlocalname(p, reg + 1, lastpc); + if (*name) /* is a local? */ + return "local"; + /* else try symbolic execution */ + pc = findsetreg(p, lastpc, reg); + if (pc != -1) { /* could find instruction? */ + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + switch (op) { + case OP_MOVE: { + int b = GETARG_B(i); /* move from 'b' to 'a' */ + if (b < GETARG_A(i)) + return getobjname(p, pc, b, name); /* get name for 'b' */ + break; + } + case OP_GETTABUP: + case OP_GETTABLE: { + int k = GETARG_C(i); /* key index */ + int t = GETARG_B(i); /* table index */ + const char *vn = (op == OP_GETTABLE) /* name of indexed variable */ + ? luaF_getlocalname(p, t + 1, pc) + : upvalname(p, t); + kname(p, pc, k, name); + return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; + } + case OP_GETUPVAL: { + *name = upvalname(p, GETARG_B(i)); + return "upvalue"; + } + case OP_LOADK: + case OP_LOADKX: { + int b = (op == OP_LOADK) ? GETARG_Bx(i) + : GETARG_Ax(p->code[pc + 1]); + if (ttisstring(&p->k[b])) { + *name = svalue(&p->k[b]); + return "constant"; + } + break; + } + case OP_SELF: { + int k = GETARG_C(i); /* key index */ + kname(p, pc, k, name); + return "method"; + } + default: break; /* go through to return NULL */ + } + } + return NULL; /* could not find reasonable name */ +} + + +/* +** Try to find a name for a function based on the code that called it. +** (Only works when function was called by a Lua function.) +** Returns what the name is (e.g., "for iterator", "method", +** "metamethod") and sets '*name' to point to the name. +*/ +static const char *funcnamefromcode (lua_State *L, CallInfo *ci, + const char **name) { + TMS tm = (TMS)0; /* (initial value avoids warnings) */ + Proto *p = ci_func(ci)->p; /* calling function */ + int pc = currentpc(ci); /* calling instruction index */ + Instruction i = p->code[pc]; /* calling instruction */ + if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ + *name = "?"; + return "hook"; + } + switch (GET_OPCODE(i)) { + case OP_CALL: + case OP_TAILCALL: + return getobjname(p, pc, GETARG_A(i), name); /* get function name */ + case OP_TFORCALL: { /* for iterator */ + *name = "for iterator"; + return "for iterator"; + } + /* other instructions can do calls through metamethods */ + case OP_SELF: case OP_GETTABUP: case OP_GETTABLE: + tm = TM_INDEX; + break; + case OP_SETTABUP: case OP_SETTABLE: + tm = TM_NEWINDEX; + break; + case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD: + case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND: + case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: { + int offset = cast_int(GET_OPCODE(i)) - cast_int(OP_ADD); /* ORDER OP */ + tm = cast(TMS, offset + cast_int(TM_ADD)); /* ORDER TM */ + break; + } + case OP_UNM: tm = TM_UNM; break; + case OP_BNOT: tm = TM_BNOT; break; + case OP_LEN: tm = TM_LEN; break; + case OP_CONCAT: tm = TM_CONCAT; break; + case OP_EQ: tm = TM_EQ; break; + case OP_LT: tm = TM_LT; break; + case OP_LE: tm = TM_LE; break; + default: + return NULL; /* cannot find a reasonable name */ + } + *name = getstr(G(L)->tmname[tm]); + return "metamethod"; +} + +/* }====================================================== */ + + + +/* +** The subtraction of two potentially unrelated pointers is +** not ISO C, but it should not crash a program; the subsequent +** checks are ISO C and ensure a correct result. +*/ +static int isinstack (CallInfo *ci, const TValue *o) { + ptrdiff_t i = o - ci->u.l.base; + return (0 <= i && i < (ci->top - ci->u.l.base) && ci->u.l.base + i == o); +} + + +/* +** Checks whether value 'o' came from an upvalue. (That can only happen +** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on +** upvalues.) +*/ +static const char *getupvalname (CallInfo *ci, const TValue *o, + const char **name) { + LClosure *c = ci_func(ci); + int i; + for (i = 0; i < c->nupvalues; i++) { + if (c->upvals[i]->v == o) { + *name = upvalname(c->p, i); + return "upvalue"; + } + } + return NULL; +} + + +static const char *varinfo (lua_State *L, const TValue *o) { + const char *name = NULL; /* to avoid warnings */ + CallInfo *ci = L->ci; + const char *kind = NULL; + if (isLua(ci)) { + kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ + if (!kind && isinstack(ci, o)) /* no? try a register */ + kind = getobjname(ci_func(ci)->p, currentpc(ci), + cast_int(o - ci->u.l.base), &name); + } + return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : ""; +} + + +l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { + const char *t = luaT_objtypename(L, o); + luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o)); +} + + +l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) { + if (ttisstring(p1) || cvt2str(p1)) p1 = p2; + luaG_typeerror(L, p1, "concatenate"); +} + + +l_noret luaG_opinterror (lua_State *L, const TValue *p1, + const TValue *p2, const char *msg) { + lua_Number temp; + if (!tonumber(p1, &temp)) /* first operand is wrong? */ + p2 = p1; /* now second is wrong */ + luaG_typeerror(L, p2, msg); +} + + +/* +** Error when both values are convertible to numbers, but not to integers +*/ +l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { + lua_Integer temp; + if (!tointeger(p1, &temp)) + p2 = p1; + luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2)); +} + + +l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { + const char *t1 = luaT_objtypename(L, p1); + const char *t2 = luaT_objtypename(L, p2); + if (strcmp(t1, t2) == 0) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); +} + + +/* add src:line information to 'msg' */ +const char *luaG_addinfo (lua_State *L, const char *msg, TString *src, + int line) { + char buff[LUA_IDSIZE]; + if (src) + luaO_chunkid(buff, getstr(src), LUA_IDSIZE); + else { /* no source available; use "?" instead */ + buff[0] = '?'; buff[1] = '\0'; + } + return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); +} + + +l_noret luaG_errormsg (lua_State *L) { + if (L->errfunc != 0) { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + setobjs2s(L, L->top, L->top - 1); /* move argument */ + setobjs2s(L, L->top - 1, errfunc); /* push function */ + L->top++; /* assume EXTRA_STACK */ + luaD_callnoyield(L, L->top - 2, 1); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); +} + + +l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { + CallInfo *ci = L->ci; + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); /* format message */ + va_end(argp); + if (isLua(ci)) /* if Lua function, add source:line information */ + luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci)); + luaG_errormsg(L); +} + + +void luaG_traceexec (lua_State *L) { + CallInfo *ci = L->ci; + lu_byte mask = L->hookmask; + int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); + if (counthook) + resethookcount(L); /* reset count */ + else if (!(mask & LUA_MASKLINE)) + return; /* no line hook and count != 0; nothing to be done */ + if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ + ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ + return; /* do not call hook again (VM yielded, so it did not move) */ + } + if (counthook) + luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ + if (mask & LUA_MASKLINE) { + Proto *p = ci_func(ci)->p; + int npc = pcRel(ci->u.l.savedpc, p); + int newline = getfuncline(p, npc); + if (npc == 0 || /* call linehook when enter a new function, */ + ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ + newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ + luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ + } + L->oldpc = ci->u.l.savedpc; + if (L->status == LUA_YIELD) { /* did hook yield? */ + if (counthook) + L->hookcount = 1; /* undo decrement to zero */ + ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ + ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ + ci->func = L->top - 1; /* protect stack below results */ + luaD_throw(L, LUA_YIELD); + } +} + diff --git a/3rd/lua-5.3.4/ldebug.h b/3rd/lua-5.3.4/ldebug.h new file mode 100644 index 0000000..0e31546 --- /dev/null +++ b/3rd/lua-5.3.4/ldebug.h @@ -0,0 +1,39 @@ +/* +** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 roberto Exp $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" + + +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) + +#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1) + +#define resethookcount(L) (L->hookcount = L->basehookcount) + + +LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, + const TValue *p2, + const char *msg); +LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, + TString *src, int line); +LUAI_FUNC l_noret luaG_errormsg (lua_State *L); +LUAI_FUNC void luaG_traceexec (lua_State *L); + + +#endif diff --git a/3rd/lua-5.3.4/ldo.c b/3rd/lua-5.3.4/ldo.c new file mode 100644 index 0000000..90b695f --- /dev/null +++ b/3rd/lua-5.3.4/ldo.c @@ -0,0 +1,802 @@ +/* +** $Id: ldo.c,v 2.157 2016/12/13 15:52:21 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#define ldo_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" +#include "lzio.h" + + + +#define errorstatus(s) ((s) > LUA_YIELD) + + +/* +** {====================================================== +** Error-recovery functions +** ======================================================= +*/ + +/* +** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By +** default, Lua handles errors with exceptions when compiling as +** C++ code, with _longjmp/_setjmp when asked to use them, and with +** longjmp/setjmp otherwise. +*/ +#if !defined(LUAI_THROW) /* { */ + +#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* { */ + +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) \ + try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_POSIX) /* }{ */ + +/* in POSIX, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else /* }{ */ + +/* ISO C handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif /* } */ + +#endif /* } */ + + + +/* chain list of long jump buffers */ +struct lua_longjmp { + struct lua_longjmp *previous; + luai_jmpbuf b; + volatile int status; /* error code */ +}; + + +static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { + switch (errcode) { + case LUA_ERRMEM: { /* memory error? */ + setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ + break; + } + case LUA_ERRERR: { + setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); + break; + } + default: { + setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ + break; + } + } + L->top = oldtop + 1; +} + + +l_noret luaD_throw (lua_State *L, int errcode) { + if (L->errorJmp) { /* thread has an error handler? */ + L->errorJmp->status = errcode; /* set status */ + LUAI_THROW(L, L->errorJmp); /* jump to it */ + } + else { /* thread has no error handler */ + global_State *g = G(L); + L->status = cast_byte(errcode); /* mark it as dead */ + if (g->mainthread->errorJmp) { /* main thread has a handler? */ + setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */ + luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ + } + else { /* no handler at all; abort */ + if (g->panic) { /* panic function? */ + seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */ + if (L->ci->top < L->top) + L->ci->top = L->top; /* pushing msg. can break this invariant */ + lua_unlock(L); + g->panic(L); /* call panic function (last chance to jump out) */ + } + abort(); + } + } +} + + +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + unsigned short oldnCcalls = L->nCcalls; + struct lua_longjmp lj; + lj.status = LUA_OK; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + LUAI_TRY(L, &lj, + (*f)(L, ud); + ); + L->errorJmp = lj.previous; /* restore old error handler */ + L->nCcalls = oldnCcalls; + return lj.status; +} + +/* }====================================================== */ + + +/* +** {================================================================== +** Stack reallocation +** =================================================================== +*/ +static void correctstack (lua_State *L, TValue *oldstack) { + CallInfo *ci; + UpVal *up; + L->top = (L->top - oldstack) + L->stack; + for (up = L->openupval; up != NULL; up = up->u.open.next) + up->v = (up->v - oldstack) + L->stack; + for (ci = L->ci; ci != NULL; ci = ci->previous) { + ci->top = (ci->top - oldstack) + L->stack; + ci->func = (ci->func - oldstack) + L->stack; + if (isLua(ci)) + ci->u.l.base = (ci->u.l.base - oldstack) + L->stack; + } +} + + +/* some space for error handling */ +#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) + + +void luaD_reallocstack (lua_State *L, int newsize) { + TValue *oldstack = L->stack; + int lim = L->stacksize; + lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); + luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue); + for (; lim < newsize; lim++) + setnilvalue(L->stack + lim); /* erase new segment */ + L->stacksize = newsize; + L->stack_last = L->stack + newsize - EXTRA_STACK; + correctstack(L, oldstack); +} + + +void luaD_growstack (lua_State *L, int n) { + int size = L->stacksize; + if (size > LUAI_MAXSTACK) /* error after extra size? */ + luaD_throw(L, LUA_ERRERR); + else { + int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; + int newsize = 2 * size; + if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK; + if (newsize < needed) newsize = needed; + if (newsize > LUAI_MAXSTACK) { /* stack overflow? */ + luaD_reallocstack(L, ERRORSTACKSIZE); + luaG_runerror(L, "stack overflow"); + } + else + luaD_reallocstack(L, newsize); + } +} + + +static int stackinuse (lua_State *L) { + CallInfo *ci; + StkId lim = L->top; + for (ci = L->ci; ci != NULL; ci = ci->previous) { + if (lim < ci->top) lim = ci->top; + } + lua_assert(lim <= L->stack_last); + return cast_int(lim - L->stack) + 1; /* part of stack in use */ +} + + +void luaD_shrinkstack (lua_State *L) { + int inuse = stackinuse(L); + int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; + if (goodsize > LUAI_MAXSTACK) + goodsize = LUAI_MAXSTACK; /* respect stack limit */ + if (L->stacksize > LUAI_MAXSTACK) /* had been handling stack overflow? */ + luaE_freeCI(L); /* free all CIs (list grew because of an error) */ + else + luaE_shrinkCI(L); /* shrink list */ + /* if thread is currently not handling a stack overflow and its + good size is smaller than current size, shrink its stack */ + if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && + goodsize < L->stacksize) + luaD_reallocstack(L, goodsize); + else /* don't change stack */ + condmovestack(L,{},{}); /* (change only for debugging) */ +} + + +void luaD_inctop (lua_State *L) { + luaD_checkstack(L, 1); + L->top++; +} + +/* }================================================================== */ + + +/* +** Call a hook for the given event. Make sure there is a hook to be +** called. (Both 'L->hook' and 'L->hookmask', which triggers this +** function, can be changed asynchronously by signals.) +*/ +void luaD_hook (lua_State *L, int event, int line) { + lua_Hook hook = L->hook; + if (hook && L->allowhook) { /* make sure there is a hook */ + CallInfo *ci = L->ci; + ptrdiff_t top = savestack(L, L->top); + ptrdiff_t ci_top = savestack(L, ci->top); + lua_Debug ar; + ar.event = event; + ar.currentline = line; + ar.i_ci = ci; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + L->allowhook = 0; /* cannot call hooks inside a hook */ + ci->callstatus |= CIST_HOOKED; + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + ci->top = restorestack(L, ci_top); + L->top = restorestack(L, top); + ci->callstatus &= ~CIST_HOOKED; + } +} + + +static void callhook (lua_State *L, CallInfo *ci) { + int hook = LUA_HOOKCALL; + ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ + if (isLua(ci->previous) && + GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) { + ci->callstatus |= CIST_TAIL; + hook = LUA_HOOKTAILCALL; + } + luaD_hook(L, hook, -1); + ci->u.l.savedpc--; /* correct 'pc' */ +} + + +static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { + int i; + int nfixargs = p->numparams; + StkId base, fixed; + /* move fixed parameters to final position */ + fixed = L->top - actual; /* first fixed argument */ + base = L->top; /* final position of first argument */ + for (i = 0; i < nfixargs && i < actual; i++) { + setobjs2s(L, L->top++, fixed + i); + setnilvalue(fixed + i); /* erase original copy (for GC) */ + } + for (; i < nfixargs; i++) + setnilvalue(L->top++); /* complete missing arguments */ + return base; +} + + +/* +** Check whether __call metafield of 'func' is a function. If so, put +** it in stack below original 'func' so that 'luaD_precall' can call +** it. Raise an error if __call metafield is not a function. +*/ +static void tryfuncTM (lua_State *L, StkId func) { + const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); + StkId p; + if (!ttisfunction(tm)) + luaG_typeerror(L, func, "call"); + /* Open a hole inside the stack at 'func' */ + for (p = L->top; p > func; p--) + setobjs2s(L, p, p-1); + L->top++; /* slot ensured by caller */ + setobj2s(L, func, tm); /* tag method is the new function to be called */ +} + + +/* +** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'. +** Handle most typical cases (zero results for commands, one result for +** expressions, multiple results for tail calls/single parameters) +** separated. +*/ +static int moveresults (lua_State *L, const TValue *firstResult, StkId res, + int nres, int wanted) { + switch (wanted) { /* handle typical cases separately */ + case 0: break; /* nothing to move */ + case 1: { /* one result needed */ + if (nres == 0) /* no results? */ + firstResult = luaO_nilobject; /* adjust with nil */ + setobjs2s(L, res, firstResult); /* move it to proper place */ + break; + } + case LUA_MULTRET: { + int i; + for (i = 0; i < nres; i++) /* move all results to correct place */ + setobjs2s(L, res + i, firstResult + i); + L->top = res + nres; + return 0; /* wanted == LUA_MULTRET */ + } + default: { + int i; + if (wanted <= nres) { /* enough results? */ + for (i = 0; i < wanted; i++) /* move wanted results to correct place */ + setobjs2s(L, res + i, firstResult + i); + } + else { /* not enough results; use all of them plus nils */ + for (i = 0; i < nres; i++) /* move all results to correct place */ + setobjs2s(L, res + i, firstResult + i); + for (; i < wanted; i++) /* complete wanted number of results */ + setnilvalue(res + i); + } + break; + } + } + L->top = res + wanted; /* top points after the last result */ + return 1; +} + + +/* +** Finishes a function call: calls hook if necessary, removes CallInfo, +** moves current number of results to proper place; returns 0 iff call +** wanted multiple (variable number of) results. +*/ +int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { + StkId res; + int wanted = ci->nresults; + if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { + if (L->hookmask & LUA_MASKRET) { + ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ + luaD_hook(L, LUA_HOOKRET, -1); + firstResult = restorestack(L, fr); + } + L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ + } + res = ci->func; /* res == final position of 1st result */ + L->ci = ci->previous; /* back to caller */ + /* move results to proper place */ + return moveresults(L, firstResult, res, nres, wanted); +} + + + +#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) + + +/* macro to check stack size, preserving 'p' */ +#define checkstackp(L,n,p) \ + luaD_checkstackaux(L, n, \ + ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ + luaC_checkGC(L), /* stack grow uses memory */ \ + p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ + + +/* +** Prepares a function call: checks the stack, creates a new CallInfo +** entry, fills in the relevant information, calls hook if needed. +** If function is a C function, does the call, too. (Otherwise, leave +** the execution ('luaV_execute') to the caller, to allow stackless +** calls.) Returns true iff function has been executed (C function). +*/ +int luaD_precall (lua_State *L, StkId func, int nresults) { + lua_CFunction f; + CallInfo *ci; + switch (ttype(func)) { + case LUA_TCCL: /* C closure */ + f = clCvalue(func)->f; + goto Cfunc; + case LUA_TLCF: /* light C function */ + f = fvalue(func); + Cfunc: { + int n; /* number of returns */ + checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = func; + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->callstatus = 0; + if (L->hookmask & LUA_MASKCALL) + luaD_hook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + n = (*f)(L); /* do the actual call */ + lua_lock(L); + api_checknelems(L, n); + luaD_poscall(L, ci, L->top - n, n); + return 1; + } + case LUA_TLCL: { /* Lua function: prepare its call */ + StkId base; + Proto *p = clLvalue(func)->p; + int n = cast_int(L->top - func) - 1; /* number of real arguments */ + int fsize = p->maxstacksize; /* frame size */ + checkstackp(L, fsize, func); + if (p->is_vararg) + base = adjust_varargs(L, p, n); + else { /* non vararg function */ + for (; n < p->numparams; n++) + setnilvalue(L->top++); /* complete missing arguments */ + base = func + 1; + } + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = func; + ci->u.l.base = base; + L->top = ci->top = base + fsize; + lua_assert(ci->top <= L->stack_last); + ci->u.l.savedpc = p->code; /* starting point */ + ci->callstatus = CIST_LUA; + if (L->hookmask & LUA_MASKCALL) + callhook(L, ci); + return 0; + } + default: { /* not a function */ + checkstackp(L, 1, func); /* ensure space for metamethod */ + tryfuncTM(L, func); /* try to get '__call' metamethod */ + return luaD_precall(L, func, nresults); /* now it must be a function */ + } + } +} + + +/* +** Check appropriate error for stack overflow ("regular" overflow or +** overflow while handling stack overflow). If 'nCalls' is larger than +** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but +** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to +** allow overflow handling to work) +*/ +static void stackerror (lua_State *L) { + if (L->nCcalls == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ +} + + +/* +** Call a function (C or Lua). The function to be called is at *func. +** The arguments are on the stack, right after the function. +** When returns, all the results are on the stack, starting at the original +** function position. +*/ +void luaD_call (lua_State *L, StkId func, int nResults) { + if (++L->nCcalls >= LUAI_MAXCCALLS) + stackerror(L); + if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ + luaV_execute(L); /* call it */ + L->nCcalls--; +} + + +/* +** Similar to 'luaD_call', but does not allow yields during the call +*/ +void luaD_callnoyield (lua_State *L, StkId func, int nResults) { + L->nny++; + luaD_call(L, func, nResults); + L->nny--; +} + + +/* +** Completes the execution of an interrupted C function, calling its +** continuation function. +*/ +static void finishCcall (lua_State *L, int status) { + CallInfo *ci = L->ci; + int n; + /* must have a continuation and must be able to call it */ + lua_assert(ci->u.c.k != NULL && L->nny == 0); + /* error status can only happen in a protected call */ + lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); + if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ + ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */ + L->errfunc = ci->u.c.old_errfunc; /* with the same error function */ + } + /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already + handled */ + adjustresults(L, ci->nresults); + lua_unlock(L); + n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ + lua_lock(L); + api_checknelems(L, n); + luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */ +} + + +/* +** Executes "full continuation" (everything in the stack) of a +** previously interrupted coroutine until the stack is empty (or another +** interruption long-jumps out of the loop). If the coroutine is +** recovering from an error, 'ud' points to the error status, which must +** be passed to the first continuation function (otherwise the default +** status is LUA_YIELD). +*/ +static void unroll (lua_State *L, void *ud) { + if (ud != NULL) /* error status? */ + finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */ + while (L->ci != &L->base_ci) { /* something in the stack */ + if (!isLua(L->ci)) /* C function? */ + finishCcall(L, LUA_YIELD); /* complete its execution */ + else { /* Lua function */ + luaV_finishOp(L); /* finish interrupted instruction */ + luaV_execute(L); /* execute down to higher C 'boundary' */ + } + } +} + + +/* +** Try to find a suspended protected call (a "recover point") for the +** given thread. +*/ +static CallInfo *findpcall (lua_State *L) { + CallInfo *ci; + for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ + if (ci->callstatus & CIST_YPCALL) + return ci; + } + return NULL; /* no pending pcall */ +} + + +/* +** Recovers from an error in a coroutine. Finds a recover point (if +** there is one) and completes the execution of the interrupted +** 'luaD_pcall'. If there is no recover point, returns zero. +*/ +static int recover (lua_State *L, int status) { + StkId oldtop; + CallInfo *ci = findpcall(L); + if (ci == NULL) return 0; /* no recovery point */ + /* "finish" luaD_pcall */ + oldtop = restorestack(L, ci->extra); + luaF_close(L, oldtop); + seterrorobj(L, status, oldtop); + L->ci = ci; + L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ + L->nny = 0; /* should be zero to be yieldable */ + luaD_shrinkstack(L); + L->errfunc = ci->u.c.old_errfunc; + return 1; /* continue running the coroutine */ +} + + +/* +** Signal an error in the call to 'lua_resume', not in the execution +** of the coroutine itself. (Such errors should not be handled by any +** coroutine error handler and should not kill the coroutine.) +*/ +static int resume_error (lua_State *L, const char *msg, int narg) { + L->top -= narg; /* remove args from the stack */ + setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */ + api_incr_top(L); + lua_unlock(L); + return LUA_ERRRUN; +} + + +/* +** Do the work for 'lua_resume' in protected mode. Most of the work +** depends on the status of the coroutine: initial state, suspended +** inside a hook, or regularly suspended (optionally with a continuation +** function), plus erroneous cases: non-suspended coroutine or dead +** coroutine. +*/ +static void resume (lua_State *L, void *ud) { + int n = *(cast(int*, ud)); /* number of arguments */ + StkId firstArg = L->top - n; /* first argument */ + CallInfo *ci = L->ci; + if (L->status == LUA_OK) { /* starting a coroutine? */ + if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ + luaV_execute(L); /* call it */ + } + else { /* resuming from previous yield */ + lua_assert(L->status == LUA_YIELD); + L->status = LUA_OK; /* mark that it is running (again) */ + ci->func = restorestack(L, ci->extra); + if (isLua(ci)) /* yielded inside a hook? */ + luaV_execute(L); /* just continue running Lua code */ + else { /* 'common' yield */ + if (ci->u.c.k != NULL) { /* does it have a continuation function? */ + lua_unlock(L); + n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ + lua_lock(L); + api_checknelems(L, n); + firstArg = L->top - n; /* yield results come from continuation */ + } + luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */ + } + unroll(L, NULL); /* run continuation */ + } +} + + +LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { + int status; + unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */ + lua_lock(L); + if (L->status == LUA_OK) { /* may be starting a coroutine */ + if (L->ci != &L->base_ci) /* not in base level? */ + return resume_error(L, "cannot resume non-suspended coroutine", nargs); + } + else if (L->status != LUA_YIELD) + return resume_error(L, "cannot resume dead coroutine", nargs); + L->nCcalls = (from) ? from->nCcalls + 1 : 1; + if (L->nCcalls >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow", nargs); + luai_userstateresume(L, nargs); + L->nny = 0; /* allow yields */ + api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); + status = luaD_rawrunprotected(L, resume, &nargs); + if (status == -1) /* error calling 'lua_resume'? */ + status = LUA_ERRRUN; + else { /* continue running after recoverable errors */ + while (errorstatus(status) && recover(L, status)) { + /* unroll continuation */ + status = luaD_rawrunprotected(L, unroll, &status); + } + if (errorstatus(status)) { /* unrecoverable error? */ + L->status = cast_byte(status); /* mark thread as 'dead' */ + seterrorobj(L, status, L->top); /* push error message */ + L->ci->top = L->top; + } + else lua_assert(status == L->status); /* normal end or yield */ + } + L->nny = oldnny; /* restore 'nny' */ + L->nCcalls--; + lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); + lua_unlock(L); + return status; +} + + +LUA_API int lua_isyieldable (lua_State *L) { + return (L->nny == 0); +} + + +LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, + lua_KFunction k) { + CallInfo *ci = L->ci; + luai_userstateyield(L, nresults); + lua_lock(L); + api_checknelems(L, nresults); + if (L->nny > 0) { + if (L != G(L)->mainthread) + luaG_runerror(L, "attempt to yield across a C-call boundary"); + else + luaG_runerror(L, "attempt to yield from outside a coroutine"); + } + L->status = LUA_YIELD; + ci->extra = savestack(L, ci->func); /* save current 'func' */ + if (isLua(ci)) { /* inside a hook? */ + api_check(L, k == NULL, "hooks cannot continue after yielding"); + } + else { + if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ + ci->u.c.ctx = ctx; /* save context */ + ci->func = L->top - nresults - 1; /* protect stack below results */ + luaD_throw(L, LUA_YIELD); + } + lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ + lua_unlock(L); + return 0; /* return to 'luaD_hook' */ +} + + +int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t old_top, ptrdiff_t ef) { + int status; + CallInfo *old_ci = L->ci; + lu_byte old_allowhooks = L->allowhook; + unsigned short old_nny = L->nny; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (status != LUA_OK) { /* an error occurred? */ + StkId oldtop = restorestack(L, old_top); + luaF_close(L, oldtop); /* close possible pending closures */ + seterrorobj(L, status, oldtop); + L->ci = old_ci; + L->allowhook = old_allowhooks; + L->nny = old_nny; + luaD_shrinkstack(L); + } + L->errfunc = old_errfunc; + return status; +} + + + +/* +** Execute a protected parser. +*/ +struct SParser { /* data to 'f_parser' */ + ZIO *z; + Mbuffer buff; /* dynamic structure used by the scanner */ + Dyndata dyd; /* dynamic structures used by the parser */ + const char *mode; + const char *name; +}; + + +static void checkmode (lua_State *L, const char *mode, const char *x) { + if (mode && strchr(mode, x[0]) == NULL) { + luaO_pushfstring(L, + "attempt to load a %s chunk (mode is '%s')", x, mode); + luaD_throw(L, LUA_ERRSYNTAX); + } +} + + +static void f_parser (lua_State *L, void *ud) { + LClosure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = zgetc(p->z); /* read first character */ + if (c == LUA_SIGNATURE[0]) { + checkmode(L, p->mode, "binary"); + cl = luaU_undump(L, p->z, p->name); + } + else { + checkmode(L, p->mode, "text"); + cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); + } + lua_assert(cl->nupvalues == cl->p->sizeupvalues); + luaF_initupvals(L, cl); +} + + +int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode) { + struct SParser p; + int status; + L->nny++; /* cannot yield during parsing */ + p.z = z; p.name = name; p.mode = mode; + p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; + p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; + p.dyd.label.arr = NULL; p.dyd.label.size = 0; + luaZ_initbuffer(L, &p.buff); + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); + luaZ_freebuffer(L, &p.buff); + luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); + luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); + luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); + L->nny--; + return status; +} + + diff --git a/3rd/lua-5.3.4/ldo.h b/3rd/lua-5.3.4/ldo.h new file mode 100644 index 0000000..4f5d51c --- /dev/null +++ b/3rd/lua-5.3.4/ldo.h @@ -0,0 +1,58 @@ +/* +** $Id: ldo.h,v 2.29 2015/12/21 13:02:14 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "lobject.h" +#include "lstate.h" +#include "lzio.h" + + +/* +** Macro to check stack size and grow stack if needed. Parameters +** 'pre'/'pos' allow the macro to preserve a pointer into the +** stack across reallocations, doing the work only when needed. +** 'condmovestack' is used in heavy tests to force a stack reallocation +** at every check. +*/ +#define luaD_checkstackaux(L,n,pre,pos) \ + if (L->stack_last - L->top <= (n)) \ + { pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); } + +/* In general, 'pre'/'pos' are empty (nothing to save) */ +#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) + + + +#define savestack(L,p) ((char *)(p) - (char *)L->stack) +#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) + + +/* type of protected functions, to be ran by 'runprotected' */ +typedef void (*Pfunc) (lua_State *L, void *ud); + +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode); +LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); +LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); +LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); +LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, + int nres); +LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); +LUAI_FUNC void luaD_growstack (lua_State *L, int n); +LUAI_FUNC void luaD_shrinkstack (lua_State *L); +LUAI_FUNC void luaD_inctop (lua_State *L); + +LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); + +#endif + diff --git a/3rd/lua-5.3.4/ldump.c b/3rd/lua-5.3.4/ldump.c new file mode 100644 index 0000000..016e300 --- /dev/null +++ b/3rd/lua-5.3.4/ldump.c @@ -0,0 +1,215 @@ +/* +** $Id: ldump.c,v 2.37 2015/10/08 15:53:49 roberto Exp $ +** save precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#define ldump_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lundump.h" + + +typedef struct { + lua_State *L; + lua_Writer writer; + void *data; + int strip; + int status; +} DumpState; + + +/* +** All high-level dumps go through DumpVector; you can change it to +** change the endianness of the result +*/ +#define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D) + +#define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D) + + +static void DumpBlock (const void *b, size_t size, DumpState *D) { + if (D->status == 0 && size > 0) { + lua_unlock(D->L); + D->status = (*D->writer)(D->L, b, size, D->data); + lua_lock(D->L); + } +} + + +#define DumpVar(x,D) DumpVector(&x,1,D) + + +static void DumpByte (int y, DumpState *D) { + lu_byte x = (lu_byte)y; + DumpVar(x, D); +} + + +static void DumpInt (int x, DumpState *D) { + DumpVar(x, D); +} + + +static void DumpNumber (lua_Number x, DumpState *D) { + DumpVar(x, D); +} + + +static void DumpInteger (lua_Integer x, DumpState *D) { + DumpVar(x, D); +} + + +static void DumpString (const TString *s, DumpState *D) { + if (s == NULL) + DumpByte(0, D); + else { + size_t size = tsslen(s) + 1; /* include trailing '\0' */ + const char *str = getstr(s); + if (size < 0xFF) + DumpByte(cast_int(size), D); + else { + DumpByte(0xFF, D); + DumpVar(size, D); + } + DumpVector(str, size - 1, D); /* no need to save '\0' */ + } +} + + +static void DumpCode (const Proto *f, DumpState *D) { + DumpInt(f->sizecode, D); + DumpVector(f->code, f->sizecode, D); +} + + +static void DumpFunction(const Proto *f, TString *psource, DumpState *D); + +static void DumpConstants (const Proto *f, DumpState *D) { + int i; + int n = f->sizek; + DumpInt(n, D); + for (i = 0; i < n; i++) { + const TValue *o = &f->k[i]; + DumpByte(ttype(o), D); + switch (ttype(o)) { + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + DumpByte(bvalue(o), D); + break; + case LUA_TNUMFLT: + DumpNumber(fltvalue(o), D); + break; + case LUA_TNUMINT: + DumpInteger(ivalue(o), D); + break; + case LUA_TSHRSTR: + case LUA_TLNGSTR: + DumpString(tsvalue(o), D); + break; + default: + lua_assert(0); + } + } +} + + +static void DumpProtos (const Proto *f, DumpState *D) { + int i; + int n = f->sizep; + DumpInt(n, D); + for (i = 0; i < n; i++) + DumpFunction(f->p[i], f->source, D); +} + + +static void DumpUpvalues (const Proto *f, DumpState *D) { + int i, n = f->sizeupvalues; + DumpInt(n, D); + for (i = 0; i < n; i++) { + DumpByte(f->upvalues[i].instack, D); + DumpByte(f->upvalues[i].idx, D); + } +} + + +static void DumpDebug (const Proto *f, DumpState *D) { + int i, n; + n = (D->strip) ? 0 : f->sizelineinfo; + DumpInt(n, D); + DumpVector(f->lineinfo, n, D); + n = (D->strip) ? 0 : f->sizelocvars; + DumpInt(n, D); + for (i = 0; i < n; i++) { + DumpString(f->locvars[i].varname, D); + DumpInt(f->locvars[i].startpc, D); + DumpInt(f->locvars[i].endpc, D); + } + n = (D->strip) ? 0 : f->sizeupvalues; + DumpInt(n, D); + for (i = 0; i < n; i++) + DumpString(f->upvalues[i].name, D); +} + + +static void DumpFunction (const Proto *f, TString *psource, DumpState *D) { + if (D->strip || f->source == psource) + DumpString(NULL, D); /* no debug info or same source as its parent */ + else + DumpString(f->source, D); + DumpInt(f->linedefined, D); + DumpInt(f->lastlinedefined, D); + DumpByte(f->numparams, D); + DumpByte(f->is_vararg, D); + DumpByte(f->maxstacksize, D); + DumpCode(f, D); + DumpConstants(f, D); + DumpUpvalues(f, D); + DumpProtos(f, D); + DumpDebug(f, D); +} + + +static void DumpHeader (DumpState *D) { + DumpLiteral(LUA_SIGNATURE, D); + DumpByte(LUAC_VERSION, D); + DumpByte(LUAC_FORMAT, D); + DumpLiteral(LUAC_DATA, D); + DumpByte(sizeof(int), D); + DumpByte(sizeof(size_t), D); + DumpByte(sizeof(Instruction), D); + DumpByte(sizeof(lua_Integer), D); + DumpByte(sizeof(lua_Number), D); + DumpInteger(LUAC_INT, D); + DumpNumber(LUAC_NUM, D); +} + + +/* +** dump Lua function as precompiled chunk +*/ +int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, + int strip) { + DumpState D; + D.L = L; + D.writer = w; + D.data = data; + D.strip = strip; + D.status = 0; + DumpHeader(&D); + DumpByte(f->sizeupvalues, &D); + DumpFunction(f, NULL, &D); + return D.status; +} + diff --git a/3rd/lua-5.3.4/lfunc.c b/3rd/lua-5.3.4/lfunc.c new file mode 100644 index 0000000..67967da --- /dev/null +++ b/3rd/lua-5.3.4/lfunc.c @@ -0,0 +1,151 @@ +/* +** $Id: lfunc.c,v 2.45 2014/11/02 19:19:04 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#define lfunc_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +CClosure *luaF_newCclosure (lua_State *L, int n) { + GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n)); + CClosure *c = gco2ccl(o); + c->nupvalues = cast_byte(n); + return c; +} + + +LClosure *luaF_newLclosure (lua_State *L, int n) { + GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n)); + LClosure *c = gco2lcl(o); + c->p = NULL; + c->nupvalues = cast_byte(n); + while (n--) c->upvals[n] = NULL; + return c; +} + +/* +** fill a closure with new closed upvalues +*/ +void luaF_initupvals (lua_State *L, LClosure *cl) { + int i; + for (i = 0; i < cl->nupvalues; i++) { + UpVal *uv = luaM_new(L, UpVal); + uv->refcount = 1; + uv->v = &uv->u.value; /* make it closed */ + setnilvalue(uv->v); + cl->upvals[i] = uv; + } +} + + +UpVal *luaF_findupval (lua_State *L, StkId level) { + UpVal **pp = &L->openupval; + UpVal *p; + UpVal *uv; + lua_assert(isintwups(L) || L->openupval == NULL); + while (*pp != NULL && (p = *pp)->v >= level) { + lua_assert(upisopen(p)); + if (p->v == level) /* found a corresponding upvalue? */ + return p; /* return it */ + pp = &p->u.open.next; + } + /* not found: create a new upvalue */ + uv = luaM_new(L, UpVal); + uv->refcount = 0; + uv->u.open.next = *pp; /* link it to list of open upvalues */ + uv->u.open.touched = 1; + *pp = uv; + uv->v = level; /* current value lives in the stack */ + if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ + L->twups = G(L)->twups; /* link it to the list */ + G(L)->twups = L; + } + return uv; +} + + +void luaF_close (lua_State *L, StkId level) { + UpVal *uv; + while (L->openupval != NULL && (uv = L->openupval)->v >= level) { + lua_assert(upisopen(uv)); + L->openupval = uv->u.open.next; /* remove from 'open' list */ + if (uv->refcount == 0) /* no references? */ + luaM_free(L, uv); /* free upvalue */ + else { + setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ + uv->v = &uv->u.value; /* now current value lives here */ + luaC_upvalbarrier(L, uv); + } + } +} + + +Proto *luaF_newproto (lua_State *L) { + GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto)); + Proto *f = gco2p(o); + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->cache = NULL; + f->sizecode = 0; + f->lineinfo = NULL; + f->sizelineinfo = 0; + f->upvalues = NULL; + f->sizeupvalues = 0; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->locvars = NULL; + f->sizelocvars = 0; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; + return f; +} + + +void luaF_freeproto (lua_State *L, Proto *f) { + luaM_freearray(L, f->code, f->sizecode); + luaM_freearray(L, f->p, f->sizep); + luaM_freearray(L, f->k, f->sizek); + luaM_freearray(L, f->lineinfo, f->sizelineinfo); + luaM_freearray(L, f->locvars, f->sizelocvars); + luaM_freearray(L, f->upvalues, f->sizeupvalues); + luaM_free(L, f); +} + + +/* +** Look for n-th local variable at line 'line' in function 'func'. +** Returns NULL if not found. +*/ +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } + } + return NULL; /* not found */ +} + diff --git a/3rd/lua-5.3.4/lfunc.h b/3rd/lua-5.3.4/lfunc.h new file mode 100644 index 0000000..2eeb0d5 --- /dev/null +++ b/3rd/lua-5.3.4/lfunc.h @@ -0,0 +1,61 @@ +/* +** $Id: lfunc.h,v 2.15 2015/01/13 15:49:11 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ + cast(int, sizeof(TValue)*((n)-1))) + +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ + cast(int, sizeof(TValue *)*((n)-1))) + + +/* test whether thread is in 'twups' list */ +#define isintwups(L) (L->twups != L) + + +/* +** maximum number of upvalues in a closure (both C and Lua). (Value +** must fit in a VM register.) +*/ +#define MAXUPVAL 255 + + +/* +** Upvalues for Lua closures +*/ +struct UpVal { + TValue *v; /* points to stack or to its own value */ + lu_mem refcount; /* reference counter */ + union { + struct { /* (when open) */ + UpVal *next; /* linked list */ + int touched; /* mark to avoid cycles with dead threads */ + } open; + TValue value; /* the value (when closed) */ + } u; +}; + +#define upisopen(up) ((up)->v != &(up)->u.value) + + +LUAI_FUNC Proto *luaF_newproto (lua_State *L); +LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems); +LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems); +LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_close (lua_State *L, StkId level); +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, + int pc); + + +#endif diff --git a/3rd/lua-5.3.4/lgc.c b/3rd/lua-5.3.4/lgc.c new file mode 100644 index 0000000..ba2c19e --- /dev/null +++ b/3rd/lua-5.3.4/lgc.c @@ -0,0 +1,1178 @@ +/* +** $Id: lgc.c,v 2.215 2016/12/22 13:08:50 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#define lgc_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +/* +** internal state for collector while inside the atomic phase. The +** collector should never be in this state while running regular code. +*/ +#define GCSinsideatomic (GCSpause + 1) + +/* +** cost of sweeping one element (the size of a small object divided +** by some adjust for the sweep speed) +*/ +#define GCSWEEPCOST ((sizeof(TString) + 4) / 4) + +/* maximum number of elements to sweep in each single step */ +#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) + +/* cost of calling one finalizer */ +#define GCFINALIZECOST GCSWEEPCOST + + +/* +** macro to adjust 'stepmul': 'stepmul' is actually used like +** 'stepmul / STEPMULADJ' (value chosen by tests) +*/ +#define STEPMULADJ 200 + + +/* +** macro to adjust 'pause': 'pause' is actually used like +** 'pause / PAUSEADJ' (value chosen by tests) +*/ +#define PAUSEADJ 100 + + +/* +** 'makewhite' erases all color bits then sets only the current white +** bit +*/ +#define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS)) +#define makewhite(g,x) \ + (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g))) + +#define white2gray(x) resetbits(x->marked, WHITEBITS) +#define black2gray(x) resetbit(x->marked, BLACKBIT) + + +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) + +#define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) + + +#define checkconsistency(obj) \ + lua_longassert(!iscollectable(obj) || righttt(obj)) + + +#define markvalue(g,o) { checkconsistency(o); \ + if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } + +#define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); } + +/* +** mark an object that can be NULL (either because it is really optional, +** or it was stripped as debug info, or inside an uncompleted structure) +*/ +#define markobjectN(g,t) { if (t) markobject(g,t); } + +static void reallymarkobject (global_State *g, GCObject *o); + + +/* +** {====================================================== +** Generic functions +** ======================================================= +*/ + + +/* +** one after last element in a hash array +*/ +#define gnodelast(h) gnode(h, cast(size_t, sizenode(h))) + + +/* +** link collectable object 'o' into list pointed by 'p' +*/ +#define linkgclist(o,p) ((o)->gclist = (p), (p) = obj2gco(o)) + + +/* +** If key is not marked, mark its entry as dead. This allows key to be +** collected, but keeps its entry in the table. A dead node is needed +** when Lua looks up for a key (it may be part of a chain) and when +** traversing a weak table (key might be removed from the table during +** traversal). Other places never manipulate dead keys, because its +** associated nil value is enough to signal that the entry is logically +** empty. +*/ +static void removeentry (Node *n) { + lua_assert(ttisnil(gval(n))); + if (valiswhite(gkey(n))) + setdeadvalue(wgkey(n)); /* unused and unmarked key; remove it */ +} + + +/* +** tells whether a key or value can be cleared from a weak +** table. Non-collectable objects are never removed from weak +** tables. Strings behave as 'values', so are never removed too. for +** other objects: if really collected, cannot keep them; for objects +** being finalized, keep them in keys, but not in values +*/ +static int iscleared (global_State *g, const TValue *o) { + if (!iscollectable(o)) return 0; + else if (ttisstring(o)) { + markobject(g, tsvalue(o)); /* strings are 'values', so are never weak */ + return 0; + } + else return iswhite(gcvalue(o)); +} + + +/* +** barrier that moves collector forward, that is, mark the white object +** being pointed by a black object. (If in sweep phase, clear the black +** object to white [sweep it] to avoid other barrier calls for this +** same object.) +*/ +void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + if (keepinvariant(g)) /* must keep invariant? */ + reallymarkobject(g, v); /* restore invariant */ + else { /* sweep phase */ + lua_assert(issweepphase(g)); + makewhite(g, o); /* mark main obj. as white to avoid other barriers */ + } +} + + +/* +** barrier that moves collector backward, that is, mark the black object +** pointing to a white object as gray again. +*/ +void luaC_barrierback_ (lua_State *L, Table *t) { + global_State *g = G(L); + lua_assert(isblack(t) && !isdead(g, t)); + black2gray(t); /* make table gray (again) */ + linkgclist(t, g->grayagain); +} + + +/* +** barrier for assignments to closed upvalues. Because upvalues are +** shared among closures, it is impossible to know the color of all +** closures pointing to it. So, we assume that the object being assigned +** must be marked. +*/ +void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) { + global_State *g = G(L); + GCObject *o = gcvalue(uv->v); + lua_assert(!upisopen(uv)); /* ensured by macro luaC_upvalbarrier */ + if (keepinvariant(g)) + markobject(g, o); +} + + +void luaC_fix (lua_State *L, GCObject *o) { + global_State *g = G(L); + lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */ + white2gray(o); /* they will be gray forever */ + g->allgc = o->next; /* remove object from 'allgc' list */ + o->next = g->fixedgc; /* link it to 'fixedgc' list */ + g->fixedgc = o; +} + + +/* +** create a new collectable object (with given type and size) and link +** it to 'allgc' list. +*/ +GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { + global_State *g = G(L); + GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz)); + o->marked = luaC_white(g); + o->tt = tt; + o->next = g->allgc; + g->allgc = o; + return o; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Mark functions +** ======================================================= +*/ + + +/* +** mark an object. Userdata, strings, and closed upvalues are visited +** and turned black here. Other objects are marked gray and added +** to appropriate list to be visited (and turned black) later. (Open +** upvalues are already linked in 'headuv' list.) +*/ +static void reallymarkobject (global_State *g, GCObject *o) { + reentry: + white2gray(o); + switch (o->tt) { + case LUA_TSHRSTR: { + gray2black(o); + g->GCmemtrav += sizelstring(gco2ts(o)->shrlen); + break; + } + case LUA_TLNGSTR: { + gray2black(o); + g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen); + break; + } + case LUA_TUSERDATA: { + TValue uvalue; + markobjectN(g, gco2u(o)->metatable); /* mark its metatable */ + gray2black(o); + g->GCmemtrav += sizeudata(gco2u(o)); + getuservalue(g->mainthread, gco2u(o), &uvalue); + if (valiswhite(&uvalue)) { /* markvalue(g, &uvalue); */ + o = gcvalue(&uvalue); + goto reentry; + } + break; + } + case LUA_TLCL: { + linkgclist(gco2lcl(o), g->gray); + break; + } + case LUA_TCCL: { + linkgclist(gco2ccl(o), g->gray); + break; + } + case LUA_TTABLE: { + linkgclist(gco2t(o), g->gray); + break; + } + case LUA_TTHREAD: { + linkgclist(gco2th(o), g->gray); + break; + } + case LUA_TPROTO: { + linkgclist(gco2p(o), g->gray); + break; + } + default: lua_assert(0); break; + } +} + + +/* +** mark metamethods for basic types +*/ +static void markmt (global_State *g) { + int i; + for (i=0; i < LUA_NUMTAGS; i++) + markobjectN(g, g->mt[i]); +} + + +/* +** mark all objects in list of being-finalized +*/ +static void markbeingfnz (global_State *g) { + GCObject *o; + for (o = g->tobefnz; o != NULL; o = o->next) + markobject(g, o); +} + + +/* +** Mark all values stored in marked open upvalues from non-marked threads. +** (Values from marked threads were already marked when traversing the +** thread.) Remove from the list threads that no longer have upvalues and +** not-marked threads. +*/ +static void remarkupvals (global_State *g) { + lua_State *thread; + lua_State **p = &g->twups; + while ((thread = *p) != NULL) { + lua_assert(!isblack(thread)); /* threads are never black */ + if (isgray(thread) && thread->openupval != NULL) + p = &thread->twups; /* keep marked thread with upvalues in the list */ + else { /* thread is not marked or without upvalues */ + UpVal *uv; + *p = thread->twups; /* remove thread from the list */ + thread->twups = thread; /* mark that it is out of list */ + for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { + if (uv->u.open.touched) { + markvalue(g, uv->v); /* remark upvalue's value */ + uv->u.open.touched = 0; + } + } + } + } +} + + +/* +** mark root set and reset all gray lists, to start a new collection +*/ +static void restartcollection (global_State *g) { + g->gray = g->grayagain = NULL; + g->weak = g->allweak = g->ephemeron = NULL; + markobject(g, g->mainthread); + markvalue(g, &g->l_registry); + markmt(g); + markbeingfnz(g); /* mark any finalizing object left from previous cycle */ +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Traverse functions +** ======================================================= +*/ + +/* +** Traverse a table with weak values and link it to proper list. During +** propagate phase, keep it in 'grayagain' list, to be revisited in the +** atomic phase. In the atomic phase, if table has any white value, +** put it in 'weak' list, to be cleared. +*/ +static void traverseweakvalue (global_State *g, Table *h) { + Node *n, *limit = gnodelast(h); + /* if there is array part, assume it may have white values (it is not + worth traversing it now just to check) */ + int hasclears = (h->sizearray > 0); + for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else { + lua_assert(!ttisnil(gkey(n))); + markvalue(g, gkey(n)); /* mark key */ + if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */ + hasclears = 1; /* table will have to be cleared */ + } + } + if (g->gcstate == GCSpropagate) + linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ + else if (hasclears) + linkgclist(h, g->weak); /* has to be cleared later */ +} + + +/* +** Traverse an ephemeron table and link it to proper list. Returns true +** iff any object was marked during this traversal (which implies that +** convergence has to continue). During propagation phase, keep table +** in 'grayagain' list, to be visited again in the atomic phase. In +** the atomic phase, if table has any white->white entry, it has to +** be revisited during ephemeron convergence (as that key may turn +** black). Otherwise, if it has any white key, table has to be cleared +** (in the atomic phase). +*/ +static int traverseephemeron (global_State *g, Table *h) { + int marked = 0; /* true if an object is marked in this traversal */ + int hasclears = 0; /* true if table has white keys */ + int hasww = 0; /* true if table has entry "white-key -> white-value" */ + Node *n, *limit = gnodelast(h); + unsigned int i; + /* traverse array part */ + for (i = 0; i < h->sizearray; i++) { + if (valiswhite(&h->array[i])) { + marked = 1; + reallymarkobject(g, gcvalue(&h->array[i])); + } + } + /* traverse hash part */ + for (n = gnode(h, 0); n < limit; n++) { + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */ + hasclears = 1; /* table must be cleared */ + if (valiswhite(gval(n))) /* value not marked yet? */ + hasww = 1; /* white-white entry */ + } + else if (valiswhite(gval(n))) { /* value not marked yet? */ + marked = 1; + reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ + } + } + /* link table into proper list */ + if (g->gcstate == GCSpropagate) + linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ + else if (hasww) /* table has white->white entries? */ + linkgclist(h, g->ephemeron); /* have to propagate again */ + else if (hasclears) /* table has white keys? */ + linkgclist(h, g->allweak); /* may have to clean white keys */ + return marked; +} + + +static void traversestrongtable (global_State *g, Table *h) { + Node *n, *limit = gnodelast(h); + unsigned int i; + for (i = 0; i < h->sizearray; i++) /* traverse array part */ + markvalue(g, &h->array[i]); + for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else { + lua_assert(!ttisnil(gkey(n))); + markvalue(g, gkey(n)); /* mark key */ + markvalue(g, gval(n)); /* mark value */ + } + } +} + + +static lu_mem traversetable (global_State *g, Table *h) { + const char *weakkey, *weakvalue; + const TValue *mode = gfasttm(g, h->metatable, TM_MODE); + markobjectN(g, h->metatable); + if (mode && ttisstring(mode) && /* is there a weak mode? */ + ((weakkey = strchr(svalue(mode), 'k')), + (weakvalue = strchr(svalue(mode), 'v')), + (weakkey || weakvalue))) { /* is really weak? */ + black2gray(h); /* keep table gray */ + if (!weakkey) /* strong keys? */ + traverseweakvalue(g, h); + else if (!weakvalue) /* strong values? */ + traverseephemeron(g, h); + else /* all weak */ + linkgclist(h, g->allweak); /* nothing to traverse now */ + } + else /* not weak */ + traversestrongtable(g, h); + return sizeof(Table) + sizeof(TValue) * h->sizearray + + sizeof(Node) * cast(size_t, allocsizenode(h)); +} + + +/* +** Traverse a prototype. (While a prototype is being build, its +** arrays can be larger than needed; the extra slots are filled with +** NULL, so the use of 'markobjectN') +*/ +static int traverseproto (global_State *g, Proto *f) { + int i; + if (f->cache && iswhite(f->cache)) + f->cache = NULL; /* allow cache to be collected */ + markobjectN(g, f->source); + for (i = 0; i < f->sizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ + markobjectN(g, f->upvalues[i].name); + for (i = 0; i < f->sizep; i++) /* mark nested protos */ + markobjectN(g, f->p[i]); + for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ + markobjectN(g, f->locvars[i].varname); + return sizeof(Proto) + sizeof(Instruction) * f->sizecode + + sizeof(Proto *) * f->sizep + + sizeof(TValue) * f->sizek + + sizeof(int) * f->sizelineinfo + + sizeof(LocVar) * f->sizelocvars + + sizeof(Upvaldesc) * f->sizeupvalues; +} + + +static lu_mem traverseCclosure (global_State *g, CClosure *cl) { + int i; + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->upvalue[i]); + return sizeCclosure(cl->nupvalues); +} + +/* +** open upvalues point to values in a thread, so those values should +** be marked when the thread is traversed except in the atomic phase +** (because then the value cannot be changed by the thread and the +** thread may not be traversed again) +*/ +static lu_mem traverseLclosure (global_State *g, LClosure *cl) { + int i; + markobjectN(g, cl->p); /* mark its prototype */ + for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */ + UpVal *uv = cl->upvals[i]; + if (uv != NULL) { + if (upisopen(uv) && g->gcstate != GCSinsideatomic) + uv->u.open.touched = 1; /* can be marked in 'remarkupvals' */ + else + markvalue(g, uv->v); + } + } + return sizeLclosure(cl->nupvalues); +} + + +static lu_mem traversethread (global_State *g, lua_State *th) { + StkId o = th->stack; + if (o == NULL) + return 1; /* stack not completely built yet */ + lua_assert(g->gcstate == GCSinsideatomic || + th->openupval == NULL || isintwups(th)); + for (; o < th->top; o++) /* mark live elements in the stack */ + markvalue(g, o); + if (g->gcstate == GCSinsideatomic) { /* final traversal? */ + StkId lim = th->stack + th->stacksize; /* real end of stack */ + for (; o < lim; o++) /* clear not-marked stack slice */ + setnilvalue(o); + /* 'remarkupvals' may have removed thread from 'twups' list */ + if (!isintwups(th) && th->openupval != NULL) { + th->twups = g->twups; /* link it back to the list */ + g->twups = th; + } + } + else if (g->gckind != KGC_EMERGENCY) + luaD_shrinkstack(th); /* do not change stack in emergency cycle */ + return (sizeof(lua_State) + sizeof(TValue) * th->stacksize + + sizeof(CallInfo) * th->nci); +} + + +/* +** traverse one gray object, turning it to black (except for threads, +** which are always gray). +*/ +static void propagatemark (global_State *g) { + lu_mem size; + GCObject *o = g->gray; + lua_assert(isgray(o)); + gray2black(o); + switch (o->tt) { + case LUA_TTABLE: { + Table *h = gco2t(o); + g->gray = h->gclist; /* remove from 'gray' list */ + size = traversetable(g, h); + break; + } + case LUA_TLCL: { + LClosure *cl = gco2lcl(o); + g->gray = cl->gclist; /* remove from 'gray' list */ + size = traverseLclosure(g, cl); + break; + } + case LUA_TCCL: { + CClosure *cl = gco2ccl(o); + g->gray = cl->gclist; /* remove from 'gray' list */ + size = traverseCclosure(g, cl); + break; + } + case LUA_TTHREAD: { + lua_State *th = gco2th(o); + g->gray = th->gclist; /* remove from 'gray' list */ + linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ + black2gray(o); + size = traversethread(g, th); + break; + } + case LUA_TPROTO: { + Proto *p = gco2p(o); + g->gray = p->gclist; /* remove from 'gray' list */ + size = traverseproto(g, p); + break; + } + default: lua_assert(0); return; + } + g->GCmemtrav += size; +} + + +static void propagateall (global_State *g) { + while (g->gray) propagatemark(g); +} + + +static void convergeephemerons (global_State *g) { + int changed; + do { + GCObject *w; + GCObject *next = g->ephemeron; /* get ephemeron list */ + g->ephemeron = NULL; /* tables may return to this list when traversed */ + changed = 0; + while ((w = next) != NULL) { + next = gco2t(w)->gclist; + if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */ + propagateall(g); /* propagate changes */ + changed = 1; /* will have to revisit all ephemeron tables */ + } + } + } while (changed); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Sweep Functions +** ======================================================= +*/ + + +/* +** clear entries with unmarked keys from all weaktables in list 'l' up +** to element 'f' +*/ +static void clearkeys (global_State *g, GCObject *l, GCObject *f) { + for (; l != f; l = gco2t(l)->gclist) { + Table *h = gco2t(l); + Node *n, *limit = gnodelast(h); + for (n = gnode(h, 0); n < limit; n++) { + if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* and remove entry from table */ + } + } + } +} + + +/* +** clear entries with unmarked values from all weaktables in list 'l' up +** to element 'f' +*/ +static void clearvalues (global_State *g, GCObject *l, GCObject *f) { + for (; l != f; l = gco2t(l)->gclist) { + Table *h = gco2t(l); + Node *n, *limit = gnodelast(h); + unsigned int i; + for (i = 0; i < h->sizearray; i++) { + TValue *o = &h->array[i]; + if (iscleared(g, o)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + for (n = gnode(h, 0); n < limit; n++) { + if (!ttisnil(gval(n)) && iscleared(g, gval(n))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* and remove entry from table */ + } + } + } +} + + +void luaC_upvdeccount (lua_State *L, UpVal *uv) { + lua_assert(uv->refcount > 0); + uv->refcount--; + if (uv->refcount == 0 && !upisopen(uv)) + luaM_free(L, uv); +} + + +static void freeLclosure (lua_State *L, LClosure *cl) { + int i; + for (i = 0; i < cl->nupvalues; i++) { + UpVal *uv = cl->upvals[i]; + if (uv) + luaC_upvdeccount(L, uv); + } + luaM_freemem(L, cl, sizeLclosure(cl->nupvalues)); +} + + +static void freeobj (lua_State *L, GCObject *o) { + switch (o->tt) { + case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; + case LUA_TLCL: { + freeLclosure(L, gco2lcl(o)); + break; + } + case LUA_TCCL: { + luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); + break; + } + case LUA_TTABLE: luaH_free(L, gco2t(o)); break; + case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; + case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; + case LUA_TSHRSTR: + luaS_remove(L, gco2ts(o)); /* remove it from hash table */ + luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen)); + break; + case LUA_TLNGSTR: { + luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen)); + break; + } + default: lua_assert(0); + } +} + + +#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); + + +/* +** sweep at most 'count' elements from a list of GCObjects erasing dead +** objects, where a dead object is one marked with the old (non current) +** white; change all non-dead objects back to white, preparing for next +** collection cycle. Return where to continue the traversal or NULL if +** list is finished. +*/ +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { + global_State *g = G(L); + int ow = otherwhite(g); + int white = luaC_white(g); /* current white */ + while (*p != NULL && count-- > 0) { + GCObject *curr = *p; + int marked = curr->marked; + if (isdeadm(ow, marked)) { /* is 'curr' dead? */ + *p = curr->next; /* remove 'curr' from list */ + freeobj(L, curr); /* erase 'curr' */ + } + else { /* change mark to 'white' */ + curr->marked = cast_byte((marked & maskcolors) | white); + p = &curr->next; /* go to next element */ + } + } + return (*p == NULL) ? NULL : p; +} + + +/* +** sweep a list until a live object (or end of list) +*/ +static GCObject **sweeptolive (lua_State *L, GCObject **p) { + GCObject **old = p; + do { + p = sweeplist(L, p, 1); + } while (p == old); + return p; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Finalization +** ======================================================= +*/ + +/* +** If possible, shrink string table +*/ +static void checkSizes (lua_State *L, global_State *g) { + if (g->gckind != KGC_EMERGENCY) { + l_mem olddebt = g->GCdebt; + if (g->strt.nuse < g->strt.size / 4) /* string table too big? */ + luaS_resize(L, g->strt.size / 2); /* shrink it a little */ + g->GCestimate += g->GCdebt - olddebt; /* update estimate */ + } +} + + +static GCObject *udata2finalize (global_State *g) { + GCObject *o = g->tobefnz; /* get first element */ + lua_assert(tofinalize(o)); + g->tobefnz = o->next; /* remove it from 'tobefnz' list */ + o->next = g->allgc; /* return it to 'allgc' list */ + g->allgc = o; + resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */ + if (issweepphase(g)) + makewhite(g, o); /* "sweep" object */ + return o; +} + + +static void dothecall (lua_State *L, void *ud) { + UNUSED(ud); + luaD_callnoyield(L, L->top - 2, 0); +} + + +static void GCTM (lua_State *L, int propagateerrors) { + global_State *g = G(L); + const TValue *tm; + TValue v; + setgcovalue(L, &v, udata2finalize(g)); + tm = luaT_gettmbyobj(L, &v, TM_GC); + if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ + int status; + lu_byte oldah = L->allowhook; + int running = g->gcrunning; + L->allowhook = 0; /* stop debug hooks during GC metamethod */ + g->gcrunning = 0; /* avoid GC steps */ + setobj2s(L, L->top, tm); /* push finalizer... */ + setobj2s(L, L->top + 1, &v); /* ... and its argument */ + L->top += 2; /* and (next line) call the finalizer */ + L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ + status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); + L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ + L->allowhook = oldah; /* restore hooks */ + g->gcrunning = running; /* restore state */ + if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ + if (status == LUA_ERRRUN) { /* is there an error object? */ + const char *msg = (ttisstring(L->top - 1)) + ? svalue(L->top - 1) + : "no message"; + luaO_pushfstring(L, "error in __gc metamethod (%s)", msg); + status = LUA_ERRGCMM; /* error in __gc metamethod */ + } + luaD_throw(L, status); /* re-throw error */ + } + } +} + + +/* +** call a few (up to 'g->gcfinnum') finalizers +*/ +static int runafewfinalizers (lua_State *L) { + global_State *g = G(L); + unsigned int i; + lua_assert(!g->tobefnz || g->gcfinnum > 0); + for (i = 0; g->tobefnz && i < g->gcfinnum; i++) + GCTM(L, 1); /* call one finalizer */ + g->gcfinnum = (!g->tobefnz) ? 0 /* nothing more to finalize? */ + : g->gcfinnum * 2; /* else call a few more next time */ + return i; +} + + +/* +** call all pending finalizers +*/ +static void callallpendingfinalizers (lua_State *L) { + global_State *g = G(L); + while (g->tobefnz) + GCTM(L, 0); +} + + +/* +** find last 'next' field in list 'p' list (to add elements in its end) +*/ +static GCObject **findlast (GCObject **p) { + while (*p != NULL) + p = &(*p)->next; + return p; +} + + +/* +** move all unreachable objects (or 'all' objects) that need +** finalization from list 'finobj' to list 'tobefnz' (to be finalized) +*/ +static void separatetobefnz (global_State *g, int all) { + GCObject *curr; + GCObject **p = &g->finobj; + GCObject **lastnext = findlast(&g->tobefnz); + while ((curr = *p) != NULL) { /* traverse all finalizable objects */ + lua_assert(tofinalize(curr)); + if (!(iswhite(curr) || all)) /* not being collected? */ + p = &curr->next; /* don't bother with it */ + else { + *p = curr->next; /* remove 'curr' from 'finobj' list */ + curr->next = *lastnext; /* link at the end of 'tobefnz' list */ + *lastnext = curr; + lastnext = &curr->next; + } + } +} + + +/* +** if object 'o' has a finalizer, remove it from 'allgc' list (must +** search the list to find it) and link it in 'finobj' list. +*/ +void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { + global_State *g = G(L); + if (tofinalize(o) || /* obj. is already marked... */ + gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ + return; /* nothing to be done */ + else { /* move 'o' to 'finobj' list */ + GCObject **p; + if (issweepphase(g)) { + makewhite(g, o); /* "sweep" object 'o' */ + if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ + g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */ + } + /* search for pointer pointing to 'o' */ + for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } + *p = o->next; /* remove 'o' from 'allgc' list */ + o->next = g->finobj; /* link it in 'finobj' list */ + g->finobj = o; + l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */ + } +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** GC control +** ======================================================= +*/ + + +/* +** Set a reasonable "time" to wait before starting a new GC cycle; cycle +** will start when memory use hits threshold. (Division by 'estimate' +** should be OK: it cannot be zero (because Lua cannot even start with +** less than PAUSEADJ bytes). +*/ +static void setpause (global_State *g) { + l_mem threshold, debt; + l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */ + lua_assert(estimate > 0); + threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */ + ? estimate * g->gcpause /* no overflow */ + : MAX_LMEM; /* overflow; truncate to maximum */ + debt = gettotalbytes(g) - threshold; + luaE_setdebt(g, debt); +} + + +/* +** Enter first sweep phase. +** The call to 'sweeplist' tries to make pointer point to an object +** inside the list (instead of to the header), so that the real sweep do +** not need to skip objects created between "now" and the start of the +** real sweep. +*/ +static void entersweep (lua_State *L) { + global_State *g = G(L); + g->gcstate = GCSswpallgc; + lua_assert(g->sweepgc == NULL); + g->sweepgc = sweeplist(L, &g->allgc, 1); +} + + +void luaC_freeallobjects (lua_State *L) { + global_State *g = G(L); + separatetobefnz(g, 1); /* separate all objects with finalizers */ + lua_assert(g->finobj == NULL); + callallpendingfinalizers(L); + lua_assert(g->tobefnz == NULL); + g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ + g->gckind = KGC_NORMAL; + sweepwholelist(L, &g->finobj); + sweepwholelist(L, &g->allgc); + sweepwholelist(L, &g->fixedgc); /* collect fixed objects */ + lua_assert(g->strt.nuse == 0); +} + + +static l_mem atomic (lua_State *L) { + global_State *g = G(L); + l_mem work; + GCObject *origweak, *origall; + GCObject *grayagain = g->grayagain; /* save original list */ + lua_assert(g->ephemeron == NULL && g->weak == NULL); + lua_assert(!iswhite(g->mainthread)); + g->gcstate = GCSinsideatomic; + g->GCmemtrav = 0; /* start counting work */ + markobject(g, L); /* mark running thread */ + /* registry and global metatables may be changed by API */ + markvalue(g, &g->l_registry); + markmt(g); /* mark global metatables */ + /* remark occasional upvalues of (maybe) dead threads */ + remarkupvals(g); + propagateall(g); /* propagate changes */ + work = g->GCmemtrav; /* stop counting (do not recount 'grayagain') */ + g->gray = grayagain; + propagateall(g); /* traverse 'grayagain' list */ + g->GCmemtrav = 0; /* restart counting */ + convergeephemerons(g); + /* at this point, all strongly accessible objects are marked. */ + /* Clear values from weak tables, before checking finalizers */ + clearvalues(g, g->weak, NULL); + clearvalues(g, g->allweak, NULL); + origweak = g->weak; origall = g->allweak; + work += g->GCmemtrav; /* stop counting (objects being finalized) */ + separatetobefnz(g, 0); /* separate objects to be finalized */ + g->gcfinnum = 1; /* there may be objects to be finalized */ + markbeingfnz(g); /* mark objects that will be finalized */ + propagateall(g); /* remark, to propagate 'resurrection' */ + g->GCmemtrav = 0; /* restart counting */ + convergeephemerons(g); + /* at this point, all resurrected objects are marked. */ + /* remove dead objects from weak tables */ + clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */ + clearkeys(g, g->allweak, NULL); /* clear keys from all 'allweak' tables */ + /* clear values from resurrected weak tables */ + clearvalues(g, g->weak, origweak); + clearvalues(g, g->allweak, origall); + luaS_clearcache(g); + g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ + work += g->GCmemtrav; /* complete counting */ + return work; /* estimate of memory marked by 'atomic' */ +} + + +static lu_mem sweepstep (lua_State *L, global_State *g, + int nextstate, GCObject **nextlist) { + if (g->sweepgc) { + l_mem olddebt = g->GCdebt; + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); + g->GCestimate += g->GCdebt - olddebt; /* update estimate */ + if (g->sweepgc) /* is there still something to sweep? */ + return (GCSWEEPMAX * GCSWEEPCOST); + } + /* else enter next state */ + g->gcstate = nextstate; + g->sweepgc = nextlist; + return 0; +} + + +static lu_mem singlestep (lua_State *L) { + global_State *g = G(L); + switch (g->gcstate) { + case GCSpause: { + g->GCmemtrav = g->strt.size * sizeof(GCObject*); + restartcollection(g); + g->gcstate = GCSpropagate; + return g->GCmemtrav; + } + case GCSpropagate: { + g->GCmemtrav = 0; + lua_assert(g->gray); + propagatemark(g); + if (g->gray == NULL) /* no more gray objects? */ + g->gcstate = GCSatomic; /* finish propagate phase */ + return g->GCmemtrav; /* memory traversed in this step */ + } + case GCSatomic: { + lu_mem work; + propagateall(g); /* make sure gray list is empty */ + work = atomic(L); /* work is what was traversed by 'atomic' */ + entersweep(L); + g->GCestimate = gettotalbytes(g); /* first estimate */; + return work; + } + case GCSswpallgc: { /* sweep "regular" objects */ + return sweepstep(L, g, GCSswpfinobj, &g->finobj); + } + case GCSswpfinobj: { /* sweep objects with finalizers */ + return sweepstep(L, g, GCSswptobefnz, &g->tobefnz); + } + case GCSswptobefnz: { /* sweep objects to be finalized */ + return sweepstep(L, g, GCSswpend, NULL); + } + case GCSswpend: { /* finish sweeps */ + makewhite(g, g->mainthread); /* sweep main thread */ + checkSizes(L, g); + g->gcstate = GCScallfin; + return 0; + } + case GCScallfin: { /* call remaining finalizers */ + if (g->tobefnz && g->gckind != KGC_EMERGENCY) { + int n = runafewfinalizers(L); + return (n * GCFINALIZECOST); + } + else { /* emergency mode or no more finalizers */ + g->gcstate = GCSpause; /* finish collection */ + return 0; + } + } + default: lua_assert(0); return 0; + } +} + + +/* +** advances the garbage collector until it reaches a state allowed +** by 'statemask' +*/ +void luaC_runtilstate (lua_State *L, int statesmask) { + global_State *g = G(L); + while (!testbit(statesmask, g->gcstate)) + singlestep(L); +} + + +/* +** get GC debt and convert it from Kb to 'work units' (avoid zero debt +** and overflows) +*/ +static l_mem getdebt (global_State *g) { + l_mem debt = g->GCdebt; + int stepmul = g->gcstepmul; + if (debt <= 0) return 0; /* minimal debt */ + else { + debt = (debt / STEPMULADJ) + 1; + debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; + return debt; + } +} + +/* +** performs a basic GC step when collector is running +*/ +void luaC_step (lua_State *L) { + global_State *g = G(L); + l_mem debt = getdebt(g); /* GC deficit (be paid now) */ + if (!g->gcrunning) { /* not running? */ + luaE_setdebt(g, -GCSTEPSIZE * 10); /* avoid being called too often */ + return; + } + do { /* repeat until pause or enough "credit" (negative debt) */ + lu_mem work = singlestep(L); /* perform one single step */ + debt -= work; + } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); + if (g->gcstate == GCSpause) + setpause(g); /* pause until next cycle */ + else { + debt = (debt / g->gcstepmul) * STEPMULADJ; /* convert 'work units' to Kb */ + luaE_setdebt(g, debt); + runafewfinalizers(L); + } +} + + +/* +** Performs a full GC cycle; if 'isemergency', set a flag to avoid +** some operations which could change the interpreter state in some +** unexpected ways (running finalizers and shrinking some structures). +** Before running the collection, check 'keepinvariant'; if it is true, +** there may be some objects marked as black, so the collector has +** to sweep all objects to turn them back to white (as white has not +** changed, nothing will be collected). +*/ +void luaC_fullgc (lua_State *L, int isemergency) { + global_State *g = G(L); + lua_assert(g->gckind == KGC_NORMAL); + if (isemergency) g->gckind = KGC_EMERGENCY; /* set flag */ + if (keepinvariant(g)) { /* black objects? */ + entersweep(L); /* sweep everything to turn them back to white */ + } + /* finish any pending sweep phase to start a new cycle */ + luaC_runtilstate(L, bitmask(GCSpause)); + luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ + luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ + /* estimate must be correct after a full GC cycle */ + lua_assert(g->GCestimate == gettotalbytes(g)); + luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ + g->gckind = KGC_NORMAL; + setpause(g); +} + +/* }====================================================== */ + + diff --git a/3rd/lua-5.3.4/lgc.h b/3rd/lua-5.3.4/lgc.h new file mode 100644 index 0000000..aed3e18 --- /dev/null +++ b/3rd/lua-5.3.4/lgc.h @@ -0,0 +1,147 @@ +/* +** $Id: lgc.h,v 2.91 2015/12/21 13:02:14 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" +#include "lstate.h" + +/* +** Collectable objects may have one of three colors: white, which +** means the object is not marked; gray, which means the +** object is marked, but its references may be not marked; and +** black, which means that the object and all its references are marked. +** The main invariant of the garbage collector, while marking objects, +** is that a black object can never point to a white one. Moreover, +** any gray object must be in a "gray list" (gray, grayagain, weak, +** allweak, ephemeron) so that it can be visited again before finishing +** the collection cycle. These lists have no meaning when the invariant +** is not being enforced (e.g., sweep phase). +*/ + + + +/* how much to allocate before next GC step */ +#if !defined(GCSTEPSIZE) +/* ~100 small strings */ +#define GCSTEPSIZE (cast_int(100 * sizeof(TString))) +#endif + + +/* +** Possible states of the Garbage Collector +*/ +#define GCSpropagate 0 +#define GCSatomic 1 +#define GCSswpallgc 2 +#define GCSswpfinobj 3 +#define GCSswptobefnz 4 +#define GCSswpend 5 +#define GCScallfin 6 +#define GCSpause 7 + + +#define issweepphase(g) \ + (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) + + +/* +** macro to tell when main invariant (white objects cannot point to black +** ones) must be kept. During a collection, the sweep +** phase may break the invariant, as objects turned white may point to +** still-black objects. The invariant is restored when sweep ends and +** all objects are white again. +*/ + +#define keepinvariant(g) ((g)->gcstate <= GCSatomic) + + +/* +** some useful bit tricks +*/ +#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) + + +/* Layout for bit use in 'marked' field: */ +#define WHITE0BIT 0 /* object is white (type 0) */ +#define WHITE1BIT 1 /* object is white (type 1) */ +#define BLACKBIT 2 /* object is black */ +#define FINALIZEDBIT 3 /* object has been marked for finalization */ +/* bit 7 is currently used by tests (luaL_checkmemory) */ + +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) + + +#define iswhite(x) testbits((x)->marked, WHITEBITS) +#define isblack(x) testbit((x)->marked, BLACKBIT) +#define isgray(x) /* neither white nor black */ \ + (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) + +#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) + +#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) +#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) +#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) + +#define changewhite(x) ((x)->marked ^= WHITEBITS) +#define gray2black(x) l_setbit((x)->marked, BLACKBIT) + +#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) + + +/* +** Does one step of collection when debt becomes positive. 'pre'/'pos' +** allows some adjustments to be done only when needed. macro +** 'condchangemem' is used only for heavy tests (forcing a full +** GC cycle on every opportunity) +*/ +#define luaC_condGC(L,pre,pos) \ + { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ + condchangemem(L,pre,pos); } + +/* more often than not, 'pre'/'pos' are empty */ +#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0) + + +#define luaC_barrier(L,p,v) ( \ + (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ + luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0)) + +#define luaC_barrierback(L,p,v) ( \ + (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ + luaC_barrierback_(L,p) : cast_void(0)) + +#define luaC_objbarrier(L,p,o) ( \ + (isblack(p) && iswhite(o)) ? \ + luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) + +#define luaC_upvalbarrier(L,uv) ( \ + (iscollectable((uv)->v) && !upisopen(uv)) ? \ + luaC_upvalbarrier_(L,uv) : cast_void(0)) + +LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); +LUAI_FUNC void luaC_freeallobjects (lua_State *L); +LUAI_FUNC void luaC_step (lua_State *L); +LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); +LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); +LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); +LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o); +LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv); +LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); +LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv); + + +#endif diff --git a/3rd/lua-5.3.4/linit.c b/3rd/lua-5.3.4/linit.c new file mode 100644 index 0000000..afcaf98 --- /dev/null +++ b/3rd/lua-5.3.4/linit.c @@ -0,0 +1,68 @@ +/* +** $Id: linit.c,v 1.39 2016/12/04 20:17:24 roberto Exp $ +** Initialization of libraries for lua.c and other clients +** See Copyright Notice in lua.h +*/ + + +#define linit_c +#define LUA_LIB + +/* +** If you embed Lua in your program and need to open the standard +** libraries, call luaL_openlibs in your program. If you need a +** different set of libraries, copy this file to your project and edit +** it to suit your needs. +** +** You can also *preload* libraries, so that a later 'require' can +** open the library, which is already linked to the application. +** For that, do the following code: +** +** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); +** lua_pushcfunction(L, luaopen_modname); +** lua_setfield(L, -2, modname); +** lua_pop(L, 1); // remove PRELOAD table +*/ + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "lualib.h" +#include "lauxlib.h" + + +/* +** these libs are loaded by lua.c and are readily available to any Lua +** program +*/ +static const luaL_Reg loadedlibs[] = { + {"_G", luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_COLIBNAME, luaopen_coroutine}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_UTF8LIBNAME, luaopen_utf8}, + {LUA_DBLIBNAME, luaopen_debug}, +#if defined(LUA_COMPAT_BITLIB) + {LUA_BITLIBNAME, luaopen_bit32}, +#endif + {NULL, NULL} +}; + + +LUALIB_API void luaL_openlibs (lua_State *L) { + const luaL_Reg *lib; + /* "require" functions from 'loadedlibs' and set results to global table */ + for (lib = loadedlibs; lib->func; lib++) { + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); /* remove lib */ + } +} + diff --git a/3rd/lua-5.3.4/liolib.c b/3rd/lua-5.3.4/liolib.c new file mode 100644 index 0000000..1568403 --- /dev/null +++ b/3rd/lua-5.3.4/liolib.c @@ -0,0 +1,771 @@ +/* +** $Id: liolib.c,v 2.151 2016/12/20 18:37:00 roberto Exp $ +** Standard I/O (and system) library +** See Copyright Notice in lua.h +*/ + +#define liolib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + + +/* +** Change this macro to accept other modes for 'fopen' besides +** the standard ones. +*/ +#if !defined(l_checkmode) + +/* accepted extensions to 'mode' in 'fopen' */ +#if !defined(L_MODEEXT) +#define L_MODEEXT "b" +#endif + +/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */ +static int l_checkmode (const char *mode) { + return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && + (*mode != '+' || (++mode, 1)) && /* skip if char is '+' */ + (strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */ +} + +#endif + +/* +** {====================================================== +** l_popen spawns a new process connected to the current +** one through the file streams. +** ======================================================= +*/ + +#if !defined(l_popen) /* { */ + +#if defined(LUA_USE_POSIX) /* { */ + +#define l_popen(L,c,m) (fflush(NULL), popen(c,m)) +#define l_pclose(L,file) (pclose(file)) + +#elif defined(LUA_USE_WINDOWS) /* }{ */ + +#define l_popen(L,c,m) (_popen(c,m)) +#define l_pclose(L,file) (_pclose(file)) + +#else /* }{ */ + +/* ISO C definitions */ +#define l_popen(L,c,m) \ + ((void)((void)c, m), \ + luaL_error(L, "'popen' not supported"), \ + (FILE*)0) +#define l_pclose(L,file) ((void)L, (void)file, -1) + +#endif /* } */ + +#endif /* } */ + +/* }====================================================== */ + + +#if !defined(l_getc) /* { */ + +#if defined(LUA_USE_POSIX) +#define l_getc(f) getc_unlocked(f) +#define l_lockfile(f) flockfile(f) +#define l_unlockfile(f) funlockfile(f) +#else +#define l_getc(f) getc(f) +#define l_lockfile(f) ((void)0) +#define l_unlockfile(f) ((void)0) +#endif + +#endif /* } */ + + +/* +** {====================================================== +** l_fseek: configuration for longer offsets +** ======================================================= +*/ + +#if !defined(l_fseek) /* { */ + +#if defined(LUA_USE_POSIX) /* { */ + +#include + +#define l_fseek(f,o,w) fseeko(f,o,w) +#define l_ftell(f) ftello(f) +#define l_seeknum off_t + +#elif defined(LUA_USE_WINDOWS) && !defined(_CRTIMP_TYPEINFO) \ + && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */ + +/* Windows (but not DDK) and Visual C++ 2005 or higher */ +#define l_fseek(f,o,w) _fseeki64(f,o,w) +#define l_ftell(f) _ftelli64(f) +#define l_seeknum __int64 + +#else /* }{ */ + +/* ISO C definitions */ +#define l_fseek(f,o,w) fseek(f,o,w) +#define l_ftell(f) ftell(f) +#define l_seeknum long + +#endif /* } */ + +#endif /* } */ + +/* }====================================================== */ + + +#define IO_PREFIX "_IO_" +#define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1) +#define IO_INPUT (IO_PREFIX "input") +#define IO_OUTPUT (IO_PREFIX "output") + + +typedef luaL_Stream LStream; + + +#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) + +#define isclosed(p) ((p)->closef == NULL) + + +static int io_type (lua_State *L) { + LStream *p; + luaL_checkany(L, 1); + p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE); + if (p == NULL) + lua_pushnil(L); /* not a file */ + else if (isclosed(p)) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; +} + + +static int f_tostring (lua_State *L) { + LStream *p = tolstream(L); + if (isclosed(p)) + lua_pushliteral(L, "file (closed)"); + else + lua_pushfstring(L, "file (%p)", p->f); + return 1; +} + + +static FILE *tofile (lua_State *L) { + LStream *p = tolstream(L); + if (isclosed(p)) + luaL_error(L, "attempt to use a closed file"); + lua_assert(p->f); + return p->f; +} + + +/* +** When creating file handles, always creates a 'closed' file handle +** before opening the actual file; so, if there is a memory error, the +** handle is in a consistent state. +*/ +static LStream *newprefile (lua_State *L) { + LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream)); + p->closef = NULL; /* mark file handle as 'closed' */ + luaL_setmetatable(L, LUA_FILEHANDLE); + return p; +} + + +/* +** Calls the 'close' function from a file handle. The 'volatile' avoids +** a bug in some versions of the Clang compiler (e.g., clang 3.0 for +** 32 bits). +*/ +static int aux_close (lua_State *L) { + LStream *p = tolstream(L); + volatile lua_CFunction cf = p->closef; + p->closef = NULL; /* mark stream as closed */ + return (*cf)(L); /* close it */ +} + + +static int io_close (lua_State *L) { + if (lua_isnone(L, 1)) /* no argument? */ + lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ + tofile(L); /* make sure argument is an open stream */ + return aux_close(L); +} + + +static int f_gc (lua_State *L) { + LStream *p = tolstream(L); + if (!isclosed(p) && p->f != NULL) + aux_close(L); /* ignore closed and incompletely open files */ + return 0; +} + + +/* +** function to close regular files +*/ +static int io_fclose (lua_State *L) { + LStream *p = tolstream(L); + int res = fclose(p->f); + return luaL_fileresult(L, (res == 0), NULL); +} + + +static LStream *newfile (lua_State *L) { + LStream *p = newprefile(L); + p->f = NULL; + p->closef = &io_fclose; + return p; +} + + +static void opencheck (lua_State *L, const char *fname, const char *mode) { + LStream *p = newfile(L); + p->f = fopen(fname, mode); + if (p->f == NULL) + luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno)); +} + + +static int io_open (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + LStream *p = newfile(L); + const char *md = mode; /* to traverse/check mode */ + luaL_argcheck(L, l_checkmode(md), 2, "invalid mode"); + p->f = fopen(filename, mode); + return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; +} + + +/* +** function to close 'popen' files +*/ +static int io_pclose (lua_State *L) { + LStream *p = tolstream(L); + return luaL_execresult(L, l_pclose(L, p->f)); +} + + +static int io_popen (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + LStream *p = newprefile(L); + p->f = l_popen(L, filename, mode); + p->closef = &io_pclose; + return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; +} + + +static int io_tmpfile (lua_State *L) { + LStream *p = newfile(L); + p->f = tmpfile(); + return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1; +} + + +static FILE *getiofile (lua_State *L, const char *findex) { + LStream *p; + lua_getfield(L, LUA_REGISTRYINDEX, findex); + p = (LStream *)lua_touserdata(L, -1); + if (isclosed(p)) + luaL_error(L, "standard %s file is closed", findex + IOPREF_LEN); + return p->f; +} + + +static int g_iofile (lua_State *L, const char *f, const char *mode) { + if (!lua_isnoneornil(L, 1)) { + const char *filename = lua_tostring(L, 1); + if (filename) + opencheck(L, filename, mode); + else { + tofile(L); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + lua_setfield(L, LUA_REGISTRYINDEX, f); + } + /* return current value */ + lua_getfield(L, LUA_REGISTRYINDEX, f); + return 1; +} + + +static int io_input (lua_State *L) { + return g_iofile(L, IO_INPUT, "r"); +} + + +static int io_output (lua_State *L) { + return g_iofile(L, IO_OUTPUT, "w"); +} + + +static int io_readline (lua_State *L); + + +/* +** maximum number of arguments to 'f:lines'/'io.lines' (it + 3 must fit +** in the limit for upvalues of a closure) +*/ +#define MAXARGLINE 250 + +static void aux_lines (lua_State *L, int toclose) { + int n = lua_gettop(L) - 1; /* number of arguments to read */ + luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments"); + lua_pushinteger(L, n); /* number of arguments to read */ + lua_pushboolean(L, toclose); /* close/not close file when finished */ + lua_rotate(L, 2, 2); /* move 'n' and 'toclose' to their positions */ + lua_pushcclosure(L, io_readline, 3 + n); +} + + +static int f_lines (lua_State *L) { + tofile(L); /* check that it's a valid file handle */ + aux_lines(L, 0); + return 1; +} + + +static int io_lines (lua_State *L) { + int toclose; + if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ + if (lua_isnil(L, 1)) { /* no file name? */ + lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */ + lua_replace(L, 1); /* put it at index 1 */ + tofile(L); /* check that it's a valid file handle */ + toclose = 0; /* do not close it after iteration */ + } + else { /* open a new file */ + const char *filename = luaL_checkstring(L, 1); + opencheck(L, filename, "r"); + lua_replace(L, 1); /* put file at index 1 */ + toclose = 1; /* close it after iteration */ + } + aux_lines(L, toclose); + return 1; +} + + +/* +** {====================================================== +** READ +** ======================================================= +*/ + + +/* maximum length of a numeral */ +#if !defined (L_MAXLENNUM) +#define L_MAXLENNUM 200 +#endif + + +/* auxiliary structure used by 'read_number' */ +typedef struct { + FILE *f; /* file being read */ + int c; /* current character (look ahead) */ + int n; /* number of elements in buffer 'buff' */ + char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */ +} RN; + + +/* +** Add current char to buffer (if not out of space) and read next one +*/ +static int nextc (RN *rn) { + if (rn->n >= L_MAXLENNUM) { /* buffer overflow? */ + rn->buff[0] = '\0'; /* invalidate result */ + return 0; /* fail */ + } + else { + rn->buff[rn->n++] = rn->c; /* save current char */ + rn->c = l_getc(rn->f); /* read next one */ + return 1; + } +} + + +/* +** Accept current char if it is in 'set' (of size 2) +*/ +static int test2 (RN *rn, const char *set) { + if (rn->c == set[0] || rn->c == set[1]) + return nextc(rn); + else return 0; +} + + +/* +** Read a sequence of (hex)digits +*/ +static int readdigits (RN *rn, int hex) { + int count = 0; + while ((hex ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn)) + count++; + return count; +} + + +/* +** Read a number: first reads a valid prefix of a numeral into a buffer. +** Then it calls 'lua_stringtonumber' to check whether the format is +** correct and to convert it to a Lua number +*/ +static int read_number (lua_State *L, FILE *f) { + RN rn; + int count = 0; + int hex = 0; + char decp[2]; + rn.f = f; rn.n = 0; + decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */ + decp[1] = '.'; /* always accept a dot */ + l_lockfile(rn.f); + do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */ + test2(&rn, "-+"); /* optional signal */ + if (test2(&rn, "00")) { + if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */ + else count = 1; /* count initial '0' as a valid digit */ + } + count += readdigits(&rn, hex); /* integral part */ + if (test2(&rn, decp)) /* decimal point? */ + count += readdigits(&rn, hex); /* fractional part */ + if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */ + test2(&rn, "-+"); /* exponent signal */ + readdigits(&rn, 0); /* exponent digits */ + } + ungetc(rn.c, rn.f); /* unread look-ahead char */ + l_unlockfile(rn.f); + rn.buff[rn.n] = '\0'; /* finish string */ + if (lua_stringtonumber(L, rn.buff)) /* is this a valid number? */ + return 1; /* ok */ + else { /* invalid format */ + lua_pushnil(L); /* "result" to be removed */ + return 0; /* read fails */ + } +} + + +static int test_eof (lua_State *L, FILE *f) { + int c = getc(f); + ungetc(c, f); /* no-op when c == EOF */ + lua_pushliteral(L, ""); + return (c != EOF); +} + + +static int read_line (lua_State *L, FILE *f, int chop) { + luaL_Buffer b; + int c = '\0'; + luaL_buffinit(L, &b); + while (c != EOF && c != '\n') { /* repeat until end of line */ + char *buff = luaL_prepbuffer(&b); /* preallocate buffer */ + int i = 0; + l_lockfile(f); /* no memory errors can happen inside the lock */ + while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n') + buff[i++] = c; + l_unlockfile(f); + luaL_addsize(&b, i); + } + if (!chop && c == '\n') /* want a newline and have one? */ + luaL_addchar(&b, c); /* add ending newline to result */ + luaL_pushresult(&b); /* close buffer */ + /* return ok if read something (either a newline or something else) */ + return (c == '\n' || lua_rawlen(L, -1) > 0); +} + + +static void read_all (lua_State *L, FILE *f) { + size_t nr; + luaL_Buffer b; + luaL_buffinit(L, &b); + do { /* read file in chunks of LUAL_BUFFERSIZE bytes */ + char *p = luaL_prepbuffer(&b); + nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f); + luaL_addsize(&b, nr); + } while (nr == LUAL_BUFFERSIZE); + luaL_pushresult(&b); /* close buffer */ +} + + +static int read_chars (lua_State *L, FILE *f, size_t n) { + size_t nr; /* number of chars actually read */ + char *p; + luaL_Buffer b; + luaL_buffinit(L, &b); + p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */ + nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */ + luaL_addsize(&b, nr); + luaL_pushresult(&b); /* close buffer */ + return (nr > 0); /* true iff read something */ +} + + +static int g_read (lua_State *L, FILE *f, int first) { + int nargs = lua_gettop(L) - 1; + int success; + int n; + clearerr(f); + if (nargs == 0) { /* no arguments? */ + success = read_line(L, f, 1); + n = first+1; /* to return 1 result */ + } + else { /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) { + if (lua_type(L, n) == LUA_TNUMBER) { + size_t l = (size_t)luaL_checkinteger(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } + else { + const char *p = luaL_checkstring(L, n); + if (*p == '*') p++; /* skip optional '*' (for compatibility) */ + switch (*p) { + case 'n': /* number */ + success = read_number(L, f); + break; + case 'l': /* line */ + success = read_line(L, f, 1); + break; + case 'L': /* line with end-of-line */ + success = read_line(L, f, 0); + break; + case 'a': /* file */ + read_all(L, f); /* read entire file */ + success = 1; /* always success */ + break; + default: + return luaL_argerror(L, n, "invalid format"); + } + } + } + } + if (ferror(f)) + return luaL_fileresult(L, 0, NULL); + if (!success) { + lua_pop(L, 1); /* remove last result */ + lua_pushnil(L); /* push nil instead */ + } + return n - first; +} + + +static int io_read (lua_State *L) { + return g_read(L, getiofile(L, IO_INPUT), 1); +} + + +static int f_read (lua_State *L) { + return g_read(L, tofile(L), 2); +} + + +static int io_readline (lua_State *L) { + LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); + int i; + int n = (int)lua_tointeger(L, lua_upvalueindex(2)); + if (isclosed(p)) /* file is already closed? */ + return luaL_error(L, "file is already closed"); + lua_settop(L , 1); + luaL_checkstack(L, n, "too many arguments"); + for (i = 1; i <= n; i++) /* push arguments to 'g_read' */ + lua_pushvalue(L, lua_upvalueindex(3 + i)); + n = g_read(L, p->f, 2); /* 'n' is number of results */ + lua_assert(n > 0); /* should return at least a nil */ + if (lua_toboolean(L, -n)) /* read at least one value? */ + return n; /* return them */ + else { /* first result is nil: EOF or error */ + if (n > 1) { /* is there error information? */ + /* 2nd result is error message */ + return luaL_error(L, "%s", lua_tostring(L, -n + 1)); + } + if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ + lua_settop(L, 0); + lua_pushvalue(L, lua_upvalueindex(1)); + aux_close(L); /* close it */ + } + return 0; + } +} + +/* }====================================================== */ + + +static int g_write (lua_State *L, FILE *f, int arg) { + int nargs = lua_gettop(L) - arg; + int status = 1; + for (; nargs--; arg++) { + if (lua_type(L, arg) == LUA_TNUMBER) { + /* optimization: could be done exactly as for strings */ + int len = lua_isinteger(L, arg) + ? fprintf(f, LUA_INTEGER_FMT, + (LUAI_UACINT)lua_tointeger(L, arg)) + : fprintf(f, LUA_NUMBER_FMT, + (LUAI_UACNUMBER)lua_tonumber(L, arg)); + status = status && (len > 0); + } + else { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + status = status && (fwrite(s, sizeof(char), l, f) == l); + } + } + if (status) return 1; /* file handle already on stack top */ + else return luaL_fileresult(L, status, NULL); +} + + +static int io_write (lua_State *L) { + return g_write(L, getiofile(L, IO_OUTPUT), 1); +} + + +static int f_write (lua_State *L) { + FILE *f = tofile(L); + lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ + return g_write(L, f, 2); +} + + +static int f_seek (lua_State *L) { + static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, "cur", modenames); + lua_Integer p3 = luaL_optinteger(L, 3, 0); + l_seeknum offset = (l_seeknum)p3; + luaL_argcheck(L, (lua_Integer)offset == p3, 3, + "not an integer in proper range"); + op = l_fseek(f, offset, mode[op]); + if (op) + return luaL_fileresult(L, 0, NULL); /* error */ + else { + lua_pushinteger(L, (lua_Integer)l_ftell(f)); + return 1; + } +} + + +static int f_setvbuf (lua_State *L) { + static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; + static const char *const modenames[] = {"no", "full", "line", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, NULL, modenames); + lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); + int res = setvbuf(f, NULL, mode[op], (size_t)sz); + return luaL_fileresult(L, res == 0, NULL); +} + + + +static int io_flush (lua_State *L) { + return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); +} + + +static int f_flush (lua_State *L) { + return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); +} + + +/* +** functions for 'io' library +*/ +static const luaL_Reg iolib[] = { + {"close", io_close}, + {"flush", io_flush}, + {"input", io_input}, + {"lines", io_lines}, + {"open", io_open}, + {"output", io_output}, + {"popen", io_popen}, + {"read", io_read}, + {"tmpfile", io_tmpfile}, + {"type", io_type}, + {"write", io_write}, + {NULL, NULL} +}; + + +/* +** methods for file handles +*/ +static const luaL_Reg flib[] = { + {"close", io_close}, + {"flush", f_flush}, + {"lines", f_lines}, + {"read", f_read}, + {"seek", f_seek}, + {"setvbuf", f_setvbuf}, + {"write", f_write}, + {"__gc", f_gc}, + {"__tostring", f_tostring}, + {NULL, NULL} +}; + + +static void createmeta (lua_State *L) { + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */ + lua_pop(L, 1); /* pop new metatable */ +} + + +/* +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + LStream *p = tolstream(L); + p->closef = &io_noclose; /* keep file opened */ + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +static void createstdfile (lua_State *L, FILE *f, const char *k, + const char *fname) { + LStream *p = newprefile(L); + p->f = f; + p->closef = &io_noclose; + if (k != NULL) { + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */ + } + lua_setfield(L, -2, fname); /* add file to module */ +} + + +LUAMOD_API int luaopen_io (lua_State *L) { + luaL_newlib(L, iolib); /* new module */ + createmeta(L); + /* create (and set) default files */ + createstdfile(L, stdin, IO_INPUT, "stdin"); + createstdfile(L, stdout, IO_OUTPUT, "stdout"); + createstdfile(L, stderr, NULL, "stderr"); + return 1; +} + diff --git a/3rd/lua-5.3.4/llex.c b/3rd/lua-5.3.4/llex.c new file mode 100644 index 0000000..7032827 --- /dev/null +++ b/3rd/lua-5.3.4/llex.c @@ -0,0 +1,565 @@ +/* +** $Id: llex.c,v 2.96 2016/05/02 14:02:12 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#define llex_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lctype.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lzio.h" + + + +#define next(ls) (ls->current = zgetc(ls->z)) + + + +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') + + +/* ORDER RESERVED */ +static const char *const luaX_tokens [] = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "goto", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "//", "..", "...", "==", ">=", "<=", "~=", + "<<", ">>", "::", "", + "", "", "", "" +}; + + +#define save_and_next(ls) (save(ls, ls->current), next(ls)) + + +static l_noret lexerror (LexState *ls, const char *msg, int token); + + +static void save (LexState *ls, int c) { + Mbuffer *b = ls->buff; + if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) { + size_t newsize; + if (luaZ_sizebuffer(b) >= MAX_SIZE/2) + lexerror(ls, "lexical element too long", 0); + newsize = luaZ_sizebuffer(b) * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[luaZ_bufflen(b)++] = cast(char, c); +} + + +void luaX_init (lua_State *L) { + int i; + TString *e = luaS_newliteral(L, LUA_ENV); /* create env name */ + luaC_fix(L, obj2gco(e)); /* never collect this name */ + for (i=0; iextra = cast_byte(i+1); /* reserved word */ + } +} + + +const char *luaX_token2str (LexState *ls, int token) { + if (token < FIRST_RESERVED) { /* single-byte symbols? */ + lua_assert(token == cast_uchar(token)); + return luaO_pushfstring(ls->L, "'%c'", token); + } + else { + const char *s = luaX_tokens[token - FIRST_RESERVED]; + if (token < TK_EOS) /* fixed format (symbols and reserved words)? */ + return luaO_pushfstring(ls->L, "'%s'", s); + else /* names, strings, and numerals */ + return s; + } +} + + +static const char *txtToken (LexState *ls, int token) { + switch (token) { + case TK_NAME: case TK_STRING: + case TK_FLT: case TK_INT: + save(ls, '\0'); + return luaO_pushfstring(ls->L, "'%s'", luaZ_buffer(ls->buff)); + default: + return luaX_token2str(ls, token); + } +} + + +static l_noret lexerror (LexState *ls, const char *msg, int token) { + msg = luaG_addinfo(ls->L, msg, ls->source, ls->linenumber); + if (token) + luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token)); + luaD_throw(ls->L, LUA_ERRSYNTAX); +} + + +l_noret luaX_syntaxerror (LexState *ls, const char *msg) { + lexerror(ls, msg, ls->t.token); +} + + +/* +** creates a new string and anchors it in scanner's table so that +** it will not be collected until the end of the compilation +** (by that time it should be anchored somewhere) +*/ +TString *luaX_newstring (LexState *ls, const char *str, size_t l) { + lua_State *L = ls->L; + TValue *o; /* entry for 'str' */ + TString *ts = luaS_newlstr(L, str, l); /* create new string */ + setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ + o = luaH_set(L, ls->h, L->top - 1); + if (ttisnil(o)) { /* not in use yet? */ + /* boolean value does not need GC barrier; + table has no metatable, so it does not need to invalidate cache */ + setbvalue(o, 1); /* t[string] = true */ + luaC_checkGC(L); + } + else { /* string already present */ + ts = tsvalue(keyfromval(o)); /* re-use value previously stored */ + } + L->top--; /* remove string from stack */ + return ts; +} + + +/* +** increment line number and skips newline sequence (any of +** \n, \r, \n\r, or \r\n) +*/ +static void inclinenumber (LexState *ls) { + int old = ls->current; + lua_assert(currIsNewline(ls)); + next(ls); /* skip '\n' or '\r' */ + if (currIsNewline(ls) && ls->current != old) + next(ls); /* skip '\n\r' or '\r\n' */ + if (++ls->linenumber >= MAX_INT) + lexerror(ls, "chunk has too many lines", 0); +} + + +void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, + int firstchar) { + ls->t.token = 0; + ls->L = L; + ls->current = firstchar; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ + ls->z = z; + ls->fs = NULL; + ls->linenumber = 1; + ls->lastline = 1; + ls->source = source; + ls->envn = luaS_newliteral(L, LUA_ENV); /* get env name */ + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ +} + + + +/* +** ======================================================= +** LEXICAL ANALYZER +** ======================================================= +*/ + + +static int check_next1 (LexState *ls, int c) { + if (ls->current == c) { + next(ls); + return 1; + } + else return 0; +} + + +/* +** Check whether current char is in set 'set' (with two chars) and +** saves it +*/ +static int check_next2 (LexState *ls, const char *set) { + lua_assert(set[2] == '\0'); + if (ls->current == set[0] || ls->current == set[1]) { + save_and_next(ls); + return 1; + } + else return 0; +} + + +/* LUA_NUMBER */ +/* +** this function is quite liberal in what it accepts, as 'luaO_str2num' +** will reject ill-formed numerals. +*/ +static int read_numeral (LexState *ls, SemInfo *seminfo) { + TValue obj; + const char *expo = "Ee"; + int first = ls->current; + lua_assert(lisdigit(ls->current)); + save_and_next(ls); + if (first == '0' && check_next2(ls, "xX")) /* hexadecimal? */ + expo = "Pp"; + for (;;) { + if (check_next2(ls, expo)) /* exponent part? */ + check_next2(ls, "-+"); /* optional exponent sign */ + if (lisxdigit(ls->current)) + save_and_next(ls); + else if (ls->current == '.') + save_and_next(ls); + else break; + } + save(ls, '\0'); + if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */ + lexerror(ls, "malformed number", TK_FLT); + if (ttisinteger(&obj)) { + seminfo->i = ivalue(&obj); + return TK_INT; + } + else { + lua_assert(ttisfloat(&obj)); + seminfo->r = fltvalue(&obj); + return TK_FLT; + } +} + + +/* +** skip a sequence '[=*[' or ']=*]'; if sequence is well formed, return +** its number of '='s; otherwise, return a negative number (-1 iff there +** are no '='s after initial bracket) +*/ +static int skip_sep (LexState *ls) { + int count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); + save_and_next(ls); + while (ls->current == '=') { + save_and_next(ls); + count++; + } + return (ls->current == s) ? count : (-count) - 1; +} + + +static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { + int line = ls->linenumber; /* initial line (for error message) */ + save_and_next(ls); /* skip 2nd '[' */ + if (currIsNewline(ls)) /* string starts with a newline? */ + inclinenumber(ls); /* skip it */ + for (;;) { + switch (ls->current) { + case EOZ: { /* error */ + const char *what = (seminfo ? "string" : "comment"); + const char *msg = luaO_pushfstring(ls->L, + "unfinished long %s (starting at line %d)", what, line); + lexerror(ls, msg, TK_EOS); + break; /* to avoid warnings */ + } + case ']': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd ']' */ + goto endloop; + } + break; + } + case '\n': case '\r': { + save(ls, '\n'); + inclinenumber(ls); + if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ + break; + } + default: { + if (seminfo) save_and_next(ls); + else next(ls); + } + } + } endloop: + if (seminfo) + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), + luaZ_bufflen(ls->buff) - 2*(2 + sep)); +} + + +static void esccheck (LexState *ls, int c, const char *msg) { + if (!c) { + if (ls->current != EOZ) + save_and_next(ls); /* add current to buffer for error message */ + lexerror(ls, msg, TK_STRING); + } +} + + +static int gethexa (LexState *ls) { + save_and_next(ls); + esccheck (ls, lisxdigit(ls->current), "hexadecimal digit expected"); + return luaO_hexavalue(ls->current); +} + + +static int readhexaesc (LexState *ls) { + int r = gethexa(ls); + r = (r << 4) + gethexa(ls); + luaZ_buffremove(ls->buff, 2); /* remove saved chars from buffer */ + return r; +} + + +static unsigned long readutf8esc (LexState *ls) { + unsigned long r; + int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */ + save_and_next(ls); /* skip 'u' */ + esccheck(ls, ls->current == '{', "missing '{'"); + r = gethexa(ls); /* must have at least one digit */ + while ((save_and_next(ls), lisxdigit(ls->current))) { + i++; + r = (r << 4) + luaO_hexavalue(ls->current); + esccheck(ls, r <= 0x10FFFF, "UTF-8 value too large"); + } + esccheck(ls, ls->current == '}', "missing '}'"); + next(ls); /* skip '}' */ + luaZ_buffremove(ls->buff, i); /* remove saved chars from buffer */ + return r; +} + + +static void utf8esc (LexState *ls) { + char buff[UTF8BUFFSZ]; + int n = luaO_utf8esc(buff, readutf8esc(ls)); + for (; n > 0; n--) /* add 'buff' to string */ + save(ls, buff[UTF8BUFFSZ - n]); +} + + +static int readdecesc (LexState *ls) { + int i; + int r = 0; /* result accumulator */ + for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */ + r = 10*r + ls->current - '0'; + save_and_next(ls); + } + esccheck(ls, r <= UCHAR_MAX, "decimal escape too large"); + luaZ_buffremove(ls->buff, i); /* remove read digits from buffer */ + return r; +} + + +static void read_string (LexState *ls, int del, SemInfo *seminfo) { + save_and_next(ls); /* keep delimiter (for error messages) */ + while (ls->current != del) { + switch (ls->current) { + case EOZ: + lexerror(ls, "unfinished string", TK_EOS); + break; /* to avoid warnings */ + case '\n': + case '\r': + lexerror(ls, "unfinished string", TK_STRING); + break; /* to avoid warnings */ + case '\\': { /* escape sequences */ + int c; /* final character to be saved */ + save_and_next(ls); /* keep '\\' for error messages */ + switch (ls->current) { + case 'a': c = '\a'; goto read_save; + case 'b': c = '\b'; goto read_save; + case 'f': c = '\f'; goto read_save; + case 'n': c = '\n'; goto read_save; + case 'r': c = '\r'; goto read_save; + case 't': c = '\t'; goto read_save; + case 'v': c = '\v'; goto read_save; + case 'x': c = readhexaesc(ls); goto read_save; + case 'u': utf8esc(ls); goto no_save; + case '\n': case '\r': + inclinenumber(ls); c = '\n'; goto only_save; + case '\\': case '\"': case '\'': + c = ls->current; goto read_save; + case EOZ: goto no_save; /* will raise an error next loop */ + case 'z': { /* zap following span of spaces */ + luaZ_buffremove(ls->buff, 1); /* remove '\\' */ + next(ls); /* skip the 'z' */ + while (lisspace(ls->current)) { + if (currIsNewline(ls)) inclinenumber(ls); + else next(ls); + } + goto no_save; + } + default: { + esccheck(ls, lisdigit(ls->current), "invalid escape sequence"); + c = readdecesc(ls); /* digital escape '\ddd' */ + goto only_save; + } + } + read_save: + next(ls); + /* go through */ + only_save: + luaZ_buffremove(ls->buff, 1); /* remove '\\' */ + save(ls, c); + /* go through */ + no_save: break; + } + default: + save_and_next(ls); + } + } + save_and_next(ls); /* skip delimiter */ + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, + luaZ_bufflen(ls->buff) - 2); +} + + +static int llex (LexState *ls, SemInfo *seminfo) { + luaZ_resetbuffer(ls->buff); + for (;;) { + switch (ls->current) { + case '\n': case '\r': { /* line breaks */ + inclinenumber(ls); + break; + } + case ' ': case '\f': case '\t': case '\v': { /* spaces */ + next(ls); + break; + } + case '-': { /* '-' or '--' (comment) */ + next(ls); + if (ls->current != '-') return '-'; + /* else is a comment */ + next(ls); + if (ls->current == '[') { /* long comment? */ + int sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */ + if (sep >= 0) { + read_long_string(ls, NULL, sep); /* skip long comment */ + luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ + break; + } + } + /* else short comment */ + while (!currIsNewline(ls) && ls->current != EOZ) + next(ls); /* skip until end of line (or end of file) */ + break; + } + case '[': { /* long string or simply '[' */ + int sep = skip_sep(ls); + if (sep >= 0) { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } + else if (sep != -1) /* '[=...' missing second bracket */ + lexerror(ls, "invalid long string delimiter", TK_STRING); + return '['; + } + case '=': { + next(ls); + if (check_next1(ls, '=')) return TK_EQ; + else return '='; + } + case '<': { + next(ls); + if (check_next1(ls, '=')) return TK_LE; + else if (check_next1(ls, '<')) return TK_SHL; + else return '<'; + } + case '>': { + next(ls); + if (check_next1(ls, '=')) return TK_GE; + else if (check_next1(ls, '>')) return TK_SHR; + else return '>'; + } + case '/': { + next(ls); + if (check_next1(ls, '/')) return TK_IDIV; + else return '/'; + } + case '~': { + next(ls); + if (check_next1(ls, '=')) return TK_NE; + else return '~'; + } + case ':': { + next(ls); + if (check_next1(ls, ':')) return TK_DBCOLON; + else return ':'; + } + case '"': case '\'': { /* short literal strings */ + read_string(ls, ls->current, seminfo); + return TK_STRING; + } + case '.': { /* '.', '..', '...', or number */ + save_and_next(ls); + if (check_next1(ls, '.')) { + if (check_next1(ls, '.')) + return TK_DOTS; /* '...' */ + else return TK_CONCAT; /* '..' */ + } + else if (!lisdigit(ls->current)) return '.'; + else return read_numeral(ls, seminfo); + } + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + return read_numeral(ls, seminfo); + } + case EOZ: { + return TK_EOS; + } + default: { + if (lislalpha(ls->current)) { /* identifier or reserved word? */ + TString *ts; + do { + save_and_next(ls); + } while (lislalnum(ls->current)); + ts = luaX_newstring(ls, luaZ_buffer(ls->buff), + luaZ_bufflen(ls->buff)); + seminfo->ts = ts; + if (isreserved(ts)) /* reserved word? */ + return ts->extra - 1 + FIRST_RESERVED; + else { + return TK_NAME; + } + } + else { /* single-char tokens (+ - / ...) */ + int c = ls->current; + next(ls); + return c; + } + } + } + } +} + + +void luaX_next (LexState *ls) { + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ +} + + +int luaX_lookahead (LexState *ls) { + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); + return ls->lookahead.token; +} + diff --git a/3rd/lua-5.3.4/llex.h b/3rd/lua-5.3.4/llex.h new file mode 100644 index 0000000..2363d87 --- /dev/null +++ b/3rd/lua-5.3.4/llex.h @@ -0,0 +1,85 @@ +/* +** $Id: llex.h,v 1.79 2016/05/02 14:02:12 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include "lobject.h" +#include "lzio.h" + + +#define FIRST_RESERVED 257 + + +#if !defined(LUA_ENV) +#define LUA_ENV "_ENV" +#endif + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, + TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, + TK_SHL, TK_SHR, + TK_DBCOLON, TK_EOS, + TK_FLT, TK_INT, TK_NAME, TK_STRING +}; + +/* number of reserved words */ +#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) + + +typedef union { + lua_Number r; + lua_Integer i; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +/* state of the lexer plus state of the parser when shared by all + functions */ +typedef struct LexState { + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token 'consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* current function (parser) */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + Table *h; /* to avoid collection/reuse strings */ + struct Dyndata *dyd; /* dynamic structures used by the parser */ + TString *source; /* current source name */ + TString *envn; /* environment variable name */ +} LexState; + + +LUAI_FUNC void luaX_init (lua_State *L); +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, + TString *source, int firstchar); +LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); +LUAI_FUNC void luaX_next (LexState *ls); +LUAI_FUNC int luaX_lookahead (LexState *ls); +LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); + + +#endif diff --git a/3rd/lua-5.3.4/llimits.h b/3rd/lua-5.3.4/llimits.h new file mode 100644 index 0000000..f21377f --- /dev/null +++ b/3rd/lua-5.3.4/llimits.h @@ -0,0 +1,323 @@ +/* +** $Id: llimits.h,v 1.141 2015/11/19 19:16:22 roberto Exp $ +** Limits, basic types, and some other 'installation-dependent' definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#include +#include + + +#include "lua.h" + +/* +** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count +** the total memory used by Lua (in bytes). Usually, 'size_t' and +** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines. +*/ +#if defined(LUAI_MEM) /* { external definitions? */ +typedef LUAI_UMEM lu_mem; +typedef LUAI_MEM l_mem; +#elif LUAI_BITSINT >= 32 /* }{ */ +typedef size_t lu_mem; +typedef ptrdiff_t l_mem; +#else /* 16-bit ints */ /* }{ */ +typedef unsigned long lu_mem; +typedef long l_mem; +#endif /* } */ + + +/* chars used as small naturals (so that 'char' is reserved for characters) */ +typedef unsigned char lu_byte; + + +/* maximum value for size_t */ +#define MAX_SIZET ((size_t)(~(size_t)0)) + +/* maximum size visible for Lua (must be representable in a lua_Integer */ +#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ + : (size_t)(LUA_MAXINTEGER)) + + +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)) + +#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1)) + + +#define MAX_INT INT_MAX /* maximum value of an int */ + + +/* +** conversion of pointer to unsigned integer: +** this is for hashing only; there is no problem if the integer +** cannot hold the whole pointer value +*/ +#define point2uint(p) ((unsigned int)((size_t)(p) & UINT_MAX)) + + + +/* type to ensure maximum alignment */ +#if defined(LUAI_USER_ALIGNMENT_T) +typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; +#else +typedef union { + lua_Number n; + double u; + void *s; + lua_Integer i; + long l; +} L_Umaxalign; +#endif + + + +/* types of 'usual argument conversions' for lua_Number and lua_Integer */ +typedef LUAI_UACNUMBER l_uacNumber; +typedef LUAI_UACINT l_uacInt; + + +/* internal assertions for in-house debugging */ +#if defined(lua_assert) +#define check_exp(c,e) (lua_assert(c), (e)) +/* to avoid problems with conditions too long */ +#define lua_longassert(c) ((c) ? (void)0 : lua_assert(0)) +#else +#define lua_assert(c) ((void)0) +#define check_exp(c,e) (e) +#define lua_longassert(c) ((void)0) +#endif + +/* +** assertion for checking API calls +*/ +#if !defined(luai_apicheck) +#define luai_apicheck(l,e) lua_assert(e) +#endif + +#define api_check(l,e,msg) luai_apicheck(l,(e) && msg) + + +/* macro to avoid warnings about unused variables */ +#if !defined(UNUSED) +#define UNUSED(x) ((void)(x)) +#endif + + +/* type casts (a macro highlights casts in the code) */ +#define cast(t, exp) ((t)(exp)) + +#define cast_void(i) cast(void, (i)) +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) +#define cast_uchar(i) cast(unsigned char, (i)) + + +/* cast a signed lua_Integer to lua_Unsigned */ +#if !defined(l_castS2U) +#define l_castS2U(i) ((lua_Unsigned)(i)) +#endif + +/* +** cast a lua_Unsigned to a signed lua_Integer; this cast is +** not strict ISO C, but two-complement architectures should +** work fine. +*/ +#if !defined(l_castU2S) +#define l_castU2S(i) ((lua_Integer)(i)) +#endif + + +/* +** non-return type +*/ +#if defined(__GNUC__) +#define l_noret void __attribute__((noreturn)) +#elif defined(_MSC_VER) && _MSC_VER >= 1200 +#define l_noret void __declspec(noreturn) +#else +#define l_noret void +#endif + + + +/* +** maximum depth for nested C calls and syntactical nested non-terminals +** in a program. (Value must fit in an unsigned short int.) +*/ +#if !defined(LUAI_MAXCCALLS) +#define LUAI_MAXCCALLS 200 +#endif + + + +/* +** type for virtual-machine instructions; +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +#if LUAI_BITSINT >= 32 +typedef unsigned int Instruction; +#else +typedef unsigned long Instruction; +#endif + + + +/* +** Maximum length for short strings, that is, strings that are +** internalized. (Cannot be smaller than reserved words or tags for +** metamethods, as these strings must be internalized; +** #("function") = 8, #("__newindex") = 10.) +*/ +#if !defined(LUAI_MAXSHORTLEN) +#define LUAI_MAXSHORTLEN 40 +#endif + + +/* +** Initial size for the string table (must be power of 2). +** The Lua core alone registers ~50 strings (reserved words + +** metaevent keys + a few others). Libraries would typically add +** a few dozens more. +*/ +#if !defined(MINSTRTABSIZE) +#define MINSTRTABSIZE 128 +#endif + + +/* +** Size of cache for strings in the API. 'N' is the number of +** sets (better be a prime) and "M" is the size of each set (M == 1 +** makes a direct cache.) +*/ +#if !defined(STRCACHE_N) +#define STRCACHE_N 53 +#define STRCACHE_M 2 +#endif + + +/* minimum size for string buffer */ +#if !defined(LUA_MINBUFFER) +#define LUA_MINBUFFER 32 +#endif + + +/* +** macros that are executed whenever program enters the Lua core +** ('lua_lock') and leaves the core ('lua_unlock') +*/ +#if !defined(lua_lock) +#define lua_lock(L) ((void) 0) +#define lua_unlock(L) ((void) 0) +#endif + +/* +** macro executed during Lua functions at points where the +** function can yield. +*/ +#if !defined(luai_threadyield) +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} +#endif + + +/* +** these macros allow user-specific actions on threads when you defined +** LUAI_EXTRASPACE and need to do something extra when a thread is +** created/deleted/resumed/yielded. +*/ +#if !defined(luai_userstateopen) +#define luai_userstateopen(L) ((void)L) +#endif + +#if !defined(luai_userstateclose) +#define luai_userstateclose(L) ((void)L) +#endif + +#if !defined(luai_userstatethread) +#define luai_userstatethread(L,L1) ((void)L) +#endif + +#if !defined(luai_userstatefree) +#define luai_userstatefree(L,L1) ((void)L) +#endif + +#if !defined(luai_userstateresume) +#define luai_userstateresume(L,n) ((void)L) +#endif + +#if !defined(luai_userstateyield) +#define luai_userstateyield(L,n) ((void)L) +#endif + + + +/* +** The luai_num* macros define the primitive operations over numbers. +*/ + +/* floor division (defined as 'floor(a/b)') */ +#if !defined(luai_numidiv) +#define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b))) +#endif + +/* float division */ +#if !defined(luai_numdiv) +#define luai_numdiv(L,a,b) ((a)/(b)) +#endif + +/* +** modulo: defined as 'a - floor(a/b)*b'; this definition gives NaN when +** 'b' is huge, but the result should be 'a'. 'fmod' gives the result of +** 'a - trunc(a/b)*b', and therefore must be corrected when 'trunc(a/b) +** ~= floor(a/b)'. That happens when the division has a non-integer +** negative result, which is equivalent to the test below. +*/ +#if !defined(luai_nummod) +#define luai_nummod(L,a,b,m) \ + { (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); } +#endif + +/* exponentiation */ +#if !defined(luai_numpow) +#define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b)) +#endif + +/* the others are quite standard operations */ +#if !defined(luai_numadd) +#define luai_numadd(L,a,b) ((a)+(b)) +#define luai_numsub(L,a,b) ((a)-(b)) +#define luai_nummul(L,a,b) ((a)*(b)) +#define luai_numunm(L,a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + + + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#if !defined(HARDSTACKTESTS) +#define condmovestack(L,pre,pos) ((void)0) +#else +/* realloc stack keeping its size */ +#define condmovestack(L,pre,pos) \ + { int sz_ = (L)->stacksize; pre; luaD_reallocstack((L), sz_); pos; } +#endif + +#if !defined(HARDMEMTESTS) +#define condchangemem(L,pre,pos) ((void)0) +#else +#define condchangemem(L,pre,pos) \ + { if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } } +#endif + +#endif diff --git a/3rd/lua-5.3.4/lmathlib.c b/3rd/lua-5.3.4/lmathlib.c new file mode 100644 index 0000000..b7f8bae --- /dev/null +++ b/3rd/lua-5.3.4/lmathlib.c @@ -0,0 +1,410 @@ +/* +** $Id: lmathlib.c,v 1.119 2016/12/22 13:08:50 roberto Exp $ +** Standard mathematical library +** See Copyright Notice in lua.h +*/ + +#define lmathlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#undef PI +#define PI (l_mathop(3.141592653589793238462643383279502884)) + + +#if !defined(l_rand) /* { */ +#if defined(LUA_USE_POSIX) +#define l_rand() random() +#define l_srand(x) srandom(x) +#define L_RANDMAX 2147483647 /* (2^31 - 1), following POSIX */ +#else +#define l_rand() rand() +#define l_srand(x) srand(x) +#define L_RANDMAX RAND_MAX +#endif +#endif /* } */ + + +static int math_abs (lua_State *L) { + if (lua_isinteger(L, 1)) { + lua_Integer n = lua_tointeger(L, 1); + if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n); + lua_pushinteger(L, n); + } + else + lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sin (lua_State *L) { + lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cos (lua_State *L) { + lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tan (lua_State *L) { + lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_asin (lua_State *L) { + lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_acos (lua_State *L) { + lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan (lua_State *L) { + lua_Number y = luaL_checknumber(L, 1); + lua_Number x = luaL_optnumber(L, 2, 1); + lua_pushnumber(L, l_mathop(atan2)(y, x)); + return 1; +} + + +static int math_toint (lua_State *L) { + int valid; + lua_Integer n = lua_tointegerx(L, 1, &valid); + if (valid) + lua_pushinteger(L, n); + else { + luaL_checkany(L, 1); + lua_pushnil(L); /* value is not convertible to integer */ + } + return 1; +} + + +static void pushnumint (lua_State *L, lua_Number d) { + lua_Integer n; + if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */ + lua_pushinteger(L, n); /* result is integer */ + else + lua_pushnumber(L, d); /* result is float */ +} + + +static int math_floor (lua_State *L) { + if (lua_isinteger(L, 1)) + lua_settop(L, 1); /* integer is its own floor */ + else { + lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1)); + pushnumint(L, d); + } + return 1; +} + + +static int math_ceil (lua_State *L) { + if (lua_isinteger(L, 1)) + lua_settop(L, 1); /* integer is its own ceil */ + else { + lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1)); + pushnumint(L, d); + } + return 1; +} + + +static int math_fmod (lua_State *L) { + if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { + lua_Integer d = lua_tointeger(L, 2); + if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */ + luaL_argcheck(L, d != 0, 2, "zero"); + lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */ + } + else + lua_pushinteger(L, lua_tointeger(L, 1) % d); + } + else + lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), + luaL_checknumber(L, 2))); + return 1; +} + + +/* +** next function does not use 'modf', avoiding problems with 'double*' +** (which is not compatible with 'float*') when lua_Number is not +** 'double'. +*/ +static int math_modf (lua_State *L) { + if (lua_isinteger(L ,1)) { + lua_settop(L, 1); /* number is its own integer part */ + lua_pushnumber(L, 0); /* no fractional part */ + } + else { + lua_Number n = luaL_checknumber(L, 1); + /* integer part (rounds toward zero) */ + lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n); + pushnumint(L, ip); + /* fractional part (test needed for inf/-inf) */ + lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); + } + return 2; +} + + +static int math_sqrt (lua_State *L) { + lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); + return 1; +} + + +static int math_ult (lua_State *L) { + lua_Integer a = luaL_checkinteger(L, 1); + lua_Integer b = luaL_checkinteger(L, 2); + lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b); + return 1; +} + +static int math_log (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + lua_Number res; + if (lua_isnoneornil(L, 2)) + res = l_mathop(log)(x); + else { + lua_Number base = luaL_checknumber(L, 2); +#if !defined(LUA_USE_C89) + if (base == l_mathop(2.0)) + res = l_mathop(log2)(x); else +#endif + if (base == l_mathop(10.0)) + res = l_mathop(log10)(x); + else + res = l_mathop(log)(x)/l_mathop(log)(base); + } + lua_pushnumber(L, res); + return 1; +} + +static int math_exp (lua_State *L) { + lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_deg (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI)); + return 1; +} + +static int math_rad (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0))); + return 1; +} + + +static int math_min (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int imin = 1; /* index of current minimum value */ + int i; + luaL_argcheck(L, n >= 1, 1, "value expected"); + for (i = 2; i <= n; i++) { + if (lua_compare(L, i, imin, LUA_OPLT)) + imin = i; + } + lua_pushvalue(L, imin); + return 1; +} + + +static int math_max (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int imax = 1; /* index of current maximum value */ + int i; + luaL_argcheck(L, n >= 1, 1, "value expected"); + for (i = 2; i <= n; i++) { + if (lua_compare(L, imax, i, LUA_OPLT)) + imax = i; + } + lua_pushvalue(L, imax); + return 1; +} + +/* +** This function uses 'double' (instead of 'lua_Number') to ensure that +** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0' +** will keep full precision (ensuring that 'r' is always less than 1.0.) +*/ +static int math_random (lua_State *L) { + lua_Integer low, up; + double r = (double)l_rand() * (1.0 / ((double)L_RANDMAX + 1.0)); + switch (lua_gettop(L)) { /* check number of arguments */ + case 0: { /* no arguments */ + lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */ + return 1; + } + case 1: { /* only upper limit */ + low = 1; + up = luaL_checkinteger(L, 1); + break; + } + case 2: { /* lower and upper limits */ + low = luaL_checkinteger(L, 1); + up = luaL_checkinteger(L, 2); + break; + } + default: return luaL_error(L, "wrong number of arguments"); + } + /* random integer in the interval [low, up] */ + luaL_argcheck(L, low <= up, 1, "interval is empty"); + luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1, + "interval too large"); + r *= (double)(up - low) + 1.0; + lua_pushinteger(L, (lua_Integer)r + low); + return 1; +} + + +static int math_randomseed (lua_State *L) { + l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1)); + (void)l_rand(); /* discard first value to avoid undesirable correlations */ + return 0; +} + + +static int math_type (lua_State *L) { + if (lua_type(L, 1) == LUA_TNUMBER) { + if (lua_isinteger(L, 1)) + lua_pushliteral(L, "integer"); + else + lua_pushliteral(L, "float"); + } + else { + luaL_checkany(L, 1); + lua_pushnil(L); + } + return 1; +} + + +/* +** {================================================================== +** Deprecated functions (for compatibility only) +** =================================================================== +*/ +#if defined(LUA_COMPAT_MATHLIB) + +static int math_cosh (lua_State *L) { + lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sinh (lua_State *L) { + lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tanh (lua_State *L) { + lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_pow (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + lua_Number y = luaL_checknumber(L, 2); + lua_pushnumber(L, l_mathop(pow)(x, y)); + return 1; +} + +static int math_frexp (lua_State *L) { + int e; + lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); + lua_pushinteger(L, e); + return 2; +} + +static int math_ldexp (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + int ep = (int)luaL_checkinteger(L, 2); + lua_pushnumber(L, l_mathop(ldexp)(x, ep)); + return 1; +} + +static int math_log10 (lua_State *L) { + lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); + return 1; +} + +#endif +/* }================================================================== */ + + + +static const luaL_Reg mathlib[] = { + {"abs", math_abs}, + {"acos", math_acos}, + {"asin", math_asin}, + {"atan", math_atan}, + {"ceil", math_ceil}, + {"cos", math_cos}, + {"deg", math_deg}, + {"exp", math_exp}, + {"tointeger", math_toint}, + {"floor", math_floor}, + {"fmod", math_fmod}, + {"ult", math_ult}, + {"log", math_log}, + {"max", math_max}, + {"min", math_min}, + {"modf", math_modf}, + {"rad", math_rad}, + {"random", math_random}, + {"randomseed", math_randomseed}, + {"sin", math_sin}, + {"sqrt", math_sqrt}, + {"tan", math_tan}, + {"type", math_type}, +#if defined(LUA_COMPAT_MATHLIB) + {"atan2", math_atan}, + {"cosh", math_cosh}, + {"sinh", math_sinh}, + {"tanh", math_tanh}, + {"pow", math_pow}, + {"frexp", math_frexp}, + {"ldexp", math_ldexp}, + {"log10", math_log10}, +#endif + /* placeholders */ + {"pi", NULL}, + {"huge", NULL}, + {"maxinteger", NULL}, + {"mininteger", NULL}, + {NULL, NULL} +}; + + +/* +** Open math library +*/ +LUAMOD_API int luaopen_math (lua_State *L) { + luaL_newlib(L, mathlib); + lua_pushnumber(L, PI); + lua_setfield(L, -2, "pi"); + lua_pushnumber(L, (lua_Number)HUGE_VAL); + lua_setfield(L, -2, "huge"); + lua_pushinteger(L, LUA_MAXINTEGER); + lua_setfield(L, -2, "maxinteger"); + lua_pushinteger(L, LUA_MININTEGER); + lua_setfield(L, -2, "mininteger"); + return 1; +} + diff --git a/3rd/lua-5.3.4/lmem.c b/3rd/lua-5.3.4/lmem.c new file mode 100644 index 0000000..0a0476c --- /dev/null +++ b/3rd/lua-5.3.4/lmem.c @@ -0,0 +1,100 @@ +/* +** $Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#define lmem_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +/* +** About the realloc function: +** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); +** ('osize' is the old size, 'nsize' is the new size) +** +** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no +** matter 'x'). +** +** * frealloc(ud, p, x, 0) frees the block 'p' +** (in this specific case, frealloc must return NULL); +** particularly, frealloc(ud, NULL, 0, 0) does nothing +** (which is equivalent to free(NULL) in ISO C) +** +** frealloc returns NULL if it cannot create or reallocate the area +** (any reallocation to an equal or smaller size cannot fail!) +*/ + + + +#define MINSIZEARRAY 4 + + +void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, + int limit, const char *what) { + void *newblock; + int newsize; + if (*size >= limit/2) { /* cannot double it? */ + if (*size >= limit) /* cannot grow even a little? */ + luaG_runerror(L, "too many %s (limit is %d)", what, limit); + newsize = limit; /* still have at least one free place */ + } + else { + newsize = (*size)*2; + if (newsize < MINSIZEARRAY) + newsize = MINSIZEARRAY; /* minimum size */ + } + newblock = luaM_reallocv(L, block, *size, newsize, size_elems); + *size = newsize; /* update only when everything else is OK */ + return newblock; +} + + +l_noret luaM_toobig (lua_State *L) { + luaG_runerror(L, "memory allocation error: block too big"); +} + + + +/* +** generic allocation routine. +*/ +void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { + void *newblock; + global_State *g = G(L); + size_t realosize = (block) ? osize : 0; + lua_assert((realosize == 0) == (block == NULL)); +#if defined(HARDMEMTESTS) + if (nsize > realosize && g->gcrunning) + luaC_fullgc(L, 1); /* force a GC whenever possible */ +#endif + newblock = (*g->frealloc)(g->ud, block, osize, nsize); + if (newblock == NULL && nsize > 0) { + lua_assert(nsize > realosize); /* cannot fail when shrinking a block */ + if (g->version) { /* is state fully built? */ + luaC_fullgc(L, 1); /* try to free some memory... */ + newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ + } + if (newblock == NULL) + luaD_throw(L, LUA_ERRMEM); + } + lua_assert((nsize == 0) == (newblock == NULL)); + g->GCdebt = (g->GCdebt + nsize) - realosize; + return newblock; +} + diff --git a/3rd/lua-5.3.4/lmem.h b/3rd/lua-5.3.4/lmem.h new file mode 100644 index 0000000..30f4848 --- /dev/null +++ b/3rd/lua-5.3.4/lmem.h @@ -0,0 +1,69 @@ +/* +** $Id: lmem.h,v 1.43 2014/12/19 17:26:14 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#include + +#include "llimits.h" +#include "lua.h" + + +/* +** This macro reallocs a vector 'b' from 'on' to 'n' elements, where +** each element has size 'e'. In case of arithmetic overflow of the +** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because +** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e). +** +** (The macro is somewhat complex to avoid warnings: The 'sizeof' +** comparison avoids a runtime comparison when overflow cannot occur. +** The compiler should be able to optimize the real test by itself, but +** when it does it, it may give a warning about "comparison is always +** false due to limited range of data type"; the +1 tricks the compiler, +** avoiding this warning but also this optimization.) +*/ +#define luaM_reallocv(L,b,on,n,e) \ + (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \ + ? luaM_toobig(L) : cast_void(0)) , \ + luaM_realloc_(L, (b), (on)*(e), (n)*(e))) + +/* +** Arrays of chars do not need any test +*/ +#define luaM_reallocvchar(L,b,on,n) \ + cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) + +#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) +#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) +#define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0) + +#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) +#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) +#define luaM_newvector(L,n,t) \ + cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) + +#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) + +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + if ((nelems)+1 > (size)) \ + ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) + +#define luaM_reallocvector(L, v,oldn,n,t) \ + ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) + +LUAI_FUNC l_noret luaM_toobig (lua_State *L); + +/* not to be called directly */ +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, + size_t size_elem, int limit, + const char *what); + +#endif + diff --git a/3rd/lua-5.3.4/loadlib.c b/3rd/lua-5.3.4/loadlib.c new file mode 100644 index 0000000..4791e74 --- /dev/null +++ b/3rd/lua-5.3.4/loadlib.c @@ -0,0 +1,790 @@ +/* +** $Id: loadlib.c,v 1.130 2017/01/12 17:14:26 roberto Exp $ +** Dynamic library loader for Lua +** See Copyright Notice in lua.h +** +** This module contains an implementation of loadlib for Unix systems +** that have dlfcn, an implementation for Windows, and a stub for other +** systems. +*/ + +#define loadlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** LUA_IGMARK is a mark to ignore all before it when building the +** luaopen_ function name. +*/ +#if !defined (LUA_IGMARK) +#define LUA_IGMARK "-" +#endif + + +/* +** LUA_CSUBSEP is the character that replaces dots in submodule names +** when searching for a C loader. +** LUA_LSUBSEP is the character that replaces dots in submodule names +** when searching for a Lua loader. +*/ +#if !defined(LUA_CSUBSEP) +#define LUA_CSUBSEP LUA_DIRSEP +#endif + +#if !defined(LUA_LSUBSEP) +#define LUA_LSUBSEP LUA_DIRSEP +#endif + + +/* prefix for open functions in C libraries */ +#define LUA_POF "luaopen_" + +/* separator for open functions in C libraries */ +#define LUA_OFSEP "_" + + +/* +** unique key for table in the registry that keeps handles +** for all loaded C libraries +*/ +static const int CLIBS = 0; + +#define LIB_FAIL "open" + + +#define setprogdir(L) ((void)0) + + +/* +** system-dependent functions +*/ + +/* +** unload library 'lib' +*/ +static void lsys_unloadlib (void *lib); + +/* +** load C library in file 'path'. If 'seeglb', load with all names in +** the library global. +** Returns the library; in case of error, returns NULL plus an +** error string in the stack. +*/ +static void *lsys_load (lua_State *L, const char *path, int seeglb); + +/* +** Try to find a function named 'sym' in library 'lib'. +** Returns the function; in case of error, returns NULL plus an +** error string in the stack. +*/ +static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym); + + + + +#if defined(LUA_USE_DLOPEN) /* { */ +/* +** {======================================================================== +** This is an implementation of loadlib based on the dlfcn interface. +** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, +** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least +** as an emulation layer on top of native functions. +** ========================================================================= +*/ + +#include + +/* +** Macro to convert pointer-to-void* to pointer-to-function. This cast +** is undefined according to ISO C, but POSIX assumes that it works. +** (The '__extension__' in gnu compilers is only to avoid warnings.) +*/ +#if defined(__GNUC__) +#define cast_func(p) (__extension__ (lua_CFunction)(p)) +#else +#define cast_func(p) ((lua_CFunction)(p)) +#endif + + +static void lsys_unloadlib (void *lib) { + dlclose(lib); +} + + +static void *lsys_load (lua_State *L, const char *path, int seeglb) { + void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); + if (lib == NULL) lua_pushstring(L, dlerror()); + return lib; +} + + +static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = cast_func(dlsym(lib, sym)); + if (f == NULL) lua_pushstring(L, dlerror()); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DLL) /* }{ */ +/* +** {====================================================================== +** This is an implementation of loadlib for Windows using native functions. +** ======================================================================= +*/ + +#include + + +/* +** optional flags for LoadLibraryEx +*/ +#if !defined(LUA_LLE_FLAGS) +#define LUA_LLE_FLAGS 0 +#endif + + +#undef setprogdir + + +/* +** Replace in the path (on the top of the stack) any occurrence +** of LUA_EXEC_DIR with the executable's path. +*/ +static void setprogdir (lua_State *L) { + char buff[MAX_PATH + 1]; + char *lb; + DWORD nsize = sizeof(buff)/sizeof(char); + DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */ + if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) + luaL_error(L, "unable to get ModuleFileName"); + else { + *lb = '\0'; /* cut name on the last '\\' to get the path */ + luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); + lua_remove(L, -2); /* remove original string */ + } +} + + + + +static void pusherror (lua_State *L) { + int error = GetLastError(); + char buffer[128]; + if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) + lua_pushstring(L, buffer); + else + lua_pushfstring(L, "system error %d\n", error); +} + +static void lsys_unloadlib (void *lib) { + FreeLibrary((HMODULE)lib); +} + + +static void *lsys_load (lua_State *L, const char *path, int seeglb) { + HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); + (void)(seeglb); /* not used: symbols are 'global' by default */ + if (lib == NULL) pusherror(L); + return lib; +} + + +static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym); + if (f == NULL) pusherror(L); + return f; +} + +/* }====================================================== */ + + +#else /* }{ */ +/* +** {====================================================== +** Fallback for other systems +** ======================================================= +*/ + +#undef LIB_FAIL +#define LIB_FAIL "absent" + + +#define DLMSG "dynamic libraries not enabled; check your Lua installation" + + +static void lsys_unloadlib (void *lib) { + (void)(lib); /* not used */ +} + + +static void *lsys_load (lua_State *L, const char *path, int seeglb) { + (void)(path); (void)(seeglb); /* not used */ + lua_pushliteral(L, DLMSG); + return NULL; +} + + +static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { + (void)(lib); (void)(sym); /* not used */ + lua_pushliteral(L, DLMSG); + return NULL; +} + +/* }====================================================== */ +#endif /* } */ + + +/* +** {================================================================== +** Set Paths +** =================================================================== +*/ + +/* +** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment +** variables that Lua check to set its paths. +*/ +#if !defined(LUA_PATH_VAR) +#define LUA_PATH_VAR "LUA_PATH" +#endif + +#if !defined(LUA_CPATH_VAR) +#define LUA_CPATH_VAR "LUA_CPATH" +#endif + + +#define AUXMARK "\1" /* auxiliary mark */ + + +/* +** return registry.LUA_NOENV as a boolean +*/ +static int noenv (lua_State *L) { + int b; + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); + b = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + return b; +} + + +/* +** Set a path +*/ +static void setpath (lua_State *L, const char *fieldname, + const char *envname, + const char *dft) { + const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX); + const char *path = getenv(nver); /* use versioned name */ + if (path == NULL) /* no environment variable? */ + path = getenv(envname); /* try unversioned name */ + if (path == NULL || noenv(L)) /* no environment variable? */ + lua_pushstring(L, dft); /* use default */ + else { + /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ + path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, + LUA_PATH_SEP AUXMARK LUA_PATH_SEP); + luaL_gsub(L, path, AUXMARK, dft); + lua_remove(L, -2); /* remove result from 1st 'gsub' */ + } + setprogdir(L); + lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */ + lua_pop(L, 1); /* pop versioned variable name */ +} + +/* }================================================================== */ + + +/* +** return registry.CLIBS[path] +*/ +static void *checkclib (lua_State *L, const char *path) { + void *plib; + lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS); + lua_getfield(L, -1, path); + plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ + lua_pop(L, 2); /* pop CLIBS table and 'plib' */ + return plib; +} + + +/* +** registry.CLIBS[path] = plib -- for queries +** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries +*/ +static void addtoclib (lua_State *L, const char *path, void *plib) { + lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS); + lua_pushlightuserdata(L, plib); + lua_pushvalue(L, -1); + lua_setfield(L, -3, path); /* CLIBS[path] = plib */ + lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ + lua_pop(L, 1); /* pop CLIBS table */ +} + + +/* +** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib +** handles in list CLIBS +*/ +static int gctm (lua_State *L) { + lua_Integer n = luaL_len(L, 1); + for (; n >= 1; n--) { /* for each handle, in reverse order */ + lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ + lsys_unloadlib(lua_touserdata(L, -1)); + lua_pop(L, 1); /* pop handle */ + } + return 0; +} + + + +/* error codes for 'lookforfunc' */ +#define ERRLIB 1 +#define ERRFUNC 2 + +/* +** Look for a C function named 'sym' in a dynamically loaded library +** 'path'. +** First, check whether the library is already loaded; if not, try +** to load it. +** Then, if 'sym' is '*', return true (as library has been loaded). +** Otherwise, look for symbol 'sym' in the library and push a +** C function with that symbol. +** Return 0 and 'true' or a function in the stack; in case of +** errors, return an error code and an error message in the stack. +*/ +static int lookforfunc (lua_State *L, const char *path, const char *sym) { + void *reg = checkclib(L, path); /* check loaded C libraries */ + if (reg == NULL) { /* must load library? */ + reg = lsys_load(L, path, *sym == '*'); /* global symbols if 'sym'=='*' */ + if (reg == NULL) return ERRLIB; /* unable to load library */ + addtoclib(L, path, reg); + } + if (*sym == '*') { /* loading only library (no function)? */ + lua_pushboolean(L, 1); /* return 'true' */ + return 0; /* no errors */ + } + else { + lua_CFunction f = lsys_sym(L, reg, sym); + if (f == NULL) + return ERRFUNC; /* unable to find function */ + lua_pushcfunction(L, f); /* else create new function */ + return 0; /* no errors */ + } +} + + +static int ll_loadlib (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + const char *init = luaL_checkstring(L, 2); + int stat = lookforfunc(L, path, init); + if (stat == 0) /* no errors? */ + return 1; /* return the loaded function */ + else { /* error; error message is on stack top */ + lua_pushnil(L); + lua_insert(L, -2); + lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); + return 3; /* return nil, error message, and where */ + } +} + + + +/* +** {====================================================== +** 'require' function +** ======================================================= +*/ + + +static int readable (const char *filename) { + FILE *f = fopen(filename, "r"); /* try to open file */ + if (f == NULL) return 0; /* open failed */ + fclose(f); + return 1; +} + + +static const char *pushnexttemplate (lua_State *L, const char *path) { + const char *l; + while (*path == *LUA_PATH_SEP) path++; /* skip separators */ + if (*path == '\0') return NULL; /* no more templates */ + l = strchr(path, *LUA_PATH_SEP); /* find next separator */ + if (l == NULL) l = path + strlen(path); + lua_pushlstring(L, path, l - path); /* template */ + return l; +} + + +static const char *searchpath (lua_State *L, const char *name, + const char *path, + const char *sep, + const char *dirsep) { + luaL_Buffer msg; /* to build error message */ + luaL_buffinit(L, &msg); + if (*sep != '\0') /* non-empty separator? */ + name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ + while ((path = pushnexttemplate(L, path)) != NULL) { + const char *filename = luaL_gsub(L, lua_tostring(L, -1), + LUA_PATH_MARK, name); + lua_remove(L, -2); /* remove path template */ + if (readable(filename)) /* does file exist and is readable? */ + return filename; /* return that file name */ + lua_pushfstring(L, "\n\tno file '%s'", filename); + lua_remove(L, -2); /* remove file name */ + luaL_addvalue(&msg); /* concatenate error msg. entry */ + } + luaL_pushresult(&msg); /* create error message */ + return NULL; /* not found */ +} + + +static int ll_searchpath (lua_State *L) { + const char *f = searchpath(L, luaL_checkstring(L, 1), + luaL_checkstring(L, 2), + luaL_optstring(L, 3, "."), + luaL_optstring(L, 4, LUA_DIRSEP)); + if (f != NULL) return 1; + else { /* error message is on top of the stack */ + lua_pushnil(L); + lua_insert(L, -2); + return 2; /* return nil + error message */ + } +} + + +static const char *findfile (lua_State *L, const char *name, + const char *pname, + const char *dirsep) { + const char *path; + lua_getfield(L, lua_upvalueindex(1), pname); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, "'package.%s' must be a string", pname); + return searchpath(L, name, path, ".", dirsep); +} + + +static int checkload (lua_State *L, int stat, const char *filename) { + if (stat) { /* module loaded successfully? */ + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; /* return open function and file name */ + } + else + return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); +} + + +static int searcher_Lua (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + filename = findfile(L, name, "path", LUA_LSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); +} + + +/* +** Try to find a load function for module 'modname' at file 'filename'. +** First, change '.' to '_' in 'modname'; then, if 'modname' has +** the form X-Y (that is, it has an "ignore mark"), build a function +** name "luaopen_X" and look for it. (For compatibility, if that +** fails, it also tries "luaopen_Y".) If there is no ignore mark, +** look for a function named "luaopen_modname". +*/ +static int loadfunc (lua_State *L, const char *filename, const char *modname) { + const char *openfunc; + const char *mark; + modname = luaL_gsub(L, modname, ".", LUA_OFSEP); + mark = strchr(modname, *LUA_IGMARK); + if (mark) { + int stat; + openfunc = lua_pushlstring(L, modname, mark - modname); + openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc); + stat = lookforfunc(L, filename, openfunc); + if (stat != ERRFUNC) return stat; + modname = mark + 1; /* else go ahead and try old-style name */ + } + openfunc = lua_pushfstring(L, LUA_POF"%s", modname); + return lookforfunc(L, filename, openfunc); +} + + +static int searcher_C (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (loadfunc(L, filename, name) == 0), filename); +} + + +static int searcher_Croot (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + const char *p = strchr(name, '.'); + int stat; + if (p == NULL) return 0; /* is root */ + lua_pushlstring(L, name, p - name); + filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* root not found */ + if ((stat = loadfunc(L, filename, name)) != 0) { + if (stat != ERRFUNC) + return checkload(L, 0, filename); /* real error */ + else { /* open function not found */ + lua_pushfstring(L, "\n\tno module '%s' in file '%s'", name, filename); + return 1; + } + } + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; +} + + +static int searcher_preload (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); + if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */ + lua_pushfstring(L, "\n\tno field package.preload['%s']", name); + return 1; +} + + +static void findloader (lua_State *L, const char *name) { + int i; + luaL_Buffer msg; /* to build error message */ + luaL_buffinit(L, &msg); + /* push 'package.searchers' to index 3 in the stack */ + if (lua_getfield(L, lua_upvalueindex(1), "searchers") != LUA_TTABLE) + luaL_error(L, "'package.searchers' must be a table"); + /* iterate over available searchers to find a loader */ + for (i = 1; ; i++) { + if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */ + lua_pop(L, 1); /* remove nil */ + luaL_pushresult(&msg); /* create error message */ + luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1)); + } + lua_pushstring(L, name); + lua_call(L, 1, 2); /* call it */ + if (lua_isfunction(L, -2)) /* did it find a loader? */ + return; /* module loader found */ + else if (lua_isstring(L, -2)) { /* searcher returned error message? */ + lua_pop(L, 1); /* remove extra return */ + luaL_addvalue(&msg); /* concatenate error message */ + } + else + lua_pop(L, 2); /* remove both returns */ + } +} + + +static int ll_require (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_settop(L, 1); /* LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_getfield(L, 2, name); /* LOADED[name] */ + if (lua_toboolean(L, -1)) /* is it there? */ + return 1; /* package is already loaded */ + /* else must load package */ + lua_pop(L, 1); /* remove 'getfield' result */ + findloader(L, name); + lua_pushstring(L, name); /* pass name as argument to module loader */ + lua_insert(L, -2); /* name is 1st argument (before search data) */ + lua_call(L, 2, 1); /* run loader to load module */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* LOADED[name] = returned value */ + if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_pushvalue(L, -1); /* extra copy to be returned */ + lua_setfield(L, 2, name); /* LOADED[name] = true */ + } + return 1; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** 'module' function +** ======================================================= +*/ +#if defined(LUA_COMPAT_MODULE) + +/* +** changes the environment variable of calling function +*/ +static void set_env (lua_State *L) { + lua_Debug ar; + if (lua_getstack(L, 1, &ar) == 0 || + lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ + lua_iscfunction(L, -1)) + luaL_error(L, "'module' not called from a Lua function"); + lua_pushvalue(L, -2); /* copy new environment table to top */ + lua_setupvalue(L, -2, 1); + lua_pop(L, 1); /* remove function */ +} + + +static void dooptions (lua_State *L, int n) { + int i; + for (i = 2; i <= n; i++) { + if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */ + lua_pushvalue(L, i); /* get option (a function) */ + lua_pushvalue(L, -2); /* module */ + lua_call(L, 1, 0); + } + } +} + + +static void modinit (lua_State *L, const char *modname) { + const char *dot; + lua_pushvalue(L, -1); + lua_setfield(L, -2, "_M"); /* module._M = module */ + lua_pushstring(L, modname); + lua_setfield(L, -2, "_NAME"); + dot = strrchr(modname, '.'); /* look for last dot in module name */ + if (dot == NULL) dot = modname; + else dot++; + /* set _PACKAGE as package name (full module name minus last part) */ + lua_pushlstring(L, modname, dot - modname); + lua_setfield(L, -2, "_PACKAGE"); +} + + +static int ll_module (lua_State *L) { + const char *modname = luaL_checkstring(L, 1); + int lastarg = lua_gettop(L); /* last parameter */ + luaL_pushmodule(L, modname, 1); /* get/create module table */ + /* check whether table already has a _NAME field */ + if (lua_getfield(L, -1, "_NAME") != LUA_TNIL) + lua_pop(L, 1); /* table is an initialized module */ + else { /* no; initialize it */ + lua_pop(L, 1); + modinit(L, modname); + } + lua_pushvalue(L, -1); + set_env(L); + dooptions(L, lastarg); + return 1; +} + + +static int ll_seeall (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + if (!lua_getmetatable(L, 1)) { + lua_createtable(L, 0, 1); /* create new metatable */ + lua_pushvalue(L, -1); + lua_setmetatable(L, 1); + } + lua_pushglobaltable(L); + lua_setfield(L, -2, "__index"); /* mt.__index = _G */ + return 0; +} + +#endif +/* }====================================================== */ + + + +static const luaL_Reg pk_funcs[] = { + {"loadlib", ll_loadlib}, + {"searchpath", ll_searchpath}, +#if defined(LUA_COMPAT_MODULE) + {"seeall", ll_seeall}, +#endif + /* placeholders */ + {"preload", NULL}, + {"cpath", NULL}, + {"path", NULL}, + {"searchers", NULL}, + {"loaded", NULL}, + {NULL, NULL} +}; + + +static const luaL_Reg ll_funcs[] = { +#if defined(LUA_COMPAT_MODULE) + {"module", ll_module}, +#endif + {"require", ll_require}, + {NULL, NULL} +}; + + +static void createsearcherstable (lua_State *L) { + static const lua_CFunction searchers[] = + {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL}; + int i; + /* create 'searchers' table */ + lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); + /* fill it with predefined searchers */ + for (i=0; searchers[i] != NULL; i++) { + lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ + lua_pushcclosure(L, searchers[i], 1); + lua_rawseti(L, -2, i+1); + } +#if defined(LUA_COMPAT_LOADERS) + lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ + lua_setfield(L, -3, "loaders"); /* put it in field 'loaders' */ +#endif + lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ +} + + +/* +** create table CLIBS to keep track of loaded C libraries, +** setting a finalizer to close all libraries when closing state. +*/ +static void createclibstable (lua_State *L) { + lua_newtable(L); /* create CLIBS table */ + lua_createtable(L, 0, 1); /* create metatable for CLIBS */ + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ + lua_setmetatable(L, -2); + lua_rawsetp(L, LUA_REGISTRYINDEX, &CLIBS); /* set CLIBS table in registry */ +} + + +LUAMOD_API int luaopen_package (lua_State *L) { + createclibstable(L); + luaL_newlib(L, pk_funcs); /* create 'package' table */ + createsearcherstable(L); + /* set paths */ + setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT); + setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT); + /* store config information */ + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" + LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); + lua_setfield(L, -2, "config"); + /* set field 'loaded' */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_setfield(L, -2, "loaded"); + /* set field 'preload' */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); + lua_setfield(L, -2, "preload"); + lua_pushglobaltable(L); + lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ + luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ + lua_pop(L, 1); /* pop global table */ + return 1; /* return 'package' table */ +} + diff --git a/3rd/lua-5.3.4/lobject.c b/3rd/lua-5.3.4/lobject.c new file mode 100644 index 0000000..2da7689 --- /dev/null +++ b/3rd/lua-5.3.4/lobject.c @@ -0,0 +1,521 @@ +/* +** $Id: lobject.c,v 2.113 2016/12/22 13:08:50 roberto Exp $ +** Some generic functions over Lua objects +** See Copyright Notice in lua.h +*/ + +#define lobject_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lctype.h" +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "lvm.h" + + + +LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT}; + + +/* +** converts an integer to a "floating point byte", represented as +** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if +** eeeee != 0 and (xxx) otherwise. +*/ +int luaO_int2fb (unsigned int x) { + int e = 0; /* exponent */ + if (x < 8) return x; + while (x >= (8 << 4)) { /* coarse steps */ + x = (x + 0xf) >> 4; /* x = ceil(x / 16) */ + e += 4; + } + while (x >= (8 << 1)) { /* fine steps */ + x = (x + 1) >> 1; /* x = ceil(x / 2) */ + e++; + } + return ((e+1) << 3) | (cast_int(x) - 8); +} + + +/* converts back */ +int luaO_fb2int (int x) { + return (x < 8) ? x : ((x & 7) + 8) << ((x >> 3) - 1); +} + + +/* +** Computes ceil(log2(x)) +*/ +int luaO_ceillog2 (unsigned int x) { + static const lu_byte log_2[256] = { /* log_2[i] = ceil(log2(i - 1)) */ + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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 + }; + int l = 0; + x--; + while (x >= 256) { l += 8; x >>= 8; } + return l + log_2[x]; +} + + +static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, + lua_Integer v2) { + switch (op) { + case LUA_OPADD: return intop(+, v1, v2); + case LUA_OPSUB:return intop(-, v1, v2); + case LUA_OPMUL:return intop(*, v1, v2); + case LUA_OPMOD: return luaV_mod(L, v1, v2); + case LUA_OPIDIV: return luaV_div(L, v1, v2); + case LUA_OPBAND: return intop(&, v1, v2); + case LUA_OPBOR: return intop(|, v1, v2); + case LUA_OPBXOR: return intop(^, v1, v2); + case LUA_OPSHL: return luaV_shiftl(v1, v2); + case LUA_OPSHR: return luaV_shiftl(v1, -v2); + case LUA_OPUNM: return intop(-, 0, v1); + case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1); + default: lua_assert(0); return 0; + } +} + + +static lua_Number numarith (lua_State *L, int op, lua_Number v1, + lua_Number v2) { + switch (op) { + case LUA_OPADD: return luai_numadd(L, v1, v2); + case LUA_OPSUB: return luai_numsub(L, v1, v2); + case LUA_OPMUL: return luai_nummul(L, v1, v2); + case LUA_OPDIV: return luai_numdiv(L, v1, v2); + case LUA_OPPOW: return luai_numpow(L, v1, v2); + case LUA_OPIDIV: return luai_numidiv(L, v1, v2); + case LUA_OPUNM: return luai_numunm(L, v1); + case LUA_OPMOD: { + lua_Number m; + luai_nummod(L, v1, v2, m); + return m; + } + default: lua_assert(0); return 0; + } +} + + +void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, + TValue *res) { + switch (op) { + case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: + case LUA_OPSHL: case LUA_OPSHR: + case LUA_OPBNOT: { /* operate only on integers */ + lua_Integer i1; lua_Integer i2; + if (tointeger(p1, &i1) && tointeger(p2, &i2)) { + setivalue(res, intarith(L, op, i1, i2)); + return; + } + else break; /* go to the end */ + } + case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */ + lua_Number n1; lua_Number n2; + if (tonumber(p1, &n1) && tonumber(p2, &n2)) { + setfltvalue(res, numarith(L, op, n1, n2)); + return; + } + else break; /* go to the end */ + } + default: { /* other operations */ + lua_Number n1; lua_Number n2; + if (ttisinteger(p1) && ttisinteger(p2)) { + setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); + return; + } + else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { + setfltvalue(res, numarith(L, op, n1, n2)); + return; + } + else break; /* go to the end */ + } + } + /* could not perform raw operation; try metamethod */ + lua_assert(L != NULL); /* should not fail when folding (compile time) */ + luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD)); +} + + +int luaO_hexavalue (int c) { + if (lisdigit(c)) return c - '0'; + else return (ltolower(c) - 'a') + 10; +} + + +static int isneg (const char **s) { + if (**s == '-') { (*s)++; return 1; } + else if (**s == '+') (*s)++; + return 0; +} + + + +/* +** {================================================================== +** Lua's implementation for 'lua_strx2number' +** =================================================================== +*/ + +#if !defined(lua_strx2number) + +/* maximum number of significant digits to read (to avoid overflows + even with single floats) */ +#define MAXSIGDIG 30 + +/* +** convert an hexadecimal numeric string to a number, following +** C99 specification for 'strtod' +*/ +static lua_Number lua_strx2number (const char *s, char **endptr) { + int dot = lua_getlocaledecpoint(); + lua_Number r = 0.0; /* result (accumulator) */ + int sigdig = 0; /* number of significant digits */ + int nosigdig = 0; /* number of non-significant digits */ + int e = 0; /* exponent correction */ + int neg; /* 1 if number is negative */ + int hasdot = 0; /* true after seen a dot */ + *endptr = cast(char *, s); /* nothing is valid yet */ + while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ + neg = isneg(&s); /* check signal */ + if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ + return 0.0; /* invalid format (no '0x') */ + for (s += 2; ; s++) { /* skip '0x' and read numeral */ + if (*s == dot) { + if (hasdot) break; /* second dot? stop loop */ + else hasdot = 1; + } + else if (lisxdigit(cast_uchar(*s))) { + if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */ + nosigdig++; + else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */ + r = (r * cast_num(16.0)) + luaO_hexavalue(*s); + else e++; /* too many digits; ignore, but still count for exponent */ + if (hasdot) e--; /* decimal digit? correct exponent */ + } + else break; /* neither a dot nor a digit */ + } + if (nosigdig + sigdig == 0) /* no digits? */ + return 0.0; /* invalid format */ + *endptr = cast(char *, s); /* valid up to here */ + e *= 4; /* each digit multiplies/divides value by 2^4 */ + if (*s == 'p' || *s == 'P') { /* exponent part? */ + int exp1 = 0; /* exponent value */ + int neg1; /* exponent signal */ + s++; /* skip 'p' */ + neg1 = isneg(&s); /* signal */ + if (!lisdigit(cast_uchar(*s))) + return 0.0; /* invalid; must have at least one digit */ + while (lisdigit(cast_uchar(*s))) /* read exponent */ + exp1 = exp1 * 10 + *(s++) - '0'; + if (neg1) exp1 = -exp1; + e += exp1; + *endptr = cast(char *, s); /* valid up to here */ + } + if (neg) r = -r; + return l_mathop(ldexp)(r, e); +} + +#endif +/* }====================================================== */ + + +/* maximum length of a numeral */ +#if !defined (L_MAXLENNUM) +#define L_MAXLENNUM 200 +#endif + +static const char *l_str2dloc (const char *s, lua_Number *result, int mode) { + char *endptr; + *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */ + : lua_str2number(s, &endptr); + if (endptr == s) return NULL; /* nothing recognized? */ + while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */ + return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */ +} + + +/* +** Convert string 's' to a Lua number (put in 'result'). Return NULL +** on fail or the address of the ending '\0' on success. +** 'pmode' points to (and 'mode' contains) special things in the string: +** - 'x'/'X' means an hexadecimal numeral +** - 'n'/'N' means 'inf' or 'nan' (which should be rejected) +** - '.' just optimizes the search for the common case (nothing special) +** This function accepts both the current locale or a dot as the radix +** mark. If the convertion fails, it may mean number has a dot but +** locale accepts something else. In that case, the code copies 's' +** to a buffer (because 's' is read-only), changes the dot to the +** current locale radix mark, and tries to convert again. +*/ +static const char *l_str2d (const char *s, lua_Number *result) { + const char *endptr; + const char *pmode = strpbrk(s, ".xXnN"); + int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0; + if (mode == 'n') /* reject 'inf' and 'nan' */ + return NULL; + endptr = l_str2dloc(s, result, mode); /* try to convert */ + if (endptr == NULL) { /* failed? may be a different locale */ + char buff[L_MAXLENNUM + 1]; + const char *pdot = strchr(s, '.'); + if (strlen(s) > L_MAXLENNUM || pdot == NULL) + return NULL; /* string too long or no dot; fail */ + strcpy(buff, s); /* copy string to buffer */ + buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */ + endptr = l_str2dloc(buff, result, mode); /* try again */ + if (endptr != NULL) + endptr = s + (endptr - buff); /* make relative to 's' */ + } + return endptr; +} + + +#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10) +#define MAXLASTD cast_int(LUA_MAXINTEGER % 10) + +static const char *l_str2int (const char *s, lua_Integer *result) { + lua_Unsigned a = 0; + int empty = 1; + int neg; + while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ + neg = isneg(&s); + if (s[0] == '0' && + (s[1] == 'x' || s[1] == 'X')) { /* hex? */ + s += 2; /* skip '0x' */ + for (; lisxdigit(cast_uchar(*s)); s++) { + a = a * 16 + luaO_hexavalue(*s); + empty = 0; + } + } + else { /* decimal */ + for (; lisdigit(cast_uchar(*s)); s++) { + int d = *s - '0'; + if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */ + return NULL; /* do not accept it (as integer) */ + a = a * 10 + d; + empty = 0; + } + } + while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */ + if (empty || *s != '\0') return NULL; /* something wrong in the numeral */ + else { + *result = l_castU2S((neg) ? 0u - a : a); + return s; + } +} + + +size_t luaO_str2num (const char *s, TValue *o) { + lua_Integer i; lua_Number n; + const char *e; + if ((e = l_str2int(s, &i)) != NULL) { /* try as an integer */ + setivalue(o, i); + } + else if ((e = l_str2d(s, &n)) != NULL) { /* else try as a float */ + setfltvalue(o, n); + } + else + return 0; /* conversion failed */ + return (e - s) + 1; /* success; return string size */ +} + + +int luaO_utf8esc (char *buff, unsigned long x) { + int n = 1; /* number of bytes put in buffer (backwards) */ + lua_assert(x <= 0x10FFFF); + if (x < 0x80) /* ascii? */ + buff[UTF8BUFFSZ - 1] = cast(char, x); + else { /* need continuation bytes */ + unsigned int mfb = 0x3f; /* maximum that fits in first byte */ + do { /* add continuation bytes */ + buff[UTF8BUFFSZ - (n++)] = cast(char, 0x80 | (x & 0x3f)); + x >>= 6; /* remove added bits */ + mfb >>= 1; /* now there is one less bit available in first byte */ + } while (x > mfb); /* still needs continuation byte? */ + buff[UTF8BUFFSZ - n] = cast(char, (~mfb << 1) | x); /* add first byte */ + } + return n; +} + + +/* maximum length of the conversion of a number to a string */ +#define MAXNUMBER2STR 50 + + +/* +** Convert a number object to a string +*/ +void luaO_tostring (lua_State *L, StkId obj) { + char buff[MAXNUMBER2STR]; + size_t len; + lua_assert(ttisnumber(obj)); + if (ttisinteger(obj)) + len = lua_integer2str(buff, sizeof(buff), ivalue(obj)); + else { + len = lua_number2str(buff, sizeof(buff), fltvalue(obj)); +#if !defined(LUA_COMPAT_FLOATSTRING) + if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */ + buff[len++] = lua_getlocaledecpoint(); + buff[len++] = '0'; /* adds '.0' to result */ + } +#endif + } + setsvalue2s(L, obj, luaS_newlstr(L, buff, len)); +} + + +static void pushstr (lua_State *L, const char *str, size_t l) { + setsvalue2s(L, L->top, luaS_newlstr(L, str, l)); + luaD_inctop(L); +} + + +/* +** this function handles only '%d', '%c', '%f', '%p', and '%s' + conventional formats, plus Lua-specific '%I' and '%U' +*/ +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { + int n = 0; + for (;;) { + const char *e = strchr(fmt, '%'); + if (e == NULL) break; + pushstr(L, fmt, e - fmt); + switch (*(e+1)) { + case 's': { /* zero-terminated string */ + const char *s = va_arg(argp, char *); + if (s == NULL) s = "(null)"; + pushstr(L, s, strlen(s)); + break; + } + case 'c': { /* an 'int' as a character */ + char buff = cast(char, va_arg(argp, int)); + if (lisprint(cast_uchar(buff))) + pushstr(L, &buff, 1); + else /* non-printable character; print its code */ + luaO_pushfstring(L, "<\\%d>", cast_uchar(buff)); + break; + } + case 'd': { /* an 'int' */ + setivalue(L->top, va_arg(argp, int)); + goto top2str; + } + case 'I': { /* a 'lua_Integer' */ + setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt))); + goto top2str; + } + case 'f': { /* a 'lua_Number' */ + setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); + top2str: /* convert the top element to a string */ + luaD_inctop(L); + luaO_tostring(L, L->top - 1); + break; + } + case 'p': { /* a pointer */ + char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */ + int l = l_sprintf(buff, sizeof(buff), "%p", va_arg(argp, void *)); + pushstr(L, buff, l); + break; + } + case 'U': { /* an 'int' as a UTF-8 sequence */ + char buff[UTF8BUFFSZ]; + int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long))); + pushstr(L, buff + UTF8BUFFSZ - l, l); + break; + } + case '%': { + pushstr(L, "%", 1); + break; + } + default: { + luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'", + *(e + 1)); + } + } + n += 2; + fmt = e+2; + } + luaD_checkstack(L, 1); + pushstr(L, fmt, strlen(fmt)); + if (n > 0) luaV_concat(L, n + 1); + return svalue(L->top - 1); +} + + +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; +} + + +/* number of chars of a literal string without the ending \0 */ +#define LL(x) (sizeof(x)/sizeof(char) - 1) + +#define RETS "..." +#define PRE "[string \"" +#define POS "\"]" + +#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) + +void luaO_chunkid (char *out, const char *source, size_t bufflen) { + size_t l = strlen(source); + if (*source == '=') { /* 'literal' source */ + if (l <= bufflen) /* small enough? */ + memcpy(out, source + 1, l * sizeof(char)); + else { /* truncate it */ + addstr(out, source + 1, bufflen - 1); + *out = '\0'; + } + } + else if (*source == '@') { /* file name */ + if (l <= bufflen) /* small enough? */ + memcpy(out, source + 1, l * sizeof(char)); + else { /* add '...' before rest of name */ + addstr(out, RETS, LL(RETS)); + bufflen -= LL(RETS); + memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char)); + } + } + else { /* string; format as [string "source"] */ + const char *nl = strchr(source, '\n'); /* find first new line (if any) */ + addstr(out, PRE, LL(PRE)); /* add prefix */ + bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ + if (l < bufflen && nl == NULL) { /* small one-line source? */ + addstr(out, source, l); /* keep it */ + } + else { + if (nl != NULL) l = nl - source; /* stop at first newline */ + if (l > bufflen) l = bufflen; + addstr(out, source, l); + addstr(out, RETS, LL(RETS)); + } + memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); + } +} + diff --git a/3rd/lua-5.3.4/lobject.h b/3rd/lua-5.3.4/lobject.h new file mode 100644 index 0000000..3c04228 --- /dev/null +++ b/3rd/lua-5.3.4/lobject.h @@ -0,0 +1,549 @@ +/* +** $Id: lobject.h,v 2.117 2016/08/01 19:51:24 roberto Exp $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + + +#ifndef lobject_h +#define lobject_h + + +#include + + +#include "llimits.h" +#include "lua.h" + + +/* +** Extra tags for non-values +*/ +#define LUA_TPROTO LUA_NUMTAGS /* function prototypes */ +#define LUA_TDEADKEY (LUA_NUMTAGS+1) /* removed keys in tables */ + +/* +** number of all possible tags (including LUA_TNONE but excluding DEADKEY) +*/ +#define LUA_TOTALTAGS (LUA_TPROTO + 2) + + +/* +** tags for Tagged Values have the following use of bits: +** bits 0-3: actual tag (a LUA_T* value) +** bits 4-5: variant bits +** bit 6: whether value is collectable +*/ + + +/* +** LUA_TFUNCTION variants: +** 0 - Lua function +** 1 - light C function +** 2 - regular C function (closure) +*/ + +/* Variant tags for functions */ +#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */ +#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */ +#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */ + + +/* Variant tags for strings */ +#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */ +#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */ + + +/* Variant tags for numbers */ +#define LUA_TNUMFLT (LUA_TNUMBER | (0 << 4)) /* float numbers */ +#define LUA_TNUMINT (LUA_TNUMBER | (1 << 4)) /* integer numbers */ + + +/* Bit mark for collectable types */ +#define BIT_ISCOLLECTABLE (1 << 6) + +/* mark a tag as collectable */ +#define ctb(t) ((t) | BIT_ISCOLLECTABLE) + + +/* +** Common type for all collectable objects +*/ +typedef struct GCObject GCObject; + + +/* +** Common Header for all collectable objects (in macro form, to be +** included in other objects) +*/ +#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked + + +/* +** Common type has only the common header +*/ +struct GCObject { + CommonHeader; +}; + + + + +/* +** Tagged Values. This is the basic representation of values in Lua, +** an actual value plus a tag with its type. +*/ + +/* +** Union of all Lua values +*/ +typedef union Value { + GCObject *gc; /* collectable objects */ + void *p; /* light userdata */ + int b; /* booleans */ + lua_CFunction f; /* light C functions */ + lua_Integer i; /* integer numbers */ + lua_Number n; /* float numbers */ +} Value; + + +#define TValuefields Value value_; int tt_ + + +typedef struct lua_TValue { + TValuefields; +} TValue; + + + +/* macro defining a nil value */ +#define NILCONSTANT {NULL}, LUA_TNIL + + +#define val_(o) ((o)->value_) + + +/* raw type tag of a TValue */ +#define rttype(o) ((o)->tt_) + +/* tag with no variants (bits 0-3) */ +#define novariant(x) ((x) & 0x0F) + +/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ +#define ttype(o) (rttype(o) & 0x3F) + +/* type tag of a TValue with no variants (bits 0-3) */ +#define ttnov(o) (novariant(rttype(o))) + + +/* Macros to test type */ +#define checktag(o,t) (rttype(o) == (t)) +#define checktype(o,t) (ttnov(o) == (t)) +#define ttisnumber(o) checktype((o), LUA_TNUMBER) +#define ttisfloat(o) checktag((o), LUA_TNUMFLT) +#define ttisinteger(o) checktag((o), LUA_TNUMINT) +#define ttisnil(o) checktag((o), LUA_TNIL) +#define ttisboolean(o) checktag((o), LUA_TBOOLEAN) +#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) +#define ttisstring(o) checktype((o), LUA_TSTRING) +#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR)) +#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR)) +#define ttistable(o) checktag((o), ctb(LUA_TTABLE)) +#define ttisfunction(o) checktype(o, LUA_TFUNCTION) +#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION) +#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) +#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) +#define ttislcf(o) checktag((o), LUA_TLCF) +#define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA)) +#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) +#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY) + + +/* Macros to access values */ +#define ivalue(o) check_exp(ttisinteger(o), val_(o).i) +#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n) +#define nvalue(o) check_exp(ttisnumber(o), \ + (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o))) +#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) +#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) +#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc)) +#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc)) +#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc)) +#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc)) +#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc)) +#define fvalue(o) check_exp(ttislcf(o), val_(o).f) +#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc)) +#define bvalue(o) check_exp(ttisboolean(o), val_(o).b) +#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc)) +/* a dead value may get the 'gc' field, but cannot access its contents */ +#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc)) + +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) + + +#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE) + + +/* Macros for internal tests */ +#define righttt(obj) (ttype(obj) == gcvalue(obj)->tt) + +#define checkliveness(L,obj) \ + lua_longassert(!iscollectable(obj) || \ + (righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj))))) + + +/* Macros to set values */ +#define settt_(o,t) ((o)->tt_=(t)) + +#define setfltvalue(obj,x) \ + { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); } + +#define chgfltvalue(obj,x) \ + { TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); } + +#define setivalue(obj,x) \ + { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); } + +#define chgivalue(obj,x) \ + { TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); } + +#define setnilvalue(obj) settt_(obj, LUA_TNIL) + +#define setfvalue(obj,x) \ + { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); } + +#define setpvalue(obj,x) \ + { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); } + +#define setbvalue(obj,x) \ + { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); } + +#define setgcovalue(L,obj,x) \ + { TValue *io = (obj); GCObject *i_g=(x); \ + val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); } + +#define setsvalue(L,obj,x) \ + { TValue *io = (obj); TString *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \ + checkliveness(L,io); } + +#define setuvalue(L,obj,x) \ + { TValue *io = (obj); Udata *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TUSERDATA)); \ + checkliveness(L,io); } + +#define setthvalue(L,obj,x) \ + { TValue *io = (obj); lua_State *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTHREAD)); \ + checkliveness(L,io); } + +#define setclLvalue(L,obj,x) \ + { TValue *io = (obj); LClosure *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TLCL)); \ + checkliveness(L,io); } + +#define setclCvalue(L,obj,x) \ + { TValue *io = (obj); CClosure *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TCCL)); \ + checkliveness(L,io); } + +#define sethvalue(L,obj,x) \ + { TValue *io = (obj); Table *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \ + checkliveness(L,io); } + +#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY) + + + +#define setobj(L,obj1,obj2) \ + { TValue *io1=(obj1); *io1 = *(obj2); \ + (void)L; checkliveness(L,io1); } + + +/* +** different types of assignments, according to destination +*/ + +/* from stack to (same) stack */ +#define setobjs2s setobj +/* to stack (not from same stack) */ +#define setobj2s setobj +#define setsvalue2s setsvalue +#define sethvalue2s sethvalue +#define setptvalue2s setptvalue +/* from table to same table */ +#define setobjt2t setobj +/* to new object */ +#define setobj2n setobj +#define setsvalue2n setsvalue + +/* to table (define it as an expression to be used in macros) */ +#define setobj2t(L,o1,o2) ((void)L, *(o1)=*(o2), checkliveness(L,(o1))) + + + + +/* +** {====================================================== +** types and prototypes +** ======================================================= +*/ + + +typedef TValue *StkId; /* index to stack elements */ + + + + +/* +** Header for string value; string bytes follow the end of this structure +** (aligned according to 'UTString'; see next). +*/ +typedef struct TString { + CommonHeader; + lu_byte extra; /* reserved words for short strings; "has hash" for longs */ + lu_byte shrlen; /* length for short strings */ + unsigned int hash; + union { + size_t lnglen; /* length for long strings */ + struct TString *hnext; /* linked list for hash table */ + } u; +} TString; + + +/* +** Ensures that address after this type is always fully aligned. +*/ +typedef union UTString { + L_Umaxalign dummy; /* ensures maximum alignment for strings */ + TString tsv; +} UTString; + + +/* +** Get the actual string (array of bytes) from a 'TString'. +** (Access to 'extra' ensures that value is really a 'TString'.) +*/ +#define getstr(ts) \ + check_exp(sizeof((ts)->extra), cast(char *, (ts)) + sizeof(UTString)) + + +/* get the actual string (array of bytes) from a Lua value */ +#define svalue(o) getstr(tsvalue(o)) + +/* get string length from 'TString *s' */ +#define tsslen(s) ((s)->tt == LUA_TSHRSTR ? (s)->shrlen : (s)->u.lnglen) + +/* get string length from 'TValue *o' */ +#define vslen(o) tsslen(tsvalue(o)) + + +/* +** Header for userdata; memory area follows the end of this structure +** (aligned according to 'UUdata'; see next). +*/ +typedef struct Udata { + CommonHeader; + lu_byte ttuv_; /* user value's tag */ + struct Table *metatable; + size_t len; /* number of bytes */ + union Value user_; /* user value */ +} Udata; + + +/* +** Ensures that address after this type is always fully aligned. +*/ +typedef union UUdata { + L_Umaxalign dummy; /* ensures maximum alignment for 'local' udata */ + Udata uv; +} UUdata; + + +/* +** Get the address of memory block inside 'Udata'. +** (Access to 'ttuv_' ensures that value is really a 'Udata'.) +*/ +#define getudatamem(u) \ + check_exp(sizeof((u)->ttuv_), (cast(char*, (u)) + sizeof(UUdata))) + +#define setuservalue(L,u,o) \ + { const TValue *io=(o); Udata *iu = (u); \ + iu->user_ = io->value_; iu->ttuv_ = rttype(io); \ + checkliveness(L,io); } + + +#define getuservalue(L,u,o) \ + { TValue *io=(o); const Udata *iu = (u); \ + io->value_ = iu->user_; settt_(io, iu->ttuv_); \ + checkliveness(L,io); } + + +/* +** Description of an upvalue for function prototypes +*/ +typedef struct Upvaldesc { + TString *name; /* upvalue name (for debug information) */ + lu_byte instack; /* whether it is in stack (register) */ + lu_byte idx; /* index of upvalue (in stack or in outer function's list) */ +} Upvaldesc; + + +/* +** Description of a local variable for function prototypes +** (used for debug information) +*/ +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + +/* +** Function Prototypes +*/ +typedef struct Proto { + CommonHeader; + lu_byte numparams; /* number of fixed parameters */ + lu_byte is_vararg; + lu_byte maxstacksize; /* number of registers needed by this function */ + int sizeupvalues; /* size of 'upvalues' */ + int sizek; /* size of 'k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of 'p' */ + int sizelocvars; + int linedefined; /* debug information */ + int lastlinedefined; /* debug information */ + TValue *k; /* constants used by the function */ + Instruction *code; /* opcodes */ + struct Proto **p; /* functions defined inside the function */ + int *lineinfo; /* map from opcodes to source lines (debug information) */ + LocVar *locvars; /* information about local variables (debug information) */ + Upvaldesc *upvalues; /* upvalue information */ + struct LClosure *cache; /* last-created closure with this prototype */ + TString *source; /* used for debug information */ + GCObject *gclist; +} Proto; + + + +/* +** Lua Upvalues +*/ +typedef struct UpVal UpVal; + + +/* +** Closures +*/ + +#define ClosureHeader \ + CommonHeader; lu_byte nupvalues; GCObject *gclist + +typedef struct CClosure { + ClosureHeader; + lua_CFunction f; + TValue upvalue[1]; /* list of upvalues */ +} CClosure; + + +typedef struct LClosure { + ClosureHeader; + struct Proto *p; + UpVal *upvals[1]; /* list of upvalues */ +} LClosure; + + +typedef union Closure { + CClosure c; + LClosure l; +} Closure; + + +#define isLfunction(o) ttisLclosure(o) + +#define getproto(o) (clLvalue(o)->p) + + +/* +** Tables +*/ + +typedef union TKey { + struct { + TValuefields; + int next; /* for chaining (offset for next node) */ + } nk; + TValue tvk; +} TKey; + + +/* copy a value into a key without messing up field 'next' */ +#define setnodekey(L,key,obj) \ + { TKey *k_=(key); const TValue *io_=(obj); \ + k_->nk.value_ = io_->value_; k_->nk.tt_ = io_->tt_; \ + (void)L; checkliveness(L,io_); } + + +typedef struct Node { + TValue i_val; + TKey i_key; +} Node; + + +typedef struct Table { + CommonHeader; + lu_byte flags; /* 1<

lsizenode)) + + +/* +** (address of) a fixed nil value +*/ +#define luaO_nilobject (&luaO_nilobject_) + + +LUAI_DDEC const TValue luaO_nilobject_; + +/* size of buffer for 'luaO_utf8esc' function */ +#define UTF8BUFFSZ 8 + +LUAI_FUNC int luaO_int2fb (unsigned int x); +LUAI_FUNC int luaO_fb2int (int x); +LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x); +LUAI_FUNC int luaO_ceillog2 (unsigned int x); +LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1, + const TValue *p2, TValue *res); +LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o); +LUAI_FUNC int luaO_hexavalue (int c); +LUAI_FUNC void luaO_tostring (lua_State *L, StkId obj); +LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, + va_list argp); +LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); + + +#endif + diff --git a/3rd/lua-5.3.4/lopcodes.c b/3rd/lua-5.3.4/lopcodes.c new file mode 100644 index 0000000..a1cbef8 --- /dev/null +++ b/3rd/lua-5.3.4/lopcodes.c @@ -0,0 +1,124 @@ +/* +** $Id: lopcodes.c,v 1.55 2015/01/05 13:48:33 roberto Exp $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#define lopcodes_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lopcodes.h" + + +/* ORDER OP */ + +LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { + "MOVE", + "LOADK", + "LOADKX", + "LOADBOOL", + "LOADNIL", + "GETUPVAL", + "GETTABUP", + "GETTABLE", + "SETTABUP", + "SETUPVAL", + "SETTABLE", + "NEWTABLE", + "SELF", + "ADD", + "SUB", + "MUL", + "MOD", + "POW", + "DIV", + "IDIV", + "BAND", + "BOR", + "BXOR", + "SHL", + "SHR", + "UNM", + "BNOT", + "NOT", + "LEN", + "CONCAT", + "JMP", + "EQ", + "LT", + "LE", + "TEST", + "TESTSET", + "CALL", + "TAILCALL", + "RETURN", + "FORLOOP", + "FORPREP", + "TFORCALL", + "TFORLOOP", + "SETLIST", + "CLOSURE", + "VARARG", + "EXTRAARG", + NULL +}; + + +#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) + +LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { +/* T A B C mode opcode */ + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ + ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ + ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ + ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ + ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ + ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ + ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ + ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ + ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ + ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ +}; + diff --git a/3rd/lua-5.3.4/lopcodes.h b/3rd/lua-5.3.4/lopcodes.h new file mode 100644 index 0000000..bbc4b61 --- /dev/null +++ b/3rd/lua-5.3.4/lopcodes.h @@ -0,0 +1,297 @@ +/* +** $Id: lopcodes.h,v 1.149 2016/07/19 17:12:21 roberto Exp $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lopcodes_h +#define lopcodes_h + +#include "llimits.h" + + +/*=========================================================================== + We assume that instructions are unsigned numbers. + All instructions have an opcode in the first 6 bits. + Instructions can have the following fields: + 'A' : 8 bits + 'B' : 9 bits + 'C' : 9 bits + 'Ax' : 26 bits ('A', 'B', and 'C' together) + 'Bx' : 18 bits ('B' and 'C' together) + 'sBx' : signed Bx + + A signed argument is represented in excess K; that is, the number + value is the unsigned value minus K. K is exactly the maximum value + for that argument (so that -max is represented by 0, and +max is + represented by 2*max), which is half the maximum for the corresponding + unsigned argument. +===========================================================================*/ + + +enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ + + +/* +** size and position of opcode arguments. +*/ +#define SIZE_C 9 +#define SIZE_B 9 +#define SIZE_Bx (SIZE_C + SIZE_B) +#define SIZE_A 8 +#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A) + +#define SIZE_OP 6 + +#define POS_OP 0 +#define POS_A (POS_OP + SIZE_OP) +#define POS_C (POS_A + SIZE_A) +#define POS_B (POS_C + SIZE_C) +#define POS_Bx POS_C +#define POS_Ax POS_A + + +/* +** limits for opcode arguments. +** we use (signed) int to manipulate most arguments, +** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) +*/ +#if SIZE_Bx < LUAI_BITSINT-1 +#define MAXARG_Bx ((1<>1) /* 'sBx' is signed */ +#else +#define MAXARG_Bx MAX_INT +#define MAXARG_sBx MAX_INT +#endif + +#if SIZE_Ax < LUAI_BITSINT-1 +#define MAXARG_Ax ((1<>POS_OP) & MASK1(SIZE_OP,0))) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ + ((cast(Instruction, o)<>pos) & MASK1(size,0))) +#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ + ((cast(Instruction, v)<> RK(C) */ +OP_UNM,/* A B R(A) := -R(B) */ +OP_BNOT,/* A B R(A) := ~R(B) */ +OP_NOT,/* A B R(A) := not R(B) */ +OP_LEN,/* A B R(A) := length of R(B) */ + +OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ + +OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */ +OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ +OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ +OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ + +OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ +OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ + +OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ + +OP_FORLOOP,/* A sBx R(A)+=R(A+2); + if R(A) > 4) & 3)) +#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) + + +LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ + + +/* number of list items to accumulate before a SETLIST instruction */ +#define LFIELDS_PER_FLUSH 50 + + +#endif diff --git a/3rd/lua-5.3.4/loslib.c b/3rd/lua-5.3.4/loslib.c new file mode 100644 index 0000000..5a94eb9 --- /dev/null +++ b/3rd/lua-5.3.4/loslib.c @@ -0,0 +1,407 @@ +/* +** $Id: loslib.c,v 1.65 2016/07/18 17:58:58 roberto Exp $ +** Standard Operating System library +** See Copyright Notice in lua.h +*/ + +#define loslib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** {================================================================== +** List of valid conversion specifiers for the 'strftime' function; +** options are grouped by length; group of length 2 start with '||'. +** =================================================================== +*/ +#if !defined(LUA_STRFTIMEOPTIONS) /* { */ + +/* options for ANSI C 89 (only 1-char options) */ +#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%" + +/* options for ISO C 99 and POSIX */ +#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \ + "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */ + +/* options for Windows */ +#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \ + "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */ + +#if defined(LUA_USE_WINDOWS) +#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN +#elif defined(LUA_USE_C89) +#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89 +#else /* C99 specification */ +#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99 +#endif + +#endif /* } */ +/* }================================================================== */ + + +/* +** {================================================================== +** Configuration for time-related stuff +** =================================================================== +*/ + +#if !defined(l_time_t) /* { */ +/* +** type to represent time_t in Lua +*/ +#define l_timet lua_Integer +#define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) + +static time_t l_checktime (lua_State *L, int arg) { + lua_Integer t = luaL_checkinteger(L, arg); + luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds"); + return (time_t)t; +} + +#endif /* } */ + + +#if !defined(l_gmtime) /* { */ +/* +** By default, Lua uses gmtime/localtime, except when POSIX is available, +** where it uses gmtime_r/localtime_r +*/ + +#if defined(LUA_USE_POSIX) /* { */ + +#define l_gmtime(t,r) gmtime_r(t,r) +#define l_localtime(t,r) localtime_r(t,r) + +#else /* }{ */ + +/* ISO C definitions */ +#define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t)) +#define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t)) + +#endif /* } */ + +#endif /* } */ + +/* }================================================================== */ + + +/* +** {================================================================== +** Configuration for 'tmpnam': +** By default, Lua uses tmpnam except when POSIX is available, where +** it uses mkstemp. +** =================================================================== +*/ +#if !defined(lua_tmpnam) /* { */ + +#if defined(LUA_USE_POSIX) /* { */ + +#include + +#define LUA_TMPNAMBUFSIZE 32 + +#if !defined(LUA_TMPNAMTEMPLATE) +#define LUA_TMPNAMTEMPLATE "/tmp/lua_XXXXXX" +#endif + +#define lua_tmpnam(b,e) { \ + strcpy(b, LUA_TMPNAMTEMPLATE); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } + +#else /* }{ */ + +/* ISO C definitions */ +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } + +#endif /* } */ + +#endif /* } */ +/* }================================================================== */ + + + + +static int os_execute (lua_State *L) { + const char *cmd = luaL_optstring(L, 1, NULL); + int stat = system(cmd); + if (cmd != NULL) + return luaL_execresult(L, stat); + else { + lua_pushboolean(L, stat); /* true if there is a shell */ + return 1; + } +} + + +static int os_remove (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + return luaL_fileresult(L, remove(filename) == 0, filename); +} + + +static int os_rename (lua_State *L) { + const char *fromname = luaL_checkstring(L, 1); + const char *toname = luaL_checkstring(L, 2); + return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); +} + + +static int os_tmpname (lua_State *L) { + char buff[LUA_TMPNAMBUFSIZE]; + int err; + lua_tmpnam(buff, err); + if (err) + return luaL_error(L, "unable to generate a unique filename"); + lua_pushstring(L, buff); + return 1; +} + + +static int os_getenv (lua_State *L) { + lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ + return 1; +} + + +static int os_clock (lua_State *L) { + lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); + return 1; +} + + +/* +** {====================================================== +** Time/Date operations +** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, +** wday=%w+1, yday=%j, isdst=? } +** ======================================================= +*/ + +static void setfield (lua_State *L, const char *key, int value) { + lua_pushinteger(L, value); + lua_setfield(L, -2, key); +} + +static void setboolfield (lua_State *L, const char *key, int value) { + if (value < 0) /* undefined? */ + return; /* does not set field */ + lua_pushboolean(L, value); + lua_setfield(L, -2, key); +} + + +/* +** Set all fields from structure 'tm' in the table on top of the stack +*/ +static void setallfields (lua_State *L, struct tm *stm) { + setfield(L, "sec", stm->tm_sec); + setfield(L, "min", stm->tm_min); + setfield(L, "hour", stm->tm_hour); + setfield(L, "day", stm->tm_mday); + setfield(L, "month", stm->tm_mon + 1); + setfield(L, "year", stm->tm_year + 1900); + setfield(L, "wday", stm->tm_wday + 1); + setfield(L, "yday", stm->tm_yday + 1); + setboolfield(L, "isdst", stm->tm_isdst); +} + + +static int getboolfield (lua_State *L, const char *key) { + int res; + res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1); + lua_pop(L, 1); + return res; +} + + +/* maximum value for date fields (to avoid arithmetic overflows with 'int') */ +#if !defined(L_MAXDATEFIELD) +#define L_MAXDATEFIELD (INT_MAX / 2) +#endif + +static int getfield (lua_State *L, const char *key, int d, int delta) { + int isnum; + int t = lua_getfield(L, -1, key); /* get field and its type */ + lua_Integer res = lua_tointegerx(L, -1, &isnum); + if (!isnum) { /* field is not an integer? */ + if (t != LUA_TNIL) /* some other value? */ + return luaL_error(L, "field '%s' is not an integer", key); + else if (d < 0) /* absent field; no default? */ + return luaL_error(L, "field '%s' missing in date table", key); + res = d; + } + else { + if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD)) + return luaL_error(L, "field '%s' is out-of-bound", key); + res -= delta; + } + lua_pop(L, 1); + return (int)res; +} + + +static const char *checkoption (lua_State *L, const char *conv, + ptrdiff_t convlen, char *buff) { + const char *option = LUA_STRFTIMEOPTIONS; + int oplen = 1; /* length of options being checked */ + for (; *option != '\0' && oplen <= convlen; option += oplen) { + if (*option == '|') /* next block? */ + oplen++; /* will check options with next length (+1) */ + else if (memcmp(conv, option, oplen) == 0) { /* match? */ + memcpy(buff, conv, oplen); /* copy valid option to buffer */ + buff[oplen] = '\0'; + return conv + oplen; /* return next item */ + } + } + luaL_argerror(L, 1, + lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv)); + return conv; /* to avoid warnings */ +} + + +/* maximum size for an individual 'strftime' item */ +#define SIZETIMEFMT 250 + + +static int os_date (lua_State *L) { + size_t slen; + const char *s = luaL_optlstring(L, 1, "%c", &slen); + time_t t = luaL_opt(L, l_checktime, 2, time(NULL)); + const char *se = s + slen; /* 's' end */ + struct tm tmr, *stm; + if (*s == '!') { /* UTC? */ + stm = l_gmtime(&t, &tmr); + s++; /* skip '!' */ + } + else + stm = l_localtime(&t, &tmr); + if (stm == NULL) /* invalid date? */ + luaL_error(L, "time result cannot be represented in this installation"); + if (strcmp(s, "*t") == 0) { + lua_createtable(L, 0, 9); /* 9 = number of fields */ + setallfields(L, stm); + } + else { + char cc[4]; /* buffer for individual conversion specifiers */ + luaL_Buffer b; + cc[0] = '%'; + luaL_buffinit(L, &b); + while (s < se) { + if (*s != '%') /* not a conversion specifier? */ + luaL_addchar(&b, *s++); + else { + size_t reslen; + char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT); + s++; /* skip '%' */ + s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */ + reslen = strftime(buff, SIZETIMEFMT, cc, stm); + luaL_addsize(&b, reslen); + } + } + luaL_pushresult(&b); + } + return 1; +} + + +static int os_time (lua_State *L) { + time_t t; + if (lua_isnoneornil(L, 1)) /* called without args? */ + t = time(NULL); /* get current time */ + else { + struct tm ts; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); /* make sure table is at the top */ + ts.tm_sec = getfield(L, "sec", 0, 0); + ts.tm_min = getfield(L, "min", 0, 0); + ts.tm_hour = getfield(L, "hour", 12, 0); + ts.tm_mday = getfield(L, "day", -1, 0); + ts.tm_mon = getfield(L, "month", -1, 1); + ts.tm_year = getfield(L, "year", -1, 1900); + ts.tm_isdst = getboolfield(L, "isdst"); + t = mktime(&ts); + setallfields(L, &ts); /* update fields with normalized values */ + } + if (t != (time_t)(l_timet)t || t == (time_t)(-1)) + luaL_error(L, "time result cannot be represented in this installation"); + l_pushtime(L, t); + return 1; +} + + +static int os_difftime (lua_State *L) { + time_t t1 = l_checktime(L, 1); + time_t t2 = l_checktime(L, 2); + lua_pushnumber(L, (lua_Number)difftime(t1, t2)); + return 1; +} + +/* }====================================================== */ + + +static int os_setlocale (lua_State *L) { + static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, + LC_NUMERIC, LC_TIME}; + static const char *const catnames[] = {"all", "collate", "ctype", "monetary", + "numeric", "time", NULL}; + const char *l = luaL_optstring(L, 1, NULL); + int op = luaL_checkoption(L, 2, "all", catnames); + lua_pushstring(L, setlocale(cat[op], l)); + return 1; +} + + +static int os_exit (lua_State *L) { + int status; + if (lua_isboolean(L, 1)) + status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE); + else + status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS); + if (lua_toboolean(L, 2)) + lua_close(L); + if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */ + return 0; +} + + +static const luaL_Reg syslib[] = { + {"clock", os_clock}, + {"date", os_date}, + {"difftime", os_difftime}, + {"execute", os_execute}, + {"exit", os_exit}, + {"getenv", os_getenv}, + {"remove", os_remove}, + {"rename", os_rename}, + {"setlocale", os_setlocale}, + {"time", os_time}, + {"tmpname", os_tmpname}, + {NULL, NULL} +}; + +/* }====================================================== */ + + + +LUAMOD_API int luaopen_os (lua_State *L) { + luaL_newlib(L, syslib); + return 1; +} + diff --git a/3rd/lua-5.3.4/lparser.c b/3rd/lua-5.3.4/lparser.c new file mode 100644 index 0000000..cd4512d --- /dev/null +++ b/3rd/lua-5.3.4/lparser.c @@ -0,0 +1,1650 @@ +/* +** $Id: lparser.c,v 2.155 2016/08/01 19:51:24 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#define lparser_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" + + + +/* maximum number of local variables per function (must be smaller + than 250, due to the bytecode format) */ +#define MAXVARS 200 + + +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) + + +/* because all strings are unified by the scanner, the parser + can use pointer equality for string equality */ +#define eqstr(a,b) ((a) == (b)) + + +/* +** nodes for block list (list of active blocks) +*/ +typedef struct BlockCnt { + struct BlockCnt *previous; /* chain */ + int firstlabel; /* index of first label in this block */ + int firstgoto; /* index of first pending goto in this block */ + lu_byte nactvar; /* # active locals outside the block */ + lu_byte upval; /* true if some variable in the block is an upvalue */ + lu_byte isloop; /* true if 'block' is a loop */ +} BlockCnt; + + + +/* +** prototypes for recursive non-terminal functions +*/ +static void statement (LexState *ls); +static void expr (LexState *ls, expdesc *v); + + +/* semantic error */ +static l_noret semerror (LexState *ls, const char *msg) { + ls->t.token = 0; /* remove "near " from final message */ + luaX_syntaxerror(ls, msg); +} + + +static l_noret error_expected (LexState *ls, int token) { + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); +} + + +static l_noret errorlimit (FuncState *fs, int limit, const char *what) { + lua_State *L = fs->ls->L; + const char *msg; + int line = fs->f->linedefined; + const char *where = (line == 0) + ? "main function" + : luaO_pushfstring(L, "function at line %d", line); + msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", + what, limit, where); + luaX_syntaxerror(fs->ls, msg); +} + + +static void checklimit (FuncState *fs, int v, int l, const char *what) { + if (v > l) errorlimit(fs, l, what); +} + + +static int testnext (LexState *ls, int c) { + if (ls->t.token == c) { + luaX_next(ls); + return 1; + } + else return 0; +} + + +static void check (LexState *ls, int c) { + if (ls->t.token != c) + error_expected(ls, c); +} + + +static void checknext (LexState *ls, int c) { + check(ls, c); + luaX_next(ls); +} + + +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } + + + +static void check_match (LexState *ls, int what, int who, int where) { + if (!testnext(ls, what)) { + if (where == ls->linenumber) + error_expected(ls, what); + else { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, + "%s expected (to close %s at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } + } +} + + +static TString *str_checkname (LexState *ls) { + TString *ts; + check(ls, TK_NAME); + ts = ls->t.seminfo.ts; + luaX_next(ls); + return ts; +} + + +static void init_exp (expdesc *e, expkind k, int i) { + e->f = e->t = NO_JUMP; + e->k = k; + e->u.info = i; +} + + +static void codestring (LexState *ls, expdesc *e, TString *s) { + init_exp(e, VK, luaK_stringK(ls->fs, s)); +} + + +static void checkname (LexState *ls, expdesc *e) { + codestring(ls, e, str_checkname(ls)); +} + + +static int registerlocalvar (LexState *ls, TString *varname) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizelocvars; + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, + LocVar, SHRT_MAX, "local variables"); + while (oldsize < f->sizelocvars) + f->locvars[oldsize++].varname = NULL; + f->locvars[fs->nlocvars].varname = varname; + luaC_objbarrier(ls->L, f, varname); + return fs->nlocvars++; +} + + +static void new_localvar (LexState *ls, TString *name) { + FuncState *fs = ls->fs; + Dyndata *dyd = ls->dyd; + int reg = registerlocalvar(ls, name); + checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, + MAXVARS, "local variables"); + luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, + dyd->actvar.size, Vardesc, MAX_INT, "local variables"); + dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg); +} + + +static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { + new_localvar(ls, luaX_newstring(ls, name, sz)); +} + +#define new_localvarliteral(ls,v) \ + new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1) + + +static LocVar *getlocvar (FuncState *fs, int i) { + int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; + lua_assert(idx < fs->nlocvars); + return &fs->f->locvars[idx]; +} + + +static void adjustlocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + fs->nactvar = cast_byte(fs->nactvar + nvars); + for (; nvars; nvars--) { + getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc; + } +} + + +static void removevars (FuncState *fs, int tolevel) { + fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); + while (fs->nactvar > tolevel) + getlocvar(fs, --fs->nactvar)->endpc = fs->pc; +} + + +static int searchupvalue (FuncState *fs, TString *name) { + int i; + Upvaldesc *up = fs->f->upvalues; + for (i = 0; i < fs->nups; i++) { + if (eqstr(up[i].name, name)) return i; + } + return -1; /* not found */ +} + + +static int newupvalue (FuncState *fs, TString *name, expdesc *v) { + Proto *f = fs->f; + int oldsize = f->sizeupvalues; + checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); + luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, + Upvaldesc, MAXUPVAL, "upvalues"); + while (oldsize < f->sizeupvalues) + f->upvalues[oldsize++].name = NULL; + f->upvalues[fs->nups].instack = (v->k == VLOCAL); + f->upvalues[fs->nups].idx = cast_byte(v->u.info); + f->upvalues[fs->nups].name = name; + luaC_objbarrier(fs->ls->L, f, name); + return fs->nups++; +} + + +static int searchvar (FuncState *fs, TString *n) { + int i; + for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { + if (eqstr(n, getlocvar(fs, i)->varname)) + return i; + } + return -1; /* not found */ +} + + +/* + Mark block where variable at given level was defined + (to emit close instructions later). +*/ +static void markupval (FuncState *fs, int level) { + BlockCnt *bl = fs->bl; + while (bl->nactvar > level) + bl = bl->previous; + bl->upval = 1; +} + + +/* + Find variable with given name 'n'. If it is an upvalue, add this + upvalue into all intermediate functions. +*/ +static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { + if (fs == NULL) /* no more levels? */ + init_exp(var, VVOID, 0); /* default is global */ + else { + int v = searchvar(fs, n); /* look up locals at current level */ + if (v >= 0) { /* found? */ + init_exp(var, VLOCAL, v); /* variable is local */ + if (!base) + markupval(fs, v); /* local will be used as an upval */ + } + else { /* not found as local at current level; try upvalues */ + int idx = searchupvalue(fs, n); /* try existing upvalues */ + if (idx < 0) { /* not found? */ + singlevaraux(fs->prev, n, var, 0); /* try upper levels */ + if (var->k == VVOID) /* not found? */ + return; /* it is a global */ + /* else was LOCAL or UPVAL */ + idx = newupvalue(fs, n, var); /* will be a new upvalue */ + } + init_exp(var, VUPVAL, idx); /* new or old upvalue */ + } + } +} + + +static void singlevar (LexState *ls, expdesc *var) { + TString *varname = str_checkname(ls); + FuncState *fs = ls->fs; + singlevaraux(fs, varname, var, 1); + if (var->k == VVOID) { /* global name? */ + expdesc key; + singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ + lua_assert(var->k != VVOID); /* this one must exist */ + codestring(ls, &key, varname); /* key is variable name */ + luaK_indexed(fs, var, &key); /* env[varname] */ + } +} + + +static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { + FuncState *fs = ls->fs; + int extra = nvars - nexps; + if (hasmultret(e->k)) { + extra++; /* includes call itself */ + if (extra < 0) extra = 0; + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + if (extra > 1) luaK_reserveregs(fs, extra-1); + } + else { + if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ + if (extra > 0) { + int reg = fs->freereg; + luaK_reserveregs(fs, extra); + luaK_nil(fs, reg, extra); + } + } + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ +} + + +static void enterlevel (LexState *ls) { + lua_State *L = ls->L; + ++L->nCcalls; + checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels"); +} + + +#define leavelevel(ls) ((ls)->L->nCcalls--) + + +static void closegoto (LexState *ls, int g, Labeldesc *label) { + int i; + FuncState *fs = ls->fs; + Labellist *gl = &ls->dyd->gt; + Labeldesc *gt = &gl->arr[g]; + lua_assert(eqstr(gt->name, label->name)); + if (gt->nactvar < label->nactvar) { + TString *vname = getlocvar(fs, gt->nactvar)->varname; + const char *msg = luaO_pushfstring(ls->L, + " at line %d jumps into the scope of local '%s'", + getstr(gt->name), gt->line, getstr(vname)); + semerror(ls, msg); + } + luaK_patchlist(fs, gt->pc, label->pc); + /* remove goto from pending list */ + for (i = g; i < gl->n - 1; i++) + gl->arr[i] = gl->arr[i + 1]; + gl->n--; +} + + +/* +** try to close a goto with existing labels; this solves backward jumps +*/ +static int findlabel (LexState *ls, int g) { + int i; + BlockCnt *bl = ls->fs->bl; + Dyndata *dyd = ls->dyd; + Labeldesc *gt = &dyd->gt.arr[g]; + /* check labels in current block for a match */ + for (i = bl->firstlabel; i < dyd->label.n; i++) { + Labeldesc *lb = &dyd->label.arr[i]; + if (eqstr(lb->name, gt->name)) { /* correct label? */ + if (gt->nactvar > lb->nactvar && + (bl->upval || dyd->label.n > bl->firstlabel)) + luaK_patchclose(ls->fs, gt->pc, lb->nactvar); + closegoto(ls, g, lb); /* close it */ + return 1; + } + } + return 0; /* label not found; cannot close goto */ +} + + +static int newlabelentry (LexState *ls, Labellist *l, TString *name, + int line, int pc) { + int n = l->n; + luaM_growvector(ls->L, l->arr, n, l->size, + Labeldesc, SHRT_MAX, "labels/gotos"); + l->arr[n].name = name; + l->arr[n].line = line; + l->arr[n].nactvar = ls->fs->nactvar; + l->arr[n].pc = pc; + l->n = n + 1; + return n; +} + + +/* +** check whether new label 'lb' matches any pending gotos in current +** block; solves forward jumps +*/ +static void findgotos (LexState *ls, Labeldesc *lb) { + Labellist *gl = &ls->dyd->gt; + int i = ls->fs->bl->firstgoto; + while (i < gl->n) { + if (eqstr(gl->arr[i].name, lb->name)) + closegoto(ls, i, lb); + else + i++; + } +} + + +/* +** export pending gotos to outer level, to check them against +** outer labels; if the block being exited has upvalues, and +** the goto exits the scope of any variable (which can be the +** upvalue), close those variables being exited. +*/ +static void movegotosout (FuncState *fs, BlockCnt *bl) { + int i = bl->firstgoto; + Labellist *gl = &fs->ls->dyd->gt; + /* correct pending gotos to current block and try to close it + with visible labels */ + while (i < gl->n) { + Labeldesc *gt = &gl->arr[i]; + if (gt->nactvar > bl->nactvar) { + if (bl->upval) + luaK_patchclose(fs, gt->pc, bl->nactvar); + gt->nactvar = bl->nactvar; + } + if (!findlabel(fs->ls, i)) + i++; /* move to next one */ + } +} + + +static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { + bl->isloop = isloop; + bl->nactvar = fs->nactvar; + bl->firstlabel = fs->ls->dyd->label.n; + bl->firstgoto = fs->ls->dyd->gt.n; + bl->upval = 0; + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == fs->nactvar); +} + + +/* +** create a label named 'break' to resolve break statements +*/ +static void breaklabel (LexState *ls) { + TString *n = luaS_new(ls->L, "break"); + int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc); + findgotos(ls, &ls->dyd->label.arr[l]); +} + +/* +** generates an error for an undefined 'goto'; choose appropriate +** message when label name is a reserved word (which can only be 'break') +*/ +static l_noret undefgoto (LexState *ls, Labeldesc *gt) { + const char *msg = isreserved(gt->name) + ? "<%s> at line %d not inside a loop" + : "no visible label '%s' for at line %d"; + msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); + semerror(ls, msg); +} + + +static void leaveblock (FuncState *fs) { + BlockCnt *bl = fs->bl; + LexState *ls = fs->ls; + if (bl->previous && bl->upval) { + /* create a 'jump to here' to close upvalues */ + int j = luaK_jump(fs); + luaK_patchclose(fs, j, bl->nactvar); + luaK_patchtohere(fs, j); + } + if (bl->isloop) + breaklabel(ls); /* close pending breaks */ + fs->bl = bl->previous; + removevars(fs, bl->nactvar); + lua_assert(bl->nactvar == fs->nactvar); + fs->freereg = fs->nactvar; /* free registers */ + ls->dyd->label.n = bl->firstlabel; /* remove local labels */ + if (bl->previous) /* inner block? */ + movegotosout(fs, bl); /* update pending gotos to outer block */ + else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ + undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ +} + + +/* +** adds a new prototype into list of prototypes +*/ +static Proto *addprototype (LexState *ls) { + Proto *clp; + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; /* prototype of current function */ + if (fs->np >= f->sizep) { + int oldsize = f->sizep; + luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); + while (oldsize < f->sizep) + f->p[oldsize++] = NULL; + } + f->p[fs->np++] = clp = luaF_newproto(L); + luaC_objbarrier(L, f, clp); + return clp; +} + + +/* +** codes instruction to create new closure in parent function. +** The OP_CLOSURE instruction must use the last available register, +** so that, if it invokes the GC, the GC knows which registers +** are in use at that time. +*/ +static void codeclosure (LexState *ls, expdesc *v) { + FuncState *fs = ls->fs->prev; + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); + luaK_exp2nextreg(fs, v); /* fix it at the last register */ +} + + +static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { + Proto *f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + ls->fs = fs; + fs->pc = 0; + fs->lasttarget = 0; + fs->jpc = NO_JUMP; + fs->freereg = 0; + fs->nk = 0; + fs->np = 0; + fs->nups = 0; + fs->nlocvars = 0; + fs->nactvar = 0; + fs->firstlocal = ls->dyd->actvar.n; + fs->bl = NULL; + f = fs->f; + f->source = ls->source; + f->maxstacksize = 2; /* registers 0/1 are always valid */ + enterblock(fs, bl, 0); +} + + +static void close_func (LexState *ls) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + luaK_ret(fs, 0, 0); /* final return */ + leaveblock(fs); + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); + f->sizelineinfo = fs->pc; + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); + f->sizek = fs->nk; + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); + f->sizep = fs->np; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); + f->sizeupvalues = fs->nups; + lua_assert(fs->bl == NULL); + ls->fs = fs->prev; + luaC_checkGC(L); +} + + + +/*============================================================*/ +/* GRAMMAR RULES */ +/*============================================================*/ + + +/* +** check whether current token is in the follow set of a block. +** 'until' closes syntactical blocks, but do not close scope, +** so it is handled in separate. +*/ +static int block_follow (LexState *ls, int withuntil) { + switch (ls->t.token) { + case TK_ELSE: case TK_ELSEIF: + case TK_END: case TK_EOS: + return 1; + case TK_UNTIL: return withuntil; + default: return 0; + } +} + + +static void statlist (LexState *ls) { + /* statlist -> { stat [';'] } */ + while (!block_follow(ls, 1)) { + if (ls->t.token == TK_RETURN) { + statement(ls); + return; /* 'return' must be last statement */ + } + statement(ls); + } +} + + +static void fieldsel (LexState *ls, expdesc *v) { + /* fieldsel -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyregup(fs, v); + luaX_next(ls); /* skip the dot or colon */ + checkname(ls, &key); + luaK_indexed(fs, v, &key); +} + + +static void yindex (LexState *ls, expdesc *v) { + /* index -> '[' expr ']' */ + luaX_next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + checknext(ls, ']'); +} + + +/* +** {====================================================================== +** Rules for Constructors +** ======================================================================= +*/ + + +struct ConsControl { + expdesc v; /* last list item read */ + expdesc *t; /* table descriptor */ + int nh; /* total number of 'record' elements */ + int na; /* total number of array elements */ + int tostore; /* number of array elements pending to be stored */ +}; + + +static void recfield (LexState *ls, struct ConsControl *cc) { + /* recfield -> (NAME | '['exp1']') = exp1 */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc key, val; + int rkkey; + if (ls->t.token == TK_NAME) { + checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + checkname(ls, &key); + } + else /* ls->t.token == '[' */ + yindex(ls, &key); + cc->nh++; + checknext(ls, '='); + rkkey = luaK_exp2RK(fs, &key); + expr(ls, &val); + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val)); + fs->freereg = reg; /* free registers */ +} + + +static void closelistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->v.k == VVOID) return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) { + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ + cc->tostore = 0; /* no more items pending */ + } +} + + +static void lastlistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->tostore == 0) return; + if (hasmultret(cc->v.k)) { + luaK_setmultret(fs, &cc->v); + luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); + cc->na--; /* do not count last expression (unknown number of elements) */ + } + else { + if (cc->v.k != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); + } +} + + +static void listfield (LexState *ls, struct ConsControl *cc) { + /* listfield -> exp */ + expr(ls, &cc->v); + checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); + cc->na++; + cc->tostore++; +} + + +static void field (LexState *ls, struct ConsControl *cc) { + /* field -> listfield | recfield */ + switch(ls->t.token) { + case TK_NAME: { /* may be 'listfield' or 'recfield' */ + if (luaX_lookahead(ls) != '=') /* expression? */ + listfield(ls, cc); + else + recfield(ls, cc); + break; + } + case '[': { + recfield(ls, cc); + break; + } + default: { + listfield(ls, cc); + break; + } + } +} + + +static void constructor (LexState *ls, expdesc *t) { + /* constructor -> '{' [ field { sep field } [sep] ] '}' + sep -> ',' | ';' */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + struct ConsControl cc; + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VRELOCABLE, pc); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */ + checknext(ls, '{'); + do { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + if (ls->t.token == '}') break; + closelistfield(fs, &cc); + field(ls, &cc); + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ +} + +/* }====================================================================== */ + + + +static void parlist (LexState *ls) { + /* parlist -> [ param { ',' param } ] */ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int nparams = 0; + f->is_vararg = 0; + if (ls->t.token != ')') { /* is 'parlist' not empty? */ + do { + switch (ls->t.token) { + case TK_NAME: { /* param -> NAME */ + new_localvar(ls, str_checkname(ls)); + nparams++; + break; + } + case TK_DOTS: { /* param -> '...' */ + luaX_next(ls); + f->is_vararg = 1; /* declared vararg */ + break; + } + default: luaX_syntaxerror(ls, " or '...' expected"); + } + } while (!f->is_vararg && testnext(ls, ',')); + } + adjustlocalvars(ls, nparams); + f->numparams = cast_byte(fs->nactvar); + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ +} + + +static void body (LexState *ls, expdesc *e, int ismethod, int line) { + /* body -> '(' parlist ')' block END */ + FuncState new_fs; + BlockCnt bl; + new_fs.f = addprototype(ls); + new_fs.f->linedefined = line; + open_func(ls, &new_fs, &bl); + checknext(ls, '('); + if (ismethod) { + new_localvarliteral(ls, "self"); /* create 'self' parameter */ + adjustlocalvars(ls, 1); + } + parlist(ls); + checknext(ls, ')'); + statlist(ls); + new_fs.f->lastlinedefined = ls->linenumber; + check_match(ls, TK_END, TK_FUNCTION, line); + codeclosure(ls, e); + close_func(ls); +} + + +static int explist (LexState *ls, expdesc *v) { + /* explist -> expr { ',' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; +} + + +static void funcargs (LexState *ls, expdesc *f, int line) { + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + switch (ls->t.token) { + case '(': { /* funcargs -> '(' [ explist ] ')' */ + luaX_next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else { + explist(ls, &args); + luaK_setmultret(fs, &args); + } + check_match(ls, ')', '(', line); + break; + } + case '{': { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + codestring(ls, &args, ls->t.seminfo.ts); + luaX_next(ls); /* must use 'seminfo' before 'next' */ + break; + } + default: { + luaX_syntaxerror(ls, "function arguments expected"); + } + } + lua_assert(f->k == VNONRELOC); + base = f->u.info; /* base register for call */ + if (hasmultret(args.k)) + nparams = LUA_MULTRET; /* open call */ + else { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base+1); + } + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); + luaK_fixline(fs, line); + fs->freereg = base+1; /* call remove function and arguments and leaves + (unless changed) one result */ +} + + + + +/* +** {====================================================================== +** Expression parsing +** ======================================================================= +*/ + + +static void primaryexp (LexState *ls, expdesc *v) { + /* primaryexp -> NAME | '(' expr ')' */ + switch (ls->t.token) { + case '(': { + int line = ls->linenumber; + luaX_next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: { + singlevar(ls, v); + return; + } + default: { + luaX_syntaxerror(ls, "unexpected symbol"); + } + } +} + + +static void suffixedexp (LexState *ls, expdesc *v) { + /* suffixedexp -> + primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + primaryexp(ls, v); + for (;;) { + switch (ls->t.token) { + case '.': { /* fieldsel */ + fieldsel(ls, v); + break; + } + case '[': { /* '[' exp1 ']' */ + expdesc key; + luaK_exp2anyregup(fs, v); + yindex(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': { /* ':' NAME funcargs */ + expdesc key; + luaX_next(ls); + checkname(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v, line); + break; + } + case '(': case TK_STRING: case '{': { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v, line); + break; + } + default: return; + } + } +} + + +static void simpleexp (LexState *ls, expdesc *v) { + /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... | + constructor | FUNCTION body | suffixedexp */ + switch (ls->t.token) { + case TK_FLT: { + init_exp(v, VKFLT, 0); + v->u.nval = ls->t.seminfo.r; + break; + } + case TK_INT: { + init_exp(v, VKINT, 0); + v->u.ival = ls->t.seminfo.i; + break; + } + case TK_STRING: { + codestring(ls, v, ls->t.seminfo.ts); + break; + } + case TK_NIL: { + init_exp(v, VNIL, 0); + break; + } + case TK_TRUE: { + init_exp(v, VTRUE, 0); + break; + } + case TK_FALSE: { + init_exp(v, VFALSE, 0); + break; + } + case TK_DOTS: { /* vararg */ + FuncState *fs = ls->fs; + check_condition(ls, fs->f->is_vararg, + "cannot use '...' outside a vararg function"); + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); + break; + } + case '{': { /* constructor */ + constructor(ls, v); + return; + } + case TK_FUNCTION: { + luaX_next(ls); + body(ls, v, 0, ls->linenumber); + return; + } + default: { + suffixedexp(ls, v); + return; + } + } + luaX_next(ls); +} + + +static UnOpr getunopr (int op) { + switch (op) { + case TK_NOT: return OPR_NOT; + case '-': return OPR_MINUS; + case '~': return OPR_BNOT; + case '#': return OPR_LEN; + default: return OPR_NOUNOPR; + } +} + + +static BinOpr getbinopr (int op) { + switch (op) { + case '+': return OPR_ADD; + case '-': return OPR_SUB; + case '*': return OPR_MUL; + case '%': return OPR_MOD; + case '^': return OPR_POW; + case '/': return OPR_DIV; + case TK_IDIV: return OPR_IDIV; + case '&': return OPR_BAND; + case '|': return OPR_BOR; + case '~': return OPR_BXOR; + case TK_SHL: return OPR_SHL; + case TK_SHR: return OPR_SHR; + case TK_CONCAT: return OPR_CONCAT; + case TK_NE: return OPR_NE; + case TK_EQ: return OPR_EQ; + case '<': return OPR_LT; + case TK_LE: return OPR_LE; + case '>': return OPR_GT; + case TK_GE: return OPR_GE; + case TK_AND: return OPR_AND; + case TK_OR: return OPR_OR; + default: return OPR_NOBINOPR; + } +} + + +static const struct { + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { /* ORDER OPR */ + {10, 10}, {10, 10}, /* '+' '-' */ + {11, 11}, {11, 11}, /* '*' '%' */ + {14, 13}, /* '^' (right associative) */ + {11, 11}, {11, 11}, /* '/' '//' */ + {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ + {7, 7}, {7, 7}, /* '<<' '>>' */ + {9, 8}, /* '..' (right associative) */ + {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ + {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ + {2, 2}, {1, 1} /* and, or */ +}; + +#define UNARY_PRIORITY 12 /* priority for unary operators */ + + +/* +** subexpr -> (simpleexp | unop subexpr) { binop subexpr } +** where 'binop' is any binary operator with a priority higher than 'limit' +*/ +static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) { + int line = ls->linenumber; + luaX_next(ls); + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v, line); + } + else simpleexp(ls, v); + /* expand while operators have priorities higher than 'limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) { + expdesc v2; + BinOpr nextop; + int line = ls->linenumber; + luaX_next(ls); + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls->fs, op, v, &v2, line); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ +} + + +static void expr (LexState *ls, expdesc *v) { + subexpr(ls, v, 0); +} + +/* }==================================================================== */ + + + +/* +** {====================================================================== +** Rules for Statements +** ======================================================================= +*/ + + +static void block (LexState *ls) { + /* block -> statlist */ + FuncState *fs = ls->fs; + BlockCnt bl; + enterblock(fs, &bl, 0); + statlist(ls); + leaveblock(fs); +} + + +/* +** structure to chain all variables in the left-hand side of an +** assignment +*/ +struct LHS_assign { + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ +}; + + +/* +** check whether, in an assignment to an upvalue/local variable, the +** upvalue/local variable is begin used in a previous assignment to a +** table. If so, save original upvalue/local value in a safe place and +** use this safe copy in the previous assignment. +*/ +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) { /* check all previous assignments */ + if (lh->v.k == VINDEXED) { /* assigning to a table? */ + /* table is the upvalue/local being assigned now? */ + if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) { + conflict = 1; + lh->v.u.ind.vt = VLOCAL; + lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ + } + /* index is the local being assigned? (index cannot be upvalue) */ + if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { + conflict = 1; + lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ + } + } + } + if (conflict) { + /* copy upvalue/local value to a temporary (in position 'extra') */ + OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, op, extra, v->u.info, 0); + luaK_reserveregs(fs, 1); + } +} + + +static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { + expdesc e; + check_condition(ls, vkisvar(lh->v.k), "syntax error"); + if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */ + struct LHS_assign nv; + nv.prev = lh; + suffixedexp(ls, &nv.v); + if (nv.v.k != VINDEXED) + check_conflict(ls, lh, &nv.v); + checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, + "C levels"); + assignment(ls, &nv, nvars+1); + } + else { /* assignment -> '=' explist */ + int nexps; + checknext(ls, '='); + nexps = explist(ls, &e); + if (nexps != nvars) + adjust_assign(ls, nvars, nexps, &e); + else { + luaK_setoneret(ls->fs, &e); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } + } + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); +} + + +static int cond (LexState *ls) { + /* cond -> exp */ + expdesc v; + expr(ls, &v); /* read condition */ + if (v.k == VNIL) v.k = VFALSE; /* 'falses' are all equal here */ + luaK_goiftrue(ls->fs, &v); + return v.f; +} + + +static void gotostat (LexState *ls, int pc) { + int line = ls->linenumber; + TString *label; + int g; + if (testnext(ls, TK_GOTO)) + label = str_checkname(ls); + else { + luaX_next(ls); /* skip break */ + label = luaS_new(ls->L, "break"); + } + g = newlabelentry(ls, &ls->dyd->gt, label, line, pc); + findlabel(ls, g); /* close it if label already defined */ +} + + +/* check for repeated labels on the same block */ +static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { + int i; + for (i = fs->bl->firstlabel; i < ll->n; i++) { + if (eqstr(label, ll->arr[i].name)) { + const char *msg = luaO_pushfstring(fs->ls->L, + "label '%s' already defined on line %d", + getstr(label), ll->arr[i].line); + semerror(fs->ls, msg); + } + } +} + + +/* skip no-op statements */ +static void skipnoopstat (LexState *ls) { + while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) + statement(ls); +} + + +static void labelstat (LexState *ls, TString *label, int line) { + /* label -> '::' NAME '::' */ + FuncState *fs = ls->fs; + Labellist *ll = &ls->dyd->label; + int l; /* index of new label being created */ + checkrepeated(fs, ll, label); /* check for repeated labels */ + checknext(ls, TK_DBCOLON); /* skip double colon */ + /* create new entry for this label */ + l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs)); + skipnoopstat(ls); /* skip other no-op statements */ + if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */ + /* assume that locals are already out of scope */ + ll->arr[l].nactvar = fs->bl->nactvar; + } + findgotos(ls, &ll->arr[l]); +} + + +static void whilestat (LexState *ls, int line) { + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int whileinit; + int condexit; + BlockCnt bl; + luaX_next(ls); /* skip WHILE */ + whileinit = luaK_getlabel(fs); + condexit = cond(ls); + enterblock(fs, &bl, 1); + checknext(ls, TK_DO); + block(ls); + luaK_jumpto(fs, whileinit); + check_match(ls, TK_END, TK_WHILE, line); + leaveblock(fs); + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ +} + + +static void repeatstat (LexState *ls, int line) { + /* repeatstat -> REPEAT block UNTIL cond */ + int condexit; + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + BlockCnt bl1, bl2; + enterblock(fs, &bl1, 1); /* loop block */ + enterblock(fs, &bl2, 0); /* scope block */ + luaX_next(ls); /* skip REPEAT */ + statlist(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + condexit = cond(ls); /* read condition (inside scope block) */ + if (bl2.upval) /* upvalues? */ + luaK_patchclose(fs, condexit, bl2.nactvar); + leaveblock(fs); /* finish scope */ + luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ + leaveblock(fs); /* finish loop */ +} + + +static int exp1 (LexState *ls) { + expdesc e; + int reg; + expr(ls, &e); + luaK_exp2nextreg(ls->fs, &e); + lua_assert(e.k == VNONRELOC); + reg = e.u.info; + return reg; +} + + +static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { + /* forbody -> DO block */ + BlockCnt bl; + FuncState *fs = ls->fs; + int prep, endfor; + adjustlocalvars(ls, 3); /* control variables */ + checknext(ls, TK_DO); + prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); + enterblock(fs, &bl, 0); /* scope for declared variables */ + adjustlocalvars(ls, nvars); + luaK_reserveregs(fs, nvars); + block(ls); + leaveblock(fs); /* end of scope for declared variables */ + luaK_patchtohere(fs, prep); + if (isnum) /* numeric for? */ + endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); + else { /* generic for */ + luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); + luaK_fixline(fs, line); + endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); + } + luaK_patchlist(fs, endfor, prep + 1); + luaK_fixline(fs, line); +} + + +static void fornum (LexState *ls, TString *varname, int line) { + /* fornum -> NAME = exp1,exp1[,exp1] forbody */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvarliteral(ls, "(for index)"); + new_localvarliteral(ls, "(for limit)"); + new_localvarliteral(ls, "(for step)"); + new_localvar(ls, varname); + checknext(ls, '='); + exp1(ls); /* initial value */ + checknext(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else { /* default step = 1 */ + luaK_codek(fs, fs->freereg, luaK_intK(fs, 1)); + luaK_reserveregs(fs, 1); + } + forbody(ls, base, line, 1, 1); +} + + +static void forlist (LexState *ls, TString *indexname) { + /* forlist -> NAME {,NAME} IN explist forbody */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 4; /* gen, state, control, plus at least one declared var */ + int line; + int base = fs->freereg; + /* create control variables */ + new_localvarliteral(ls, "(for generator)"); + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for control)"); + /* create declared variables */ + new_localvar(ls, indexname); + while (testnext(ls, ',')) { + new_localvar(ls, str_checkname(ls)); + nvars++; + } + checknext(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, 3, explist(ls, &e), &e); + luaK_checkstack(fs, 3); /* extra space to call generator */ + forbody(ls, base, line, nvars - 3, 0); +} + + +static void forstat (LexState *ls, int line) { + /* forstat -> FOR (fornum | forlist) END */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 1); /* scope for loop and control variables */ + luaX_next(ls); /* skip 'for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) { + case '=': fornum(ls, varname, line); break; + case ',': case TK_IN: forlist(ls, varname); break; + default: luaX_syntaxerror(ls, "'=' or 'in' expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); /* loop scope ('break' jumps to this point) */ +} + + +static void test_then_block (LexState *ls, int *escapelist) { + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + BlockCnt bl; + FuncState *fs = ls->fs; + expdesc v; + int jf; /* instruction to skip 'then' code (if condition is false) */ + luaX_next(ls); /* skip IF or ELSEIF */ + expr(ls, &v); /* read condition */ + checknext(ls, TK_THEN); + if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) { + luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ + enterblock(fs, &bl, 0); /* must enter block before 'goto' */ + gotostat(ls, v.t); /* handle goto/break */ + skipnoopstat(ls); /* skip other no-op statements */ + if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ + leaveblock(fs); + return; /* and that is it */ + } + else /* must skip over 'then' part if condition is false */ + jf = luaK_jump(fs); + } + else { /* regular case (not goto/break) */ + luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ + enterblock(fs, &bl, 0); + jf = v.f; + } + statlist(ls); /* 'then' part */ + leaveblock(fs); + if (ls->t.token == TK_ELSE || + ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ + luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ + luaK_patchtohere(fs, jf); +} + + +static void ifstat (LexState *ls, int line) { + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + int escapelist = NO_JUMP; /* exit list for finished parts */ + test_then_block(ls, &escapelist); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) + test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ + if (testnext(ls, TK_ELSE)) + block(ls); /* 'else' part */ + check_match(ls, TK_END, TK_IF, line); + luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ +} + + +static void localfunc (LexState *ls) { + expdesc b; + FuncState *fs = ls->fs; + new_localvar(ls, str_checkname(ls)); /* new local variable */ + adjustlocalvars(ls, 1); /* enter its scope */ + body(ls, &b, 0, ls->linenumber); /* function created in next register */ + /* debug information will only see the variable after this point! */ + getlocvar(fs, b.u.info)->startpc = fs->pc; +} + + +static void localstat (LexState *ls) { + /* stat -> LOCAL NAME {',' NAME} ['=' explist] */ + int nvars = 0; + int nexps; + expdesc e; + do { + new_localvar(ls, str_checkname(ls)); + nvars++; + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist(ls, &e); + else { + e.k = VVOID; + nexps = 0; + } + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); +} + + +static int funcname (LexState *ls, expdesc *v) { + /* funcname -> NAME {fieldsel} [':' NAME] */ + int ismethod = 0; + singlevar(ls, v); + while (ls->t.token == '.') + fieldsel(ls, v); + if (ls->t.token == ':') { + ismethod = 1; + fieldsel(ls, v); + } + return ismethod; +} + + +static void funcstat (LexState *ls, int line) { + /* funcstat -> FUNCTION funcname body */ + int ismethod; + expdesc v, b; + luaX_next(ls); /* skip FUNCTION */ + ismethod = funcname(ls, &v); + body(ls, &b, ismethod, line); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition "happens" in the first line */ +} + + +static void exprstat (LexState *ls) { + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + suffixedexp(ls, &v.v); + if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ + v.prev = NULL; + assignment(ls, &v, 1); + } + else { /* stat -> func */ + check_condition(ls, v.v.k == VCALL, "syntax error"); + SETARG_C(getinstruction(fs, &v.v), 1); /* call statement uses no results */ + } +} + + +static void retstat (LexState *ls) { + /* stat -> RETURN [explist] [';'] */ + FuncState *fs = ls->fs; + expdesc e; + int first, nret; /* registers with returned values */ + if (block_follow(ls, 1) || ls->t.token == ';') + first = nret = 0; /* return no values */ + else { + nret = explist(ls, &e); /* optional return values */ + if (hasmultret(e.k)) { + luaK_setmultret(fs, &e); + if (e.k == VCALL && nret == 1) { /* tail call? */ + SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL); + lua_assert(GETARG_A(getinstruction(fs,&e)) == fs->nactvar); + } + first = fs->nactvar; + nret = LUA_MULTRET; /* return all values */ + } + else { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); + else { + luaK_exp2nextreg(fs, &e); /* values must go to the stack */ + first = fs->nactvar; /* return all active values */ + lua_assert(nret == fs->freereg - first); + } + } + } + luaK_ret(fs, first, nret); + testnext(ls, ';'); /* skip optional semicolon */ +} + + +static void statement (LexState *ls) { + int line = ls->linenumber; /* may be needed for error messages */ + enterlevel(ls); + switch (ls->t.token) { + case ';': { /* stat -> ';' (empty statement) */ + luaX_next(ls); /* skip ';' */ + break; + } + case TK_IF: { /* stat -> ifstat */ + ifstat(ls, line); + break; + } + case TK_WHILE: { /* stat -> whilestat */ + whilestat(ls, line); + break; + } + case TK_DO: { /* stat -> DO block END */ + luaX_next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + break; + } + case TK_FOR: { /* stat -> forstat */ + forstat(ls, line); + break; + } + case TK_REPEAT: { /* stat -> repeatstat */ + repeatstat(ls, line); + break; + } + case TK_FUNCTION: { /* stat -> funcstat */ + funcstat(ls, line); + break; + } + case TK_LOCAL: { /* stat -> localstat */ + luaX_next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + break; + } + case TK_DBCOLON: { /* stat -> label */ + luaX_next(ls); /* skip double colon */ + labelstat(ls, str_checkname(ls), line); + break; + } + case TK_RETURN: { /* stat -> retstat */ + luaX_next(ls); /* skip RETURN */ + retstat(ls); + break; + } + case TK_BREAK: /* stat -> breakstat */ + case TK_GOTO: { /* stat -> 'goto' NAME */ + gotostat(ls, luaK_jump(ls->fs)); + break; + } + default: { /* stat -> func | assignment */ + exprstat(ls); + break; + } + } + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && + ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ + leavelevel(ls); +} + +/* }====================================================================== */ + + +/* +** compiles the main function, which is a regular vararg function with an +** upvalue named LUA_ENV +*/ +static void mainfunc (LexState *ls, FuncState *fs) { + BlockCnt bl; + expdesc v; + open_func(ls, fs, &bl); + fs->f->is_vararg = 1; /* main function is always declared vararg */ + init_exp(&v, VLOCAL, 0); /* create and... */ + newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ + luaX_next(ls); /* read first token */ + statlist(ls); /* parse main body */ + check(ls, TK_EOS); + close_func(ls); +} + + +LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar) { + LexState lexstate; + FuncState funcstate; + LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ + setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */ + luaD_inctop(L); + lexstate.h = luaH_new(L); /* create table for scanner */ + sethvalue(L, L->top, lexstate.h); /* anchor it */ + luaD_inctop(L); + funcstate.f = cl->p = luaF_newproto(L); + funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ + lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ + lexstate.buff = buff; + lexstate.dyd = dyd; + dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; + luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar); + mainfunc(&lexstate, &funcstate); + lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); + /* all scopes should be correctly finished */ + lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); + L->top--; /* remove scanner's table */ + return cl; /* closure is on the stack, too */ +} + diff --git a/3rd/lua-5.3.4/lparser.h b/3rd/lua-5.3.4/lparser.h new file mode 100644 index 0000000..02e9b03 --- /dev/null +++ b/3rd/lua-5.3.4/lparser.h @@ -0,0 +1,133 @@ +/* +** $Id: lparser.h,v 1.76 2015/12/30 18:16:13 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* +** Expression and variable descriptor. +** Code generation for variables and expressions can be delayed to allow +** optimizations; An 'expdesc' structure describes a potentially-delayed +** variable/expression. It has a description of its "main" value plus a +** list of conditional jumps that can also produce its value (generated +** by short-circuit operators 'and'/'or'). +*/ + +/* kinds of variables/expressions */ +typedef enum { + VVOID, /* when 'expdesc' describes the last expression a list, + this kind means an empty list (so, no expression) */ + VNIL, /* constant nil */ + VTRUE, /* constant true */ + VFALSE, /* constant false */ + VK, /* constant in 'k'; info = index of constant in 'k' */ + VKFLT, /* floating constant; nval = numerical float value */ + VKINT, /* integer constant; nval = numerical integer value */ + VNONRELOC, /* expression has its value in a fixed register; + info = result register */ + VLOCAL, /* local variable; info = local register */ + VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ + VINDEXED, /* indexed variable; + ind.vt = whether 't' is register or upvalue; + ind.t = table register or upvalue; + ind.idx = key's R/K index */ + VJMP, /* expression is a test/comparison; + info = pc of corresponding jump instruction */ + VRELOCABLE, /* expression can put result in any register; + info = instruction pc */ + VCALL, /* expression is a function call; info = instruction pc */ + VVARARG /* vararg expression; info = instruction pc */ +} expkind; + + +#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) +#define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) + +typedef struct expdesc { + expkind k; + union { + lua_Integer ival; /* for VKINT */ + lua_Number nval; /* for VKFLT */ + int info; /* for generic use */ + struct { /* for indexed variables (VINDEXED) */ + short idx; /* index (R/K) */ + lu_byte t; /* table (register or upvalue) */ + lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ + } ind; + } u; + int t; /* patch list of 'exit when true' */ + int f; /* patch list of 'exit when false' */ +} expdesc; + + +/* description of active local variable */ +typedef struct Vardesc { + short idx; /* variable index in stack */ +} Vardesc; + + +/* description of pending goto statements and label statements */ +typedef struct Labeldesc { + TString *name; /* label identifier */ + int pc; /* position in code */ + int line; /* line where it appeared */ + lu_byte nactvar; /* local level where it appears in current block */ +} Labeldesc; + + +/* list of labels or gotos */ +typedef struct Labellist { + Labeldesc *arr; /* array */ + int n; /* number of entries in use */ + int size; /* array size */ +} Labellist; + + +/* dynamic structures used by the parser */ +typedef struct Dyndata { + struct { /* list of active local variables */ + Vardesc *arr; + int n; + int size; + } actvar; + Labellist gt; /* list of pending gotos */ + Labellist label; /* list of active labels */ +} Dyndata; + + +/* control of blocks */ +struct BlockCnt; /* defined in lparser.c */ + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to 'ncode') */ + int lasttarget; /* 'label' of last 'jump label' */ + int jpc; /* list of pending jumps to 'pc' */ + int nk; /* number of elements in 'k' */ + int np; /* number of elements in 'p' */ + int firstlocal; /* index of first local var (in Dyndata array) */ + short nlocvars; /* number of elements in 'f->locvars' */ + lu_byte nactvar; /* number of active local variables */ + lu_byte nups; /* number of upvalues */ + lu_byte freereg; /* first free register */ +} FuncState; + + +LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar); + + +#endif diff --git a/3rd/lua-5.3.4/lprefix.h b/3rd/lua-5.3.4/lprefix.h new file mode 100644 index 0000000..02daa83 --- /dev/null +++ b/3rd/lua-5.3.4/lprefix.h @@ -0,0 +1,45 @@ +/* +** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $ +** Definitions for Lua code that must come before any other header file +** See Copyright Notice in lua.h +*/ + +#ifndef lprefix_h +#define lprefix_h + + +/* +** Allows POSIX/XSI stuff +*/ +#if !defined(LUA_USE_C89) /* { */ + +#if !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE 600 +#elif _XOPEN_SOURCE == 0 +#undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ +#endif + +/* +** Allows manipulation of large files in gcc and some other compilers +*/ +#if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) +#define _LARGEFILE_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#endif + +#endif /* } */ + + +/* +** Windows stuff +*/ +#if defined(_WIN32) /* { */ + +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ +#endif + +#endif /* } */ + +#endif + diff --git a/3rd/lua-5.3.4/lstate.c b/3rd/lua-5.3.4/lstate.c new file mode 100644 index 0000000..9194ac3 --- /dev/null +++ b/3rd/lua-5.3.4/lstate.c @@ -0,0 +1,347 @@ +/* +** $Id: lstate.c,v 2.133 2015/11/13 12:16:51 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + +#define lstate_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#if !defined(LUAI_GCPAUSE) +#define LUAI_GCPAUSE 200 /* 200% */ +#endif + +#if !defined(LUAI_GCMUL) +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ +#endif + + +/* +** a macro to help the creation of a unique random seed when a state is +** created; the seed is used to randomize hashes. +*/ +#if !defined(luai_makeseed) +#include +#define luai_makeseed() cast(unsigned int, time(NULL)) +#endif + + + +/* +** thread state + extra space +*/ +typedef struct LX { + lu_byte extra_[LUA_EXTRASPACE]; + lua_State l; +} LX; + + +/* +** Main thread combines a thread state and the global state +*/ +typedef struct LG { + LX l; + global_State g; +} LG; + + + +#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) + + +/* +** Compute an initial seed as random as possible. Rely on Address Space +** Layout Randomization (if present) to increase randomness.. +*/ +#define addbuff(b,p,e) \ + { size_t t = cast(size_t, e); \ + memcpy(b + p, &t, sizeof(t)); p += sizeof(t); } + +static unsigned int makeseed (lua_State *L) { + char buff[4 * sizeof(size_t)]; + unsigned int h = luai_makeseed(); + int p = 0; + addbuff(buff, p, L); /* heap variable */ + addbuff(buff, p, &h); /* local variable */ + addbuff(buff, p, luaO_nilobject); /* global variable */ + addbuff(buff, p, &lua_newstate); /* public function */ + lua_assert(p == sizeof(buff)); + return luaS_hash(buff, p, h); +} + + +/* +** set GCdebt to a new value keeping the value (totalbytes + GCdebt) +** invariant (and avoiding underflows in 'totalbytes') +*/ +void luaE_setdebt (global_State *g, l_mem debt) { + l_mem tb = gettotalbytes(g); + lua_assert(tb > 0); + if (debt < tb - MAX_LMEM) + debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */ + g->totalbytes = tb - debt; + g->GCdebt = debt; +} + + +CallInfo *luaE_extendCI (lua_State *L) { + CallInfo *ci = luaM_new(L, CallInfo); + lua_assert(L->ci->next == NULL); + L->ci->next = ci; + ci->previous = L->ci; + ci->next = NULL; + L->nci++; + return ci; +} + + +/* +** free all CallInfo structures not in use by a thread +*/ +void luaE_freeCI (lua_State *L) { + CallInfo *ci = L->ci; + CallInfo *next = ci->next; + ci->next = NULL; + while ((ci = next) != NULL) { + next = ci->next; + luaM_free(L, ci); + L->nci--; + } +} + + +/* +** free half of the CallInfo structures not in use by a thread +*/ +void luaE_shrinkCI (lua_State *L) { + CallInfo *ci = L->ci; + CallInfo *next2; /* next's next */ + /* while there are two nexts */ + while (ci->next != NULL && (next2 = ci->next->next) != NULL) { + luaM_free(L, ci->next); /* free next */ + L->nci--; + ci->next = next2; /* remove 'next' from the list */ + next2->previous = ci; + ci = next2; /* keep next's next */ + } +} + + +static void stack_init (lua_State *L1, lua_State *L) { + int i; CallInfo *ci; + /* initialize stack array */ + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); + L1->stacksize = BASIC_STACK_SIZE; + for (i = 0; i < BASIC_STACK_SIZE; i++) + setnilvalue(L1->stack + i); /* erase new stack */ + L1->top = L1->stack; + L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; + /* initialize first ci */ + ci = &L1->base_ci; + ci->next = ci->previous = NULL; + ci->callstatus = 0; + ci->func = L1->top; + setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ + ci->top = L1->top + LUA_MINSTACK; + L1->ci = ci; +} + + +static void freestack (lua_State *L) { + if (L->stack == NULL) + return; /* stack not completely built yet */ + L->ci = &L->base_ci; /* free the entire 'ci' list */ + luaE_freeCI(L); + lua_assert(L->nci == 0); + luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ +} + + +/* +** Create registry table and its predefined values +*/ +static void init_registry (lua_State *L, global_State *g) { + TValue temp; + /* create registry */ + Table *registry = luaH_new(L); + sethvalue(L, &g->l_registry, registry); + luaH_resize(L, registry, LUA_RIDX_LAST, 0); + /* registry[LUA_RIDX_MAINTHREAD] = L */ + setthvalue(L, &temp, L); /* temp = L */ + luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp); + /* registry[LUA_RIDX_GLOBALS] = table of globals */ + sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */ + luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp); +} + + +/* +** open parts of the state that may cause memory-allocation errors. +** ('g->version' != NULL flags that the state was completely build) +*/ +static void f_luaopen (lua_State *L, void *ud) { + global_State *g = G(L); + UNUSED(ud); + stack_init(L, L); /* init stack */ + init_registry(L, g); + luaS_init(L); + luaT_init(L); + luaX_init(L); + g->gcrunning = 1; /* allow gc */ + g->version = lua_version(NULL); + luai_userstateopen(L); +} + + +/* +** preinitialize a thread with consistent values without allocating +** any memory (to avoid errors) +*/ +static void preinit_thread (lua_State *L, global_State *g) { + G(L) = g; + L->stack = NULL; + L->ci = NULL; + L->nci = 0; + L->stacksize = 0; + L->twups = L; /* thread has no upvalues */ + L->errorJmp = NULL; + L->nCcalls = 0; + L->hook = NULL; + L->hookmask = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->nny = 1; + L->status = LUA_OK; + L->errfunc = 0; +} + + +static void close_state (lua_State *L) { + global_State *g = G(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_freeallobjects(L); /* collect all objects */ + if (g->version) /* closing a fully built state? */ + luai_userstateclose(L); + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); + freestack(L); + lua_assert(gettotalbytes(g) == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ +} + + +LUA_API lua_State *lua_newthread (lua_State *L) { + global_State *g = G(L); + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + /* create new thread */ + L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l; + L1->marked = luaC_white(g); + L1->tt = LUA_TTHREAD; + /* link it on list 'allgc' */ + L1->next = g->allgc; + g->allgc = obj2gco(L1); + /* anchor it on L stack */ + setthvalue(L, L->top, L1); + api_incr_top(L); + preinit_thread(L1, g); + L1->hookmask = L->hookmask; + L1->basehookcount = L->basehookcount; + L1->hook = L->hook; + resethookcount(L1); + /* initialize L1 extra space */ + memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread), + LUA_EXTRASPACE); + luai_userstatethread(L, L1); + stack_init(L1, L); /* init stack */ + lua_unlock(L); + return L1; +} + + +void luaE_freethread (lua_State *L, lua_State *L1) { + LX *l = fromstate(L1); + luaF_close(L1, L1->stack); /* close all upvalues for this thread */ + lua_assert(L1->openupval == NULL); + luai_userstatefree(L, L1); + freestack(L1); + luaM_free(L, l); +} + + +LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { + int i; + lua_State *L; + global_State *g; + LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); + if (l == NULL) return NULL; + L = &l->l.l; + g = &l->g; + L->next = NULL; + L->tt = LUA_TTHREAD; + g->currentwhite = bitmask(WHITE0BIT); + L->marked = luaC_white(g); + preinit_thread(L, g); + g->frealloc = f; + g->ud = ud; + g->mainthread = L; + g->seed = makeseed(L); + g->gcrunning = 0; /* no GC while building state */ + g->GCestimate = 0; + g->strt.size = g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(&g->l_registry); + g->panic = NULL; + g->version = NULL; + g->gcstate = GCSpause; + g->gckind = KGC_NORMAL; + g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL; + g->sweepgc = NULL; + g->gray = g->grayagain = NULL; + g->weak = g->ephemeron = g->allweak = NULL; + g->twups = NULL; + g->totalbytes = sizeof(LG); + g->GCdebt = 0; + g->gcfinnum = 0; + g->gcpause = LUAI_GCPAUSE; + g->gcstepmul = LUAI_GCMUL; + for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + return L; +} + + +LUA_API void lua_close (lua_State *L) { + L = G(L)->mainthread; /* only the main thread can be closed */ + lua_lock(L); + close_state(L); +} + + diff --git a/3rd/lua-5.3.4/lstate.h b/3rd/lua-5.3.4/lstate.h new file mode 100644 index 0000000..a469466 --- /dev/null +++ b/3rd/lua-5.3.4/lstate.h @@ -0,0 +1,235 @@ +/* +** $Id: lstate.h,v 2.133 2016/12/22 13:08:50 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lua.h" + +#include "lobject.h" +#include "ltm.h" +#include "lzio.h" + + +/* + +** Some notes about garbage-collected objects: All objects in Lua must +** be kept somehow accessible until being freed, so all objects always +** belong to one (and only one) of these lists, using field 'next' of +** the 'CommonHeader' for the link: +** +** 'allgc': all objects not marked for finalization; +** 'finobj': all objects marked for finalization; +** 'tobefnz': all objects ready to be finalized; +** 'fixedgc': all objects that are not to be collected (currently +** only small strings, such as reserved words). + +*/ + + +struct lua_longjmp; /* defined in ldo.c */ + + +/* +** Atomic type (relative to signals) to better ensure that 'lua_sethook' +** is thread safe +*/ +#if !defined(l_signalT) +#include +#define l_signalT sig_atomic_t +#endif + + +/* extra stack space to handle TM calls and some other extras */ +#define EXTRA_STACK 5 + + +#define BASIC_STACK_SIZE (2*LUA_MINSTACK) + + +/* kinds of Garbage Collection */ +#define KGC_NORMAL 0 +#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ + + +typedef struct stringtable { + TString **hash; + int nuse; /* number of elements */ + int size; +} stringtable; + + +/* +** Information about a call. +** When a thread yields, 'func' is adjusted to pretend that the +** top function has only the yielded values in its stack; in that +** case, the actual 'func' value is saved in field 'extra'. +** When a function calls another with a continuation, 'extra' keeps +** the function index so that, in case of errors, the continuation +** function can be called with the correct top. +*/ +typedef struct CallInfo { + StkId func; /* function index in the stack */ + StkId top; /* top for this function */ + struct CallInfo *previous, *next; /* dynamic call link */ + union { + struct { /* only for Lua functions */ + StkId base; /* base for this function */ + const Instruction *savedpc; + } l; + struct { /* only for C functions */ + lua_KFunction k; /* continuation in case of yields */ + ptrdiff_t old_errfunc; + lua_KContext ctx; /* context info. in case of yields */ + } c; + } u; + ptrdiff_t extra; + short nresults; /* expected number of results from this function */ + unsigned short callstatus; +} CallInfo; + + +/* +** Bits in CallInfo status +*/ +#define CIST_OAH (1<<0) /* original value of 'allowhook' */ +#define CIST_LUA (1<<1) /* call is running a Lua function */ +#define CIST_HOOKED (1<<2) /* call is running a debug hook */ +#define CIST_FRESH (1<<3) /* call is running on a fresh invocation + of luaV_execute */ +#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ +#define CIST_TAIL (1<<5) /* call was tail called */ +#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ +#define CIST_LEQ (1<<7) /* using __lt for __le */ +#define CIST_FIN (1<<8) /* call is running a finalizer */ + +#define isLua(ci) ((ci)->callstatus & CIST_LUA) + +/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ +#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) +#define getoah(st) ((st) & CIST_OAH) + + +/* +** 'global state', shared by all threads of this state +*/ +typedef struct global_State { + lua_Alloc frealloc; /* function to reallocate memory */ + void *ud; /* auxiliary data to 'frealloc' */ + l_mem totalbytes; /* number of bytes currently allocated - GCdebt */ + l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ + lu_mem GCmemtrav; /* memory traversed by the GC */ + lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ + stringtable strt; /* hash table for strings */ + TValue l_registry; + unsigned int seed; /* randomized seed for hashes */ + lu_byte currentwhite; + lu_byte gcstate; /* state of garbage collector */ + lu_byte gckind; /* kind of GC running */ + lu_byte gcrunning; /* true if GC is running */ + GCObject *allgc; /* list of all collectable objects */ + GCObject **sweepgc; /* current position of sweep in list */ + GCObject *finobj; /* list of collectable objects with finalizers */ + GCObject *gray; /* list of gray objects */ + GCObject *grayagain; /* list of objects to be traversed atomically */ + GCObject *weak; /* list of tables with weak values */ + GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ + GCObject *allweak; /* list of all-weak tables */ + GCObject *tobefnz; /* list of userdata to be GC */ + GCObject *fixedgc; /* list of objects not to be collected */ + struct lua_State *twups; /* list of threads with open upvalues */ + unsigned int gcfinnum; /* number of finalizers to call in each GC step */ + int gcpause; /* size of pause between successive GCs */ + int gcstepmul; /* GC 'granularity' */ + lua_CFunction panic; /* to be called in unprotected errors */ + struct lua_State *mainthread; + const lua_Number *version; /* pointer to version number */ + TString *memerrmsg; /* memory-error message */ + TString *tmname[TM_N]; /* array with tag-method names */ + struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ + TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ +} global_State; + + +/* +** 'per thread' state +*/ +struct lua_State { + CommonHeader; + unsigned short nci; /* number of items in 'ci' list */ + lu_byte status; + StkId top; /* first free slot in the stack */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + const Instruction *oldpc; /* last pc traced */ + StkId stack_last; /* last free slot in the stack */ + StkId stack; /* stack base */ + UpVal *openupval; /* list of open upvalues in this stack */ + GCObject *gclist; + struct lua_State *twups; /* list of threads with open upvalues */ + struct lua_longjmp *errorJmp; /* current error recover point */ + CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ + volatile lua_Hook hook; + ptrdiff_t errfunc; /* current error handling function (stack index) */ + int stacksize; + int basehookcount; + int hookcount; + unsigned short nny; /* number of non-yieldable calls in stack */ + unsigned short nCcalls; /* number of nested C calls */ + l_signalT hookmask; + lu_byte allowhook; +}; + + +#define G(L) (L->l_G) + + +/* +** Union of all collectable objects (only for conversions) +*/ +union GCUnion { + GCObject gc; /* common header */ + struct TString ts; + struct Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct lua_State th; /* thread */ +}; + + +#define cast_u(o) cast(union GCUnion *, (o)) + +/* macros to convert a GCObject into a specific value */ +#define gco2ts(o) \ + check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) +#define gco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u)) +#define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l)) +#define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c)) +#define gco2cl(o) \ + check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) +#define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h)) +#define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p)) +#define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th)) + + +/* macro to convert a Lua object into a GCObject */ +#define obj2gco(v) \ + check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc))) + + +/* actual number of total bytes allocated */ +#define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt) + +LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); +LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); +LUAI_FUNC void luaE_freeCI (lua_State *L); +LUAI_FUNC void luaE_shrinkCI (lua_State *L); + + +#endif + diff --git a/3rd/lua-5.3.4/lstring.c b/3rd/lua-5.3.4/lstring.c new file mode 100644 index 0000000..9351766 --- /dev/null +++ b/3rd/lua-5.3.4/lstring.c @@ -0,0 +1,248 @@ +/* +** $Id: lstring.c,v 2.56 2015/11/23 11:32:51 roberto Exp $ +** String table (keeps all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#define lstring_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" + + +#define MEMERRMSG "not enough memory" + + +/* +** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to +** compute its hash +*/ +#if !defined(LUAI_HASHLIMIT) +#define LUAI_HASHLIMIT 5 +#endif + + +/* +** equality for long strings +*/ +int luaS_eqlngstr (TString *a, TString *b) { + size_t len = a->u.lnglen; + lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR); + return (a == b) || /* same instance or... */ + ((len == b->u.lnglen) && /* equal length and ... */ + (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ +} + + +unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { + unsigned int h = seed ^ cast(unsigned int, l); + size_t step = (l >> LUAI_HASHLIMIT) + 1; + for (; l >= step; l -= step) + h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); + return h; +} + + +unsigned int luaS_hashlongstr (TString *ts) { + lua_assert(ts->tt == LUA_TLNGSTR); + if (ts->extra == 0) { /* no hash? */ + ts->hash = luaS_hash(getstr(ts), ts->u.lnglen, ts->hash); + ts->extra = 1; /* now it has its hash */ + } + return ts->hash; +} + + +/* +** resizes the string table +*/ +void luaS_resize (lua_State *L, int newsize) { + int i; + stringtable *tb = &G(L)->strt; + if (newsize > tb->size) { /* grow table if needed */ + luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *); + for (i = tb->size; i < newsize; i++) + tb->hash[i] = NULL; + } + for (i = 0; i < tb->size; i++) { /* rehash */ + TString *p = tb->hash[i]; + tb->hash[i] = NULL; + while (p) { /* for each node in the list */ + TString *hnext = p->u.hnext; /* save next */ + unsigned int h = lmod(p->hash, newsize); /* new position */ + p->u.hnext = tb->hash[h]; /* chain it */ + tb->hash[h] = p; + p = hnext; + } + } + if (newsize < tb->size) { /* shrink table if needed */ + /* vanishing slice should be empty */ + lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); + luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *); + } + tb->size = newsize; +} + + +/* +** Clear API string cache. (Entries cannot be empty, so fill them with +** a non-collectable string.) +*/ +void luaS_clearcache (global_State *g) { + int i, j; + for (i = 0; i < STRCACHE_N; i++) + for (j = 0; j < STRCACHE_M; j++) { + if (iswhite(g->strcache[i][j])) /* will entry be collected? */ + g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */ + } +} + + +/* +** Initialize the string table and the string cache +*/ +void luaS_init (lua_State *L) { + global_State *g = G(L); + int i, j; + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ + /* pre-create memory-error message */ + g->memerrmsg = luaS_newliteral(L, MEMERRMSG); + luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ + for (i = 0; i < STRCACHE_N; i++) /* fill cache with valid strings */ + for (j = 0; j < STRCACHE_M; j++) + g->strcache[i][j] = g->memerrmsg; +} + + + +/* +** creates a new string object +*/ +static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) { + TString *ts; + GCObject *o; + size_t totalsize; /* total size of TString object */ + totalsize = sizelstring(l); + o = luaC_newobj(L, tag, totalsize); + ts = gco2ts(o); + ts->hash = h; + ts->extra = 0; + getstr(ts)[l] = '\0'; /* ending 0 */ + return ts; +} + + +TString *luaS_createlngstrobj (lua_State *L, size_t l) { + TString *ts = createstrobj(L, l, LUA_TLNGSTR, G(L)->seed); + ts->u.lnglen = l; + return ts; +} + + +void luaS_remove (lua_State *L, TString *ts) { + stringtable *tb = &G(L)->strt; + TString **p = &tb->hash[lmod(ts->hash, tb->size)]; + while (*p != ts) /* find previous element */ + p = &(*p)->u.hnext; + *p = (*p)->u.hnext; /* remove element from its list */ + tb->nuse--; +} + + +/* +** checks whether short string exists and reuses it or creates a new one +*/ +static TString *internshrstr (lua_State *L, const char *str, size_t l) { + TString *ts; + global_State *g = G(L); + unsigned int h = luaS_hash(str, l, g->seed); + TString **list = &g->strt.hash[lmod(h, g->strt.size)]; + lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ + for (ts = *list; ts != NULL; ts = ts->u.hnext) { + if (l == ts->shrlen && + (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { + /* found! */ + if (isdead(g, ts)) /* dead (but not collected yet)? */ + changewhite(ts); /* resurrect it */ + return ts; + } + } + if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT/2) { + luaS_resize(L, g->strt.size * 2); + list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ + } + ts = createstrobj(L, l, LUA_TSHRSTR, h); + memcpy(getstr(ts), str, l * sizeof(char)); + ts->shrlen = cast_byte(l); + ts->u.hnext = *list; + *list = ts; + g->strt.nuse++; + return ts; +} + + +/* +** new string (with explicit length) +*/ +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + if (l <= LUAI_MAXSHORTLEN) /* short string? */ + return internshrstr(L, str, l); + else { + TString *ts; + if (l >= (MAX_SIZE - sizeof(TString))/sizeof(char)) + luaM_toobig(L); + ts = luaS_createlngstrobj(L, l); + memcpy(getstr(ts), str, l * sizeof(char)); + return ts; + } +} + + +/* +** Create or reuse a zero-terminated string, first checking in the +** cache (using the string address as a key). The cache can contain +** only zero-terminated strings, so it is safe to use 'strcmp' to +** check hits. +*/ +TString *luaS_new (lua_State *L, const char *str) { + unsigned int i = point2uint(str) % STRCACHE_N; /* hash */ + int j; + TString **p = G(L)->strcache[i]; + for (j = 0; j < STRCACHE_M; j++) { + if (strcmp(str, getstr(p[j])) == 0) /* hit? */ + return p[j]; /* that is it */ + } + /* normal route */ + for (j = STRCACHE_M - 1; j > 0; j--) + p[j] = p[j - 1]; /* move out last element */ + /* new element is first in the list */ + p[0] = luaS_newlstr(L, str, strlen(str)); + return p[0]; +} + + +Udata *luaS_newudata (lua_State *L, size_t s) { + Udata *u; + GCObject *o; + if (s > MAX_SIZE - sizeof(Udata)) + luaM_toobig(L); + o = luaC_newobj(L, LUA_TUSERDATA, sizeludata(s)); + u = gco2u(o); + u->len = s; + u->metatable = NULL; + setuservalue(L, u, luaO_nilobject); + return u; +} + diff --git a/3rd/lua-5.3.4/lstring.h b/3rd/lua-5.3.4/lstring.h new file mode 100644 index 0000000..27efd20 --- /dev/null +++ b/3rd/lua-5.3.4/lstring.h @@ -0,0 +1,49 @@ +/* +** $Id: lstring.h,v 1.61 2015/11/03 15:36:01 roberto Exp $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" + + +#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char)) + +#define sizeludata(l) (sizeof(union UUdata) + (l)) +#define sizeudata(u) sizeludata((u)->len) + +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s)/sizeof(char))-1)) + + +/* +** test whether a string is a reserved word +*/ +#define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0) + + +/* +** equality for short strings, which are always internalized +*/ +#define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b)) + + +LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); +LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); +LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); +LUAI_FUNC void luaS_resize (lua_State *L, int newsize); +LUAI_FUNC void luaS_clearcache (global_State *g); +LUAI_FUNC void luaS_init (lua_State *L); +LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); +LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); +LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); + + +#endif diff --git a/3rd/lua-5.3.4/lstrlib.c b/3rd/lua-5.3.4/lstrlib.c new file mode 100644 index 0000000..c7aa755 --- /dev/null +++ b/3rd/lua-5.3.4/lstrlib.c @@ -0,0 +1,1584 @@ +/* +** $Id: lstrlib.c,v 1.254 2016/12/22 13:08:50 roberto Exp $ +** Standard library for string operations and pattern-matching +** See Copyright Notice in lua.h +*/ + +#define lstrlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** maximum number of captures that a pattern can do during +** pattern-matching. This limit is arbitrary, but must fit in +** an unsigned char. +*/ +#if !defined(LUA_MAXCAPTURES) +#define LUA_MAXCAPTURES 32 +#endif + + +/* macro to 'unsign' a character */ +#define uchar(c) ((unsigned char)(c)) + + +/* +** Some sizes are better limited to fit in 'int', but must also fit in +** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.) +*/ +#define MAX_SIZET ((size_t)(~(size_t)0)) + +#define MAXSIZE \ + (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX)) + + + + +static int str_len (lua_State *L) { + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushinteger(L, (lua_Integer)l); + return 1; +} + + +/* translate a relative string position: negative means back from end */ +static lua_Integer posrelat (lua_Integer pos, size_t len) { + if (pos >= 0) return pos; + else if (0u - (size_t)pos > len) return 0; + else return (lua_Integer)len + pos + 1; +} + + +static int str_sub (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + lua_Integer start = posrelat(luaL_checkinteger(L, 2), l); + lua_Integer end = posrelat(luaL_optinteger(L, 3, -1), l); + if (start < 1) start = 1; + if (end > (lua_Integer)l) end = l; + if (start <= end) + lua_pushlstring(L, s + start - 1, (size_t)(end - start) + 1); + else lua_pushliteral(L, ""); + return 1; +} + + +static int str_reverse (lua_State *L) { + size_t l, i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + char *p = luaL_buffinitsize(L, &b, l); + for (i = 0; i < l; i++) + p[i] = s[l - i - 1]; + luaL_pushresultsize(&b, l); + return 1; +} + + +static int str_lower (lua_State *L) { + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + char *p = luaL_buffinitsize(L, &b, l); + for (i=0; i MAXSIZE / n) /* may overflow? */ + return luaL_error(L, "resulting string too large"); + else { + size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep; + luaL_Buffer b; + char *p = luaL_buffinitsize(L, &b, totallen); + while (n-- > 1) { /* first n-1 copies (followed by separator) */ + memcpy(p, s, l * sizeof(char)); p += l; + if (lsep > 0) { /* empty 'memcpy' is not that cheap */ + memcpy(p, sep, lsep * sizeof(char)); + p += lsep; + } + } + memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ + luaL_pushresultsize(&b, totallen); + } + return 1; +} + + +static int str_byte (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + lua_Integer posi = posrelat(luaL_optinteger(L, 2, 1), l); + lua_Integer pose = posrelat(luaL_optinteger(L, 3, posi), l); + int n, i; + if (posi < 1) posi = 1; + if (pose > (lua_Integer)l) pose = l; + if (posi > pose) return 0; /* empty interval; return no values */ + if (pose - posi >= INT_MAX) /* arithmetic overflow? */ + return luaL_error(L, "string slice too long"); + n = (int)(pose - posi) + 1; + luaL_checkstack(L, n, "string slice too long"); + for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED) + return luaL_error(ms->L, "invalid capture index %%%d", l + 1); + return l; +} + + +static int capture_to_close (MatchState *ms) { + int level = ms->level; + for (level--; level>=0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) return level; + return luaL_error(ms->L, "invalid pattern capture"); +} + + +static const char *classend (MatchState *ms, const char *p) { + switch (*p++) { + case L_ESC: { + if (p == ms->p_end) + luaL_error(ms->L, "malformed pattern (ends with '%%')"); + return p+1; + } + case '[': { + if (*p == '^') p++; + do { /* look for a ']' */ + if (p == ms->p_end) + luaL_error(ms->L, "malformed pattern (missing ']')"); + if (*(p++) == L_ESC && p < ms->p_end) + p++; /* skip escapes (e.g. '%]') */ + } while (*p != ']'); + return p+1; + } + default: { + return p; + } + } +} + + +static int match_class (int c, int cl) { + int res; + switch (tolower(cl)) { + case 'a' : res = isalpha(c); break; + case 'c' : res = iscntrl(c); break; + case 'd' : res = isdigit(c); break; + case 'g' : res = isgraph(c); break; + case 'l' : res = islower(c); break; + case 'p' : res = ispunct(c); break; + case 's' : res = isspace(c); break; + case 'u' : res = isupper(c); break; + case 'w' : res = isalnum(c); break; + case 'x' : res = isxdigit(c); break; + case 'z' : res = (c == 0); break; /* deprecated option */ + default: return (cl == c); + } + return (islower(cl) ? res : !res); +} + + +static int matchbracketclass (int c, const char *p, const char *ec) { + int sig = 1; + if (*(p+1) == '^') { + sig = 0; + p++; /* skip the '^' */ + } + while (++p < ec) { + if (*p == L_ESC) { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p+1) == '-') && (p+2 < ec)) { + p+=2; + if (uchar(*(p-2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) return sig; + } + return !sig; +} + + +static int singlematch (MatchState *ms, const char *s, const char *p, + const char *ep) { + if (s >= ms->src_end) + return 0; + else { + int c = uchar(*s); + switch (*p) { + case '.': return 1; /* matches any char */ + case L_ESC: return match_class(c, uchar(*(p+1))); + case '[': return matchbracketclass(c, p, ep-1); + default: return (uchar(*p) == c); + } + } +} + + +static const char *matchbalance (MatchState *ms, const char *s, + const char *p) { + if (p >= ms->p_end - 1) + luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); + if (*s != *p) return NULL; + else { + int b = *p; + int e = *(p+1); + int cont = 1; + while (++s < ms->src_end) { + if (*s == e) { + if (--cont == 0) return s+1; + } + else if (*s == b) cont++; + } + } + return NULL; /* string ends out of balance */ +} + + +static const char *max_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + ptrdiff_t i = 0; /* counts maximum expand for item */ + while (singlematch(ms, s + i, p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i>=0) { + const char *res = match(ms, (s+i), ep+1); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; +} + + +static const char *min_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + for (;;) { + const char *res = match(ms, s, ep+1); + if (res != NULL) + return res; + else if (singlematch(ms, s, p, ep)) + s++; /* try with one more repetition */ + else return NULL; + } +} + + +static const char *start_capture (MatchState *ms, const char *s, + const char *p, int what) { + const char *res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level+1; + if ((res=match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; +} + + +static const char *end_capture (MatchState *ms, const char *s, + const char *p) { + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; +} + + +static const char *match_capture (MatchState *ms, const char *s, int l) { + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end-s) >= len && + memcmp(ms->capture[l].init, s, len) == 0) + return s+len; + else return NULL; +} + + +static const char *match (MatchState *ms, const char *s, const char *p) { + if (ms->matchdepth-- == 0) + luaL_error(ms->L, "pattern too complex"); + init: /* using goto's to optimize tail recursion */ + if (p != ms->p_end) { /* end of pattern? */ + switch (*p) { + case '(': { /* start capture */ + if (*(p + 1) == ')') /* position capture? */ + s = start_capture(ms, s, p + 2, CAP_POSITION); + else + s = start_capture(ms, s, p + 1, CAP_UNFINISHED); + break; + } + case ')': { /* end capture */ + s = end_capture(ms, s, p + 1); + break; + } + case '$': { + if ((p + 1) != ms->p_end) /* is the '$' the last char in pattern? */ + goto dflt; /* no; go to default */ + s = (s == ms->src_end) ? s : NULL; /* check end of string */ + break; + } + case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ + switch (*(p + 1)) { + case 'b': { /* balanced string? */ + s = matchbalance(ms, s, p + 2); + if (s != NULL) { + p += 4; goto init; /* return match(ms, s, p + 4); */ + } /* else fail (s == NULL) */ + break; + } + case 'f': { /* frontier? */ + const char *ep; char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing '[' after '%%f' in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s - 1); + if (!matchbracketclass(uchar(previous), p, ep - 1) && + matchbracketclass(uchar(*s), p, ep - 1)) { + p = ep; goto init; /* return match(ms, s, ep); */ + } + s = NULL; /* match failed */ + break; + } + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p + 1))); + if (s != NULL) { + p += 2; goto init; /* return match(ms, s, p + 2) */ + } + break; + } + default: goto dflt; + } + break; + } + default: dflt: { /* pattern class plus optional suffix */ + const char *ep = classend(ms, p); /* points to optional suffix */ + /* does not match at least once? */ + if (!singlematch(ms, s, p, ep)) { + if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */ + p = ep + 1; goto init; /* return match(ms, s, ep + 1); */ + } + else /* '+' or no suffix */ + s = NULL; /* fail */ + } + else { /* matched once */ + switch (*ep) { /* handle optional suffix */ + case '?': { /* optional */ + const char *res; + if ((res = match(ms, s + 1, ep + 1)) != NULL) + s = res; + else { + p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */ + } + break; + } + case '+': /* 1 or more repetitions */ + s++; /* 1 match already done */ + /* FALLTHROUGH */ + case '*': /* 0 or more repetitions */ + s = max_expand(ms, s, p, ep); + break; + case '-': /* 0 or more repetitions (minimum) */ + s = min_expand(ms, s, p, ep); + break; + default: /* no suffix */ + s++; p = ep; goto init; /* return match(ms, s + 1, ep); */ + } + } + break; + } + } + } + ms->matchdepth++; + return s; +} + + + +static const char *lmemfind (const char *s1, size_t l1, + const char *s2, size_t l2) { + if (l2 == 0) return s1; /* empty strings are everywhere */ + else if (l2 > l1) return NULL; /* avoids a negative 'l1' */ + else { + const char *init; /* to search for a '*s2' inside 's1' */ + l2--; /* 1st char will be checked by 'memchr' */ + l1 = l1-l2; /* 's2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { + init++; /* 1st char is already checked */ + if (memcmp(init, s2+1, l2) == 0) + return init-1; + else { /* correct 'l1' and 's1' to try again */ + l1 -= init-s1; + s1 = init; + } + } + return NULL; /* not found */ + } +} + + +static void push_onecapture (MatchState *ms, int i, const char *s, + const char *e) { + if (i >= ms->level) { + if (i == 0) /* ms->level == 0, too */ + lua_pushlstring(ms->L, s, e - s); /* add whole match */ + else + luaL_error(ms->L, "invalid capture index %%%d", i + 1); + } + else { + ptrdiff_t l = ms->capture[i].len; + if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); + if (l == CAP_POSITION) + lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); + else + lua_pushlstring(ms->L, ms->capture[i].init, l); + } +} + + +static int push_captures (MatchState *ms, const char *s, const char *e) { + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) + push_onecapture(ms, i, s, e); + return nlevels; /* number of strings pushed */ +} + + +/* check whether pattern has no special characters */ +static int nospecials (const char *p, size_t l) { + size_t upto = 0; + do { + if (strpbrk(p + upto, SPECIALS)) + return 0; /* pattern has a special character */ + upto += strlen(p + upto) + 1; /* may have more after \0 */ + } while (upto <= l); + return 1; /* no special chars found */ +} + + +static void prepstate (MatchState *ms, lua_State *L, + const char *s, size_t ls, const char *p, size_t lp) { + ms->L = L; + ms->matchdepth = MAXCCALLS; + ms->src_init = s; + ms->src_end = s + ls; + ms->p_end = p + lp; +} + + +static void reprepstate (MatchState *ms) { + ms->level = 0; + lua_assert(ms->matchdepth == MAXCCALLS); +} + + +static int str_find_aux (lua_State *L, int find) { + size_t ls, lp; + const char *s = luaL_checklstring(L, 1, &ls); + const char *p = luaL_checklstring(L, 2, &lp); + lua_Integer init = posrelat(luaL_optinteger(L, 3, 1), ls); + if (init < 1) init = 1; + else if (init > (lua_Integer)ls + 1) { /* start after string's end? */ + lua_pushnil(L); /* cannot find anything */ + return 1; + } + /* explicit request or no special characters? */ + if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { + /* do a plain search */ + const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp); + if (s2) { + lua_pushinteger(L, (s2 - s) + 1); + lua_pushinteger(L, (s2 - s) + lp); + return 2; + } + } + else { + MatchState ms; + const char *s1 = s + init - 1; + int anchor = (*p == '^'); + if (anchor) { + p++; lp--; /* skip anchor character */ + } + prepstate(&ms, L, s, ls, p, lp); + do { + const char *res; + reprepstate(&ms); + if ((res=match(&ms, s1, p)) != NULL) { + if (find) { + lua_pushinteger(L, (s1 - s) + 1); /* start */ + lua_pushinteger(L, res - s); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + lua_pushnil(L); /* not found */ + return 1; +} + + +static int str_find (lua_State *L) { + return str_find_aux(L, 1); +} + + +static int str_match (lua_State *L) { + return str_find_aux(L, 0); +} + + +/* state for 'gmatch' */ +typedef struct GMatchState { + const char *src; /* current position */ + const char *p; /* pattern */ + const char *lastmatch; /* end of last match */ + MatchState ms; /* match state */ +} GMatchState; + + +static int gmatch_aux (lua_State *L) { + GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3)); + const char *src; + gm->ms.L = L; + for (src = gm->src; src <= gm->ms.src_end; src++) { + const char *e; + reprepstate(&gm->ms); + if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) { + gm->src = gm->lastmatch = e; + return push_captures(&gm->ms, src, e); + } + } + return 0; /* not found */ +} + + +static int gmatch (lua_State *L) { + size_t ls, lp; + const char *s = luaL_checklstring(L, 1, &ls); + const char *p = luaL_checklstring(L, 2, &lp); + GMatchState *gm; + lua_settop(L, 2); /* keep them on closure to avoid being collected */ + gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState)); + prepstate(&gm->ms, L, s, ls, p, lp); + gm->src = s; gm->p = p; gm->lastmatch = NULL; + lua_pushcclosure(L, gmatch_aux, 3); + return 1; +} + + +static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + size_t l, i; + lua_State *L = ms->L; + const char *news = lua_tolstring(L, 3, &l); + for (i = 0; i < l; i++) { + if (news[i] != L_ESC) + luaL_addchar(b, news[i]); + else { + i++; /* skip ESC */ + if (!isdigit(uchar(news[i]))) { + if (news[i] != L_ESC) + luaL_error(L, "invalid use of '%c' in replacement string", L_ESC); + luaL_addchar(b, news[i]); + } + else if (news[i] == '0') + luaL_addlstring(b, s, e - s); + else { + push_onecapture(ms, news[i] - '1', s, e); + luaL_tolstring(L, -1, NULL); /* if number, convert it to string */ + lua_remove(L, -2); /* remove original value */ + luaL_addvalue(b); /* add capture to accumulated result */ + } + } + } +} + + +static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e, int tr) { + lua_State *L = ms->L; + switch (tr) { + case LUA_TFUNCTION: { + int n; + lua_pushvalue(L, 3); + n = push_captures(ms, s, e); + lua_call(L, n, 1); + break; + } + case LUA_TTABLE: { + push_onecapture(ms, 0, s, e); + lua_gettable(L, 3); + break; + } + default: { /* LUA_TNUMBER or LUA_TSTRING */ + add_s(ms, b, s, e); + return; + } + } + if (!lua_toboolean(L, -1)) { /* nil or false? */ + lua_pop(L, 1); + lua_pushlstring(L, s, e - s); /* keep original text */ + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_addvalue(b); /* add result to accumulator */ +} + + +static int str_gsub (lua_State *L) { + size_t srcl, lp; + const char *src = luaL_checklstring(L, 1, &srcl); /* subject */ + const char *p = luaL_checklstring(L, 2, &lp); /* pattern */ + const char *lastmatch = NULL; /* end of last match */ + int tr = lua_type(L, 3); /* replacement type */ + lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ + int anchor = (*p == '^'); + lua_Integer n = 0; /* replacement count */ + MatchState ms; + luaL_Buffer b; + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table expected"); + luaL_buffinit(L, &b); + if (anchor) { + p++; lp--; /* skip anchor character */ + } + prepstate(&ms, L, src, srcl, p, lp); + while (n < max_s) { + const char *e; + reprepstate(&ms); /* (re)prepare state for new match */ + if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */ + n++; + add_value(&ms, &b, src, e, tr); /* add replacement to buffer */ + src = lastmatch = e; + } + else if (src < ms.src_end) /* otherwise, skip one character */ + luaL_addchar(&b, *src++); + else break; /* end of subject */ + if (anchor) break; + } + luaL_addlstring(&b, src, ms.src_end-src); + luaL_pushresult(&b); + lua_pushinteger(L, n); /* number of substitutions */ + return 2; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** STRING FORMAT +** ======================================================= +*/ + +#if !defined(lua_number2strx) /* { */ + +/* +** Hexadecimal floating-point formatter +*/ + +#include + +#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char)) + + +/* +** Number of bits that goes into the first digit. It can be any value +** between 1 and 4; the following definition tries to align the number +** to nibble boundaries by making what is left after that first digit a +** multiple of 4. +*/ +#define L_NBFD ((l_mathlim(MANT_DIG) - 1)%4 + 1) + + +/* +** Add integer part of 'x' to buffer and return new 'x' +*/ +static lua_Number adddigit (char *buff, int n, lua_Number x) { + lua_Number dd = l_mathop(floor)(x); /* get integer part from 'x' */ + int d = (int)dd; + buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */ + return x - dd; /* return what is left */ +} + + +static int num2straux (char *buff, int sz, lua_Number x) { + /* if 'inf' or 'NaN', format it like '%g' */ + if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL) + return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x); + else if (x == 0) { /* can be -0... */ + /* create "0" or "-0" followed by exponent */ + return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x); + } + else { + int e; + lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */ + int n = 0; /* character count */ + if (m < 0) { /* is number negative? */ + buff[n++] = '-'; /* add signal */ + m = -m; /* make it positive */ + } + buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */ + m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */ + e -= L_NBFD; /* this digit goes before the radix point */ + if (m > 0) { /* more digits? */ + buff[n++] = lua_getlocaledecpoint(); /* add radix point */ + do { /* add as many digits as needed */ + m = adddigit(buff, n++, m * 16); + } while (m > 0); + } + n += l_sprintf(buff + n, sz - n, "p%+d", e); /* add exponent */ + lua_assert(n < sz); + return n; + } +} + + +static int lua_number2strx (lua_State *L, char *buff, int sz, + const char *fmt, lua_Number x) { + int n = num2straux(buff, sz, x); + if (fmt[SIZELENMOD] == 'A') { + int i; + for (i = 0; i < n; i++) + buff[i] = toupper(uchar(buff[i])); + } + else if (fmt[SIZELENMOD] != 'a') + luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); + return n; +} + +#endif /* } */ + + +/* +** Maximum size of each formatted item. This maximum size is produced +** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.', +** and '\0') + number of decimal digits to represent maxfloat (which +** is maximum exponent + 1). (99+3+1 then rounded to 120 for "extra +** expenses", such as locale-dependent stuff) +*/ +#define MAX_ITEM (120 + l_mathlim(MAX_10_EXP)) + + +/* valid flags in a format specification */ +#define FLAGS "-+ #0" + +/* +** maximum size of each format specification (such as "%-099.99d") +*/ +#define MAX_FORMAT 32 + + +static void addquoted (luaL_Buffer *b, const char *s, size_t len) { + luaL_addchar(b, '"'); + while (len--) { + if (*s == '"' || *s == '\\' || *s == '\n') { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + } + else if (iscntrl(uchar(*s))) { + char buff[10]; + if (!isdigit(uchar(*(s+1)))) + l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s)); + else + l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s)); + luaL_addstring(b, buff); + } + else + luaL_addchar(b, *s); + s++; + } + luaL_addchar(b, '"'); +} + + +/* +** Ensures the 'buff' string uses a dot as the radix character. +*/ +static void checkdp (char *buff, int nb) { + if (memchr(buff, '.', nb) == NULL) { /* no dot? */ + char point = lua_getlocaledecpoint(); /* try locale point */ + char *ppoint = (char *)memchr(buff, point, nb); + if (ppoint) *ppoint = '.'; /* change it to a dot */ + } +} + + +static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { + switch (lua_type(L, arg)) { + case LUA_TSTRING: { + size_t len; + const char *s = lua_tolstring(L, arg, &len); + addquoted(b, s, len); + break; + } + case LUA_TNUMBER: { + char *buff = luaL_prepbuffsize(b, MAX_ITEM); + int nb; + if (!lua_isinteger(L, arg)) { /* float? */ + lua_Number n = lua_tonumber(L, arg); /* write as hexa ('%a') */ + nb = lua_number2strx(L, buff, MAX_ITEM, "%" LUA_NUMBER_FRMLEN "a", n); + checkdp(buff, nb); /* ensure it uses a dot */ + } + else { /* integers */ + lua_Integer n = lua_tointeger(L, arg); + const char *format = (n == LUA_MININTEGER) /* corner case? */ + ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hexa */ + : LUA_INTEGER_FMT; /* else use default format */ + nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n); + } + luaL_addsize(b, nb); + break; + } + case LUA_TNIL: case LUA_TBOOLEAN: { + luaL_tolstring(L, arg, NULL); + luaL_addvalue(b); + break; + } + default: { + luaL_argerror(L, arg, "value has no literal form"); + } + } +} + + +static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { + const char *p = strfrmt; + while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ + if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char)) + luaL_error(L, "invalid format (repeated flags)"); + if (isdigit(uchar(*p))) p++; /* skip width */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + if (*p == '.') { + p++; + if (isdigit(uchar(*p))) p++; /* skip precision */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + } + if (isdigit(uchar(*p))) + luaL_error(L, "invalid format (width or precision too long)"); + *(form++) = '%'; + memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char)); + form += (p - strfrmt) + 1; + *form = '\0'; + return p; +} + + +/* +** add length modifier into formats +*/ +static void addlenmod (char *form, const char *lenmod) { + size_t l = strlen(form); + size_t lm = strlen(lenmod); + char spec = form[l - 1]; + strcpy(form + l - 1, lenmod); + form[l + lm - 1] = spec; + form[l + lm] = '\0'; +} + + +static int str_format (lua_State *L) { + int top = lua_gettop(L); + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt+sfl; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); /* %% */ + else { /* format item */ + char form[MAX_FORMAT]; /* to store the format ('%...') */ + char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ + int nb = 0; /* number of bytes in added item */ + if (++arg > top) + luaL_argerror(L, arg, "no value"); + strfrmt = scanformat(L, strfrmt, form); + switch (*strfrmt++) { + case 'c': { + nb = l_sprintf(buff, MAX_ITEM, form, (int)luaL_checkinteger(L, arg)); + break; + } + case 'd': case 'i': + case 'o': case 'u': case 'x': case 'X': { + lua_Integer n = luaL_checkinteger(L, arg); + addlenmod(form, LUA_INTEGER_FRMLEN); + nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACINT)n); + break; + } + case 'a': case 'A': + addlenmod(form, LUA_NUMBER_FRMLEN); + nb = lua_number2strx(L, buff, MAX_ITEM, form, + luaL_checknumber(L, arg)); + break; + case 'e': case 'E': case 'f': + case 'g': case 'G': { + lua_Number n = luaL_checknumber(L, arg); + addlenmod(form, LUA_NUMBER_FRMLEN); + nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n); + break; + } + case 'q': { + addliteral(L, &b, arg); + break; + } + case 's': { + size_t l; + const char *s = luaL_tolstring(L, arg, &l); + if (form[2] == '\0') /* no modifiers? */ + luaL_addvalue(&b); /* keep entire string */ + else { + luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); + if (!strchr(form, '.') && l >= 100) { + /* no precision and string is too long to be formatted */ + luaL_addvalue(&b); /* keep entire string */ + } + else { /* format the string into 'buff' */ + nb = l_sprintf(buff, MAX_ITEM, form, s); + lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ + } + } + break; + } + default: { /* also treat cases 'pnLlh' */ + return luaL_error(L, "invalid option '%%%c' to 'format'", + *(strfrmt - 1)); + } + } + lua_assert(nb < MAX_ITEM); + luaL_addsize(&b, nb); + } + } + luaL_pushresult(&b); + return 1; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** PACK/UNPACK +** ======================================================= +*/ + + +/* value used for padding */ +#if !defined(LUAL_PACKPADBYTE) +#define LUAL_PACKPADBYTE 0x00 +#endif + +/* maximum size for the binary representation of an integer */ +#define MAXINTSIZE 16 + +/* number of bits in a character */ +#define NB CHAR_BIT + +/* mask for one character (NB 1's) */ +#define MC ((1 << NB) - 1) + +/* size of a lua_Integer */ +#define SZINT ((int)sizeof(lua_Integer)) + + +/* dummy union to get native endianness */ +static const union { + int dummy; + char little; /* true iff machine is little endian */ +} nativeendian = {1}; + + +/* dummy structure to get native alignment requirements */ +struct cD { + char c; + union { double d; void *p; lua_Integer i; lua_Number n; } u; +}; + +#define MAXALIGN (offsetof(struct cD, u)) + + +/* +** Union for serializing floats +*/ +typedef union Ftypes { + float f; + double d; + lua_Number n; + char buff[5 * sizeof(lua_Number)]; /* enough for any float type */ +} Ftypes; + + +/* +** information to pack/unpack stuff +*/ +typedef struct Header { + lua_State *L; + int islittle; + int maxalign; +} Header; + + +/* +** options for pack/unpack +*/ +typedef enum KOption { + Kint, /* signed integers */ + Kuint, /* unsigned integers */ + Kfloat, /* floating-point numbers */ + Kchar, /* fixed-length strings */ + Kstring, /* strings with prefixed length */ + Kzstr, /* zero-terminated strings */ + Kpadding, /* padding */ + Kpaddalign, /* padding for alignment */ + Knop /* no-op (configuration or spaces) */ +} KOption; + + +/* +** Read an integer numeral from string 'fmt' or return 'df' if +** there is no numeral +*/ +static int digit (int c) { return '0' <= c && c <= '9'; } + +static int getnum (const char **fmt, int df) { + if (!digit(**fmt)) /* no number? */ + return df; /* return default value */ + else { + int a = 0; + do { + a = a*10 + (*((*fmt)++) - '0'); + } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10); + return a; + } +} + + +/* +** Read an integer numeral and raises an error if it is larger +** than the maximum size for integers. +*/ +static int getnumlimit (Header *h, const char **fmt, int df) { + int sz = getnum(fmt, df); + if (sz > MAXINTSIZE || sz <= 0) + luaL_error(h->L, "integral size (%d) out of limits [1,%d]", + sz, MAXINTSIZE); + return sz; +} + + +/* +** Initialize Header +*/ +static void initheader (lua_State *L, Header *h) { + h->L = L; + h->islittle = nativeendian.little; + h->maxalign = 1; +} + + +/* +** Read and classify next option. 'size' is filled with option's size. +*/ +static KOption getoption (Header *h, const char **fmt, int *size) { + int opt = *((*fmt)++); + *size = 0; /* default */ + switch (opt) { + case 'b': *size = sizeof(char); return Kint; + case 'B': *size = sizeof(char); return Kuint; + case 'h': *size = sizeof(short); return Kint; + case 'H': *size = sizeof(short); return Kuint; + case 'l': *size = sizeof(long); return Kint; + case 'L': *size = sizeof(long); return Kuint; + case 'j': *size = sizeof(lua_Integer); return Kint; + case 'J': *size = sizeof(lua_Integer); return Kuint; + case 'T': *size = sizeof(size_t); return Kuint; + case 'f': *size = sizeof(float); return Kfloat; + case 'd': *size = sizeof(double); return Kfloat; + case 'n': *size = sizeof(lua_Number); return Kfloat; + case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint; + case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint; + case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; + case 'c': + *size = getnum(fmt, -1); + if (*size == -1) + luaL_error(h->L, "missing size for format option 'c'"); + return Kchar; + case 'z': return Kzstr; + case 'x': *size = 1; return Kpadding; + case 'X': return Kpaddalign; + case ' ': break; + case '<': h->islittle = 1; break; + case '>': h->islittle = 0; break; + case '=': h->islittle = nativeendian.little; break; + case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break; + default: luaL_error(h->L, "invalid format option '%c'", opt); + } + return Knop; +} + + +/* +** Read, classify, and fill other details about the next option. +** 'psize' is filled with option's size, 'notoalign' with its +** alignment requirements. +** Local variable 'size' gets the size to be aligned. (Kpadal option +** always gets its full alignment, other options are limited by +** the maximum alignment ('maxalign'). Kchar option needs no alignment +** despite its size. +*/ +static KOption getdetails (Header *h, size_t totalsize, + const char **fmt, int *psize, int *ntoalign) { + KOption opt = getoption(h, fmt, psize); + int align = *psize; /* usually, alignment follows size */ + if (opt == Kpaddalign) { /* 'X' gets alignment from following option */ + if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0) + luaL_argerror(h->L, 1, "invalid next option for option 'X'"); + } + if (align <= 1 || opt == Kchar) /* need no alignment? */ + *ntoalign = 0; + else { + if (align > h->maxalign) /* enforce maximum alignment */ + align = h->maxalign; + if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */ + luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); + *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); + } + return opt; +} + + +/* +** Pack integer 'n' with 'size' bytes and 'islittle' endianness. +** The final 'if' handles the case when 'size' is larger than +** the size of a Lua integer, correcting the extra sign-extension +** bytes if necessary (by default they would be zeros). +*/ +static void packint (luaL_Buffer *b, lua_Unsigned n, + int islittle, int size, int neg) { + char *buff = luaL_prepbuffsize(b, size); + int i; + buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */ + for (i = 1; i < size; i++) { + n >>= NB; + buff[islittle ? i : size - 1 - i] = (char)(n & MC); + } + if (neg && size > SZINT) { /* negative number need sign extension? */ + for (i = SZINT; i < size; i++) /* correct extra bytes */ + buff[islittle ? i : size - 1 - i] = (char)MC; + } + luaL_addsize(b, size); /* add result to buffer */ +} + + +/* +** Copy 'size' bytes from 'src' to 'dest', correcting endianness if +** given 'islittle' is different from native endianness. +*/ +static void copywithendian (volatile char *dest, volatile const char *src, + int size, int islittle) { + if (islittle == nativeendian.little) { + while (size-- != 0) + *(dest++) = *(src++); + } + else { + dest += size - 1; + while (size-- != 0) + *(dest--) = *(src++); + } +} + + +static int str_pack (lua_State *L) { + luaL_Buffer b; + Header h; + const char *fmt = luaL_checkstring(L, 1); /* format string */ + int arg = 1; /* current argument to pack */ + size_t totalsize = 0; /* accumulate total size of result */ + initheader(L, &h); + lua_pushnil(L); /* mark to separate arguments from string buffer */ + luaL_buffinit(L, &b); + while (*fmt != '\0') { + int size, ntoalign; + KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); + totalsize += ntoalign + size; + while (ntoalign-- > 0) + luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */ + arg++; + switch (opt) { + case Kint: { /* signed integers */ + lua_Integer n = luaL_checkinteger(L, arg); + if (size < SZINT) { /* need overflow check? */ + lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); + luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); + } + packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); + break; + } + case Kuint: { /* unsigned integers */ + lua_Integer n = luaL_checkinteger(L, arg); + if (size < SZINT) /* need overflow check? */ + luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), + arg, "unsigned overflow"); + packint(&b, (lua_Unsigned)n, h.islittle, size, 0); + break; + } + case Kfloat: { /* floating-point options */ + volatile Ftypes u; + char *buff = luaL_prepbuffsize(&b, size); + lua_Number n = luaL_checknumber(L, arg); /* get argument */ + if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ + else if (size == sizeof(u.d)) u.d = (double)n; + else u.n = n; + /* move 'u' to final result, correcting endianness if needed */ + copywithendian(buff, u.buff, size, h.islittle); + luaL_addsize(&b, size); + break; + } + case Kchar: { /* fixed-size string */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, len <= (size_t)size, arg, + "string longer than given size"); + luaL_addlstring(&b, s, len); /* add string */ + while (len++ < (size_t)size) /* pad extra space */ + luaL_addchar(&b, LUAL_PACKPADBYTE); + break; + } + case Kstring: { /* strings with length count */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, size >= (int)sizeof(size_t) || + len < ((size_t)1 << (size * NB)), + arg, "string length does not fit in given size"); + packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ + luaL_addlstring(&b, s, len); + totalsize += len; + break; + } + case Kzstr: { /* zero-terminated string */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); + luaL_addlstring(&b, s, len); + luaL_addchar(&b, '\0'); /* add zero at the end */ + totalsize += len + 1; + break; + } + case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */ + case Kpaddalign: case Knop: + arg--; /* undo increment */ + break; + } + } + luaL_pushresult(&b); + return 1; +} + + +static int str_packsize (lua_State *L) { + Header h; + const char *fmt = luaL_checkstring(L, 1); /* format string */ + size_t totalsize = 0; /* accumulate total size of result */ + initheader(L, &h); + while (*fmt != '\0') { + int size, ntoalign; + KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); + size += ntoalign; /* total space used by option */ + luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, + "format result too large"); + totalsize += size; + switch (opt) { + case Kstring: /* strings with length count */ + case Kzstr: /* zero-terminated string */ + luaL_argerror(L, 1, "variable-length format"); + /* call never return, but to avoid warnings: *//* FALLTHROUGH */ + default: break; + } + } + lua_pushinteger(L, (lua_Integer)totalsize); + return 1; +} + + +/* +** Unpack an integer with 'size' bytes and 'islittle' endianness. +** If size is smaller than the size of a Lua integer and integer +** is signed, must do sign extension (propagating the sign to the +** higher bits); if size is larger than the size of a Lua integer, +** it must check the unread bytes to see whether they do not cause an +** overflow. +*/ +static lua_Integer unpackint (lua_State *L, const char *str, + int islittle, int size, int issigned) { + lua_Unsigned res = 0; + int i; + int limit = (size <= SZINT) ? size : SZINT; + for (i = limit - 1; i >= 0; i--) { + res <<= NB; + res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i]; + } + if (size < SZINT) { /* real size smaller than lua_Integer? */ + if (issigned) { /* needs sign extension? */ + lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1); + res = ((res ^ mask) - mask); /* do sign extension */ + } + } + else if (size > SZINT) { /* must check unread bytes */ + int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; + for (i = limit; i < size; i++) { + if ((unsigned char)str[islittle ? i : size - 1 - i] != mask) + luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); + } + } + return (lua_Integer)res; +} + + +static int str_unpack (lua_State *L) { + Header h; + const char *fmt = luaL_checkstring(L, 1); + size_t ld; + const char *data = luaL_checklstring(L, 2, &ld); + size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1; + int n = 0; /* number of results */ + luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); + initheader(L, &h); + while (*fmt != '\0') { + int size, ntoalign; + KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); + if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) + luaL_argerror(L, 2, "data string too short"); + pos += ntoalign; /* skip alignment */ + /* stack space for item + next position */ + luaL_checkstack(L, 2, "too many results"); + n++; + switch (opt) { + case Kint: + case Kuint: { + lua_Integer res = unpackint(L, data + pos, h.islittle, size, + (opt == Kint)); + lua_pushinteger(L, res); + break; + } + case Kfloat: { + volatile Ftypes u; + lua_Number num; + copywithendian(u.buff, data + pos, size, h.islittle); + if (size == sizeof(u.f)) num = (lua_Number)u.f; + else if (size == sizeof(u.d)) num = (lua_Number)u.d; + else num = u.n; + lua_pushnumber(L, num); + break; + } + case Kchar: { + lua_pushlstring(L, data + pos, size); + break; + } + case Kstring: { + size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); + luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short"); + lua_pushlstring(L, data + pos + size, len); + pos += len; /* skip string */ + break; + } + case Kzstr: { + size_t len = (int)strlen(data + pos); + lua_pushlstring(L, data + pos, len); + pos += len + 1; /* skip string plus final '\0' */ + break; + } + case Kpaddalign: case Kpadding: case Knop: + n--; /* undo increment */ + break; + } + pos += size; + } + lua_pushinteger(L, pos + 1); /* next position */ + return n + 1; +} + +/* }====================================================== */ + + +static const luaL_Reg strlib[] = { + {"byte", str_byte}, + {"char", str_char}, + {"dump", str_dump}, + {"find", str_find}, + {"format", str_format}, + {"gmatch", gmatch}, + {"gsub", str_gsub}, + {"len", str_len}, + {"lower", str_lower}, + {"match", str_match}, + {"rep", str_rep}, + {"reverse", str_reverse}, + {"sub", str_sub}, + {"upper", str_upper}, + {"pack", str_pack}, + {"packsize", str_packsize}, + {"unpack", str_unpack}, + {NULL, NULL} +}; + + +static void createmetatable (lua_State *L) { + lua_createtable(L, 0, 1); /* table to be metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); /* copy table */ + lua_setmetatable(L, -2); /* set table as metatable for strings */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* get string library */ + lua_setfield(L, -2, "__index"); /* metatable.__index = string */ + lua_pop(L, 1); /* pop metatable */ +} + + +/* +** Open string library +*/ +LUAMOD_API int luaopen_string (lua_State *L) { + luaL_newlib(L, strlib); + createmetatable(L); + return 1; +} + diff --git a/3rd/lua-5.3.4/ltable.c b/3rd/lua-5.3.4/ltable.c new file mode 100644 index 0000000..d080189 --- /dev/null +++ b/3rd/lua-5.3.4/ltable.c @@ -0,0 +1,669 @@ +/* +** $Id: ltable.c,v 2.118 2016/11/07 12:38:35 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#define ltable_c +#define LUA_CORE + +#include "lprefix.h" + + +/* +** Implementation of tables (aka arrays, objects, or hash tables). +** Tables keep its elements in two parts: an array part and a hash part. +** Non-negative integer keys are all candidates to be kept in the array +** part. The actual size of the array is the largest 'n' such that +** more than half the slots between 1 and n are in use. +** Hash uses a mix of chained scatter table with Brent's variation. +** A main invariant of these tables is that, if an element is not +** in its main position (i.e. the 'original' position that its hash gives +** to it), then the colliding element is in its own main position. +** Hence even when the load factor reaches 100%, performance remains good. +*/ + +#include +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lvm.h" + + +/* +** Maximum size of array part (MAXASIZE) is 2^MAXABITS. MAXABITS is +** the largest integer such that MAXASIZE fits in an unsigned int. +*/ +#define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1) +#define MAXASIZE (1u << MAXABITS) + +/* +** Maximum size of hash part is 2^MAXHBITS. MAXHBITS is the largest +** integer such that 2^MAXHBITS fits in a signed int. (Note that the +** maximum number of elements in a table, 2^MAXABITS + 2^MAXHBITS, still +** fits comfortably in an unsigned int.) +*/ +#define MAXHBITS (MAXABITS - 1) + + +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) + +#define hashstr(t,str) hashpow2(t, (str)->hash) +#define hashboolean(t,p) hashpow2(t, p) +#define hashint(t,i) hashpow2(t, i) + + +/* +** for some types, it is better to avoid modulus by power of 2, as +** they tend to have many 2 factors. +*/ +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) + + +#define hashpointer(t,p) hashmod(t, point2uint(p)) + + +#define dummynode (&dummynode_) + +static const Node dummynode_ = { + {NILCONSTANT}, /* value */ + {{NILCONSTANT, 0}} /* key */ +}; + + +/* +** Hash for floating-point numbers. +** The main computation should be just +** n = frexp(n, &i); return (n * INT_MAX) + i +** but there are some numerical subtleties. +** In a two-complement representation, INT_MAX does not has an exact +** representation as a float, but INT_MIN does; because the absolute +** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the +** absolute value of the product 'frexp * -INT_MIN' is smaller or equal +** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when +** adding 'i'; the use of '~u' (instead of '-u') avoids problems with +** INT_MIN. +*/ +#if !defined(l_hashfloat) +static int l_hashfloat (lua_Number n) { + int i; + lua_Integer ni; + n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN); + if (!lua_numbertointeger(n, &ni)) { /* is 'n' inf/-inf/NaN? */ + lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == cast_num(HUGE_VAL)); + return 0; + } + else { /* normal case */ + unsigned int u = cast(unsigned int, i) + cast(unsigned int, ni); + return cast_int(u <= cast(unsigned int, INT_MAX) ? u : ~u); + } +} +#endif + + +/* +** returns the 'main' position of an element in a table (that is, the index +** of its hash value) +*/ +static Node *mainposition (const Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNUMINT: + return hashint(t, ivalue(key)); + case LUA_TNUMFLT: + return hashmod(t, l_hashfloat(fltvalue(key))); + case LUA_TSHRSTR: + return hashstr(t, tsvalue(key)); + case LUA_TLNGSTR: + return hashpow2(t, luaS_hashlongstr(tsvalue(key))); + case LUA_TBOOLEAN: + return hashboolean(t, bvalue(key)); + case LUA_TLIGHTUSERDATA: + return hashpointer(t, pvalue(key)); + case LUA_TLCF: + return hashpointer(t, fvalue(key)); + default: + lua_assert(!ttisdeadkey(key)); + return hashpointer(t, gcvalue(key)); + } +} + + +/* +** returns the index for 'key' if 'key' is an appropriate key to live in +** the array part of the table, 0 otherwise. +*/ +static unsigned int arrayindex (const TValue *key) { + if (ttisinteger(key)) { + lua_Integer k = ivalue(key); + if (0 < k && (lua_Unsigned)k <= MAXASIZE) + return cast(unsigned int, k); /* 'key' is an appropriate array index */ + } + return 0; /* 'key' did not match some condition */ +} + + +/* +** returns the index of a 'key' for table traversals. First goes all +** elements in the array part, then elements in the hash part. The +** beginning of a traversal is signaled by 0. +*/ +static unsigned int findindex (lua_State *L, Table *t, StkId key) { + unsigned int i; + if (ttisnil(key)) return 0; /* first iteration */ + i = arrayindex(key); + if (i != 0 && i <= t->sizearray) /* is 'key' inside array part? */ + return i; /* yes; that's the index */ + else { + int nx; + Node *n = mainposition(t, key); + for (;;) { /* check whether 'key' is somewhere in the chain */ + /* key may be dead already, but it is ok to use it in 'next' */ + if (luaV_rawequalobj(gkey(n), key) || + (ttisdeadkey(gkey(n)) && iscollectable(key) && + deadvalue(gkey(n)) == gcvalue(key))) { + i = cast_int(n - gnode(t, 0)); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return (i + 1) + t->sizearray; + } + nx = gnext(n); + if (nx == 0) + luaG_runerror(L, "invalid key to 'next'"); /* key not found */ + else n += nx; + } + } +} + + +int luaH_next (lua_State *L, Table *t, StkId key) { + unsigned int i = findindex(L, t, key); /* find original element */ + for (; i < t->sizearray; i++) { /* try first array part */ + if (!ttisnil(&t->array[i])) { /* a non-nil value? */ + setivalue(key, i + 1); + setobj2s(L, key+1, &t->array[i]); + return 1; + } + } + for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */ + if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ + setobj2s(L, key, gkey(gnode(t, i))); + setobj2s(L, key+1, gval(gnode(t, i))); + return 1; + } + } + return 0; /* no more elements */ +} + + +/* +** {============================================================= +** Rehash +** ============================================================== +*/ + +/* +** Compute the optimal size for the array part of table 't'. 'nums' is a +** "count array" where 'nums[i]' is the number of integers in the table +** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of +** integer keys in the table and leaves with the number of keys that +** will go to the array part; return the optimal size. +*/ +static unsigned int computesizes (unsigned int nums[], unsigned int *pna) { + int i; + unsigned int twotoi; /* 2^i (candidate for optimal size) */ + unsigned int a = 0; /* number of elements smaller than 2^i */ + unsigned int na = 0; /* number of elements to go to array part */ + unsigned int optimal = 0; /* optimal size for array part */ + /* loop while keys can fill more than half of total size */ + for (i = 0, twotoi = 1; *pna > twotoi / 2; i++, twotoi *= 2) { + if (nums[i] > 0) { + a += nums[i]; + if (a > twotoi/2) { /* more than half elements present? */ + optimal = twotoi; /* optimal size (till now) */ + na = a; /* all elements up to 'optimal' will go to array part */ + } + } + } + lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal); + *pna = na; + return optimal; +} + + +static int countint (const TValue *key, unsigned int *nums) { + unsigned int k = arrayindex(key); + if (k != 0) { /* is 'key' an appropriate array index? */ + nums[luaO_ceillog2(k)]++; /* count as such */ + return 1; + } + else + return 0; +} + + +/* +** Count keys in array part of table 't': Fill 'nums[i]' with +** number of keys that will go into corresponding slice and return +** total number of non-nil keys. +*/ +static unsigned int numusearray (const Table *t, unsigned int *nums) { + int lg; + unsigned int ttlg; /* 2^lg */ + unsigned int ause = 0; /* summation of 'nums' */ + unsigned int i = 1; /* count to traverse all array keys */ + /* traverse each slice */ + for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) { + unsigned int lc = 0; /* counter */ + unsigned int lim = ttlg; + if (lim > t->sizearray) { + lim = t->sizearray; /* adjust upper limit */ + if (i > lim) + break; /* no more elements to count */ + } + /* count elements in range (2^(lg - 1), 2^lg] */ + for (; i <= lim; i++) { + if (!ttisnil(&t->array[i-1])) + lc++; + } + nums[lg] += lc; + ause += lc; + } + return ause; +} + + +static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) { + int totaluse = 0; /* total number of elements */ + int ause = 0; /* elements added to 'nums' (can go to array part) */ + int i = sizenode(t); + while (i--) { + Node *n = &t->node[i]; + if (!ttisnil(gval(n))) { + ause += countint(gkey(n), nums); + totaluse++; + } + } + *pna += ause; + return totaluse; +} + + +static void setarrayvector (lua_State *L, Table *t, unsigned int size) { + unsigned int i; + luaM_reallocvector(L, t->array, t->sizearray, size, TValue); + for (i=t->sizearray; iarray[i]); + t->sizearray = size; +} + + +static void setnodevector (lua_State *L, Table *t, unsigned int size) { + if (size == 0) { /* no elements to hash part? */ + t->node = cast(Node *, dummynode); /* use common 'dummynode' */ + t->lsizenode = 0; + t->lastfree = NULL; /* signal that it is using dummy node */ + } + else { + int i; + int lsize = luaO_ceillog2(size); + if (lsize > MAXHBITS) + luaG_runerror(L, "table overflow"); + size = twoto(lsize); + t->node = luaM_newvector(L, size, Node); + for (i = 0; i < (int)size; i++) { + Node *n = gnode(t, i); + gnext(n) = 0; + setnilvalue(wgkey(n)); + setnilvalue(gval(n)); + } + t->lsizenode = cast_byte(lsize); + t->lastfree = gnode(t, size); /* all positions are free */ + } +} + + +void luaH_resize (lua_State *L, Table *t, unsigned int nasize, + unsigned int nhsize) { + unsigned int i; + int j; + unsigned int oldasize = t->sizearray; + int oldhsize = allocsizenode(t); + Node *nold = t->node; /* save old hash ... */ + if (nasize > oldasize) /* array part must grow? */ + setarrayvector(L, t, nasize); + /* create new hash part with appropriate size */ + setnodevector(L, t, nhsize); + if (nasize < oldasize) { /* array part must shrink? */ + t->sizearray = nasize; + /* re-insert elements from vanishing slice */ + for (i=nasize; iarray[i])) + luaH_setint(L, t, i + 1, &t->array[i]); + } + /* shrink array */ + luaM_reallocvector(L, t->array, oldasize, nasize, TValue); + } + /* re-insert elements from hash part */ + for (j = oldhsize - 1; j >= 0; j--) { + Node *old = nold + j; + if (!ttisnil(gval(old))) { + /* doesn't need barrier/invalidate cache, as entry was + already present in the table */ + setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); + } + } + if (oldhsize > 0) /* not the dummy node? */ + luaM_freearray(L, nold, cast(size_t, oldhsize)); /* free old hash */ +} + + +void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { + int nsize = allocsizenode(t); + luaH_resize(L, t, nasize, nsize); +} + +/* +** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i +*/ +static void rehash (lua_State *L, Table *t, const TValue *ek) { + unsigned int asize; /* optimal size for array part */ + unsigned int na; /* number of keys in the array part */ + unsigned int nums[MAXABITS + 1]; + int i; + int totaluse; + for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */ + na = numusearray(t, nums); /* count keys in array part */ + totaluse = na; /* all those keys are integer keys */ + totaluse += numusehash(t, nums, &na); /* count keys in hash part */ + /* count extra key */ + na += countint(ek, nums); + totaluse++; + /* compute new size for array part */ + asize = computesizes(nums, &na); + /* resize the table to new computed sizes */ + luaH_resize(L, t, asize, totaluse - na); +} + + + +/* +** }============================================================= +*/ + + +Table *luaH_new (lua_State *L) { + GCObject *o = luaC_newobj(L, LUA_TTABLE, sizeof(Table)); + Table *t = gco2t(o); + t->metatable = NULL; + t->flags = cast_byte(~0); + t->array = NULL; + t->sizearray = 0; + setnodevector(L, t, 0); + return t; +} + + +void luaH_free (lua_State *L, Table *t) { + if (!isdummy(t)) + luaM_freearray(L, t->node, cast(size_t, sizenode(t))); + luaM_freearray(L, t->array, t->sizearray); + luaM_free(L, t); +} + + +static Node *getfreepos (Table *t) { + if (!isdummy(t)) { + while (t->lastfree > t->node) { + t->lastfree--; + if (ttisnil(gkey(t->lastfree))) + return t->lastfree; + } + } + return NULL; /* could not find a free place */ +} + + + +/* +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. +*/ +TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { + Node *mp; + TValue aux; + if (ttisnil(key)) luaG_runerror(L, "table index is nil"); + else if (ttisfloat(key)) { + lua_Integer k; + if (luaV_tointeger(key, &k, 0)) { /* does index fit in an integer? */ + setivalue(&aux, k); + key = &aux; /* insert it as an integer */ + } + else if (luai_numisnan(fltvalue(key))) + luaG_runerror(L, "table index is NaN"); + } + mp = mainposition(t, key); + if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */ + Node *othern; + Node *f = getfreepos(t); /* get a free place */ + if (f == NULL) { /* cannot find a free place? */ + rehash(L, t, key); /* grow table */ + /* whatever called 'newkey' takes care of TM cache */ + return luaH_set(L, t, key); /* insert key into grown table */ + } + lua_assert(!isdummy(t)); + othern = mainposition(t, gkey(mp)); + if (othern != mp) { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (othern + gnext(othern) != mp) /* find previous */ + othern += gnext(othern); + gnext(othern) = cast_int(f - othern); /* rechain to point to 'f' */ + *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + if (gnext(mp) != 0) { + gnext(f) += cast_int(mp - f); /* correct 'next' */ + gnext(mp) = 0; /* now 'mp' is free */ + } + setnilvalue(gval(mp)); + } + else { /* colliding node is in its own main position */ + /* new node will go into free position */ + if (gnext(mp) != 0) + gnext(f) = cast_int((mp + gnext(mp)) - f); /* chain new position */ + else lua_assert(gnext(f) == 0); + gnext(mp) = cast_int(f - mp); + mp = f; + } + } + setnodekey(L, &mp->i_key, key); + luaC_barrierback(L, t, key); + lua_assert(ttisnil(gval(mp))); + return gval(mp); +} + + +/* +** search function for integers +*/ +const TValue *luaH_getint (Table *t, lua_Integer key) { + /* (1 <= key && key <= t->sizearray) */ + if (l_castS2U(key) - 1 < t->sizearray) + return &t->array[key - 1]; + else { + Node *n = hashint(t, key); + for (;;) { /* check whether 'key' is somewhere in the chain */ + if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key) + return gval(n); /* that's it */ + else { + int nx = gnext(n); + if (nx == 0) break; + n += nx; + } + } + return luaO_nilobject; + } +} + + +/* +** search function for short strings +*/ +const TValue *luaH_getshortstr (Table *t, TString *key) { + Node *n = hashstr(t, key); + lua_assert(key->tt == LUA_TSHRSTR); + for (;;) { /* check whether 'key' is somewhere in the chain */ + const TValue *k = gkey(n); + if (ttisshrstring(k) && eqshrstr(tsvalue(k), key)) + return gval(n); /* that's it */ + else { + int nx = gnext(n); + if (nx == 0) + return luaO_nilobject; /* not found */ + n += nx; + } + } +} + + +/* +** "Generic" get version. (Not that generic: not valid for integers, +** which may be in array part, nor for floats with integral values.) +*/ +static const TValue *getgeneric (Table *t, const TValue *key) { + Node *n = mainposition(t, key); + for (;;) { /* check whether 'key' is somewhere in the chain */ + if (luaV_rawequalobj(gkey(n), key)) + return gval(n); /* that's it */ + else { + int nx = gnext(n); + if (nx == 0) + return luaO_nilobject; /* not found */ + n += nx; + } + } +} + + +const TValue *luaH_getstr (Table *t, TString *key) { + if (key->tt == LUA_TSHRSTR) + return luaH_getshortstr(t, key); + else { /* for long strings, use generic case */ + TValue ko; + setsvalue(cast(lua_State *, NULL), &ko, key); + return getgeneric(t, &ko); + } +} + + +/* +** main search function +*/ +const TValue *luaH_get (Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key)); + case LUA_TNUMINT: return luaH_getint(t, ivalue(key)); + case LUA_TNIL: return luaO_nilobject; + case LUA_TNUMFLT: { + lua_Integer k; + if (luaV_tointeger(key, &k, 0)) /* index is int? */ + return luaH_getint(t, k); /* use specialized version */ + /* else... */ + } /* FALLTHROUGH */ + default: + return getgeneric(t, key); + } +} + + +/* +** beware: when using this function you probably need to check a GC +** barrier and invalidate the TM cache. +*/ +TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { + const TValue *p = luaH_get(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else return luaH_newkey(L, t, key); +} + + +void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { + const TValue *p = luaH_getint(t, key); + TValue *cell; + if (p != luaO_nilobject) + cell = cast(TValue *, p); + else { + TValue k; + setivalue(&k, key); + cell = luaH_newkey(L, t, &k); + } + setobj2t(L, cell, value); +} + + +static int unbound_search (Table *t, unsigned int j) { + unsigned int i = j; /* i is zero or a present index */ + j++; + /* find 'i' and 'j' such that i is present and j is not */ + while (!ttisnil(luaH_getint(t, j))) { + i = j; + if (j > cast(unsigned int, MAX_INT)/2) { /* overflow? */ + /* table was built with bad purposes: resort to linear search */ + i = 1; + while (!ttisnil(luaH_getint(t, i))) i++; + return i - 1; + } + j *= 2; + } + /* now do a binary search between them */ + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(luaH_getint(t, m))) j = m; + else i = m; + } + return i; +} + + +/* +** Try to find a boundary in table 't'. A 'boundary' is an integer index +** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). +*/ +int luaH_getn (Table *t) { + unsigned int j = t->sizearray; + if (j > 0 && ttisnil(&t->array[j - 1])) { + /* there is a boundary in the array part: (binary) search for it */ + unsigned int i = 0; + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(&t->array[m - 1])) j = m; + else i = m; + } + return i; + } + /* else must find a boundary in hash part */ + else if (isdummy(t)) /* hash part is empty? */ + return j; /* that is easy... */ + else return unbound_search(t, j); +} + + + +#if defined(LUA_DEBUG) + +Node *luaH_mainposition (const Table *t, const TValue *key) { + return mainposition(t, key); +} + +int luaH_isdummy (const Table *t) { return isdummy(t); } + +#endif diff --git a/3rd/lua-5.3.4/ltable.h b/3rd/lua-5.3.4/ltable.h new file mode 100644 index 0000000..6da9024 --- /dev/null +++ b/3rd/lua-5.3.4/ltable.h @@ -0,0 +1,66 @@ +/* +** $Id: ltable.h,v 2.23 2016/12/22 13:08:50 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define gnode(t,i) (&(t)->node[i]) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->i_key.nk.next) + + +/* 'const' to avoid wrong writings that can mess up field 'next' */ +#define gkey(n) cast(const TValue*, (&(n)->i_key.tvk)) + +/* +** writable version of 'gkey'; allows updates to individual fields, +** but not to the whole (which has incompatible type) +*/ +#define wgkey(n) (&(n)->i_key.nk) + +#define invalidateTMcache(t) ((t)->flags = 0) + + +/* true when 't' is using 'dummynode' as its hash part */ +#define isdummy(t) ((t)->lastfree == NULL) + + +/* allocated size for hash nodes */ +#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) + + +/* returns the key, given the value of a table entry */ +#define keyfromval(v) \ + (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) + + +LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); +LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, + TValue *value); +LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); +LUAI_FUNC Table *luaH_new (lua_State *L); +LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, + unsigned int nhsize); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); +LUAI_FUNC void luaH_free (lua_State *L, Table *t); +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC int luaH_getn (Table *t); + + +#if defined(LUA_DEBUG) +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); +LUAI_FUNC int luaH_isdummy (const Table *t); +#endif + + +#endif diff --git a/3rd/lua-5.3.4/ltablib.c b/3rd/lua-5.3.4/ltablib.c new file mode 100644 index 0000000..98b2f87 --- /dev/null +++ b/3rd/lua-5.3.4/ltablib.c @@ -0,0 +1,450 @@ +/* +** $Id: ltablib.c,v 1.93 2016/02/25 19:41:54 roberto Exp $ +** Library for Table Manipulation +** See Copyright Notice in lua.h +*/ + +#define ltablib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** Operations that an object must define to mimic a table +** (some functions only need some of them) +*/ +#define TAB_R 1 /* read */ +#define TAB_W 2 /* write */ +#define TAB_L 4 /* length */ +#define TAB_RW (TAB_R | TAB_W) /* read/write */ + + +#define aux_getn(L,n,w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n)) + + +static int checkfield (lua_State *L, const char *key, int n) { + lua_pushstring(L, key); + return (lua_rawget(L, -n) != LUA_TNIL); +} + + +/* +** Check that 'arg' either is a table or can behave like one (that is, +** has a metatable with the required metamethods) +*/ +static void checktab (lua_State *L, int arg, int what) { + if (lua_type(L, arg) != LUA_TTABLE) { /* is it not a table? */ + int n = 1; /* number of elements to pop */ + if (lua_getmetatable(L, arg) && /* must have metatable */ + (!(what & TAB_R) || checkfield(L, "__index", ++n)) && + (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) && + (!(what & TAB_L) || checkfield(L, "__len", ++n))) { + lua_pop(L, n); /* pop metatable and tested metamethods */ + } + else + luaL_checktype(L, arg, LUA_TTABLE); /* force an error */ + } +} + + +#if defined(LUA_COMPAT_MAXN) +static int maxn (lua_State *L) { + lua_Number max = 0; + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pop(L, 1); /* remove value */ + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_Number v = lua_tonumber(L, -1); + if (v > max) max = v; + } + } + lua_pushnumber(L, max); + return 1; +} +#endif + + +static int tinsert (lua_State *L) { + lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */ + lua_Integer pos; /* where to insert new element */ + switch (lua_gettop(L)) { + case 2: { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: { + lua_Integer i; + pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ + luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); + for (i = e; i > pos; i--) { /* move up elements */ + lua_geti(L, 1, i - 1); + lua_seti(L, 1, i); /* t[i] = t[i - 1] */ + } + break; + } + default: { + return luaL_error(L, "wrong number of arguments to 'insert'"); + } + } + lua_seti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int tremove (lua_State *L) { + lua_Integer size = aux_getn(L, 1, TAB_RW); + lua_Integer pos = luaL_optinteger(L, 2, size); + if (pos != size) /* validate 'pos' if given */ + luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); + lua_geti(L, 1, pos); /* result = t[pos] */ + for ( ; pos < size; pos++) { + lua_geti(L, 1, pos + 1); + lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ + } + lua_pushnil(L); + lua_seti(L, 1, pos); /* t[pos] = nil */ + return 1; +} + + +/* +** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever +** possible, copy in increasing order, which is better for rehashing. +** "possible" means destination after original range, or smaller +** than origin, or copying to another table. +*/ +static int tmove (lua_State *L) { + lua_Integer f = luaL_checkinteger(L, 2); + lua_Integer e = luaL_checkinteger(L, 3); + lua_Integer t = luaL_checkinteger(L, 4); + int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ + checktab(L, 1, TAB_R); + checktab(L, tt, TAB_W); + if (e >= f) { /* otherwise, nothing to move */ + lua_Integer n, i; + luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3, + "too many elements to move"); + n = e - f + 1; /* number of elements to move */ + luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4, + "destination wrap around"); + if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) { + for (i = 0; i < n; i++) { + lua_geti(L, 1, f + i); + lua_seti(L, tt, t + i); + } + } + else { + for (i = n - 1; i >= 0; i--) { + lua_geti(L, 1, f + i); + lua_seti(L, tt, t + i); + } + } + } + lua_pushvalue(L, tt); /* return destination table */ + return 1; +} + + +static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) { + lua_geti(L, 1, i); + if (!lua_isstring(L, -1)) + luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", + luaL_typename(L, -1), i); + luaL_addvalue(b); +} + + +static int tconcat (lua_State *L) { + luaL_Buffer b; + lua_Integer last = aux_getn(L, 1, TAB_R); + size_t lsep; + const char *sep = luaL_optlstring(L, 2, "", &lsep); + lua_Integer i = luaL_optinteger(L, 3, 1); + last = luaL_optinteger(L, 4, last); + luaL_buffinit(L, &b); + for (; i < last; i++) { + addfield(L, &b, i); + luaL_addlstring(&b, sep, lsep); + } + if (i == last) /* add last value (if interval was not empty) */ + addfield(L, &b, i); + luaL_pushresult(&b); + return 1; +} + + +/* +** {====================================================== +** Pack/unpack +** ======================================================= +*/ + +static int pack (lua_State *L) { + int i; + int n = lua_gettop(L); /* number of elements to pack */ + lua_createtable(L, n, 1); /* create result table */ + lua_insert(L, 1); /* put it at index 1 */ + for (i = n; i >= 1; i--) /* assign elements */ + lua_seti(L, 1, i); + lua_pushinteger(L, n); + lua_setfield(L, 1, "n"); /* t.n = number of elements */ + return 1; /* return table */ +} + + +static int unpack (lua_State *L) { + lua_Unsigned n; + lua_Integer i = luaL_optinteger(L, 2, 1); + lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); + if (i > e) return 0; /* empty range */ + n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */ + if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n))) + return luaL_error(L, "too many results to unpack"); + for (; i < e; i++) { /* push arg[i..e - 1] (to avoid overflows) */ + lua_geti(L, 1, i); + } + lua_geti(L, 1, e); /* push last element */ + return (int)n; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Quicksort +** (based on 'Algorithms in MODULA-3', Robert Sedgewick; +** Addison-Wesley, 1993.) +** ======================================================= +*/ + + +/* type for array indices */ +typedef unsigned int IdxT; + + +/* +** Produce a "random" 'unsigned int' to randomize pivot choice. This +** macro is used only when 'sort' detects a big imbalance in the result +** of a partition. (If you don't want/need this "randomness", ~0 is a +** good choice.) +*/ +#if !defined(l_randomizePivot) /* { */ + +#include + +/* size of 'e' measured in number of 'unsigned int's */ +#define sof(e) (sizeof(e) / sizeof(unsigned int)) + +/* +** Use 'time' and 'clock' as sources of "randomness". Because we don't +** know the types 'clock_t' and 'time_t', we cannot cast them to +** anything without risking overflows. A safe way to use their values +** is to copy them to an array of a known type and use the array values. +*/ +static unsigned int l_randomizePivot (void) { + clock_t c = clock(); + time_t t = time(NULL); + unsigned int buff[sof(c) + sof(t)]; + unsigned int i, rnd = 0; + memcpy(buff, &c, sof(c) * sizeof(unsigned int)); + memcpy(buff + sof(c), &t, sof(t) * sizeof(unsigned int)); + for (i = 0; i < sof(buff); i++) + rnd += buff[i]; + return rnd; +} + +#endif /* } */ + + +/* arrays larger than 'RANLIMIT' may use randomized pivots */ +#define RANLIMIT 100u + + +static void set2 (lua_State *L, IdxT i, IdxT j) { + lua_seti(L, 1, i); + lua_seti(L, 1, j); +} + + +/* +** Return true iff value at stack index 'a' is less than the value at +** index 'b' (according to the order of the sort). +*/ +static int sort_comp (lua_State *L, int a, int b) { + if (lua_isnil(L, 2)) /* no function? */ + return lua_compare(L, a, b, LUA_OPLT); /* a < b */ + else { /* function */ + int res; + lua_pushvalue(L, 2); /* push function */ + lua_pushvalue(L, a-1); /* -1 to compensate function */ + lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ + lua_call(L, 2, 1); /* call function */ + res = lua_toboolean(L, -1); /* get result */ + lua_pop(L, 1); /* pop result */ + return res; + } +} + + +/* +** Does the partition: Pivot P is at the top of the stack. +** precondition: a[lo] <= P == a[up-1] <= a[up], +** so it only needs to do the partition from lo + 1 to up - 2. +** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up] +** returns 'i'. +*/ +static IdxT partition (lua_State *L, IdxT lo, IdxT up) { + IdxT i = lo; /* will be incremented before first use */ + IdxT j = up - 1; /* will be decremented before first use */ + /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ + for (;;) { + /* next loop: repeat ++i while a[i] < P */ + while (lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */ + luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ + /* next loop: repeat --j while P < a[j] */ + while (lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { + if (j < i) /* j < i but a[j] > P ?? */ + luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[j] */ + } + /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */ + if (j < i) { /* no elements out of place? */ + /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */ + lua_pop(L, 1); /* pop a[j] */ + /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */ + set2(L, up - 1, i); + return i; + } + /* otherwise, swap a[i] - a[j] to restore invariant and repeat */ + set2(L, i, j); + } +} + + +/* +** Choose an element in the middle (2nd-3th quarters) of [lo,up] +** "randomized" by 'rnd' +*/ +static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) { + IdxT r4 = (up - lo) / 4; /* range/4 */ + IdxT p = rnd % (r4 * 2) + (lo + r4); + lua_assert(lo + r4 <= p && p <= up - r4); + return p; +} + + +/* +** QuickSort algorithm (recursive function) +*/ +static void auxsort (lua_State *L, IdxT lo, IdxT up, + unsigned int rnd) { + while (lo < up) { /* loop for tail recursion */ + IdxT p; /* Pivot index */ + IdxT n; /* to be used later */ + /* sort elements 'lo', 'p', and 'up' */ + lua_geti(L, 1, lo); + lua_geti(L, 1, up); + if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */ + set2(L, lo, up); /* swap a[lo] - a[up] */ + else + lua_pop(L, 2); /* remove both values */ + if (up - lo == 1) /* only 2 elements? */ + return; /* already sorted */ + if (up - lo < RANLIMIT || rnd == 0) /* small interval or no randomize? */ + p = (lo + up)/2; /* middle element is a good pivot */ + else /* for larger intervals, it is worth a random pivot */ + p = choosePivot(lo, up, rnd); + lua_geti(L, 1, p); + lua_geti(L, 1, lo); + if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */ + set2(L, p, lo); /* swap a[p] - a[lo] */ + else { + lua_pop(L, 1); /* remove a[lo] */ + lua_geti(L, 1, up); + if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */ + set2(L, p, up); /* swap a[up] - a[p] */ + else + lua_pop(L, 2); + } + if (up - lo == 2) /* only 3 elements? */ + return; /* already sorted */ + lua_geti(L, 1, p); /* get middle element (Pivot) */ + lua_pushvalue(L, -1); /* push Pivot */ + lua_geti(L, 1, up - 1); /* push a[up - 1] */ + set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */ + p = partition(L, lo, up); + /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */ + if (p - lo < up - p) { /* lower interval is smaller? */ + auxsort(L, lo, p - 1, rnd); /* call recursively for lower interval */ + n = p - lo; /* size of smaller interval */ + lo = p + 1; /* tail call for [p + 1 .. up] (upper interval) */ + } + else { + auxsort(L, p + 1, up, rnd); /* call recursively for upper interval */ + n = up - p; /* size of smaller interval */ + up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */ + } + if ((up - lo) / 128 > n) /* partition too imbalanced? */ + rnd = l_randomizePivot(); /* try a new randomization */ + } /* tail call auxsort(L, lo, up, rnd) */ +} + + +static int sort (lua_State *L) { + lua_Integer n = aux_getn(L, 1, TAB_RW); + if (n > 1) { /* non-trivial interval? */ + luaL_argcheck(L, n < INT_MAX, 1, "array too big"); + if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ + luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */ + lua_settop(L, 2); /* make sure there are two arguments */ + auxsort(L, 1, (IdxT)n, 0); + } + return 0; +} + +/* }====================================================== */ + + +static const luaL_Reg tab_funcs[] = { + {"concat", tconcat}, +#if defined(LUA_COMPAT_MAXN) + {"maxn", maxn}, +#endif + {"insert", tinsert}, + {"pack", pack}, + {"unpack", unpack}, + {"remove", tremove}, + {"move", tmove}, + {"sort", sort}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_table (lua_State *L) { + luaL_newlib(L, tab_funcs); +#if defined(LUA_COMPAT_UNPACK) + /* _G.unpack = table.unpack */ + lua_getfield(L, -1, "unpack"); + lua_setglobal(L, "unpack"); +#endif + return 1; +} + diff --git a/3rd/lua-5.3.4/ltm.c b/3rd/lua-5.3.4/ltm.c new file mode 100644 index 0000000..14e5257 --- /dev/null +++ b/3rd/lua-5.3.4/ltm.c @@ -0,0 +1,165 @@ +/* +** $Id: ltm.c,v 2.38 2016/12/22 13:08:50 roberto Exp $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#define ltm_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + +static const char udatatypename[] = "userdata"; + +LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { + "no value", + "nil", "boolean", udatatypename, "number", + "string", "table", "function", udatatypename, "thread", + "proto" /* this last case is used for tests only */ +}; + + +void luaT_init (lua_State *L) { + static const char *const luaT_eventname[] = { /* ORDER TM */ + "__index", "__newindex", + "__gc", "__mode", "__len", "__eq", + "__add", "__sub", "__mul", "__mod", "__pow", + "__div", "__idiv", + "__band", "__bor", "__bxor", "__shl", "__shr", + "__unm", "__bnot", "__lt", "__le", + "__concat", "__call" + }; + int i; + for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); + luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ + } +} + + +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods +*/ +const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { + const TValue *tm = luaH_getshortstr(events, ename); + lua_assert(event <= TM_EQ); + if (ttisnil(tm)) { /* no tag method? */ + events->flags |= cast_byte(1u<metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = G(L)->mt[ttnov(o)]; + } + return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject); +} + + +/* +** Return the name of the type of an object. For tables and userdata +** with metatable, use their '__name' metafield, if present. +*/ +const char *luaT_objtypename (lua_State *L, const TValue *o) { + Table *mt; + if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || + (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { + const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); + if (ttisstring(name)) /* is '__name' a string? */ + return getstr(tsvalue(name)); /* use it as type name */ + } + return ttypename(ttnov(o)); /* else use standard type name */ +} + + +void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, TValue *p3, int hasres) { + ptrdiff_t result = savestack(L, p3); + StkId func = L->top; + setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ + setobj2s(L, func + 1, p1); /* 1st argument */ + setobj2s(L, func + 2, p2); /* 2nd argument */ + L->top += 3; + if (!hasres) /* no result? 'p3' is third argument */ + setobj2s(L, L->top++, p3); /* 3rd argument */ + /* metamethod may yield only when called from Lua code */ + if (isLua(L->ci)) + luaD_call(L, func, hasres); + else + luaD_callnoyield(L, func, hasres); + if (hasres) { /* if has result, move it to its place */ + p3 = restorestack(L, result); + setobjs2s(L, p3, --L->top); + } +} + + +int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (ttisnil(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (ttisnil(tm)) return 0; + luaT_callTM(L, tm, p1, p2, res, 1); + return 1; +} + + +void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + if (!luaT_callbinTM(L, p1, p2, res, event)) { + switch (event) { + case TM_CONCAT: + luaG_concaterror(L, p1, p2); + /* call never returns, but to avoid warnings: *//* FALLTHROUGH */ + case TM_BAND: case TM_BOR: case TM_BXOR: + case TM_SHL: case TM_SHR: case TM_BNOT: { + lua_Number dummy; + if (tonumber(p1, &dummy) && tonumber(p2, &dummy)) + luaG_tointerror(L, p1, p2); + else + luaG_opinterror(L, p1, p2, "perform bitwise operation on"); + } + /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ + default: + luaG_opinterror(L, p1, p2, "perform arithmetic on"); + } + } +} + + +int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, + TMS event) { + if (!luaT_callbinTM(L, p1, p2, L->top, event)) + return -1; /* no metamethod */ + else + return !l_isfalse(L->top); +} + diff --git a/3rd/lua-5.3.4/ltm.h b/3rd/lua-5.3.4/ltm.h new file mode 100644 index 0000000..63db726 --- /dev/null +++ b/3rd/lua-5.3.4/ltm.h @@ -0,0 +1,76 @@ +/* +** $Id: ltm.h,v 2.22 2016/02/26 19:20:15 roberto Exp $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" and "ORDER OP" +*/ +typedef enum { + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_LEN, + TM_EQ, /* last tag method with fast access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_MOD, + TM_POW, + TM_DIV, + TM_IDIV, + TM_BAND, + TM_BOR, + TM_BXOR, + TM_SHL, + TM_SHR, + TM_UNM, + TM_BNOT, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_N /* number of elements in the enum */ +} TMS; + + + +#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ + ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l,et,e) gfasttm(G(l), et, e) + +#define ttypename(x) luaT_typenames_[(x) + 1] + +LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; + + +LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); + +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init (lua_State *L); + +LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, TValue *p3, int hasres); +LUAI_FUNC int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event); +LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event); +LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, + const TValue *p2, TMS event); + + + +#endif diff --git a/3rd/lua-5.3.4/lua b/3rd/lua-5.3.4/lua new file mode 100755 index 0000000000000000000000000000000000000000..7acf7b99f75a0266f8a8f590b5383fbf192907ca GIT binary patch literal 1084992 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

iiYa3mHjsL@`LV_FJ3T%Hc5zSmu|(Vd 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 z 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�KWpLAhqmSV4Xh1^3ccDi7pSa(=sc= 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.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