aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-03-11 00:21:33 +0800
committerLi Jin <dragon-fly@qq.com>2020-03-11 00:21:33 +0800
commit1ee056eedf773ac6166247755439092e0e0a9bca (patch)
tree1b8863338d37fe6ded7fbaecd92d76cdb3801ab3
parent015af4b70cd751e1c1580fd542997a796e1ca225 (diff)
downloadyuescript-1ee056eedf773ac6166247755439092e0e0a9bca.tar.gz
yuescript-1ee056eedf773ac6166247755439092e0e0a9bca.tar.bz2
yuescript-1ee056eedf773ac6166247755439092e0e0a9bca.zip
add macro functions.
-rw-r--r--MoonPlus.vcxproj77
-rw-r--r--MoonPlus.vcxproj.filters186
-rw-r--r--README.md42
-rw-r--r--makefile9
-rw-r--r--spec/inputs/macro.moon69
-rw-r--r--spec/inputs/macro_export.moon29
-rw-r--r--src/MoonP/moon_ast.h62
-rw-r--r--src/MoonP/moon_compiler.cpp661
-rw-r--r--src/MoonP/moon_compiler.h6
-rw-r--r--src/MoonP/moon_parser.cpp68
-rw-r--r--src/MoonP/moon_parser.h13
-rw-r--r--src/Moonscript.h146
-rw-r--r--src/StackTracePlus.h548
-rw-r--r--src/lua-5.3/lapi.c1299
-rw-r--r--src/lua-5.3/lapi.h24
-rw-r--r--src/lua-5.3/lauxlib.c1043
-rw-r--r--src/lua-5.3/lauxlib.h264
-rw-r--r--src/lua-5.3/lbaselib.c498
-rw-r--r--src/lua-5.3/lbitlib.c233
-rw-r--r--src/lua-5.3/lcode.c1203
-rw-r--r--src/lua-5.3/lcode.h88
-rw-r--r--src/lua-5.3/lcorolib.c168
-rw-r--r--src/lua-5.3/lctype.c55
-rw-r--r--src/lua-5.3/lctype.h95
-rw-r--r--src/lua-5.3/ldblib.c456
-rw-r--r--src/lua-5.3/ldebug.c699
-rw-r--r--src/lua-5.3/ldebug.h39
-rw-r--r--src/lua-5.3/ldo.c802
-rw-r--r--src/lua-5.3/ldo.h58
-rw-r--r--src/lua-5.3/ldump.c215
-rw-r--r--src/lua-5.3/lfunc.c151
-rw-r--r--src/lua-5.3/lfunc.h61
-rw-r--r--src/lua-5.3/lgc.c1179
-rw-r--r--src/lua-5.3/lgc.h147
-rw-r--r--src/lua-5.3/license.txt6
-rw-r--r--src/lua-5.3/linit.c68
-rw-r--r--src/lua-5.3/liolib.c776
-rw-r--r--src/lua-5.3/llex.c568
-rw-r--r--src/lua-5.3/llex.h85
-rw-r--r--src/lua-5.3/llimits.h323
-rw-r--r--src/lua-5.3/lmathlib.c410
-rw-r--r--src/lua-5.3/lmem.c100
-rw-r--r--src/lua-5.3/lmem.h69
-rw-r--r--src/lua-5.3/loadlib.c790
-rw-r--r--src/lua-5.3/lobject.c522
-rw-r--r--src/lua-5.3/lobject.h549
-rw-r--r--src/lua-5.3/lopcodes.c124
-rw-r--r--src/lua-5.3/lopcodes.h297
-rw-r--r--src/lua-5.3/loslib.c409
-rw-r--r--src/lua-5.3/lparser.c1650
-rw-r--r--src/lua-5.3/lparser.h133
-rw-r--r--src/lua-5.3/lprefix.h45
-rw-r--r--src/lua-5.3/lstate.c347
-rw-r--r--src/lua-5.3/lstate.h253
-rw-r--r--src/lua-5.3/lstring.c248
-rw-r--r--src/lua-5.3/lstring.h49
-rw-r--r--src/lua-5.3/lstrlib.c1584
-rw-r--r--src/lua-5.3/ltable.c688
-rw-r--r--src/lua-5.3/ltable.h66
-rw-r--r--src/lua-5.3/ltablib.c450
-rw-r--r--src/lua-5.3/ltm.c165
-rw-r--r--src/lua-5.3/ltm.h76
-rw-r--r--src/lua-5.3/lua.h486
-rw-r--r--src/lua-5.3/luaconf.h790
-rw-r--r--src/lua-5.3/lualib.h61
-rw-r--r--src/lua-5.3/lundump.c279
-rw-r--r--src/lua-5.3/lundump.h32
-rw-r--r--src/lua-5.3/lutf8lib.c256
-rw-r--r--src/lua-5.3/lvm.c1322
-rw-r--r--src/lua-5.3/lvm.h113
-rw-r--r--src/lua-5.3/lzio.c68
-rw-r--r--src/lua-5.3/lzio.h66
-rw-r--r--src/lua-5.3/makefile177
-rw-r--r--src/moonp.cpp180
74 files changed, 24441 insertions, 932 deletions
diff --git a/MoonPlus.vcxproj b/MoonPlus.vcxproj
index fd502ab..d027aa0 100644
--- a/MoonPlus.vcxproj
+++ b/MoonPlus.vcxproj
@@ -93,10 +93,10 @@
93 <ClCompile> 93 <ClCompile>
94 <WarningLevel>Level3</WarningLevel> 94 <WarningLevel>Level3</WarningLevel>
95 <SDLCheck>true</SDLCheck> 95 <SDLCheck>true</SDLCheck>
96 <PreprocessorDefinitions>_DEBUG;_CONSOLE;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;%(PreprocessorDefinitions)</PreprocessorDefinitions> 96 <PreprocessorDefinitions>_DEBUG;_CONSOLE;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;LUA_COMPAT_5_2;LUA_COMPAT_5_1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
97 <ConformanceMode>true</ConformanceMode> 97 <ConformanceMode>true</ConformanceMode>
98 <LanguageStandard>stdcpplatest</LanguageStandard> 98 <LanguageStandard>stdcpplatest</LanguageStandard>
99 <AdditionalIncludeDirectories>.\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> 99 <AdditionalIncludeDirectories>.\src;.\src\lua-5.3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
100 </ClCompile> 100 </ClCompile>
101 <Link> 101 <Link>
102 <SubSystem>Console</SubSystem> 102 <SubSystem>Console</SubSystem>
@@ -107,10 +107,10 @@
107 <ClCompile> 107 <ClCompile>
108 <WarningLevel>Level3</WarningLevel> 108 <WarningLevel>Level3</WarningLevel>
109 <SDLCheck>true</SDLCheck> 109 <SDLCheck>true</SDLCheck>
110 <PreprocessorDefinitions>_DEBUG;_CONSOLE;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;%(PreprocessorDefinitions)</PreprocessorDefinitions> 110 <PreprocessorDefinitions>_DEBUG;_CONSOLE;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;LUA_COMPAT_5_2;LUA_COMPAT_5_1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
111 <ConformanceMode>true</ConformanceMode> 111 <ConformanceMode>true</ConformanceMode>
112 <LanguageStandard>stdcpplatest</LanguageStandard> 112 <LanguageStandard>stdcpplatest</LanguageStandard>
113 <AdditionalIncludeDirectories>.\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> 113 <AdditionalIncludeDirectories>.\src;.\src\lua-5.3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
114 </ClCompile> 114 </ClCompile>
115 <Link> 115 <Link>
116 <SubSystem>Console</SubSystem> 116 <SubSystem>Console</SubSystem>
@@ -123,10 +123,10 @@
123 <FunctionLevelLinking>true</FunctionLevelLinking> 123 <FunctionLevelLinking>true</FunctionLevelLinking>
124 <IntrinsicFunctions>true</IntrinsicFunctions> 124 <IntrinsicFunctions>true</IntrinsicFunctions>
125 <SDLCheck>true</SDLCheck> 125 <SDLCheck>true</SDLCheck>
126 <PreprocessorDefinitions>NDEBUG;_CONSOLE;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;%(PreprocessorDefinitions)</PreprocessorDefinitions> 126 <PreprocessorDefinitions>NDEBUG;_CONSOLE;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;LUA_COMPAT_5_2;LUA_COMPAT_5_1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
127 <ConformanceMode>true</ConformanceMode> 127 <ConformanceMode>true</ConformanceMode>
128 <LanguageStandard>stdcpplatest</LanguageStandard> 128 <LanguageStandard>stdcpplatest</LanguageStandard>
129 <AdditionalIncludeDirectories>.\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> 129 <AdditionalIncludeDirectories>.\src;.\src\lua-5.3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
130 </ClCompile> 130 </ClCompile>
131 <Link> 131 <Link>
132 <SubSystem>Console</SubSystem> 132 <SubSystem>Console</SubSystem>
@@ -141,10 +141,10 @@
141 <FunctionLevelLinking>true</FunctionLevelLinking> 141 <FunctionLevelLinking>true</FunctionLevelLinking>
142 <IntrinsicFunctions>true</IntrinsicFunctions> 142 <IntrinsicFunctions>true</IntrinsicFunctions>
143 <SDLCheck>true</SDLCheck> 143 <SDLCheck>true</SDLCheck>
144 <PreprocessorDefinitions>NDEBUG;_CONSOLE;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;%(PreprocessorDefinitions)</PreprocessorDefinitions> 144 <PreprocessorDefinitions>NDEBUG;_CONSOLE;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;LUA_COMPAT_5_2;LUA_COMPAT_5_1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
145 <ConformanceMode>true</ConformanceMode> 145 <ConformanceMode>true</ConformanceMode>
146 <LanguageStandard>stdcpplatest</LanguageStandard> 146 <LanguageStandard>stdcpplatest</LanguageStandard>
147 <AdditionalIncludeDirectories>.\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> 147 <AdditionalIncludeDirectories>.\src;.\src\lua-5.3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
148 </ClCompile> 148 </ClCompile>
149 <Link> 149 <Link>
150 <SubSystem>Console</SubSystem> 150 <SubSystem>Console</SubSystem>
@@ -154,18 +154,79 @@
154 </Link> 154 </Link>
155 </ItemDefinitionGroup> 155 </ItemDefinitionGroup>
156 <ItemGroup> 156 <ItemGroup>
157 <ClCompile Include="src\lua-5.3\lapi.c" />
158 <ClCompile Include="src\lua-5.3\lauxlib.c" />
159 <ClCompile Include="src\lua-5.3\lbaselib.c" />
160 <ClCompile Include="src\lua-5.3\lbitlib.c" />
161 <ClCompile Include="src\lua-5.3\lcode.c" />
162 <ClCompile Include="src\lua-5.3\lcorolib.c" />
163 <ClCompile Include="src\lua-5.3\lctype.c" />
164 <ClCompile Include="src\lua-5.3\ldblib.c" />
165 <ClCompile Include="src\lua-5.3\ldebug.c" />
166 <ClCompile Include="src\lua-5.3\ldo.c" />
167 <ClCompile Include="src\lua-5.3\ldump.c" />
168 <ClCompile Include="src\lua-5.3\lfunc.c" />
169 <ClCompile Include="src\lua-5.3\lgc.c" />
170 <ClCompile Include="src\lua-5.3\linit.c" />
171 <ClCompile Include="src\lua-5.3\liolib.c" />
172 <ClCompile Include="src\lua-5.3\llex.c" />
173 <ClCompile Include="src\lua-5.3\lmathlib.c" />
174 <ClCompile Include="src\lua-5.3\lmem.c" />
175 <ClCompile Include="src\lua-5.3\loadlib.c" />
176 <ClCompile Include="src\lua-5.3\lobject.c" />
177 <ClCompile Include="src\lua-5.3\lopcodes.c" />
178 <ClCompile Include="src\lua-5.3\loslib.c" />
179 <ClCompile Include="src\lua-5.3\lparser.c" />
180 <ClCompile Include="src\lua-5.3\lstate.c" />
181 <ClCompile Include="src\lua-5.3\lstring.c" />
182 <ClCompile Include="src\lua-5.3\lstrlib.c" />
183 <ClCompile Include="src\lua-5.3\ltable.c" />
184 <ClCompile Include="src\lua-5.3\ltablib.c" />
185 <ClCompile Include="src\lua-5.3\ltm.c" />
186 <ClCompile Include="src\lua-5.3\lundump.c" />
187 <ClCompile Include="src\lua-5.3\lutf8lib.c" />
188 <ClCompile Include="src\lua-5.3\lvm.c" />
189 <ClCompile Include="src\lua-5.3\lzio.c" />
157 <ClCompile Include="src\moonp.cpp" /> 190 <ClCompile Include="src\moonp.cpp" />
158 <ClCompile Include="src\MoonP\ast.cpp" /> 191 <ClCompile Include="src\MoonP\ast.cpp" />
192 <ClCompile Include="src\MoonP\moonplus.cpp" />
159 <ClCompile Include="src\MoonP\moon_compiler.cpp" /> 193 <ClCompile Include="src\MoonP\moon_compiler.cpp" />
160 <ClCompile Include="src\MoonP\moon_parser.cpp" /> 194 <ClCompile Include="src\MoonP\moon_parser.cpp" />
161 <ClCompile Include="src\MoonP\parser.cpp" /> 195 <ClCompile Include="src\MoonP\parser.cpp" />
162 </ItemGroup> 196 </ItemGroup>
163 <ItemGroup> 197 <ItemGroup>
198 <ClInclude Include="src\lua-5.3\lapi.h" />
199 <ClInclude Include="src\lua-5.3\lauxlib.h" />
200 <ClInclude Include="src\lua-5.3\lcode.h" />
201 <ClInclude Include="src\lua-5.3\lctype.h" />
202 <ClInclude Include="src\lua-5.3\ldebug.h" />
203 <ClInclude Include="src\lua-5.3\ldo.h" />
204 <ClInclude Include="src\lua-5.3\lfunc.h" />
205 <ClInclude Include="src\lua-5.3\lgc.h" />
206 <ClInclude Include="src\lua-5.3\llex.h" />
207 <ClInclude Include="src\lua-5.3\llimits.h" />
208 <ClInclude Include="src\lua-5.3\lmem.h" />
209 <ClInclude Include="src\lua-5.3\lobject.h" />
210 <ClInclude Include="src\lua-5.3\lopcodes.h" />
211 <ClInclude Include="src\lua-5.3\lparser.h" />
212 <ClInclude Include="src\lua-5.3\lprefix.h" />
213 <ClInclude Include="src\lua-5.3\lstate.h" />
214 <ClInclude Include="src\lua-5.3\lstring.h" />
215 <ClInclude Include="src\lua-5.3\ltable.h" />
216 <ClInclude Include="src\lua-5.3\ltm.h" />
217 <ClInclude Include="src\lua-5.3\lua.h" />
218 <ClInclude Include="src\lua-5.3\luaconf.h" />
219 <ClInclude Include="src\lua-5.3\lualib.h" />
220 <ClInclude Include="src\lua-5.3\lundump.h" />
221 <ClInclude Include="src\lua-5.3\lvm.h" />
222 <ClInclude Include="src\lua-5.3\lzio.h" />
164 <ClInclude Include="src\MoonP\ast.hpp" /> 223 <ClInclude Include="src\MoonP\ast.hpp" />
224 <ClInclude Include="src\MoonP\moonplus.h" />
165 <ClInclude Include="src\MoonP\moon_ast.h" /> 225 <ClInclude Include="src\MoonP\moon_ast.h" />
166 <ClInclude Include="src\MoonP\moon_compiler.h" /> 226 <ClInclude Include="src\MoonP\moon_compiler.h" />
167 <ClInclude Include="src\MoonP\moon_parser.h" /> 227 <ClInclude Include="src\MoonP\moon_parser.h" />
168 <ClInclude Include="src\MoonP\parser.hpp" /> 228 <ClInclude Include="src\MoonP\parser.hpp" />
229 <ClInclude Include="src\MoonP\stacktraceplus.h" />
169 </ItemGroup> 230 </ItemGroup>
170 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> 231 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
171 <ImportGroup Label="ExtensionTargets"> 232 <ImportGroup Label="ExtensionTargets">
diff --git a/MoonPlus.vcxproj.filters b/MoonPlus.vcxproj.filters
index 6550779..6f3377e 100644
--- a/MoonPlus.vcxproj.filters
+++ b/MoonPlus.vcxproj.filters
@@ -8,6 +8,9 @@
8 <Filter Include="src\MoonP"> 8 <Filter Include="src\MoonP">
9 <UniqueIdentifier>{c88639d5-457d-42eb-b852-65682c89c618}</UniqueIdentifier> 9 <UniqueIdentifier>{c88639d5-457d-42eb-b852-65682c89c618}</UniqueIdentifier>
10 </Filter> 10 </Filter>
11 <Filter Include="src\lua-5.3">
12 <UniqueIdentifier>{338bdf98-6a02-4589-a373-c7bca25c746b}</UniqueIdentifier>
13 </Filter>
11 </ItemGroup> 14 </ItemGroup>
12 <ItemGroup> 15 <ItemGroup>
13 <ClCompile Include="src\MoonP\ast.cpp"> 16 <ClCompile Include="src\MoonP\ast.cpp">
@@ -25,6 +28,108 @@
25 <ClCompile Include="src\moonp.cpp"> 28 <ClCompile Include="src\moonp.cpp">
26 <Filter>src</Filter> 29 <Filter>src</Filter>
27 </ClCompile> 30 </ClCompile>
31 <ClCompile Include="src\MoonP\moonplus.cpp">
32 <Filter>src\MoonP</Filter>
33 </ClCompile>
34 <ClCompile Include="src\lua-5.3\lapi.c">
35 <Filter>src\lua-5.3</Filter>
36 </ClCompile>
37 <ClCompile Include="src\lua-5.3\lauxlib.c">
38 <Filter>src\lua-5.3</Filter>
39 </ClCompile>
40 <ClCompile Include="src\lua-5.3\lbaselib.c">
41 <Filter>src\lua-5.3</Filter>
42 </ClCompile>
43 <ClCompile Include="src\lua-5.3\lbitlib.c">
44 <Filter>src\lua-5.3</Filter>
45 </ClCompile>
46 <ClCompile Include="src\lua-5.3\lcode.c">
47 <Filter>src\lua-5.3</Filter>
48 </ClCompile>
49 <ClCompile Include="src\lua-5.3\lcorolib.c">
50 <Filter>src\lua-5.3</Filter>
51 </ClCompile>
52 <ClCompile Include="src\lua-5.3\lctype.c">
53 <Filter>src\lua-5.3</Filter>
54 </ClCompile>
55 <ClCompile Include="src\lua-5.3\ldblib.c">
56 <Filter>src\lua-5.3</Filter>
57 </ClCompile>
58 <ClCompile Include="src\lua-5.3\ldebug.c">
59 <Filter>src\lua-5.3</Filter>
60 </ClCompile>
61 <ClCompile Include="src\lua-5.3\ldo.c">
62 <Filter>src\lua-5.3</Filter>
63 </ClCompile>
64 <ClCompile Include="src\lua-5.3\ldump.c">
65 <Filter>src\lua-5.3</Filter>
66 </ClCompile>
67 <ClCompile Include="src\lua-5.3\lfunc.c">
68 <Filter>src\lua-5.3</Filter>
69 </ClCompile>
70 <ClCompile Include="src\lua-5.3\lgc.c">
71 <Filter>src\lua-5.3</Filter>
72 </ClCompile>
73 <ClCompile Include="src\lua-5.3\linit.c">
74 <Filter>src\lua-5.3</Filter>
75 </ClCompile>
76 <ClCompile Include="src\lua-5.3\liolib.c">
77 <Filter>src\lua-5.3</Filter>
78 </ClCompile>
79 <ClCompile Include="src\lua-5.3\llex.c">
80 <Filter>src\lua-5.3</Filter>
81 </ClCompile>
82 <ClCompile Include="src\lua-5.3\lmathlib.c">
83 <Filter>src\lua-5.3</Filter>
84 </ClCompile>
85 <ClCompile Include="src\lua-5.3\lmem.c">
86 <Filter>src\lua-5.3</Filter>
87 </ClCompile>
88 <ClCompile Include="src\lua-5.3\loadlib.c">
89 <Filter>src\lua-5.3</Filter>
90 </ClCompile>
91 <ClCompile Include="src\lua-5.3\lobject.c">
92 <Filter>src\lua-5.3</Filter>
93 </ClCompile>
94 <ClCompile Include="src\lua-5.3\lopcodes.c">
95 <Filter>src\lua-5.3</Filter>
96 </ClCompile>
97 <ClCompile Include="src\lua-5.3\loslib.c">
98 <Filter>src\lua-5.3</Filter>
99 </ClCompile>
100 <ClCompile Include="src\lua-5.3\lparser.c">
101 <Filter>src\lua-5.3</Filter>
102 </ClCompile>
103 <ClCompile Include="src\lua-5.3\lstate.c">
104 <Filter>src\lua-5.3</Filter>
105 </ClCompile>
106 <ClCompile Include="src\lua-5.3\lstring.c">
107 <Filter>src\lua-5.3</Filter>
108 </ClCompile>
109 <ClCompile Include="src\lua-5.3\lstrlib.c">
110 <Filter>src\lua-5.3</Filter>
111 </ClCompile>
112 <ClCompile Include="src\lua-5.3\ltable.c">
113 <Filter>src\lua-5.3</Filter>
114 </ClCompile>
115 <ClCompile Include="src\lua-5.3\ltablib.c">
116 <Filter>src\lua-5.3</Filter>
117 </ClCompile>
118 <ClCompile Include="src\lua-5.3\ltm.c">
119 <Filter>src\lua-5.3</Filter>
120 </ClCompile>
121 <ClCompile Include="src\lua-5.3\lundump.c">
122 <Filter>src\lua-5.3</Filter>
123 </ClCompile>
124 <ClCompile Include="src\lua-5.3\lutf8lib.c">
125 <Filter>src\lua-5.3</Filter>
126 </ClCompile>
127 <ClCompile Include="src\lua-5.3\lvm.c">
128 <Filter>src\lua-5.3</Filter>
129 </ClCompile>
130 <ClCompile Include="src\lua-5.3\lzio.c">
131 <Filter>src\lua-5.3</Filter>
132 </ClCompile>
28 </ItemGroup> 133 </ItemGroup>
29 <ItemGroup> 134 <ItemGroup>
30 <ClInclude Include="src\MoonP\ast.hpp"> 135 <ClInclude Include="src\MoonP\ast.hpp">
@@ -42,5 +147,86 @@
42 <ClInclude Include="src\MoonP\parser.hpp"> 147 <ClInclude Include="src\MoonP\parser.hpp">
43 <Filter>src\MoonP</Filter> 148 <Filter>src\MoonP</Filter>
44 </ClInclude> 149 </ClInclude>
150 <ClInclude Include="src\MoonP\moonplus.h">
151 <Filter>src\MoonP</Filter>
152 </ClInclude>
153 <ClInclude Include="src\MoonP\stacktraceplus.h">
154 <Filter>src\MoonP</Filter>
155 </ClInclude>
156 <ClInclude Include="src\lua-5.3\lapi.h">
157 <Filter>src\lua-5.3</Filter>
158 </ClInclude>
159 <ClInclude Include="src\lua-5.3\lauxlib.h">
160 <Filter>src\lua-5.3</Filter>
161 </ClInclude>
162 <ClInclude Include="src\lua-5.3\lcode.h">
163 <Filter>src\lua-5.3</Filter>
164 </ClInclude>
165 <ClInclude Include="src\lua-5.3\lctype.h">
166 <Filter>src\lua-5.3</Filter>
167 </ClInclude>
168 <ClInclude Include="src\lua-5.3\ldebug.h">
169 <Filter>src\lua-5.3</Filter>
170 </ClInclude>
171 <ClInclude Include="src\lua-5.3\ldo.h">
172 <Filter>src\lua-5.3</Filter>
173 </ClInclude>
174 <ClInclude Include="src\lua-5.3\lfunc.h">
175 <Filter>src\lua-5.3</Filter>
176 </ClInclude>
177 <ClInclude Include="src\lua-5.3\lgc.h">
178 <Filter>src\lua-5.3</Filter>
179 </ClInclude>
180 <ClInclude Include="src\lua-5.3\llex.h">
181 <Filter>src\lua-5.3</Filter>
182 </ClInclude>
183 <ClInclude Include="src\lua-5.3\llimits.h">
184 <Filter>src\lua-5.3</Filter>
185 </ClInclude>
186 <ClInclude Include="src\lua-5.3\lmem.h">
187 <Filter>src\lua-5.3</Filter>
188 </ClInclude>
189 <ClInclude Include="src\lua-5.3\lobject.h">
190 <Filter>src\lua-5.3</Filter>
191 </ClInclude>
192 <ClInclude Include="src\lua-5.3\lopcodes.h">
193 <Filter>src\lua-5.3</Filter>
194 </ClInclude>
195 <ClInclude Include="src\lua-5.3\lparser.h">
196 <Filter>src\lua-5.3</Filter>
197 </ClInclude>
198 <ClInclude Include="src\lua-5.3\lprefix.h">
199 <Filter>src\lua-5.3</Filter>
200 </ClInclude>
201 <ClInclude Include="src\lua-5.3\lstate.h">
202 <Filter>src\lua-5.3</Filter>
203 </ClInclude>
204 <ClInclude Include="src\lua-5.3\lstring.h">
205 <Filter>src\lua-5.3</Filter>
206 </ClInclude>
207 <ClInclude Include="src\lua-5.3\ltable.h">
208 <Filter>src\lua-5.3</Filter>
209 </ClInclude>
210 <ClInclude Include="src\lua-5.3\ltm.h">
211 <Filter>src\lua-5.3</Filter>
212 </ClInclude>
213 <ClInclude Include="src\lua-5.3\lua.h">
214 <Filter>src\lua-5.3</Filter>
215 </ClInclude>
216 <ClInclude Include="src\lua-5.3\luaconf.h">
217 <Filter>src\lua-5.3</Filter>
218 </ClInclude>
219 <ClInclude Include="src\lua-5.3\lualib.h">
220 <Filter>src\lua-5.3</Filter>
221 </ClInclude>
222 <ClInclude Include="src\lua-5.3\lundump.h">
223 <Filter>src\lua-5.3</Filter>
224 </ClInclude>
225 <ClInclude Include="src\lua-5.3\lvm.h">
226 <Filter>src\lua-5.3</Filter>
227 </ClInclude>
228 <ClInclude Include="src\lua-5.3\lzio.h">
229 <Filter>src\lua-5.3</Filter>
230 </ClInclude>
45 </ItemGroup> 231 </ItemGroup>
46</Project> \ No newline at end of file 232</Project> \ No newline at end of file
diff --git a/README.md b/README.md
index ea4c305..42da196 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,48 @@ f!
42 42
43The original Moonscript language 0.5.0 support can be found in the `0.5.0` branch. Moonscript with new features is in the master branch. Here are the new features introduced in MoonPlus. 43The original Moonscript language 0.5.0 support can be found in the `0.5.0` branch. Moonscript with new features is in the master branch. Here are the new features introduced in MoonPlus.
44 44
45* Add macro functions.
46```Moonscript
47-- file 'macro.moon'
48export macro block config = (debugging = true)->
49 global debugMode = debugging == "true"
50 ""
51
52export macro block asserts = (cond)->
53 debugMode and "assert #{cond}" or ""
54
55export macro expr assert = (cond)->
56 debugMode and "assert #{cond}" or "#{cond}"
57
58$config!
59
60-- file 'main.moon'
61import 'macro' as {:$config, :$assert, :$asserts}
62
63macro expr and = (...)->
64 "#{ table.concat {...}, ' and ' }"
65
66$asserts item ~= nil
67$config false
68value = $assert item
69
70if $and f1!, f2!, f3!
71 print "OK"
72```
73 Compiles to:
74```Lua
75-- file 'macro.moon'
76local _module_0 = { }
77return _module_0
78
79-- file 'main.moon'
80assert(item ~= nil)
81local value = item
82if (f1() and f2() and f3()) then
83 print("OK")
84end
85```
86
45* Move old `export` statement functions to `global` statement to match the `local` statement. 87* Move old `export` statement functions to `global` statement to match the `local` statement.
46 88
47* Change `export` statement behavier to support module management. Moon codes with `export` statement can not explicit return values in root scope. And codes with `export default` can export only one value as the module content. Use cases: 89* Change `export` statement behavier to support module management. Moon codes with `export` statement can not explicit return values in root scope. And codes with `export default` can export only one value as the module content. Use cases:
diff --git a/makefile b/makefile
index 14a7752..68f35be 100644
--- a/makefile
+++ b/makefile
@@ -10,15 +10,15 @@ SRC_PATH = ./src
10# Space-separated pkg-config libraries used by this project 10# Space-separated pkg-config libraries used by this project
11LIBS = 11LIBS =
12# General compiler flags 12# General compiler flags
13COMPILE_FLAGS = -std=c++17 -Wall -Wextra -g 13COMPILE_FLAGS = -std=c++17 -Wall -Wextra -g -DLUA_COMPAT_5_2 -DLUA_COMPAT_5_1
14# Additional release-specific flags 14# Additional release-specific flags
15RCOMPILE_FLAGS = -D NDEBUG -O3 15RCOMPILE_FLAGS = -D NDEBUG -O3
16# Additional debug-specific flags 16# Additional debug-specific flags
17DCOMPILE_FLAGS = -D DEBUG 17DCOMPILE_FLAGS = -D DEBUG
18# Add additional include paths 18# Add additional include paths
19INCLUDES = -I $(SRC_PATH) 19INCLUDES = -I $(SRC_PATH) -I ./src/lua-5.3
20# General linker settings 20# General linker settings
21LINK_FLAGS = -lpthread 21LINK_FLAGS = -L ./src/lua-5.3 -lpthread -llua
22# Additional release-specific linker settings 22# Additional release-specific linker settings
23RLINK_FLAGS = 23RLINK_FLAGS =
24# Additional debug-specific linker settings 24# Additional debug-specific linker settings
@@ -153,6 +153,7 @@ ifeq ($(USE_VERSION), true)
153else 153else
154 @echo "Beginning release build" 154 @echo "Beginning release build"
155endif 155endif
156 @$(MAKE) -C ./src/lua-5.3
156 @$(START_TIME) 157 @$(START_TIME)
157 @$(MAKE) all --no-print-directory 158 @$(MAKE) all --no-print-directory
158 @echo -n "Total build time: " 159 @echo -n "Total build time: "
@@ -166,6 +167,7 @@ ifeq ($(USE_VERSION), true)
166else 167else
167 @echo "Beginning debug build" 168 @echo "Beginning debug build"
168endif 169endif
170 @$(MAKE) -C ./src/lua-5.3
169 @$(START_TIME) 171 @$(START_TIME)
170 @$(MAKE) all --no-print-directory 172 @$(MAKE) all --no-print-directory
171 @echo -n "Total build time: " 173 @echo -n "Total build time: "
@@ -194,6 +196,7 @@ uninstall:
194# Removes all build files 196# Removes all build files
195.PHONY: clean 197.PHONY: clean
196clean: 198clean:
199 @$(MAKE) clean -C ./src/lua-5.3
197 @echo "Deleting $(BIN_NAME) symlink" 200 @echo "Deleting $(BIN_NAME) symlink"
198 @$(RM) $(BIN_NAME) 201 @$(RM) $(BIN_NAME)
199 @echo "Deleting directories" 202 @echo "Deleting directories"
diff --git a/spec/inputs/macro.moon b/spec/inputs/macro.moon
new file mode 100644
index 0000000..eb1e224
--- /dev/null
+++ b/spec/inputs/macro.moon
@@ -0,0 +1,69 @@
1macro block init = ->
2 with require "moonp"
3 package.moonpath = "?.moon;./spec/inputs/?.moon"
4 ""
5
6$init!
7
8import "macro_export" as {$myconfig:$config, :$showMacro, :$asserts, :$assert}
9
10$asserts item == nil
11
12$myconfig false
13
14v = $assert item == nil
15
16macro expr and = (...)->
17 values = [value for value in *{...}]
18 $showMacro "and", "#{ table.concat values, " and " }"
19
20if $and f1
21 print "OK"
22
23if $and f1,f2,f3
24 print "OK"
25
26macro expr map = (items,action)->
27 $showMacro "map", "[#{action} for _ in *#{items}]"
28
29macro expr filter = (items,action)->
30 $showMacro "filter", "[_ for _ in *#{items} when #{action}]"
31
32macro expr reduce = (items,def,action)->
33 $showMacro "reduce", "if ##{items} == 0
34 #{def}
35else
36 _1 = #{def}
37 for _2 in *#{items}
38 _1 = #{action}
39 _1"
40
41macro block foreach = (items,action)->
42 $showMacro "foreach", "for _ in *#{items}
43 #{action}"
44
45macro expr pipe = (...)->
46 switch select "#",...
47 when 0 then return ""
48 when 1 then return ...
49 ops = {...}
50 last = ops[1]
51 stmts = for i = 2,#ops
52 stmt = "\tlocal _#{i} = #{last} |> #{ops[i]}"
53 last = "_#{i}"
54 stmt
55 res = "do
56#{table.concat stmts,"\n"}
57 #{last}"
58 $showMacro "pipe", res
59
60{1,2,3} |> $map(_ * 2) |> $filter(_ > 4) |> $foreach print _
61
62$foreach $filter($map({1,2,3}, _ * 2), _ > 4), print _
63
64print $pipe(
65 {1, 2, 3}
66 $map(_ * 2)
67 $filter(_ > 4)
68 $reduce(0, _1 + _2)
69)
diff --git a/spec/inputs/macro_export.moon b/spec/inputs/macro_export.moon
new file mode 100644
index 0000000..369b83b
--- /dev/null
+++ b/spec/inputs/macro_export.moon
@@ -0,0 +1,29 @@
1export macro block config = (debugging = true)->
2 global debugMode = debugging == "true"
3 global debugMacro = true
4 ""
5
6export macro expr showMacro = (name,res)->
7 if debugMacro
8 "do
9 txt = #{res}
10 print '['..#{name}..']'
11 print txt
12 txt"
13 else
14 "#{res}"
15
16export macro block asserts = (cond)->
17 if debugMode
18 $showMacro "assert", "assert #{cond}"
19 else
20 ""
21
22export macro expr assert = (cond)->
23 if debugMode
24 $showMacro "assert", "assert #{cond}"
25 else
26 "#{cond}"
27
28$config!
29
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h
index 9fab215..0725bda 100644
--- a/src/MoonP/moon_ast.h
+++ b/src/MoonP/moon_ast.h
@@ -92,11 +92,19 @@ AST_NODE(NameList)
92 AST_MEMBER(NameList, &sep, &names) 92 AST_MEMBER(NameList, &sep, &names)
93AST_END(NameList) 93AST_END(NameList)
94 94
95class ExpListLow_t;
96
97AST_NODE(local_values)
98 ast_ptr<true, NameList_t> nameList;
99 ast_ptr<false, ExpListLow_t> valueList;
100 AST_MEMBER(local_values, &nameList, &valueList)
101AST_END(local_values)
102
95AST_NODE(Local) 103AST_NODE(Local)
96 ast_sel<true, local_flag_t, NameList_t> name; 104 ast_sel<true, local_flag_t, local_values_t> item;
97 std::list<std::string> forceDecls; 105 std::list<std::string> forceDecls;
98 std::list<std::string> decls; 106 std::list<std::string> decls;
99 AST_MEMBER(Local, &name) 107 AST_MEMBER(Local, &item)
100AST_END(Local) 108AST_END(Local)
101 109
102AST_NODE(colon_import_name) 110AST_NODE(colon_import_name)
@@ -116,12 +124,6 @@ AST_NODE(ImportLiteral)
116 AST_MEMBER(ImportLiteral, &sep, &inners) 124 AST_MEMBER(ImportLiteral, &sep, &inners)
117AST_END(ImportLiteral) 125AST_END(ImportLiteral)
118 126
119AST_NODE(ImportAs)
120 ast_ptr<true, ImportLiteral_t> literal;
121 ast_sel<false, Variable_t, TableLit_t> target;
122 AST_MEMBER(ImportAs, &literal, &target)
123AST_END(ImportAs)
124
125AST_NODE(ImportFrom) 127AST_NODE(ImportFrom)
126 ast_ptr<true, Seperator_t> sep; 128 ast_ptr<true, Seperator_t> sep;
127 ast_sel_list<true, colon_import_name_t, Variable_t> names; 129 ast_sel_list<true, colon_import_name_t, Variable_t> names;
@@ -129,6 +131,12 @@ AST_NODE(ImportFrom)
129 AST_MEMBER(ImportFrom, &sep, &names, &exp) 131 AST_MEMBER(ImportFrom, &sep, &names, &exp)
130AST_END(ImportFrom) 132AST_END(ImportFrom)
131 133
134AST_NODE(ImportAs)
135 ast_ptr<true, ImportLiteral_t> literal;
136 ast_sel<false, Variable_t, TableLit_t> target;
137 AST_MEMBER(ImportAs, &literal, &target)
138AST_END(ImportAs)
139
132AST_NODE(Import) 140AST_NODE(Import)
133 ast_sel<true, ImportAs_t, ImportFrom_t> content; 141 ast_sel<true, ImportAs_t, ImportFrom_t> content;
134 AST_MEMBER(Import, &content) 142 AST_MEMBER(Import, &content)
@@ -333,9 +341,10 @@ AST_NODE(Exp)
333AST_END(Exp) 341AST_END(Exp)
334 342
335class Parens_t; 343class Parens_t;
344class MacroName_t;
336 345
337AST_NODE(Callable) 346AST_NODE(Callable)
338 ast_sel<true, Variable_t, SelfName_t, VarArg_t, Parens_t> item; 347 ast_sel<true, Variable_t, SelfName_t, VarArg_t, Parens_t, MacroName_t> item;
339 AST_MEMBER(Callable, &item) 348 AST_MEMBER(Callable, &item)
340AST_END(Callable) 349AST_END(Callable)
341 350
@@ -469,9 +478,15 @@ AST_END(Value)
469AST_LEAF(default_value) 478AST_LEAF(default_value)
470AST_END(default_value) 479AST_END(default_value)
471 480
481AST_NODE(macro_name_pair)
482 ast_ptr<true, MacroName_t> key;
483 ast_ptr<true, MacroName_t> value;
484 AST_MEMBER(macro_name_pair, &key, &value)
485AST_END(macro_name_pair)
486
472AST_NODE(TableLit) 487AST_NODE(TableLit)
473 ast_ptr<true, Seperator_t> sep; 488 ast_ptr<true, Seperator_t> sep;
474 ast_sel_list<false, variable_pair_t, normal_pair_t, Exp_t> values; 489 ast_sel_list<false, variable_pair_t, normal_pair_t, Exp_t, MacroName_t, macro_name_pair_t> values;
475 AST_MEMBER(TableLit, &sep, &values) 490 AST_MEMBER(TableLit, &sep, &values)
476AST_END(TableLit) 491AST_END(TableLit)
477 492
@@ -517,9 +532,11 @@ AST_END(Global)
517AST_LEAF(export_default) 532AST_LEAF(export_default)
518AST_END(export_default) 533AST_END(export_default)
519 534
535class Macro_t;
536
520AST_NODE(Export) 537AST_NODE(Export)
521 ast_ptr<false, export_default_t> def; 538 ast_ptr<false, export_default_t> def;
522 ast_sel<true, ExpList_t, Exp_t> target; 539 ast_sel<true, ExpList_t, Exp_t, Macro_t> target;
523 ast_ptr<false, Assign_t> assign; 540 ast_ptr<false, Assign_t> assign;
524 AST_MEMBER(Export, &def, &target, &assign) 541 AST_MEMBER(Export, &def, &target, &assign)
525AST_END(Export) 542AST_END(Export)
@@ -558,6 +575,27 @@ AST_NODE(FunLit)
558 AST_MEMBER(FunLit, &argsDef, &arrow, &body) 575 AST_MEMBER(FunLit, &argsDef, &arrow, &body)
559AST_END(FunLit) 576AST_END(FunLit)
560 577
578AST_LEAF(macro_type)
579AST_END(macro_type)
580
581AST_NODE(MacroName)
582 ast_ptr<true, Name_t> name;
583 AST_MEMBER(MacroName, &name)
584AST_END(MacroName)
585
586AST_NODE(MacroLit)
587 ast_ptr<false, FnArgDefList_t> argsDef;
588 ast_ptr<true, Body_t> body;
589 AST_MEMBER(MacroLit, &argsDef, &body)
590AST_END(MacroLit)
591
592AST_NODE(Macro)
593 ast_ptr<true, macro_type_t> type;
594 ast_ptr<true, Name_t> name;
595 ast_ptr<true, MacroLit_t> macroLit;
596 AST_MEMBER(Macro, &type, &name, &macroLit)
597AST_END(Macro)
598
561AST_NODE(NameOrDestructure) 599AST_NODE(NameOrDestructure)
562 ast_sel<true, Variable_t, TableLit_t> item; 600 ast_sel<true, Variable_t, TableLit_t> item;
563 AST_MEMBER(NameOrDestructure, &item) 601 AST_MEMBER(NameOrDestructure, &item)
@@ -611,7 +649,7 @@ AST_END(BreakLoop)
611 649
612AST_NODE(Statement) 650AST_NODE(Statement)
613 ast_sel<true, Import_t, While_t, For_t, ForEach_t, 651 ast_sel<true, Import_t, While_t, For_t, ForEach_t,
614 Return_t, Local_t, Global_t, Export_t, BreakLoop_t, 652 Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t,
615 Backcall_t, ExpListAssign_t> content; 653 Backcall_t, ExpListAssign_t> content;
616 ast_ptr<false, statement_appendix_t> appendix; 654 ast_ptr<false, statement_appendix_t> appendix;
617 AST_MEMBER(Statement, &content, &appendix) 655 AST_MEMBER(Statement, &content, &appendix)
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp
index 1adfec9..046bf28 100644
--- a/src/MoonP/moon_compiler.cpp
+++ b/src/MoonP/moon_compiler.cpp
@@ -17,6 +17,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
17#include "MoonP/moon_parser.h" 17#include "MoonP/moon_parser.h"
18#include "MoonP/moon_compiler.h" 18#include "MoonP/moon_compiler.h"
19 19
20extern "C" {
21
22#include "lua.h"
23#include "lauxlib.h"
24#include "lualib.h"
25
26} // extern "C"
27
20namespace MoonP { 28namespace MoonP {
21using namespace std::string_view_literals; 29using namespace std::string_view_literals;
22using namespace parserlib; 30using namespace parserlib;
@@ -32,11 +40,44 @@ inline std::string s(std::string_view sv) {
32} 40}
33 41
34const char* moonScriptVersion() { 42const char* moonScriptVersion() {
35 return "0.5.0-r0.2.0"; 43 return "0.5.0-r0.3.0";
36} 44}
37 45
46// name of table stored in lua registry
47#define MOONP_MODULE "_modules_"
48
38class MoonCompilerImpl { 49class MoonCompilerImpl {
39public: 50public:
51 MoonCompilerImpl(lua_State* sharedState,
52 const std::function<void(void*)>& luaOpen,
53 bool sameModule,
54 std::string_view moduleName = {}):
55 L(sharedState),
56 _luaOpen(luaOpen),
57 _moduleName(moduleName) {
58 int top = -1;
59 BLOCK_START
60 BREAK_IF(!sameModule);
61 BREAK_IF(!L);
62 top = lua_gettop(L);
63 lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE
64 lua_rawget(L, LUA_REGISTRYINDEX); // reg[MOONP_MODULE], tb
65 BREAK_IF(lua_istable(L, -1) == 0);
66 int idx = static_cast<int>(lua_objlen(L, -1)); // idx = #tb, tb
67 BREAK_IF(idx == 0);
68 _useModule = true;
69 _sameModule = true;
70 BLOCK_END
71 if (top != -1) lua_settop(L, top);
72 }
73
74 ~MoonCompilerImpl() {
75 if (L && _stateOwner) {
76 lua_close(L);
77 L = nullptr;
78 }
79 }
80
40 std::tuple<std::string,std::string,GlobalVars> compile(std::string_view codes, const MoonConfig& config) { 81 std::tuple<std::string,std::string,GlobalVars> compile(std::string_view codes, const MoonConfig& config) {
41 _config = config; 82 _config = config;
42 _info = _parser.parse<File_t>(codes); 83 _info = _parser.parse<File_t>(codes);
@@ -83,8 +124,23 @@ public:
83 _joinBuf.str(""); 124 _joinBuf.str("");
84 _joinBuf.clear(); 125 _joinBuf.clear();
85 _globals.clear(); 126 _globals.clear();
127 if (_useModule) {
128 _useModule = false;
129 if (!_sameModule) {
130 lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE
131 lua_rawget(L, LUA_REGISTRYINDEX); // reg[MOONP_MODULE], tb
132 int idx = static_cast<int>(lua_objlen(L, -1));
133 lua_pushnil(L); // tb nil
134 lua_rawseti(L, -2, idx); // tb[idx] = nil, tb
135 lua_pop(L, 1); // empty
136 }
137 }
86 } 138 }
87private: 139private:
140 bool _stateOwner = false;
141 bool _useModule = false;
142 bool _sameModule = false;
143 lua_State* L = nullptr;
88 MoonConfig _config; 144 MoonConfig _config;
89 MoonParser _parser; 145 MoonParser _parser;
90 ParseInfo _info; 146 ParseInfo _info;
@@ -97,6 +153,9 @@ private:
97 std::ostringstream _buf; 153 std::ostringstream _buf;
98 std::ostringstream _joinBuf; 154 std::ostringstream _joinBuf;
99 const std::string _newLine = "\n"; 155 const std::string _newLine = "\n";
156 std::function<void(void*)> _luaOpen;
157 std::string _moduleName;
158
100 enum class LocalMode { 159 enum class LocalMode {
101 None = 0, 160 None = 0,
102 Capital = 1, 161 Capital = 1,
@@ -254,7 +313,7 @@ private:
254 313
255 const std::string nll(ast_node* node) const { 314 const std::string nll(ast_node* node) const {
256 if (_config.reserveLineNumber) { 315 if (_config.reserveLineNumber) {
257 return s(" -- "sv) + std::to_string(node->m_begin.m_line) + _newLine; 316 return s(" -- "sv) + std::to_string(node->m_begin.m_line + _config.lineOffset) + _newLine;
258 } else { 317 } else {
259 return _newLine; 318 return _newLine;
260 } 319 }
@@ -262,7 +321,7 @@ private:
262 321
263 const std::string nlr(ast_node* node) const { 322 const std::string nlr(ast_node* node) const {
264 if (_config.reserveLineNumber) { 323 if (_config.reserveLineNumber) {
265 return s(" -- "sv) + std::to_string(node->m_end.m_line) + _newLine; 324 return s(" -- "sv) + std::to_string(node->m_end.m_line + _config.lineOffset) + _newLine;
266 } else { 325 } else {
267 return _newLine; 326 return _newLine;
268 } 327 }
@@ -383,9 +442,13 @@ private:
383 template <class T> 442 template <class T>
384 ast_ptr<false, T> toAst(std::string_view codes, ast_node* parent) { 443 ast_ptr<false, T> toAst(std::string_view codes, ast_node* parent) {
385 auto res = _parser.parse<T>(s(codes)); 444 auto res = _parser.parse<T>(s(codes));
445 int line = parent->m_begin.m_line;
446 int col = parent->m_begin.m_line;
386 res.node->traverse([&](ast_node* node) { 447 res.node->traverse([&](ast_node* node) {
387 node->m_begin.m_line = parent->m_begin.m_line; 448 node->m_begin.m_line = line;
388 node->m_end.m_line = parent->m_begin.m_line; 449 node->m_end.m_line = line;
450 node->m_begin.m_col = col;
451 node->m_end.m_col = col;
389 return traversal::Continue; 452 return traversal::Continue;
390 }); 453 });
391 _codeCache.push_back(std::move(res.codes)); 454 _codeCache.push_back(std::move(res.codes));
@@ -401,10 +464,14 @@ private:
401 EndWithColon, 464 EndWithColon,
402 EndWithEOP, 465 EndWithEOP,
403 HasEOP, 466 HasEOP,
404 HasKeyword 467 HasKeyword,
468 Macro
405 }; 469 };
406 470
407 ChainType specialChainValue(ChainValue_t* chainValue) const { 471 ChainType specialChainValue(ChainValue_t* chainValue) const {
472 if (isMacroChain(chainValue)) {
473 return ChainType::Macro;
474 }
408 if (ast_is<ColonChainItem_t>(chainValue->items.back())) { 475 if (ast_is<ColonChainItem_t>(chainValue->items.back())) {
409 return ChainType::EndWithColon; 476 return ChainType::EndWithColon;
410 } 477 }
@@ -531,7 +598,7 @@ private:
531 for (auto exp_ : expList->exprs.objects()) { 598 for (auto exp_ : expList->exprs.objects()) {
532 Exp_t* exp = static_cast<Exp_t*>(exp_); 599 Exp_t* exp = static_cast<Exp_t*>(exp_);
533 if (!isAssignable(exp)) { 600 if (!isAssignable(exp)) {
534 throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, exp)); 601 throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, exp));
535 } 602 }
536 } 603 }
537 } 604 }
@@ -551,6 +618,21 @@ private:
551 return backcall; 618 return backcall;
552 } 619 }
553 620
621 bool isMacroChain(ChainValue_t* chainValue) const {
622 const auto& chainList = chainValue->items.objects();
623 BLOCK_START
624 auto callable = ast_cast<Callable_t>(chainList.front());
625 BREAK_IF(!callable);
626 BREAK_IF(!callable->item.is<MacroName_t>());
627 if (chainList.size() == 1 ||
628 !ast_is<Invoke_t,InvokeArgs_t>(*(++chainList.begin()))) {
629 throw std::logic_error(_info.errorMessage("macro expression must be followed by argument list"sv, callable));
630 }
631 return true;
632 BLOCK_END
633 return false;
634 }
635
554 void transformStatement(Statement_t* statement, str_list& out) { 636 void transformStatement(Statement_t* statement, str_list& out) {
555 auto x = statement; 637 auto x = statement;
556 if (statement->appendix) { 638 if (statement->appendix) {
@@ -667,6 +749,7 @@ private:
667 case id<Local_t>(): transformLocal(static_cast<Local_t*>(content), out); break; 749 case id<Local_t>(): transformLocal(static_cast<Local_t*>(content), out); break;
668 case id<Global_t>(): transformGlobal(static_cast<Global_t*>(content), out); break; 750 case id<Global_t>(): transformGlobal(static_cast<Global_t*>(content), out); break;
669 case id<Export_t>(): transformExport(static_cast<Export_t*>(content), out); break; 751 case id<Export_t>(): transformExport(static_cast<Export_t*>(content), out); break;
752 case id<Macro_t>(): transformMacro(static_cast<Macro_t*>(content), out, false); break;
670 case id<BreakLoop_t>(): transformBreakLoop(static_cast<BreakLoop_t*>(content), out); break; 753 case id<BreakLoop_t>(): transformBreakLoop(static_cast<BreakLoop_t*>(content), out); break;
671 case id<ExpListAssign_t>(): { 754 case id<ExpListAssign_t>(): {
672 auto expListAssign = static_cast<ExpListAssign_t*>(content); 755 auto expListAssign = static_cast<ExpListAssign_t*>(content);
@@ -712,7 +795,7 @@ private:
712 break; 795 break;
713 } 796 }
714 } 797 }
715 throw std::logic_error(_info.errorMessage("Expression list is not supported here."sv, expList)); 798 throw std::logic_error(_info.errorMessage("expression list is not supported here"sv, expList));
716 } 799 }
717 break; 800 break;
718 } 801 }
@@ -762,7 +845,7 @@ private:
762 BLOCK_END 845 BLOCK_END
763 } 846 }
764 } else { 847 } else {
765 throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, exp)); 848 throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, exp));
766 } 849 }
767 } 850 }
768 return preDefs; 851 return preDefs;
@@ -791,7 +874,7 @@ private:
791 BLOCK_END 874 BLOCK_END
792 } 875 }
793 } else { 876 } else {
794 throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, exp)); 877 throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, exp));
795 } 878 }
796 } 879 }
797 return defs; 880 return defs;
@@ -950,6 +1033,7 @@ private:
950 return; 1033 return;
951 } 1034 }
952 case ChainType::HasKeyword: 1035 case ChainType::HasKeyword:
1036 case ChainType::Macro:
953 transformChainValue(chainValue, out, ExpUsage::Assignment, expList); 1037 transformChainValue(chainValue, out, ExpUsage::Assignment, expList);
954 return; 1038 return;
955 case ChainType::Common: 1039 case ChainType::Common:
@@ -1041,7 +1125,7 @@ private:
1041 const node_container* tableItems = nullptr; 1125 const node_container* tableItems = nullptr;
1042 if (ast_is<Exp_t>(node)) { 1126 if (ast_is<Exp_t>(node)) {
1043 auto item = singleValueFrom(node)->item.get(); 1127 auto item = singleValueFrom(node)->item.get();
1044 if (!item) throw std::logic_error(_info.errorMessage("Invalid destructure value."sv, node)); 1128 if (!item) throw std::logic_error(_info.errorMessage("invalid destructure value"sv, node));
1045 auto tbA = item->getByPath<TableLit_t>(); 1129 auto tbA = item->getByPath<TableLit_t>();
1046 if (tbA) { 1130 if (tbA) {
1047 tableItems = &tbA->values.objects(); 1131 tableItems = &tbA->values.objects();
@@ -1059,7 +1143,7 @@ private:
1059 case id<Exp_t>(): { 1143 case id<Exp_t>(): {
1060 ++index; 1144 ++index;
1061 if (!isAssignable(static_cast<Exp_t*>(pair))) { 1145 if (!isAssignable(static_cast<Exp_t*>(pair))) {
1062 throw std::logic_error(_info.errorMessage("Can't destructure value."sv, pair)); 1146 throw std::logic_error(_info.errorMessage("can't destructure value"sv, pair));
1063 } 1147 }
1064 auto value = singleValueFrom(pair); 1148 auto value = singleValueFrom(pair);
1065 auto item = value->item.get(); 1149 auto item = value->item.get();
@@ -1103,9 +1187,9 @@ private:
1103 case id<normal_pair_t>(): { 1187 case id<normal_pair_t>(): {
1104 auto np = static_cast<normal_pair_t*>(pair); 1188 auto np = static_cast<normal_pair_t*>(pair);
1105 auto key = np->key->getByPath<Name_t>(); 1189 auto key = np->key->getByPath<Name_t>();
1106 if (!key) throw std::logic_error(_info.errorMessage("Invalid key for destructure."sv, np)); 1190 if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, np));
1107 if (auto exp = np->value.as<Exp_t>()) { 1191 if (auto exp = np->value.as<Exp_t>()) {
1108 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("Can't destructure value."sv, exp)); 1192 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp));
1109 auto item = singleValueFrom(exp)->item.get(); 1193 auto item = singleValueFrom(exp)->item.get();
1110 if (ast_is<simple_table_t>(item) || 1194 if (ast_is<simple_table_t>(item) ||
1111 item->getByPath<TableLit_t>()) { 1195 item->getByPath<TableLit_t>()) {
@@ -1227,11 +1311,11 @@ private:
1227 auto action = assignment->action.get(); 1311 auto action = assignment->action.get();
1228 switch (action->getId()) { 1312 switch (action->getId()) {
1229 case id<Update_t>(): { 1313 case id<Update_t>(): {
1230 if (expList->exprs.size() > 1) throw std::logic_error(_info.errorMessage("Can not apply update to multiple values."sv, expList)); 1314 if (expList->exprs.size() > 1) throw std::logic_error(_info.errorMessage("can not apply update to multiple values"sv, expList));
1231 auto update = static_cast<Update_t*>(action); 1315 auto update = static_cast<Update_t*>(action);
1232 auto leftExp = static_cast<Exp_t*>(expList->exprs.objects().front()); 1316 auto leftExp = static_cast<Exp_t*>(expList->exprs.objects().front());
1233 auto leftValue = singleValueFrom(leftExp); 1317 auto leftValue = singleValueFrom(leftExp);
1234 if (!leftValue) throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, leftExp)); 1318 if (!leftValue) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftExp));
1235 if (auto chain = leftValue->getByPath<ChainValue_t>()) { 1319 if (auto chain = leftValue->getByPath<ChainValue_t>()) {
1236 auto tmpChain = x->new_ptr<ChainValue_t>(); 1320 auto tmpChain = x->new_ptr<ChainValue_t>();
1237 for (auto item : chain->items.objects()) { 1321 for (auto item : chain->items.objects()) {
@@ -1544,7 +1628,7 @@ private:
1544 args->swap(a, arg); 1628 args->swap(a, arg);
1545 findPlaceHolder = true; 1629 findPlaceHolder = true;
1546 } else { 1630 } else {
1547 throw std::logic_error(_info.errorMessage("backcall placeholder can be used only in one place."sv, a)); 1631 throw std::logic_error(_info.errorMessage("backcall placeholder can be used only in one place"sv, a));
1548 } 1632 }
1549 } 1633 }
1550 } 1634 }
@@ -1576,7 +1660,7 @@ private:
1576 } 1660 }
1577 return; 1661 return;
1578 } else { 1662 } else {
1579 throw std::logic_error(_info.errorMessage("Backcall operator must be followed by chain value."sv, opValue->value)); 1663 throw std::logic_error(_info.errorMessage("backcall operator must be followed by chain value"sv, opValue->value));
1580 } 1664 }
1581 } 1665 }
1582 } 1666 }
@@ -1789,7 +1873,7 @@ private:
1789 args->swap(a, arg); 1873 args->swap(a, arg);
1790 findPlaceHolder = true; 1874 findPlaceHolder = true;
1791 } else { 1875 } else {
1792 throw std::logic_error(_info.errorMessage("Backcall placeholder can be used only in one place."sv, a)); 1876 throw std::logic_error(_info.errorMessage("backcall placeholder can be used only in one place"sv, a));
1793 } 1877 }
1794 } 1878 }
1795 } 1879 }
@@ -1820,21 +1904,27 @@ private:
1820 return; 1904 return;
1821 } 1905 }
1822 if (auto local = stmt->content.as<Local_t>()) { 1906 if (auto local = stmt->content.as<Local_t>()) {
1823 if (auto flag = local->name.as<local_flag_t>()) { 1907 switch (local->item->getId()) {
1824 LocalMode newMode = _parser.toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; 1908 case id<local_flag_t>(): {
1825 if (int(newMode) > int(mode)) { 1909 auto flag = local->item.to<local_flag_t>();
1826 mode = newMode; 1910 LocalMode newMode = _parser.toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital;
1827 } 1911 if (int(newMode) > int(mode)) {
1828 if (mode == LocalMode::Any) { 1912 mode = newMode;
1829 if (!any) any = local; 1913 }
1830 if (!capital) capital = local; 1914 if (mode == LocalMode::Any) {
1831 } else { 1915 if (!any) any = local;
1832 if (!capital) capital = local; 1916 if (!capital) capital = local;
1917 } else {
1918 if (!capital) capital = local;
1919 }
1920 break;
1833 } 1921 }
1834 } else { 1922 case id<local_values_t>(): {
1835 auto names = local->name.to<NameList_t>(); 1923 auto values = local->item.to<local_values_t>();
1836 for (auto name : names->names.objects()) { 1924 for (auto name : values->nameList->names.objects()) {
1837 local->forceDecls.push_back(_parser.toString(name)); 1925 local->forceDecls.push_back(_parser.toString(name));
1926 }
1927 break;
1838 } 1928 }
1839 } 1929 }
1840 } else if (mode != LocalMode::None) { 1930 } else if (mode != LocalMode::None) {
@@ -1960,11 +2050,190 @@ private:
1960 } 2050 }
1961 } 2051 }
1962 2052
2053 void pushCurrentModule() {
2054 if (_useModule) {
2055 lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE
2056 lua_rawget(L, LUA_REGISTRYINDEX); // reg[MOONP_MODULE], tb
2057 int idx = static_cast<int>(lua_objlen(L, -1)); // idx = #tb, tb
2058 lua_rawgeti(L, -1, idx); // tb[idx], tb cur
2059 lua_remove(L, -2); // cur
2060 return;
2061 }
2062 _useModule = true;
2063 if (!L) {
2064 L = luaL_newstate();
2065 if (_luaOpen) {
2066 _luaOpen(static_cast<void*>(L));
2067 }
2068 _stateOwner = true;
2069 }
2070 lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE
2071 lua_rawget(L, LUA_REGISTRYINDEX); // reg[MOONP_MODULE], tb
2072 if (lua_isnil(L, -1) != 0) { // tb == nil
2073 lua_pop(L, 1);
2074 lua_newtable(L); // tb
2075 lua_pushliteral(L, MOONP_MODULE); // tb MOONP_MODULE
2076 lua_pushvalue(L, -2); // tb MOONP_MODULE tb
2077 lua_rawset(L, LUA_REGISTRYINDEX); // reg[MOONP_MODULE] = tb, tb
2078 } // tb
2079 int idx = static_cast<int>(lua_objlen(L, -1)); // idx = #tb, tb
2080 lua_newtable(L); // tb cur
2081 lua_pushvalue(L, -1); // tb cur cur
2082 lua_rawseti(L, -3, idx + 1); // tb[idx + 1] = cur, tb cur
2083 lua_remove(L, -2); // cur
2084 }
2085
2086 void pushMoonp(std::string_view name) {
2087 lua_getglobal(L, "package"); // package
2088 lua_getfield(L, -1, "loaded"); // package loaded
2089 lua_getfield(L, -1, "moonp"); // package loaded moonp
2090 lua_pushlstring(L, &name.front(), name.size()); // package loaded moonp name
2091 lua_gettable(L, -2); // loaded[name], package loaded moonp item
2092 lua_insert(L, -4); // item package loaded moonp
2093 lua_pop(L, 3); // item
2094 }
2095
2096 void hideStackTrace(bool hide) {
2097 lua_getglobal(L, "package"); // package
2098 lua_getfield(L, -1, "loaded"); // package loaded
2099 lua_getfield(L, -1, "moonp"); // package loaded moonp
2100 if (hide) {
2101 lua_pushboolean(L, 1); // package loaded moonp true
2102 } else {
2103 lua_pushnil(L); // package loaded moonp nil
2104 }
2105 lua_setfield(L, -2, "_hide_stacktrace_");
2106 lua_pop(L, 3); // empty
2107 }
2108
2109 bool isModuleLoaded(std::string_view name) {
2110 int top = lua_gettop(L);
2111 lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE
2112 lua_rawget(L, LUA_REGISTRYINDEX); // modules
2113 lua_pushlstring(L, &name.front(), name.size());
2114 lua_rawget(L, -2); // modules module
2115 if (lua_isnil(L, -1) != 0) {
2116 lua_settop(L, top);
2117 return false;
2118 }
2119 lua_settop(L, top);
2120 return true;
2121 }
2122
2123 void pushModuleTable(std::string_view name) {
2124 lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE
2125 lua_rawget(L, LUA_REGISTRYINDEX); // modules
2126 lua_pushlstring(L, &name.front(), name.size());
2127 lua_rawget(L, -2); // modules module
2128 if (lua_isnil(L, -1) != 0) {
2129 lua_pop(L, 1);
2130 lua_newtable(L); // modules module
2131 lua_pushlstring(L, &name.front(), name.size());
2132 lua_pushvalue(L, -2); // modules module name module
2133 lua_rawset(L, -4); // modules[name] = module, modules module
2134 }
2135 lua_remove(L, -2); // module
2136 }
2137
2138 void pushOptions(int lineOffset) {
2139 lua_newtable(L);
2140 lua_pushliteral(L, "lint_global");
2141 lua_pushboolean(L, 0);
2142 lua_rawset(L, -3);
2143 lua_pushliteral(L, "implicit_return_root");
2144 lua_pushboolean(L, 1);
2145 lua_rawset(L, -3);
2146 lua_pushliteral(L, "reserve_line_number");
2147 lua_pushboolean(L, 1);
2148 lua_rawset(L, -3);
2149 lua_pushliteral(L, "same_module");
2150 lua_pushboolean(L, 1);
2151 lua_rawset(L, -3);
2152 lua_pushliteral(L, "line_offset");
2153 lua_pushinteger(L, lineOffset);
2154 lua_rawset(L, -3);
2155 }
2156
2157 void transformMacro(Macro_t* macro, str_list& out, bool exporting) {
2158 auto type = _parser.toString(macro->type);
2159 auto macroName = _parser.toString(macro->name);
2160 auto argsDef = macro->macroLit->argsDef.get();
2161 str_list newArgs;
2162 if (argsDef) {
2163 for (auto def_ : argsDef->definitions.objects()) {
2164 auto def = static_cast<FnArgDef_t*>(def_);
2165 if (def->name.is<SelfName_t>()) {
2166 throw std::logic_error(_info.errorMessage("self name is not supported here"sv, def->name));
2167 } else {
2168 std::string defVal;
2169 if (def->defaultValue) {
2170 defVal = _parser.toString(def->defaultValue);
2171 Utils::trim(defVal);
2172 defVal.insert(0, "=[==========["sv);
2173 defVal.append("]==========]"sv);
2174 }
2175 newArgs.emplace_back(_parser.toString(def->name) + defVal);
2176 }
2177 }
2178 if (argsDef->varArg) {
2179 newArgs.emplace_back(_parser.toString(argsDef->varArg));
2180 }
2181 }
2182 _buf << "fmacro = ("sv << join(newArgs, ","sv) << ")->"sv;
2183 _buf << _parser.toString(macro->macroLit->body) << '\n';
2184 _buf << "{fmacro, \"" << type << "\"}"sv;
2185 auto macroCodes = clearBuf();
2186 _buf << "=(macro "sv << macroName << ")";
2187 auto chunkName = clearBuf();
2188 pushCurrentModule(); // cur
2189 int top = lua_gettop(L) - 1;
2190 pushMoonp("loadstring"sv); // cur loadstring
2191 lua_pushlstring(L, macroCodes.c_str(), macroCodes.size()); // cur loadstring codes
2192 lua_pushlstring(L, chunkName.c_str(), chunkName.size()); // cur loadstring codes chunk
2193 pushOptions(macro->m_begin.m_line - 1); // cur loadstring codes chunk options
2194 if (lua_pcall(L, 3, 2, 0) != 0) { // loadstring(codes,chunk,options), cur f err
2195 std::string err = lua_tostring(L, -1);
2196 lua_settop(L, top);
2197 throw std::logic_error(_info.errorMessage(s("fail to load macro codes\n"sv) + err, macro->macroLit));
2198 } // cur f err
2199 if (lua_isnil(L, -2) != 0) { // f == nil, cur f err
2200 std::string err = lua_tostring(L, -1);
2201 lua_settop(L, top);
2202 throw std::logic_error(_info.errorMessage(s("fail to load macro codes, at (macro "sv) + macroName + s("): "sv) + err, macro->macroLit));
2203 }
2204 lua_pop(L, 1); // cur f
2205 pushMoonp("pcall"sv); // cur f pcall
2206 lua_insert(L, -2); // cur pcall f
2207 if (lua_pcall(L, 1, 2, 0) != 0) { // f(), cur success macro
2208 std::string err = lua_tostring(L, -1);
2209 lua_settop(L, top);
2210 throw std::logic_error(_info.errorMessage(s("fail to generate macro function\n"sv) + err, macro->macroLit));
2211 } // cur success res
2212 if (lua_toboolean(L, -2) == 0) {
2213 std::string err = lua_tostring(L, -1);
2214 lua_settop(L, top);
2215 throw std::logic_error(_info.errorMessage(s("fail to generate macro function\n"sv) + err, macro->macroLit));
2216 } // cur true macro
2217 lua_remove(L, -2); // cur macro
2218 if (exporting && !_moduleName.empty()) {
2219 pushModuleTable(_moduleName); // cur macro module
2220 lua_pushlstring(L, macroName.c_str(), macroName.size()); // cur macro module name
2221 lua_pushvalue(L, -3); // cur macro module name macro
2222 lua_rawset(L, -3); // cur macro module
2223 lua_pop(L, 1);
2224 } // cur macro
2225 lua_pushlstring(L, macroName.c_str(), macroName.size()); // cur macro name
2226 lua_insert(L, -2); // cur name macro
2227 lua_rawset(L, -3); // cur[name] = macro, cur
2228 lua_settop(L, top);
2229 out.push_back(Empty);
2230 }
2231
1963 void transformReturn(Return_t* returnNode, str_list& out) { 2232 void transformReturn(Return_t* returnNode, str_list& out) {
1964 if (!enableReturn.top()) { 2233 if (!enableReturn.top()) {
1965 ast_node* target = returnNode->valueList.get(); 2234 ast_node* target = returnNode->valueList.get();
1966 if (!target) target = returnNode; 2235 if (!target) target = returnNode;
1967 throw std::logic_error(_info.errorMessage("Illegal return statement here."sv, target)); 2236 throw std::logic_error(_info.errorMessage("illegal return statement here"sv, target));
1968 } 2237 }
1969 if (auto valueList = returnNode->valueList.get()) { 2238 if (auto valueList = returnNode->valueList.get()) {
1970 if (valueList->exprs.size() == 1) { 2239 if (valueList->exprs.size() == 1) {
@@ -2286,7 +2555,7 @@ private:
2286 chainValue->items.pop_back(); 2555 chainValue->items.pop_back();
2287 if (chainValue->items.empty()) { 2556 if (chainValue->items.empty()) {
2288 if (_withVars.empty()) { 2557 if (_withVars.empty()) {
2289 throw std::logic_error(_info.errorMessage("Short dot/colon syntax must be called within a with block."sv, x)); 2558 throw std::logic_error(_info.errorMessage("short dot/colon syntax must be called within a with block"sv, x));
2290 } 2559 }
2291 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x)); 2560 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x));
2292 } 2561 }
@@ -2417,7 +2686,7 @@ private:
2417 case id<DotChainItem_t>(): 2686 case id<DotChainItem_t>():
2418 case id<ColonChainItem_t>(): 2687 case id<ColonChainItem_t>():
2419 if (_withVars.empty()) { 2688 if (_withVars.empty()) {
2420 throw std::logic_error(_info.errorMessage("Short dot/colon syntax must be called within a with block."sv, chainList.front())); 2689 throw std::logic_error(_info.errorMessage("short dot/colon syntax must be called within a with block"sv, chainList.front()));
2421 } else { 2690 } else {
2422 baseChain->items.push_back(toAst<Callable_t>(_withVars.top(), x)); 2691 baseChain->items.push_back(toAst<Callable_t>(_withVars.top(), x));
2423 } 2692 }
@@ -2499,7 +2768,7 @@ private:
2499 case id<DotChainItem_t>(): 2768 case id<DotChainItem_t>():
2500 case id<ColonChainItem_t>(): 2769 case id<ColonChainItem_t>():
2501 if (_withVars.empty()) { 2770 if (_withVars.empty()) {
2502 throw std::logic_error(_info.errorMessage("Short dot/colon syntax must be called within a with block."sv, x)); 2771 throw std::logic_error(_info.errorMessage("short dot/colon syntax must be called within a with block"sv, x));
2503 } else { 2772 } else {
2504 temp.push_back(_withVars.top()); 2773 temp.push_back(_withVars.top());
2505 } 2774 }
@@ -2531,7 +2800,7 @@ private:
2531 --next; 2800 --next;
2532 } 2801 }
2533 if (!ast_is<Invoke_t, InvokeArgs_t>(followItem)) { 2802 if (!ast_is<Invoke_t, InvokeArgs_t>(followItem)) {
2534 throw std::logic_error(_info.errorMessage("Colon chain item must be followed by invoke arguments."sv, colonItem)); 2803 throw std::logic_error(_info.errorMessage("colon chain item must be followed by invoke arguments"sv, colonItem));
2535 } 2804 }
2536 if (colonItem->name.is<LuaKeyword_t>()) { 2805 if (colonItem->name.is<LuaKeyword_t>()) {
2537 std::string callVar; 2806 std::string callVar;
@@ -2667,7 +2936,172 @@ private:
2667 } 2936 }
2668 } 2937 }
2669 2938
2939 std::pair<std::string,std::string> expandMacroStr(ChainValue_t* chainValue) {
2940 const auto& chainList = chainValue->items.objects();
2941 auto callable = ast_cast<Callable_t>(chainList.front());
2942 auto macroName = _parser.toString(callable->item.to<MacroName_t>()->name);
2943 if (!_useModule) {
2944 throw std::logic_error(_info.errorMessage("can not resolve macro", callable->item));
2945 }
2946 pushCurrentModule(); // cur
2947 int top = lua_gettop(L) - 1;
2948 lua_pushlstring(L, macroName.c_str(), macroName.size()); // cur macroName
2949 lua_rawget(L, -2); // cur[macroName], cur macro
2950 if (lua_istable(L, -1) == 0) {
2951 lua_settop(L, top);
2952 throw std::logic_error(_info.errorMessage("can not resolve macro", callable->item));
2953 }
2954 lua_rawgeti(L, -1, 1); // cur macro func
2955 pushMoonp("pcall"sv); // cur macro func pcall
2956 lua_insert(L, -2); // cur macro pcall func
2957 auto item = *(++chainList.begin());
2958 const node_container* args = nullptr;
2959 if (auto invoke = ast_cast<Invoke_t>(item)) {
2960 args = &invoke->args.objects();
2961 } else {
2962 args = &ast_to<InvokeArgs_t>(item)->args.objects();
2963 }
2964 for (auto arg : *args) {
2965 std::string str;
2966 if (auto exp = ast_cast<Exp_t>(arg)) {
2967 // patch for backcall operator support
2968 BLOCK_START
2969 BREAK_IF(arg->m_begin.m_line != arg->m_end.m_line ||
2970 arg->m_begin.m_col != arg->m_end.m_col);
2971 BREAK_IF(!exp->opValues.empty());
2972 auto chainValue = exp->getByPath<Value_t, ChainValue_t>();
2973 BREAK_IF(!chainValue);
2974 BREAK_IF(!isMacroChain(chainValue));
2975 BREAK_IF(chainValue->items.size() != 2);
2976 std::string type, codes;
2977 std::tie(type, codes) = expandMacroStr(chainValue);
2978 str = codes;
2979 BLOCK_END
2980 if (str.empty()) {
2981 str = _parser.toString(exp->value);
2982 for (auto opVal : exp->opValues.objects()) {
2983 str += _parser.toString(opVal);
2984 }
2985 }
2986 } else str = _parser.toString(arg);
2987 Utils::trim(str);
2988 lua_pushlstring(L, str.c_str(), str.size());
2989 } // cur macro pcall func args...
2990 hideStackTrace(true);
2991 bool success = lua_pcall(L, static_cast<int>(args->size()) + 1, 2, 0) == 0;
2992 if (!success) { // cur macro err
2993 std::string err = lua_tostring(L, -1);
2994 lua_settop(L, top);
2995 throw std::logic_error(_info.errorMessage(s("fail to expand macro\n"sv) + err, callable));
2996 } // cur macro success res
2997 hideStackTrace(false);
2998 if (lua_toboolean(L, -2) == 0) {
2999 std::string err = lua_tostring(L, -1);
3000 lua_settop(L, top);
3001 throw std::logic_error(_info.errorMessage(s("fail to expand macro\n"sv) + err, callable));
3002 }
3003 lua_remove(L, -2); // cur macro res
3004 if (lua_isstring(L, -1) == 0) {
3005 lua_settop(L, top);
3006 throw std::logic_error(_info.errorMessage(s("macro function must return string with expanded codes"sv), callable));
3007 } // cur macro codes
3008 lua_rawgeti(L, -2, 2); // cur macro codes type
3009 std::string type = lua_tostring(L, -1);
3010 std::string codes = lua_tostring(L, -2);
3011 lua_settop(L, top);
3012 return {type, codes};
3013 }
3014
3015 std::pair<ast_ptr<false,ast_node>, std::unique_ptr<input>> expandMacro(ChainValue_t* chainValue, ExpUsage usage) {
3016 auto x = chainValue;
3017 const auto& chainList = chainValue->items.objects();
3018 std::string type, codes;
3019 std::tie(type, codes) = expandMacroStr(chainValue);
3020 std::string targetType(usage == ExpUsage::Common ? "block"sv : "expr"sv);
3021 if (type != targetType) {
3022 throw std::logic_error(_info.errorMessage(s("macro type mismatch, "sv) + targetType + s(" expected, got "sv) + type + '.', x));
3023 }
3024 ParseInfo info;
3025 if (usage == ExpUsage::Common) {
3026 if (codes.empty()) {
3027 return {x->new_ptr<Block_t>().get(),std::move(info.codes)};
3028 }
3029 info = _parser.parse<Block_t>(codes);
3030 } else {
3031 info = _parser.parse<Exp_t>(codes);
3032 }
3033 if (!info.node) {
3034 throw std::logic_error(_info.errorMessage("fail to expand macro: " + info.error, x));
3035 }
3036 int line = x->m_begin.m_line;
3037 int col = x->m_begin.m_col;
3038 info.node->traverse([&](ast_node* node) {
3039 node->m_begin.m_line = line;
3040 node->m_end.m_line = line;
3041 node->m_begin.m_col = col;
3042 node->m_end.m_col = col;
3043 return traversal::Continue;
3044 });
3045 if (usage == ExpUsage::Common) {
3046 return {info.node,std::move(info.codes)};
3047 } else {
3048 ast_ptr<false, Exp_t> exp;
3049 exp.set(info.node);
3050 if (!exp->opValues.empty() || chainList.size() > 2) {
3051 auto paren = x->new_ptr<Parens_t>();
3052 paren->expr.set(exp);
3053 auto callable = x->new_ptr<Callable_t>();
3054 callable->item.set(paren);
3055 auto newChain = x->new_ptr<ChainValue_t>();
3056 newChain->items.push_back(callable);
3057 auto it = chainList.begin();
3058 it++; it++;
3059 for (; it != chainList.end(); ++it) {
3060 newChain->items.push_back(*it);
3061 }
3062 auto value = x->new_ptr<Value_t>();
3063 value->item.set(newChain);
3064 exp = x->new_ptr<Exp_t>();
3065 exp->value.set(value);
3066 }
3067 return {exp.get(),std::move(info.codes)};
3068 }
3069 }
3070
2670 void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 3071 void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
3072 if (isMacroChain(chainValue)) {
3073 ast_ptr<false,ast_node> node;
3074 std::unique_ptr<input> codes;
3075 std::tie(node,codes) = expandMacro(chainValue, usage);
3076 if (usage == ExpUsage::Common) {
3077 transformBlock(node.to<Block_t>(), out, usage, assignList);
3078 } else {
3079 auto x = chainValue;
3080 switch (usage) {
3081 case ExpUsage::Assignment: {
3082 auto assign = x->new_ptr<Assign_t>();
3083 assign->values.push_back(node);
3084 auto assignment = x->new_ptr<ExpListAssign_t>();
3085 assignment->expList.set(assignList);
3086 assignment->action.set(assign);
3087 transformAssignment(assignment, out);
3088 break;
3089 }
3090 case ExpUsage::Return: {
3091 auto expListLow = x->new_ptr<ExpListLow_t>();
3092 expListLow->exprs.push_back(node);
3093 auto returnNode = x->new_ptr<Return_t>();
3094 returnNode->valueList.set(expListLow);
3095 transformReturn(returnNode, out);
3096 break;
3097 }
3098 default:
3099 transformExp(node.to<Exp_t>(), out, usage);
3100 break;
3101 }
3102 }
3103 return;
3104 }
2671 const auto& chainList = chainValue->items.objects(); 3105 const auto& chainList = chainValue->items.objects();
2672 if (transformChainEndWithColonItem(chainList, out, usage, assignList)) { 3106 if (transformChainEndWithColonItem(chainList, out, usage, assignList)) {
2673 return; 3107 return;
@@ -2700,7 +3134,7 @@ private:
2700 } 3134 }
2701 3135
2702 void transformSlice(Slice_t* slice, str_list&) { 3136 void transformSlice(Slice_t* slice, str_list&) {
2703 throw std::logic_error(_info.errorMessage("Slice syntax not supported here."sv, slice)); 3137 throw std::logic_error(_info.errorMessage("slice syntax not supported here"sv, slice));
2704 } 3138 }
2705 3139
2706 void transformInvoke(Invoke_t* invoke, str_list& out) { 3140 void transformInvoke(Invoke_t* invoke, str_list& out) {
@@ -2895,7 +3329,7 @@ private:
2895 auto indexVar = getUnusedName("_index_"sv); 3329 auto indexVar = getUnusedName("_index_"sv);
2896 varAfter.push_back(indexVar); 3330 varAfter.push_back(indexVar);
2897 auto value = singleValueFrom(star_exp->value); 3331 auto value = singleValueFrom(star_exp->value);
2898 if (!value) throw std::logic_error(_info.errorMessage("Invalid star syntax."sv, star_exp)); 3332 if (!value) throw std::logic_error(_info.errorMessage("invalid star syntax"sv, star_exp));
2899 bool endWithSlice = false; 3333 bool endWithSlice = false;
2900 BLOCK_START 3334 BLOCK_START
2901 auto chainValue = value->item.as<ChainValue_t>(); 3335 auto chainValue = value->item.as<ChainValue_t>();
@@ -3345,7 +3779,7 @@ private:
3345 std::string assignItem; 3779 std::string assignItem;
3346 if (assignable) { 3780 if (assignable) {
3347 if (!isAssignable(assignable)) { 3781 if (!isAssignable(assignable)) {
3348 throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, assignable)); 3782 throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, assignable));
3349 } 3783 }
3350 bool newDefined = false; 3784 bool newDefined = false;
3351 std::tie(className, newDefined) = defineClassVariable(assignable); 3785 std::tie(className, newDefined) = defineClassVariable(assignable);
@@ -3586,7 +4020,7 @@ private:
3586 if (selfName) { 4020 if (selfName) {
3587 type = MemType::Property; 4021 type = MemType::Property;
3588 auto name = ast_cast<self_name_t>(selfName->name); 4022 auto name = ast_cast<self_name_t>(selfName->name);
3589 if (!name) throw std::logic_error(_info.errorMessage("Invalid class poperty name."sv, selfName->name)); 4023 if (!name) throw std::logic_error(_info.errorMessage("invalid class poperty name"sv, selfName->name));
3590 newSuperCall = classVar + s(".__parent."sv) + _parser.toString(name->name); 4024 newSuperCall = classVar + s(".__parent."sv) + _parser.toString(name->name);
3591 } else { 4025 } else {
3592 auto x = keyName; 4026 auto x = keyName;
@@ -3897,19 +4331,19 @@ private:
3897 void transformExport(Export_t* exportNode, str_list& out) { 4331 void transformExport(Export_t* exportNode, str_list& out) {
3898 auto x = exportNode; 4332 auto x = exportNode;
3899 if (_scopes.size() > 1) { 4333 if (_scopes.size() > 1) {
3900 throw std::logic_error(_info.errorMessage("Can not do module export outside root block."sv, x)); 4334 throw std::logic_error(_info.errorMessage("can not do module export outside root block"sv, x));
3901 } 4335 }
3902 if (exportNode->assign) { 4336 if (exportNode->assign) {
3903 auto expList = exportNode->target.to<ExpList_t>(); 4337 auto expList = exportNode->target.to<ExpList_t>();
3904 if (expList->exprs.size() != exportNode->assign->values.size()) { 4338 if (expList->exprs.size() != exportNode->assign->values.size()) {
3905 throw std::logic_error(_info.errorMessage("Left and right expressions must be matched in export statement."sv, x)); 4339 throw std::logic_error(_info.errorMessage("left and right expressions must be matched in export statement"sv, x));
3906 } 4340 }
3907 for (auto _exp : expList->exprs.objects()) { 4341 for (auto _exp : expList->exprs.objects()) {
3908 auto exp = static_cast<Exp_t*>(_exp); 4342 auto exp = static_cast<Exp_t*>(_exp);
3909 if (!variableFrom(exp) && 4343 if (!variableFrom(exp) &&
3910 !exp->getByPath<Value_t, SimpleValue_t, TableLit_t>() && 4344 !exp->getByPath<Value_t, SimpleValue_t, TableLit_t>() &&
3911 !exp->getByPath<Value_t, simple_table_t>()) { 4345 !exp->getByPath<Value_t, simple_table_t>()) {
3912 throw std::logic_error(_info.errorMessage("Left hand expressions must be variables in export statement."sv, x)); 4346 throw std::logic_error(_info.errorMessage("left hand expressions must be variables in export statement"sv, x));
3913 } 4347 }
3914 } 4348 }
3915 auto assignment = x->new_ptr<ExpListAssign_t>(); 4349 auto assignment = x->new_ptr<ExpListAssign_t>();
@@ -3935,7 +4369,9 @@ private:
3935 out.back().append(indent() + join(lefts,", "sv) + s(" = "sv) + join(rights, ", "sv) + nlr(exportNode)); 4369 out.back().append(indent() + join(lefts,", "sv) + s(" = "sv) + join(rights, ", "sv) + nlr(exportNode));
3936 } 4370 }
3937 } else { 4371 } else {
3938 if (_info.exportDefault) { 4372 if (auto macro = exportNode->target.as<Macro_t>()) {
4373 transformMacro(macro, out, true);
4374 } else if (_info.exportDefault) {
3939 auto exp = exportNode->target.to<Exp_t>(); 4375 auto exp = exportNode->target.to<Exp_t>();
3940 auto assignment = x->new_ptr<ExpListAssign_t>(); 4376 auto assignment = x->new_ptr<ExpListAssign_t>();
3941 assignment->expList.set(toAst<ExpList_t>(_info.moduleName, x)); 4377 assignment->expList.set(toAst<ExpList_t>(_info.moduleName, x));
@@ -4218,14 +4654,102 @@ private:
4218 out.push_back(join(temp)); 4654 out.push_back(join(temp));
4219 } 4655 }
4220 4656
4657 std::string moduleNameFrom(ImportLiteral_t* literal) {
4658 auto name = _parser.toString(literal->inners.back());
4659 Utils::replace(name, "-"sv, "_"sv);
4660 Utils::replace(name, " "sv, "_"sv);
4661 return name;
4662 }
4663
4221 void transformImportAs(ImportAs_t* import, str_list& out) { 4664 void transformImportAs(ImportAs_t* import, str_list& out) {
4222 auto x = import; 4665 auto x = import;
4223 if (!import->target) { 4666 if (!import->target) {
4224 auto name = _parser.toString(import->literal->inners.back()); 4667 auto name = moduleNameFrom(import->literal);
4225 Utils::replace(name, "-"sv, "_"sv);
4226 Utils::replace(name, " "sv, "_"sv);
4227 import->target.set(toAst<Variable_t>(name, x)); 4668 import->target.set(toAst<Variable_t>(name, x));
4228 } 4669 }
4670 if (auto tableLit = import->target.as<TableLit_t>()) {
4671 auto newTab = x->new_ptr<TableLit_t>();
4672 std::list<std::pair<std::string,std::string>> macroPairs;
4673 for (auto item : tableLit->values.objects()) {
4674 switch (item->getId()) {
4675 case id<MacroName_t>(): {
4676 auto macroName = static_cast<MacroName_t*>(item);
4677 auto name = _parser.toString(macroName->name);
4678 macroPairs.emplace_back(name, name);
4679 break;
4680 }
4681 case id<macro_name_pair_t>(): {
4682 auto pair = static_cast<macro_name_pair_t*>(item);
4683 macroPairs.emplace_back(_parser.toString(pair->value->name), _parser.toString(pair->key->name));
4684 break;
4685 }
4686 default:
4687 newTab->values.push_back(item);
4688 break;
4689 }
4690 }
4691 if (!macroPairs.empty()) {
4692 auto moduleName = _parser.toString(import->literal);
4693 Utils::replace(moduleName, "'"sv, ""sv);
4694 Utils::replace(moduleName, "\""sv, ""sv);
4695 Utils::trim(moduleName);
4696 pushCurrentModule(); // cur
4697 int top = lua_gettop(L) - 1;
4698 pushMoonp("find_modulepath"sv); // cur find_modulepath
4699 lua_pushlstring(L, moduleName.c_str(), moduleName.size()); // cur find_modulepath moduleName
4700 if (lua_pcall(L, 1, 1, 0) != 0) {
4701 std::string err = lua_tostring(L, -1);
4702 lua_settop(L, top);
4703 throw std::logic_error(_info.errorMessage(s("fail to resolve module path\n"sv) + err, x));
4704 }
4705 if (lua_isnil(L, -1) != 0) {
4706 lua_settop(L, top);
4707 throw std::logic_error(_info.errorMessage(s("fail to find module '"sv) + moduleName + '\'', x));
4708 }
4709 std::string moduleFullName = lua_tostring(L, -1);
4710 lua_pop(L, 1); // cur
4711 if (!isModuleLoaded(moduleFullName)) {
4712 pushMoonp("read_file"sv); // cur read_file
4713 lua_pushlstring(L, moduleFullName.c_str(), moduleFullName.size()); // cur load_text moduleFullName
4714 if (lua_pcall(L, 1, 1, 0) != 0) {
4715 std::string err = lua_tostring(L, -1);
4716 lua_settop(L, top);
4717 throw std::logic_error(_info.errorMessage(s("fail to read module file\n"sv) + err, x));
4718 } // cur text
4719 if (lua_isnil(L, -1) != 0) {
4720 lua_settop(L, top);
4721 throw std::logic_error(_info.errorMessage("fail to get module text"sv, x));
4722 } // cur text
4723 std::string text = lua_tostring(L, -1);
4724 auto compiler = MoonCompilerImpl(L, _luaOpen, false, moduleFullName);
4725 MoonConfig config;
4726 config.lineOffset = 0;
4727 config.lintGlobalVariable = false;
4728 config.reserveLineNumber = false;
4729 config.implicitReturnRoot = _config.implicitReturnRoot;
4730 std::string codes, err;
4731 GlobalVars globals;
4732 std::tie(codes, err, globals) = compiler.compile(text, config);
4733 if (codes.empty() && !err.empty()) {
4734 lua_settop(L, top);
4735 throw std::logic_error(_info.errorMessage(s("fail to compile module '"sv) + moduleName + s("\': "sv) + err, x));
4736 }
4737 lua_pop(L, 1); // cur
4738 }
4739 pushModuleTable(moduleFullName); // cur module
4740 for (const auto& pair : macroPairs) {
4741 lua_getfield(L, -1, pair.first.c_str());
4742 lua_setfield(L, -3, pair.second.c_str());
4743 }
4744 lua_settop(L, top);
4745 }
4746 if (newTab->values.empty()) {
4747 out.push_back(Empty);
4748 return;
4749 } else {
4750 import->target.set(newTab);
4751 }
4752 }
4229 auto target = import->target.get(); 4753 auto target = import->target.get();
4230 auto value = x->new_ptr<Value_t>(); 4754 auto value = x->new_ptr<Value_t>();
4231 if (auto var = ast_cast<Variable_t>(target)) { 4755 if (auto var = ast_cast<Variable_t>(target)) {
@@ -4389,6 +4913,7 @@ private:
4389 } 4913 }
4390 4914
4391 void transformLocal(Local_t* local, str_list& out) { 4915 void transformLocal(Local_t* local, str_list& out) {
4916 str_list temp;
4392 if (!local->forceDecls.empty() || !local->decls.empty()) { 4917 if (!local->forceDecls.empty() || !local->decls.empty()) {
4393 str_list defs; 4918 str_list defs;
4394 for (const auto& decl : local->forceDecls) { 4919 for (const auto& decl : local->forceDecls) {
@@ -4402,9 +4927,33 @@ private:
4402 } 4927 }
4403 auto preDefine = getPredefine(defs); 4928 auto preDefine = getPredefine(defs);
4404 if (!preDefine.empty()) { 4929 if (!preDefine.empty()) {
4405 out.push_back(preDefine + nll(local)); 4930 temp.push_back(preDefine + nll(local));
4931 }
4932 }
4933 if (auto values = local->item.as<local_values_t>()) {
4934 if (values->valueList) {
4935 auto x = local;
4936 auto expList = x->new_ptr<ExpList_t>();
4937 for (auto name : values->nameList->names.objects()) {
4938 auto callable = x->new_ptr<Callable_t>();
4939 callable->item.set(name);
4940 auto chainValue = x->new_ptr<ChainValue_t>();
4941 chainValue->items.push_back(callable);
4942 auto value = x->new_ptr<Value_t>();
4943 value->item.set(chainValue);
4944 auto exp = x->new_ptr<Exp_t>();
4945 exp->value.set(value);
4946 expList->exprs.push_back(exp);
4947 }
4948 auto assignment = x->new_ptr<ExpListAssign_t>();
4949 assignment->expList.set(expList);
4950 auto assign = x->new_ptr<Assign_t>();
4951 assign->values.dup(values->valueList->exprs);
4952 assignment->action.set(assign);
4953 transformAssignment(assignment, temp);
4406 } 4954 }
4407 } 4955 }
4956 out.push_back(join(temp));
4408 } 4957 }
4409 4958
4410 void transformBreakLoop(BreakLoop_t* breakLoop, str_list& out) { 4959 void transformBreakLoop(BreakLoop_t* breakLoop, str_list& out) {
@@ -4413,7 +4962,7 @@ private:
4413 out.push_back(indent() + keyword + nll(breakLoop)); 4962 out.push_back(indent() + keyword + nll(breakLoop));
4414 return; 4963 return;
4415 } 4964 }
4416 if (_continueVars.empty()) throw std::logic_error(_info.errorMessage("Continue is not inside a loop."sv, breakLoop)); 4965 if (_continueVars.empty()) throw std::logic_error(_info.errorMessage("continue is not inside a loop"sv, breakLoop));
4417 _buf << indent() << _continueVars.top() << " = true"sv << nll(breakLoop); 4966 _buf << indent() << _continueVars.top() << " = true"sv << nll(breakLoop);
4418 _buf << indent() << "break"sv << nll(breakLoop); 4967 _buf << indent() << "break"sv << nll(breakLoop);
4419 out.push_back(clearBuf()); 4968 out.push_back(clearBuf());
@@ -4422,12 +4971,12 @@ private:
4422 4971
4423const std::string MoonCompilerImpl::Empty; 4972const std::string MoonCompilerImpl::Empty;
4424 4973
4425MoonCompiler::MoonCompiler(): 4974MoonCompiler::MoonCompiler(void* sharedState,
4426_compiler(std::make_unique<MoonCompilerImpl>()) 4975 const std::function<void(void*)>& luaOpen,
4427{ } 4976 bool sameModule):
4977_compiler(std::make_unique<MoonCompilerImpl>(static_cast<lua_State*>(sharedState), luaOpen, sameModule)) {}
4428 4978
4429MoonCompiler::~MoonCompiler() 4979MoonCompiler::~MoonCompiler() {}
4430{ }
4431 4980
4432std::tuple<std::string,std::string,GlobalVars> MoonCompiler::compile(std::string_view codes, const MoonConfig& config) { 4981std::tuple<std::string,std::string,GlobalVars> MoonCompiler::compile(std::string_view codes, const MoonConfig& config) {
4433 return _compiler->compile(codes, config); 4982 return _compiler->compile(codes, config);
diff --git a/src/MoonP/moon_compiler.h b/src/MoonP/moon_compiler.h
index 36fd77a..573f130 100644
--- a/src/MoonP/moon_compiler.h
+++ b/src/MoonP/moon_compiler.h
@@ -13,6 +13,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
13#include <tuple> 13#include <tuple>
14#include <list> 14#include <list>
15#include <memory> 15#include <memory>
16#include <functional>
16 17
17namespace MoonP { 18namespace MoonP {
18 19
@@ -22,6 +23,7 @@ struct MoonConfig {
22 bool lintGlobalVariable = false; 23 bool lintGlobalVariable = false;
23 bool implicitReturnRoot = true; 24 bool implicitReturnRoot = true;
24 bool reserveLineNumber = true; 25 bool reserveLineNumber = true;
26 int lineOffset = 0;
25}; 27};
26 28
27struct GlobalVar { 29struct GlobalVar {
@@ -36,7 +38,9 @@ class MoonCompilerImpl;
36 38
37class MoonCompiler { 39class MoonCompiler {
38public: 40public:
39 MoonCompiler(); 41 MoonCompiler(void* luaState = nullptr,
42 const std::function<void(void*)>& luaOpen = nullptr,
43 bool sameModule = false);
40 virtual ~MoonCompiler(); 44 virtual ~MoonCompiler();
41 std::tuple<std::string,std::string,GlobalVars> compile(std::string_view codes, const MoonConfig& config = {}); 45 std::tuple<std::string,std::string,GlobalVars> compile(std::string_view codes, const MoonConfig& config = {});
42private: 46private:
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp
index baa8eff..f0269d7 100644
--- a/src/MoonP/moon_parser.cpp
+++ b/src/MoonP/moon_parser.cpp
@@ -28,8 +28,8 @@ std::unordered_set<std::string> Keywords = {
28 "repeat", "return", "then", "true", "until", 28 "repeat", "return", "then", "true", "until",
29 "while", // Lua keywords 29 "while", // Lua keywords
30 "as", "class", "continue", "export", "extends", 30 "as", "class", "continue", "export", "extends",
31 "from", "global", "import", "switch", "unless", 31 "from", "global", "import", "macro", "switch",
32 "using", "when", "with" // Moon keywords 32 "unless", "using", "when", "with" // Moon keywords
33}; 33};
34 34
35MoonParser::MoonParser() { 35MoonParser::MoonParser() {
@@ -98,9 +98,9 @@ MoonParser::MoonParser() {
98 self_class = expr("@@"); 98 self_class = expr("@@");
99 self_class_name = "@@" >> Name; 99 self_class_name = "@@" >> Name;
100 100
101 SelfName = Space >> (self_class_name | self_class | self_name | self); 101 SelfName = self_class_name | self_class | self_name | self;
102 KeyName = SelfName | Space >> Name; 102 KeyName = Space >> (SelfName | Name);
103 VarArg = Space >> "..."; 103 VarArg = expr("...");
104 104
105 check_indent = pl::user(Indent, [](const item_t& item) { 105 check_indent = pl::user(Indent, [](const item_t& item) {
106 int indent = 0; 106 int indent = 0;
@@ -162,7 +162,8 @@ MoonParser::MoonParser() {
162 InBlock = Advance >> ensure(Block, PopIndent); 162 InBlock = Advance >> ensure(Block, PopIndent);
163 163
164 local_flag = expr('*') | expr('^'); 164 local_flag = expr('*') | expr('^');
165 Local = key("local") >> ((Space >> local_flag) | NameList); 165 local_values = NameList >> -(sym('=') >> ExpListLow);
166 Local = key("local") >> (Space >> local_flag | local_values);
166 167
167 colon_import_name = sym('\\') >> Space >> Variable; 168 colon_import_name = sym('\\') >> Space >> Variable;
168 ImportName = colon_import_name | Space >> Variable; 169 ImportName = colon_import_name | Space >> Variable;
@@ -173,9 +174,23 @@ MoonParser::MoonParser() {
173 ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"'); 174 ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"');
174 175
175 ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp; 176 ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp;
176 ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | TableLit)); 177
178 EnableMacroPair = pl::user(true_(), [](const item_t& item) {
179 State* st = reinterpret_cast<State*>(item.user_data);
180 st->macroPairEnabled = true;
181 return true;
182 });
183
184 DiableMacroPair = pl::user(true_(), [](const item_t& item) {
185 State* st = reinterpret_cast<State*>(item.user_data);
186 st->macroPairEnabled = false;
187 return true;
188 });
189
190 ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | EnableMacroPair >> ensure(TableLit, DiableMacroPair)));
177 191
178 Import = key("import") >> (ImportAs | ImportFrom); 192 Import = key("import") >> (ImportAs | ImportFrom);
193
179 BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum); 194 BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum);
180 195
181 Return = key("return") >> -ExpListLow; 196 Return = key("return") >> -ExpListLow;
@@ -278,7 +293,7 @@ MoonParser::MoonParser() {
278 293
279 BackcallOperator = expr("|>"); 294 BackcallOperator = expr("|>");
280 295
281 Assignable = AssignableChain | Space >> Variable | SelfName; 296 Assignable = AssignableChain | Space >> Variable | Space >> SelfName;
282 297
283 exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value; 298 exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value;
284 Exp = Value >> *exp_op_value; 299 Exp = Value >> *exp_op_value;
@@ -317,8 +332,8 @@ MoonParser::MoonParser() {
317 332
318 LuaString = LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose; 333 LuaString = LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose;
319 334
320 Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); 335 Parens = symx('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')');
321 Callable = Space >> Variable | SelfName | VarArg | Parens; 336 Callable = Space >> (Variable | SelfName | MacroName | VarArg | Parens);
322 FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp); 337 FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp);
323 338
324 FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) | 339 FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) |
@@ -414,7 +429,8 @@ MoonParser::MoonParser() {
414 } else { 429 } else {
415 return true; 430 return true;
416 } 431 }
417 }) >> ExpList >> -Assign)) >> not_(Space >> statement_appendix); 432 }) >> ExpList >> -Assign)
433 | Macro) >> not_(Space >> statement_appendix);
418 434
419 variable_pair = sym(':') >> Variable; 435 variable_pair = sym(':') >> Variable;
420 436
@@ -427,14 +443,19 @@ MoonParser::MoonParser() {
427 symx(':') >> 443 symx(':') >>
428 (Exp | TableBlock | +(SpaceBreak) >> Exp); 444 (Exp | TableBlock | +(SpaceBreak) >> Exp);
429 445
430 KeyValue = variable_pair | normal_pair; 446 macro_name_pair = Space >> MacroName >> Space >> symx(':') >> Space >> MacroName;
447
448 KeyValue = variable_pair | normal_pair | pl::user(sym(':') >> MacroName | macro_name_pair, [](const item_t& item) {
449 State* st = reinterpret_cast<State*>(item.user_data);
450 return st->macroPairEnabled;
451 });
431 452
432 KeyValueList = KeyValue >> *(sym(',') >> KeyValue); 453 KeyValueList = KeyValue >> *(sym(',') >> KeyValue);
433 KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); 454 KeyValueLine = CheckIndent >> KeyValueList >> -sym(',');
434 455
435 FnArgDef = (Space >> Variable | SelfName) >> -(sym('=') >> Exp); 456 FnArgDef = (Variable | SelfName) >> -(sym('=') >> Space >> Exp);
436 457
437 FnArgDefList = Seperator >> ( 458 FnArgDefList = Space >> Seperator >> (
438 ( 459 (
439 FnArgDef >> 460 FnArgDef >>
440 *((sym(',') | Break) >> White >> FnArgDef) >> 461 *((sym(',') | Break) >> White >> FnArgDef) >>
@@ -450,6 +471,12 @@ MoonParser::MoonParser() {
450 fn_arrow = expr("->") | expr("=>"); 471 fn_arrow = expr("->") | expr("=>");
451 FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body; 472 FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body;
452 473
474 MacroName = expr('$') >> Name;
475 macro_type = expr("expr") | expr("block");
476 macro_args_def = sym('(') >> White >> -FnArgDefList >> White >> sym(')');
477 MacroLit = -macro_args_def >> Space >> expr("->") >> Body;
478 Macro = key("macro") >> Space >> macro_type >> Space >> Name >> sym('=') >> MacroLit;
479
453 NameList = Seperator >> Space >> Variable >> *(sym(',') >> White >> Variable); 480 NameList = Seperator >> Space >> Variable >> *(sym(',') >> White >> Variable);
454 NameOrDestructure = Space >> Variable | TableLit; 481 NameOrDestructure = Space >> Variable | TableLit;
455 AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> White >> NameOrDestructure); 482 AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> White >> NameOrDestructure);
@@ -499,7 +526,8 @@ MoonParser::MoonParser() {
499 statement_appendix = (if_else_line | unless_line | CompInner) >> Space; 526 statement_appendix = (if_else_line | unless_line | CompInner) >> Space;
500 Statement = ( 527 Statement = (
501 Import | While | For | ForEach | 528 Import | While | For | ForEach |
502 Return | Local | Global | Export | Space >> BreakLoop | 529 Return | Local | Global | Export |
530 Macro | Space >> BreakLoop |
503 Backcall | ExpListAssign 531 Backcall | ExpListAssign
504 ) >> Space >> 532 ) >> Space >>
505 -statement_appendix; 533 -statement_appendix;
@@ -541,10 +569,10 @@ ParseInfo MoonParser::parse(std::string_view codes, rule& r) {
541 const error& err = *it; 569 const error& err = *it;
542 switch (err.m_type) { 570 switch (err.m_type) {
543 case ERROR_TYPE::ERROR_SYNTAX_ERROR: 571 case ERROR_TYPE::ERROR_SYNTAX_ERROR:
544 buf << res.errorMessage("Syntax error."sv, &err); 572 buf << res.errorMessage("syntax error"sv, &err);
545 break; 573 break;
546 case ERROR_TYPE::ERROR_INVALID_EOF: 574 case ERROR_TYPE::ERROR_INVALID_EOF:
547 buf << res.errorMessage("Invalid EOF."sv, &err); 575 buf << res.errorMessage("invalid EOF"sv, &err);
548 break; 576 break;
549 } 577 }
550 } 578 }
@@ -577,6 +605,12 @@ namespace Utils {
577 start_pos += to.size(); 605 start_pos += to.size();
578 } 606 }
579 } 607 }
608
609 void trim(std::string& str) {
610 if (str.empty()) return;
611 str.erase(0, str.find_first_not_of(" \t"));
612 str.erase(str.find_last_not_of(" \t") + 1);
613 }
580} 614}
581 615
582std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc) const { 616std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc) const {
diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h
index eefcba5..4d67696 100644
--- a/src/MoonP/moon_parser.h
+++ b/src/MoonP/moon_parser.h
@@ -12,7 +12,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
12#include <unordered_set> 12#include <unordered_set>
13#include <stack> 13#include <stack>
14#include <algorithm> 14#include <algorithm>
15#include <vector> 15#include <list>
16#include <sstream> 16#include <sstream>
17#include <string_view> 17#include <string_view>
18 18
@@ -75,6 +75,7 @@ protected:
75 State() { 75 State() {
76 indents.push(0); 76 indents.push(0);
77 } 77 }
78 bool macroPairEnabled = false;
78 bool exportDefault = false; 79 bool exportDefault = false;
79 int exportCount = 0; 80 int exportCount = 0;
80 int moduleFix = 0; 81 int moduleFix = 0;
@@ -131,6 +132,8 @@ private:
131 rule WithExp; 132 rule WithExp;
132 rule DisableDo; 133 rule DisableDo;
133 rule PopDo; 134 rule PopDo;
135 rule EnableMacroPair;
136 rule DiableMacroPair;
134 rule SwitchElse; 137 rule SwitchElse;
135 rule SwitchBlock; 138 rule SwitchBlock;
136 rule IfElseIf; 139 rule IfElseIf;
@@ -147,6 +150,7 @@ private:
147 rule lua_string_close; 150 rule lua_string_close;
148 rule FnArgsExpList; 151 rule FnArgsExpList;
149 rule FnArgs; 152 rule FnArgs;
153 rule macro_args_def;
150 rule chain_call; 154 rule chain_call;
151 rule chain_item; 155 rule chain_item;
152 rule ChainItems; 156 rule ChainItems;
@@ -189,6 +193,7 @@ private:
189 AST_RULE(Seperator) 193 AST_RULE(Seperator)
190 AST_RULE(NameList) 194 AST_RULE(NameList)
191 AST_RULE(local_flag) 195 AST_RULE(local_flag)
196 AST_RULE(local_values)
192 AST_RULE(Local) 197 AST_RULE(Local)
193 AST_RULE(colon_import_name) 198 AST_RULE(colon_import_name)
194 AST_RULE(import_literal_inner) 199 AST_RULE(import_literal_inner)
@@ -261,12 +266,17 @@ private:
261 AST_RULE(Export) 266 AST_RULE(Export)
262 AST_RULE(variable_pair) 267 AST_RULE(variable_pair)
263 AST_RULE(normal_pair) 268 AST_RULE(normal_pair)
269 AST_RULE(macro_name_pair)
264 AST_RULE(FnArgDef) 270 AST_RULE(FnArgDef)
265 AST_RULE(FnArgDefList) 271 AST_RULE(FnArgDefList)
266 AST_RULE(outer_var_shadow) 272 AST_RULE(outer_var_shadow)
267 AST_RULE(FnArgsDef) 273 AST_RULE(FnArgsDef)
268 AST_RULE(fn_arrow) 274 AST_RULE(fn_arrow)
269 AST_RULE(FunLit) 275 AST_RULE(FunLit)
276 AST_RULE(macro_type)
277 AST_RULE(MacroName)
278 AST_RULE(MacroLit)
279 AST_RULE(Macro)
270 AST_RULE(NameOrDestructure) 280 AST_RULE(NameOrDestructure)
271 AST_RULE(AssignableNameList) 281 AST_RULE(AssignableNameList)
272 AST_RULE(InvokeArgs) 282 AST_RULE(InvokeArgs)
@@ -285,6 +295,7 @@ private:
285 295
286namespace Utils { 296namespace Utils {
287 void replace(std::string& str, std::string_view from, std::string_view to); 297 void replace(std::string& str, std::string_view from, std::string_view to);
298 void trim(std::string& str);
288}; 299};
289 300
290} // namespace MoonP 301} // namespace MoonP
diff --git a/src/Moonscript.h b/src/Moonscript.h
deleted file mode 100644
index 6e84552..0000000
--- a/src/Moonscript.h
+++ /dev/null
@@ -1,146 +0,0 @@
1R"moonscript_codes(
2--[[
3Copyright (C) 2020 by Leaf Corcoran, modified by Li Jin
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.]]
22
23import "moonp"
24import concat, insert, remove from table
25unpack = unpack or table.unpack
26lua = :loadstring, :load
27
28local *
29
30dirsep = "/"
31
32moonp.moon_compiled = {}
33
34split = (str, delim) ->
35 return {} if str == ""
36 str ..= delim
37 [m for m in str\gmatch("(.-)"..delim)]
38
39get_options = (...) ->
40 count = select "#", ...
41 opts = select count, ...
42 if type(opts) == "table"
43 opts, unpack {...}, nil, count - 1
44 else
45 {}, ...
46
47-- create moon path package from lua package path
48create_moonpath = (package_path) ->
49 moonpaths = for path in *split package_path, ";"
50 prefix = path\match "^(.-)%.lua$"
51 continue unless prefix
52 prefix .. ".moon"
53 concat moonpaths, ";"
54
55moon_loader = (name) ->
56 name_path = name\gsub "%.", dirsep
57
58 local file, file_path
59 for path in package.moonpath\gmatch "[^;]+"
60 file_path = path\gsub "?", name_path
61 file = io.open file_path
62 break if file
63
64 if file
65 text = file\read "*a"
66 file\close!
67 res, err = loadstring text, "@#{file_path}"
68 if not res
69 error file_path .. ": " .. err
70
71 return res
72
73 return nil, "Could not find moon file"
74
75
76loadstring = (...) ->
77 options, str, chunk_name, mode, env = get_options ...
78 chunk_name or= "=(moonscript.loadstring)"
79
80 code, err = moonp.to_lua str, options
81 unless code
82 return nil, err
83
84 moonp.moon_compiled[chunk_name] = code if chunk_name
85 -- the unpack prevents us from passing nil
86 (lua.loadstring or lua.load) code, chunk_name, unpack { mode, env }
87
88loadfile = (fname, ...) ->
89 file, err = io.open fname
90 return nil, err unless file
91 text = assert file\read "*a"
92 file\close!
93 loadstring text, "@#{fname}", ...
94
95-- throws errros
96dofile = (...) ->
97 f = assert loadfile ...
98 f!
99
100insert_loader = (pos=2) ->
101 if not package.moonpath
102 package.moonpath = create_moonpath package.path
103
104 loaders = package.loaders or package.searchers
105 for loader in *loaders
106 return false if loader == moon_loader
107
108 insert loaders, pos, moon_loader
109 true
110
111remove_loader = ->
112 loaders = package.loaders or package.searchers
113
114 for i, loader in ipairs loaders
115 if loader == moon_loader
116 remove loaders, i
117 return true
118
119 false
120
121moon_require = (name)->
122 insert_loader!
123 xpcall (-> require name), (err)->
124 msg = moonp.stp.stacktrace err, 2
125 print msg
126
127setmetatable moonp, {
128 __index: (key)=>
129 return nil unless key == "stp"
130 stp = rawget moonp,"stp"
131 unless stp
132 stp = with moonp.load_stacktraceplus!
133 .dump_locals = false
134 .simplified = true
135 rawset moonp,"stp",stp
136 rawset moonp,"load_stacktraceplus",nil
137 stp
138 __call: (name)=> @.require name
139}
140
141moonp[k] = v for k,v in pairs {
142 :insert_loader, :remove_loader, :moon_loader, :dirsep,
143 :dofile, :loadfile, :loadstring, :create_moonpath,
144 require:moon_require
145}
146)moonscript_codes";
diff --git a/src/StackTracePlus.h b/src/StackTracePlus.h
deleted file mode 100644
index 202ae22..0000000
--- a/src/StackTracePlus.h
+++ /dev/null
@@ -1,548 +0,0 @@
1R"lua_codes(
2--[[
3Copyright (c) 2010 Ignacio Burgueño, modified by Li Jin
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.]]
22
23-- tables
24local _G = _G
25local string, io, debug, coroutine = string, io, debug, coroutine
26
27-- functions
28local tostring, require = tostring, require
29local next, assert = next, assert
30local pcall, type, pairs, ipairs = pcall, type, pairs, ipairs
31local error = error
32
33assert(debug, "debug table must be available at this point")
34
35local string_gmatch = string.gmatch
36local string_sub = string.sub
37local table_concat = table.concat
38
39local _M = {
40 max_tb_output_len = 70, -- controls the maximum length of the 'stringified' table before cutting with ' (more...)'
41 dump_locals = true,
42 simplified = false
43}
44
45-- this tables should be weak so the elements in them won't become uncollectable
46local m_known_tables = { [_G] = "_G (global table)" }
47local function add_known_module(name, desc)
48 local ok, mod = pcall(require, name)
49 if ok then
50 m_known_tables[mod] = desc
51 end
52end
53
54add_known_module("string", "string module")
55add_known_module("io", "io module")
56add_known_module("os", "os module")
57add_known_module("table", "table module")
58add_known_module("math", "math module")
59add_known_module("package", "package module")
60add_known_module("debug", "debug module")
61add_known_module("coroutine", "coroutine module")
62
63-- lua5.2
64add_known_module("bit32", "bit32 module")
65-- luajit
66add_known_module("bit", "bit module")
67add_known_module("jit", "jit module")
68-- lua5.3
69if _VERSION >= "Lua 5.3" then
70 add_known_module("utf8", "utf8 module")
71end
72
73
74local m_user_known_tables = {}
75
76local m_known_functions = {}
77for _, name in ipairs{
78 -- Lua 5.2, 5.1
79 "assert",
80 "collectgarbage",
81 "dofile",
82 "error",
83 "getmetatable",
84 "ipairs",
85 "load",
86 "loadfile",
87 "next",
88 "pairs",
89 "pcall",
90 "print",
91 "rawequal",
92 "rawget",
93 "rawlen",
94 "rawset",
95 "require",
96 "select",
97 "setmetatable",
98 "tonumber",
99 "tostring",
100 "type",
101 "xpcall",
102
103 -- Lua 5.1
104 "gcinfo",
105 "getfenv",
106 "loadstring",
107 "module",
108 "newproxy",
109 "setfenv",
110 "unpack",
111 -- TODO: add table.* etc functions
112} do
113 if _G[name] then
114 m_known_functions[_G[name]] = name
115 end
116end
117
118local m_user_known_functions = {}
119
120local function safe_tostring (value)
121 local ok, err = pcall(tostring, value)
122 if ok then return err else return ("<failed to get printable value>: '%s'"):format(err) end
123end
124
125-- Private:
126-- Parses a line, looking for possible function definitions (in a very naive way)
127-- Returns '(anonymous)' if no function name was found in the line
128local function ParseLine(line)
129 assert(type(line) == "string")
130 local match = line:match("^%s*function%s+(%w+)")
131 if match then
132 --print("+++++++++++++function", match)
133 return match
134 end
135 match = line:match("^%s*local%s+function%s+(%w+)")
136 if match then
137 --print("++++++++++++local", match)
138 return match
139 end
140 match = line:match("^%s*local%s+(%w+)%s+=%s+function")
141 if match then
142 --print("++++++++++++local func", match)
143 return match
144 end
145 match = line:match("%s*function%s*%(") -- this is an anonymous function
146 if match then
147 --print("+++++++++++++function2", match)
148 return "(anonymous)"
149 end
150 return "(anonymous)"
151end
152
153-- Private:
154-- Tries to guess a function's name when the debug info structure does not have it.
155-- It parses either the file or the string where the function is defined.
156-- Returns '?' if the line where the function is defined is not found
157local function GuessFunctionName(info)
158 -- print("guessing function name")
159 if type(info.source) == "string" and info.source:sub(1,1) == "@" then
160 local file = io.open(info.source:sub(2))
161 local text
162 if file then
163 text = file:read("*a")
164 file:close()
165 end
166 if not text then
167 -- print("file not found: "..tostring(err)) -- whoops!
168 return "?"
169 end
170 local line
171 local count = 0
172 for lineText in (text.."\n"):gmatch("(.-)\n") do
173 line = lineText
174 count = count + 1
175 if count == info.linedefined then
176 break
177 end
178 end
179 if not line then
180 --print("line not found") -- whoops!
181 return "?"
182 end
183 return ParseLine(line)
184 else
185 local line
186 local lineNumber = 0
187 for l in string_gmatch(info.source, "([^\n]+)\n-") do
188 lineNumber = lineNumber + 1
189 if lineNumber == info.linedefined then
190 line = l
191 break
192 end
193 end
194 if not line then
195 -- print("line not found") -- whoops!
196 return "?"
197 end
198 return ParseLine(line)
199 end
200end
201
202---
203-- Dumper instances are used to analyze stacks and collect its information.
204--
205local Dumper = {}
206
207Dumper.new = function(thread)
208 local t = { lines = {} }
209 for k,v in pairs(Dumper) do t[k] = v end
210
211 t.dumping_same_thread = (thread == coroutine.running())
212
213 -- if a thread was supplied, bind it to debug.info and debug.get
214 -- we also need to skip this additional level we are introducing in the callstack (only if we are running
215 -- in the same thread we're inspecting)
216 if type(thread) == "thread" then
217 t.getinfo = function(level, what)
218 if t.dumping_same_thread and type(level) == "number" then
219 level = level + 1
220 end
221 return debug.getinfo(thread, level, what)
222 end
223 t.getlocal = function(level, loc)
224 if t.dumping_same_thread then
225 level = level + 1
226 end
227 return debug.getlocal(thread, level, loc)
228 end
229 else
230 t.getinfo = debug.getinfo
231 t.getlocal = debug.getlocal
232 end
233
234 return t
235end
236
237-- helpers for collecting strings to be used when assembling the final trace
238function Dumper:add (text)
239 self.lines[#self.lines + 1] = text
240end
241function Dumper:add_f (fmt, ...)
242 self:add(fmt:format(...))
243end
244function Dumper:concat_lines ()
245 return table_concat(self.lines)
246end
247
248---
249-- Private:
250-- Iterates over the local variables of a given function.
251--
252-- @param level The stack level where the function is.
253--
254function Dumper:DumpLocals (level)
255 if not _M.dump_locals then return end
256
257 local prefix = "\t "
258 local i = 1
259
260 if self.dumping_same_thread then
261 level = level + 1
262 end
263
264 local name, value = self.getlocal(level, i)
265 if not name then
266 return
267 end
268 self:add("\tLocal variables:\r\n")
269 while name do
270 if type(value) == "number" then
271 self:add_f("%s%s = number: %g\r\n", prefix, name, value)
272 elseif type(value) == "boolean" then
273 self:add_f("%s%s = boolean: %s\r\n", prefix, name, tostring(value))
274 elseif type(value) == "string" then
275 self:add_f("%s%s = string: %q\r\n", prefix, name, value)
276 elseif type(value) == "userdata" then
277 self:add_f("%s%s = %s\r\n", prefix, name, safe_tostring(value))
278 elseif type(value) == "nil" then
279 self:add_f("%s%s = nil\r\n", prefix, name)
280 elseif type(value) == "table" then
281 if m_known_tables[value] then
282 self:add_f("%s%s = %s\r\n", prefix, name, m_known_tables[value])
283 elseif m_user_known_tables[value] then
284 self:add_f("%s%s = %s\r\n", prefix, name, m_user_known_tables[value])
285 else
286 local txt = "{"
287 for k,v in pairs(value) do
288 txt = txt..safe_tostring(k)..":"..safe_tostring(v)
289 if #txt > _M.max_tb_output_len then
290 txt = txt.." (more...)"
291 break
292 end
293 if next(value, k) then txt = txt..", " end
294 end
295 self:add_f("%s%s = %s %s\r\n", prefix, name, safe_tostring(value), txt.."}")
296 end
297 elseif type(value) == "function" then
298 local info = self.getinfo(value, "nS")
299 local fun_name = info.name or m_known_functions[value] or m_user_known_functions[value]
300 if info.what == "C" then
301 self:add_f("%s%s = C %s\r\n", prefix, name, (fun_name and ("function: " .. fun_name) or tostring(value)))
302 else
303 local source = info.short_src
304 if source:sub(2,7) == "string" then
305 source = source:sub(9)
306 end
307 --for k,v in pairs(info) do print(k,v) end
308 fun_name = fun_name or GuessFunctionName(info)
309 self:add_f("%s%s = Lua function '%s' (defined at line %d of chunk %s)\r\n", prefix, name, fun_name, info.linedefined, source)
310 end
311 elseif type(value) == "thread" then
312 self:add_f("%sthread %q = %s\r\n", prefix, name, tostring(value))
313 end
314 i = i + 1
315 name, value = self.getlocal(level, i)
316 end
317end
318
319local function getMoonLineNumber(fname, line)
320 local moonCompiled = require("moonp").moon_compiled
321 local source = moonCompiled["@"..fname]
322 local file = io.open(fname)
323 if not source and file then
324 local codes = file:read("*a")
325 file:close()
326 local moonFile = codes:match("^%s*--%s*%[moon%]:%s*([^\n]*)")
327 if moonFile then
328 fname = moonFile:gsub("^%s*(.-)%s*$", "%1")
329 source = codes
330 end
331 end
332 if source then
333 local i, target = 1, tonumber(line)
334 for lineCode in source:gmatch("([^\n]*)\n") do
335 if i == target then
336 local num = lineCode:match("--%s*(%d*)%s*$")
337 if num then
338 return fname, num
339 end
340 break
341 end
342 i = i + 1
343 end
344 end
345 return fname, line
346end
347
348---
349-- Public:
350-- Collects a detailed stack trace, dumping locals, resolving function names when they're not available, etc.
351-- This function is suitable to be used as an error handler with pcall or xpcall
352--
353-- @param thread An optional thread whose stack is to be inspected (defaul is the current thread)
354-- @param message An optional error string or object.
355-- @param level An optional number telling at which level to start the traceback (default is 1)
356--
357-- Returns a string with the stack trace and a string with the original error.
358--
359function _M.stacktrace(thread, message, level)
360 if type(thread) ~= "thread" then
361 -- shift parameters left
362 thread, message, level = nil, thread, message
363 end
364
365 thread = thread or coroutine.running()
366
367 level = level or 1
368
369 local dumper = Dumper.new(thread)
370
371 local original_error
372
373 if type(message) == "table" then
374 dumper:add("an error object {\r\n")
375 local first = true
376 for k,v in pairs(message) do
377 if first then
378 dumper:add(" ")
379 first = false
380 else
381 dumper:add(",\r\n ")
382 end
383 dumper:add(safe_tostring(k))
384 dumper:add(": ")
385 dumper:add(safe_tostring(v))
386 end
387 dumper:add("\r\n}")
388 original_error = dumper:concat_lines()
389 elseif type(message) == "string" then
390 original_error = message
391 local fname, line, msg = message:match('(.+):(%d+): (.*)$')
392 local nfname, nline, nmsg = fname:match('(.+):(%d+): (.*)$')
393 if nfname then
394 fname = nmsg
395 end
396 if fname then
397 fname = fname:gsub("%[string \"", "")
398 fname = fname:gsub("\"%]", "")
399 fname = fname:gsub("^%s*(.-)%s*$", "%1")
400 local extension = fname:match("%.([^%.\\/]*)$")
401 if not extension then
402 local fext = fname .. ".lua"
403 local file = io.open(fext)
404 if file then
405 file:close()
406 fname = fext
407 else
408 fext = fname .. ".moon"
409 file = io.open(fext)
410 if file then
411 file:close()
412 fname = fext
413 end
414 end
415 end
416 fname, line = getMoonLineNumber(fname, line)
417 if _M.simplified then
418 message = table.concat({
419 "'", fname, "':",
420 line, ": ", msg})
421 else
422 message = table.concat({
423 "[string \"", fname, "\"]:",
424 line, ": ", msg})
425 end
426 end
427 dumper:add(message)
428 end
429
430 dumper:add("\r\n")
431 dumper:add[[
432Stack Traceback
433===============
434]]
435 --print(error_message)
436
437 local level_to_show = 1
438 if dumper.dumping_same_thread then level = level + 1 end
439
440 local info = dumper.getinfo(level, "nSlf")
441 while info do
442 if info.source and info.source:sub(1,1) == "@" then
443 info.source = info.source:sub(2)
444 elseif info.what == "main" or info.what == "Lua" then
445 info.source = info.source
446 end
447 local fname = info.source
448 local extension = fname:match("%.([^%.\\/]*)$")
449 if not extension then
450 local fext = fname .. ".lua"
451 local file = io.open(fext)
452 if file then
453 file:close()
454 fname = fext
455 else
456 fext = fname .. ".moon"
457 file = io.open(fext)
458 if file then
459 file:close()
460 fname = fext
461 end
462 end
463 end
464 info.source, info.currentline = getMoonLineNumber(fname, info.currentline)
465 if info.what == "main" then
466 if _M.simplified then
467 dumper:add_f("(%d) '%s':%d\r\n", level_to_show, info.source, info.currentline)
468 else
469 dumper:add_f("(%d) main chunk of file '%s' at line %d\r\n", level_to_show, info.source, info.currentline)
470 end
471 elseif info.what == "C" then
472 --print(info.namewhat, info.name)
473 --for k,v in pairs(info) do print(k,v, type(v)) end
474 local function_name = m_user_known_functions[info.func] or m_known_functions[info.func] or info.name or tostring(info.func)
475 dumper:add_f("(%d) %s C function '%s'\r\n", level_to_show, info.namewhat, function_name)
476 --dumper:add_f("%s%s = C %s\r\n", prefix, name, (m_known_functions[value] and ("function: " .. m_known_functions[value]) or tostring(value)))
477 elseif info.what == "tail" then
478 --print("tail")
479 --for k,v in pairs(info) do print(k,v, type(v)) end--print(info.namewhat, info.name)
480 dumper:add_f("(%d) tail call\r\n", level_to_show)
481 dumper:DumpLocals(level)
482 elseif info.what == "Lua" then
483 local source = info.source
484 local function_name = m_user_known_functions[info.func] or m_known_functions[info.func] or info.name
485 if source:sub(2, 7) == "string" then
486 source = source:sub(10,-3)
487 end
488 local was_guessed = false
489 if not function_name or function_name == "?" then
490 --for k,v in pairs(info) do print(k,v, type(v)) end
491 function_name = GuessFunctionName(info)
492 was_guessed = true
493 end
494 -- test if we have a file name
495 local function_type = (info.namewhat == "") and "function" or info.namewhat
496 if info.source and info.source:sub(1, 1) == "@" then
497 if _M.simplified then
498 dumper:add_f("(%d) '%s':%d%s\r\n", level_to_show, info.source:sub(2), info.currentline, was_guessed and " (guess)" or "")
499 else
500 dumper:add_f("(%d) Lua %s '%s' at file '%s':%d%s\r\n", level_to_show, function_type, function_name, info.source:sub(2), info.currentline, was_guessed and " (best guess)" or "")
501 end
502 elseif info.source and info.source:sub(1,1) == '#' then
503 if _M.simplified then
504 dumper:add_f("(%d) '%s':%d%s\r\n", level_to_show, info.source:sub(2), info.currentline, was_guessed and " (guess)" or "")
505 else
506 dumper:add_f("(%d) Lua %s '%s' at template '%s':%d%s\r\n", level_to_show, function_type, function_name, info.source:sub(2), info.currentline, was_guessed and " (best guess)" or "")
507 end
508 else
509 if _M.simplified then
510 dumper:add_f("(%d) '%s':%d\r\n", level_to_show, source, info.currentline)
511 else
512 dumper:add_f("(%d) Lua %s '%s' at chunk '%s':%d\r\n", level_to_show, function_type, function_name, source, info.currentline)
513 end
514 end
515 dumper:DumpLocals(level)
516 else
517 dumper:add_f("(%d) unknown frame %s\r\n", level_to_show, info.what)
518 end
519
520 level = level + 1
521 level_to_show = level_to_show + 1
522 info = dumper.getinfo(level, "nSlf")
523 end
524
525 return dumper:concat_lines(), original_error
526end
527
528--
529-- Adds a table to the list of known tables
530function _M.add_known_table(tab, description)
531 if m_known_tables[tab] then
532 error("Cannot override an already known table")
533 end
534 m_user_known_tables[tab] = description
535end
536
537--
538-- Adds a function to the list of known functions
539function _M.add_known_function(fun, description)
540 if m_known_functions[fun] then
541 error("Cannot override an already known function")
542 end
543 m_user_known_functions[fun] = description
544end
545
546return _M
547
548)lua_codes";
diff --git a/src/lua-5.3/lapi.c b/src/lua-5.3/lapi.c
new file mode 100644
index 0000000..711895b
--- /dev/null
+++ b/src/lua-5.3/lapi.c
@@ -0,0 +1,1299 @@
1/*
2** $Id: lapi.c,v 2.259.1.2 2017/12/06 18:35:12 roberto Exp $
3** Lua API
4** See Copyright Notice in lua.h
5*/
6
7#define lapi_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <stdarg.h>
14#include <string.h>
15
16#include "lua.h"
17
18#include "lapi.h"
19#include "ldebug.h"
20#include "ldo.h"
21#include "lfunc.h"
22#include "lgc.h"
23#include "lmem.h"
24#include "lobject.h"
25#include "lstate.h"
26#include "lstring.h"
27#include "ltable.h"
28#include "ltm.h"
29#include "lundump.h"
30#include "lvm.h"
31
32
33
34const char lua_ident[] =
35 "$LuaVersion: " LUA_COPYRIGHT " $"
36 "$LuaAuthors: " LUA_AUTHORS " $";
37
38
39/* value at a non-valid index */
40#define NONVALIDVALUE cast(TValue *, luaO_nilobject)
41
42/* corresponding test */
43#define isvalid(o) ((o) != luaO_nilobject)
44
45/* test for pseudo index */
46#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX)
47
48/* test for upvalue */
49#define isupvalue(i) ((i) < LUA_REGISTRYINDEX)
50
51/* test for valid but not pseudo index */
52#define isstackindex(i, o) (isvalid(o) && !ispseudo(i))
53
54#define api_checkvalidindex(l,o) api_check(l, isvalid(o), "invalid index")
55
56#define api_checkstackindex(l, i, o) \
57 api_check(l, isstackindex(i, o), "index not in the stack")
58
59
60static TValue *index2addr (lua_State *L, int idx) {
61 CallInfo *ci = L->ci;
62 if (idx > 0) {
63 TValue *o = ci->func + idx;
64 api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
65 if (o >= L->top) return NONVALIDVALUE;
66 else return o;
67 }
68 else if (!ispseudo(idx)) { /* negative index */
69 api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
70 return L->top + idx;
71 }
72 else if (idx == LUA_REGISTRYINDEX)
73 return &G(L)->l_registry;
74 else { /* upvalues */
75 idx = LUA_REGISTRYINDEX - idx;
76 api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
77 if (ttislcf(ci->func)) /* light C function? */
78 return NONVALIDVALUE; /* it has no upvalues */
79 else {
80 CClosure *func = clCvalue(ci->func);
81 return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
82 }
83 }
84}
85
86
87/*
88** to be called by 'lua_checkstack' in protected mode, to grow stack
89** capturing memory errors
90*/
91static void growstack (lua_State *L, void *ud) {
92 int size = *(int *)ud;
93 luaD_growstack(L, size);
94}
95
96
97LUA_API int lua_checkstack (lua_State *L, int n) {
98 int res;
99 CallInfo *ci = L->ci;
100 lua_lock(L);
101 api_check(L, n >= 0, "negative 'n'");
102 if (L->stack_last - L->top > n) /* stack large enough? */
103 res = 1; /* yes; check is OK */
104 else { /* no; need to grow stack */
105 int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
106 if (inuse > LUAI_MAXSTACK - n) /* can grow without overflow? */
107 res = 0; /* no */
108 else /* try to grow stack */
109 res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK);
110 }
111 if (res && ci->top < L->top + n)
112 ci->top = L->top + n; /* adjust frame top */
113 lua_unlock(L);
114 return res;
115}
116
117
118LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
119 int i;
120 if (from == to) return;
121 lua_lock(to);
122 api_checknelems(from, n);
123 api_check(from, G(from) == G(to), "moving among independent states");
124 api_check(from, to->ci->top - to->top >= n, "stack overflow");
125 from->top -= n;
126 for (i = 0; i < n; i++) {
127 setobj2s(to, to->top, from->top + i);
128 to->top++; /* stack already checked by previous 'api_check' */
129 }
130 lua_unlock(to);
131}
132
133
134LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
135 lua_CFunction old;
136 lua_lock(L);
137 old = G(L)->panic;
138 G(L)->panic = panicf;
139 lua_unlock(L);
140 return old;
141}
142
143
144LUA_API const lua_Number *lua_version (lua_State *L) {
145 static const lua_Number version = LUA_VERSION_NUM;
146 if (L == NULL) return &version;
147 else return G(L)->version;
148}
149
150
151
152/*
153** basic stack manipulation
154*/
155
156
157/*
158** convert an acceptable stack index into an absolute index
159*/
160LUA_API int lua_absindex (lua_State *L, int idx) {
161 return (idx > 0 || ispseudo(idx))
162 ? idx
163 : cast_int(L->top - L->ci->func) + idx;
164}
165
166
167LUA_API int lua_gettop (lua_State *L) {
168 return cast_int(L->top - (L->ci->func + 1));
169}
170
171
172LUA_API void lua_settop (lua_State *L, int idx) {
173 StkId func = L->ci->func;
174 lua_lock(L);
175 if (idx >= 0) {
176 api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
177 while (L->top < (func + 1) + idx)
178 setnilvalue(L->top++);
179 L->top = (func + 1) + idx;
180 }
181 else {
182 api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
183 L->top += idx+1; /* 'subtract' index (index is negative) */
184 }
185 lua_unlock(L);
186}
187
188
189/*
190** Reverse the stack segment from 'from' to 'to'
191** (auxiliary to 'lua_rotate')
192*/
193static void reverse (lua_State *L, StkId from, StkId to) {
194 for (; from < to; from++, to--) {
195 TValue temp;
196 setobj(L, &temp, from);
197 setobjs2s(L, from, to);
198 setobj2s(L, to, &temp);
199 }
200}
201
202
203/*
204** Let x = AB, where A is a prefix of length 'n'. Then,
205** rotate x n == BA. But BA == (A^r . B^r)^r.
206*/
207LUA_API void lua_rotate (lua_State *L, int idx, int n) {
208 StkId p, t, m;
209 lua_lock(L);
210 t = L->top - 1; /* end of stack segment being rotated */
211 p = index2addr(L, idx); /* start of segment */
212 api_checkstackindex(L, idx, p);
213 api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
214 m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */
215 reverse(L, p, m); /* reverse the prefix with length 'n' */
216 reverse(L, m + 1, t); /* reverse the suffix */
217 reverse(L, p, t); /* reverse the entire segment */
218 lua_unlock(L);
219}
220
221
222LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
223 TValue *fr, *to;
224 lua_lock(L);
225 fr = index2addr(L, fromidx);
226 to = index2addr(L, toidx);
227 api_checkvalidindex(L, to);
228 setobj(L, to, fr);
229 if (isupvalue(toidx)) /* function upvalue? */
230 luaC_barrier(L, clCvalue(L->ci->func), fr);
231 /* LUA_REGISTRYINDEX does not need gc barrier
232 (collector revisits it before finishing collection) */
233 lua_unlock(L);
234}
235
236
237LUA_API void lua_pushvalue (lua_State *L, int idx) {
238 lua_lock(L);
239 setobj2s(L, L->top, index2addr(L, idx));
240 api_incr_top(L);
241 lua_unlock(L);
242}
243
244
245
246/*
247** access functions (stack -> C)
248*/
249
250
251LUA_API int lua_type (lua_State *L, int idx) {
252 StkId o = index2addr(L, idx);
253 return (isvalid(o) ? ttnov(o) : LUA_TNONE);
254}
255
256
257LUA_API const char *lua_typename (lua_State *L, int t) {
258 UNUSED(L);
259 api_check(L, LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
260 return ttypename(t);
261}
262
263
264LUA_API int lua_iscfunction (lua_State *L, int idx) {
265 StkId o = index2addr(L, idx);
266 return (ttislcf(o) || (ttisCclosure(o)));
267}
268
269
270LUA_API int lua_isinteger (lua_State *L, int idx) {
271 StkId o = index2addr(L, idx);
272 return ttisinteger(o);
273}
274
275
276LUA_API int lua_isnumber (lua_State *L, int idx) {
277 lua_Number n;
278 const TValue *o = index2addr(L, idx);
279 return tonumber(o, &n);
280}
281
282
283LUA_API int lua_isstring (lua_State *L, int idx) {
284 const TValue *o = index2addr(L, idx);
285 return (ttisstring(o) || cvt2str(o));
286}
287
288
289LUA_API int lua_isuserdata (lua_State *L, int idx) {
290 const TValue *o = index2addr(L, idx);
291 return (ttisfulluserdata(o) || ttislightuserdata(o));
292}
293
294
295LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
296 StkId o1 = index2addr(L, index1);
297 StkId o2 = index2addr(L, index2);
298 return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
299}
300
301
302LUA_API void lua_arith (lua_State *L, int op) {
303 lua_lock(L);
304 if (op != LUA_OPUNM && op != LUA_OPBNOT)
305 api_checknelems(L, 2); /* all other operations expect two operands */
306 else { /* for unary operations, add fake 2nd operand */
307 api_checknelems(L, 1);
308 setobjs2s(L, L->top, L->top - 1);
309 api_incr_top(L);
310 }
311 /* first operand at top - 2, second at top - 1; result go to top - 2 */
312 luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
313 L->top--; /* remove second operand */
314 lua_unlock(L);
315}
316
317
318LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
319 StkId o1, o2;
320 int i = 0;
321 lua_lock(L); /* may call tag method */
322 o1 = index2addr(L, index1);
323 o2 = index2addr(L, index2);
324 if (isvalid(o1) && isvalid(o2)) {
325 switch (op) {
326 case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
327 case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
328 case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
329 default: api_check(L, 0, "invalid option");
330 }
331 }
332 lua_unlock(L);
333 return i;
334}
335
336
337LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
338 size_t sz = luaO_str2num(s, L->top);
339 if (sz != 0)
340 api_incr_top(L);
341 return sz;
342}
343
344
345LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
346 lua_Number n;
347 const TValue *o = index2addr(L, idx);
348 int isnum = tonumber(o, &n);
349 if (!isnum)
350 n = 0; /* call to 'tonumber' may change 'n' even if it fails */
351 if (pisnum) *pisnum = isnum;
352 return n;
353}
354
355
356LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
357 lua_Integer res;
358 const TValue *o = index2addr(L, idx);
359 int isnum = tointeger(o, &res);
360 if (!isnum)
361 res = 0; /* call to 'tointeger' may change 'n' even if it fails */
362 if (pisnum) *pisnum = isnum;
363 return res;
364}
365
366
367LUA_API int lua_toboolean (lua_State *L, int idx) {
368 const TValue *o = index2addr(L, idx);
369 return !l_isfalse(o);
370}
371
372
373LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
374 StkId o = index2addr(L, idx);
375 if (!ttisstring(o)) {
376 if (!cvt2str(o)) { /* not convertible? */
377 if (len != NULL) *len = 0;
378 return NULL;
379 }
380 lua_lock(L); /* 'luaO_tostring' may create a new string */
381 luaO_tostring(L, o);
382 luaC_checkGC(L);
383 o = index2addr(L, idx); /* previous call may reallocate the stack */
384 lua_unlock(L);
385 }
386 if (len != NULL)
387 *len = vslen(o);
388 return svalue(o);
389}
390
391
392LUA_API size_t lua_rawlen (lua_State *L, int idx) {
393 StkId o = index2addr(L, idx);
394 switch (ttype(o)) {
395 case LUA_TSHRSTR: return tsvalue(o)->shrlen;
396 case LUA_TLNGSTR: return tsvalue(o)->u.lnglen;
397 case LUA_TUSERDATA: return uvalue(o)->len;
398 case LUA_TTABLE: return luaH_getn(hvalue(o));
399 default: return 0;
400 }
401}
402
403
404LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
405 StkId o = index2addr(L, idx);
406 if (ttislcf(o)) return fvalue(o);
407 else if (ttisCclosure(o))
408 return clCvalue(o)->f;
409 else return NULL; /* not a C function */
410}
411
412
413LUA_API void *lua_touserdata (lua_State *L, int idx) {
414 StkId o = index2addr(L, idx);
415 switch (ttnov(o)) {
416 case LUA_TUSERDATA: return getudatamem(uvalue(o));
417 case LUA_TLIGHTUSERDATA: return pvalue(o);
418 default: return NULL;
419 }
420}
421
422
423LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
424 StkId o = index2addr(L, idx);
425 return (!ttisthread(o)) ? NULL : thvalue(o);
426}
427
428
429LUA_API const void *lua_topointer (lua_State *L, int idx) {
430 StkId o = index2addr(L, idx);
431 switch (ttype(o)) {
432 case LUA_TTABLE: return hvalue(o);
433 case LUA_TLCL: return clLvalue(o);
434 case LUA_TCCL: return clCvalue(o);
435 case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
436 case LUA_TTHREAD: return thvalue(o);
437 case LUA_TUSERDATA: return getudatamem(uvalue(o));
438 case LUA_TLIGHTUSERDATA: return pvalue(o);
439 default: return NULL;
440 }
441}
442
443
444
445/*
446** push functions (C -> stack)
447*/
448
449
450LUA_API void lua_pushnil (lua_State *L) {
451 lua_lock(L);
452 setnilvalue(L->top);
453 api_incr_top(L);
454 lua_unlock(L);
455}
456
457
458LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
459 lua_lock(L);
460 setfltvalue(L->top, n);
461 api_incr_top(L);
462 lua_unlock(L);
463}
464
465
466LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
467 lua_lock(L);
468 setivalue(L->top, n);
469 api_incr_top(L);
470 lua_unlock(L);
471}
472
473
474/*
475** Pushes on the stack a string with given length. Avoid using 's' when
476** 'len' == 0 (as 's' can be NULL in that case), due to later use of
477** 'memcmp' and 'memcpy'.
478*/
479LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
480 TString *ts;
481 lua_lock(L);
482 ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
483 setsvalue2s(L, L->top, ts);
484 api_incr_top(L);
485 luaC_checkGC(L);
486 lua_unlock(L);
487 return getstr(ts);
488}
489
490
491LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
492 lua_lock(L);
493 if (s == NULL)
494 setnilvalue(L->top);
495 else {
496 TString *ts;
497 ts = luaS_new(L, s);
498 setsvalue2s(L, L->top, ts);
499 s = getstr(ts); /* internal copy's address */
500 }
501 api_incr_top(L);
502 luaC_checkGC(L);
503 lua_unlock(L);
504 return s;
505}
506
507
508LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
509 va_list argp) {
510 const char *ret;
511 lua_lock(L);
512 ret = luaO_pushvfstring(L, fmt, argp);
513 luaC_checkGC(L);
514 lua_unlock(L);
515 return ret;
516}
517
518
519LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
520 const char *ret;
521 va_list argp;
522 lua_lock(L);
523 va_start(argp, fmt);
524 ret = luaO_pushvfstring(L, fmt, argp);
525 va_end(argp);
526 luaC_checkGC(L);
527 lua_unlock(L);
528 return ret;
529}
530
531
532LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
533 lua_lock(L);
534 if (n == 0) {
535 setfvalue(L->top, fn);
536 api_incr_top(L);
537 }
538 else {
539 CClosure *cl;
540 api_checknelems(L, n);
541 api_check(L, n <= MAXUPVAL, "upvalue index too large");
542 cl = luaF_newCclosure(L, n);
543 cl->f = fn;
544 L->top -= n;
545 while (n--) {
546 setobj2n(L, &cl->upvalue[n], L->top + n);
547 /* does not need barrier because closure is white */
548 }
549 setclCvalue(L, L->top, cl);
550 api_incr_top(L);
551 luaC_checkGC(L);
552 }
553 lua_unlock(L);
554}
555
556
557LUA_API void lua_pushboolean (lua_State *L, int b) {
558 lua_lock(L);
559 setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
560 api_incr_top(L);
561 lua_unlock(L);
562}
563
564
565LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
566 lua_lock(L);
567 setpvalue(L->top, p);
568 api_incr_top(L);
569 lua_unlock(L);
570}
571
572
573LUA_API int lua_pushthread (lua_State *L) {
574 lua_lock(L);
575 setthvalue(L, L->top, L);
576 api_incr_top(L);
577 lua_unlock(L);
578 return (G(L)->mainthread == L);
579}
580
581
582
583/*
584** get functions (Lua -> stack)
585*/
586
587
588static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
589 const TValue *slot;
590 TString *str = luaS_new(L, k);
591 if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
592 setobj2s(L, L->top, slot);
593 api_incr_top(L);
594 }
595 else {
596 setsvalue2s(L, L->top, str);
597 api_incr_top(L);
598 luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
599 }
600 lua_unlock(L);
601 return ttnov(L->top - 1);
602}
603
604
605LUA_API int lua_getglobal (lua_State *L, const char *name) {
606 Table *reg = hvalue(&G(L)->l_registry);
607 lua_lock(L);
608 return auxgetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name);
609}
610
611
612LUA_API int lua_gettable (lua_State *L, int idx) {
613 StkId t;
614 lua_lock(L);
615 t = index2addr(L, idx);
616 luaV_gettable(L, t, L->top - 1, L->top - 1);
617 lua_unlock(L);
618 return ttnov(L->top - 1);
619}
620
621
622LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
623 lua_lock(L);
624 return auxgetstr(L, index2addr(L, idx), k);
625}
626
627
628LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
629 StkId t;
630 const TValue *slot;
631 lua_lock(L);
632 t = index2addr(L, idx);
633 if (luaV_fastget(L, t, n, slot, luaH_getint)) {
634 setobj2s(L, L->top, slot);
635 api_incr_top(L);
636 }
637 else {
638 setivalue(L->top, n);
639 api_incr_top(L);
640 luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
641 }
642 lua_unlock(L);
643 return ttnov(L->top - 1);
644}
645
646
647LUA_API int lua_rawget (lua_State *L, int idx) {
648 StkId t;
649 lua_lock(L);
650 t = index2addr(L, idx);
651 api_check(L, ttistable(t), "table expected");
652 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
653 lua_unlock(L);
654 return ttnov(L->top - 1);
655}
656
657
658LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
659 StkId t;
660 lua_lock(L);
661 t = index2addr(L, idx);
662 api_check(L, ttistable(t), "table expected");
663 setobj2s(L, L->top, luaH_getint(hvalue(t), n));
664 api_incr_top(L);
665 lua_unlock(L);
666 return ttnov(L->top - 1);
667}
668
669
670LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
671 StkId t;
672 TValue k;
673 lua_lock(L);
674 t = index2addr(L, idx);
675 api_check(L, ttistable(t), "table expected");
676 setpvalue(&k, cast(void *, p));
677 setobj2s(L, L->top, luaH_get(hvalue(t), &k));
678 api_incr_top(L);
679 lua_unlock(L);
680 return ttnov(L->top - 1);
681}
682
683
684LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
685 Table *t;
686 lua_lock(L);
687 t = luaH_new(L);
688 sethvalue(L, L->top, t);
689 api_incr_top(L);
690 if (narray > 0 || nrec > 0)
691 luaH_resize(L, t, narray, nrec);
692 luaC_checkGC(L);
693 lua_unlock(L);
694}
695
696
697LUA_API int lua_getmetatable (lua_State *L, int objindex) {
698 const TValue *obj;
699 Table *mt;
700 int res = 0;
701 lua_lock(L);
702 obj = index2addr(L, objindex);
703 switch (ttnov(obj)) {
704 case LUA_TTABLE:
705 mt = hvalue(obj)->metatable;
706 break;
707 case LUA_TUSERDATA:
708 mt = uvalue(obj)->metatable;
709 break;
710 default:
711 mt = G(L)->mt[ttnov(obj)];
712 break;
713 }
714 if (mt != NULL) {
715 sethvalue(L, L->top, mt);
716 api_incr_top(L);
717 res = 1;
718 }
719 lua_unlock(L);
720 return res;
721}
722
723
724LUA_API int lua_getuservalue (lua_State *L, int idx) {
725 StkId o;
726 lua_lock(L);
727 o = index2addr(L, idx);
728 api_check(L, ttisfulluserdata(o), "full userdata expected");
729 getuservalue(L, uvalue(o), L->top);
730 api_incr_top(L);
731 lua_unlock(L);
732 return ttnov(L->top - 1);
733}
734
735
736/*
737** set functions (stack -> Lua)
738*/
739
740/*
741** t[k] = value at the top of the stack (where 'k' is a string)
742*/
743static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
744 const TValue *slot;
745 TString *str = luaS_new(L, k);
746 api_checknelems(L, 1);
747 if (luaV_fastset(L, t, str, slot, luaH_getstr, L->top - 1))
748 L->top--; /* pop value */
749 else {
750 setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */
751 api_incr_top(L);
752 luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
753 L->top -= 2; /* pop value and key */
754 }
755 lua_unlock(L); /* lock done by caller */
756}
757
758
759LUA_API void lua_setglobal (lua_State *L, const char *name) {
760 Table *reg = hvalue(&G(L)->l_registry);
761 lua_lock(L); /* unlock done in 'auxsetstr' */
762 auxsetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name);
763}
764
765
766LUA_API void lua_settable (lua_State *L, int idx) {
767 StkId t;
768 lua_lock(L);
769 api_checknelems(L, 2);
770 t = index2addr(L, idx);
771 luaV_settable(L, t, L->top - 2, L->top - 1);
772 L->top -= 2; /* pop index and value */
773 lua_unlock(L);
774}
775
776
777LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
778 lua_lock(L); /* unlock done in 'auxsetstr' */
779 auxsetstr(L, index2addr(L, idx), k);
780}
781
782
783LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
784 StkId t;
785 const TValue *slot;
786 lua_lock(L);
787 api_checknelems(L, 1);
788 t = index2addr(L, idx);
789 if (luaV_fastset(L, t, n, slot, luaH_getint, L->top - 1))
790 L->top--; /* pop value */
791 else {
792 setivalue(L->top, n);
793 api_incr_top(L);
794 luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
795 L->top -= 2; /* pop value and key */
796 }
797 lua_unlock(L);
798}
799
800
801LUA_API void lua_rawset (lua_State *L, int idx) {
802 StkId o;
803 TValue *slot;
804 lua_lock(L);
805 api_checknelems(L, 2);
806 o = index2addr(L, idx);
807 api_check(L, ttistable(o), "table expected");
808 slot = luaH_set(L, hvalue(o), L->top - 2);
809 setobj2t(L, slot, L->top - 1);
810 invalidateTMcache(hvalue(o));
811 luaC_barrierback(L, hvalue(o), L->top-1);
812 L->top -= 2;
813 lua_unlock(L);
814}
815
816
817LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
818 StkId o;
819 lua_lock(L);
820 api_checknelems(L, 1);
821 o = index2addr(L, idx);
822 api_check(L, ttistable(o), "table expected");
823 luaH_setint(L, hvalue(o), n, L->top - 1);
824 luaC_barrierback(L, hvalue(o), L->top-1);
825 L->top--;
826 lua_unlock(L);
827}
828
829
830LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
831 StkId o;
832 TValue k, *slot;
833 lua_lock(L);
834 api_checknelems(L, 1);
835 o = index2addr(L, idx);
836 api_check(L, ttistable(o), "table expected");
837 setpvalue(&k, cast(void *, p));
838 slot = luaH_set(L, hvalue(o), &k);
839 setobj2t(L, slot, L->top - 1);
840 luaC_barrierback(L, hvalue(o), L->top - 1);
841 L->top--;
842 lua_unlock(L);
843}
844
845
846LUA_API int lua_setmetatable (lua_State *L, int objindex) {
847 TValue *obj;
848 Table *mt;
849 lua_lock(L);
850 api_checknelems(L, 1);
851 obj = index2addr(L, objindex);
852 if (ttisnil(L->top - 1))
853 mt = NULL;
854 else {
855 api_check(L, ttistable(L->top - 1), "table expected");
856 mt = hvalue(L->top - 1);
857 }
858 switch (ttnov(obj)) {
859 case LUA_TTABLE: {
860 hvalue(obj)->metatable = mt;
861 if (mt) {
862 luaC_objbarrier(L, gcvalue(obj), mt);
863 luaC_checkfinalizer(L, gcvalue(obj), mt);
864 }
865 break;
866 }
867 case LUA_TUSERDATA: {
868 uvalue(obj)->metatable = mt;
869 if (mt) {
870 luaC_objbarrier(L, uvalue(obj), mt);
871 luaC_checkfinalizer(L, gcvalue(obj), mt);
872 }
873 break;
874 }
875 default: {
876 G(L)->mt[ttnov(obj)] = mt;
877 break;
878 }
879 }
880 L->top--;
881 lua_unlock(L);
882 return 1;
883}
884
885
886LUA_API void lua_setuservalue (lua_State *L, int idx) {
887 StkId o;
888 lua_lock(L);
889 api_checknelems(L, 1);
890 o = index2addr(L, idx);
891 api_check(L, ttisfulluserdata(o), "full userdata expected");
892 setuservalue(L, uvalue(o), L->top - 1);
893 luaC_barrier(L, gcvalue(o), L->top - 1);
894 L->top--;
895 lua_unlock(L);
896}
897
898
899/*
900** 'load' and 'call' functions (run Lua code)
901*/
902
903
904#define checkresults(L,na,nr) \
905 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
906 "results from function overflow current stack size")
907
908
909LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
910 lua_KContext ctx, lua_KFunction k) {
911 StkId func;
912 lua_lock(L);
913 api_check(L, k == NULL || !isLua(L->ci),
914 "cannot use continuations inside hooks");
915 api_checknelems(L, nargs+1);
916 api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
917 checkresults(L, nargs, nresults);
918 func = L->top - (nargs+1);
919 if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
920 L->ci->u.c.k = k; /* save continuation */
921 L->ci->u.c.ctx = ctx; /* save context */
922 luaD_call(L, func, nresults); /* do the call */
923 }
924 else /* no continuation or no yieldable */
925 luaD_callnoyield(L, func, nresults); /* just do the call */
926 adjustresults(L, nresults);
927 lua_unlock(L);
928}
929
930
931
932/*
933** Execute a protected call.
934*/
935struct CallS { /* data to 'f_call' */
936 StkId func;
937 int nresults;
938};
939
940
941static void f_call (lua_State *L, void *ud) {
942 struct CallS *c = cast(struct CallS *, ud);
943 luaD_callnoyield(L, c->func, c->nresults);
944}
945
946
947
948LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
949 lua_KContext ctx, lua_KFunction k) {
950 struct CallS c;
951 int status;
952 ptrdiff_t func;
953 lua_lock(L);
954 api_check(L, k == NULL || !isLua(L->ci),
955 "cannot use continuations inside hooks");
956 api_checknelems(L, nargs+1);
957 api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
958 checkresults(L, nargs, nresults);
959 if (errfunc == 0)
960 func = 0;
961 else {
962 StkId o = index2addr(L, errfunc);
963 api_checkstackindex(L, errfunc, o);
964 func = savestack(L, o);
965 }
966 c.func = L->top - (nargs+1); /* function to be called */
967 if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */
968 c.nresults = nresults; /* do a 'conventional' protected call */
969 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
970 }
971 else { /* prepare continuation (call is already protected by 'resume') */
972 CallInfo *ci = L->ci;
973 ci->u.c.k = k; /* save continuation */
974 ci->u.c.ctx = ctx; /* save context */
975 /* save information for error recovery */
976 ci->extra = savestack(L, c.func);
977 ci->u.c.old_errfunc = L->errfunc;
978 L->errfunc = func;
979 setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */
980 ci->callstatus |= CIST_YPCALL; /* function can do error recovery */
981 luaD_call(L, c.func, nresults); /* do the call */
982 ci->callstatus &= ~CIST_YPCALL;
983 L->errfunc = ci->u.c.old_errfunc;
984 status = LUA_OK; /* if it is here, there were no errors */
985 }
986 adjustresults(L, nresults);
987 lua_unlock(L);
988 return status;
989}
990
991
992LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
993 const char *chunkname, const char *mode) {
994 ZIO z;
995 int status;
996 lua_lock(L);
997 if (!chunkname) chunkname = "?";
998 luaZ_init(L, &z, reader, data);
999 status = luaD_protectedparser(L, &z, chunkname, mode);
1000 if (status == LUA_OK) { /* no errors? */
1001 LClosure *f = clLvalue(L->top - 1); /* get newly created function */
1002 if (f->nupvalues >= 1) { /* does it have an upvalue? */
1003 /* get global table from registry */
1004 Table *reg = hvalue(&G(L)->l_registry);
1005 const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
1006 /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
1007 setobj(L, f->upvals[0]->v, gt);
1008 luaC_upvalbarrier(L, f->upvals[0]);
1009 }
1010 }
1011 lua_unlock(L);
1012 return status;
1013}
1014
1015
1016LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
1017 int status;
1018 TValue *o;
1019 lua_lock(L);
1020 api_checknelems(L, 1);
1021 o = L->top - 1;
1022 if (isLfunction(o))
1023 status = luaU_dump(L, getproto(o), writer, data, strip);
1024 else
1025 status = 1;
1026 lua_unlock(L);
1027 return status;
1028}
1029
1030
1031LUA_API int lua_status (lua_State *L) {
1032 return L->status;
1033}
1034
1035
1036/*
1037** Garbage-collection function
1038*/
1039
1040LUA_API int lua_gc (lua_State *L, int what, int data) {
1041 int res = 0;
1042 global_State *g;
1043 lua_lock(L);
1044 g = G(L);
1045 switch (what) {
1046 case LUA_GCSTOP: {
1047 g->gcrunning = 0;
1048 break;
1049 }
1050 case LUA_GCRESTART: {
1051 luaE_setdebt(g, 0);
1052 g->gcrunning = 1;
1053 break;
1054 }
1055 case LUA_GCCOLLECT: {
1056 luaC_fullgc(L, 0);
1057 break;
1058 }
1059 case LUA_GCCOUNT: {
1060 /* GC values are expressed in Kbytes: #bytes/2^10 */
1061 res = cast_int(gettotalbytes(g) >> 10);
1062 break;
1063 }
1064 case LUA_GCCOUNTB: {
1065 res = cast_int(gettotalbytes(g) & 0x3ff);
1066 break;
1067 }
1068 case LUA_GCSTEP: {
1069 l_mem debt = 1; /* =1 to signal that it did an actual step */
1070 lu_byte oldrunning = g->gcrunning;
1071 g->gcrunning = 1; /* allow GC to run */
1072 if (data == 0) {
1073 luaE_setdebt(g, -GCSTEPSIZE); /* to do a "small" step */
1074 luaC_step(L);
1075 }
1076 else { /* add 'data' to total debt */
1077 debt = cast(l_mem, data) * 1024 + g->GCdebt;
1078 luaE_setdebt(g, debt);
1079 luaC_checkGC(L);
1080 }
1081 g->gcrunning = oldrunning; /* restore previous state */
1082 if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */
1083 res = 1; /* signal it */
1084 break;
1085 }
1086 case LUA_GCSETPAUSE: {
1087 res = g->gcpause;
1088 g->gcpause = data;
1089 break;
1090 }
1091 case LUA_GCSETSTEPMUL: {
1092 res = g->gcstepmul;
1093 if (data < 40) data = 40; /* avoid ridiculous low values (and 0) */
1094 g->gcstepmul = data;
1095 break;
1096 }
1097 case LUA_GCISRUNNING: {
1098 res = g->gcrunning;
1099 break;
1100 }
1101 default: res = -1; /* invalid option */
1102 }
1103 lua_unlock(L);
1104 return res;
1105}
1106
1107
1108
1109/*
1110** miscellaneous functions
1111*/
1112
1113
1114LUA_API int lua_error (lua_State *L) {
1115 lua_lock(L);
1116 api_checknelems(L, 1);
1117 luaG_errormsg(L);
1118 /* code unreachable; will unlock when control actually leaves the kernel */
1119 return 0; /* to avoid warnings */
1120}
1121
1122
1123LUA_API int lua_next (lua_State *L, int idx) {
1124 StkId t;
1125 int more;
1126 lua_lock(L);
1127 t = index2addr(L, idx);
1128 api_check(L, ttistable(t), "table expected");
1129 more = luaH_next(L, hvalue(t), L->top - 1);
1130 if (more) {
1131 api_incr_top(L);
1132 }
1133 else /* no more elements */
1134 L->top -= 1; /* remove key */
1135 lua_unlock(L);
1136 return more;
1137}
1138
1139
1140LUA_API void lua_concat (lua_State *L, int n) {
1141 lua_lock(L);
1142 api_checknelems(L, n);
1143 if (n >= 2) {
1144 luaV_concat(L, n);
1145 }
1146 else if (n == 0) { /* push empty string */
1147 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
1148 api_incr_top(L);
1149 }
1150 /* else n == 1; nothing to do */
1151 luaC_checkGC(L);
1152 lua_unlock(L);
1153}
1154
1155
1156LUA_API void lua_len (lua_State *L, int idx) {
1157 StkId t;
1158 lua_lock(L);
1159 t = index2addr(L, idx);
1160 luaV_objlen(L, L->top, t);
1161 api_incr_top(L);
1162 lua_unlock(L);
1163}
1164
1165
1166LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1167 lua_Alloc f;
1168 lua_lock(L);
1169 if (ud) *ud = G(L)->ud;
1170 f = G(L)->frealloc;
1171 lua_unlock(L);
1172 return f;
1173}
1174
1175
1176LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1177 lua_lock(L);
1178 G(L)->ud = ud;
1179 G(L)->frealloc = f;
1180 lua_unlock(L);
1181}
1182
1183
1184LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1185 Udata *u;
1186 lua_lock(L);
1187 u = luaS_newudata(L, size);
1188 setuvalue(L, L->top, u);
1189 api_incr_top(L);
1190 luaC_checkGC(L);
1191 lua_unlock(L);
1192 return getudatamem(u);
1193}
1194
1195
1196
1197static const char *aux_upvalue (StkId fi, int n, TValue **val,
1198 CClosure **owner, UpVal **uv) {
1199 switch (ttype(fi)) {
1200 case LUA_TCCL: { /* C closure */
1201 CClosure *f = clCvalue(fi);
1202 if (!(1 <= n && n <= f->nupvalues)) return NULL;
1203 *val = &f->upvalue[n-1];
1204 if (owner) *owner = f;
1205 return "";
1206 }
1207 case LUA_TLCL: { /* Lua closure */
1208 LClosure *f = clLvalue(fi);
1209 TString *name;
1210 Proto *p = f->p;
1211 if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1212 *val = f->upvals[n-1]->v;
1213 if (uv) *uv = f->upvals[n - 1];
1214 name = p->upvalues[n-1].name;
1215 return (name == NULL) ? "(*no name)" : getstr(name);
1216 }
1217 default: return NULL; /* not a closure */
1218 }
1219}
1220
1221
1222LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1223 const char *name;
1224 TValue *val = NULL; /* to avoid warnings */
1225 lua_lock(L);
1226 name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL);
1227 if (name) {
1228 setobj2s(L, L->top, val);
1229 api_incr_top(L);
1230 }
1231 lua_unlock(L);
1232 return name;
1233}
1234
1235
1236LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1237 const char *name;
1238 TValue *val = NULL; /* to avoid warnings */
1239 CClosure *owner = NULL;
1240 UpVal *uv = NULL;
1241 StkId fi;
1242 lua_lock(L);
1243 fi = index2addr(L, funcindex);
1244 api_checknelems(L, 1);
1245 name = aux_upvalue(fi, n, &val, &owner, &uv);
1246 if (name) {
1247 L->top--;
1248 setobj(L, val, L->top);
1249 if (owner) { luaC_barrier(L, owner, L->top); }
1250 else if (uv) { luaC_upvalbarrier(L, uv); }
1251 }
1252 lua_unlock(L);
1253 return name;
1254}
1255
1256
1257static UpVal **getupvalref (lua_State *L, int fidx, int n) {
1258 LClosure *f;
1259 StkId fi = index2addr(L, fidx);
1260 api_check(L, ttisLclosure(fi), "Lua function expected");
1261 f = clLvalue(fi);
1262 api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
1263 return &f->upvals[n - 1]; /* get its upvalue pointer */
1264}
1265
1266
1267LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
1268 StkId fi = index2addr(L, fidx);
1269 switch (ttype(fi)) {
1270 case LUA_TLCL: { /* lua closure */
1271 return *getupvalref(L, fidx, n);
1272 }
1273 case LUA_TCCL: { /* C closure */
1274 CClosure *f = clCvalue(fi);
1275 api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
1276 return &f->upvalue[n - 1];
1277 }
1278 default: {
1279 api_check(L, 0, "closure expected");
1280 return NULL;
1281 }
1282 }
1283}
1284
1285
1286LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
1287 int fidx2, int n2) {
1288 UpVal **up1 = getupvalref(L, fidx1, n1);
1289 UpVal **up2 = getupvalref(L, fidx2, n2);
1290 if (*up1 == *up2)
1291 return;
1292 luaC_upvdeccount(L, *up1);
1293 *up1 = *up2;
1294 (*up1)->refcount++;
1295 if (upisopen(*up1)) (*up1)->u.open.touched = 1;
1296 luaC_upvalbarrier(L, *up1);
1297}
1298
1299
diff --git a/src/lua-5.3/lapi.h b/src/lua-5.3/lapi.h
new file mode 100644
index 0000000..8e16ad5
--- /dev/null
+++ b/src/lua-5.3/lapi.h
@@ -0,0 +1,24 @@
1/*
2** $Id: lapi.h,v 2.9.1.1 2017/04/19 17:20:42 roberto Exp $
3** Auxiliary functions from Lua API
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lapi_h
8#define lapi_h
9
10
11#include "llimits.h"
12#include "lstate.h"
13
14#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
15 "stack overflow");}
16
17#define adjustresults(L,nres) \
18 { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
19
20#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
21 "not enough elements in the stack")
22
23
24#endif
diff --git a/src/lua-5.3/lauxlib.c b/src/lua-5.3/lauxlib.c
new file mode 100644
index 0000000..8bdada5
--- /dev/null
+++ b/src/lua-5.3/lauxlib.c
@@ -0,0 +1,1043 @@
1/*
2** $Id: lauxlib.c,v 1.289.1.1 2017/04/19 17:20:42 roberto Exp $
3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h
5*/
6
7#define lauxlib_c
8#define LUA_LIB
9
10#include "lprefix.h"
11
12
13#include <errno.h>
14#include <stdarg.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18
19
20/*
21** This file uses only the official API of Lua.
22** Any function declared here could be written as an application function.
23*/
24
25#include "lua.h"
26
27#include "lauxlib.h"
28
29
30/*
31** {======================================================
32** Traceback
33** =======================================================
34*/
35
36
37#define LEVELS1 10 /* size of the first part of the stack */
38#define LEVELS2 11 /* size of the second part of the stack */
39
40
41
42/*
43** search for 'objidx' in table at index -1.
44** return 1 + string at top if find a good name.
45*/
46static int findfield (lua_State *L, int objidx, int level) {
47 if (level == 0 || !lua_istable(L, -1))
48 return 0; /* not found */
49 lua_pushnil(L); /* start 'next' loop */
50 while (lua_next(L, -2)) { /* for each pair in table */
51 if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
52 if (lua_rawequal(L, objidx, -1)) { /* found object? */
53 lua_pop(L, 1); /* remove value (but keep name) */
54 return 1;
55 }
56 else if (findfield(L, objidx, level - 1)) { /* try recursively */
57 lua_remove(L, -2); /* remove table (but keep name) */
58 lua_pushliteral(L, ".");
59 lua_insert(L, -2); /* place '.' between the two names */
60 lua_concat(L, 3);
61 return 1;
62 }
63 }
64 lua_pop(L, 1); /* remove value */
65 }
66 return 0; /* not found */
67}
68
69
70/*
71** Search for a name for a function in all loaded modules
72*/
73static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
74 int top = lua_gettop(L);
75 lua_getinfo(L, "f", ar); /* push function */
76 lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
77 if (findfield(L, top + 1, 2)) {
78 const char *name = lua_tostring(L, -1);
79 if (strncmp(name, "_G.", 3) == 0) { /* name start with '_G.'? */
80 lua_pushstring(L, name + 3); /* push name without prefix */
81 lua_remove(L, -2); /* remove original name */
82 }
83 lua_copy(L, -1, top + 1); /* move name to proper place */
84 lua_pop(L, 2); /* remove pushed values */
85 return 1;
86 }
87 else {
88 lua_settop(L, top); /* remove function and global table */
89 return 0;
90 }
91}
92
93
94static void pushfuncname (lua_State *L, lua_Debug *ar) {
95 if (pushglobalfuncname(L, ar)) { /* try first a global name */
96 lua_pushfstring(L, "function '%s'", lua_tostring(L, -1));
97 lua_remove(L, -2); /* remove name */
98 }
99 else if (*ar->namewhat != '\0') /* is there a name from code? */
100 lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name); /* use it */
101 else if (*ar->what == 'm') /* main? */
102 lua_pushliteral(L, "main chunk");
103 else if (*ar->what != 'C') /* for Lua functions, use <file:line> */
104 lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
105 else /* nothing left... */
106 lua_pushliteral(L, "?");
107}
108
109
110static int lastlevel (lua_State *L) {
111 lua_Debug ar;
112 int li = 1, le = 1;
113 /* find an upper bound */
114 while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
115 /* do a binary search */
116 while (li < le) {
117 int m = (li + le)/2;
118 if (lua_getstack(L, m, &ar)) li = m + 1;
119 else le = m;
120 }
121 return le - 1;
122}
123
124
125LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
126 const char *msg, int level) {
127 lua_Debug ar;
128 int top = lua_gettop(L);
129 int last = lastlevel(L1);
130 int n1 = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1;
131 if (msg)
132 lua_pushfstring(L, "%s\n", msg);
133 luaL_checkstack(L, 10, NULL);
134 lua_pushliteral(L, "stack traceback:");
135 while (lua_getstack(L1, level++, &ar)) {
136 if (n1-- == 0) { /* too many levels? */
137 lua_pushliteral(L, "\n\t..."); /* add a '...' */
138 level = last - LEVELS2 + 1; /* and skip to last ones */
139 }
140 else {
141 lua_getinfo(L1, "Slnt", &ar);
142 lua_pushfstring(L, "\n\t%s:", ar.short_src);
143 if (ar.currentline > 0)
144 lua_pushfstring(L, "%d:", ar.currentline);
145 lua_pushliteral(L, " in ");
146 pushfuncname(L, &ar);
147 if (ar.istailcall)
148 lua_pushliteral(L, "\n\t(...tail calls...)");
149 lua_concat(L, lua_gettop(L) - top);
150 }
151 }
152 lua_concat(L, lua_gettop(L) - top);
153}
154
155/* }====================================================== */
156
157
158/*
159** {======================================================
160** Error-report functions
161** =======================================================
162*/
163
164LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
165 lua_Debug ar;
166 if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
167 return luaL_error(L, "bad argument #%d (%s)", arg, extramsg);
168 lua_getinfo(L, "n", &ar);
169 if (strcmp(ar.namewhat, "method") == 0) {
170 arg--; /* do not count 'self' */
171 if (arg == 0) /* error is in the self argument itself? */
172 return luaL_error(L, "calling '%s' on bad self (%s)",
173 ar.name, extramsg);
174 }
175 if (ar.name == NULL)
176 ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
177 return luaL_error(L, "bad argument #%d to '%s' (%s)",
178 arg, ar.name, extramsg);
179}
180
181
182static int typeerror (lua_State *L, int arg, const char *tname) {
183 const char *msg;
184 const char *typearg; /* name for the type of the actual argument */
185 if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING)
186 typearg = lua_tostring(L, -1); /* use the given type name */
187 else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA)
188 typearg = "light userdata"; /* special name for messages */
189 else
190 typearg = luaL_typename(L, arg); /* standard name */
191 msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg);
192 return luaL_argerror(L, arg, msg);
193}
194
195
196static void tag_error (lua_State *L, int arg, int tag) {
197 typeerror(L, arg, lua_typename(L, tag));
198}
199
200
201/*
202** The use of 'lua_pushfstring' ensures this function does not
203** need reserved stack space when called.
204*/
205LUALIB_API void luaL_where (lua_State *L, int level) {
206 lua_Debug ar;
207 if (lua_getstack(L, level, &ar)) { /* check function at level */
208 lua_getinfo(L, "Sl", &ar); /* get info about it */
209 if (ar.currentline > 0) { /* is there info? */
210 lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
211 return;
212 }
213 }
214 lua_pushfstring(L, ""); /* else, no information available... */
215}
216
217
218/*
219** Again, the use of 'lua_pushvfstring' ensures this function does
220** not need reserved stack space when called. (At worst, it generates
221** an error with "stack overflow" instead of the given message.)
222*/
223LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
224 va_list argp;
225 va_start(argp, fmt);
226 luaL_where(L, 1);
227 lua_pushvfstring(L, fmt, argp);
228 va_end(argp);
229 lua_concat(L, 2);
230 return lua_error(L);
231}
232
233
234LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
235 int en = errno; /* calls to Lua API may change this value */
236 if (stat) {
237 lua_pushboolean(L, 1);
238 return 1;
239 }
240 else {
241 lua_pushnil(L);
242 if (fname)
243 lua_pushfstring(L, "%s: %s", fname, strerror(en));
244 else
245 lua_pushstring(L, strerror(en));
246 lua_pushinteger(L, en);
247 return 3;
248 }
249}
250
251
252#if !defined(l_inspectstat) /* { */
253
254#if defined(LUA_USE_POSIX)
255
256#include <sys/wait.h>
257
258/*
259** use appropriate macros to interpret 'pclose' return status
260*/
261#define l_inspectstat(stat,what) \
262 if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
263 else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
264
265#else
266
267#define l_inspectstat(stat,what) /* no op */
268
269#endif
270
271#endif /* } */
272
273
274LUALIB_API int luaL_execresult (lua_State *L, int stat) {
275 const char *what = "exit"; /* type of termination */
276 if (stat == -1) /* error? */
277 return luaL_fileresult(L, 0, NULL);
278 else {
279 l_inspectstat(stat, what); /* interpret result */
280 if (*what == 'e' && stat == 0) /* successful termination? */
281 lua_pushboolean(L, 1);
282 else
283 lua_pushnil(L);
284 lua_pushstring(L, what);
285 lua_pushinteger(L, stat);
286 return 3; /* return true/nil,what,code */
287 }
288}
289
290/* }====================================================== */
291
292
293/*
294** {======================================================
295** Userdata's metatable manipulation
296** =======================================================
297*/
298
299LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
300 if (luaL_getmetatable(L, tname) != LUA_TNIL) /* name already in use? */
301 return 0; /* leave previous value on top, but return 0 */
302 lua_pop(L, 1);
303 lua_createtable(L, 0, 2); /* create metatable */
304 lua_pushstring(L, tname);
305 lua_setfield(L, -2, "__name"); /* metatable.__name = tname */
306 lua_pushvalue(L, -1);
307 lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
308 return 1;
309}
310
311
312LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
313 luaL_getmetatable(L, tname);
314 lua_setmetatable(L, -2);
315}
316
317
318LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
319 void *p = lua_touserdata(L, ud);
320 if (p != NULL) { /* value is a userdata? */
321 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
322 luaL_getmetatable(L, tname); /* get correct metatable */
323 if (!lua_rawequal(L, -1, -2)) /* not the same? */
324 p = NULL; /* value is a userdata with wrong metatable */
325 lua_pop(L, 2); /* remove both metatables */
326 return p;
327 }
328 }
329 return NULL; /* value is not a userdata with a metatable */
330}
331
332
333LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
334 void *p = luaL_testudata(L, ud, tname);
335 if (p == NULL) typeerror(L, ud, tname);
336 return p;
337}
338
339/* }====================================================== */
340
341
342/*
343** {======================================================
344** Argument check functions
345** =======================================================
346*/
347
348LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
349 const char *const lst[]) {
350 const char *name = (def) ? luaL_optstring(L, arg, def) :
351 luaL_checkstring(L, arg);
352 int i;
353 for (i=0; lst[i]; i++)
354 if (strcmp(lst[i], name) == 0)
355 return i;
356 return luaL_argerror(L, arg,
357 lua_pushfstring(L, "invalid option '%s'", name));
358}
359
360
361/*
362** Ensures the stack has at least 'space' extra slots, raising an error
363** if it cannot fulfill the request. (The error handling needs a few
364** extra slots to format the error message. In case of an error without
365** this extra space, Lua will generate the same 'stack overflow' error,
366** but without 'msg'.)
367*/
368LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
369 if (!lua_checkstack(L, space)) {
370 if (msg)
371 luaL_error(L, "stack overflow (%s)", msg);
372 else
373 luaL_error(L, "stack overflow");
374 }
375}
376
377
378LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) {
379 if (lua_type(L, arg) != t)
380 tag_error(L, arg, t);
381}
382
383
384LUALIB_API void luaL_checkany (lua_State *L, int arg) {
385 if (lua_type(L, arg) == LUA_TNONE)
386 luaL_argerror(L, arg, "value expected");
387}
388
389
390LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) {
391 const char *s = lua_tolstring(L, arg, len);
392 if (!s) tag_error(L, arg, LUA_TSTRING);
393 return s;
394}
395
396
397LUALIB_API const char *luaL_optlstring (lua_State *L, int arg,
398 const char *def, size_t *len) {
399 if (lua_isnoneornil(L, arg)) {
400 if (len)
401 *len = (def ? strlen(def) : 0);
402 return def;
403 }
404 else return luaL_checklstring(L, arg, len);
405}
406
407
408LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) {
409 int isnum;
410 lua_Number d = lua_tonumberx(L, arg, &isnum);
411 if (!isnum)
412 tag_error(L, arg, LUA_TNUMBER);
413 return d;
414}
415
416
417LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) {
418 return luaL_opt(L, luaL_checknumber, arg, def);
419}
420
421
422static void interror (lua_State *L, int arg) {
423 if (lua_isnumber(L, arg))
424 luaL_argerror(L, arg, "number has no integer representation");
425 else
426 tag_error(L, arg, LUA_TNUMBER);
427}
428
429
430LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) {
431 int isnum;
432 lua_Integer d = lua_tointegerx(L, arg, &isnum);
433 if (!isnum) {
434 interror(L, arg);
435 }
436 return d;
437}
438
439
440LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg,
441 lua_Integer def) {
442 return luaL_opt(L, luaL_checkinteger, arg, def);
443}
444
445/* }====================================================== */
446
447
448/*
449** {======================================================
450** Generic Buffer manipulation
451** =======================================================
452*/
453
454/* userdata to box arbitrary data */
455typedef struct UBox {
456 void *box;
457 size_t bsize;
458} UBox;
459
460
461static void *resizebox (lua_State *L, int idx, size_t newsize) {
462 void *ud;
463 lua_Alloc allocf = lua_getallocf(L, &ud);
464 UBox *box = (UBox *)lua_touserdata(L, idx);
465 void *temp = allocf(ud, box->box, box->bsize, newsize);
466 if (temp == NULL && newsize > 0) { /* allocation error? */
467 resizebox(L, idx, 0); /* free buffer */
468 luaL_error(L, "not enough memory for buffer allocation");
469 }
470 box->box = temp;
471 box->bsize = newsize;
472 return temp;
473}
474
475
476static int boxgc (lua_State *L) {
477 resizebox(L, 1, 0);
478 return 0;
479}
480
481
482static void *newbox (lua_State *L, size_t newsize) {
483 UBox *box = (UBox *)lua_newuserdata(L, sizeof(UBox));
484 box->box = NULL;
485 box->bsize = 0;
486 if (luaL_newmetatable(L, "LUABOX")) { /* creating metatable? */
487 lua_pushcfunction(L, boxgc);
488 lua_setfield(L, -2, "__gc"); /* metatable.__gc = boxgc */
489 }
490 lua_setmetatable(L, -2);
491 return resizebox(L, -1, newsize);
492}
493
494
495/*
496** check whether buffer is using a userdata on the stack as a temporary
497** buffer
498*/
499#define buffonstack(B) ((B)->b != (B)->initb)
500
501
502/*
503** returns a pointer to a free area with at least 'sz' bytes
504*/
505LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
506 lua_State *L = B->L;
507 if (B->size - B->n < sz) { /* not enough space? */
508 char *newbuff;
509 size_t newsize = B->size * 2; /* double buffer size */
510 if (newsize - B->n < sz) /* not big enough? */
511 newsize = B->n + sz;
512 if (newsize < B->n || newsize - B->n < sz)
513 luaL_error(L, "buffer too large");
514 /* create larger buffer */
515 if (buffonstack(B))
516 newbuff = (char *)resizebox(L, -1, newsize);
517 else { /* no buffer yet */
518 newbuff = (char *)newbox(L, newsize);
519 memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */
520 }
521 B->b = newbuff;
522 B->size = newsize;
523 }
524 return &B->b[B->n];
525}
526
527
528LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
529 if (l > 0) { /* avoid 'memcpy' when 's' can be NULL */
530 char *b = luaL_prepbuffsize(B, l);
531 memcpy(b, s, l * sizeof(char));
532 luaL_addsize(B, l);
533 }
534}
535
536
537LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
538 luaL_addlstring(B, s, strlen(s));
539}
540
541
542LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
543 lua_State *L = B->L;
544 lua_pushlstring(L, B->b, B->n);
545 if (buffonstack(B)) {
546 resizebox(L, -2, 0); /* delete old buffer */
547 lua_remove(L, -2); /* remove its header from the stack */
548 }
549}
550
551
552LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
553 luaL_addsize(B, sz);
554 luaL_pushresult(B);
555}
556
557
558LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
559 lua_State *L = B->L;
560 size_t l;
561 const char *s = lua_tolstring(L, -1, &l);
562 if (buffonstack(B))
563 lua_insert(L, -2); /* put value below buffer */
564 luaL_addlstring(B, s, l);
565 lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */
566}
567
568
569LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
570 B->L = L;
571 B->b = B->initb;
572 B->n = 0;
573 B->size = LUAL_BUFFERSIZE;
574}
575
576
577LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
578 luaL_buffinit(L, B);
579 return luaL_prepbuffsize(B, sz);
580}
581
582/* }====================================================== */
583
584
585/*
586** {======================================================
587** Reference system
588** =======================================================
589*/
590
591/* index of free-list header */
592#define freelist 0
593
594
595LUALIB_API int luaL_ref (lua_State *L, int t) {
596 int ref;
597 if (lua_isnil(L, -1)) {
598 lua_pop(L, 1); /* remove from stack */
599 return LUA_REFNIL; /* 'nil' has a unique fixed reference */
600 }
601 t = lua_absindex(L, t);
602 lua_rawgeti(L, t, freelist); /* get first free element */
603 ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */
604 lua_pop(L, 1); /* remove it from stack */
605 if (ref != 0) { /* any free element? */
606 lua_rawgeti(L, t, ref); /* remove it from list */
607 lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */
608 }
609 else /* no free elements */
610 ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */
611 lua_rawseti(L, t, ref);
612 return ref;
613}
614
615
616LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
617 if (ref >= 0) {
618 t = lua_absindex(L, t);
619 lua_rawgeti(L, t, freelist);
620 lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */
621 lua_pushinteger(L, ref);
622 lua_rawseti(L, t, freelist); /* t[freelist] = ref */
623 }
624}
625
626/* }====================================================== */
627
628
629/*
630** {======================================================
631** Load functions
632** =======================================================
633*/
634
635typedef struct LoadF {
636 int n; /* number of pre-read characters */
637 FILE *f; /* file being read */
638 char buff[BUFSIZ]; /* area for reading file */
639} LoadF;
640
641
642static const char *getF (lua_State *L, void *ud, size_t *size) {
643 LoadF *lf = (LoadF *)ud;
644 (void)L; /* not used */
645 if (lf->n > 0) { /* are there pre-read characters to be read? */
646 *size = lf->n; /* return them (chars already in buffer) */
647 lf->n = 0; /* no more pre-read characters */
648 }
649 else { /* read a block from file */
650 /* 'fread' can return > 0 *and* set the EOF flag. If next call to
651 'getF' called 'fread', it might still wait for user input.
652 The next check avoids this problem. */
653 if (feof(lf->f)) return NULL;
654 *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */
655 }
656 return lf->buff;
657}
658
659
660static int errfile (lua_State *L, const char *what, int fnameindex) {
661 const char *serr = strerror(errno);
662 const char *filename = lua_tostring(L, fnameindex) + 1;
663 lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
664 lua_remove(L, fnameindex);
665 return LUA_ERRFILE;
666}
667
668
669static int skipBOM (LoadF *lf) {
670 const char *p = "\xEF\xBB\xBF"; /* UTF-8 BOM mark */
671 int c;
672 lf->n = 0;
673 do {
674 c = getc(lf->f);
675 if (c == EOF || c != *(const unsigned char *)p++) return c;
676 lf->buff[lf->n++] = c; /* to be read by the parser */
677 } while (*p != '\0');
678 lf->n = 0; /* prefix matched; discard it */
679 return getc(lf->f); /* return next character */
680}
681
682
683/*
684** reads the first character of file 'f' and skips an optional BOM mark
685** in its beginning plus its first line if it starts with '#'. Returns
686** true if it skipped the first line. In any case, '*cp' has the
687** first "valid" character of the file (after the optional BOM and
688** a first-line comment).
689*/
690static int skipcomment (LoadF *lf, int *cp) {
691 int c = *cp = skipBOM(lf);
692 if (c == '#') { /* first line is a comment (Unix exec. file)? */
693 do { /* skip first line */
694 c = getc(lf->f);
695 } while (c != EOF && c != '\n');
696 *cp = getc(lf->f); /* skip end-of-line, if present */
697 return 1; /* there was a comment */
698 }
699 else return 0; /* no comment */
700}
701
702
703LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
704 const char *mode) {
705 LoadF lf;
706 int status, readstatus;
707 int c;
708 int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
709 if (filename == NULL) {
710 lua_pushliteral(L, "=stdin");
711 lf.f = stdin;
712 }
713 else {
714 lua_pushfstring(L, "@%s", filename);
715 lf.f = fopen(filename, "r");
716 if (lf.f == NULL) return errfile(L, "open", fnameindex);
717 }
718 if (skipcomment(&lf, &c)) /* read initial portion */
719 lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
720 if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
721 lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
722 if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
723 skipcomment(&lf, &c); /* re-read initial portion */
724 }
725 if (c != EOF)
726 lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
727 status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
728 readstatus = ferror(lf.f);
729 if (filename) fclose(lf.f); /* close file (even in case of errors) */
730 if (readstatus) {
731 lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
732 return errfile(L, "read", fnameindex);
733 }
734 lua_remove(L, fnameindex);
735 return status;
736}
737
738
739typedef struct LoadS {
740 const char *s;
741 size_t size;
742} LoadS;
743
744
745static const char *getS (lua_State *L, void *ud, size_t *size) {
746 LoadS *ls = (LoadS *)ud;
747 (void)L; /* not used */
748 if (ls->size == 0) return NULL;
749 *size = ls->size;
750 ls->size = 0;
751 return ls->s;
752}
753
754
755LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
756 const char *name, const char *mode) {
757 LoadS ls;
758 ls.s = buff;
759 ls.size = size;
760 return lua_load(L, getS, &ls, name, mode);
761}
762
763
764LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
765 return luaL_loadbuffer(L, s, strlen(s), s);
766}
767
768/* }====================================================== */
769
770
771
772LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
773 if (!lua_getmetatable(L, obj)) /* no metatable? */
774 return LUA_TNIL;
775 else {
776 int tt;
777 lua_pushstring(L, event);
778 tt = lua_rawget(L, -2);
779 if (tt == LUA_TNIL) /* is metafield nil? */
780 lua_pop(L, 2); /* remove metatable and metafield */
781 else
782 lua_remove(L, -2); /* remove only metatable */
783 return tt; /* return metafield type */
784 }
785}
786
787
788LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
789 obj = lua_absindex(L, obj);
790 if (luaL_getmetafield(L, obj, event) == LUA_TNIL) /* no metafield? */
791 return 0;
792 lua_pushvalue(L, obj);
793 lua_call(L, 1, 1);
794 return 1;
795}
796
797
798LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
799 lua_Integer l;
800 int isnum;
801 lua_len(L, idx);
802 l = lua_tointegerx(L, -1, &isnum);
803 if (!isnum)
804 luaL_error(L, "object length is not an integer");
805 lua_pop(L, 1); /* remove object */
806 return l;
807}
808
809
810LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
811 if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */
812 if (!lua_isstring(L, -1))
813 luaL_error(L, "'__tostring' must return a string");
814 }
815 else {
816 switch (lua_type(L, idx)) {
817 case LUA_TNUMBER: {
818 if (lua_isinteger(L, idx))
819 lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx));
820 else
821 lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx));
822 break;
823 }
824 case LUA_TSTRING:
825 lua_pushvalue(L, idx);
826 break;
827 case LUA_TBOOLEAN:
828 lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false"));
829 break;
830 case LUA_TNIL:
831 lua_pushliteral(L, "nil");
832 break;
833 default: {
834 int tt = luaL_getmetafield(L, idx, "__name"); /* try name */
835 const char *kind = (tt == LUA_TSTRING) ? lua_tostring(L, -1) :
836 luaL_typename(L, idx);
837 lua_pushfstring(L, "%s: %p", kind, lua_topointer(L, idx));
838 if (tt != LUA_TNIL)
839 lua_remove(L, -2); /* remove '__name' */
840 break;
841 }
842 }
843 }
844 return lua_tolstring(L, -1, len);
845}
846
847
848/*
849** {======================================================
850** Compatibility with 5.1 module functions
851** =======================================================
852*/
853#if defined(LUA_COMPAT_MODULE)
854
855static const char *luaL_findtable (lua_State *L, int idx,
856 const char *fname, int szhint) {
857 const char *e;
858 if (idx) lua_pushvalue(L, idx);
859 do {
860 e = strchr(fname, '.');
861 if (e == NULL) e = fname + strlen(fname);
862 lua_pushlstring(L, fname, e - fname);
863 if (lua_rawget(L, -2) == LUA_TNIL) { /* no such field? */
864 lua_pop(L, 1); /* remove this nil */
865 lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
866 lua_pushlstring(L, fname, e - fname);
867 lua_pushvalue(L, -2);
868 lua_settable(L, -4); /* set new table into field */
869 }
870 else if (!lua_istable(L, -1)) { /* field has a non-table value? */
871 lua_pop(L, 2); /* remove table and value */
872 return fname; /* return problematic part of the name */
873 }
874 lua_remove(L, -2); /* remove previous table */
875 fname = e + 1;
876 } while (*e == '.');
877 return NULL;
878}
879
880
881/*
882** Count number of elements in a luaL_Reg list.
883*/
884static int libsize (const luaL_Reg *l) {
885 int size = 0;
886 for (; l && l->name; l++) size++;
887 return size;
888}
889
890
891/*
892** Find or create a module table with a given name. The function
893** first looks at the LOADED table and, if that fails, try a
894** global variable with that name. In any case, leaves on the stack
895** the module table.
896*/
897LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
898 int sizehint) {
899 luaL_findtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE, 1);
900 if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no LOADED[modname]? */
901 lua_pop(L, 1); /* remove previous result */
902 /* try global variable (and create one if it does not exist) */
903 lua_pushglobaltable(L);
904 if (luaL_findtable(L, 0, modname, sizehint) != NULL)
905 luaL_error(L, "name conflict for module '%s'", modname);
906 lua_pushvalue(L, -1);
907 lua_setfield(L, -3, modname); /* LOADED[modname] = new table */
908 }
909 lua_remove(L, -2); /* remove LOADED table */
910}
911
912
913LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
914 const luaL_Reg *l, int nup) {
915 luaL_checkversion(L);
916 if (libname) {
917 luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */
918 lua_insert(L, -(nup + 1)); /* move library table to below upvalues */
919 }
920 if (l)
921 luaL_setfuncs(L, l, nup);
922 else
923 lua_pop(L, nup); /* remove upvalues */
924}
925
926#endif
927/* }====================================================== */
928
929/*
930** set functions from list 'l' into table at top - 'nup'; each
931** function gets the 'nup' elements at the top as upvalues.
932** Returns with only the table at the stack.
933*/
934LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
935 luaL_checkstack(L, nup, "too many upvalues");
936 for (; l->name != NULL; l++) { /* fill the table with given functions */
937 int i;
938 for (i = 0; i < nup; i++) /* copy upvalues to the top */
939 lua_pushvalue(L, -nup);
940 lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
941 lua_setfield(L, -(nup + 2), l->name);
942 }
943 lua_pop(L, nup); /* remove upvalues */
944}
945
946
947/*
948** ensure that stack[idx][fname] has a table and push that table
949** into the stack
950*/
951LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
952 if (lua_getfield(L, idx, fname) == LUA_TTABLE)
953 return 1; /* table already there */
954 else {
955 lua_pop(L, 1); /* remove previous result */
956 idx = lua_absindex(L, idx);
957 lua_newtable(L);
958 lua_pushvalue(L, -1); /* copy to be left at top */
959 lua_setfield(L, idx, fname); /* assign new table to field */
960 return 0; /* false, because did not find table there */
961 }
962}
963
964
965/*
966** Stripped-down 'require': After checking "loaded" table, calls 'openf'
967** to open a module, registers the result in 'package.loaded' table and,
968** if 'glb' is true, also registers the result in the global table.
969** Leaves resulting module on the top.
970*/
971LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
972 lua_CFunction openf, int glb) {
973 luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
974 lua_getfield(L, -1, modname); /* LOADED[modname] */
975 if (!lua_toboolean(L, -1)) { /* package not already loaded? */
976 lua_pop(L, 1); /* remove field */
977 lua_pushcfunction(L, openf);
978 lua_pushstring(L, modname); /* argument to open function */
979 lua_call(L, 1, 1); /* call 'openf' to open module */
980 lua_pushvalue(L, -1); /* make copy of module (call result) */
981 lua_setfield(L, -3, modname); /* LOADED[modname] = module */
982 }
983 lua_remove(L, -2); /* remove LOADED table */
984 if (glb) {
985 lua_pushvalue(L, -1); /* copy of module */
986 lua_setglobal(L, modname); /* _G[modname] = module */
987 }
988}
989
990
991LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
992 const char *r) {
993 const char *wild;
994 size_t l = strlen(p);
995 luaL_Buffer b;
996 luaL_buffinit(L, &b);
997 while ((wild = strstr(s, p)) != NULL) {
998 luaL_addlstring(&b, s, wild - s); /* push prefix */
999 luaL_addstring(&b, r); /* push replacement in place of pattern */
1000 s = wild + l; /* continue after 'p' */
1001 }
1002 luaL_addstring(&b, s); /* push last suffix */
1003 luaL_pushresult(&b);
1004 return lua_tostring(L, -1);
1005}
1006
1007
1008static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
1009 (void)ud; (void)osize; /* not used */
1010 if (nsize == 0) {
1011 free(ptr);
1012 return NULL;
1013 }
1014 else
1015 return realloc(ptr, nsize);
1016}
1017
1018
1019static int panic (lua_State *L) {
1020 lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
1021 lua_tostring(L, -1));
1022 return 0; /* return to Lua to abort */
1023}
1024
1025
1026LUALIB_API lua_State *luaL_newstate (void) {
1027 lua_State *L = lua_newstate(l_alloc, NULL);
1028 if (L) lua_atpanic(L, &panic);
1029 return L;
1030}
1031
1032
1033LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
1034 const lua_Number *v = lua_version(L);
1035 if (sz != LUAL_NUMSIZES) /* check numeric types */
1036 luaL_error(L, "core and library have incompatible numeric types");
1037 if (v != lua_version(NULL))
1038 luaL_error(L, "multiple Lua VMs detected");
1039 else if (*v != ver)
1040 luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
1041 (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)*v);
1042}
1043
diff --git a/src/lua-5.3/lauxlib.h b/src/lua-5.3/lauxlib.h
new file mode 100644
index 0000000..9857d3a
--- /dev/null
+++ b/src/lua-5.3/lauxlib.h
@@ -0,0 +1,264 @@
1/*
2** $Id: lauxlib.h,v 1.131.1.1 2017/04/19 17:20:42 roberto Exp $
3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lauxlib_h
9#define lauxlib_h
10
11
12#include <stddef.h>
13#include <stdio.h>
14
15#include "lua.h"
16
17
18
19/* extra error code for 'luaL_loadfilex' */
20#define LUA_ERRFILE (LUA_ERRERR+1)
21
22
23/* key, in the registry, for table of loaded modules */
24#define LUA_LOADED_TABLE "_LOADED"
25
26
27/* key, in the registry, for table of preloaded loaders */
28#define LUA_PRELOAD_TABLE "_PRELOAD"
29
30
31typedef struct luaL_Reg {
32 const char *name;
33 lua_CFunction func;
34} luaL_Reg;
35
36
37#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number))
38
39LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz);
40#define luaL_checkversion(L) \
41 luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES)
42
43LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
44LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
45LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
46LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
47LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
48 size_t *l);
49LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg,
50 const char *def, size_t *l);
51LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg);
52LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def);
53
54LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg);
55LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg,
56 lua_Integer def);
57
58LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
59LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t);
60LUALIB_API void (luaL_checkany) (lua_State *L, int arg);
61
62LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
63LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
64LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
65LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
66
67LUALIB_API void (luaL_where) (lua_State *L, int lvl);
68LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
69
70LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def,
71 const char *const lst[]);
72
73LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
74LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
75
76/* predefined references */
77#define LUA_NOREF (-2)
78#define LUA_REFNIL (-1)
79
80LUALIB_API int (luaL_ref) (lua_State *L, int t);
81LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
82
83LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
84 const char *mode);
85
86#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL)
87
88LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
89 const char *name, const char *mode);
90LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
91
92LUALIB_API lua_State *(luaL_newstate) (void);
93
94LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
95
96LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
97 const char *r);
98
99LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
100
101LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
102
103LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
104 const char *msg, int level);
105
106LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
107 lua_CFunction openf, int glb);
108
109/*
110** ===============================================================
111** some useful macros
112** ===============================================================
113*/
114
115
116#define luaL_newlibtable(L,l) \
117 lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
118
119#define luaL_newlib(L,l) \
120 (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
121
122#define luaL_argcheck(L, cond,arg,extramsg) \
123 ((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
124#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
125#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
126
127#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
128
129#define luaL_dofile(L, fn) \
130 (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
131
132#define luaL_dostring(L, s) \
133 (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
134
135#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
136
137#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
138
139#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
140
141
142/*
143** {======================================================
144** Generic Buffer manipulation
145** =======================================================
146*/
147
148typedef struct luaL_Buffer {
149 char *b; /* buffer address */
150 size_t size; /* buffer size */
151 size_t n; /* number of characters in buffer */
152 lua_State *L;
153 char initb[LUAL_BUFFERSIZE]; /* initial buffer */
154} luaL_Buffer;
155
156
157#define luaL_addchar(B,c) \
158 ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
159 ((B)->b[(B)->n++] = (c)))
160
161#define luaL_addsize(B,s) ((B)->n += (s))
162
163LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
164LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
165LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
166LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
167LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
168LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
169LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
170LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
171
172#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
173
174/* }====================================================== */
175
176
177
178/*
179** {======================================================
180** File handles for IO library
181** =======================================================
182*/
183
184/*
185** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
186** initial structure 'luaL_Stream' (it may contain other fields
187** after that initial structure).
188*/
189
190#define LUA_FILEHANDLE "FILE*"
191
192
193typedef struct luaL_Stream {
194 FILE *f; /* stream (NULL for incompletely created streams) */
195 lua_CFunction closef; /* to close stream (NULL for closed streams) */
196} luaL_Stream;
197
198/* }====================================================== */
199
200
201
202/* compatibility with old module system */
203#if defined(LUA_COMPAT_MODULE)
204
205LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
206 int sizehint);
207LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
208 const luaL_Reg *l, int nup);
209
210#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0))
211
212#endif
213
214
215/*
216** {==================================================================
217** "Abstraction Layer" for basic report of messages and errors
218** ===================================================================
219*/
220
221/* print a string */
222#if !defined(lua_writestring)
223#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
224#endif
225
226/* print a newline and flush the output */
227#if !defined(lua_writeline)
228#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout))
229#endif
230
231/* print an error message */
232#if !defined(lua_writestringerror)
233#define lua_writestringerror(s,p) \
234 (fprintf(stderr, (s), (p)), fflush(stderr))
235#endif
236
237/* }================================================================== */
238
239
240/*
241** {============================================================
242** Compatibility with deprecated conversions
243** =============================================================
244*/
245#if defined(LUA_COMPAT_APIINTCASTS)
246
247#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a))
248#define luaL_optunsigned(L,a,d) \
249 ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d)))
250
251#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
252#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
253
254#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
255#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
256
257#endif
258/* }============================================================ */
259
260
261
262#endif
263
264
diff --git a/src/lua-5.3/lbaselib.c b/src/lua-5.3/lbaselib.c
new file mode 100644
index 0000000..6460e4f
--- /dev/null
+++ b/src/lua-5.3/lbaselib.c
@@ -0,0 +1,498 @@
1/*
2** $Id: lbaselib.c,v 1.314.1.1 2017/04/19 17:39:34 roberto Exp $
3** Basic library
4** See Copyright Notice in lua.h
5*/
6
7#define lbaselib_c
8#define LUA_LIB
9
10#include "lprefix.h"
11
12
13#include <ctype.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17
18#include "lua.h"
19
20#include "lauxlib.h"
21#include "lualib.h"
22
23
24static int luaB_print (lua_State *L) {
25 int n = lua_gettop(L); /* number of arguments */
26 int i;
27 lua_getglobal(L, "tostring");
28 for (i=1; i<=n; i++) {
29 const char *s;
30 size_t l;
31 lua_pushvalue(L, -1); /* function to be called */
32 lua_pushvalue(L, i); /* value to print */
33 lua_call(L, 1, 1);
34 s = lua_tolstring(L, -1, &l); /* get result */
35 if (s == NULL)
36 return luaL_error(L, "'tostring' must return a string to 'print'");
37 if (i>1) lua_writestring("\t", 1);
38 lua_writestring(s, l);
39 lua_pop(L, 1); /* pop result */
40 }
41 lua_writeline();
42 return 0;
43}
44
45
46#define SPACECHARS " \f\n\r\t\v"
47
48static const char *b_str2int (const char *s, int base, lua_Integer *pn) {
49 lua_Unsigned n = 0;
50 int neg = 0;
51 s += strspn(s, SPACECHARS); /* skip initial spaces */
52 if (*s == '-') { s++; neg = 1; } /* handle signal */
53 else if (*s == '+') s++;
54 if (!isalnum((unsigned char)*s)) /* no digit? */
55 return NULL;
56 do {
57 int digit = (isdigit((unsigned char)*s)) ? *s - '0'
58 : (toupper((unsigned char)*s) - 'A') + 10;
59 if (digit >= base) return NULL; /* invalid numeral */
60 n = n * base + digit;
61 s++;
62 } while (isalnum((unsigned char)*s));
63 s += strspn(s, SPACECHARS); /* skip trailing spaces */
64 *pn = (lua_Integer)((neg) ? (0u - n) : n);
65 return s;
66}
67
68
69static int luaB_tonumber (lua_State *L) {
70 if (lua_isnoneornil(L, 2)) { /* standard conversion? */
71 luaL_checkany(L, 1);
72 if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */
73 lua_settop(L, 1); /* yes; return it */
74 return 1;
75 }
76 else {
77 size_t l;
78 const char *s = lua_tolstring(L, 1, &l);
79 if (s != NULL && lua_stringtonumber(L, s) == l + 1)
80 return 1; /* successful conversion to number */
81 /* else not a number */
82 }
83 }
84 else {
85 size_t l;
86 const char *s;
87 lua_Integer n = 0; /* to avoid warnings */
88 lua_Integer base = luaL_checkinteger(L, 2);
89 luaL_checktype(L, 1, LUA_TSTRING); /* no numbers as strings */
90 s = lua_tolstring(L, 1, &l);
91 luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
92 if (b_str2int(s, (int)base, &n) == s + l) {
93 lua_pushinteger(L, n);
94 return 1;
95 } /* else not a number */
96 } /* else not a number */
97 lua_pushnil(L); /* not a number */
98 return 1;
99}
100
101
102static int luaB_error (lua_State *L) {
103 int level = (int)luaL_optinteger(L, 2, 1);
104 lua_settop(L, 1);
105 if (lua_type(L, 1) == LUA_TSTRING && level > 0) {
106 luaL_where(L, level); /* add extra information */
107 lua_pushvalue(L, 1);
108 lua_concat(L, 2);
109 }
110 return lua_error(L);
111}
112
113
114static int luaB_getmetatable (lua_State *L) {
115 luaL_checkany(L, 1);
116 if (!lua_getmetatable(L, 1)) {
117 lua_pushnil(L);
118 return 1; /* no metatable */
119 }
120 luaL_getmetafield(L, 1, "__metatable");
121 return 1; /* returns either __metatable field (if present) or metatable */
122}
123
124
125static int luaB_setmetatable (lua_State *L) {
126 int t = lua_type(L, 2);
127 luaL_checktype(L, 1, LUA_TTABLE);
128 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
129 "nil or table expected");
130 if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)
131 return luaL_error(L, "cannot change a protected metatable");
132 lua_settop(L, 2);
133 lua_setmetatable(L, 1);
134 return 1;
135}
136
137
138static int luaB_rawequal (lua_State *L) {
139 luaL_checkany(L, 1);
140 luaL_checkany(L, 2);
141 lua_pushboolean(L, lua_rawequal(L, 1, 2));
142 return 1;
143}
144
145
146static int luaB_rawlen (lua_State *L) {
147 int t = lua_type(L, 1);
148 luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
149 "table or string expected");
150 lua_pushinteger(L, lua_rawlen(L, 1));
151 return 1;
152}
153
154
155static int luaB_rawget (lua_State *L) {
156 luaL_checktype(L, 1, LUA_TTABLE);
157 luaL_checkany(L, 2);
158 lua_settop(L, 2);
159 lua_rawget(L, 1);
160 return 1;
161}
162
163static int luaB_rawset (lua_State *L) {
164 luaL_checktype(L, 1, LUA_TTABLE);
165 luaL_checkany(L, 2);
166 luaL_checkany(L, 3);
167 lua_settop(L, 3);
168 lua_rawset(L, 1);
169 return 1;
170}
171
172
173static int luaB_collectgarbage (lua_State *L) {
174 static const char *const opts[] = {"stop", "restart", "collect",
175 "count", "step", "setpause", "setstepmul",
176 "isrunning", NULL};
177 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
178 LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
179 LUA_GCISRUNNING};
180 int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
181 int ex = (int)luaL_optinteger(L, 2, 0);
182 int res = lua_gc(L, o, ex);
183 switch (o) {
184 case LUA_GCCOUNT: {
185 int b = lua_gc(L, LUA_GCCOUNTB, 0);
186 lua_pushnumber(L, (lua_Number)res + ((lua_Number)b/1024));
187 return 1;
188 }
189 case LUA_GCSTEP: case LUA_GCISRUNNING: {
190 lua_pushboolean(L, res);
191 return 1;
192 }
193 default: {
194 lua_pushinteger(L, res);
195 return 1;
196 }
197 }
198}
199
200
201static int luaB_type (lua_State *L) {
202 int t = lua_type(L, 1);
203 luaL_argcheck(L, t != LUA_TNONE, 1, "value expected");
204 lua_pushstring(L, lua_typename(L, t));
205 return 1;
206}
207
208
209static int pairsmeta (lua_State *L, const char *method, int iszero,
210 lua_CFunction iter) {
211 luaL_checkany(L, 1);
212 if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */
213 lua_pushcfunction(L, iter); /* will return generator, */
214 lua_pushvalue(L, 1); /* state, */
215 if (iszero) lua_pushinteger(L, 0); /* and initial value */
216 else lua_pushnil(L);
217 }
218 else {
219 lua_pushvalue(L, 1); /* argument 'self' to metamethod */
220 lua_call(L, 1, 3); /* get 3 values from metamethod */
221 }
222 return 3;
223}
224
225
226static int luaB_next (lua_State *L) {
227 luaL_checktype(L, 1, LUA_TTABLE);
228 lua_settop(L, 2); /* create a 2nd argument if there isn't one */
229 if (lua_next(L, 1))
230 return 2;
231 else {
232 lua_pushnil(L);
233 return 1;
234 }
235}
236
237
238static int luaB_pairs (lua_State *L) {
239 return pairsmeta(L, "__pairs", 0, luaB_next);
240}
241
242
243/*
244** Traversal function for 'ipairs'
245*/
246static int ipairsaux (lua_State *L) {
247 lua_Integer i = luaL_checkinteger(L, 2) + 1;
248 lua_pushinteger(L, i);
249 return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
250}
251
252
253/*
254** 'ipairs' function. Returns 'ipairsaux', given "table", 0.
255** (The given "table" may not be a table.)
256*/
257static int luaB_ipairs (lua_State *L) {
258#if defined(LUA_COMPAT_IPAIRS)
259 return pairsmeta(L, "__ipairs", 1, ipairsaux);
260#else
261 luaL_checkany(L, 1);
262 lua_pushcfunction(L, ipairsaux); /* iteration function */
263 lua_pushvalue(L, 1); /* state */
264 lua_pushinteger(L, 0); /* initial value */
265 return 3;
266#endif
267}
268
269
270static int load_aux (lua_State *L, int status, int envidx) {
271 if (status == LUA_OK) {
272 if (envidx != 0) { /* 'env' parameter? */
273 lua_pushvalue(L, envidx); /* environment for loaded function */
274 if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */
275 lua_pop(L, 1); /* remove 'env' if not used by previous call */
276 }
277 return 1;
278 }
279 else { /* error (message is on top of the stack) */
280 lua_pushnil(L);
281 lua_insert(L, -2); /* put before error message */
282 return 2; /* return nil plus error message */
283 }
284}
285
286
287static int luaB_loadfile (lua_State *L) {
288 const char *fname = luaL_optstring(L, 1, NULL);
289 const char *mode = luaL_optstring(L, 2, NULL);
290 int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */
291 int status = luaL_loadfilex(L, fname, mode);
292 return load_aux(L, status, env);
293}
294
295
296/*
297** {======================================================
298** Generic Read function
299** =======================================================
300*/
301
302
303/*
304** reserved slot, above all arguments, to hold a copy of the returned
305** string to avoid it being collected while parsed. 'load' has four
306** optional arguments (chunk, source name, mode, and environment).
307*/
308#define RESERVEDSLOT 5
309
310
311/*
312** Reader for generic 'load' function: 'lua_load' uses the
313** stack for internal stuff, so the reader cannot change the
314** stack top. Instead, it keeps its resulting string in a
315** reserved slot inside the stack.
316*/
317static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
318 (void)(ud); /* not used */
319 luaL_checkstack(L, 2, "too many nested functions");
320 lua_pushvalue(L, 1); /* get function */
321 lua_call(L, 0, 1); /* call it */
322 if (lua_isnil(L, -1)) {
323 lua_pop(L, 1); /* pop result */
324 *size = 0;
325 return NULL;
326 }
327 else if (!lua_isstring(L, -1))
328 luaL_error(L, "reader function must return a string");
329 lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */
330 return lua_tolstring(L, RESERVEDSLOT, size);
331}
332
333
334static int luaB_load (lua_State *L) {
335 int status;
336 size_t l;
337 const char *s = lua_tolstring(L, 1, &l);
338 const char *mode = luaL_optstring(L, 3, "bt");
339 int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */
340 if (s != NULL) { /* loading a string? */
341 const char *chunkname = luaL_optstring(L, 2, s);
342 status = luaL_loadbufferx(L, s, l, chunkname, mode);
343 }
344 else { /* loading from a reader function */
345 const char *chunkname = luaL_optstring(L, 2, "=(load)");
346 luaL_checktype(L, 1, LUA_TFUNCTION);
347 lua_settop(L, RESERVEDSLOT); /* create reserved slot */
348 status = lua_load(L, generic_reader, NULL, chunkname, mode);
349 }
350 return load_aux(L, status, env);
351}
352
353/* }====================================================== */
354
355
356static int dofilecont (lua_State *L, int d1, lua_KContext d2) {
357 (void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */
358 return lua_gettop(L) - 1;
359}
360
361
362static int luaB_dofile (lua_State *L) {
363 const char *fname = luaL_optstring(L, 1, NULL);
364 lua_settop(L, 1);
365 if (luaL_loadfile(L, fname) != LUA_OK)
366 return lua_error(L);
367 lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
368 return dofilecont(L, 0, 0);
369}
370
371
372static int luaB_assert (lua_State *L) {
373 if (lua_toboolean(L, 1)) /* condition is true? */
374 return lua_gettop(L); /* return all arguments */
375 else { /* error */
376 luaL_checkany(L, 1); /* there must be a condition */
377 lua_remove(L, 1); /* remove it */
378 lua_pushliteral(L, "assertion failed!"); /* default message */
379 lua_settop(L, 1); /* leave only message (default if no other one) */
380 return luaB_error(L); /* call 'error' */
381 }
382}
383
384
385static int luaB_select (lua_State *L) {
386 int n = lua_gettop(L);
387 if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
388 lua_pushinteger(L, n-1);
389 return 1;
390 }
391 else {
392 lua_Integer i = luaL_checkinteger(L, 1);
393 if (i < 0) i = n + i;
394 else if (i > n) i = n;
395 luaL_argcheck(L, 1 <= i, 1, "index out of range");
396 return n - (int)i;
397 }
398}
399
400
401/*
402** Continuation function for 'pcall' and 'xpcall'. Both functions
403** already pushed a 'true' before doing the call, so in case of success
404** 'finishpcall' only has to return everything in the stack minus
405** 'extra' values (where 'extra' is exactly the number of items to be
406** ignored).
407*/
408static int finishpcall (lua_State *L, int status, lua_KContext extra) {
409 if (status != LUA_OK && status != LUA_YIELD) { /* error? */
410 lua_pushboolean(L, 0); /* first result (false) */
411 lua_pushvalue(L, -2); /* error message */
412 return 2; /* return false, msg */
413 }
414 else
415 return lua_gettop(L) - (int)extra; /* return all results */
416}
417
418
419static int luaB_pcall (lua_State *L) {
420 int status;
421 luaL_checkany(L, 1);
422 lua_pushboolean(L, 1); /* first result if no errors */
423 lua_insert(L, 1); /* put it in place */
424 status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall);
425 return finishpcall(L, status, 0);
426}
427
428
429/*
430** Do a protected call with error handling. After 'lua_rotate', the
431** stack will have <f, err, true, f, [args...]>; so, the function passes
432** 2 to 'finishpcall' to skip the 2 first values when returning results.
433*/
434static int luaB_xpcall (lua_State *L) {
435 int status;
436 int n = lua_gettop(L);
437 luaL_checktype(L, 2, LUA_TFUNCTION); /* check error function */
438 lua_pushboolean(L, 1); /* first result */
439 lua_pushvalue(L, 1); /* function */
440 lua_rotate(L, 3, 2); /* move them below function's arguments */
441 status = lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall);
442 return finishpcall(L, status, 2);
443}
444
445
446static int luaB_tostring (lua_State *L) {
447 luaL_checkany(L, 1);
448 luaL_tolstring(L, 1, NULL);
449 return 1;
450}
451
452
453static const luaL_Reg base_funcs[] = {
454 {"assert", luaB_assert},
455 {"collectgarbage", luaB_collectgarbage},
456 {"dofile", luaB_dofile},
457 {"error", luaB_error},
458 {"getmetatable", luaB_getmetatable},
459 {"ipairs", luaB_ipairs},
460 {"loadfile", luaB_loadfile},
461 {"load", luaB_load},
462#if defined(LUA_COMPAT_LOADSTRING)
463 {"loadstring", luaB_load},
464#endif
465 {"next", luaB_next},
466 {"pairs", luaB_pairs},
467 {"pcall", luaB_pcall},
468 {"print", luaB_print},
469 {"rawequal", luaB_rawequal},
470 {"rawlen", luaB_rawlen},
471 {"rawget", luaB_rawget},
472 {"rawset", luaB_rawset},
473 {"select", luaB_select},
474 {"setmetatable", luaB_setmetatable},
475 {"tonumber", luaB_tonumber},
476 {"tostring", luaB_tostring},
477 {"type", luaB_type},
478 {"xpcall", luaB_xpcall},
479 /* placeholders */
480 {"_G", NULL},
481 {"_VERSION", NULL},
482 {NULL, NULL}
483};
484
485
486LUAMOD_API int luaopen_base (lua_State *L) {
487 /* open lib into global table */
488 lua_pushglobaltable(L);
489 luaL_setfuncs(L, base_funcs, 0);
490 /* set global _G */
491 lua_pushvalue(L, -1);
492 lua_setfield(L, -2, "_G");
493 /* set global _VERSION */
494 lua_pushliteral(L, LUA_VERSION);
495 lua_setfield(L, -2, "_VERSION");
496 return 1;
497}
498
diff --git a/src/lua-5.3/lbitlib.c b/src/lua-5.3/lbitlib.c
new file mode 100644
index 0000000..4786c0d
--- /dev/null
+++ b/src/lua-5.3/lbitlib.c
@@ -0,0 +1,233 @@
1/*
2** $Id: lbitlib.c,v 1.30.1.1 2017/04/19 17:20:42 roberto Exp $
3** Standard library for bitwise operations
4** See Copyright Notice in lua.h
5*/
6
7#define lbitlib_c
8#define LUA_LIB
9
10#include "lprefix.h"
11
12
13#include "lua.h"
14
15#include "lauxlib.h"
16#include "lualib.h"
17
18
19#if defined(LUA_COMPAT_BITLIB) /* { */
20
21
22#define pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
23#define checkunsigned(L,i) ((lua_Unsigned)luaL_checkinteger(L,i))
24
25
26/* number of bits to consider in a number */
27#if !defined(LUA_NBITS)
28#define LUA_NBITS 32
29#endif
30
31
32/*
33** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must
34** be made in two parts to avoid problems when LUA_NBITS is equal to the
35** number of bits in a lua_Unsigned.)
36*/
37#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
38
39
40/* macro to trim extra bits */
41#define trim(x) ((x) & ALLONES)
42
43
44/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
45#define mask(n) (~((ALLONES << 1) << ((n) - 1)))
46
47
48
49static lua_Unsigned andaux (lua_State *L) {
50 int i, n = lua_gettop(L);
51 lua_Unsigned r = ~(lua_Unsigned)0;
52 for (i = 1; i <= n; i++)
53 r &= checkunsigned(L, i);
54 return trim(r);
55}
56
57
58static int b_and (lua_State *L) {
59 lua_Unsigned r = andaux(L);
60 pushunsigned(L, r);
61 return 1;
62}
63
64
65static int b_test (lua_State *L) {
66 lua_Unsigned r = andaux(L);
67 lua_pushboolean(L, r != 0);
68 return 1;
69}
70
71
72static int b_or (lua_State *L) {
73 int i, n = lua_gettop(L);
74 lua_Unsigned r = 0;
75 for (i = 1; i <= n; i++)
76 r |= checkunsigned(L, i);
77 pushunsigned(L, trim(r));
78 return 1;
79}
80
81
82static int b_xor (lua_State *L) {
83 int i, n = lua_gettop(L);
84 lua_Unsigned r = 0;
85 for (i = 1; i <= n; i++)
86 r ^= checkunsigned(L, i);
87 pushunsigned(L, trim(r));
88 return 1;
89}
90
91
92static int b_not (lua_State *L) {
93 lua_Unsigned r = ~checkunsigned(L, 1);
94 pushunsigned(L, trim(r));
95 return 1;
96}
97
98
99static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) {
100 if (i < 0) { /* shift right? */
101 i = -i;
102 r = trim(r);
103 if (i >= LUA_NBITS) r = 0;
104 else r >>= i;
105 }
106 else { /* shift left */
107 if (i >= LUA_NBITS) r = 0;
108 else r <<= i;
109 r = trim(r);
110 }
111 pushunsigned(L, r);
112 return 1;
113}
114
115
116static int b_lshift (lua_State *L) {
117 return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2));
118}
119
120
121static int b_rshift (lua_State *L) {
122 return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2));
123}
124
125
126static int b_arshift (lua_State *L) {
127 lua_Unsigned r = checkunsigned(L, 1);
128 lua_Integer i = luaL_checkinteger(L, 2);
129 if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1))))
130 return b_shift(L, r, -i);
131 else { /* arithmetic shift for 'negative' number */
132 if (i >= LUA_NBITS) r = ALLONES;
133 else
134 r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */
135 pushunsigned(L, r);
136 return 1;
137 }
138}
139
140
141static int b_rot (lua_State *L, lua_Integer d) {
142 lua_Unsigned r = checkunsigned(L, 1);
143 int i = d & (LUA_NBITS - 1); /* i = d % NBITS */
144 r = trim(r);
145 if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */
146 r = (r << i) | (r >> (LUA_NBITS - i));
147 pushunsigned(L, trim(r));
148 return 1;
149}
150
151
152static int b_lrot (lua_State *L) {
153 return b_rot(L, luaL_checkinteger(L, 2));
154}
155
156
157static int b_rrot (lua_State *L) {
158 return b_rot(L, -luaL_checkinteger(L, 2));
159}
160
161
162/*
163** get field and width arguments for field-manipulation functions,
164** checking whether they are valid.
165** ('luaL_error' called without 'return' to avoid later warnings about
166** 'width' being used uninitialized.)
167*/
168static int fieldargs (lua_State *L, int farg, int *width) {
169 lua_Integer f = luaL_checkinteger(L, farg);
170 lua_Integer w = luaL_optinteger(L, farg + 1, 1);
171 luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
172 luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
173 if (f + w > LUA_NBITS)
174 luaL_error(L, "trying to access non-existent bits");
175 *width = (int)w;
176 return (int)f;
177}
178
179
180static int b_extract (lua_State *L) {
181 int w;
182 lua_Unsigned r = trim(checkunsigned(L, 1));
183 int f = fieldargs(L, 2, &w);
184 r = (r >> f) & mask(w);
185 pushunsigned(L, r);
186 return 1;
187}
188
189
190static int b_replace (lua_State *L) {
191 int w;
192 lua_Unsigned r = trim(checkunsigned(L, 1));
193 lua_Unsigned v = trim(checkunsigned(L, 2));
194 int f = fieldargs(L, 3, &w);
195 lua_Unsigned m = mask(w);
196 r = (r & ~(m << f)) | ((v & m) << f);
197 pushunsigned(L, r);
198 return 1;
199}
200
201
202static const luaL_Reg bitlib[] = {
203 {"arshift", b_arshift},
204 {"band", b_and},
205 {"bnot", b_not},
206 {"bor", b_or},
207 {"bxor", b_xor},
208 {"btest", b_test},
209 {"extract", b_extract},
210 {"lrotate", b_lrot},
211 {"lshift", b_lshift},
212 {"replace", b_replace},
213 {"rrotate", b_rrot},
214 {"rshift", b_rshift},
215 {NULL, NULL}
216};
217
218
219
220LUAMOD_API int luaopen_bit32 (lua_State *L) {
221 luaL_newlib(L, bitlib);
222 return 1;
223}
224
225
226#else /* }{ */
227
228
229LUAMOD_API int luaopen_bit32 (lua_State *L) {
230 return luaL_error(L, "library 'bit32' has been deprecated");
231}
232
233#endif /* } */
diff --git a/src/lua-5.3/lcode.c b/src/lua-5.3/lcode.c
new file mode 100644
index 0000000..dc7271d
--- /dev/null
+++ b/src/lua-5.3/lcode.c
@@ -0,0 +1,1203 @@
1/*
2** $Id: lcode.c,v 2.112.1.1 2017/04/19 17:20:42 roberto Exp $
3** Code generator for Lua
4** See Copyright Notice in lua.h
5*/
6
7#define lcode_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <math.h>
14#include <stdlib.h>
15
16#include "lua.h"
17
18#include "lcode.h"
19#include "ldebug.h"
20#include "ldo.h"
21#include "lgc.h"
22#include "llex.h"
23#include "lmem.h"
24#include "lobject.h"
25#include "lopcodes.h"
26#include "lparser.h"
27#include "lstring.h"
28#include "ltable.h"
29#include "lvm.h"
30
31
32/* Maximum number of registers in a Lua function (must fit in 8 bits) */
33#define MAXREGS 255
34
35
36#define hasjumps(e) ((e)->t != (e)->f)
37
38
39/*
40** If expression is a numeric constant, fills 'v' with its value
41** and returns 1. Otherwise, returns 0.
42*/
43static int tonumeral(const expdesc *e, TValue *v) {
44 if (hasjumps(e))
45 return 0; /* not a numeral */
46 switch (e->k) {
47 case VKINT:
48 if (v) setivalue(v, e->u.ival);
49 return 1;
50 case VKFLT:
51 if (v) setfltvalue(v, e->u.nval);
52 return 1;
53 default: return 0;
54 }
55}
56
57
58/*
59** Create a OP_LOADNIL instruction, but try to optimize: if the previous
60** instruction is also OP_LOADNIL and ranges are compatible, adjust
61** range of previous instruction instead of emitting a new one. (For
62** instance, 'local a; local b' will generate a single opcode.)
63*/
64void luaK_nil (FuncState *fs, int from, int n) {
65 Instruction *previous;
66 int l = from + n - 1; /* last register to set nil */
67 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
68 previous = &fs->f->code[fs->pc-1];
69 if (GET_OPCODE(*previous) == OP_LOADNIL) { /* previous is LOADNIL? */
70 int pfrom = GETARG_A(*previous); /* get previous range */
71 int pl = pfrom + GETARG_B(*previous);
72 if ((pfrom <= from && from <= pl + 1) ||
73 (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */
74 if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */
75 if (pl > l) l = pl; /* l = max(l, pl) */
76 SETARG_A(*previous, from);
77 SETARG_B(*previous, l - from);
78 return;
79 }
80 } /* else go through */
81 }
82 luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */
83}
84
85
86/*
87** Gets the destination address of a jump instruction. Used to traverse
88** a list of jumps.
89*/
90static int getjump (FuncState *fs, int pc) {
91 int offset = GETARG_sBx(fs->f->code[pc]);
92 if (offset == NO_JUMP) /* point to itself represents end of list */
93 return NO_JUMP; /* end of list */
94 else
95 return (pc+1)+offset; /* turn offset into absolute position */
96}
97
98
99/*
100** Fix jump instruction at position 'pc' to jump to 'dest'.
101** (Jump addresses are relative in Lua)
102*/
103static void fixjump (FuncState *fs, int pc, int dest) {
104 Instruction *jmp = &fs->f->code[pc];
105 int offset = dest - (pc + 1);
106 lua_assert(dest != NO_JUMP);
107 if (abs(offset) > MAXARG_sBx)
108 luaX_syntaxerror(fs->ls, "control structure too long");
109 SETARG_sBx(*jmp, offset);
110}
111
112
113/*
114** Concatenate jump-list 'l2' into jump-list 'l1'
115*/
116void luaK_concat (FuncState *fs, int *l1, int l2) {
117 if (l2 == NO_JUMP) return; /* nothing to concatenate? */
118 else if (*l1 == NO_JUMP) /* no original list? */
119 *l1 = l2; /* 'l1' points to 'l2' */
120 else {
121 int list = *l1;
122 int next;
123 while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
124 list = next;
125 fixjump(fs, list, l2); /* last element links to 'l2' */
126 }
127}
128
129
130/*
131** Create a jump instruction and return its position, so its destination
132** can be fixed later (with 'fixjump'). If there are jumps to
133** this position (kept in 'jpc'), link them all together so that
134** 'patchlistaux' will fix all them directly to the final destination.
135*/
136int luaK_jump (FuncState *fs) {
137 int jpc = fs->jpc; /* save list of jumps to here */
138 int j;
139 fs->jpc = NO_JUMP; /* no more jumps to here */
140 j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
141 luaK_concat(fs, &j, jpc); /* keep them on hold */
142 return j;
143}
144
145
146/*
147** Code a 'return' instruction
148*/
149void luaK_ret (FuncState *fs, int first, int nret) {
150 luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
151}
152
153
154/*
155** Code a "conditional jump", that is, a test or comparison opcode
156** followed by a jump. Return jump position.
157*/
158static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
159 luaK_codeABC(fs, op, A, B, C);
160 return luaK_jump(fs);
161}
162
163
164/*
165** returns current 'pc' and marks it as a jump target (to avoid wrong
166** optimizations with consecutive instructions not in the same basic block).
167*/
168int luaK_getlabel (FuncState *fs) {
169 fs->lasttarget = fs->pc;
170 return fs->pc;
171}
172
173
174/*
175** Returns the position of the instruction "controlling" a given
176** jump (that is, its condition), or the jump itself if it is
177** unconditional.
178*/
179static Instruction *getjumpcontrol (FuncState *fs, int pc) {
180 Instruction *pi = &fs->f->code[pc];
181 if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
182 return pi-1;
183 else
184 return pi;
185}
186
187
188/*
189** Patch destination register for a TESTSET instruction.
190** If instruction in position 'node' is not a TESTSET, return 0 ("fails").
191** Otherwise, if 'reg' is not 'NO_REG', set it as the destination
192** register. Otherwise, change instruction to a simple 'TEST' (produces
193** no register value)
194*/
195static int patchtestreg (FuncState *fs, int node, int reg) {
196 Instruction *i = getjumpcontrol(fs, node);
197 if (GET_OPCODE(*i) != OP_TESTSET)
198 return 0; /* cannot patch other instructions */
199 if (reg != NO_REG && reg != GETARG_B(*i))
200 SETARG_A(*i, reg);
201 else {
202 /* no register to put value or register already has the value;
203 change instruction to simple test */
204 *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
205 }
206 return 1;
207}
208
209
210/*
211** Traverse a list of tests ensuring no one produces a value
212*/
213static void removevalues (FuncState *fs, int list) {
214 for (; list != NO_JUMP; list = getjump(fs, list))
215 patchtestreg(fs, list, NO_REG);
216}
217
218
219/*
220** Traverse a list of tests, patching their destination address and
221** registers: tests producing values jump to 'vtarget' (and put their
222** values in 'reg'), other tests jump to 'dtarget'.
223*/
224static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
225 int dtarget) {
226 while (list != NO_JUMP) {
227 int next = getjump(fs, list);
228 if (patchtestreg(fs, list, reg))
229 fixjump(fs, list, vtarget);
230 else
231 fixjump(fs, list, dtarget); /* jump to default target */
232 list = next;
233 }
234}
235
236
237/*
238** Ensure all pending jumps to current position are fixed (jumping
239** to current position with no values) and reset list of pending
240** jumps
241*/
242static void dischargejpc (FuncState *fs) {
243 patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
244 fs->jpc = NO_JUMP;
245}
246
247
248/*
249** Add elements in 'list' to list of pending jumps to "here"
250** (current position)
251*/
252void luaK_patchtohere (FuncState *fs, int list) {
253 luaK_getlabel(fs); /* mark "here" as a jump target */
254 luaK_concat(fs, &fs->jpc, list);
255}
256
257
258/*
259** Path all jumps in 'list' to jump to 'target'.
260** (The assert means that we cannot fix a jump to a forward address
261** because we only know addresses once code is generated.)
262*/
263void luaK_patchlist (FuncState *fs, int list, int target) {
264 if (target == fs->pc) /* 'target' is current position? */
265 luaK_patchtohere(fs, list); /* add list to pending jumps */
266 else {
267 lua_assert(target < fs->pc);
268 patchlistaux(fs, list, target, NO_REG, target);
269 }
270}
271
272
273/*
274** Path all jumps in 'list' to close upvalues up to given 'level'
275** (The assertion checks that jumps either were closing nothing
276** or were closing higher levels, from inner blocks.)
277*/
278void luaK_patchclose (FuncState *fs, int list, int level) {
279 level++; /* argument is +1 to reserve 0 as non-op */
280 for (; list != NO_JUMP; list = getjump(fs, list)) {
281 lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
282 (GETARG_A(fs->f->code[list]) == 0 ||
283 GETARG_A(fs->f->code[list]) >= level));
284 SETARG_A(fs->f->code[list], level);
285 }
286}
287
288
289/*
290** Emit instruction 'i', checking for array sizes and saving also its
291** line information. Return 'i' position.
292*/
293static int luaK_code (FuncState *fs, Instruction i) {
294 Proto *f = fs->f;
295 dischargejpc(fs); /* 'pc' will change */
296 /* put new instruction in code array */
297 luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
298 MAX_INT, "opcodes");
299 f->code[fs->pc] = i;
300 /* save corresponding line information */
301 luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
302 MAX_INT, "opcodes");
303 f->lineinfo[fs->pc] = fs->ls->lastline;
304 return fs->pc++;
305}
306
307
308/*
309** Format and emit an 'iABC' instruction. (Assertions check consistency
310** of parameters versus opcode.)
311*/
312int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
313 lua_assert(getOpMode(o) == iABC);
314 lua_assert(getBMode(o) != OpArgN || b == 0);
315 lua_assert(getCMode(o) != OpArgN || c == 0);
316 lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
317 return luaK_code(fs, CREATE_ABC(o, a, b, c));
318}
319
320
321/*
322** Format and emit an 'iABx' instruction.
323*/
324int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
325 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
326 lua_assert(getCMode(o) == OpArgN);
327 lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
328 return luaK_code(fs, CREATE_ABx(o, a, bc));
329}
330
331
332/*
333** Emit an "extra argument" instruction (format 'iAx')
334*/
335static int codeextraarg (FuncState *fs, int a) {
336 lua_assert(a <= MAXARG_Ax);
337 return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
338}
339
340
341/*
342** Emit a "load constant" instruction, using either 'OP_LOADK'
343** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX'
344** instruction with "extra argument".
345*/
346int luaK_codek (FuncState *fs, int reg, int k) {
347 if (k <= MAXARG_Bx)
348 return luaK_codeABx(fs, OP_LOADK, reg, k);
349 else {
350 int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
351 codeextraarg(fs, k);
352 return p;
353 }
354}
355
356
357/*
358** Check register-stack level, keeping track of its maximum size
359** in field 'maxstacksize'
360*/
361void luaK_checkstack (FuncState *fs, int n) {
362 int newstack = fs->freereg + n;
363 if (newstack > fs->f->maxstacksize) {
364 if (newstack >= MAXREGS)
365 luaX_syntaxerror(fs->ls,
366 "function or expression needs too many registers");
367 fs->f->maxstacksize = cast_byte(newstack);
368 }
369}
370
371
372/*
373** Reserve 'n' registers in register stack
374*/
375void luaK_reserveregs (FuncState *fs, int n) {
376 luaK_checkstack(fs, n);
377 fs->freereg += n;
378}
379
380
381/*
382** Free register 'reg', if it is neither a constant index nor
383** a local variable.
384)
385*/
386static void freereg (FuncState *fs, int reg) {
387 if (!ISK(reg) && reg >= fs->nactvar) {
388 fs->freereg--;
389 lua_assert(reg == fs->freereg);
390 }
391}
392
393
394/*
395** Free register used by expression 'e' (if any)
396*/
397static void freeexp (FuncState *fs, expdesc *e) {
398 if (e->k == VNONRELOC)
399 freereg(fs, e->u.info);
400}
401
402
403/*
404** Free registers used by expressions 'e1' and 'e2' (if any) in proper
405** order.
406*/
407static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
408 int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1;
409 int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1;
410 if (r1 > r2) {
411 freereg(fs, r1);
412 freereg(fs, r2);
413 }
414 else {
415 freereg(fs, r2);
416 freereg(fs, r1);
417 }
418}
419
420
421/*
422** Add constant 'v' to prototype's list of constants (field 'k').
423** Use scanner's table to cache position of constants in constant list
424** and try to reuse constants. Because some values should not be used
425** as keys (nil cannot be a key, integer keys can collapse with float
426** keys), the caller must provide a useful 'key' for indexing the cache.
427*/
428static int addk (FuncState *fs, TValue *key, TValue *v) {
429 lua_State *L = fs->ls->L;
430 Proto *f = fs->f;
431 TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */
432 int k, oldsize;
433 if (ttisinteger(idx)) { /* is there an index there? */
434 k = cast_int(ivalue(idx));
435 /* correct value? (warning: must distinguish floats from integers!) */
436 if (k < fs->nk && ttype(&f->k[k]) == ttype(v) &&
437 luaV_rawequalobj(&f->k[k], v))
438 return k; /* reuse index */
439 }
440 /* constant not found; create a new entry */
441 oldsize = f->sizek;
442 k = fs->nk;
443 /* numerical value does not need GC barrier;
444 table has no metatable, so it does not need to invalidate cache */
445 setivalue(idx, k);
446 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
447 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
448 setobj(L, &f->k[k], v);
449 fs->nk++;
450 luaC_barrier(L, f, v);
451 return k;
452}
453
454
455/*
456** Add a string to list of constants and return its index.
457*/
458int luaK_stringK (FuncState *fs, TString *s) {
459 TValue o;
460 setsvalue(fs->ls->L, &o, s);
461 return addk(fs, &o, &o); /* use string itself as key */
462}
463
464
465/*
466** Add an integer to list of constants and return its index.
467** Integers use userdata as keys to avoid collision with floats with
468** same value; conversion to 'void*' is used only for hashing, so there
469** are no "precision" problems.
470*/
471int luaK_intK (FuncState *fs, lua_Integer n) {
472 TValue k, o;
473 setpvalue(&k, cast(void*, cast(size_t, n)));
474 setivalue(&o, n);
475 return addk(fs, &k, &o);
476}
477
478/*
479** Add a float to list of constants and return its index.
480*/
481static int luaK_numberK (FuncState *fs, lua_Number r) {
482 TValue o;
483 setfltvalue(&o, r);
484 return addk(fs, &o, &o); /* use number itself as key */
485}
486
487
488/*
489** Add a boolean to list of constants and return its index.
490*/
491static int boolK (FuncState *fs, int b) {
492 TValue o;
493 setbvalue(&o, b);
494 return addk(fs, &o, &o); /* use boolean itself as key */
495}
496
497
498/*
499** Add nil to list of constants and return its index.
500*/
501static int nilK (FuncState *fs) {
502 TValue k, v;
503 setnilvalue(&v);
504 /* cannot use nil as key; instead use table itself to represent nil */
505 sethvalue(fs->ls->L, &k, fs->ls->h);
506 return addk(fs, &k, &v);
507}
508
509
510/*
511** Fix an expression to return the number of results 'nresults'.
512** Either 'e' is a multi-ret expression (function call or vararg)
513** or 'nresults' is LUA_MULTRET (as any expression can satisfy that).
514*/
515void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
516 if (e->k == VCALL) { /* expression is an open function call? */
517 SETARG_C(getinstruction(fs, e), nresults + 1);
518 }
519 else if (e->k == VVARARG) {
520 Instruction *pc = &getinstruction(fs, e);
521 SETARG_B(*pc, nresults + 1);
522 SETARG_A(*pc, fs->freereg);
523 luaK_reserveregs(fs, 1);
524 }
525 else lua_assert(nresults == LUA_MULTRET);
526}
527
528
529/*
530** Fix an expression to return one result.
531** If expression is not a multi-ret expression (function call or
532** vararg), it already returns one result, so nothing needs to be done.
533** Function calls become VNONRELOC expressions (as its result comes
534** fixed in the base register of the call), while vararg expressions
535** become VRELOCABLE (as OP_VARARG puts its results where it wants).
536** (Calls are created returning one result, so that does not need
537** to be fixed.)
538*/
539void luaK_setoneret (FuncState *fs, expdesc *e) {
540 if (e->k == VCALL) { /* expression is an open function call? */
541 /* already returns 1 value */
542 lua_assert(GETARG_C(getinstruction(fs, e)) == 2);
543 e->k = VNONRELOC; /* result has fixed position */
544 e->u.info = GETARG_A(getinstruction(fs, e));
545 }
546 else if (e->k == VVARARG) {
547 SETARG_B(getinstruction(fs, e), 2);
548 e->k = VRELOCABLE; /* can relocate its simple result */
549 }
550}
551
552
553/*
554** Ensure that expression 'e' is not a variable.
555*/
556void luaK_dischargevars (FuncState *fs, expdesc *e) {
557 switch (e->k) {
558 case VLOCAL: { /* already in a register */
559 e->k = VNONRELOC; /* becomes a non-relocatable value */
560 break;
561 }
562 case VUPVAL: { /* move value to some (pending) register */
563 e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
564 e->k = VRELOCABLE;
565 break;
566 }
567 case VINDEXED: {
568 OpCode op;
569 freereg(fs, e->u.ind.idx);
570 if (e->u.ind.vt == VLOCAL) { /* is 't' in a register? */
571 freereg(fs, e->u.ind.t);
572 op = OP_GETTABLE;
573 }
574 else {
575 lua_assert(e->u.ind.vt == VUPVAL);
576 op = OP_GETTABUP; /* 't' is in an upvalue */
577 }
578 e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
579 e->k = VRELOCABLE;
580 break;
581 }
582 case VVARARG: case VCALL: {
583 luaK_setoneret(fs, e);
584 break;
585 }
586 default: break; /* there is one value available (somewhere) */
587 }
588}
589
590
591/*
592** Ensures expression value is in register 'reg' (and therefore
593** 'e' will become a non-relocatable expression).
594*/
595static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
596 luaK_dischargevars(fs, e);
597 switch (e->k) {
598 case VNIL: {
599 luaK_nil(fs, reg, 1);
600 break;
601 }
602 case VFALSE: case VTRUE: {
603 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
604 break;
605 }
606 case VK: {
607 luaK_codek(fs, reg, e->u.info);
608 break;
609 }
610 case VKFLT: {
611 luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
612 break;
613 }
614 case VKINT: {
615 luaK_codek(fs, reg, luaK_intK(fs, e->u.ival));
616 break;
617 }
618 case VRELOCABLE: {
619 Instruction *pc = &getinstruction(fs, e);
620 SETARG_A(*pc, reg); /* instruction will put result in 'reg' */
621 break;
622 }
623 case VNONRELOC: {
624 if (reg != e->u.info)
625 luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
626 break;
627 }
628 default: {
629 lua_assert(e->k == VJMP);
630 return; /* nothing to do... */
631 }
632 }
633 e->u.info = reg;
634 e->k = VNONRELOC;
635}
636
637
638/*
639** Ensures expression value is in any register.
640*/
641static void discharge2anyreg (FuncState *fs, expdesc *e) {
642 if (e->k != VNONRELOC) { /* no fixed register yet? */
643 luaK_reserveregs(fs, 1); /* get a register */
644 discharge2reg(fs, e, fs->freereg-1); /* put value there */
645 }
646}
647
648
649static int code_loadbool (FuncState *fs, int A, int b, int jump) {
650 luaK_getlabel(fs); /* those instructions may be jump targets */
651 return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
652}
653
654
655/*
656** check whether list has any jump that do not produce a value
657** or produce an inverted value
658*/
659static int need_value (FuncState *fs, int list) {
660 for (; list != NO_JUMP; list = getjump(fs, list)) {
661 Instruction i = *getjumpcontrol(fs, list);
662 if (GET_OPCODE(i) != OP_TESTSET) return 1;
663 }
664 return 0; /* not found */
665}
666
667
668/*
669** Ensures final expression result (including results from its jump
670** lists) is in register 'reg'.
671** If expression has jumps, need to patch these jumps either to
672** its final position or to "load" instructions (for those tests
673** that do not produce values).
674*/
675static void exp2reg (FuncState *fs, expdesc *e, int reg) {
676 discharge2reg(fs, e, reg);
677 if (e->k == VJMP) /* expression itself is a test? */
678 luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */
679 if (hasjumps(e)) {
680 int final; /* position after whole expression */
681 int p_f = NO_JUMP; /* position of an eventual LOAD false */
682 int p_t = NO_JUMP; /* position of an eventual LOAD true */
683 if (need_value(fs, e->t) || need_value(fs, e->f)) {
684 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
685 p_f = code_loadbool(fs, reg, 0, 1);
686 p_t = code_loadbool(fs, reg, 1, 0);
687 luaK_patchtohere(fs, fj);
688 }
689 final = luaK_getlabel(fs);
690 patchlistaux(fs, e->f, final, reg, p_f);
691 patchlistaux(fs, e->t, final, reg, p_t);
692 }
693 e->f = e->t = NO_JUMP;
694 e->u.info = reg;
695 e->k = VNONRELOC;
696}
697
698
699/*
700** Ensures final expression result (including results from its jump
701** lists) is in next available register.
702*/
703void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
704 luaK_dischargevars(fs, e);
705 freeexp(fs, e);
706 luaK_reserveregs(fs, 1);
707 exp2reg(fs, e, fs->freereg - 1);
708}
709
710
711/*
712** Ensures final expression result (including results from its jump
713** lists) is in some (any) register and return that register.
714*/
715int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
716 luaK_dischargevars(fs, e);
717 if (e->k == VNONRELOC) { /* expression already has a register? */
718 if (!hasjumps(e)) /* no jumps? */
719 return e->u.info; /* result is already in a register */
720 if (e->u.info >= fs->nactvar) { /* reg. is not a local? */
721 exp2reg(fs, e, e->u.info); /* put final result in it */
722 return e->u.info;
723 }
724 }
725 luaK_exp2nextreg(fs, e); /* otherwise, use next available register */
726 return e->u.info;
727}
728
729
730/*
731** Ensures final expression result is either in a register or in an
732** upvalue.
733*/
734void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
735 if (e->k != VUPVAL || hasjumps(e))
736 luaK_exp2anyreg(fs, e);
737}
738
739
740/*
741** Ensures final expression result is either in a register or it is
742** a constant.
743*/
744void luaK_exp2val (FuncState *fs, expdesc *e) {
745 if (hasjumps(e))
746 luaK_exp2anyreg(fs, e);
747 else
748 luaK_dischargevars(fs, e);
749}
750
751
752/*
753** Ensures final expression result is in a valid R/K index
754** (that is, it is either in a register or in 'k' with an index
755** in the range of R/K indices).
756** Returns R/K index.
757*/
758int luaK_exp2RK (FuncState *fs, expdesc *e) {
759 luaK_exp2val(fs, e);
760 switch (e->k) { /* move constants to 'k' */
761 case VTRUE: e->u.info = boolK(fs, 1); goto vk;
762 case VFALSE: e->u.info = boolK(fs, 0); goto vk;
763 case VNIL: e->u.info = nilK(fs); goto vk;
764 case VKINT: e->u.info = luaK_intK(fs, e->u.ival); goto vk;
765 case VKFLT: e->u.info = luaK_numberK(fs, e->u.nval); goto vk;
766 case VK:
767 vk:
768 e->k = VK;
769 if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */
770 return RKASK(e->u.info);
771 else break;
772 default: break;
773 }
774 /* not a constant in the right range: put it in a register */
775 return luaK_exp2anyreg(fs, e);
776}
777
778
779/*
780** Generate code to store result of expression 'ex' into variable 'var'.
781*/
782void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
783 switch (var->k) {
784 case VLOCAL: {
785 freeexp(fs, ex);
786 exp2reg(fs, ex, var->u.info); /* compute 'ex' into proper place */
787 return;
788 }
789 case VUPVAL: {
790 int e = luaK_exp2anyreg(fs, ex);
791 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
792 break;
793 }
794 case VINDEXED: {
795 OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
796 int e = luaK_exp2RK(fs, ex);
797 luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
798 break;
799 }
800 default: lua_assert(0); /* invalid var kind to store */
801 }
802 freeexp(fs, ex);
803}
804
805
806/*
807** Emit SELF instruction (convert expression 'e' into 'e:key(e,').
808*/
809void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
810 int ereg;
811 luaK_exp2anyreg(fs, e);
812 ereg = e->u.info; /* register where 'e' was placed */
813 freeexp(fs, e);
814 e->u.info = fs->freereg; /* base register for op_self */
815 e->k = VNONRELOC; /* self expression has a fixed register */
816 luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */
817 luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
818 freeexp(fs, key);
819}
820
821
822/*
823** Negate condition 'e' (where 'e' is a comparison).
824*/
825static void negatecondition (FuncState *fs, expdesc *e) {
826 Instruction *pc = getjumpcontrol(fs, e->u.info);
827 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
828 GET_OPCODE(*pc) != OP_TEST);
829 SETARG_A(*pc, !(GETARG_A(*pc)));
830}
831
832
833/*
834** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond'
835** is true, code will jump if 'e' is true.) Return jump position.
836** Optimize when 'e' is 'not' something, inverting the condition
837** and removing the 'not'.
838*/
839static int jumponcond (FuncState *fs, expdesc *e, int cond) {
840 if (e->k == VRELOCABLE) {
841 Instruction ie = getinstruction(fs, e);
842 if (GET_OPCODE(ie) == OP_NOT) {
843 fs->pc--; /* remove previous OP_NOT */
844 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
845 }
846 /* else go through */
847 }
848 discharge2anyreg(fs, e);
849 freeexp(fs, e);
850 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
851}
852
853
854/*
855** Emit code to go through if 'e' is true, jump otherwise.
856*/
857void luaK_goiftrue (FuncState *fs, expdesc *e) {
858 int pc; /* pc of new jump */
859 luaK_dischargevars(fs, e);
860 switch (e->k) {
861 case VJMP: { /* condition? */
862 negatecondition(fs, e); /* jump when it is false */
863 pc = e->u.info; /* save jump position */
864 break;
865 }
866 case VK: case VKFLT: case VKINT: case VTRUE: {
867 pc = NO_JUMP; /* always true; do nothing */
868 break;
869 }
870 default: {
871 pc = jumponcond(fs, e, 0); /* jump when false */
872 break;
873 }
874 }
875 luaK_concat(fs, &e->f, pc); /* insert new jump in false list */
876 luaK_patchtohere(fs, e->t); /* true list jumps to here (to go through) */
877 e->t = NO_JUMP;
878}
879
880
881/*
882** Emit code to go through if 'e' is false, jump otherwise.
883*/
884void luaK_goiffalse (FuncState *fs, expdesc *e) {
885 int pc; /* pc of new jump */
886 luaK_dischargevars(fs, e);
887 switch (e->k) {
888 case VJMP: {
889 pc = e->u.info; /* already jump if true */
890 break;
891 }
892 case VNIL: case VFALSE: {
893 pc = NO_JUMP; /* always false; do nothing */
894 break;
895 }
896 default: {
897 pc = jumponcond(fs, e, 1); /* jump if true */
898 break;
899 }
900 }
901 luaK_concat(fs, &e->t, pc); /* insert new jump in 't' list */
902 luaK_patchtohere(fs, e->f); /* false list jumps to here (to go through) */
903 e->f = NO_JUMP;
904}
905
906
907/*
908** Code 'not e', doing constant folding.
909*/
910static void codenot (FuncState *fs, expdesc *e) {
911 luaK_dischargevars(fs, e);
912 switch (e->k) {
913 case VNIL: case VFALSE: {
914 e->k = VTRUE; /* true == not nil == not false */
915 break;
916 }
917 case VK: case VKFLT: case VKINT: case VTRUE: {
918 e->k = VFALSE; /* false == not "x" == not 0.5 == not 1 == not true */
919 break;
920 }
921 case VJMP: {
922 negatecondition(fs, e);
923 break;
924 }
925 case VRELOCABLE:
926 case VNONRELOC: {
927 discharge2anyreg(fs, e);
928 freeexp(fs, e);
929 e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
930 e->k = VRELOCABLE;
931 break;
932 }
933 default: lua_assert(0); /* cannot happen */
934 }
935 /* interchange true and false lists */
936 { int temp = e->f; e->f = e->t; e->t = temp; }
937 removevalues(fs, e->f); /* values are useless when negated */
938 removevalues(fs, e->t);
939}
940
941
942/*
943** Create expression 't[k]'. 't' must have its final result already in a
944** register or upvalue.
945*/
946void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
947 lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL));
948 t->u.ind.t = t->u.info; /* register or upvalue index */
949 t->u.ind.idx = luaK_exp2RK(fs, k); /* R/K index for key */
950 t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL;
951 t->k = VINDEXED;
952}
953
954
955/*
956** Return false if folding can raise an error.
957** Bitwise operations need operands convertible to integers; division
958** operations cannot have 0 as divisor.
959*/
960static int validop (int op, TValue *v1, TValue *v2) {
961 switch (op) {
962 case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
963 case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */
964 lua_Integer i;
965 return (tointeger(v1, &i) && tointeger(v2, &i));
966 }
967 case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */
968 return (nvalue(v2) != 0);
969 default: return 1; /* everything else is valid */
970 }
971}
972
973
974/*
975** Try to "constant-fold" an operation; return 1 iff successful.
976** (In this case, 'e1' has the final result.)
977*/
978static int constfolding (FuncState *fs, int op, expdesc *e1,
979 const expdesc *e2) {
980 TValue v1, v2, res;
981 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
982 return 0; /* non-numeric operands or not safe to fold */
983 luaO_arith(fs->ls->L, op, &v1, &v2, &res); /* does operation */
984 if (ttisinteger(&res)) {
985 e1->k = VKINT;
986 e1->u.ival = ivalue(&res);
987 }
988 else { /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */
989 lua_Number n = fltvalue(&res);
990 if (luai_numisnan(n) || n == 0)
991 return 0;
992 e1->k = VKFLT;
993 e1->u.nval = n;
994 }
995 return 1;
996}
997
998
999/*
1000** Emit code for unary expressions that "produce values"
1001** (everything but 'not').
1002** Expression to produce final result will be encoded in 'e'.
1003*/
1004static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
1005 int r = luaK_exp2anyreg(fs, e); /* opcodes operate only on registers */
1006 freeexp(fs, e);
1007 e->u.info = luaK_codeABC(fs, op, 0, r, 0); /* generate opcode */
1008 e->k = VRELOCABLE; /* all those operations are relocatable */
1009 luaK_fixline(fs, line);
1010}
1011
1012
1013/*
1014** Emit code for binary expressions that "produce values"
1015** (everything but logical operators 'and'/'or' and comparison
1016** operators).
1017** Expression to produce final result will be encoded in 'e1'.
1018** Because 'luaK_exp2RK' can free registers, its calls must be
1019** in "stack order" (that is, first on 'e2', which may have more
1020** recent registers to be released).
1021*/
1022static void codebinexpval (FuncState *fs, OpCode op,
1023 expdesc *e1, expdesc *e2, int line) {
1024 int rk2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */
1025 int rk1 = luaK_exp2RK(fs, e1);
1026 freeexps(fs, e1, e2);
1027 e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2); /* generate opcode */
1028 e1->k = VRELOCABLE; /* all those operations are relocatable */
1029 luaK_fixline(fs, line);
1030}
1031
1032
1033/*
1034** Emit code for comparisons.
1035** 'e1' was already put in R/K form by 'luaK_infix'.
1036*/
1037static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1038 int rk1 = (e1->k == VK) ? RKASK(e1->u.info)
1039 : check_exp(e1->k == VNONRELOC, e1->u.info);
1040 int rk2 = luaK_exp2RK(fs, e2);
1041 freeexps(fs, e1, e2);
1042 switch (opr) {
1043 case OPR_NE: { /* '(a ~= b)' ==> 'not (a == b)' */
1044 e1->u.info = condjump(fs, OP_EQ, 0, rk1, rk2);
1045 break;
1046 }
1047 case OPR_GT: case OPR_GE: {
1048 /* '(a > b)' ==> '(b < a)'; '(a >= b)' ==> '(b <= a)' */
1049 OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ);
1050 e1->u.info = condjump(fs, op, 1, rk2, rk1); /* invert operands */
1051 break;
1052 }
1053 default: { /* '==', '<', '<=' use their own opcodes */
1054 OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ);
1055 e1->u.info = condjump(fs, op, 1, rk1, rk2);
1056 break;
1057 }
1058 }
1059 e1->k = VJMP;
1060}
1061
1062
1063/*
1064** Apply prefix operation 'op' to expression 'e'.
1065*/
1066void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
1067 static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
1068 switch (op) {
1069 case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */
1070 if (constfolding(fs, op + LUA_OPUNM, e, &ef))
1071 break;
1072 /* FALLTHROUGH */
1073 case OPR_LEN:
1074 codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line);
1075 break;
1076 case OPR_NOT: codenot(fs, e); break;
1077 default: lua_assert(0);
1078 }
1079}
1080
1081
1082/*
1083** Process 1st operand 'v' of binary operation 'op' before reading
1084** 2nd operand.
1085*/
1086void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
1087 switch (op) {
1088 case OPR_AND: {
1089 luaK_goiftrue(fs, v); /* go ahead only if 'v' is true */
1090 break;
1091 }
1092 case OPR_OR: {
1093 luaK_goiffalse(fs, v); /* go ahead only if 'v' is false */
1094 break;
1095 }
1096 case OPR_CONCAT: {
1097 luaK_exp2nextreg(fs, v); /* operand must be on the 'stack' */
1098 break;
1099 }
1100 case OPR_ADD: case OPR_SUB:
1101 case OPR_MUL: case OPR_DIV: case OPR_IDIV:
1102 case OPR_MOD: case OPR_POW:
1103 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
1104 case OPR_SHL: case OPR_SHR: {
1105 if (!tonumeral(v, NULL))
1106 luaK_exp2RK(fs, v);
1107 /* else keep numeral, which may be folded with 2nd operand */
1108 break;
1109 }
1110 default: {
1111 luaK_exp2RK(fs, v);
1112 break;
1113 }
1114 }
1115}
1116
1117
1118/*
1119** Finalize code for binary operation, after reading 2nd operand.
1120** For '(a .. b .. c)' (which is '(a .. (b .. c))', because
1121** concatenation is right associative), merge second CONCAT into first
1122** one.
1123*/
1124void luaK_posfix (FuncState *fs, BinOpr op,
1125 expdesc *e1, expdesc *e2, int line) {
1126 switch (op) {
1127 case OPR_AND: {
1128 lua_assert(e1->t == NO_JUMP); /* list closed by 'luK_infix' */
1129 luaK_dischargevars(fs, e2);
1130 luaK_concat(fs, &e2->f, e1->f);
1131 *e1 = *e2;
1132 break;
1133 }
1134 case OPR_OR: {
1135 lua_assert(e1->f == NO_JUMP); /* list closed by 'luK_infix' */
1136 luaK_dischargevars(fs, e2);
1137 luaK_concat(fs, &e2->t, e1->t);
1138 *e1 = *e2;
1139 break;
1140 }
1141 case OPR_CONCAT: {
1142 luaK_exp2val(fs, e2);
1143 if (e2->k == VRELOCABLE &&
1144 GET_OPCODE(getinstruction(fs, e2)) == OP_CONCAT) {
1145 lua_assert(e1->u.info == GETARG_B(getinstruction(fs, e2))-1);
1146 freeexp(fs, e1);
1147 SETARG_B(getinstruction(fs, e2), e1->u.info);
1148 e1->k = VRELOCABLE; e1->u.info = e2->u.info;
1149 }
1150 else {
1151 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
1152 codebinexpval(fs, OP_CONCAT, e1, e2, line);
1153 }
1154 break;
1155 }
1156 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
1157 case OPR_IDIV: case OPR_MOD: case OPR_POW:
1158 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
1159 case OPR_SHL: case OPR_SHR: {
1160 if (!constfolding(fs, op + LUA_OPADD, e1, e2))
1161 codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line);
1162 break;
1163 }
1164 case OPR_EQ: case OPR_LT: case OPR_LE:
1165 case OPR_NE: case OPR_GT: case OPR_GE: {
1166 codecomp(fs, op, e1, e2);
1167 break;
1168 }
1169 default: lua_assert(0);
1170 }
1171}
1172
1173
1174/*
1175** Change line information associated with current position.
1176*/
1177void luaK_fixline (FuncState *fs, int line) {
1178 fs->f->lineinfo[fs->pc - 1] = line;
1179}
1180
1181
1182/*
1183** Emit a SETLIST instruction.
1184** 'base' is register that keeps table;
1185** 'nelems' is #table plus those to be stored now;
1186** 'tostore' is number of values (in registers 'base + 1',...) to add to
1187** table (or LUA_MULTRET to add up to stack top).
1188*/
1189void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
1190 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
1191 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
1192 lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH);
1193 if (c <= MAXARG_C)
1194 luaK_codeABC(fs, OP_SETLIST, base, b, c);
1195 else if (c <= MAXARG_Ax) {
1196 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
1197 codeextraarg(fs, c);
1198 }
1199 else
1200 luaX_syntaxerror(fs->ls, "constructor too long");
1201 fs->freereg = base + 1; /* free registers with list values */
1202}
1203
diff --git a/src/lua-5.3/lcode.h b/src/lua-5.3/lcode.h
new file mode 100644
index 0000000..882dc9c
--- /dev/null
+++ b/src/lua-5.3/lcode.h
@@ -0,0 +1,88 @@
1/*
2** $Id: lcode.h,v 1.64.1.1 2017/04/19 17:20:42 roberto Exp $
3** Code generator for Lua
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lcode_h
8#define lcode_h
9
10#include "llex.h"
11#include "lobject.h"
12#include "lopcodes.h"
13#include "lparser.h"
14
15
16/*
17** Marks the end of a patch list. It is an invalid value both as an absolute
18** address, and as a list link (would link an element to itself).
19*/
20#define NO_JUMP (-1)
21
22
23/*
24** grep "ORDER OPR" if you change these enums (ORDER OP)
25*/
26typedef enum BinOpr {
27 OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW,
28 OPR_DIV,
29 OPR_IDIV,
30 OPR_BAND, OPR_BOR, OPR_BXOR,
31 OPR_SHL, OPR_SHR,
32 OPR_CONCAT,
33 OPR_EQ, OPR_LT, OPR_LE,
34 OPR_NE, OPR_GT, OPR_GE,
35 OPR_AND, OPR_OR,
36 OPR_NOBINOPR
37} BinOpr;
38
39
40typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
41
42
43/* get (pointer to) instruction of given 'expdesc' */
44#define getinstruction(fs,e) ((fs)->f->code[(e)->u.info])
45
46#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
47
48#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
49
50#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t)
51
52LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
53LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
54LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k);
55LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
56LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
57LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
58LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
59LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
60LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n);
61LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
62LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
63LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
64LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
65LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
66LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
67LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
68LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
69LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
70LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
71LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
72LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
73LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
74LUAI_FUNC int luaK_jump (FuncState *fs);
75LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
76LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
77LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
78LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level);
79LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
80LUAI_FUNC int luaK_getlabel (FuncState *fs);
81LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line);
82LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
83LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
84 expdesc *v2, int line);
85LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
86
87
88#endif
diff --git a/src/lua-5.3/lcorolib.c b/src/lua-5.3/lcorolib.c
new file mode 100644
index 0000000..0b17af9
--- /dev/null
+++ b/src/lua-5.3/lcorolib.c
@@ -0,0 +1,168 @@
1/*
2** $Id: lcorolib.c,v 1.10.1.1 2017/04/19 17:20:42 roberto Exp $
3** Coroutine Library
4** See Copyright Notice in lua.h
5*/
6
7#define lcorolib_c
8#define LUA_LIB
9
10#include "lprefix.h"
11
12
13#include <stdlib.h>
14
15#include "lua.h"
16
17#include "lauxlib.h"
18#include "lualib.h"
19
20
21static lua_State *getco (lua_State *L) {
22 lua_State *co = lua_tothread(L, 1);
23 luaL_argcheck(L, co, 1, "thread expected");
24 return co;
25}
26
27
28static int auxresume (lua_State *L, lua_State *co, int narg) {
29 int status;
30 if (!lua_checkstack(co, narg)) {
31 lua_pushliteral(L, "too many arguments to resume");
32 return -1; /* error flag */
33 }
34 if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
35 lua_pushliteral(L, "cannot resume dead coroutine");
36 return -1; /* error flag */
37 }
38 lua_xmove(L, co, narg);
39 status = lua_resume(co, L, narg);
40 if (status == LUA_OK || status == LUA_YIELD) {
41 int nres = lua_gettop(co);
42 if (!lua_checkstack(L, nres + 1)) {
43 lua_pop(co, nres); /* remove results anyway */
44 lua_pushliteral(L, "too many results to resume");
45 return -1; /* error flag */
46 }
47 lua_xmove(co, L, nres); /* move yielded values */
48 return nres;
49 }
50 else {
51 lua_xmove(co, L, 1); /* move error message */
52 return -1; /* error flag */
53 }
54}
55
56
57static int luaB_coresume (lua_State *L) {
58 lua_State *co = getco(L);
59 int r;
60 r = auxresume(L, co, lua_gettop(L) - 1);
61 if (r < 0) {
62 lua_pushboolean(L, 0);
63 lua_insert(L, -2);
64 return 2; /* return false + error message */
65 }
66 else {
67 lua_pushboolean(L, 1);
68 lua_insert(L, -(r + 1));
69 return r + 1; /* return true + 'resume' returns */
70 }
71}
72
73
74static int luaB_auxwrap (lua_State *L) {
75 lua_State *co = lua_tothread(L, lua_upvalueindex(1));
76 int r = auxresume(L, co, lua_gettop(L));
77 if (r < 0) {
78 if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */
79 luaL_where(L, 1); /* add extra info */
80 lua_insert(L, -2);
81 lua_concat(L, 2);
82 }
83 return lua_error(L); /* propagate error */
84 }
85 return r;
86}
87
88
89static int luaB_cocreate (lua_State *L) {
90 lua_State *NL;
91 luaL_checktype(L, 1, LUA_TFUNCTION);
92 NL = lua_newthread(L);
93 lua_pushvalue(L, 1); /* move function to top */
94 lua_xmove(L, NL, 1); /* move function from L to NL */
95 return 1;
96}
97
98
99static int luaB_cowrap (lua_State *L) {
100 luaB_cocreate(L);
101 lua_pushcclosure(L, luaB_auxwrap, 1);
102 return 1;
103}
104
105
106static int luaB_yield (lua_State *L) {
107 return lua_yield(L, lua_gettop(L));
108}
109
110
111static int luaB_costatus (lua_State *L) {
112 lua_State *co = getco(L);
113 if (L == co) lua_pushliteral(L, "running");
114 else {
115 switch (lua_status(co)) {
116 case LUA_YIELD:
117 lua_pushliteral(L, "suspended");
118 break;
119 case LUA_OK: {
120 lua_Debug ar;
121 if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
122 lua_pushliteral(L, "normal"); /* it is running */
123 else if (lua_gettop(co) == 0)
124 lua_pushliteral(L, "dead");
125 else
126 lua_pushliteral(L, "suspended"); /* initial state */
127 break;
128 }
129 default: /* some error occurred */
130 lua_pushliteral(L, "dead");
131 break;
132 }
133 }
134 return 1;
135}
136
137
138static int luaB_yieldable (lua_State *L) {
139 lua_pushboolean(L, lua_isyieldable(L));
140 return 1;
141}
142
143
144static int luaB_corunning (lua_State *L) {
145 int ismain = lua_pushthread(L);
146 lua_pushboolean(L, ismain);
147 return 2;
148}
149
150
151static const luaL_Reg co_funcs[] = {
152 {"create", luaB_cocreate},
153 {"resume", luaB_coresume},
154 {"running", luaB_corunning},
155 {"status", luaB_costatus},
156 {"wrap", luaB_cowrap},
157 {"yield", luaB_yield},
158 {"isyieldable", luaB_yieldable},
159 {NULL, NULL}
160};
161
162
163
164LUAMOD_API int luaopen_coroutine (lua_State *L) {
165 luaL_newlib(L, co_funcs);
166 return 1;
167}
168
diff --git a/src/lua-5.3/lctype.c b/src/lua-5.3/lctype.c
new file mode 100644
index 0000000..f8ad7a2
--- /dev/null
+++ b/src/lua-5.3/lctype.c
@@ -0,0 +1,55 @@
1/*
2** $Id: lctype.c,v 1.12.1.1 2017/04/19 17:20:42 roberto Exp $
3** 'ctype' functions for Lua
4** See Copyright Notice in lua.h
5*/
6
7#define lctype_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include "lctype.h"
14
15#if !LUA_USE_CTYPE /* { */
16
17#include <limits.h>
18
19LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = {
20 0x00, /* EOZ */
21 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */
22 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */
24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */
26 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
27 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */
28 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
29 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */
30 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
31 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */
32 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05,
33 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */
34 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
35 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */
36 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00,
37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */
40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */
42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53};
54
55#endif /* } */
diff --git a/src/lua-5.3/lctype.h b/src/lua-5.3/lctype.h
new file mode 100644
index 0000000..b09b21a
--- /dev/null
+++ b/src/lua-5.3/lctype.h
@@ -0,0 +1,95 @@
1/*
2** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $
3** 'ctype' functions for Lua
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lctype_h
8#define lctype_h
9
10#include "lua.h"
11
12
13/*
14** WARNING: the functions defined here do not necessarily correspond
15** to the similar functions in the standard C ctype.h. They are
16** optimized for the specific needs of Lua
17*/
18
19#if !defined(LUA_USE_CTYPE)
20
21#if 'A' == 65 && '0' == 48
22/* ASCII case: can use its own tables; faster and fixed */
23#define LUA_USE_CTYPE 0
24#else
25/* must use standard C ctype */
26#define LUA_USE_CTYPE 1
27#endif
28
29#endif
30
31
32#if !LUA_USE_CTYPE /* { */
33
34#include <limits.h>
35
36#include "llimits.h"
37
38
39#define ALPHABIT 0
40#define DIGITBIT 1
41#define PRINTBIT 2
42#define SPACEBIT 3
43#define XDIGITBIT 4
44
45
46#define MASK(B) (1 << (B))
47
48
49/*
50** add 1 to char to allow index -1 (EOZ)
51*/
52#define testprop(c,p) (luai_ctype_[(c)+1] & (p))
53
54/*
55** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
56*/
57#define lislalpha(c) testprop(c, MASK(ALPHABIT))
58#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
59#define lisdigit(c) testprop(c, MASK(DIGITBIT))
60#define lisspace(c) testprop(c, MASK(SPACEBIT))
61#define lisprint(c) testprop(c, MASK(PRINTBIT))
62#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
63
64/*
65** this 'ltolower' only works for alphabetic characters
66*/
67#define ltolower(c) ((c) | ('A' ^ 'a'))
68
69
70/* two more entries for 0 and -1 (EOZ) */
71LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2];
72
73
74#else /* }{ */
75
76/*
77** use standard C ctypes
78*/
79
80#include <ctype.h>
81
82
83#define lislalpha(c) (isalpha(c) || (c) == '_')
84#define lislalnum(c) (isalnum(c) || (c) == '_')
85#define lisdigit(c) (isdigit(c))
86#define lisspace(c) (isspace(c))
87#define lisprint(c) (isprint(c))
88#define lisxdigit(c) (isxdigit(c))
89
90#define ltolower(c) (tolower(c))
91
92#endif /* } */
93
94#endif
95
diff --git a/src/lua-5.3/ldblib.c b/src/lua-5.3/ldblib.c
new file mode 100644
index 0000000..9d29afb
--- /dev/null
+++ b/src/lua-5.3/ldblib.c
@@ -0,0 +1,456 @@
1/*
2** $Id: ldblib.c,v 1.151.1.1 2017/04/19 17:20:42 roberto Exp $
3** Interface from Lua to its debug API
4** See Copyright Notice in lua.h
5*/
6
7#define ldblib_c
8#define LUA_LIB
9
10#include "lprefix.h"
11
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21
22
23/*
24** The hook table at registry[&HOOKKEY] maps threads to their current
25** hook function. (We only need the unique address of 'HOOKKEY'.)
26*/
27static const int HOOKKEY = 0;
28
29
30/*
31** If L1 != L, L1 can be in any state, and therefore there are no
32** guarantees about its stack space; any push in L1 must be
33** checked.
34*/
35static void checkstack (lua_State *L, lua_State *L1, int n) {
36 if (L != L1 && !lua_checkstack(L1, n))
37 luaL_error(L, "stack overflow");
38}
39
40
41static int db_getregistry (lua_State *L) {
42 lua_pushvalue(L, LUA_REGISTRYINDEX);
43 return 1;
44}
45
46
47static int db_getmetatable (lua_State *L) {
48 luaL_checkany(L, 1);
49 if (!lua_getmetatable(L, 1)) {
50 lua_pushnil(L); /* no metatable */
51 }
52 return 1;
53}
54
55
56static int db_setmetatable (lua_State *L) {
57 int t = lua_type(L, 2);
58 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
59 "nil or table expected");
60 lua_settop(L, 2);
61 lua_setmetatable(L, 1);
62 return 1; /* return 1st argument */
63}
64
65
66static int db_getuservalue (lua_State *L) {
67 if (lua_type(L, 1) != LUA_TUSERDATA)
68 lua_pushnil(L);
69 else
70 lua_getuservalue(L, 1);
71 return 1;
72}
73
74
75static int db_setuservalue (lua_State *L) {
76 luaL_checktype(L, 1, LUA_TUSERDATA);
77 luaL_checkany(L, 2);
78 lua_settop(L, 2);
79 lua_setuservalue(L, 1);
80 return 1;
81}
82
83
84/*
85** Auxiliary function used by several library functions: check for
86** an optional thread as function's first argument and set 'arg' with
87** 1 if this argument is present (so that functions can skip it to
88** access their other arguments)
89*/
90static lua_State *getthread (lua_State *L, int *arg) {
91 if (lua_isthread(L, 1)) {
92 *arg = 1;
93 return lua_tothread(L, 1);
94 }
95 else {
96 *arg = 0;
97 return L; /* function will operate over current thread */
98 }
99}
100
101
102/*
103** Variations of 'lua_settable', used by 'db_getinfo' to put results
104** from 'lua_getinfo' into result table. Key is always a string;
105** value can be a string, an int, or a boolean.
106*/
107static void settabss (lua_State *L, const char *k, const char *v) {
108 lua_pushstring(L, v);
109 lua_setfield(L, -2, k);
110}
111
112static void settabsi (lua_State *L, const char *k, int v) {
113 lua_pushinteger(L, v);
114 lua_setfield(L, -2, k);
115}
116
117static void settabsb (lua_State *L, const char *k, int v) {
118 lua_pushboolean(L, v);
119 lua_setfield(L, -2, k);
120}
121
122
123/*
124** In function 'db_getinfo', the call to 'lua_getinfo' may push
125** results on the stack; later it creates the result table to put
126** these objects. Function 'treatstackoption' puts the result from
127** 'lua_getinfo' on top of the result table so that it can call
128** 'lua_setfield'.
129*/
130static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
131 if (L == L1)
132 lua_rotate(L, -2, 1); /* exchange object and table */
133 else
134 lua_xmove(L1, L, 1); /* move object to the "main" stack */
135 lua_setfield(L, -2, fname); /* put object into table */
136}
137
138
139/*
140** Calls 'lua_getinfo' and collects all results in a new table.
141** L1 needs stack space for an optional input (function) plus
142** two optional outputs (function and line table) from function
143** 'lua_getinfo'.
144*/
145static int db_getinfo (lua_State *L) {
146 lua_Debug ar;
147 int arg;
148 lua_State *L1 = getthread(L, &arg);
149 const char *options = luaL_optstring(L, arg+2, "flnStu");
150 checkstack(L, L1, 3);
151 if (lua_isfunction(L, arg + 1)) { /* info about a function? */
152 options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */
153 lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */
154 lua_xmove(L, L1, 1);
155 }
156 else { /* stack level */
157 if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) {
158 lua_pushnil(L); /* level out of range */
159 return 1;
160 }
161 }
162 if (!lua_getinfo(L1, options, &ar))
163 return luaL_argerror(L, arg+2, "invalid option");
164 lua_newtable(L); /* table to collect results */
165 if (strchr(options, 'S')) {
166 settabss(L, "source", ar.source);
167 settabss(L, "short_src", ar.short_src);
168 settabsi(L, "linedefined", ar.linedefined);
169 settabsi(L, "lastlinedefined", ar.lastlinedefined);
170 settabss(L, "what", ar.what);
171 }
172 if (strchr(options, 'l'))
173 settabsi(L, "currentline", ar.currentline);
174 if (strchr(options, 'u')) {
175 settabsi(L, "nups", ar.nups);
176 settabsi(L, "nparams", ar.nparams);
177 settabsb(L, "isvararg", ar.isvararg);
178 }
179 if (strchr(options, 'n')) {
180 settabss(L, "name", ar.name);
181 settabss(L, "namewhat", ar.namewhat);
182 }
183 if (strchr(options, 't'))
184 settabsb(L, "istailcall", ar.istailcall);
185 if (strchr(options, 'L'))
186 treatstackoption(L, L1, "activelines");
187 if (strchr(options, 'f'))
188 treatstackoption(L, L1, "func");
189 return 1; /* return table */
190}
191
192
193static int db_getlocal (lua_State *L) {
194 int arg;
195 lua_State *L1 = getthread(L, &arg);
196 lua_Debug ar;
197 const char *name;
198 int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */
199 if (lua_isfunction(L, arg + 1)) { /* function argument? */
200 lua_pushvalue(L, arg + 1); /* push function */
201 lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */
202 return 1; /* return only name (there is no value) */
203 }
204 else { /* stack-level argument */
205 int level = (int)luaL_checkinteger(L, arg + 1);
206 if (!lua_getstack(L1, level, &ar)) /* out of range? */
207 return luaL_argerror(L, arg+1, "level out of range");
208 checkstack(L, L1, 1);
209 name = lua_getlocal(L1, &ar, nvar);
210 if (name) {
211 lua_xmove(L1, L, 1); /* move local value */
212 lua_pushstring(L, name); /* push name */
213 lua_rotate(L, -2, 1); /* re-order */
214 return 2;
215 }
216 else {
217 lua_pushnil(L); /* no name (nor value) */
218 return 1;
219 }
220 }
221}
222
223
224static int db_setlocal (lua_State *L) {
225 int arg;
226 const char *name;
227 lua_State *L1 = getthread(L, &arg);
228 lua_Debug ar;
229 int level = (int)luaL_checkinteger(L, arg + 1);
230 int nvar = (int)luaL_checkinteger(L, arg + 2);
231 if (!lua_getstack(L1, level, &ar)) /* out of range? */
232 return luaL_argerror(L, arg+1, "level out of range");
233 luaL_checkany(L, arg+3);
234 lua_settop(L, arg+3);
235 checkstack(L, L1, 1);
236 lua_xmove(L, L1, 1);
237 name = lua_setlocal(L1, &ar, nvar);
238 if (name == NULL)
239 lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */
240 lua_pushstring(L, name);
241 return 1;
242}
243
244
245/*
246** get (if 'get' is true) or set an upvalue from a closure
247*/
248static int auxupvalue (lua_State *L, int get) {
249 const char *name;
250 int n = (int)luaL_checkinteger(L, 2); /* upvalue index */
251 luaL_checktype(L, 1, LUA_TFUNCTION); /* closure */
252 name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
253 if (name == NULL) return 0;
254 lua_pushstring(L, name);
255 lua_insert(L, -(get+1)); /* no-op if get is false */
256 return get + 1;
257}
258
259
260static int db_getupvalue (lua_State *L) {
261 return auxupvalue(L, 1);
262}
263
264
265static int db_setupvalue (lua_State *L) {
266 luaL_checkany(L, 3);
267 return auxupvalue(L, 0);
268}
269
270
271/*
272** Check whether a given upvalue from a given closure exists and
273** returns its index
274*/
275static int checkupval (lua_State *L, int argf, int argnup) {
276 int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */
277 luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */
278 luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup,
279 "invalid upvalue index");
280 return nup;
281}
282
283
284static int db_upvalueid (lua_State *L) {
285 int n = checkupval(L, 1, 2);
286 lua_pushlightuserdata(L, lua_upvalueid(L, 1, n));
287 return 1;
288}
289
290
291static int db_upvaluejoin (lua_State *L) {
292 int n1 = checkupval(L, 1, 2);
293 int n2 = checkupval(L, 3, 4);
294 luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected");
295 luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected");
296 lua_upvaluejoin(L, 1, n1, 3, n2);
297 return 0;
298}
299
300
301/*
302** Call hook function registered at hook table for the current
303** thread (if there is one)
304*/
305static void hookf (lua_State *L, lua_Debug *ar) {
306 static const char *const hooknames[] =
307 {"call", "return", "line", "count", "tail call"};
308 lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
309 lua_pushthread(L);
310 if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */
311 lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */
312 if (ar->currentline >= 0)
313 lua_pushinteger(L, ar->currentline); /* push current line */
314 else lua_pushnil(L);
315 lua_assert(lua_getinfo(L, "lS", ar));
316 lua_call(L, 2, 0); /* call hook function */
317 }
318}
319
320
321/*
322** Convert a string mask (for 'sethook') into a bit mask
323*/
324static int makemask (const char *smask, int count) {
325 int mask = 0;
326 if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
327 if (strchr(smask, 'r')) mask |= LUA_MASKRET;
328 if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
329 if (count > 0) mask |= LUA_MASKCOUNT;
330 return mask;
331}
332
333
334/*
335** Convert a bit mask (for 'gethook') into a string mask
336*/
337static char *unmakemask (int mask, char *smask) {
338 int i = 0;
339 if (mask & LUA_MASKCALL) smask[i++] = 'c';
340 if (mask & LUA_MASKRET) smask[i++] = 'r';
341 if (mask & LUA_MASKLINE) smask[i++] = 'l';
342 smask[i] = '\0';
343 return smask;
344}
345
346
347static int db_sethook (lua_State *L) {
348 int arg, mask, count;
349 lua_Hook func;
350 lua_State *L1 = getthread(L, &arg);
351 if (lua_isnoneornil(L, arg+1)) { /* no hook? */
352 lua_settop(L, arg+1);
353 func = NULL; mask = 0; count = 0; /* turn off hooks */
354 }
355 else {
356 const char *smask = luaL_checkstring(L, arg+2);
357 luaL_checktype(L, arg+1, LUA_TFUNCTION);
358 count = (int)luaL_optinteger(L, arg + 3, 0);
359 func = hookf; mask = makemask(smask, count);
360 }
361 if (lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY) == LUA_TNIL) {
362 lua_createtable(L, 0, 2); /* create a hook table */
363 lua_pushvalue(L, -1);
364 lua_rawsetp(L, LUA_REGISTRYINDEX, &HOOKKEY); /* set it in position */
365 lua_pushstring(L, "k");
366 lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */
367 lua_pushvalue(L, -1);
368 lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */
369 }
370 checkstack(L, L1, 1);
371 lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */
372 lua_pushvalue(L, arg + 1); /* value (hook function) */
373 lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */
374 lua_sethook(L1, func, mask, count);
375 return 0;
376}
377
378
379static int db_gethook (lua_State *L) {
380 int arg;
381 lua_State *L1 = getthread(L, &arg);
382 char buff[5];
383 int mask = lua_gethookmask(L1);
384 lua_Hook hook = lua_gethook(L1);
385 if (hook == NULL) /* no hook? */
386 lua_pushnil(L);
387 else if (hook != hookf) /* external hook? */
388 lua_pushliteral(L, "external hook");
389 else { /* hook table must exist */
390 lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
391 checkstack(L, L1, 1);
392 lua_pushthread(L1); lua_xmove(L1, L, 1);
393 lua_rawget(L, -2); /* 1st result = hooktable[L1] */
394 lua_remove(L, -2); /* remove hook table */
395 }
396 lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */
397 lua_pushinteger(L, lua_gethookcount(L1)); /* 3rd result = count */
398 return 3;
399}
400
401
402static int db_debug (lua_State *L) {
403 for (;;) {
404 char buffer[250];
405 lua_writestringerror("%s", "lua_debug> ");
406 if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
407 strcmp(buffer, "cont\n") == 0)
408 return 0;
409 if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
410 lua_pcall(L, 0, 0, 0))
411 lua_writestringerror("%s\n", lua_tostring(L, -1));
412 lua_settop(L, 0); /* remove eventual returns */
413 }
414}
415
416
417static int db_traceback (lua_State *L) {
418 int arg;
419 lua_State *L1 = getthread(L, &arg);
420 const char *msg = lua_tostring(L, arg + 1);
421 if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */
422 lua_pushvalue(L, arg + 1); /* return it untouched */
423 else {
424 int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0);
425 luaL_traceback(L, L1, msg, level);
426 }
427 return 1;
428}
429
430
431static const luaL_Reg dblib[] = {
432 {"debug", db_debug},
433 {"getuservalue", db_getuservalue},
434 {"gethook", db_gethook},
435 {"getinfo", db_getinfo},
436 {"getlocal", db_getlocal},
437 {"getregistry", db_getregistry},
438 {"getmetatable", db_getmetatable},
439 {"getupvalue", db_getupvalue},
440 {"upvaluejoin", db_upvaluejoin},
441 {"upvalueid", db_upvalueid},
442 {"setuservalue", db_setuservalue},
443 {"sethook", db_sethook},
444 {"setlocal", db_setlocal},
445 {"setmetatable", db_setmetatable},
446 {"setupvalue", db_setupvalue},
447 {"traceback", db_traceback},
448 {NULL, NULL}
449};
450
451
452LUAMOD_API int luaopen_debug (lua_State *L) {
453 luaL_newlib(L, dblib);
454 return 1;
455}
456
diff --git a/src/lua-5.3/ldebug.c b/src/lua-5.3/ldebug.c
new file mode 100644
index 0000000..e138929
--- /dev/null
+++ b/src/lua-5.3/ldebug.c
@@ -0,0 +1,699 @@
1/*
2** $Id: ldebug.c,v 2.121.1.2 2017/07/10 17:21:50 roberto Exp $
3** Debug Interface
4** See Copyright Notice in lua.h
5*/
6
7#define ldebug_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <stdarg.h>
14#include <stddef.h>
15#include <string.h>
16
17#include "lua.h"
18
19#include "lapi.h"
20#include "lcode.h"
21#include "ldebug.h"
22#include "ldo.h"
23#include "lfunc.h"
24#include "lobject.h"
25#include "lopcodes.h"
26#include "lstate.h"
27#include "lstring.h"
28#include "ltable.h"
29#include "ltm.h"
30#include "lvm.h"
31
32
33
34#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
35
36
37/* Active Lua function (given call info) */
38#define ci_func(ci) (clLvalue((ci)->func))
39
40
41static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
42 const char **name);
43
44
45static int currentpc (CallInfo *ci) {
46 lua_assert(isLua(ci));
47 return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
48}
49
50
51static int currentline (CallInfo *ci) {
52 return getfuncline(ci_func(ci)->p, currentpc(ci));
53}
54
55
56/*
57** If function yielded, its 'func' can be in the 'extra' field. The
58** next function restores 'func' to its correct value for debugging
59** purposes. (It exchanges 'func' and 'extra'; so, when called again,
60** after debugging, it also "re-restores" ** 'func' to its altered value.
61*/
62static void swapextra (lua_State *L) {
63 if (L->status == LUA_YIELD) {
64 CallInfo *ci = L->ci; /* get function that yielded */
65 StkId temp = ci->func; /* exchange its 'func' and 'extra' values */
66 ci->func = restorestack(L, ci->extra);
67 ci->extra = savestack(L, temp);
68 }
69}
70
71
72/*
73** This function can be called asynchronously (e.g. during a signal).
74** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
75** 'resethookcount') are for debug only, and it is no problem if they
76** get arbitrary values (causes at most one wrong hook call). 'hookmask'
77** is an atomic value. We assume that pointers are atomic too (e.g., gcc
78** ensures that for all platforms where it runs). Moreover, 'hook' is
79** always checked before being called (see 'luaD_hook').
80*/
81LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
82 if (func == NULL || mask == 0) { /* turn off hooks? */
83 mask = 0;
84 func = NULL;
85 }
86 if (isLua(L->ci))
87 L->oldpc = L->ci->u.l.savedpc;
88 L->hook = func;
89 L->basehookcount = count;
90 resethookcount(L);
91 L->hookmask = cast_byte(mask);
92}
93
94
95LUA_API lua_Hook lua_gethook (lua_State *L) {
96 return L->hook;
97}
98
99
100LUA_API int lua_gethookmask (lua_State *L) {
101 return L->hookmask;
102}
103
104
105LUA_API int lua_gethookcount (lua_State *L) {
106 return L->basehookcount;
107}
108
109
110LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
111 int status;
112 CallInfo *ci;
113 if (level < 0) return 0; /* invalid (negative) level */
114 lua_lock(L);
115 for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
116 level--;
117 if (level == 0 && ci != &L->base_ci) { /* level found? */
118 status = 1;
119 ar->i_ci = ci;
120 }
121 else status = 0; /* no such level */
122 lua_unlock(L);
123 return status;
124}
125
126
127static const char *upvalname (Proto *p, int uv) {
128 TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
129 if (s == NULL) return "?";
130 else return getstr(s);
131}
132
133
134static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
135 int nparams = clLvalue(ci->func)->p->numparams;
136 if (n >= cast_int(ci->u.l.base - ci->func) - nparams)
137 return NULL; /* no such vararg */
138 else {
139 *pos = ci->func + nparams + n;
140 return "(*vararg)"; /* generic name for any vararg */
141 }
142}
143
144
145static const char *findlocal (lua_State *L, CallInfo *ci, int n,
146 StkId *pos) {
147 const char *name = NULL;
148 StkId base;
149 if (isLua(ci)) {
150 if (n < 0) /* access to vararg values? */
151 return findvararg(ci, -n, pos);
152 else {
153 base = ci->u.l.base;
154 name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
155 }
156 }
157 else
158 base = ci->func + 1;
159 if (name == NULL) { /* no 'standard' name? */
160 StkId limit = (ci == L->ci) ? L->top : ci->next->func;
161 if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
162 name = "(*temporary)"; /* generic name for any valid slot */
163 else
164 return NULL; /* no name */
165 }
166 *pos = base + (n - 1);
167 return name;
168}
169
170
171LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
172 const char *name;
173 lua_lock(L);
174 swapextra(L);
175 if (ar == NULL) { /* information about non-active function? */
176 if (!isLfunction(L->top - 1)) /* not a Lua function? */
177 name = NULL;
178 else /* consider live variables at function start (parameters) */
179 name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
180 }
181 else { /* active function; get information through 'ar' */
182 StkId pos = NULL; /* to avoid warnings */
183 name = findlocal(L, ar->i_ci, n, &pos);
184 if (name) {
185 setobj2s(L, L->top, pos);
186 api_incr_top(L);
187 }
188 }
189 swapextra(L);
190 lua_unlock(L);
191 return name;
192}
193
194
195LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
196 StkId pos = NULL; /* to avoid warnings */
197 const char *name;
198 lua_lock(L);
199 swapextra(L);
200 name = findlocal(L, ar->i_ci, n, &pos);
201 if (name) {
202 setobjs2s(L, pos, L->top - 1);
203 L->top--; /* pop value */
204 }
205 swapextra(L);
206 lua_unlock(L);
207 return name;
208}
209
210
211static void funcinfo (lua_Debug *ar, Closure *cl) {
212 if (noLuaClosure(cl)) {
213 ar->source = "=[C]";
214 ar->linedefined = -1;
215 ar->lastlinedefined = -1;
216 ar->what = "C";
217 }
218 else {
219 Proto *p = cl->l.p;
220 ar->source = p->source ? getstr(p->source) : "=?";
221 ar->linedefined = p->linedefined;
222 ar->lastlinedefined = p->lastlinedefined;
223 ar->what = (ar->linedefined == 0) ? "main" : "Lua";
224 }
225 luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
226}
227
228
229static void collectvalidlines (lua_State *L, Closure *f) {
230 if (noLuaClosure(f)) {
231 setnilvalue(L->top);
232 api_incr_top(L);
233 }
234 else {
235 int i;
236 TValue v;
237 int *lineinfo = f->l.p->lineinfo;
238 Table *t = luaH_new(L); /* new table to store active lines */
239 sethvalue(L, L->top, t); /* push it on stack */
240 api_incr_top(L);
241 setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
242 for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
243 luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
244 }
245}
246
247
248static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
249 if (ci == NULL) /* no 'ci'? */
250 return NULL; /* no info */
251 else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */
252 *name = "__gc";
253 return "metamethod"; /* report it as such */
254 }
255 /* calling function is a known Lua function? */
256 else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
257 return funcnamefromcode(L, ci->previous, name);
258 else return NULL; /* no way to find a name */
259}
260
261
262static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
263 Closure *f, CallInfo *ci) {
264 int status = 1;
265 for (; *what; what++) {
266 switch (*what) {
267 case 'S': {
268 funcinfo(ar, f);
269 break;
270 }
271 case 'l': {
272 ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
273 break;
274 }
275 case 'u': {
276 ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
277 if (noLuaClosure(f)) {
278 ar->isvararg = 1;
279 ar->nparams = 0;
280 }
281 else {
282 ar->isvararg = f->l.p->is_vararg;
283 ar->nparams = f->l.p->numparams;
284 }
285 break;
286 }
287 case 't': {
288 ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
289 break;
290 }
291 case 'n': {
292 ar->namewhat = getfuncname(L, ci, &ar->name);
293 if (ar->namewhat == NULL) {
294 ar->namewhat = ""; /* not found */
295 ar->name = NULL;
296 }
297 break;
298 }
299 case 'L':
300 case 'f': /* handled by lua_getinfo */
301 break;
302 default: status = 0; /* invalid option */
303 }
304 }
305 return status;
306}
307
308
309LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
310 int status;
311 Closure *cl;
312 CallInfo *ci;
313 StkId func;
314 lua_lock(L);
315 swapextra(L);
316 if (*what == '>') {
317 ci = NULL;
318 func = L->top - 1;
319 api_check(L, ttisfunction(func), "function expected");
320 what++; /* skip the '>' */
321 L->top--; /* pop function */
322 }
323 else {
324 ci = ar->i_ci;
325 func = ci->func;
326 lua_assert(ttisfunction(ci->func));
327 }
328 cl = ttisclosure(func) ? clvalue(func) : NULL;
329 status = auxgetinfo(L, what, ar, cl, ci);
330 if (strchr(what, 'f')) {
331 setobjs2s(L, L->top, func);
332 api_incr_top(L);
333 }
334 swapextra(L); /* correct before option 'L', which can raise a mem. error */
335 if (strchr(what, 'L'))
336 collectvalidlines(L, cl);
337 lua_unlock(L);
338 return status;
339}
340
341
342/*
343** {======================================================
344** Symbolic Execution
345** =======================================================
346*/
347
348static const char *getobjname (Proto *p, int lastpc, int reg,
349 const char **name);
350
351
352/*
353** find a "name" for the RK value 'c'
354*/
355static void kname (Proto *p, int pc, int c, const char **name) {
356 if (ISK(c)) { /* is 'c' a constant? */
357 TValue *kvalue = &p->k[INDEXK(c)];
358 if (ttisstring(kvalue)) { /* literal constant? */
359 *name = svalue(kvalue); /* it is its own name */
360 return;
361 }
362 /* else no reasonable name found */
363 }
364 else { /* 'c' is a register */
365 const char *what = getobjname(p, pc, c, name); /* search for 'c' */
366 if (what && *what == 'c') { /* found a constant name? */
367 return; /* 'name' already filled */
368 }
369 /* else no reasonable name found */
370 }
371 *name = "?"; /* no reasonable name found */
372}
373
374
375static int filterpc (int pc, int jmptarget) {
376 if (pc < jmptarget) /* is code conditional (inside a jump)? */
377 return -1; /* cannot know who sets that register */
378 else return pc; /* current position sets that register */
379}
380
381
382/*
383** try to find last instruction before 'lastpc' that modified register 'reg'
384*/
385static int findsetreg (Proto *p, int lastpc, int reg) {
386 int pc;
387 int setreg = -1; /* keep last instruction that changed 'reg' */
388 int jmptarget = 0; /* any code before this address is conditional */
389 for (pc = 0; pc < lastpc; pc++) {
390 Instruction i = p->code[pc];
391 OpCode op = GET_OPCODE(i);
392 int a = GETARG_A(i);
393 switch (op) {
394 case OP_LOADNIL: {
395 int b = GETARG_B(i);
396 if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
397 setreg = filterpc(pc, jmptarget);
398 break;
399 }
400 case OP_TFORCALL: {
401 if (reg >= a + 2) /* affect all regs above its base */
402 setreg = filterpc(pc, jmptarget);
403 break;
404 }
405 case OP_CALL:
406 case OP_TAILCALL: {
407 if (reg >= a) /* affect all registers above base */
408 setreg = filterpc(pc, jmptarget);
409 break;
410 }
411 case OP_JMP: {
412 int b = GETARG_sBx(i);
413 int dest = pc + 1 + b;
414 /* jump is forward and do not skip 'lastpc'? */
415 if (pc < dest && dest <= lastpc) {
416 if (dest > jmptarget)
417 jmptarget = dest; /* update 'jmptarget' */
418 }
419 break;
420 }
421 default:
422 if (testAMode(op) && reg == a) /* any instruction that set A */
423 setreg = filterpc(pc, jmptarget);
424 break;
425 }
426 }
427 return setreg;
428}
429
430
431static const char *getobjname (Proto *p, int lastpc, int reg,
432 const char **name) {
433 int pc;
434 *name = luaF_getlocalname(p, reg + 1, lastpc);
435 if (*name) /* is a local? */
436 return "local";
437 /* else try symbolic execution */
438 pc = findsetreg(p, lastpc, reg);
439 if (pc != -1) { /* could find instruction? */
440 Instruction i = p->code[pc];
441 OpCode op = GET_OPCODE(i);
442 switch (op) {
443 case OP_MOVE: {
444 int b = GETARG_B(i); /* move from 'b' to 'a' */
445 if (b < GETARG_A(i))
446 return getobjname(p, pc, b, name); /* get name for 'b' */
447 break;
448 }
449 case OP_GETTABUP:
450 case OP_GETTABLE: {
451 int k = GETARG_C(i); /* key index */
452 int t = GETARG_B(i); /* table index */
453 const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
454 ? luaF_getlocalname(p, t + 1, pc)
455 : upvalname(p, t);
456 kname(p, pc, k, name);
457 return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
458 }
459 case OP_GETUPVAL: {
460 *name = upvalname(p, GETARG_B(i));
461 return "upvalue";
462 }
463 case OP_LOADK:
464 case OP_LOADKX: {
465 int b = (op == OP_LOADK) ? GETARG_Bx(i)
466 : GETARG_Ax(p->code[pc + 1]);
467 if (ttisstring(&p->k[b])) {
468 *name = svalue(&p->k[b]);
469 return "constant";
470 }
471 break;
472 }
473 case OP_SELF: {
474 int k = GETARG_C(i); /* key index */
475 kname(p, pc, k, name);
476 return "method";
477 }
478 default: break; /* go through to return NULL */
479 }
480 }
481 return NULL; /* could not find reasonable name */
482}
483
484
485/*
486** Try to find a name for a function based on the code that called it.
487** (Only works when function was called by a Lua function.)
488** Returns what the name is (e.g., "for iterator", "method",
489** "metamethod") and sets '*name' to point to the name.
490*/
491static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
492 const char **name) {
493 TMS tm = (TMS)0; /* (initial value avoids warnings) */
494 Proto *p = ci_func(ci)->p; /* calling function */
495 int pc = currentpc(ci); /* calling instruction index */
496 Instruction i = p->code[pc]; /* calling instruction */
497 if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
498 *name = "?";
499 return "hook";
500 }
501 switch (GET_OPCODE(i)) {
502 case OP_CALL:
503 case OP_TAILCALL:
504 return getobjname(p, pc, GETARG_A(i), name); /* get function name */
505 case OP_TFORCALL: { /* for iterator */
506 *name = "for iterator";
507 return "for iterator";
508 }
509 /* other instructions can do calls through metamethods */
510 case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
511 tm = TM_INDEX;
512 break;
513 case OP_SETTABUP: case OP_SETTABLE:
514 tm = TM_NEWINDEX;
515 break;
516 case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD:
517 case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND:
518 case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: {
519 int offset = cast_int(GET_OPCODE(i)) - cast_int(OP_ADD); /* ORDER OP */
520 tm = cast(TMS, offset + cast_int(TM_ADD)); /* ORDER TM */
521 break;
522 }
523 case OP_UNM: tm = TM_UNM; break;
524 case OP_BNOT: tm = TM_BNOT; break;
525 case OP_LEN: tm = TM_LEN; break;
526 case OP_CONCAT: tm = TM_CONCAT; break;
527 case OP_EQ: tm = TM_EQ; break;
528 case OP_LT: tm = TM_LT; break;
529 case OP_LE: tm = TM_LE; break;
530 default:
531 return NULL; /* cannot find a reasonable name */
532 }
533 *name = getstr(G(L)->tmname[tm]);
534 return "metamethod";
535}
536
537/* }====================================================== */
538
539
540
541/*
542** The subtraction of two potentially unrelated pointers is
543** not ISO C, but it should not crash a program; the subsequent
544** checks are ISO C and ensure a correct result.
545*/
546static int isinstack (CallInfo *ci, const TValue *o) {
547 ptrdiff_t i = o - ci->u.l.base;
548 return (0 <= i && i < (ci->top - ci->u.l.base) && ci->u.l.base + i == o);
549}
550
551
552/*
553** Checks whether value 'o' came from an upvalue. (That can only happen
554** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on
555** upvalues.)
556*/
557static const char *getupvalname (CallInfo *ci, const TValue *o,
558 const char **name) {
559 LClosure *c = ci_func(ci);
560 int i;
561 for (i = 0; i < c->nupvalues; i++) {
562 if (c->upvals[i]->v == o) {
563 *name = upvalname(c->p, i);
564 return "upvalue";
565 }
566 }
567 return NULL;
568}
569
570
571static const char *varinfo (lua_State *L, const TValue *o) {
572 const char *name = NULL; /* to avoid warnings */
573 CallInfo *ci = L->ci;
574 const char *kind = NULL;
575 if (isLua(ci)) {
576 kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
577 if (!kind && isinstack(ci, o)) /* no? try a register */
578 kind = getobjname(ci_func(ci)->p, currentpc(ci),
579 cast_int(o - ci->u.l.base), &name);
580 }
581 return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
582}
583
584
585l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
586 const char *t = luaT_objtypename(L, o);
587 luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
588}
589
590
591l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) {
592 if (ttisstring(p1) || cvt2str(p1)) p1 = p2;
593 luaG_typeerror(L, p1, "concatenate");
594}
595
596
597l_noret luaG_opinterror (lua_State *L, const TValue *p1,
598 const TValue *p2, const char *msg) {
599 lua_Number temp;
600 if (!tonumber(p1, &temp)) /* first operand is wrong? */
601 p2 = p1; /* now second is wrong */
602 luaG_typeerror(L, p2, msg);
603}
604
605
606/*
607** Error when both values are convertible to numbers, but not to integers
608*/
609l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
610 lua_Integer temp;
611 if (!tointeger(p1, &temp))
612 p2 = p1;
613 luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2));
614}
615
616
617l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
618 const char *t1 = luaT_objtypename(L, p1);
619 const char *t2 = luaT_objtypename(L, p2);
620 if (strcmp(t1, t2) == 0)
621 luaG_runerror(L, "attempt to compare two %s values", t1);
622 else
623 luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
624}
625
626
627/* add src:line information to 'msg' */
628const char *luaG_addinfo (lua_State *L, const char *msg, TString *src,
629 int line) {
630 char buff[LUA_IDSIZE];
631 if (src)
632 luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
633 else { /* no source available; use "?" instead */
634 buff[0] = '?'; buff[1] = '\0';
635 }
636 return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
637}
638
639
640l_noret luaG_errormsg (lua_State *L) {
641 if (L->errfunc != 0) { /* is there an error handling function? */
642 StkId errfunc = restorestack(L, L->errfunc);
643 setobjs2s(L, L->top, L->top - 1); /* move argument */
644 setobjs2s(L, L->top - 1, errfunc); /* push function */
645 L->top++; /* assume EXTRA_STACK */
646 luaD_callnoyield(L, L->top - 2, 1); /* call it */
647 }
648 luaD_throw(L, LUA_ERRRUN);
649}
650
651
652l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
653 CallInfo *ci = L->ci;
654 const char *msg;
655 va_list argp;
656 luaC_checkGC(L); /* error message uses memory */
657 va_start(argp, fmt);
658 msg = luaO_pushvfstring(L, fmt, argp); /* format message */
659 va_end(argp);
660 if (isLua(ci)) /* if Lua function, add source:line information */
661 luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci));
662 luaG_errormsg(L);
663}
664
665
666void luaG_traceexec (lua_State *L) {
667 CallInfo *ci = L->ci;
668 lu_byte mask = L->hookmask;
669 int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT));
670 if (counthook)
671 resethookcount(L); /* reset count */
672 else if (!(mask & LUA_MASKLINE))
673 return; /* no line hook and count != 0; nothing to be done */
674 if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */
675 ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
676 return; /* do not call hook again (VM yielded, so it did not move) */
677 }
678 if (counthook)
679 luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
680 if (mask & LUA_MASKLINE) {
681 Proto *p = ci_func(ci)->p;
682 int npc = pcRel(ci->u.l.savedpc, p);
683 int newline = getfuncline(p, npc);
684 if (npc == 0 || /* call linehook when enter a new function, */
685 ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
686 newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */
687 luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */
688 }
689 L->oldpc = ci->u.l.savedpc;
690 if (L->status == LUA_YIELD) { /* did hook yield? */
691 if (counthook)
692 L->hookcount = 1; /* undo decrement to zero */
693 ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
694 ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
695 ci->func = L->top - 1; /* protect stack below results */
696 luaD_throw(L, LUA_YIELD);
697 }
698}
699
diff --git a/src/lua-5.3/ldebug.h b/src/lua-5.3/ldebug.h
new file mode 100644
index 0000000..8cea0ee
--- /dev/null
+++ b/src/lua-5.3/ldebug.h
@@ -0,0 +1,39 @@
1/*
2** $Id: ldebug.h,v 2.14.1.1 2017/04/19 17:20:42 roberto Exp $
3** Auxiliary functions from Debug Interface module
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ldebug_h
8#define ldebug_h
9
10
11#include "lstate.h"
12
13
14#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
15
16#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1)
17
18#define resethookcount(L) (L->hookcount = L->basehookcount)
19
20
21LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
22 const char *opname);
23LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1,
24 const TValue *p2);
25LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1,
26 const TValue *p2,
27 const char *msg);
28LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1,
29 const TValue *p2);
30LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
31 const TValue *p2);
32LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
33LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg,
34 TString *src, int line);
35LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
36LUAI_FUNC void luaG_traceexec (lua_State *L);
37
38
39#endif
diff --git a/src/lua-5.3/ldo.c b/src/lua-5.3/ldo.c
new file mode 100644
index 0000000..316e45c
--- /dev/null
+++ b/src/lua-5.3/ldo.c
@@ -0,0 +1,802 @@
1/*
2** $Id: ldo.c,v 2.157.1.1 2017/04/19 17:20:42 roberto Exp $
3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h
5*/
6
7#define ldo_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <setjmp.h>
14#include <stdlib.h>
15#include <string.h>
16
17#include "lua.h"
18
19#include "lapi.h"
20#include "ldebug.h"
21#include "ldo.h"
22#include "lfunc.h"
23#include "lgc.h"
24#include "lmem.h"
25#include "lobject.h"
26#include "lopcodes.h"
27#include "lparser.h"
28#include "lstate.h"
29#include "lstring.h"
30#include "ltable.h"
31#include "ltm.h"
32#include "lundump.h"
33#include "lvm.h"
34#include "lzio.h"
35
36
37
38#define errorstatus(s) ((s) > LUA_YIELD)
39
40
41/*
42** {======================================================
43** Error-recovery functions
44** =======================================================
45*/
46
47/*
48** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
49** default, Lua handles errors with exceptions when compiling as
50** C++ code, with _longjmp/_setjmp when asked to use them, and with
51** longjmp/setjmp otherwise.
52*/
53#if !defined(LUAI_THROW) /* { */
54
55#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* { */
56
57/* C++ exceptions */
58#define LUAI_THROW(L,c) throw(c)
59#define LUAI_TRY(L,c,a) \
60 try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; }
61#define luai_jmpbuf int /* dummy variable */
62
63#elif defined(LUA_USE_POSIX) /* }{ */
64
65/* in POSIX, try _longjmp/_setjmp (more efficient) */
66#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
67#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
68#define luai_jmpbuf jmp_buf
69
70#else /* }{ */
71
72/* ISO C handling with long jumps */
73#define LUAI_THROW(L,c) longjmp((c)->b, 1)
74#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
75#define luai_jmpbuf jmp_buf
76
77#endif /* } */
78
79#endif /* } */
80
81
82
83/* chain list of long jump buffers */
84struct lua_longjmp {
85 struct lua_longjmp *previous;
86 luai_jmpbuf b;
87 volatile int status; /* error code */
88};
89
90
91static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
92 switch (errcode) {
93 case LUA_ERRMEM: { /* memory error? */
94 setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
95 break;
96 }
97 case LUA_ERRERR: {
98 setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
99 break;
100 }
101 default: {
102 setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
103 break;
104 }
105 }
106 L->top = oldtop + 1;
107}
108
109
110l_noret luaD_throw (lua_State *L, int errcode) {
111 if (L->errorJmp) { /* thread has an error handler? */
112 L->errorJmp->status = errcode; /* set status */
113 LUAI_THROW(L, L->errorJmp); /* jump to it */
114 }
115 else { /* thread has no error handler */
116 global_State *g = G(L);
117 L->status = cast_byte(errcode); /* mark it as dead */
118 if (g->mainthread->errorJmp) { /* main thread has a handler? */
119 setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */
120 luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
121 }
122 else { /* no handler at all; abort */
123 if (g->panic) { /* panic function? */
124 seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */
125 if (L->ci->top < L->top)
126 L->ci->top = L->top; /* pushing msg. can break this invariant */
127 lua_unlock(L);
128 g->panic(L); /* call panic function (last chance to jump out) */
129 }
130 abort();
131 }
132 }
133}
134
135
136int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
137 unsigned short oldnCcalls = L->nCcalls;
138 struct lua_longjmp lj;
139 lj.status = LUA_OK;
140 lj.previous = L->errorJmp; /* chain new error handler */
141 L->errorJmp = &lj;
142 LUAI_TRY(L, &lj,
143 (*f)(L, ud);
144 );
145 L->errorJmp = lj.previous; /* restore old error handler */
146 L->nCcalls = oldnCcalls;
147 return lj.status;
148}
149
150/* }====================================================== */
151
152
153/*
154** {==================================================================
155** Stack reallocation
156** ===================================================================
157*/
158static void correctstack (lua_State *L, TValue *oldstack) {
159 CallInfo *ci;
160 UpVal *up;
161 L->top = (L->top - oldstack) + L->stack;
162 for (up = L->openupval; up != NULL; up = up->u.open.next)
163 up->v = (up->v - oldstack) + L->stack;
164 for (ci = L->ci; ci != NULL; ci = ci->previous) {
165 ci->top = (ci->top - oldstack) + L->stack;
166 ci->func = (ci->func - oldstack) + L->stack;
167 if (isLua(ci))
168 ci->u.l.base = (ci->u.l.base - oldstack) + L->stack;
169 }
170}
171
172
173/* some space for error handling */
174#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
175
176
177void luaD_reallocstack (lua_State *L, int newsize) {
178 TValue *oldstack = L->stack;
179 int lim = L->stacksize;
180 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
181 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
182 luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue);
183 for (; lim < newsize; lim++)
184 setnilvalue(L->stack + lim); /* erase new segment */
185 L->stacksize = newsize;
186 L->stack_last = L->stack + newsize - EXTRA_STACK;
187 correctstack(L, oldstack);
188}
189
190
191void luaD_growstack (lua_State *L, int n) {
192 int size = L->stacksize;
193 if (size > LUAI_MAXSTACK) /* error after extra size? */
194 luaD_throw(L, LUA_ERRERR);
195 else {
196 int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK;
197 int newsize = 2 * size;
198 if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK;
199 if (newsize < needed) newsize = needed;
200 if (newsize > LUAI_MAXSTACK) { /* stack overflow? */
201 luaD_reallocstack(L, ERRORSTACKSIZE);
202 luaG_runerror(L, "stack overflow");
203 }
204 else
205 luaD_reallocstack(L, newsize);
206 }
207}
208
209
210static int stackinuse (lua_State *L) {
211 CallInfo *ci;
212 StkId lim = L->top;
213 for (ci = L->ci; ci != NULL; ci = ci->previous) {
214 if (lim < ci->top) lim = ci->top;
215 }
216 lua_assert(lim <= L->stack_last);
217 return cast_int(lim - L->stack) + 1; /* part of stack in use */
218}
219
220
221void luaD_shrinkstack (lua_State *L) {
222 int inuse = stackinuse(L);
223 int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
224 if (goodsize > LUAI_MAXSTACK)
225 goodsize = LUAI_MAXSTACK; /* respect stack limit */
226 if (L->stacksize > LUAI_MAXSTACK) /* had been handling stack overflow? */
227 luaE_freeCI(L); /* free all CIs (list grew because of an error) */
228 else
229 luaE_shrinkCI(L); /* shrink list */
230 /* if thread is currently not handling a stack overflow and its
231 good size is smaller than current size, shrink its stack */
232 if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) &&
233 goodsize < L->stacksize)
234 luaD_reallocstack(L, goodsize);
235 else /* don't change stack */
236 condmovestack(L,{},{}); /* (change only for debugging) */
237}
238
239
240void luaD_inctop (lua_State *L) {
241 luaD_checkstack(L, 1);
242 L->top++;
243}
244
245/* }================================================================== */
246
247
248/*
249** Call a hook for the given event. Make sure there is a hook to be
250** called. (Both 'L->hook' and 'L->hookmask', which triggers this
251** function, can be changed asynchronously by signals.)
252*/
253void luaD_hook (lua_State *L, int event, int line) {
254 lua_Hook hook = L->hook;
255 if (hook && L->allowhook) { /* make sure there is a hook */
256 CallInfo *ci = L->ci;
257 ptrdiff_t top = savestack(L, L->top);
258 ptrdiff_t ci_top = savestack(L, ci->top);
259 lua_Debug ar;
260 ar.event = event;
261 ar.currentline = line;
262 ar.i_ci = ci;
263 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
264 ci->top = L->top + LUA_MINSTACK;
265 lua_assert(ci->top <= L->stack_last);
266 L->allowhook = 0; /* cannot call hooks inside a hook */
267 ci->callstatus |= CIST_HOOKED;
268 lua_unlock(L);
269 (*hook)(L, &ar);
270 lua_lock(L);
271 lua_assert(!L->allowhook);
272 L->allowhook = 1;
273 ci->top = restorestack(L, ci_top);
274 L->top = restorestack(L, top);
275 ci->callstatus &= ~CIST_HOOKED;
276 }
277}
278
279
280static void callhook (lua_State *L, CallInfo *ci) {
281 int hook = LUA_HOOKCALL;
282 ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
283 if (isLua(ci->previous) &&
284 GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
285 ci->callstatus |= CIST_TAIL;
286 hook = LUA_HOOKTAILCALL;
287 }
288 luaD_hook(L, hook, -1);
289 ci->u.l.savedpc--; /* correct 'pc' */
290}
291
292
293static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
294 int i;
295 int nfixargs = p->numparams;
296 StkId base, fixed;
297 /* move fixed parameters to final position */
298 fixed = L->top - actual; /* first fixed argument */
299 base = L->top; /* final position of first argument */
300 for (i = 0; i < nfixargs && i < actual; i++) {
301 setobjs2s(L, L->top++, fixed + i);
302 setnilvalue(fixed + i); /* erase original copy (for GC) */
303 }
304 for (; i < nfixargs; i++)
305 setnilvalue(L->top++); /* complete missing arguments */
306 return base;
307}
308
309
310/*
311** Check whether __call metafield of 'func' is a function. If so, put
312** it in stack below original 'func' so that 'luaD_precall' can call
313** it. Raise an error if __call metafield is not a function.
314*/
315static void tryfuncTM (lua_State *L, StkId func) {
316 const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
317 StkId p;
318 if (!ttisfunction(tm))
319 luaG_typeerror(L, func, "call");
320 /* Open a hole inside the stack at 'func' */
321 for (p = L->top; p > func; p--)
322 setobjs2s(L, p, p-1);
323 L->top++; /* slot ensured by caller */
324 setobj2s(L, func, tm); /* tag method is the new function to be called */
325}
326
327
328/*
329** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'.
330** Handle most typical cases (zero results for commands, one result for
331** expressions, multiple results for tail calls/single parameters)
332** separated.
333*/
334static int moveresults (lua_State *L, const TValue *firstResult, StkId res,
335 int nres, int wanted) {
336 switch (wanted) { /* handle typical cases separately */
337 case 0: break; /* nothing to move */
338 case 1: { /* one result needed */
339 if (nres == 0) /* no results? */
340 firstResult = luaO_nilobject; /* adjust with nil */
341 setobjs2s(L, res, firstResult); /* move it to proper place */
342 break;
343 }
344 case LUA_MULTRET: {
345 int i;
346 for (i = 0; i < nres; i++) /* move all results to correct place */
347 setobjs2s(L, res + i, firstResult + i);
348 L->top = res + nres;
349 return 0; /* wanted == LUA_MULTRET */
350 }
351 default: {
352 int i;
353 if (wanted <= nres) { /* enough results? */
354 for (i = 0; i < wanted; i++) /* move wanted results to correct place */
355 setobjs2s(L, res + i, firstResult + i);
356 }
357 else { /* not enough results; use all of them plus nils */
358 for (i = 0; i < nres; i++) /* move all results to correct place */
359 setobjs2s(L, res + i, firstResult + i);
360 for (; i < wanted; i++) /* complete wanted number of results */
361 setnilvalue(res + i);
362 }
363 break;
364 }
365 }
366 L->top = res + wanted; /* top points after the last result */
367 return 1;
368}
369
370
371/*
372** Finishes a function call: calls hook if necessary, removes CallInfo,
373** moves current number of results to proper place; returns 0 iff call
374** wanted multiple (variable number of) results.
375*/
376int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
377 StkId res;
378 int wanted = ci->nresults;
379 if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
380 if (L->hookmask & LUA_MASKRET) {
381 ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
382 luaD_hook(L, LUA_HOOKRET, -1);
383 firstResult = restorestack(L, fr);
384 }
385 L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
386 }
387 res = ci->func; /* res == final position of 1st result */
388 L->ci = ci->previous; /* back to caller */
389 /* move results to proper place */
390 return moveresults(L, firstResult, res, nres, wanted);
391}
392
393
394
395#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
396
397
398/* macro to check stack size, preserving 'p' */
399#define checkstackp(L,n,p) \
400 luaD_checkstackaux(L, n, \
401 ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
402 luaC_checkGC(L), /* stack grow uses memory */ \
403 p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
404
405
406/*
407** Prepares a function call: checks the stack, creates a new CallInfo
408** entry, fills in the relevant information, calls hook if needed.
409** If function is a C function, does the call, too. (Otherwise, leave
410** the execution ('luaV_execute') to the caller, to allow stackless
411** calls.) Returns true iff function has been executed (C function).
412*/
413int luaD_precall (lua_State *L, StkId func, int nresults) {
414 lua_CFunction f;
415 CallInfo *ci;
416 switch (ttype(func)) {
417 case LUA_TCCL: /* C closure */
418 f = clCvalue(func)->f;
419 goto Cfunc;
420 case LUA_TLCF: /* light C function */
421 f = fvalue(func);
422 Cfunc: {
423 int n; /* number of returns */
424 checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
425 ci = next_ci(L); /* now 'enter' new function */
426 ci->nresults = nresults;
427 ci->func = func;
428 ci->top = L->top + LUA_MINSTACK;
429 lua_assert(ci->top <= L->stack_last);
430 ci->callstatus = 0;
431 if (L->hookmask & LUA_MASKCALL)
432 luaD_hook(L, LUA_HOOKCALL, -1);
433 lua_unlock(L);
434 n = (*f)(L); /* do the actual call */
435 lua_lock(L);
436 api_checknelems(L, n);
437 luaD_poscall(L, ci, L->top - n, n);
438 return 1;
439 }
440 case LUA_TLCL: { /* Lua function: prepare its call */
441 StkId base;
442 Proto *p = clLvalue(func)->p;
443 int n = cast_int(L->top - func) - 1; /* number of real arguments */
444 int fsize = p->maxstacksize; /* frame size */
445 checkstackp(L, fsize, func);
446 if (p->is_vararg)
447 base = adjust_varargs(L, p, n);
448 else { /* non vararg function */
449 for (; n < p->numparams; n++)
450 setnilvalue(L->top++); /* complete missing arguments */
451 base = func + 1;
452 }
453 ci = next_ci(L); /* now 'enter' new function */
454 ci->nresults = nresults;
455 ci->func = func;
456 ci->u.l.base = base;
457 L->top = ci->top = base + fsize;
458 lua_assert(ci->top <= L->stack_last);
459 ci->u.l.savedpc = p->code; /* starting point */
460 ci->callstatus = CIST_LUA;
461 if (L->hookmask & LUA_MASKCALL)
462 callhook(L, ci);
463 return 0;
464 }
465 default: { /* not a function */
466 checkstackp(L, 1, func); /* ensure space for metamethod */
467 tryfuncTM(L, func); /* try to get '__call' metamethod */
468 return luaD_precall(L, func, nresults); /* now it must be a function */
469 }
470 }
471}
472
473
474/*
475** Check appropriate error for stack overflow ("regular" overflow or
476** overflow while handling stack overflow). If 'nCalls' is larger than
477** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but
478** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to
479** allow overflow handling to work)
480*/
481static void stackerror (lua_State *L) {
482 if (L->nCcalls == LUAI_MAXCCALLS)
483 luaG_runerror(L, "C stack overflow");
484 else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
485 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
486}
487
488
489/*
490** Call a function (C or Lua). The function to be called is at *func.
491** The arguments are on the stack, right after the function.
492** When returns, all the results are on the stack, starting at the original
493** function position.
494*/
495void luaD_call (lua_State *L, StkId func, int nResults) {
496 if (++L->nCcalls >= LUAI_MAXCCALLS)
497 stackerror(L);
498 if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
499 luaV_execute(L); /* call it */
500 L->nCcalls--;
501}
502
503
504/*
505** Similar to 'luaD_call', but does not allow yields during the call
506*/
507void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
508 L->nny++;
509 luaD_call(L, func, nResults);
510 L->nny--;
511}
512
513
514/*
515** Completes the execution of an interrupted C function, calling its
516** continuation function.
517*/
518static void finishCcall (lua_State *L, int status) {
519 CallInfo *ci = L->ci;
520 int n;
521 /* must have a continuation and must be able to call it */
522 lua_assert(ci->u.c.k != NULL && L->nny == 0);
523 /* error status can only happen in a protected call */
524 lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
525 if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
526 ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */
527 L->errfunc = ci->u.c.old_errfunc; /* with the same error function */
528 }
529 /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
530 handled */
531 adjustresults(L, ci->nresults);
532 lua_unlock(L);
533 n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */
534 lua_lock(L);
535 api_checknelems(L, n);
536 luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */
537}
538
539
540/*
541** Executes "full continuation" (everything in the stack) of a
542** previously interrupted coroutine until the stack is empty (or another
543** interruption long-jumps out of the loop). If the coroutine is
544** recovering from an error, 'ud' points to the error status, which must
545** be passed to the first continuation function (otherwise the default
546** status is LUA_YIELD).
547*/
548static void unroll (lua_State *L, void *ud) {
549 if (ud != NULL) /* error status? */
550 finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */
551 while (L->ci != &L->base_ci) { /* something in the stack */
552 if (!isLua(L->ci)) /* C function? */
553 finishCcall(L, LUA_YIELD); /* complete its execution */
554 else { /* Lua function */
555 luaV_finishOp(L); /* finish interrupted instruction */
556 luaV_execute(L); /* execute down to higher C 'boundary' */
557 }
558 }
559}
560
561
562/*
563** Try to find a suspended protected call (a "recover point") for the
564** given thread.
565*/
566static CallInfo *findpcall (lua_State *L) {
567 CallInfo *ci;
568 for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */
569 if (ci->callstatus & CIST_YPCALL)
570 return ci;
571 }
572 return NULL; /* no pending pcall */
573}
574
575
576/*
577** Recovers from an error in a coroutine. Finds a recover point (if
578** there is one) and completes the execution of the interrupted
579** 'luaD_pcall'. If there is no recover point, returns zero.
580*/
581static int recover (lua_State *L, int status) {
582 StkId oldtop;
583 CallInfo *ci = findpcall(L);
584 if (ci == NULL) return 0; /* no recovery point */
585 /* "finish" luaD_pcall */
586 oldtop = restorestack(L, ci->extra);
587 luaF_close(L, oldtop);
588 seterrorobj(L, status, oldtop);
589 L->ci = ci;
590 L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
591 L->nny = 0; /* should be zero to be yieldable */
592 luaD_shrinkstack(L);
593 L->errfunc = ci->u.c.old_errfunc;
594 return 1; /* continue running the coroutine */
595}
596
597
598/*
599** Signal an error in the call to 'lua_resume', not in the execution
600** of the coroutine itself. (Such errors should not be handled by any
601** coroutine error handler and should not kill the coroutine.)
602*/
603static int resume_error (lua_State *L, const char *msg, int narg) {
604 L->top -= narg; /* remove args from the stack */
605 setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
606 api_incr_top(L);
607 lua_unlock(L);
608 return LUA_ERRRUN;
609}
610
611
612/*
613** Do the work for 'lua_resume' in protected mode. Most of the work
614** depends on the status of the coroutine: initial state, suspended
615** inside a hook, or regularly suspended (optionally with a continuation
616** function), plus erroneous cases: non-suspended coroutine or dead
617** coroutine.
618*/
619static void resume (lua_State *L, void *ud) {
620 int n = *(cast(int*, ud)); /* number of arguments */
621 StkId firstArg = L->top - n; /* first argument */
622 CallInfo *ci = L->ci;
623 if (L->status == LUA_OK) { /* starting a coroutine? */
624 if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
625 luaV_execute(L); /* call it */
626 }
627 else { /* resuming from previous yield */
628 lua_assert(L->status == LUA_YIELD);
629 L->status = LUA_OK; /* mark that it is running (again) */
630 ci->func = restorestack(L, ci->extra);
631 if (isLua(ci)) /* yielded inside a hook? */
632 luaV_execute(L); /* just continue running Lua code */
633 else { /* 'common' yield */
634 if (ci->u.c.k != NULL) { /* does it have a continuation function? */
635 lua_unlock(L);
636 n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
637 lua_lock(L);
638 api_checknelems(L, n);
639 firstArg = L->top - n; /* yield results come from continuation */
640 }
641 luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */
642 }
643 unroll(L, NULL); /* run continuation */
644 }
645}
646
647
648LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
649 int status;
650 unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */
651 lua_lock(L);
652 if (L->status == LUA_OK) { /* may be starting a coroutine */
653 if (L->ci != &L->base_ci) /* not in base level? */
654 return resume_error(L, "cannot resume non-suspended coroutine", nargs);
655 }
656 else if (L->status != LUA_YIELD)
657 return resume_error(L, "cannot resume dead coroutine", nargs);
658 L->nCcalls = (from) ? from->nCcalls + 1 : 1;
659 if (L->nCcalls >= LUAI_MAXCCALLS)
660 return resume_error(L, "C stack overflow", nargs);
661 luai_userstateresume(L, nargs);
662 L->nny = 0; /* allow yields */
663 api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
664 status = luaD_rawrunprotected(L, resume, &nargs);
665 if (status == -1) /* error calling 'lua_resume'? */
666 status = LUA_ERRRUN;
667 else { /* continue running after recoverable errors */
668 while (errorstatus(status) && recover(L, status)) {
669 /* unroll continuation */
670 status = luaD_rawrunprotected(L, unroll, &status);
671 }
672 if (errorstatus(status)) { /* unrecoverable error? */
673 L->status = cast_byte(status); /* mark thread as 'dead' */
674 seterrorobj(L, status, L->top); /* push error message */
675 L->ci->top = L->top;
676 }
677 else lua_assert(status == L->status); /* normal end or yield */
678 }
679 L->nny = oldnny; /* restore 'nny' */
680 L->nCcalls--;
681 lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
682 lua_unlock(L);
683 return status;
684}
685
686
687LUA_API int lua_isyieldable (lua_State *L) {
688 return (L->nny == 0);
689}
690
691
692LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
693 lua_KFunction k) {
694 CallInfo *ci = L->ci;
695 luai_userstateyield(L, nresults);
696 lua_lock(L);
697 api_checknelems(L, nresults);
698 if (L->nny > 0) {
699 if (L != G(L)->mainthread)
700 luaG_runerror(L, "attempt to yield across a C-call boundary");
701 else
702 luaG_runerror(L, "attempt to yield from outside a coroutine");
703 }
704 L->status = LUA_YIELD;
705 ci->extra = savestack(L, ci->func); /* save current 'func' */
706 if (isLua(ci)) { /* inside a hook? */
707 api_check(L, k == NULL, "hooks cannot continue after yielding");
708 }
709 else {
710 if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
711 ci->u.c.ctx = ctx; /* save context */
712 ci->func = L->top - nresults - 1; /* protect stack below results */
713 luaD_throw(L, LUA_YIELD);
714 }
715 lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */
716 lua_unlock(L);
717 return 0; /* return to 'luaD_hook' */
718}
719
720
721int luaD_pcall (lua_State *L, Pfunc func, void *u,
722 ptrdiff_t old_top, ptrdiff_t ef) {
723 int status;
724 CallInfo *old_ci = L->ci;
725 lu_byte old_allowhooks = L->allowhook;
726 unsigned short old_nny = L->nny;
727 ptrdiff_t old_errfunc = L->errfunc;
728 L->errfunc = ef;
729 status = luaD_rawrunprotected(L, func, u);
730 if (status != LUA_OK) { /* an error occurred? */
731 StkId oldtop = restorestack(L, old_top);
732 luaF_close(L, oldtop); /* close possible pending closures */
733 seterrorobj(L, status, oldtop);
734 L->ci = old_ci;
735 L->allowhook = old_allowhooks;
736 L->nny = old_nny;
737 luaD_shrinkstack(L);
738 }
739 L->errfunc = old_errfunc;
740 return status;
741}
742
743
744
745/*
746** Execute a protected parser.
747*/
748struct SParser { /* data to 'f_parser' */
749 ZIO *z;
750 Mbuffer buff; /* dynamic structure used by the scanner */
751 Dyndata dyd; /* dynamic structures used by the parser */
752 const char *mode;
753 const char *name;
754};
755
756
757static void checkmode (lua_State *L, const char *mode, const char *x) {
758 if (mode && strchr(mode, x[0]) == NULL) {
759 luaO_pushfstring(L,
760 "attempt to load a %s chunk (mode is '%s')", x, mode);
761 luaD_throw(L, LUA_ERRSYNTAX);
762 }
763}
764
765
766static void f_parser (lua_State *L, void *ud) {
767 LClosure *cl;
768 struct SParser *p = cast(struct SParser *, ud);
769 int c = zgetc(p->z); /* read first character */
770 if (c == LUA_SIGNATURE[0]) {
771 checkmode(L, p->mode, "binary");
772 cl = luaU_undump(L, p->z, p->name);
773 }
774 else {
775 checkmode(L, p->mode, "text");
776 cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
777 }
778 lua_assert(cl->nupvalues == cl->p->sizeupvalues);
779 luaF_initupvals(L, cl);
780}
781
782
783int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
784 const char *mode) {
785 struct SParser p;
786 int status;
787 L->nny++; /* cannot yield during parsing */
788 p.z = z; p.name = name; p.mode = mode;
789 p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
790 p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
791 p.dyd.label.arr = NULL; p.dyd.label.size = 0;
792 luaZ_initbuffer(L, &p.buff);
793 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
794 luaZ_freebuffer(L, &p.buff);
795 luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
796 luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
797 luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);
798 L->nny--;
799 return status;
800}
801
802
diff --git a/src/lua-5.3/ldo.h b/src/lua-5.3/ldo.h
new file mode 100644
index 0000000..3b2983a
--- /dev/null
+++ b/src/lua-5.3/ldo.h
@@ -0,0 +1,58 @@
1/*
2** $Id: ldo.h,v 2.29.1.1 2017/04/19 17:20:42 roberto Exp $
3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ldo_h
8#define ldo_h
9
10
11#include "lobject.h"
12#include "lstate.h"
13#include "lzio.h"
14
15
16/*
17** Macro to check stack size and grow stack if needed. Parameters
18** 'pre'/'pos' allow the macro to preserve a pointer into the
19** stack across reallocations, doing the work only when needed.
20** 'condmovestack' is used in heavy tests to force a stack reallocation
21** at every check.
22*/
23#define luaD_checkstackaux(L,n,pre,pos) \
24 if (L->stack_last - L->top <= (n)) \
25 { pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); }
26
27/* In general, 'pre'/'pos' are empty (nothing to save) */
28#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0)
29
30
31
32#define savestack(L,p) ((char *)(p) - (char *)L->stack)
33#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
34
35
36/* type of protected functions, to be ran by 'runprotected' */
37typedef void (*Pfunc) (lua_State *L, void *ud);
38
39LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
40 const char *mode);
41LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
42LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
43LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
44LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
45LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
46 ptrdiff_t oldtop, ptrdiff_t ef);
47LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult,
48 int nres);
49LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
50LUAI_FUNC void luaD_growstack (lua_State *L, int n);
51LUAI_FUNC void luaD_shrinkstack (lua_State *L);
52LUAI_FUNC void luaD_inctop (lua_State *L);
53
54LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
55LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
56
57#endif
58
diff --git a/src/lua-5.3/ldump.c b/src/lua-5.3/ldump.c
new file mode 100644
index 0000000..f025aca
--- /dev/null
+++ b/src/lua-5.3/ldump.c
@@ -0,0 +1,215 @@
1/*
2** $Id: ldump.c,v 2.37.1.1 2017/04/19 17:20:42 roberto Exp $
3** save precompiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#define ldump_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <stddef.h>
14
15#include "lua.h"
16
17#include "lobject.h"
18#include "lstate.h"
19#include "lundump.h"
20
21
22typedef struct {
23 lua_State *L;
24 lua_Writer writer;
25 void *data;
26 int strip;
27 int status;
28} DumpState;
29
30
31/*
32** All high-level dumps go through DumpVector; you can change it to
33** change the endianness of the result
34*/
35#define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D)
36
37#define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D)
38
39
40static void DumpBlock (const void *b, size_t size, DumpState *D) {
41 if (D->status == 0 && size > 0) {
42 lua_unlock(D->L);
43 D->status = (*D->writer)(D->L, b, size, D->data);
44 lua_lock(D->L);
45 }
46}
47
48
49#define DumpVar(x,D) DumpVector(&x,1,D)
50
51
52static void DumpByte (int y, DumpState *D) {
53 lu_byte x = (lu_byte)y;
54 DumpVar(x, D);
55}
56
57
58static void DumpInt (int x, DumpState *D) {
59 DumpVar(x, D);
60}
61
62
63static void DumpNumber (lua_Number x, DumpState *D) {
64 DumpVar(x, D);
65}
66
67
68static void DumpInteger (lua_Integer x, DumpState *D) {
69 DumpVar(x, D);
70}
71
72
73static void DumpString (const TString *s, DumpState *D) {
74 if (s == NULL)
75 DumpByte(0, D);
76 else {
77 size_t size = tsslen(s) + 1; /* include trailing '\0' */
78 const char *str = getstr(s);
79 if (size < 0xFF)
80 DumpByte(cast_int(size), D);
81 else {
82 DumpByte(0xFF, D);
83 DumpVar(size, D);
84 }
85 DumpVector(str, size - 1, D); /* no need to save '\0' */
86 }
87}
88
89
90static void DumpCode (const Proto *f, DumpState *D) {
91 DumpInt(f->sizecode, D);
92 DumpVector(f->code, f->sizecode, D);
93}
94
95
96static void DumpFunction(const Proto *f, TString *psource, DumpState *D);
97
98static void DumpConstants (const Proto *f, DumpState *D) {
99 int i;
100 int n = f->sizek;
101 DumpInt(n, D);
102 for (i = 0; i < n; i++) {
103 const TValue *o = &f->k[i];
104 DumpByte(ttype(o), D);
105 switch (ttype(o)) {
106 case LUA_TNIL:
107 break;
108 case LUA_TBOOLEAN:
109 DumpByte(bvalue(o), D);
110 break;
111 case LUA_TNUMFLT:
112 DumpNumber(fltvalue(o), D);
113 break;
114 case LUA_TNUMINT:
115 DumpInteger(ivalue(o), D);
116 break;
117 case LUA_TSHRSTR:
118 case LUA_TLNGSTR:
119 DumpString(tsvalue(o), D);
120 break;
121 default:
122 lua_assert(0);
123 }
124 }
125}
126
127
128static void DumpProtos (const Proto *f, DumpState *D) {
129 int i;
130 int n = f->sizep;
131 DumpInt(n, D);
132 for (i = 0; i < n; i++)
133 DumpFunction(f->p[i], f->source, D);
134}
135
136
137static void DumpUpvalues (const Proto *f, DumpState *D) {
138 int i, n = f->sizeupvalues;
139 DumpInt(n, D);
140 for (i = 0; i < n; i++) {
141 DumpByte(f->upvalues[i].instack, D);
142 DumpByte(f->upvalues[i].idx, D);
143 }
144}
145
146
147static void DumpDebug (const Proto *f, DumpState *D) {
148 int i, n;
149 n = (D->strip) ? 0 : f->sizelineinfo;
150 DumpInt(n, D);
151 DumpVector(f->lineinfo, n, D);
152 n = (D->strip) ? 0 : f->sizelocvars;
153 DumpInt(n, D);
154 for (i = 0; i < n; i++) {
155 DumpString(f->locvars[i].varname, D);
156 DumpInt(f->locvars[i].startpc, D);
157 DumpInt(f->locvars[i].endpc, D);
158 }
159 n = (D->strip) ? 0 : f->sizeupvalues;
160 DumpInt(n, D);
161 for (i = 0; i < n; i++)
162 DumpString(f->upvalues[i].name, D);
163}
164
165
166static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
167 if (D->strip || f->source == psource)
168 DumpString(NULL, D); /* no debug info or same source as its parent */
169 else
170 DumpString(f->source, D);
171 DumpInt(f->linedefined, D);
172 DumpInt(f->lastlinedefined, D);
173 DumpByte(f->numparams, D);
174 DumpByte(f->is_vararg, D);
175 DumpByte(f->maxstacksize, D);
176 DumpCode(f, D);
177 DumpConstants(f, D);
178 DumpUpvalues(f, D);
179 DumpProtos(f, D);
180 DumpDebug(f, D);
181}
182
183
184static void DumpHeader (DumpState *D) {
185 DumpLiteral(LUA_SIGNATURE, D);
186 DumpByte(LUAC_VERSION, D);
187 DumpByte(LUAC_FORMAT, D);
188 DumpLiteral(LUAC_DATA, D);
189 DumpByte(sizeof(int), D);
190 DumpByte(sizeof(size_t), D);
191 DumpByte(sizeof(Instruction), D);
192 DumpByte(sizeof(lua_Integer), D);
193 DumpByte(sizeof(lua_Number), D);
194 DumpInteger(LUAC_INT, D);
195 DumpNumber(LUAC_NUM, D);
196}
197
198
199/*
200** dump Lua function as precompiled chunk
201*/
202int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
203 int strip) {
204 DumpState D;
205 D.L = L;
206 D.writer = w;
207 D.data = data;
208 D.strip = strip;
209 D.status = 0;
210 DumpHeader(&D);
211 DumpByte(f->sizeupvalues, &D);
212 DumpFunction(f, NULL, &D);
213 return D.status;
214}
215
diff --git a/src/lua-5.3/lfunc.c b/src/lua-5.3/lfunc.c
new file mode 100644
index 0000000..ccafbb8
--- /dev/null
+++ b/src/lua-5.3/lfunc.c
@@ -0,0 +1,151 @@
1/*
2** $Id: lfunc.c,v 2.45.1.1 2017/04/19 17:39:34 roberto Exp $
3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h
5*/
6
7#define lfunc_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <stddef.h>
14
15#include "lua.h"
16
17#include "lfunc.h"
18#include "lgc.h"
19#include "lmem.h"
20#include "lobject.h"
21#include "lstate.h"
22
23
24
25CClosure *luaF_newCclosure (lua_State *L, int n) {
26 GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n));
27 CClosure *c = gco2ccl(o);
28 c->nupvalues = cast_byte(n);
29 return c;
30}
31
32
33LClosure *luaF_newLclosure (lua_State *L, int n) {
34 GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n));
35 LClosure *c = gco2lcl(o);
36 c->p = NULL;
37 c->nupvalues = cast_byte(n);
38 while (n--) c->upvals[n] = NULL;
39 return c;
40}
41
42/*
43** fill a closure with new closed upvalues
44*/
45void luaF_initupvals (lua_State *L, LClosure *cl) {
46 int i;
47 for (i = 0; i < cl->nupvalues; i++) {
48 UpVal *uv = luaM_new(L, UpVal);
49 uv->refcount = 1;
50 uv->v = &uv->u.value; /* make it closed */
51 setnilvalue(uv->v);
52 cl->upvals[i] = uv;
53 }
54}
55
56
57UpVal *luaF_findupval (lua_State *L, StkId level) {
58 UpVal **pp = &L->openupval;
59 UpVal *p;
60 UpVal *uv;
61 lua_assert(isintwups(L) || L->openupval == NULL);
62 while (*pp != NULL && (p = *pp)->v >= level) {
63 lua_assert(upisopen(p));
64 if (p->v == level) /* found a corresponding upvalue? */
65 return p; /* return it */
66 pp = &p->u.open.next;
67 }
68 /* not found: create a new upvalue */
69 uv = luaM_new(L, UpVal);
70 uv->refcount = 0;
71 uv->u.open.next = *pp; /* link it to list of open upvalues */
72 uv->u.open.touched = 1;
73 *pp = uv;
74 uv->v = level; /* current value lives in the stack */
75 if (!isintwups(L)) { /* thread not in list of threads with upvalues? */
76 L->twups = G(L)->twups; /* link it to the list */
77 G(L)->twups = L;
78 }
79 return uv;
80}
81
82
83void luaF_close (lua_State *L, StkId level) {
84 UpVal *uv;
85 while (L->openupval != NULL && (uv = L->openupval)->v >= level) {
86 lua_assert(upisopen(uv));
87 L->openupval = uv->u.open.next; /* remove from 'open' list */
88 if (uv->refcount == 0) /* no references? */
89 luaM_free(L, uv); /* free upvalue */
90 else {
91 setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */
92 uv->v = &uv->u.value; /* now current value lives here */
93 luaC_upvalbarrier(L, uv);
94 }
95 }
96}
97
98
99Proto *luaF_newproto (lua_State *L) {
100 GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto));
101 Proto *f = gco2p(o);
102 f->k = NULL;
103 f->sizek = 0;
104 f->p = NULL;
105 f->sizep = 0;
106 f->code = NULL;
107 f->cache = NULL;
108 f->sizecode = 0;
109 f->lineinfo = NULL;
110 f->sizelineinfo = 0;
111 f->upvalues = NULL;
112 f->sizeupvalues = 0;
113 f->numparams = 0;
114 f->is_vararg = 0;
115 f->maxstacksize = 0;
116 f->locvars = NULL;
117 f->sizelocvars = 0;
118 f->linedefined = 0;
119 f->lastlinedefined = 0;
120 f->source = NULL;
121 return f;
122}
123
124
125void luaF_freeproto (lua_State *L, Proto *f) {
126 luaM_freearray(L, f->code, f->sizecode);
127 luaM_freearray(L, f->p, f->sizep);
128 luaM_freearray(L, f->k, f->sizek);
129 luaM_freearray(L, f->lineinfo, f->sizelineinfo);
130 luaM_freearray(L, f->locvars, f->sizelocvars);
131 luaM_freearray(L, f->upvalues, f->sizeupvalues);
132 luaM_free(L, f);
133}
134
135
136/*
137** Look for n-th local variable at line 'line' in function 'func'.
138** Returns NULL if not found.
139*/
140const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
141 int i;
142 for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
143 if (pc < f->locvars[i].endpc) { /* is variable active? */
144 local_number--;
145 if (local_number == 0)
146 return getstr(f->locvars[i].varname);
147 }
148 }
149 return NULL; /* not found */
150}
151
diff --git a/src/lua-5.3/lfunc.h b/src/lua-5.3/lfunc.h
new file mode 100644
index 0000000..c916e98
--- /dev/null
+++ b/src/lua-5.3/lfunc.h
@@ -0,0 +1,61 @@
1/*
2** $Id: lfunc.h,v 2.15.1.1 2017/04/19 17:39:34 roberto Exp $
3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lfunc_h
8#define lfunc_h
9
10
11#include "lobject.h"
12
13
14#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
15 cast(int, sizeof(TValue)*((n)-1)))
16
17#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
18 cast(int, sizeof(TValue *)*((n)-1)))
19
20
21/* test whether thread is in 'twups' list */
22#define isintwups(L) (L->twups != L)
23
24
25/*
26** maximum number of upvalues in a closure (both C and Lua). (Value
27** must fit in a VM register.)
28*/
29#define MAXUPVAL 255
30
31
32/*
33** Upvalues for Lua closures
34*/
35struct UpVal {
36 TValue *v; /* points to stack or to its own value */
37 lu_mem refcount; /* reference counter */
38 union {
39 struct { /* (when open) */
40 UpVal *next; /* linked list */
41 int touched; /* mark to avoid cycles with dead threads */
42 } open;
43 TValue value; /* the value (when closed) */
44 } u;
45};
46
47#define upisopen(up) ((up)->v != &(up)->u.value)
48
49
50LUAI_FUNC Proto *luaF_newproto (lua_State *L);
51LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems);
52LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems);
53LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
54LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
55LUAI_FUNC void luaF_close (lua_State *L, StkId level);
56LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
57LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
58 int pc);
59
60
61#endif
diff --git a/src/lua-5.3/lgc.c b/src/lua-5.3/lgc.c
new file mode 100644
index 0000000..db4df82
--- /dev/null
+++ b/src/lua-5.3/lgc.c
@@ -0,0 +1,1179 @@
1/*
2** $Id: lgc.c,v 2.215.1.2 2017/08/31 16:15:27 roberto Exp $
3** Garbage Collector
4** See Copyright Notice in lua.h
5*/
6
7#define lgc_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <string.h>
14
15#include "lua.h"
16
17#include "ldebug.h"
18#include "ldo.h"
19#include "lfunc.h"
20#include "lgc.h"
21#include "lmem.h"
22#include "lobject.h"
23#include "lstate.h"
24#include "lstring.h"
25#include "ltable.h"
26#include "ltm.h"
27
28
29/*
30** internal state for collector while inside the atomic phase. The
31** collector should never be in this state while running regular code.
32*/
33#define GCSinsideatomic (GCSpause + 1)
34
35/*
36** cost of sweeping one element (the size of a small object divided
37** by some adjust for the sweep speed)
38*/
39#define GCSWEEPCOST ((sizeof(TString) + 4) / 4)
40
41/* maximum number of elements to sweep in each single step */
42#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4))
43
44/* cost of calling one finalizer */
45#define GCFINALIZECOST GCSWEEPCOST
46
47
48/*
49** macro to adjust 'stepmul': 'stepmul' is actually used like
50** 'stepmul / STEPMULADJ' (value chosen by tests)
51*/
52#define STEPMULADJ 200
53
54
55/*
56** macro to adjust 'pause': 'pause' is actually used like
57** 'pause / PAUSEADJ' (value chosen by tests)
58*/
59#define PAUSEADJ 100
60
61
62/*
63** 'makewhite' erases all color bits then sets only the current white
64** bit
65*/
66#define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS))
67#define makewhite(g,x) \
68 (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g)))
69
70#define white2gray(x) resetbits(x->marked, WHITEBITS)
71#define black2gray(x) resetbit(x->marked, BLACKBIT)
72
73
74#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
75
76#define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n)))
77
78
79#define checkconsistency(obj) \
80 lua_longassert(!iscollectable(obj) || righttt(obj))
81
82
83#define markvalue(g,o) { checkconsistency(o); \
84 if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
85
86#define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); }
87
88/*
89** mark an object that can be NULL (either because it is really optional,
90** or it was stripped as debug info, or inside an uncompleted structure)
91*/
92#define markobjectN(g,t) { if (t) markobject(g,t); }
93
94static void reallymarkobject (global_State *g, GCObject *o);
95
96
97/*
98** {======================================================
99** Generic functions
100** =======================================================
101*/
102
103
104/*
105** one after last element in a hash array
106*/
107#define gnodelast(h) gnode(h, cast(size_t, sizenode(h)))
108
109
110/*
111** link collectable object 'o' into list pointed by 'p'
112*/
113#define linkgclist(o,p) ((o)->gclist = (p), (p) = obj2gco(o))
114
115
116/*
117** If key is not marked, mark its entry as dead. This allows key to be
118** collected, but keeps its entry in the table. A dead node is needed
119** when Lua looks up for a key (it may be part of a chain) and when
120** traversing a weak table (key might be removed from the table during
121** traversal). Other places never manipulate dead keys, because its
122** associated nil value is enough to signal that the entry is logically
123** empty.
124*/
125static void removeentry (Node *n) {
126 lua_assert(ttisnil(gval(n)));
127 if (valiswhite(gkey(n)))
128 setdeadvalue(wgkey(n)); /* unused and unmarked key; remove it */
129}
130
131
132/*
133** tells whether a key or value can be cleared from a weak
134** table. Non-collectable objects are never removed from weak
135** tables. Strings behave as 'values', so are never removed too. for
136** other objects: if really collected, cannot keep them; for objects
137** being finalized, keep them in keys, but not in values
138*/
139static int iscleared (global_State *g, const TValue *o) {
140 if (!iscollectable(o)) return 0;
141 else if (ttisstring(o)) {
142 markobject(g, tsvalue(o)); /* strings are 'values', so are never weak */
143 return 0;
144 }
145 else return iswhite(gcvalue(o));
146}
147
148
149/*
150** barrier that moves collector forward, that is, mark the white object
151** being pointed by a black object. (If in sweep phase, clear the black
152** object to white [sweep it] to avoid other barrier calls for this
153** same object.)
154*/
155void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
156 global_State *g = G(L);
157 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
158 if (keepinvariant(g)) /* must keep invariant? */
159 reallymarkobject(g, v); /* restore invariant */
160 else { /* sweep phase */
161 lua_assert(issweepphase(g));
162 makewhite(g, o); /* mark main obj. as white to avoid other barriers */
163 }
164}
165
166
167/*
168** barrier that moves collector backward, that is, mark the black object
169** pointing to a white object as gray again.
170*/
171void luaC_barrierback_ (lua_State *L, Table *t) {
172 global_State *g = G(L);
173 lua_assert(isblack(t) && !isdead(g, t));
174 black2gray(t); /* make table gray (again) */
175 linkgclist(t, g->grayagain);
176}
177
178
179/*
180** barrier for assignments to closed upvalues. Because upvalues are
181** shared among closures, it is impossible to know the color of all
182** closures pointing to it. So, we assume that the object being assigned
183** must be marked.
184*/
185void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) {
186 global_State *g = G(L);
187 GCObject *o = gcvalue(uv->v);
188 lua_assert(!upisopen(uv)); /* ensured by macro luaC_upvalbarrier */
189 if (keepinvariant(g))
190 markobject(g, o);
191}
192
193
194void luaC_fix (lua_State *L, GCObject *o) {
195 global_State *g = G(L);
196 lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */
197 white2gray(o); /* they will be gray forever */
198 g->allgc = o->next; /* remove object from 'allgc' list */
199 o->next = g->fixedgc; /* link it to 'fixedgc' list */
200 g->fixedgc = o;
201}
202
203
204/*
205** create a new collectable object (with given type and size) and link
206** it to 'allgc' list.
207*/
208GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
209 global_State *g = G(L);
210 GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz));
211 o->marked = luaC_white(g);
212 o->tt = tt;
213 o->next = g->allgc;
214 g->allgc = o;
215 return o;
216}
217
218/* }====================================================== */
219
220
221
222/*
223** {======================================================
224** Mark functions
225** =======================================================
226*/
227
228
229/*
230** mark an object. Userdata, strings, and closed upvalues are visited
231** and turned black here. Other objects are marked gray and added
232** to appropriate list to be visited (and turned black) later. (Open
233** upvalues are already linked in 'headuv' list.)
234*/
235static void reallymarkobject (global_State *g, GCObject *o) {
236 reentry:
237 white2gray(o);
238 switch (o->tt) {
239 case LUA_TSHRSTR: {
240 gray2black(o);
241 g->GCmemtrav += sizelstring(gco2ts(o)->shrlen);
242 break;
243 }
244 case LUA_TLNGSTR: {
245 gray2black(o);
246 g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
247 break;
248 }
249 case LUA_TUSERDATA: {
250 TValue uvalue;
251 markobjectN(g, gco2u(o)->metatable); /* mark its metatable */
252 gray2black(o);
253 g->GCmemtrav += sizeudata(gco2u(o));
254 getuservalue(g->mainthread, gco2u(o), &uvalue);
255 if (valiswhite(&uvalue)) { /* markvalue(g, &uvalue); */
256 o = gcvalue(&uvalue);
257 goto reentry;
258 }
259 break;
260 }
261 case LUA_TLCL: {
262 linkgclist(gco2lcl(o), g->gray);
263 break;
264 }
265 case LUA_TCCL: {
266 linkgclist(gco2ccl(o), g->gray);
267 break;
268 }
269 case LUA_TTABLE: {
270 linkgclist(gco2t(o), g->gray);
271 break;
272 }
273 case LUA_TTHREAD: {
274 linkgclist(gco2th(o), g->gray);
275 break;
276 }
277 case LUA_TPROTO: {
278 linkgclist(gco2p(o), g->gray);
279 break;
280 }
281 default: lua_assert(0); break;
282 }
283}
284
285
286/*
287** mark metamethods for basic types
288*/
289static void markmt (global_State *g) {
290 int i;
291 for (i=0; i < LUA_NUMTAGS; i++)
292 markobjectN(g, g->mt[i]);
293}
294
295
296/*
297** mark all objects in list of being-finalized
298*/
299static void markbeingfnz (global_State *g) {
300 GCObject *o;
301 for (o = g->tobefnz; o != NULL; o = o->next)
302 markobject(g, o);
303}
304
305
306/*
307** Mark all values stored in marked open upvalues from non-marked threads.
308** (Values from marked threads were already marked when traversing the
309** thread.) Remove from the list threads that no longer have upvalues and
310** not-marked threads.
311*/
312static void remarkupvals (global_State *g) {
313 lua_State *thread;
314 lua_State **p = &g->twups;
315 while ((thread = *p) != NULL) {
316 lua_assert(!isblack(thread)); /* threads are never black */
317 if (isgray(thread) && thread->openupval != NULL)
318 p = &thread->twups; /* keep marked thread with upvalues in the list */
319 else { /* thread is not marked or without upvalues */
320 UpVal *uv;
321 *p = thread->twups; /* remove thread from the list */
322 thread->twups = thread; /* mark that it is out of list */
323 for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) {
324 if (uv->u.open.touched) {
325 markvalue(g, uv->v); /* remark upvalue's value */
326 uv->u.open.touched = 0;
327 }
328 }
329 }
330 }
331}
332
333
334/*
335** mark root set and reset all gray lists, to start a new collection
336*/
337static void restartcollection (global_State *g) {
338 g->gray = g->grayagain = NULL;
339 g->weak = g->allweak = g->ephemeron = NULL;
340 markobject(g, g->mainthread);
341 markvalue(g, &g->l_registry);
342 markmt(g);
343 markbeingfnz(g); /* mark any finalizing object left from previous cycle */
344}
345
346/* }====================================================== */
347
348
349/*
350** {======================================================
351** Traverse functions
352** =======================================================
353*/
354
355/*
356** Traverse a table with weak values and link it to proper list. During
357** propagate phase, keep it in 'grayagain' list, to be revisited in the
358** atomic phase. In the atomic phase, if table has any white value,
359** put it in 'weak' list, to be cleared.
360*/
361static void traverseweakvalue (global_State *g, Table *h) {
362 Node *n, *limit = gnodelast(h);
363 /* if there is array part, assume it may have white values (it is not
364 worth traversing it now just to check) */
365 int hasclears = (h->sizearray > 0);
366 for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */
367 checkdeadkey(n);
368 if (ttisnil(gval(n))) /* entry is empty? */
369 removeentry(n); /* remove it */
370 else {
371 lua_assert(!ttisnil(gkey(n)));
372 markvalue(g, gkey(n)); /* mark key */
373 if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */
374 hasclears = 1; /* table will have to be cleared */
375 }
376 }
377 if (g->gcstate == GCSpropagate)
378 linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */
379 else if (hasclears)
380 linkgclist(h, g->weak); /* has to be cleared later */
381}
382
383
384/*
385** Traverse an ephemeron table and link it to proper list. Returns true
386** iff any object was marked during this traversal (which implies that
387** convergence has to continue). During propagation phase, keep table
388** in 'grayagain' list, to be visited again in the atomic phase. In
389** the atomic phase, if table has any white->white entry, it has to
390** be revisited during ephemeron convergence (as that key may turn
391** black). Otherwise, if it has any white key, table has to be cleared
392** (in the atomic phase).
393*/
394static int traverseephemeron (global_State *g, Table *h) {
395 int marked = 0; /* true if an object is marked in this traversal */
396 int hasclears = 0; /* true if table has white keys */
397 int hasww = 0; /* true if table has entry "white-key -> white-value" */
398 Node *n, *limit = gnodelast(h);
399 unsigned int i;
400 /* traverse array part */
401 for (i = 0; i < h->sizearray; i++) {
402 if (valiswhite(&h->array[i])) {
403 marked = 1;
404 reallymarkobject(g, gcvalue(&h->array[i]));
405 }
406 }
407 /* traverse hash part */
408 for (n = gnode(h, 0); n < limit; n++) {
409 checkdeadkey(n);
410 if (ttisnil(gval(n))) /* entry is empty? */
411 removeentry(n); /* remove it */
412 else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */
413 hasclears = 1; /* table must be cleared */
414 if (valiswhite(gval(n))) /* value not marked yet? */
415 hasww = 1; /* white-white entry */
416 }
417 else if (valiswhite(gval(n))) { /* value not marked yet? */
418 marked = 1;
419 reallymarkobject(g, gcvalue(gval(n))); /* mark it now */
420 }
421 }
422 /* link table into proper list */
423 if (g->gcstate == GCSpropagate)
424 linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */
425 else if (hasww) /* table has white->white entries? */
426 linkgclist(h, g->ephemeron); /* have to propagate again */
427 else if (hasclears) /* table has white keys? */
428 linkgclist(h, g->allweak); /* may have to clean white keys */
429 return marked;
430}
431
432
433static void traversestrongtable (global_State *g, Table *h) {
434 Node *n, *limit = gnodelast(h);
435 unsigned int i;
436 for (i = 0; i < h->sizearray; i++) /* traverse array part */
437 markvalue(g, &h->array[i]);
438 for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */
439 checkdeadkey(n);
440 if (ttisnil(gval(n))) /* entry is empty? */
441 removeentry(n); /* remove it */
442 else {
443 lua_assert(!ttisnil(gkey(n)));
444 markvalue(g, gkey(n)); /* mark key */
445 markvalue(g, gval(n)); /* mark value */
446 }
447 }
448}
449
450
451static lu_mem traversetable (global_State *g, Table *h) {
452 const char *weakkey, *weakvalue;
453 const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
454 markobjectN(g, h->metatable);
455 if (mode && ttisstring(mode) && /* is there a weak mode? */
456 ((weakkey = strchr(svalue(mode), 'k')),
457 (weakvalue = strchr(svalue(mode), 'v')),
458 (weakkey || weakvalue))) { /* is really weak? */
459 black2gray(h); /* keep table gray */
460 if (!weakkey) /* strong keys? */
461 traverseweakvalue(g, h);
462 else if (!weakvalue) /* strong values? */
463 traverseephemeron(g, h);
464 else /* all weak */
465 linkgclist(h, g->allweak); /* nothing to traverse now */
466 }
467 else /* not weak */
468 traversestrongtable(g, h);
469 return sizeof(Table) + sizeof(TValue) * h->sizearray +
470 sizeof(Node) * cast(size_t, allocsizenode(h));
471}
472
473
474/*
475** Traverse a prototype. (While a prototype is being build, its
476** arrays can be larger than needed; the extra slots are filled with
477** NULL, so the use of 'markobjectN')
478*/
479static int traverseproto (global_State *g, Proto *f) {
480 int i;
481 if (f->cache && iswhite(f->cache))
482 f->cache = NULL; /* allow cache to be collected */
483 markobjectN(g, f->source);
484 for (i = 0; i < f->sizek; i++) /* mark literals */
485 markvalue(g, &f->k[i]);
486 for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
487 markobjectN(g, f->upvalues[i].name);
488 for (i = 0; i < f->sizep; i++) /* mark nested protos */
489 markobjectN(g, f->p[i]);
490 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
491 markobjectN(g, f->locvars[i].varname);
492 return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
493 sizeof(Proto *) * f->sizep +
494 sizeof(TValue) * f->sizek +
495 sizeof(int) * f->sizelineinfo +
496 sizeof(LocVar) * f->sizelocvars +
497 sizeof(Upvaldesc) * f->sizeupvalues;
498}
499
500
501static lu_mem traverseCclosure (global_State *g, CClosure *cl) {
502 int i;
503 for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */
504 markvalue(g, &cl->upvalue[i]);
505 return sizeCclosure(cl->nupvalues);
506}
507
508/*
509** open upvalues point to values in a thread, so those values should
510** be marked when the thread is traversed except in the atomic phase
511** (because then the value cannot be changed by the thread and the
512** thread may not be traversed again)
513*/
514static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
515 int i;
516 markobjectN(g, cl->p); /* mark its prototype */
517 for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */
518 UpVal *uv = cl->upvals[i];
519 if (uv != NULL) {
520 if (upisopen(uv) && g->gcstate != GCSinsideatomic)
521 uv->u.open.touched = 1; /* can be marked in 'remarkupvals' */
522 else
523 markvalue(g, uv->v);
524 }
525 }
526 return sizeLclosure(cl->nupvalues);
527}
528
529
530static lu_mem traversethread (global_State *g, lua_State *th) {
531 StkId o = th->stack;
532 if (o == NULL)
533 return 1; /* stack not completely built yet */
534 lua_assert(g->gcstate == GCSinsideatomic ||
535 th->openupval == NULL || isintwups(th));
536 for (; o < th->top; o++) /* mark live elements in the stack */
537 markvalue(g, o);
538 if (g->gcstate == GCSinsideatomic) { /* final traversal? */
539 StkId lim = th->stack + th->stacksize; /* real end of stack */
540 for (; o < lim; o++) /* clear not-marked stack slice */
541 setnilvalue(o);
542 /* 'remarkupvals' may have removed thread from 'twups' list */
543 if (!isintwups(th) && th->openupval != NULL) {
544 th->twups = g->twups; /* link it back to the list */
545 g->twups = th;
546 }
547 }
548 else if (g->gckind != KGC_EMERGENCY)
549 luaD_shrinkstack(th); /* do not change stack in emergency cycle */
550 return (sizeof(lua_State) + sizeof(TValue) * th->stacksize +
551 sizeof(CallInfo) * th->nci);
552}
553
554
555/*
556** traverse one gray object, turning it to black (except for threads,
557** which are always gray).
558*/
559static void propagatemark (global_State *g) {
560 lu_mem size;
561 GCObject *o = g->gray;
562 lua_assert(isgray(o));
563 gray2black(o);
564 switch (o->tt) {
565 case LUA_TTABLE: {
566 Table *h = gco2t(o);
567 g->gray = h->gclist; /* remove from 'gray' list */
568 size = traversetable(g, h);
569 break;
570 }
571 case LUA_TLCL: {
572 LClosure *cl = gco2lcl(o);
573 g->gray = cl->gclist; /* remove from 'gray' list */
574 size = traverseLclosure(g, cl);
575 break;
576 }
577 case LUA_TCCL: {
578 CClosure *cl = gco2ccl(o);
579 g->gray = cl->gclist; /* remove from 'gray' list */
580 size = traverseCclosure(g, cl);
581 break;
582 }
583 case LUA_TTHREAD: {
584 lua_State *th = gco2th(o);
585 g->gray = th->gclist; /* remove from 'gray' list */
586 linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
587 black2gray(o);
588 size = traversethread(g, th);
589 break;
590 }
591 case LUA_TPROTO: {
592 Proto *p = gco2p(o);
593 g->gray = p->gclist; /* remove from 'gray' list */
594 size = traverseproto(g, p);
595 break;
596 }
597 default: lua_assert(0); return;
598 }
599 g->GCmemtrav += size;
600}
601
602
603static void propagateall (global_State *g) {
604 while (g->gray) propagatemark(g);
605}
606
607
608static void convergeephemerons (global_State *g) {
609 int changed;
610 do {
611 GCObject *w;
612 GCObject *next = g->ephemeron; /* get ephemeron list */
613 g->ephemeron = NULL; /* tables may return to this list when traversed */
614 changed = 0;
615 while ((w = next) != NULL) {
616 next = gco2t(w)->gclist;
617 if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */
618 propagateall(g); /* propagate changes */
619 changed = 1; /* will have to revisit all ephemeron tables */
620 }
621 }
622 } while (changed);
623}
624
625/* }====================================================== */
626
627
628/*
629** {======================================================
630** Sweep Functions
631** =======================================================
632*/
633
634
635/*
636** clear entries with unmarked keys from all weaktables in list 'l' up
637** to element 'f'
638*/
639static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
640 for (; l != f; l = gco2t(l)->gclist) {
641 Table *h = gco2t(l);
642 Node *n, *limit = gnodelast(h);
643 for (n = gnode(h, 0); n < limit; n++) {
644 if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
645 setnilvalue(gval(n)); /* remove value ... */
646 }
647 if (ttisnil(gval(n))) /* is entry empty? */
648 removeentry(n); /* remove entry from table */
649 }
650 }
651}
652
653
654/*
655** clear entries with unmarked values from all weaktables in list 'l' up
656** to element 'f'
657*/
658static void clearvalues (global_State *g, GCObject *l, GCObject *f) {
659 for (; l != f; l = gco2t(l)->gclist) {
660 Table *h = gco2t(l);
661 Node *n, *limit = gnodelast(h);
662 unsigned int i;
663 for (i = 0; i < h->sizearray; i++) {
664 TValue *o = &h->array[i];
665 if (iscleared(g, o)) /* value was collected? */
666 setnilvalue(o); /* remove value */
667 }
668 for (n = gnode(h, 0); n < limit; n++) {
669 if (!ttisnil(gval(n)) && iscleared(g, gval(n))) {
670 setnilvalue(gval(n)); /* remove value ... */
671 removeentry(n); /* and remove entry from table */
672 }
673 }
674 }
675}
676
677
678void luaC_upvdeccount (lua_State *L, UpVal *uv) {
679 lua_assert(uv->refcount > 0);
680 uv->refcount--;
681 if (uv->refcount == 0 && !upisopen(uv))
682 luaM_free(L, uv);
683}
684
685
686static void freeLclosure (lua_State *L, LClosure *cl) {
687 int i;
688 for (i = 0; i < cl->nupvalues; i++) {
689 UpVal *uv = cl->upvals[i];
690 if (uv)
691 luaC_upvdeccount(L, uv);
692 }
693 luaM_freemem(L, cl, sizeLclosure(cl->nupvalues));
694}
695
696
697static void freeobj (lua_State *L, GCObject *o) {
698 switch (o->tt) {
699 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
700 case LUA_TLCL: {
701 freeLclosure(L, gco2lcl(o));
702 break;
703 }
704 case LUA_TCCL: {
705 luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));
706 break;
707 }
708 case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
709 case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
710 case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
711 case LUA_TSHRSTR:
712 luaS_remove(L, gco2ts(o)); /* remove it from hash table */
713 luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen));
714 break;
715 case LUA_TLNGSTR: {
716 luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen));
717 break;
718 }
719 default: lua_assert(0);
720 }
721}
722
723
724#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
725static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count);
726
727
728/*
729** sweep at most 'count' elements from a list of GCObjects erasing dead
730** objects, where a dead object is one marked with the old (non current)
731** white; change all non-dead objects back to white, preparing for next
732** collection cycle. Return where to continue the traversal or NULL if
733** list is finished.
734*/
735static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
736 global_State *g = G(L);
737 int ow = otherwhite(g);
738 int white = luaC_white(g); /* current white */
739 while (*p != NULL && count-- > 0) {
740 GCObject *curr = *p;
741 int marked = curr->marked;
742 if (isdeadm(ow, marked)) { /* is 'curr' dead? */
743 *p = curr->next; /* remove 'curr' from list */
744 freeobj(L, curr); /* erase 'curr' */
745 }
746 else { /* change mark to 'white' */
747 curr->marked = cast_byte((marked & maskcolors) | white);
748 p = &curr->next; /* go to next element */
749 }
750 }
751 return (*p == NULL) ? NULL : p;
752}
753
754
755/*
756** sweep a list until a live object (or end of list)
757*/
758static GCObject **sweeptolive (lua_State *L, GCObject **p) {
759 GCObject **old = p;
760 do {
761 p = sweeplist(L, p, 1);
762 } while (p == old);
763 return p;
764}
765
766/* }====================================================== */
767
768
769/*
770** {======================================================
771** Finalization
772** =======================================================
773*/
774
775/*
776** If possible, shrink string table
777*/
778static void checkSizes (lua_State *L, global_State *g) {
779 if (g->gckind != KGC_EMERGENCY) {
780 l_mem olddebt = g->GCdebt;
781 if (g->strt.nuse < g->strt.size / 4) /* string table too big? */
782 luaS_resize(L, g->strt.size / 2); /* shrink it a little */
783 g->GCestimate += g->GCdebt - olddebt; /* update estimate */
784 }
785}
786
787
788static GCObject *udata2finalize (global_State *g) {
789 GCObject *o = g->tobefnz; /* get first element */
790 lua_assert(tofinalize(o));
791 g->tobefnz = o->next; /* remove it from 'tobefnz' list */
792 o->next = g->allgc; /* return it to 'allgc' list */
793 g->allgc = o;
794 resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */
795 if (issweepphase(g))
796 makewhite(g, o); /* "sweep" object */
797 return o;
798}
799
800
801static void dothecall (lua_State *L, void *ud) {
802 UNUSED(ud);
803 luaD_callnoyield(L, L->top - 2, 0);
804}
805
806
807static void GCTM (lua_State *L, int propagateerrors) {
808 global_State *g = G(L);
809 const TValue *tm;
810 TValue v;
811 setgcovalue(L, &v, udata2finalize(g));
812 tm = luaT_gettmbyobj(L, &v, TM_GC);
813 if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */
814 int status;
815 lu_byte oldah = L->allowhook;
816 int running = g->gcrunning;
817 L->allowhook = 0; /* stop debug hooks during GC metamethod */
818 g->gcrunning = 0; /* avoid GC steps */
819 setobj2s(L, L->top, tm); /* push finalizer... */
820 setobj2s(L, L->top + 1, &v); /* ... and its argument */
821 L->top += 2; /* and (next line) call the finalizer */
822 L->ci->callstatus |= CIST_FIN; /* will run a finalizer */
823 status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
824 L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */
825 L->allowhook = oldah; /* restore hooks */
826 g->gcrunning = running; /* restore state */
827 if (status != LUA_OK && propagateerrors) { /* error while running __gc? */
828 if (status == LUA_ERRRUN) { /* is there an error object? */
829 const char *msg = (ttisstring(L->top - 1))
830 ? svalue(L->top - 1)
831 : "no message";
832 luaO_pushfstring(L, "error in __gc metamethod (%s)", msg);
833 status = LUA_ERRGCMM; /* error in __gc metamethod */
834 }
835 luaD_throw(L, status); /* re-throw error */
836 }
837 }
838}
839
840
841/*
842** call a few (up to 'g->gcfinnum') finalizers
843*/
844static int runafewfinalizers (lua_State *L) {
845 global_State *g = G(L);
846 unsigned int i;
847 lua_assert(!g->tobefnz || g->gcfinnum > 0);
848 for (i = 0; g->tobefnz && i < g->gcfinnum; i++)
849 GCTM(L, 1); /* call one finalizer */
850 g->gcfinnum = (!g->tobefnz) ? 0 /* nothing more to finalize? */
851 : g->gcfinnum * 2; /* else call a few more next time */
852 return i;
853}
854
855
856/*
857** call all pending finalizers
858*/
859static void callallpendingfinalizers (lua_State *L) {
860 global_State *g = G(L);
861 while (g->tobefnz)
862 GCTM(L, 0);
863}
864
865
866/*
867** find last 'next' field in list 'p' list (to add elements in its end)
868*/
869static GCObject **findlast (GCObject **p) {
870 while (*p != NULL)
871 p = &(*p)->next;
872 return p;
873}
874
875
876/*
877** move all unreachable objects (or 'all' objects) that need
878** finalization from list 'finobj' to list 'tobefnz' (to be finalized)
879*/
880static void separatetobefnz (global_State *g, int all) {
881 GCObject *curr;
882 GCObject **p = &g->finobj;
883 GCObject **lastnext = findlast(&g->tobefnz);
884 while ((curr = *p) != NULL) { /* traverse all finalizable objects */
885 lua_assert(tofinalize(curr));
886 if (!(iswhite(curr) || all)) /* not being collected? */
887 p = &curr->next; /* don't bother with it */
888 else {
889 *p = curr->next; /* remove 'curr' from 'finobj' list */
890 curr->next = *lastnext; /* link at the end of 'tobefnz' list */
891 *lastnext = curr;
892 lastnext = &curr->next;
893 }
894 }
895}
896
897
898/*
899** if object 'o' has a finalizer, remove it from 'allgc' list (must
900** search the list to find it) and link it in 'finobj' list.
901*/
902void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
903 global_State *g = G(L);
904 if (tofinalize(o) || /* obj. is already marked... */
905 gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */
906 return; /* nothing to be done */
907 else { /* move 'o' to 'finobj' list */
908 GCObject **p;
909 if (issweepphase(g)) {
910 makewhite(g, o); /* "sweep" object 'o' */
911 if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */
912 g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */
913 }
914 /* search for pointer pointing to 'o' */
915 for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
916 *p = o->next; /* remove 'o' from 'allgc' list */
917 o->next = g->finobj; /* link it in 'finobj' list */
918 g->finobj = o;
919 l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */
920 }
921}
922
923/* }====================================================== */
924
925
926
927/*
928** {======================================================
929** GC control
930** =======================================================
931*/
932
933
934/*
935** Set a reasonable "time" to wait before starting a new GC cycle; cycle
936** will start when memory use hits threshold. (Division by 'estimate'
937** should be OK: it cannot be zero (because Lua cannot even start with
938** less than PAUSEADJ bytes).
939*/
940static void setpause (global_State *g) {
941 l_mem threshold, debt;
942 l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */
943 lua_assert(estimate > 0);
944 threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */
945 ? estimate * g->gcpause /* no overflow */
946 : MAX_LMEM; /* overflow; truncate to maximum */
947 debt = gettotalbytes(g) - threshold;
948 luaE_setdebt(g, debt);
949}
950
951
952/*
953** Enter first sweep phase.
954** The call to 'sweeplist' tries to make pointer point to an object
955** inside the list (instead of to the header), so that the real sweep do
956** not need to skip objects created between "now" and the start of the
957** real sweep.
958*/
959static void entersweep (lua_State *L) {
960 global_State *g = G(L);
961 g->gcstate = GCSswpallgc;
962 lua_assert(g->sweepgc == NULL);
963 g->sweepgc = sweeplist(L, &g->allgc, 1);
964}
965
966
967void luaC_freeallobjects (lua_State *L) {
968 global_State *g = G(L);
969 separatetobefnz(g, 1); /* separate all objects with finalizers */
970 lua_assert(g->finobj == NULL);
971 callallpendingfinalizers(L);
972 lua_assert(g->tobefnz == NULL);
973 g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
974 g->gckind = KGC_NORMAL;
975 sweepwholelist(L, &g->finobj);
976 sweepwholelist(L, &g->allgc);
977 sweepwholelist(L, &g->fixedgc); /* collect fixed objects */
978 lua_assert(g->strt.nuse == 0);
979}
980
981
982static l_mem atomic (lua_State *L) {
983 global_State *g = G(L);
984 l_mem work;
985 GCObject *origweak, *origall;
986 GCObject *grayagain = g->grayagain; /* save original list */
987 lua_assert(g->ephemeron == NULL && g->weak == NULL);
988 lua_assert(!iswhite(g->mainthread));
989 g->gcstate = GCSinsideatomic;
990 g->GCmemtrav = 0; /* start counting work */
991 markobject(g, L); /* mark running thread */
992 /* registry and global metatables may be changed by API */
993 markvalue(g, &g->l_registry);
994 markmt(g); /* mark global metatables */
995 /* remark occasional upvalues of (maybe) dead threads */
996 remarkupvals(g);
997 propagateall(g); /* propagate changes */
998 work = g->GCmemtrav; /* stop counting (do not recount 'grayagain') */
999 g->gray = grayagain;
1000 propagateall(g); /* traverse 'grayagain' list */
1001 g->GCmemtrav = 0; /* restart counting */
1002 convergeephemerons(g);
1003 /* at this point, all strongly accessible objects are marked. */
1004 /* Clear values from weak tables, before checking finalizers */
1005 clearvalues(g, g->weak, NULL);
1006 clearvalues(g, g->allweak, NULL);
1007 origweak = g->weak; origall = g->allweak;
1008 work += g->GCmemtrav; /* stop counting (objects being finalized) */
1009 separatetobefnz(g, 0); /* separate objects to be finalized */
1010 g->gcfinnum = 1; /* there may be objects to be finalized */
1011 markbeingfnz(g); /* mark objects that will be finalized */
1012 propagateall(g); /* remark, to propagate 'resurrection' */
1013 g->GCmemtrav = 0; /* restart counting */
1014 convergeephemerons(g);
1015 /* at this point, all resurrected objects are marked. */
1016 /* remove dead objects from weak tables */
1017 clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */
1018 clearkeys(g, g->allweak, NULL); /* clear keys from all 'allweak' tables */
1019 /* clear values from resurrected weak tables */
1020 clearvalues(g, g->weak, origweak);
1021 clearvalues(g, g->allweak, origall);
1022 luaS_clearcache(g);
1023 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
1024 work += g->GCmemtrav; /* complete counting */
1025 return work; /* estimate of memory marked by 'atomic' */
1026}
1027
1028
1029static lu_mem sweepstep (lua_State *L, global_State *g,
1030 int nextstate, GCObject **nextlist) {
1031 if (g->sweepgc) {
1032 l_mem olddebt = g->GCdebt;
1033 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
1034 g->GCestimate += g->GCdebt - olddebt; /* update estimate */
1035 if (g->sweepgc) /* is there still something to sweep? */
1036 return (GCSWEEPMAX * GCSWEEPCOST);
1037 }
1038 /* else enter next state */
1039 g->gcstate = nextstate;
1040 g->sweepgc = nextlist;
1041 return 0;
1042}
1043
1044
1045static lu_mem singlestep (lua_State *L) {
1046 global_State *g = G(L);
1047 switch (g->gcstate) {
1048 case GCSpause: {
1049 g->GCmemtrav = g->strt.size * sizeof(GCObject*);
1050 restartcollection(g);
1051 g->gcstate = GCSpropagate;
1052 return g->GCmemtrav;
1053 }
1054 case GCSpropagate: {
1055 g->GCmemtrav = 0;
1056 lua_assert(g->gray);
1057 propagatemark(g);
1058 if (g->gray == NULL) /* no more gray objects? */
1059 g->gcstate = GCSatomic; /* finish propagate phase */
1060 return g->GCmemtrav; /* memory traversed in this step */
1061 }
1062 case GCSatomic: {
1063 lu_mem work;
1064 propagateall(g); /* make sure gray list is empty */
1065 work = atomic(L); /* work is what was traversed by 'atomic' */
1066 entersweep(L);
1067 g->GCestimate = gettotalbytes(g); /* first estimate */;
1068 return work;
1069 }
1070 case GCSswpallgc: { /* sweep "regular" objects */
1071 return sweepstep(L, g, GCSswpfinobj, &g->finobj);
1072 }
1073 case GCSswpfinobj: { /* sweep objects with finalizers */
1074 return sweepstep(L, g, GCSswptobefnz, &g->tobefnz);
1075 }
1076 case GCSswptobefnz: { /* sweep objects to be finalized */
1077 return sweepstep(L, g, GCSswpend, NULL);
1078 }
1079 case GCSswpend: { /* finish sweeps */
1080 makewhite(g, g->mainthread); /* sweep main thread */
1081 checkSizes(L, g);
1082 g->gcstate = GCScallfin;
1083 return 0;
1084 }
1085 case GCScallfin: { /* call remaining finalizers */
1086 if (g->tobefnz && g->gckind != KGC_EMERGENCY) {
1087 int n = runafewfinalizers(L);
1088 return (n * GCFINALIZECOST);
1089 }
1090 else { /* emergency mode or no more finalizers */
1091 g->gcstate = GCSpause; /* finish collection */
1092 return 0;
1093 }
1094 }
1095 default: lua_assert(0); return 0;
1096 }
1097}
1098
1099
1100/*
1101** advances the garbage collector until it reaches a state allowed
1102** by 'statemask'
1103*/
1104void luaC_runtilstate (lua_State *L, int statesmask) {
1105 global_State *g = G(L);
1106 while (!testbit(statesmask, g->gcstate))
1107 singlestep(L);
1108}
1109
1110
1111/*
1112** get GC debt and convert it from Kb to 'work units' (avoid zero debt
1113** and overflows)
1114*/
1115static l_mem getdebt (global_State *g) {
1116 l_mem debt = g->GCdebt;
1117 int stepmul = g->gcstepmul;
1118 if (debt <= 0) return 0; /* minimal debt */
1119 else {
1120 debt = (debt / STEPMULADJ) + 1;
1121 debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
1122 return debt;
1123 }
1124}
1125
1126/*
1127** performs a basic GC step when collector is running
1128*/
1129void luaC_step (lua_State *L) {
1130 global_State *g = G(L);
1131 l_mem debt = getdebt(g); /* GC deficit (be paid now) */
1132 if (!g->gcrunning) { /* not running? */
1133 luaE_setdebt(g, -GCSTEPSIZE * 10); /* avoid being called too often */
1134 return;
1135 }
1136 do { /* repeat until pause or enough "credit" (negative debt) */
1137 lu_mem work = singlestep(L); /* perform one single step */
1138 debt -= work;
1139 } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
1140 if (g->gcstate == GCSpause)
1141 setpause(g); /* pause until next cycle */
1142 else {
1143 debt = (debt / g->gcstepmul) * STEPMULADJ; /* convert 'work units' to Kb */
1144 luaE_setdebt(g, debt);
1145 runafewfinalizers(L);
1146 }
1147}
1148
1149
1150/*
1151** Performs a full GC cycle; if 'isemergency', set a flag to avoid
1152** some operations which could change the interpreter state in some
1153** unexpected ways (running finalizers and shrinking some structures).
1154** Before running the collection, check 'keepinvariant'; if it is true,
1155** there may be some objects marked as black, so the collector has
1156** to sweep all objects to turn them back to white (as white has not
1157** changed, nothing will be collected).
1158*/
1159void luaC_fullgc (lua_State *L, int isemergency) {
1160 global_State *g = G(L);
1161 lua_assert(g->gckind == KGC_NORMAL);
1162 if (isemergency) g->gckind = KGC_EMERGENCY; /* set flag */
1163 if (keepinvariant(g)) { /* black objects? */
1164 entersweep(L); /* sweep everything to turn them back to white */
1165 }
1166 /* finish any pending sweep phase to start a new cycle */
1167 luaC_runtilstate(L, bitmask(GCSpause));
1168 luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */
1169 luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */
1170 /* estimate must be correct after a full GC cycle */
1171 lua_assert(g->GCestimate == gettotalbytes(g));
1172 luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */
1173 g->gckind = KGC_NORMAL;
1174 setpause(g);
1175}
1176
1177/* }====================================================== */
1178
1179
diff --git a/src/lua-5.3/lgc.h b/src/lua-5.3/lgc.h
new file mode 100644
index 0000000..425cd7c
--- /dev/null
+++ b/src/lua-5.3/lgc.h
@@ -0,0 +1,147 @@
1/*
2** $Id: lgc.h,v 2.91.1.1 2017/04/19 17:39:34 roberto Exp $
3** Garbage Collector
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lgc_h
8#define lgc_h
9
10
11#include "lobject.h"
12#include "lstate.h"
13
14/*
15** Collectable objects may have one of three colors: white, which
16** means the object is not marked; gray, which means the
17** object is marked, but its references may be not marked; and
18** black, which means that the object and all its references are marked.
19** The main invariant of the garbage collector, while marking objects,
20** is that a black object can never point to a white one. Moreover,
21** any gray object must be in a "gray list" (gray, grayagain, weak,
22** allweak, ephemeron) so that it can be visited again before finishing
23** the collection cycle. These lists have no meaning when the invariant
24** is not being enforced (e.g., sweep phase).
25*/
26
27
28
29/* how much to allocate before next GC step */
30#if !defined(GCSTEPSIZE)
31/* ~100 small strings */
32#define GCSTEPSIZE (cast_int(100 * sizeof(TString)))
33#endif
34
35
36/*
37** Possible states of the Garbage Collector
38*/
39#define GCSpropagate 0
40#define GCSatomic 1
41#define GCSswpallgc 2
42#define GCSswpfinobj 3
43#define GCSswptobefnz 4
44#define GCSswpend 5
45#define GCScallfin 6
46#define GCSpause 7
47
48
49#define issweepphase(g) \
50 (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend)
51
52
53/*
54** macro to tell when main invariant (white objects cannot point to black
55** ones) must be kept. During a collection, the sweep
56** phase may break the invariant, as objects turned white may point to
57** still-black objects. The invariant is restored when sweep ends and
58** all objects are white again.
59*/
60
61#define keepinvariant(g) ((g)->gcstate <= GCSatomic)
62
63
64/*
65** some useful bit tricks
66*/
67#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
68#define setbits(x,m) ((x) |= (m))
69#define testbits(x,m) ((x) & (m))
70#define bitmask(b) (1<<(b))
71#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
72#define l_setbit(x,b) setbits(x, bitmask(b))
73#define resetbit(x,b) resetbits(x, bitmask(b))
74#define testbit(x,b) testbits(x, bitmask(b))
75
76
77/* Layout for bit use in 'marked' field: */
78#define WHITE0BIT 0 /* object is white (type 0) */
79#define WHITE1BIT 1 /* object is white (type 1) */
80#define BLACKBIT 2 /* object is black */
81#define FINALIZEDBIT 3 /* object has been marked for finalization */
82/* bit 7 is currently used by tests (luaL_checkmemory) */
83
84#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
85
86
87#define iswhite(x) testbits((x)->marked, WHITEBITS)
88#define isblack(x) testbit((x)->marked, BLACKBIT)
89#define isgray(x) /* neither white nor black */ \
90 (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT)))
91
92#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT)
93
94#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS)
95#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
96#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked)
97
98#define changewhite(x) ((x)->marked ^= WHITEBITS)
99#define gray2black(x) l_setbit((x)->marked, BLACKBIT)
100
101#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
102
103
104/*
105** Does one step of collection when debt becomes positive. 'pre'/'pos'
106** allows some adjustments to be done only when needed. macro
107** 'condchangemem' is used only for heavy tests (forcing a full
108** GC cycle on every opportunity)
109*/
110#define luaC_condGC(L,pre,pos) \
111 { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \
112 condchangemem(L,pre,pos); }
113
114/* more often than not, 'pre'/'pos' are empty */
115#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0)
116
117
118#define luaC_barrier(L,p,v) ( \
119 (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
120 luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0))
121
122#define luaC_barrierback(L,p,v) ( \
123 (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
124 luaC_barrierback_(L,p) : cast_void(0))
125
126#define luaC_objbarrier(L,p,o) ( \
127 (isblack(p) && iswhite(o)) ? \
128 luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0))
129
130#define luaC_upvalbarrier(L,uv) ( \
131 (iscollectable((uv)->v) && !upisopen(uv)) ? \
132 luaC_upvalbarrier_(L,uv) : cast_void(0))
133
134LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
135LUAI_FUNC void luaC_freeallobjects (lua_State *L);
136LUAI_FUNC void luaC_step (lua_State *L);
137LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
138LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
139LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
140LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
141LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o);
142LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv);
143LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
144LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv);
145
146
147#endif
diff --git a/src/lua-5.3/license.txt b/src/lua-5.3/license.txt
new file mode 100644
index 0000000..5049d14
--- /dev/null
+++ b/src/lua-5.3/license.txt
@@ -0,0 +1,6 @@
1Copyright © 1994–2019 Lua.org, PUC-Rio.
2Permission 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:
3
4The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
5
6THE 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/src/lua-5.3/linit.c b/src/lua-5.3/linit.c
new file mode 100644
index 0000000..480da52
--- /dev/null
+++ b/src/lua-5.3/linit.c
@@ -0,0 +1,68 @@
1/*
2** $Id: linit.c,v 1.39.1.1 2017/04/19 17:20:42 roberto Exp $
3** Initialization of libraries for lua.c and other clients
4** See Copyright Notice in lua.h
5*/
6
7
8#define linit_c
9#define LUA_LIB
10
11/*
12** If you embed Lua in your program and need to open the standard
13** libraries, call luaL_openlibs in your program. If you need a
14** different set of libraries, copy this file to your project and edit
15** it to suit your needs.
16**
17** You can also *preload* libraries, so that a later 'require' can
18** open the library, which is already linked to the application.
19** For that, do the following code:
20**
21** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
22** lua_pushcfunction(L, luaopen_modname);
23** lua_setfield(L, -2, modname);
24** lua_pop(L, 1); // remove PRELOAD table
25*/
26
27#include "lprefix.h"
28
29
30#include <stddef.h>
31
32#include "lua.h"
33
34#include "lualib.h"
35#include "lauxlib.h"
36
37
38/*
39** these libs are loaded by lua.c and are readily available to any Lua
40** program
41*/
42static const luaL_Reg loadedlibs[] = {
43 {"_G", luaopen_base},
44 {LUA_LOADLIBNAME, luaopen_package},
45 {LUA_COLIBNAME, luaopen_coroutine},
46 {LUA_TABLIBNAME, luaopen_table},
47 {LUA_IOLIBNAME, luaopen_io},
48 {LUA_OSLIBNAME, luaopen_os},
49 {LUA_STRLIBNAME, luaopen_string},
50 {LUA_MATHLIBNAME, luaopen_math},
51 {LUA_UTF8LIBNAME, luaopen_utf8},
52 {LUA_DBLIBNAME, luaopen_debug},
53#if defined(LUA_COMPAT_BITLIB)
54 {LUA_BITLIBNAME, luaopen_bit32},
55#endif
56 {NULL, NULL}
57};
58
59
60LUALIB_API void luaL_openlibs (lua_State *L) {
61 const luaL_Reg *lib;
62 /* "require" functions from 'loadedlibs' and set results to global table */
63 for (lib = loadedlibs; lib->func; lib++) {
64 luaL_requiref(L, lib->name, lib->func, 1);
65 lua_pop(L, 1); /* remove lib */
66 }
67}
68
diff --git a/src/lua-5.3/liolib.c b/src/lua-5.3/liolib.c
new file mode 100644
index 0000000..8a9e75c
--- /dev/null
+++ b/src/lua-5.3/liolib.c
@@ -0,0 +1,776 @@
1/*
2** $Id: liolib.c,v 2.151.1.1 2017/04/19 17:29:57 roberto Exp $
3** Standard I/O (and system) library
4** See Copyright Notice in lua.h
5*/
6
7#define liolib_c
8#define LUA_LIB
9
10#include "lprefix.h"
11
12
13#include <ctype.h>
14#include <errno.h>
15#include <locale.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19
20#include "lua.h"
21
22#include "lauxlib.h"
23#include "lualib.h"
24
25
26
27
28/*
29** Change this macro to accept other modes for 'fopen' besides
30** the standard ones.
31*/
32#if !defined(l_checkmode)
33
34/* accepted extensions to 'mode' in 'fopen' */
35#if !defined(L_MODEEXT)
36#define L_MODEEXT "b"
37#endif
38
39/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */
40static int l_checkmode (const char *mode) {
41 return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&
42 (*mode != '+' || (++mode, 1)) && /* skip if char is '+' */
43 (strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */
44}
45
46#endif
47
48/*
49** {======================================================
50** l_popen spawns a new process connected to the current
51** one through the file streams.
52** =======================================================
53*/
54
55#if !defined(l_popen) /* { */
56
57#if defined(LUA_USE_POSIX) /* { */
58
59#define l_popen(L,c,m) (fflush(NULL), popen(c,m))
60#define l_pclose(L,file) (pclose(file))
61
62#elif defined(LUA_USE_WINDOWS) /* }{ */
63
64#define l_popen(L,c,m) (_popen(c,m))
65#define l_pclose(L,file) (_pclose(file))
66
67#else /* }{ */
68
69/* ISO C definitions */
70#define l_popen(L,c,m) \
71 ((void)((void)c, m), \
72 luaL_error(L, "'popen' not supported"), \
73 (FILE*)0)
74#define l_pclose(L,file) ((void)L, (void)file, -1)
75
76#endif /* } */
77
78#endif /* } */
79
80/* }====================================================== */
81
82
83#if !defined(l_getc) /* { */
84
85#if defined(LUA_USE_POSIX)
86#define l_getc(f) getc_unlocked(f)
87#define l_lockfile(f) flockfile(f)
88#define l_unlockfile(f) funlockfile(f)
89#else
90#define l_getc(f) getc(f)
91#define l_lockfile(f) ((void)0)
92#define l_unlockfile(f) ((void)0)
93#endif
94
95#endif /* } */
96
97
98/*
99** {======================================================
100** l_fseek: configuration for longer offsets
101** =======================================================
102*/
103
104#if !defined(l_fseek) /* { */
105
106#if defined(LUA_USE_POSIX) /* { */
107
108#include <sys/types.h>
109
110#define l_fseek(f,o,w) fseeko(f,o,w)
111#define l_ftell(f) ftello(f)
112#define l_seeknum off_t
113
114#elif defined(LUA_USE_WINDOWS) && !defined(_CRTIMP_TYPEINFO) \
115 && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */
116
117/* Windows (but not DDK) and Visual C++ 2005 or higher */
118#define l_fseek(f,o,w) _fseeki64(f,o,w)
119#define l_ftell(f) _ftelli64(f)
120#define l_seeknum __int64
121
122#else /* }{ */
123
124/* ISO C definitions */
125#define l_fseek(f,o,w) fseek(f,o,w)
126#define l_ftell(f) ftell(f)
127#define l_seeknum long
128
129#endif /* } */
130
131#endif /* } */
132
133/* }====================================================== */
134
135
136#define IO_PREFIX "_IO_"
137#define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1)
138#define IO_INPUT (IO_PREFIX "input")
139#define IO_OUTPUT (IO_PREFIX "output")
140
141
142typedef luaL_Stream LStream;
143
144
145#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
146
147#define isclosed(p) ((p)->closef == NULL)
148
149
150static int io_type (lua_State *L) {
151 LStream *p;
152 luaL_checkany(L, 1);
153 p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE);
154 if (p == NULL)
155 lua_pushnil(L); /* not a file */
156 else if (isclosed(p))
157 lua_pushliteral(L, "closed file");
158 else
159 lua_pushliteral(L, "file");
160 return 1;
161}
162
163
164static int f_tostring (lua_State *L) {
165 LStream *p = tolstream(L);
166 if (isclosed(p))
167 lua_pushliteral(L, "file (closed)");
168 else
169 lua_pushfstring(L, "file (%p)", p->f);
170 return 1;
171}
172
173
174static FILE *tofile (lua_State *L) {
175 LStream *p = tolstream(L);
176 if (isclosed(p))
177 luaL_error(L, "attempt to use a closed file");
178 lua_assert(p->f);
179 return p->f;
180}
181
182
183/*
184** When creating file handles, always creates a 'closed' file handle
185** before opening the actual file; so, if there is a memory error, the
186** handle is in a consistent state.
187*/
188static LStream *newprefile (lua_State *L) {
189 LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream));
190 p->closef = NULL; /* mark file handle as 'closed' */
191 luaL_setmetatable(L, LUA_FILEHANDLE);
192 return p;
193}
194
195
196/*
197** Calls the 'close' function from a file handle. The 'volatile' avoids
198** a bug in some versions of the Clang compiler (e.g., clang 3.0 for
199** 32 bits).
200*/
201static int aux_close (lua_State *L) {
202 LStream *p = tolstream(L);
203 volatile lua_CFunction cf = p->closef;
204 p->closef = NULL; /* mark stream as closed */
205 return (*cf)(L); /* close it */
206}
207
208
209static int f_close (lua_State *L) {
210 tofile(L); /* make sure argument is an open stream */
211 return aux_close(L);
212}
213
214
215static int io_close (lua_State *L) {
216 if (lua_isnone(L, 1)) /* no argument? */
217 lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */
218 return f_close(L);
219}
220
221
222static int f_gc (lua_State *L) {
223 LStream *p = tolstream(L);
224 if (!isclosed(p) && p->f != NULL)
225 aux_close(L); /* ignore closed and incompletely open files */
226 return 0;
227}
228
229
230/*
231** function to close regular files
232*/
233static int io_fclose (lua_State *L) {
234 LStream *p = tolstream(L);
235 int res = fclose(p->f);
236 return luaL_fileresult(L, (res == 0), NULL);
237}
238
239
240static LStream *newfile (lua_State *L) {
241 LStream *p = newprefile(L);
242 p->f = NULL;
243 p->closef = &io_fclose;
244 return p;
245}
246
247
248static void opencheck (lua_State *L, const char *fname, const char *mode) {
249 LStream *p = newfile(L);
250 p->f = fopen(fname, mode);
251 if (p->f == NULL)
252 luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno));
253}
254
255
256static int io_open (lua_State *L) {
257 const char *filename = luaL_checkstring(L, 1);
258 const char *mode = luaL_optstring(L, 2, "r");
259 LStream *p = newfile(L);
260 const char *md = mode; /* to traverse/check mode */
261 luaL_argcheck(L, l_checkmode(md), 2, "invalid mode");
262 p->f = fopen(filename, mode);
263 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
264}
265
266
267/*
268** function to close 'popen' files
269*/
270static int io_pclose (lua_State *L) {
271 LStream *p = tolstream(L);
272 return luaL_execresult(L, l_pclose(L, p->f));
273}
274
275
276static int io_popen (lua_State *L) {
277 const char *filename = luaL_checkstring(L, 1);
278 const char *mode = luaL_optstring(L, 2, "r");
279 LStream *p = newprefile(L);
280 p->f = l_popen(L, filename, mode);
281 p->closef = &io_pclose;
282 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
283}
284
285
286static int io_tmpfile (lua_State *L) {
287 LStream *p = newfile(L);
288 p->f = tmpfile();
289 return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
290}
291
292
293static FILE *getiofile (lua_State *L, const char *findex) {
294 LStream *p;
295 lua_getfield(L, LUA_REGISTRYINDEX, findex);
296 p = (LStream *)lua_touserdata(L, -1);
297 if (isclosed(p))
298 luaL_error(L, "standard %s file is closed", findex + IOPREF_LEN);
299 return p->f;
300}
301
302
303static int g_iofile (lua_State *L, const char *f, const char *mode) {
304 if (!lua_isnoneornil(L, 1)) {
305 const char *filename = lua_tostring(L, 1);
306 if (filename)
307 opencheck(L, filename, mode);
308 else {
309 tofile(L); /* check that it's a valid file handle */
310 lua_pushvalue(L, 1);
311 }
312 lua_setfield(L, LUA_REGISTRYINDEX, f);
313 }
314 /* return current value */
315 lua_getfield(L, LUA_REGISTRYINDEX, f);
316 return 1;
317}
318
319
320static int io_input (lua_State *L) {
321 return g_iofile(L, IO_INPUT, "r");
322}
323
324
325static int io_output (lua_State *L) {
326 return g_iofile(L, IO_OUTPUT, "w");
327}
328
329
330static int io_readline (lua_State *L);
331
332
333/*
334** maximum number of arguments to 'f:lines'/'io.lines' (it + 3 must fit
335** in the limit for upvalues of a closure)
336*/
337#define MAXARGLINE 250
338
339static void aux_lines (lua_State *L, int toclose) {
340 int n = lua_gettop(L) - 1; /* number of arguments to read */
341 luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments");
342 lua_pushinteger(L, n); /* number of arguments to read */
343 lua_pushboolean(L, toclose); /* close/not close file when finished */
344 lua_rotate(L, 2, 2); /* move 'n' and 'toclose' to their positions */
345 lua_pushcclosure(L, io_readline, 3 + n);
346}
347
348
349static int f_lines (lua_State *L) {
350 tofile(L); /* check that it's a valid file handle */
351 aux_lines(L, 0);
352 return 1;
353}
354
355
356static int io_lines (lua_State *L) {
357 int toclose;
358 if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */
359 if (lua_isnil(L, 1)) { /* no file name? */
360 lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */
361 lua_replace(L, 1); /* put it at index 1 */
362 tofile(L); /* check that it's a valid file handle */
363 toclose = 0; /* do not close it after iteration */
364 }
365 else { /* open a new file */
366 const char *filename = luaL_checkstring(L, 1);
367 opencheck(L, filename, "r");
368 lua_replace(L, 1); /* put file at index 1 */
369 toclose = 1; /* close it after iteration */
370 }
371 aux_lines(L, toclose);
372 return 1;
373}
374
375
376/*
377** {======================================================
378** READ
379** =======================================================
380*/
381
382
383/* maximum length of a numeral */
384#if !defined (L_MAXLENNUM)
385#define L_MAXLENNUM 200
386#endif
387
388
389/* auxiliary structure used by 'read_number' */
390typedef struct {
391 FILE *f; /* file being read */
392 int c; /* current character (look ahead) */
393 int n; /* number of elements in buffer 'buff' */
394 char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */
395} RN;
396
397
398/*
399** Add current char to buffer (if not out of space) and read next one
400*/
401static int nextc (RN *rn) {
402 if (rn->n >= L_MAXLENNUM) { /* buffer overflow? */
403 rn->buff[0] = '\0'; /* invalidate result */
404 return 0; /* fail */
405 }
406 else {
407 rn->buff[rn->n++] = rn->c; /* save current char */
408 rn->c = l_getc(rn->f); /* read next one */
409 return 1;
410 }
411}
412
413
414/*
415** Accept current char if it is in 'set' (of size 2)
416*/
417static int test2 (RN *rn, const char *set) {
418 if (rn->c == set[0] || rn->c == set[1])
419 return nextc(rn);
420 else return 0;
421}
422
423
424/*
425** Read a sequence of (hex)digits
426*/
427static int readdigits (RN *rn, int hex) {
428 int count = 0;
429 while ((hex ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn))
430 count++;
431 return count;
432}
433
434
435/*
436** Read a number: first reads a valid prefix of a numeral into a buffer.
437** Then it calls 'lua_stringtonumber' to check whether the format is
438** correct and to convert it to a Lua number
439*/
440static int read_number (lua_State *L, FILE *f) {
441 RN rn;
442 int count = 0;
443 int hex = 0;
444 char decp[2];
445 rn.f = f; rn.n = 0;
446 decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */
447 decp[1] = '.'; /* always accept a dot */
448 l_lockfile(rn.f);
449 do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
450 test2(&rn, "-+"); /* optional signal */
451 if (test2(&rn, "00")) {
452 if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */
453 else count = 1; /* count initial '0' as a valid digit */
454 }
455 count += readdigits(&rn, hex); /* integral part */
456 if (test2(&rn, decp)) /* decimal point? */
457 count += readdigits(&rn, hex); /* fractional part */
458 if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */
459 test2(&rn, "-+"); /* exponent signal */
460 readdigits(&rn, 0); /* exponent digits */
461 }
462 ungetc(rn.c, rn.f); /* unread look-ahead char */
463 l_unlockfile(rn.f);
464 rn.buff[rn.n] = '\0'; /* finish string */
465 if (lua_stringtonumber(L, rn.buff)) /* is this a valid number? */
466 return 1; /* ok */
467 else { /* invalid format */
468 lua_pushnil(L); /* "result" to be removed */
469 return 0; /* read fails */
470 }
471}
472
473
474static int test_eof (lua_State *L, FILE *f) {
475 int c = getc(f);
476 ungetc(c, f); /* no-op when c == EOF */
477 lua_pushliteral(L, "");
478 return (c != EOF);
479}
480
481
482static int read_line (lua_State *L, FILE *f, int chop) {
483 luaL_Buffer b;
484 int c = '\0';
485 luaL_buffinit(L, &b);
486 while (c != EOF && c != '\n') { /* repeat until end of line */
487 char *buff = luaL_prepbuffer(&b); /* preallocate buffer */
488 int i = 0;
489 l_lockfile(f); /* no memory errors can happen inside the lock */
490 while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n')
491 buff[i++] = c;
492 l_unlockfile(f);
493 luaL_addsize(&b, i);
494 }
495 if (!chop && c == '\n') /* want a newline and have one? */
496 luaL_addchar(&b, c); /* add ending newline to result */
497 luaL_pushresult(&b); /* close buffer */
498 /* return ok if read something (either a newline or something else) */
499 return (c == '\n' || lua_rawlen(L, -1) > 0);
500}
501
502
503static void read_all (lua_State *L, FILE *f) {
504 size_t nr;
505 luaL_Buffer b;
506 luaL_buffinit(L, &b);
507 do { /* read file in chunks of LUAL_BUFFERSIZE bytes */
508 char *p = luaL_prepbuffer(&b);
509 nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f);
510 luaL_addsize(&b, nr);
511 } while (nr == LUAL_BUFFERSIZE);
512 luaL_pushresult(&b); /* close buffer */
513}
514
515
516static int read_chars (lua_State *L, FILE *f, size_t n) {
517 size_t nr; /* number of chars actually read */
518 char *p;
519 luaL_Buffer b;
520 luaL_buffinit(L, &b);
521 p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */
522 nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */
523 luaL_addsize(&b, nr);
524 luaL_pushresult(&b); /* close buffer */
525 return (nr > 0); /* true iff read something */
526}
527
528
529static int g_read (lua_State *L, FILE *f, int first) {
530 int nargs = lua_gettop(L) - 1;
531 int success;
532 int n;
533 clearerr(f);
534 if (nargs == 0) { /* no arguments? */
535 success = read_line(L, f, 1);
536 n = first+1; /* to return 1 result */
537 }
538 else { /* ensure stack space for all results and for auxlib's buffer */
539 luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
540 success = 1;
541 for (n = first; nargs-- && success; n++) {
542 if (lua_type(L, n) == LUA_TNUMBER) {
543 size_t l = (size_t)luaL_checkinteger(L, n);
544 success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
545 }
546 else {
547 const char *p = luaL_checkstring(L, n);
548 if (*p == '*') p++; /* skip optional '*' (for compatibility) */
549 switch (*p) {
550 case 'n': /* number */
551 success = read_number(L, f);
552 break;
553 case 'l': /* line */
554 success = read_line(L, f, 1);
555 break;
556 case 'L': /* line with end-of-line */
557 success = read_line(L, f, 0);
558 break;
559 case 'a': /* file */
560 read_all(L, f); /* read entire file */
561 success = 1; /* always success */
562 break;
563 default:
564 return luaL_argerror(L, n, "invalid format");
565 }
566 }
567 }
568 }
569 if (ferror(f))
570 return luaL_fileresult(L, 0, NULL);
571 if (!success) {
572 lua_pop(L, 1); /* remove last result */
573 lua_pushnil(L); /* push nil instead */
574 }
575 return n - first;
576}
577
578
579static int io_read (lua_State *L) {
580 return g_read(L, getiofile(L, IO_INPUT), 1);
581}
582
583
584static int f_read (lua_State *L) {
585 return g_read(L, tofile(L), 2);
586}
587
588
589static int io_readline (lua_State *L) {
590 LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
591 int i;
592 int n = (int)lua_tointeger(L, lua_upvalueindex(2));
593 if (isclosed(p)) /* file is already closed? */
594 return luaL_error(L, "file is already closed");
595 lua_settop(L , 1);
596 luaL_checkstack(L, n, "too many arguments");
597 for (i = 1; i <= n; i++) /* push arguments to 'g_read' */
598 lua_pushvalue(L, lua_upvalueindex(3 + i));
599 n = g_read(L, p->f, 2); /* 'n' is number of results */
600 lua_assert(n > 0); /* should return at least a nil */
601 if (lua_toboolean(L, -n)) /* read at least one value? */
602 return n; /* return them */
603 else { /* first result is nil: EOF or error */
604 if (n > 1) { /* is there error information? */
605 /* 2nd result is error message */
606 return luaL_error(L, "%s", lua_tostring(L, -n + 1));
607 }
608 if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
609 lua_settop(L, 0);
610 lua_pushvalue(L, lua_upvalueindex(1));
611 aux_close(L); /* close it */
612 }
613 return 0;
614 }
615}
616
617/* }====================================================== */
618
619
620static int g_write (lua_State *L, FILE *f, int arg) {
621 int nargs = lua_gettop(L) - arg;
622 int status = 1;
623 for (; nargs--; arg++) {
624 if (lua_type(L, arg) == LUA_TNUMBER) {
625 /* optimization: could be done exactly as for strings */
626 int len = lua_isinteger(L, arg)
627 ? fprintf(f, LUA_INTEGER_FMT,
628 (LUAI_UACINT)lua_tointeger(L, arg))
629 : fprintf(f, LUA_NUMBER_FMT,
630 (LUAI_UACNUMBER)lua_tonumber(L, arg));
631 status = status && (len > 0);
632 }
633 else {
634 size_t l;
635 const char *s = luaL_checklstring(L, arg, &l);
636 status = status && (fwrite(s, sizeof(char), l, f) == l);
637 }
638 }
639 if (status) return 1; /* file handle already on stack top */
640 else return luaL_fileresult(L, status, NULL);
641}
642
643
644static int io_write (lua_State *L) {
645 return g_write(L, getiofile(L, IO_OUTPUT), 1);
646}
647
648
649static int f_write (lua_State *L) {
650 FILE *f = tofile(L);
651 lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */
652 return g_write(L, f, 2);
653}
654
655
656static int f_seek (lua_State *L) {
657 static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
658 static const char *const modenames[] = {"set", "cur", "end", NULL};
659 FILE *f = tofile(L);
660 int op = luaL_checkoption(L, 2, "cur", modenames);
661 lua_Integer p3 = luaL_optinteger(L, 3, 0);
662 l_seeknum offset = (l_seeknum)p3;
663 luaL_argcheck(L, (lua_Integer)offset == p3, 3,
664 "not an integer in proper range");
665 op = l_fseek(f, offset, mode[op]);
666 if (op)
667 return luaL_fileresult(L, 0, NULL); /* error */
668 else {
669 lua_pushinteger(L, (lua_Integer)l_ftell(f));
670 return 1;
671 }
672}
673
674
675static int f_setvbuf (lua_State *L) {
676 static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
677 static const char *const modenames[] = {"no", "full", "line", NULL};
678 FILE *f = tofile(L);
679 int op = luaL_checkoption(L, 2, NULL, modenames);
680 lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
681 int res = setvbuf(f, NULL, mode[op], (size_t)sz);
682 return luaL_fileresult(L, res == 0, NULL);
683}
684
685
686
687static int io_flush (lua_State *L) {
688 return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
689}
690
691
692static int f_flush (lua_State *L) {
693 return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
694}
695
696
697/*
698** functions for 'io' library
699*/
700static const luaL_Reg iolib[] = {
701 {"close", io_close},
702 {"flush", io_flush},
703 {"input", io_input},
704 {"lines", io_lines},
705 {"open", io_open},
706 {"output", io_output},
707 {"popen", io_popen},
708 {"read", io_read},
709 {"tmpfile", io_tmpfile},
710 {"type", io_type},
711 {"write", io_write},
712 {NULL, NULL}
713};
714
715
716/*
717** methods for file handles
718*/
719static const luaL_Reg flib[] = {
720 {"close", f_close},
721 {"flush", f_flush},
722 {"lines", f_lines},
723 {"read", f_read},
724 {"seek", f_seek},
725 {"setvbuf", f_setvbuf},
726 {"write", f_write},
727 {"__gc", f_gc},
728 {"__tostring", f_tostring},
729 {NULL, NULL}
730};
731
732
733static void createmeta (lua_State *L) {
734 luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
735 lua_pushvalue(L, -1); /* push metatable */
736 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
737 luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */
738 lua_pop(L, 1); /* pop new metatable */
739}
740
741
742/*
743** function to (not) close the standard files stdin, stdout, and stderr
744*/
745static int io_noclose (lua_State *L) {
746 LStream *p = tolstream(L);
747 p->closef = &io_noclose; /* keep file opened */
748 lua_pushnil(L);
749 lua_pushliteral(L, "cannot close standard file");
750 return 2;
751}
752
753
754static void createstdfile (lua_State *L, FILE *f, const char *k,
755 const char *fname) {
756 LStream *p = newprefile(L);
757 p->f = f;
758 p->closef = &io_noclose;
759 if (k != NULL) {
760 lua_pushvalue(L, -1);
761 lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */
762 }
763 lua_setfield(L, -2, fname); /* add file to module */
764}
765
766
767LUAMOD_API int luaopen_io (lua_State *L) {
768 luaL_newlib(L, iolib); /* new module */
769 createmeta(L);
770 /* create (and set) default files */
771 createstdfile(L, stdin, IO_INPUT, "stdin");
772 createstdfile(L, stdout, IO_OUTPUT, "stdout");
773 createstdfile(L, stderr, NULL, "stderr");
774 return 1;
775}
776
diff --git a/src/lua-5.3/llex.c b/src/lua-5.3/llex.c
new file mode 100644
index 0000000..b6d9a46
--- /dev/null
+++ b/src/lua-5.3/llex.c
@@ -0,0 +1,568 @@
1/*
2** $Id: llex.c,v 2.96.1.1 2017/04/19 17:20:42 roberto Exp $
3** Lexical Analyzer
4** See Copyright Notice in lua.h
5*/
6
7#define llex_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <locale.h>
14#include <string.h>
15
16#include "lua.h"
17
18#include "lctype.h"
19#include "ldebug.h"
20#include "ldo.h"
21#include "lgc.h"
22#include "llex.h"
23#include "lobject.h"
24#include "lparser.h"
25#include "lstate.h"
26#include "lstring.h"
27#include "ltable.h"
28#include "lzio.h"
29
30
31
32#define next(ls) (ls->current = zgetc(ls->z))
33
34
35
36#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
37
38
39/* ORDER RESERVED */
40static const char *const luaX_tokens [] = {
41 "and", "break", "do", "else", "elseif",
42 "end", "false", "for", "function", "goto", "if",
43 "in", "local", "nil", "not", "or", "repeat",
44 "return", "then", "true", "until", "while",
45 "//", "..", "...", "==", ">=", "<=", "~=",
46 "<<", ">>", "::", "<eof>",
47 "<number>", "<integer>", "<name>", "<string>"
48};
49
50
51#define save_and_next(ls) (save(ls, ls->current), next(ls))
52
53
54static l_noret lexerror (LexState *ls, const char *msg, int token);
55
56
57static void save (LexState *ls, int c) {
58 Mbuffer *b = ls->buff;
59 if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
60 size_t newsize;
61 if (luaZ_sizebuffer(b) >= MAX_SIZE/2)
62 lexerror(ls, "lexical element too long", 0);
63 newsize = luaZ_sizebuffer(b) * 2;
64 luaZ_resizebuffer(ls->L, b, newsize);
65 }
66 b->buffer[luaZ_bufflen(b)++] = cast(char, c);
67}
68
69
70void luaX_init (lua_State *L) {
71 int i;
72 TString *e = luaS_newliteral(L, LUA_ENV); /* create env name */
73 luaC_fix(L, obj2gco(e)); /* never collect this name */
74 for (i=0; i<NUM_RESERVED; i++) {
75 TString *ts = luaS_new(L, luaX_tokens[i]);
76 luaC_fix(L, obj2gco(ts)); /* reserved words are never collected */
77 ts->extra = cast_byte(i+1); /* reserved word */
78 }
79}
80
81
82const char *luaX_token2str (LexState *ls, int token) {
83 if (token < FIRST_RESERVED) { /* single-byte symbols? */
84 lua_assert(token == cast_uchar(token));
85 return luaO_pushfstring(ls->L, "'%c'", token);
86 }
87 else {
88 const char *s = luaX_tokens[token - FIRST_RESERVED];
89 if (token < TK_EOS) /* fixed format (symbols and reserved words)? */
90 return luaO_pushfstring(ls->L, "'%s'", s);
91 else /* names, strings, and numerals */
92 return s;
93 }
94}
95
96
97static const char *txtToken (LexState *ls, int token) {
98 switch (token) {
99 case TK_NAME: case TK_STRING:
100 case TK_FLT: case TK_INT:
101 save(ls, '\0');
102 return luaO_pushfstring(ls->L, "'%s'", luaZ_buffer(ls->buff));
103 default:
104 return luaX_token2str(ls, token);
105 }
106}
107
108
109static l_noret lexerror (LexState *ls, const char *msg, int token) {
110 msg = luaG_addinfo(ls->L, msg, ls->source, ls->linenumber);
111 if (token)
112 luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
113 luaD_throw(ls->L, LUA_ERRSYNTAX);
114}
115
116
117l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
118 lexerror(ls, msg, ls->t.token);
119}
120
121
122/*
123** creates a new string and anchors it in scanner's table so that
124** it will not be collected until the end of the compilation
125** (by that time it should be anchored somewhere)
126*/
127TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
128 lua_State *L = ls->L;
129 TValue *o; /* entry for 'str' */
130 TString *ts = luaS_newlstr(L, str, l); /* create new string */
131 setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
132 o = luaH_set(L, ls->h, L->top - 1);
133 if (ttisnil(o)) { /* not in use yet? */
134 /* boolean value does not need GC barrier;
135 table has no metatable, so it does not need to invalidate cache */
136 setbvalue(o, 1); /* t[string] = true */
137 luaC_checkGC(L);
138 }
139 else { /* string already present */
140 ts = tsvalue(keyfromval(o)); /* re-use value previously stored */
141 }
142 L->top--; /* remove string from stack */
143 return ts;
144}
145
146
147/*
148** increment line number and skips newline sequence (any of
149** \n, \r, \n\r, or \r\n)
150*/
151static void inclinenumber (LexState *ls) {
152 int old = ls->current;
153 lua_assert(currIsNewline(ls));
154 next(ls); /* skip '\n' or '\r' */
155 if (currIsNewline(ls) && ls->current != old)
156 next(ls); /* skip '\n\r' or '\r\n' */
157 if (++ls->linenumber >= MAX_INT)
158 lexerror(ls, "chunk has too many lines", 0);
159}
160
161
162void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
163 int firstchar) {
164 ls->t.token = 0;
165 ls->L = L;
166 ls->current = firstchar;
167 ls->lookahead.token = TK_EOS; /* no look-ahead token */
168 ls->z = z;
169 ls->fs = NULL;
170 ls->linenumber = 1;
171 ls->lastline = 1;
172 ls->source = source;
173 ls->envn = luaS_newliteral(L, LUA_ENV); /* get env name */
174 luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
175}
176
177
178
179/*
180** =======================================================
181** LEXICAL ANALYZER
182** =======================================================
183*/
184
185
186static int check_next1 (LexState *ls, int c) {
187 if (ls->current == c) {
188 next(ls);
189 return 1;
190 }
191 else return 0;
192}
193
194
195/*
196** Check whether current char is in set 'set' (with two chars) and
197** saves it
198*/
199static int check_next2 (LexState *ls, const char *set) {
200 lua_assert(set[2] == '\0');
201 if (ls->current == set[0] || ls->current == set[1]) {
202 save_and_next(ls);
203 return 1;
204 }
205 else return 0;
206}
207
208
209/* LUA_NUMBER */
210/*
211** this function is quite liberal in what it accepts, as 'luaO_str2num'
212** will reject ill-formed numerals.
213*/
214static int read_numeral (LexState *ls, SemInfo *seminfo) {
215 TValue obj;
216 const char *expo = "Ee";
217 int first = ls->current;
218 lua_assert(lisdigit(ls->current));
219 save_and_next(ls);
220 if (first == '0' && check_next2(ls, "xX")) /* hexadecimal? */
221 expo = "Pp";
222 for (;;) {
223 if (check_next2(ls, expo)) /* exponent part? */
224 check_next2(ls, "-+"); /* optional exponent sign */
225 if (lisxdigit(ls->current))
226 save_and_next(ls);
227 else if (ls->current == '.')
228 save_and_next(ls);
229 else break;
230 }
231 save(ls, '\0');
232 if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */
233 lexerror(ls, "malformed number", TK_FLT);
234 if (ttisinteger(&obj)) {
235 seminfo->i = ivalue(&obj);
236 return TK_INT;
237 }
238 else {
239 lua_assert(ttisfloat(&obj));
240 seminfo->r = fltvalue(&obj);
241 return TK_FLT;
242 }
243}
244
245
246/*
247** reads a sequence '[=*[' or ']=*]', leaving the last bracket.
248** If sequence is well formed, return its number of '='s + 2; otherwise,
249** return 1 if there is no '='s or 0 otherwise (an unfinished '[==...').
250*/
251static size_t skip_sep (LexState *ls) {
252 size_t count = 0;
253 int s = ls->current;
254 lua_assert(s == '[' || s == ']');
255 save_and_next(ls);
256 while (ls->current == '=') {
257 save_and_next(ls);
258 count++;
259 }
260 return (ls->current == s) ? count + 2
261 : (count == 0) ? 1
262 : 0;
263
264}
265
266
267static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) {
268 int line = ls->linenumber; /* initial line (for error message) */
269 save_and_next(ls); /* skip 2nd '[' */
270 if (currIsNewline(ls)) /* string starts with a newline? */
271 inclinenumber(ls); /* skip it */
272 for (;;) {
273 switch (ls->current) {
274 case EOZ: { /* error */
275 const char *what = (seminfo ? "string" : "comment");
276 const char *msg = luaO_pushfstring(ls->L,
277 "unfinished long %s (starting at line %d)", what, line);
278 lexerror(ls, msg, TK_EOS);
279 break; /* to avoid warnings */
280 }
281 case ']': {
282 if (skip_sep(ls) == sep) {
283 save_and_next(ls); /* skip 2nd ']' */
284 goto endloop;
285 }
286 break;
287 }
288 case '\n': case '\r': {
289 save(ls, '\n');
290 inclinenumber(ls);
291 if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
292 break;
293 }
294 default: {
295 if (seminfo) save_and_next(ls);
296 else next(ls);
297 }
298 }
299 } endloop:
300 if (seminfo)
301 seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep,
302 luaZ_bufflen(ls->buff) - 2 * sep);
303}
304
305
306static void esccheck (LexState *ls, int c, const char *msg) {
307 if (!c) {
308 if (ls->current != EOZ)
309 save_and_next(ls); /* add current to buffer for error message */
310 lexerror(ls, msg, TK_STRING);
311 }
312}
313
314
315static int gethexa (LexState *ls) {
316 save_and_next(ls);
317 esccheck (ls, lisxdigit(ls->current), "hexadecimal digit expected");
318 return luaO_hexavalue(ls->current);
319}
320
321
322static int readhexaesc (LexState *ls) {
323 int r = gethexa(ls);
324 r = (r << 4) + gethexa(ls);
325 luaZ_buffremove(ls->buff, 2); /* remove saved chars from buffer */
326 return r;
327}
328
329
330static unsigned long readutf8esc (LexState *ls) {
331 unsigned long r;
332 int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */
333 save_and_next(ls); /* skip 'u' */
334 esccheck(ls, ls->current == '{', "missing '{'");
335 r = gethexa(ls); /* must have at least one digit */
336 while ((save_and_next(ls), lisxdigit(ls->current))) {
337 i++;
338 r = (r << 4) + luaO_hexavalue(ls->current);
339 esccheck(ls, r <= 0x10FFFF, "UTF-8 value too large");
340 }
341 esccheck(ls, ls->current == '}', "missing '}'");
342 next(ls); /* skip '}' */
343 luaZ_buffremove(ls->buff, i); /* remove saved chars from buffer */
344 return r;
345}
346
347
348static void utf8esc (LexState *ls) {
349 char buff[UTF8BUFFSZ];
350 int n = luaO_utf8esc(buff, readutf8esc(ls));
351 for (; n > 0; n--) /* add 'buff' to string */
352 save(ls, buff[UTF8BUFFSZ - n]);
353}
354
355
356static int readdecesc (LexState *ls) {
357 int i;
358 int r = 0; /* result accumulator */
359 for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */
360 r = 10*r + ls->current - '0';
361 save_and_next(ls);
362 }
363 esccheck(ls, r <= UCHAR_MAX, "decimal escape too large");
364 luaZ_buffremove(ls->buff, i); /* remove read digits from buffer */
365 return r;
366}
367
368
369static void read_string (LexState *ls, int del, SemInfo *seminfo) {
370 save_and_next(ls); /* keep delimiter (for error messages) */
371 while (ls->current != del) {
372 switch (ls->current) {
373 case EOZ:
374 lexerror(ls, "unfinished string", TK_EOS);
375 break; /* to avoid warnings */
376 case '\n':
377 case '\r':
378 lexerror(ls, "unfinished string", TK_STRING);
379 break; /* to avoid warnings */
380 case '\\': { /* escape sequences */
381 int c; /* final character to be saved */
382 save_and_next(ls); /* keep '\\' for error messages */
383 switch (ls->current) {
384 case 'a': c = '\a'; goto read_save;
385 case 'b': c = '\b'; goto read_save;
386 case 'f': c = '\f'; goto read_save;
387 case 'n': c = '\n'; goto read_save;
388 case 'r': c = '\r'; goto read_save;
389 case 't': c = '\t'; goto read_save;
390 case 'v': c = '\v'; goto read_save;
391 case 'x': c = readhexaesc(ls); goto read_save;
392 case 'u': utf8esc(ls); goto no_save;
393 case '\n': case '\r':
394 inclinenumber(ls); c = '\n'; goto only_save;
395 case '\\': case '\"': case '\'':
396 c = ls->current; goto read_save;
397 case EOZ: goto no_save; /* will raise an error next loop */
398 case 'z': { /* zap following span of spaces */
399 luaZ_buffremove(ls->buff, 1); /* remove '\\' */
400 next(ls); /* skip the 'z' */
401 while (lisspace(ls->current)) {
402 if (currIsNewline(ls)) inclinenumber(ls);
403 else next(ls);
404 }
405 goto no_save;
406 }
407 default: {
408 esccheck(ls, lisdigit(ls->current), "invalid escape sequence");
409 c = readdecesc(ls); /* digital escape '\ddd' */
410 goto only_save;
411 }
412 }
413 read_save:
414 next(ls);
415 /* go through */
416 only_save:
417 luaZ_buffremove(ls->buff, 1); /* remove '\\' */
418 save(ls, c);
419 /* go through */
420 no_save: break;
421 }
422 default:
423 save_and_next(ls);
424 }
425 }
426 save_and_next(ls); /* skip delimiter */
427 seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
428 luaZ_bufflen(ls->buff) - 2);
429}
430
431
432static int llex (LexState *ls, SemInfo *seminfo) {
433 luaZ_resetbuffer(ls->buff);
434 for (;;) {
435 switch (ls->current) {
436 case '\n': case '\r': { /* line breaks */
437 inclinenumber(ls);
438 break;
439 }
440 case ' ': case '\f': case '\t': case '\v': { /* spaces */
441 next(ls);
442 break;
443 }
444 case '-': { /* '-' or '--' (comment) */
445 next(ls);
446 if (ls->current != '-') return '-';
447 /* else is a comment */
448 next(ls);
449 if (ls->current == '[') { /* long comment? */
450 size_t sep = skip_sep(ls);
451 luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */
452 if (sep >= 2) {
453 read_long_string(ls, NULL, sep); /* skip long comment */
454 luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */
455 break;
456 }
457 }
458 /* else short comment */
459 while (!currIsNewline(ls) && ls->current != EOZ)
460 next(ls); /* skip until end of line (or end of file) */
461 break;
462 }
463 case '[': { /* long string or simply '[' */
464 size_t sep = skip_sep(ls);
465 if (sep >= 2) {
466 read_long_string(ls, seminfo, sep);
467 return TK_STRING;
468 }
469 else if (sep == 0) /* '[=...' missing second bracket */
470 lexerror(ls, "invalid long string delimiter", TK_STRING);
471 return '[';
472 }
473 case '=': {
474 next(ls);
475 if (check_next1(ls, '=')) return TK_EQ;
476 else return '=';
477 }
478 case '<': {
479 next(ls);
480 if (check_next1(ls, '=')) return TK_LE;
481 else if (check_next1(ls, '<')) return TK_SHL;
482 else return '<';
483 }
484 case '>': {
485 next(ls);
486 if (check_next1(ls, '=')) return TK_GE;
487 else if (check_next1(ls, '>')) return TK_SHR;
488 else return '>';
489 }
490 case '/': {
491 next(ls);
492 if (check_next1(ls, '/')) return TK_IDIV;
493 else return '/';
494 }
495 case '~': {
496 next(ls);
497 if (check_next1(ls, '=')) return TK_NE;
498 else return '~';
499 }
500 case ':': {
501 next(ls);
502 if (check_next1(ls, ':')) return TK_DBCOLON;
503 else return ':';
504 }
505 case '"': case '\'': { /* short literal strings */
506 read_string(ls, ls->current, seminfo);
507 return TK_STRING;
508 }
509 case '.': { /* '.', '..', '...', or number */
510 save_and_next(ls);
511 if (check_next1(ls, '.')) {
512 if (check_next1(ls, '.'))
513 return TK_DOTS; /* '...' */
514 else return TK_CONCAT; /* '..' */
515 }
516 else if (!lisdigit(ls->current)) return '.';
517 else return read_numeral(ls, seminfo);
518 }
519 case '0': case '1': case '2': case '3': case '4':
520 case '5': case '6': case '7': case '8': case '9': {
521 return read_numeral(ls, seminfo);
522 }
523 case EOZ: {
524 return TK_EOS;
525 }
526 default: {
527 if (lislalpha(ls->current)) { /* identifier or reserved word? */
528 TString *ts;
529 do {
530 save_and_next(ls);
531 } while (lislalnum(ls->current));
532 ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
533 luaZ_bufflen(ls->buff));
534 seminfo->ts = ts;
535 if (isreserved(ts)) /* reserved word? */
536 return ts->extra - 1 + FIRST_RESERVED;
537 else {
538 return TK_NAME;
539 }
540 }
541 else { /* single-char tokens (+ - / ...) */
542 int c = ls->current;
543 next(ls);
544 return c;
545 }
546 }
547 }
548 }
549}
550
551
552void luaX_next (LexState *ls) {
553 ls->lastline = ls->linenumber;
554 if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
555 ls->t = ls->lookahead; /* use this one */
556 ls->lookahead.token = TK_EOS; /* and discharge it */
557 }
558 else
559 ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
560}
561
562
563int luaX_lookahead (LexState *ls) {
564 lua_assert(ls->lookahead.token == TK_EOS);
565 ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
566 return ls->lookahead.token;
567}
568
diff --git a/src/lua-5.3/llex.h b/src/lua-5.3/llex.h
new file mode 100644
index 0000000..2ed0af6
--- /dev/null
+++ b/src/lua-5.3/llex.h
@@ -0,0 +1,85 @@
1/*
2** $Id: llex.h,v 1.79.1.1 2017/04/19 17:20:42 roberto Exp $
3** Lexical Analyzer
4** See Copyright Notice in lua.h
5*/
6
7#ifndef llex_h
8#define llex_h
9
10#include "lobject.h"
11#include "lzio.h"
12
13
14#define FIRST_RESERVED 257
15
16
17#if !defined(LUA_ENV)
18#define LUA_ENV "_ENV"
19#endif
20
21
22/*
23* WARNING: if you change the order of this enumeration,
24* grep "ORDER RESERVED"
25*/
26enum RESERVED {
27 /* terminal symbols denoted by reserved words */
28 TK_AND = FIRST_RESERVED, TK_BREAK,
29 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
30 TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
31 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
32 /* other terminal symbols */
33 TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
34 TK_SHL, TK_SHR,
35 TK_DBCOLON, TK_EOS,
36 TK_FLT, TK_INT, TK_NAME, TK_STRING
37};
38
39/* number of reserved words */
40#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
41
42
43typedef union {
44 lua_Number r;
45 lua_Integer i;
46 TString *ts;
47} SemInfo; /* semantics information */
48
49
50typedef struct Token {
51 int token;
52 SemInfo seminfo;
53} Token;
54
55
56/* state of the lexer plus state of the parser when shared by all
57 functions */
58typedef struct LexState {
59 int current; /* current character (charint) */
60 int linenumber; /* input line counter */
61 int lastline; /* line of last token 'consumed' */
62 Token t; /* current token */
63 Token lookahead; /* look ahead token */
64 struct FuncState *fs; /* current function (parser) */
65 struct lua_State *L;
66 ZIO *z; /* input stream */
67 Mbuffer *buff; /* buffer for tokens */
68 Table *h; /* to avoid collection/reuse strings */
69 struct Dyndata *dyd; /* dynamic structures used by the parser */
70 TString *source; /* current source name */
71 TString *envn; /* environment variable name */
72} LexState;
73
74
75LUAI_FUNC void luaX_init (lua_State *L);
76LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
77 TString *source, int firstchar);
78LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
79LUAI_FUNC void luaX_next (LexState *ls);
80LUAI_FUNC int luaX_lookahead (LexState *ls);
81LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s);
82LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
83
84
85#endif
diff --git a/src/lua-5.3/llimits.h b/src/lua-5.3/llimits.h
new file mode 100644
index 0000000..d1036f6
--- /dev/null
+++ b/src/lua-5.3/llimits.h
@@ -0,0 +1,323 @@
1/*
2** $Id: llimits.h,v 1.141.1.1 2017/04/19 17:20:42 roberto Exp $
3** Limits, basic types, and some other 'installation-dependent' definitions
4** See Copyright Notice in lua.h
5*/
6
7#ifndef llimits_h
8#define llimits_h
9
10
11#include <limits.h>
12#include <stddef.h>
13
14
15#include "lua.h"
16
17/*
18** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count
19** the total memory used by Lua (in bytes). Usually, 'size_t' and
20** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines.
21*/
22#if defined(LUAI_MEM) /* { external definitions? */
23typedef LUAI_UMEM lu_mem;
24typedef LUAI_MEM l_mem;
25#elif LUAI_BITSINT >= 32 /* }{ */
26typedef size_t lu_mem;
27typedef ptrdiff_t l_mem;
28#else /* 16-bit ints */ /* }{ */
29typedef unsigned long lu_mem;
30typedef long l_mem;
31#endif /* } */
32
33
34/* chars used as small naturals (so that 'char' is reserved for characters) */
35typedef unsigned char lu_byte;
36
37
38/* maximum value for size_t */
39#define MAX_SIZET ((size_t)(~(size_t)0))
40
41/* maximum size visible for Lua (must be representable in a lua_Integer */
42#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \
43 : (size_t)(LUA_MAXINTEGER))
44
45
46#define MAX_LUMEM ((lu_mem)(~(lu_mem)0))
47
48#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1))
49
50
51#define MAX_INT INT_MAX /* maximum value of an int */
52
53
54/*
55** conversion of pointer to unsigned integer:
56** this is for hashing only; there is no problem if the integer
57** cannot hold the whole pointer value
58*/
59#define point2uint(p) ((unsigned int)((size_t)(p) & UINT_MAX))
60
61
62
63/* type to ensure maximum alignment */
64#if defined(LUAI_USER_ALIGNMENT_T)
65typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
66#else
67typedef union {
68 lua_Number n;
69 double u;
70 void *s;
71 lua_Integer i;
72 long l;
73} L_Umaxalign;
74#endif
75
76
77
78/* types of 'usual argument conversions' for lua_Number and lua_Integer */
79typedef LUAI_UACNUMBER l_uacNumber;
80typedef LUAI_UACINT l_uacInt;
81
82
83/* internal assertions for in-house debugging */
84#if defined(lua_assert)
85#define check_exp(c,e) (lua_assert(c), (e))
86/* to avoid problems with conditions too long */
87#define lua_longassert(c) ((c) ? (void)0 : lua_assert(0))
88#else
89#define lua_assert(c) ((void)0)
90#define check_exp(c,e) (e)
91#define lua_longassert(c) ((void)0)
92#endif
93
94/*
95** assertion for checking API calls
96*/
97#if !defined(luai_apicheck)
98#define luai_apicheck(l,e) lua_assert(e)
99#endif
100
101#define api_check(l,e,msg) luai_apicheck(l,(e) && msg)
102
103
104/* macro to avoid warnings about unused variables */
105#if !defined(UNUSED)
106#define UNUSED(x) ((void)(x))
107#endif
108
109
110/* type casts (a macro highlights casts in the code) */
111#define cast(t, exp) ((t)(exp))
112
113#define cast_void(i) cast(void, (i))
114#define cast_byte(i) cast(lu_byte, (i))
115#define cast_num(i) cast(lua_Number, (i))
116#define cast_int(i) cast(int, (i))
117#define cast_uchar(i) cast(unsigned char, (i))
118
119
120/* cast a signed lua_Integer to lua_Unsigned */
121#if !defined(l_castS2U)
122#define l_castS2U(i) ((lua_Unsigned)(i))
123#endif
124
125/*
126** cast a lua_Unsigned to a signed lua_Integer; this cast is
127** not strict ISO C, but two-complement architectures should
128** work fine.
129*/
130#if !defined(l_castU2S)
131#define l_castU2S(i) ((lua_Integer)(i))
132#endif
133
134
135/*
136** non-return type
137*/
138#if defined(__GNUC__)
139#define l_noret void __attribute__((noreturn))
140#elif defined(_MSC_VER) && _MSC_VER >= 1200
141#define l_noret void __declspec(noreturn)
142#else
143#define l_noret void
144#endif
145
146
147
148/*
149** maximum depth for nested C calls and syntactical nested non-terminals
150** in a program. (Value must fit in an unsigned short int.)
151*/
152#if !defined(LUAI_MAXCCALLS)
153#define LUAI_MAXCCALLS 200
154#endif
155
156
157
158/*
159** type for virtual-machine instructions;
160** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
161*/
162#if LUAI_BITSINT >= 32
163typedef unsigned int Instruction;
164#else
165typedef unsigned long Instruction;
166#endif
167
168
169
170/*
171** Maximum length for short strings, that is, strings that are
172** internalized. (Cannot be smaller than reserved words or tags for
173** metamethods, as these strings must be internalized;
174** #("function") = 8, #("__newindex") = 10.)
175*/
176#if !defined(LUAI_MAXSHORTLEN)
177#define LUAI_MAXSHORTLEN 40
178#endif
179
180
181/*
182** Initial size for the string table (must be power of 2).
183** The Lua core alone registers ~50 strings (reserved words +
184** metaevent keys + a few others). Libraries would typically add
185** a few dozens more.
186*/
187#if !defined(MINSTRTABSIZE)
188#define MINSTRTABSIZE 128
189#endif
190
191
192/*
193** Size of cache for strings in the API. 'N' is the number of
194** sets (better be a prime) and "M" is the size of each set (M == 1
195** makes a direct cache.)
196*/
197#if !defined(STRCACHE_N)
198#define STRCACHE_N 53
199#define STRCACHE_M 2
200#endif
201
202
203/* minimum size for string buffer */
204#if !defined(LUA_MINBUFFER)
205#define LUA_MINBUFFER 32
206#endif
207
208
209/*
210** macros that are executed whenever program enters the Lua core
211** ('lua_lock') and leaves the core ('lua_unlock')
212*/
213#if !defined(lua_lock)
214#define lua_lock(L) ((void) 0)
215#define lua_unlock(L) ((void) 0)
216#endif
217
218/*
219** macro executed during Lua functions at points where the
220** function can yield.
221*/
222#if !defined(luai_threadyield)
223#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
224#endif
225
226
227/*
228** these macros allow user-specific actions on threads when you defined
229** LUAI_EXTRASPACE and need to do something extra when a thread is
230** created/deleted/resumed/yielded.
231*/
232#if !defined(luai_userstateopen)
233#define luai_userstateopen(L) ((void)L)
234#endif
235
236#if !defined(luai_userstateclose)
237#define luai_userstateclose(L) ((void)L)
238#endif
239
240#if !defined(luai_userstatethread)
241#define luai_userstatethread(L,L1) ((void)L)
242#endif
243
244#if !defined(luai_userstatefree)
245#define luai_userstatefree(L,L1) ((void)L)
246#endif
247
248#if !defined(luai_userstateresume)
249#define luai_userstateresume(L,n) ((void)L)
250#endif
251
252#if !defined(luai_userstateyield)
253#define luai_userstateyield(L,n) ((void)L)
254#endif
255
256
257
258/*
259** The luai_num* macros define the primitive operations over numbers.
260*/
261
262/* floor division (defined as 'floor(a/b)') */
263#if !defined(luai_numidiv)
264#define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b)))
265#endif
266
267/* float division */
268#if !defined(luai_numdiv)
269#define luai_numdiv(L,a,b) ((a)/(b))
270#endif
271
272/*
273** modulo: defined as 'a - floor(a/b)*b'; this definition gives NaN when
274** 'b' is huge, but the result should be 'a'. 'fmod' gives the result of
275** 'a - trunc(a/b)*b', and therefore must be corrected when 'trunc(a/b)
276** ~= floor(a/b)'. That happens when the division has a non-integer
277** negative result, which is equivalent to the test below.
278*/
279#if !defined(luai_nummod)
280#define luai_nummod(L,a,b,m) \
281 { (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); }
282#endif
283
284/* exponentiation */
285#if !defined(luai_numpow)
286#define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b))
287#endif
288
289/* the others are quite standard operations */
290#if !defined(luai_numadd)
291#define luai_numadd(L,a,b) ((a)+(b))
292#define luai_numsub(L,a,b) ((a)-(b))
293#define luai_nummul(L,a,b) ((a)*(b))
294#define luai_numunm(L,a) (-(a))
295#define luai_numeq(a,b) ((a)==(b))
296#define luai_numlt(a,b) ((a)<(b))
297#define luai_numle(a,b) ((a)<=(b))
298#define luai_numisnan(a) (!luai_numeq((a), (a)))
299#endif
300
301
302
303
304
305/*
306** macro to control inclusion of some hard tests on stack reallocation
307*/
308#if !defined(HARDSTACKTESTS)
309#define condmovestack(L,pre,pos) ((void)0)
310#else
311/* realloc stack keeping its size */
312#define condmovestack(L,pre,pos) \
313 { int sz_ = (L)->stacksize; pre; luaD_reallocstack((L), sz_); pos; }
314#endif
315
316#if !defined(HARDMEMTESTS)
317#define condchangemem(L,pre,pos) ((void)0)
318#else
319#define condchangemem(L,pre,pos) \
320 { if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } }
321#endif
322
323#endif
diff --git a/src/lua-5.3/lmathlib.c b/src/lua-5.3/lmathlib.c
new file mode 100644
index 0000000..7ef7e59
--- /dev/null
+++ b/src/lua-5.3/lmathlib.c
@@ -0,0 +1,410 @@
1/*
2** $Id: lmathlib.c,v 1.119.1.1 2017/04/19 17:20:42 roberto Exp $
3** Standard mathematical library
4** See Copyright Notice in lua.h
5*/
6
7#define lmathlib_c
8#define LUA_LIB
9
10#include "lprefix.h"
11
12
13#include <stdlib.h>
14#include <math.h>
15
16#include "lua.h"
17
18#include "lauxlib.h"
19#include "lualib.h"
20
21
22#undef PI
23#define PI (l_mathop(3.141592653589793238462643383279502884))
24
25
26#if !defined(l_rand) /* { */
27#if defined(LUA_USE_POSIX)
28#define l_rand() random()
29#define l_srand(x) srandom(x)
30#define L_RANDMAX 2147483647 /* (2^31 - 1), following POSIX */
31#else
32#define l_rand() rand()
33#define l_srand(x) srand(x)
34#define L_RANDMAX RAND_MAX
35#endif
36#endif /* } */
37
38
39static int math_abs (lua_State *L) {
40 if (lua_isinteger(L, 1)) {
41 lua_Integer n = lua_tointeger(L, 1);
42 if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n);
43 lua_pushinteger(L, n);
44 }
45 else
46 lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
47 return 1;
48}
49
50static int math_sin (lua_State *L) {
51 lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
52 return 1;
53}
54
55static int math_cos (lua_State *L) {
56 lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
57 return 1;
58}
59
60static int math_tan (lua_State *L) {
61 lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
62 return 1;
63}
64
65static int math_asin (lua_State *L) {
66 lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
67 return 1;
68}
69
70static int math_acos (lua_State *L) {
71 lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
72 return 1;
73}
74
75static int math_atan (lua_State *L) {
76 lua_Number y = luaL_checknumber(L, 1);
77 lua_Number x = luaL_optnumber(L, 2, 1);
78 lua_pushnumber(L, l_mathop(atan2)(y, x));
79 return 1;
80}
81
82
83static int math_toint (lua_State *L) {
84 int valid;
85 lua_Integer n = lua_tointegerx(L, 1, &valid);
86 if (valid)
87 lua_pushinteger(L, n);
88 else {
89 luaL_checkany(L, 1);
90 lua_pushnil(L); /* value is not convertible to integer */
91 }
92 return 1;
93}
94
95
96static void pushnumint (lua_State *L, lua_Number d) {
97 lua_Integer n;
98 if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */
99 lua_pushinteger(L, n); /* result is integer */
100 else
101 lua_pushnumber(L, d); /* result is float */
102}
103
104
105static int math_floor (lua_State *L) {
106 if (lua_isinteger(L, 1))
107 lua_settop(L, 1); /* integer is its own floor */
108 else {
109 lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1));
110 pushnumint(L, d);
111 }
112 return 1;
113}
114
115
116static int math_ceil (lua_State *L) {
117 if (lua_isinteger(L, 1))
118 lua_settop(L, 1); /* integer is its own ceil */
119 else {
120 lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1));
121 pushnumint(L, d);
122 }
123 return 1;
124}
125
126
127static int math_fmod (lua_State *L) {
128 if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) {
129 lua_Integer d = lua_tointeger(L, 2);
130 if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */
131 luaL_argcheck(L, d != 0, 2, "zero");
132 lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */
133 }
134 else
135 lua_pushinteger(L, lua_tointeger(L, 1) % d);
136 }
137 else
138 lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
139 luaL_checknumber(L, 2)));
140 return 1;
141}
142
143
144/*
145** next function does not use 'modf', avoiding problems with 'double*'
146** (which is not compatible with 'float*') when lua_Number is not
147** 'double'.
148*/
149static int math_modf (lua_State *L) {
150 if (lua_isinteger(L ,1)) {
151 lua_settop(L, 1); /* number is its own integer part */
152 lua_pushnumber(L, 0); /* no fractional part */
153 }
154 else {
155 lua_Number n = luaL_checknumber(L, 1);
156 /* integer part (rounds toward zero) */
157 lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n);
158 pushnumint(L, ip);
159 /* fractional part (test needed for inf/-inf) */
160 lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip));
161 }
162 return 2;
163}
164
165
166static int math_sqrt (lua_State *L) {
167 lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
168 return 1;
169}
170
171
172static int math_ult (lua_State *L) {
173 lua_Integer a = luaL_checkinteger(L, 1);
174 lua_Integer b = luaL_checkinteger(L, 2);
175 lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b);
176 return 1;
177}
178
179static int math_log (lua_State *L) {
180 lua_Number x = luaL_checknumber(L, 1);
181 lua_Number res;
182 if (lua_isnoneornil(L, 2))
183 res = l_mathop(log)(x);
184 else {
185 lua_Number base = luaL_checknumber(L, 2);
186#if !defined(LUA_USE_C89)
187 if (base == l_mathop(2.0))
188 res = l_mathop(log2)(x); else
189#endif
190 if (base == l_mathop(10.0))
191 res = l_mathop(log10)(x);
192 else
193 res = l_mathop(log)(x)/l_mathop(log)(base);
194 }
195 lua_pushnumber(L, res);
196 return 1;
197}
198
199static int math_exp (lua_State *L) {
200 lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
201 return 1;
202}
203
204static int math_deg (lua_State *L) {
205 lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI));
206 return 1;
207}
208
209static int math_rad (lua_State *L) {
210 lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0)));
211 return 1;
212}
213
214
215static int math_min (lua_State *L) {
216 int n = lua_gettop(L); /* number of arguments */
217 int imin = 1; /* index of current minimum value */
218 int i;
219 luaL_argcheck(L, n >= 1, 1, "value expected");
220 for (i = 2; i <= n; i++) {
221 if (lua_compare(L, i, imin, LUA_OPLT))
222 imin = i;
223 }
224 lua_pushvalue(L, imin);
225 return 1;
226}
227
228
229static int math_max (lua_State *L) {
230 int n = lua_gettop(L); /* number of arguments */
231 int imax = 1; /* index of current maximum value */
232 int i;
233 luaL_argcheck(L, n >= 1, 1, "value expected");
234 for (i = 2; i <= n; i++) {
235 if (lua_compare(L, imax, i, LUA_OPLT))
236 imax = i;
237 }
238 lua_pushvalue(L, imax);
239 return 1;
240}
241
242/*
243** This function uses 'double' (instead of 'lua_Number') to ensure that
244** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0'
245** will keep full precision (ensuring that 'r' is always less than 1.0.)
246*/
247static int math_random (lua_State *L) {
248 lua_Integer low, up;
249 double r = (double)l_rand() * (1.0 / ((double)L_RANDMAX + 1.0));
250 switch (lua_gettop(L)) { /* check number of arguments */
251 case 0: { /* no arguments */
252 lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */
253 return 1;
254 }
255 case 1: { /* only upper limit */
256 low = 1;
257 up = luaL_checkinteger(L, 1);
258 break;
259 }
260 case 2: { /* lower and upper limits */
261 low = luaL_checkinteger(L, 1);
262 up = luaL_checkinteger(L, 2);
263 break;
264 }
265 default: return luaL_error(L, "wrong number of arguments");
266 }
267 /* random integer in the interval [low, up] */
268 luaL_argcheck(L, low <= up, 1, "interval is empty");
269 luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1,
270 "interval too large");
271 r *= (double)(up - low) + 1.0;
272 lua_pushinteger(L, (lua_Integer)r + low);
273 return 1;
274}
275
276
277static int math_randomseed (lua_State *L) {
278 l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1));
279 (void)l_rand(); /* discard first value to avoid undesirable correlations */
280 return 0;
281}
282
283
284static int math_type (lua_State *L) {
285 if (lua_type(L, 1) == LUA_TNUMBER) {
286 if (lua_isinteger(L, 1))
287 lua_pushliteral(L, "integer");
288 else
289 lua_pushliteral(L, "float");
290 }
291 else {
292 luaL_checkany(L, 1);
293 lua_pushnil(L);
294 }
295 return 1;
296}
297
298
299/*
300** {==================================================================
301** Deprecated functions (for compatibility only)
302** ===================================================================
303*/
304#if defined(LUA_COMPAT_MATHLIB)
305
306static int math_cosh (lua_State *L) {
307 lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
308 return 1;
309}
310
311static int math_sinh (lua_State *L) {
312 lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
313 return 1;
314}
315
316static int math_tanh (lua_State *L) {
317 lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
318 return 1;
319}
320
321static int math_pow (lua_State *L) {
322 lua_Number x = luaL_checknumber(L, 1);
323 lua_Number y = luaL_checknumber(L, 2);
324 lua_pushnumber(L, l_mathop(pow)(x, y));
325 return 1;
326}
327
328static int math_frexp (lua_State *L) {
329 int e;
330 lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
331 lua_pushinteger(L, e);
332 return 2;
333}
334
335static int math_ldexp (lua_State *L) {
336 lua_Number x = luaL_checknumber(L, 1);
337 int ep = (int)luaL_checkinteger(L, 2);
338 lua_pushnumber(L, l_mathop(ldexp)(x, ep));
339 return 1;
340}
341
342static int math_log10 (lua_State *L) {
343 lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
344 return 1;
345}
346
347#endif
348/* }================================================================== */
349
350
351
352static const luaL_Reg mathlib[] = {
353 {"abs", math_abs},
354 {"acos", math_acos},
355 {"asin", math_asin},
356 {"atan", math_atan},
357 {"ceil", math_ceil},
358 {"cos", math_cos},
359 {"deg", math_deg},
360 {"exp", math_exp},
361 {"tointeger", math_toint},
362 {"floor", math_floor},
363 {"fmod", math_fmod},
364 {"ult", math_ult},
365 {"log", math_log},
366 {"max", math_max},
367 {"min", math_min},
368 {"modf", math_modf},
369 {"rad", math_rad},
370 {"random", math_random},
371 {"randomseed", math_randomseed},
372 {"sin", math_sin},
373 {"sqrt", math_sqrt},
374 {"tan", math_tan},
375 {"type", math_type},
376#if defined(LUA_COMPAT_MATHLIB)
377 {"atan2", math_atan},
378 {"cosh", math_cosh},
379 {"sinh", math_sinh},
380 {"tanh", math_tanh},
381 {"pow", math_pow},
382 {"frexp", math_frexp},
383 {"ldexp", math_ldexp},
384 {"log10", math_log10},
385#endif
386 /* placeholders */
387 {"pi", NULL},
388 {"huge", NULL},
389 {"maxinteger", NULL},
390 {"mininteger", NULL},
391 {NULL, NULL}
392};
393
394
395/*
396** Open math library
397*/
398LUAMOD_API int luaopen_math (lua_State *L) {
399 luaL_newlib(L, mathlib);
400 lua_pushnumber(L, PI);
401 lua_setfield(L, -2, "pi");
402 lua_pushnumber(L, (lua_Number)HUGE_VAL);
403 lua_setfield(L, -2, "huge");
404 lua_pushinteger(L, LUA_MAXINTEGER);
405 lua_setfield(L, -2, "maxinteger");
406 lua_pushinteger(L, LUA_MININTEGER);
407 lua_setfield(L, -2, "mininteger");
408 return 1;
409}
410
diff --git a/src/lua-5.3/lmem.c b/src/lua-5.3/lmem.c
new file mode 100644
index 0000000..0241cc3
--- /dev/null
+++ b/src/lua-5.3/lmem.c
@@ -0,0 +1,100 @@
1/*
2** $Id: lmem.c,v 1.91.1.1 2017/04/19 17:20:42 roberto Exp $
3** Interface to Memory Manager
4** See Copyright Notice in lua.h
5*/
6
7#define lmem_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <stddef.h>
14
15#include "lua.h"
16
17#include "ldebug.h"
18#include "ldo.h"
19#include "lgc.h"
20#include "lmem.h"
21#include "lobject.h"
22#include "lstate.h"
23
24
25
26/*
27** About the realloc function:
28** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
29** ('osize' is the old size, 'nsize' is the new size)
30**
31** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no
32** matter 'x').
33**
34** * frealloc(ud, p, x, 0) frees the block 'p'
35** (in this specific case, frealloc must return NULL);
36** particularly, frealloc(ud, NULL, 0, 0) does nothing
37** (which is equivalent to free(NULL) in ISO C)
38**
39** frealloc returns NULL if it cannot create or reallocate the area
40** (any reallocation to an equal or smaller size cannot fail!)
41*/
42
43
44
45#define MINSIZEARRAY 4
46
47
48void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
49 int limit, const char *what) {
50 void *newblock;
51 int newsize;
52 if (*size >= limit/2) { /* cannot double it? */
53 if (*size >= limit) /* cannot grow even a little? */
54 luaG_runerror(L, "too many %s (limit is %d)", what, limit);
55 newsize = limit; /* still have at least one free place */
56 }
57 else {
58 newsize = (*size)*2;
59 if (newsize < MINSIZEARRAY)
60 newsize = MINSIZEARRAY; /* minimum size */
61 }
62 newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
63 *size = newsize; /* update only when everything else is OK */
64 return newblock;
65}
66
67
68l_noret luaM_toobig (lua_State *L) {
69 luaG_runerror(L, "memory allocation error: block too big");
70}
71
72
73
74/*
75** generic allocation routine.
76*/
77void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
78 void *newblock;
79 global_State *g = G(L);
80 size_t realosize = (block) ? osize : 0;
81 lua_assert((realosize == 0) == (block == NULL));
82#if defined(HARDMEMTESTS)
83 if (nsize > realosize && g->gcrunning)
84 luaC_fullgc(L, 1); /* force a GC whenever possible */
85#endif
86 newblock = (*g->frealloc)(g->ud, block, osize, nsize);
87 if (newblock == NULL && nsize > 0) {
88 lua_assert(nsize > realosize); /* cannot fail when shrinking a block */
89 if (g->version) { /* is state fully built? */
90 luaC_fullgc(L, 1); /* try to free some memory... */
91 newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
92 }
93 if (newblock == NULL)
94 luaD_throw(L, LUA_ERRMEM);
95 }
96 lua_assert((nsize == 0) == (newblock == NULL));
97 g->GCdebt = (g->GCdebt + nsize) - realosize;
98 return newblock;
99}
100
diff --git a/src/lua-5.3/lmem.h b/src/lua-5.3/lmem.h
new file mode 100644
index 0000000..357b1e4
--- /dev/null
+++ b/src/lua-5.3/lmem.h
@@ -0,0 +1,69 @@
1/*
2** $Id: lmem.h,v 1.43.1.1 2017/04/19 17:20:42 roberto Exp $
3** Interface to Memory Manager
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lmem_h
8#define lmem_h
9
10
11#include <stddef.h>
12
13#include "llimits.h"
14#include "lua.h"
15
16
17/*
18** This macro reallocs a vector 'b' from 'on' to 'n' elements, where
19** each element has size 'e'. In case of arithmetic overflow of the
20** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because
21** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e).
22**
23** (The macro is somewhat complex to avoid warnings: The 'sizeof'
24** comparison avoids a runtime comparison when overflow cannot occur.
25** The compiler should be able to optimize the real test by itself, but
26** when it does it, it may give a warning about "comparison is always
27** false due to limited range of data type"; the +1 tricks the compiler,
28** avoiding this warning but also this optimization.)
29*/
30#define luaM_reallocv(L,b,on,n,e) \
31 (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \
32 ? luaM_toobig(L) : cast_void(0)) , \
33 luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
34
35/*
36** Arrays of chars do not need any test
37*/
38#define luaM_reallocvchar(L,b,on,n) \
39 cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char)))
40
41#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
42#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
43#define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0)
44
45#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s))
46#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
47#define luaM_newvector(L,n,t) \
48 cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
49
50#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s))
51
52#define luaM_growvector(L,v,nelems,size,t,limit,e) \
53 if ((nelems)+1 > (size)) \
54 ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
55
56#define luaM_reallocvector(L, v,oldn,n,t) \
57 ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
58
59LUAI_FUNC l_noret luaM_toobig (lua_State *L);
60
61/* not to be called directly */
62LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
63 size_t size);
64LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
65 size_t size_elem, int limit,
66 const char *what);
67
68#endif
69
diff --git a/src/lua-5.3/loadlib.c b/src/lua-5.3/loadlib.c
new file mode 100644
index 0000000..45f44d3
--- /dev/null
+++ b/src/lua-5.3/loadlib.c
@@ -0,0 +1,790 @@
1/*
2** $Id: loadlib.c,v 1.130.1.1 2017/04/19 17:20:42 roberto Exp $
3** Dynamic library loader for Lua
4** See Copyright Notice in lua.h
5**
6** This module contains an implementation of loadlib for Unix systems
7** that have dlfcn, an implementation for Windows, and a stub for other
8** systems.
9*/
10
11#define loadlib_c
12#define LUA_LIB
13
14#include "lprefix.h"
15
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20
21#include "lua.h"
22
23#include "lauxlib.h"
24#include "lualib.h"
25
26
27/*
28** LUA_IGMARK is a mark to ignore all before it when building the
29** luaopen_ function name.
30*/
31#if !defined (LUA_IGMARK)
32#define LUA_IGMARK "-"
33#endif
34
35
36/*
37** LUA_CSUBSEP is the character that replaces dots in submodule names
38** when searching for a C loader.
39** LUA_LSUBSEP is the character that replaces dots in submodule names
40** when searching for a Lua loader.
41*/
42#if !defined(LUA_CSUBSEP)
43#define LUA_CSUBSEP LUA_DIRSEP
44#endif
45
46#if !defined(LUA_LSUBSEP)
47#define LUA_LSUBSEP LUA_DIRSEP
48#endif
49
50
51/* prefix for open functions in C libraries */
52#define LUA_POF "luaopen_"
53
54/* separator for open functions in C libraries */
55#define LUA_OFSEP "_"
56
57
58/*
59** unique key for table in the registry that keeps handles
60** for all loaded C libraries
61*/
62static const int CLIBS = 0;
63
64#define LIB_FAIL "open"
65
66
67#define setprogdir(L) ((void)0)
68
69
70/*
71** system-dependent functions
72*/
73
74/*
75** unload library 'lib'
76*/
77static void lsys_unloadlib (void *lib);
78
79/*
80** load C library in file 'path'. If 'seeglb', load with all names in
81** the library global.
82** Returns the library; in case of error, returns NULL plus an
83** error string in the stack.
84*/
85static void *lsys_load (lua_State *L, const char *path, int seeglb);
86
87/*
88** Try to find a function named 'sym' in library 'lib'.
89** Returns the function; in case of error, returns NULL plus an
90** error string in the stack.
91*/
92static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym);
93
94
95
96
97#if defined(LUA_USE_DLOPEN) /* { */
98/*
99** {========================================================================
100** This is an implementation of loadlib based on the dlfcn interface.
101** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
102** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
103** as an emulation layer on top of native functions.
104** =========================================================================
105*/
106
107#include <dlfcn.h>
108
109/*
110** Macro to convert pointer-to-void* to pointer-to-function. This cast
111** is undefined according to ISO C, but POSIX assumes that it works.
112** (The '__extension__' in gnu compilers is only to avoid warnings.)
113*/
114#if defined(__GNUC__)
115#define cast_func(p) (__extension__ (lua_CFunction)(p))
116#else
117#define cast_func(p) ((lua_CFunction)(p))
118#endif
119
120
121static void lsys_unloadlib (void *lib) {
122 dlclose(lib);
123}
124
125
126static void *lsys_load (lua_State *L, const char *path, int seeglb) {
127 void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
128 if (lib == NULL) lua_pushstring(L, dlerror());
129 return lib;
130}
131
132
133static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
134 lua_CFunction f = cast_func(dlsym(lib, sym));
135 if (f == NULL) lua_pushstring(L, dlerror());
136 return f;
137}
138
139/* }====================================================== */
140
141
142
143#elif defined(LUA_DL_DLL) /* }{ */
144/*
145** {======================================================================
146** This is an implementation of loadlib for Windows using native functions.
147** =======================================================================
148*/
149
150#include <windows.h>
151
152
153/*
154** optional flags for LoadLibraryEx
155*/
156#if !defined(LUA_LLE_FLAGS)
157#define LUA_LLE_FLAGS 0
158#endif
159
160
161#undef setprogdir
162
163
164/*
165** Replace in the path (on the top of the stack) any occurrence
166** of LUA_EXEC_DIR with the executable's path.
167*/
168static void setprogdir (lua_State *L) {
169 char buff[MAX_PATH + 1];
170 char *lb;
171 DWORD nsize = sizeof(buff)/sizeof(char);
172 DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */
173 if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
174 luaL_error(L, "unable to get ModuleFileName");
175 else {
176 *lb = '\0'; /* cut name on the last '\\' to get the path */
177 luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
178 lua_remove(L, -2); /* remove original string */
179 }
180}
181
182
183
184
185static void pusherror (lua_State *L) {
186 int error = GetLastError();
187 char buffer[128];
188 if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
189 NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL))
190 lua_pushstring(L, buffer);
191 else
192 lua_pushfstring(L, "system error %d\n", error);
193}
194
195static void lsys_unloadlib (void *lib) {
196 FreeLibrary((HMODULE)lib);
197}
198
199
200static void *lsys_load (lua_State *L, const char *path, int seeglb) {
201 HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
202 (void)(seeglb); /* not used: symbols are 'global' by default */
203 if (lib == NULL) pusherror(L);
204 return lib;
205}
206
207
208static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
209 lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
210 if (f == NULL) pusherror(L);
211 return f;
212}
213
214/* }====================================================== */
215
216
217#else /* }{ */
218/*
219** {======================================================
220** Fallback for other systems
221** =======================================================
222*/
223
224#undef LIB_FAIL
225#define LIB_FAIL "absent"
226
227
228#define DLMSG "dynamic libraries not enabled; check your Lua installation"
229
230
231static void lsys_unloadlib (void *lib) {
232 (void)(lib); /* not used */
233}
234
235
236static void *lsys_load (lua_State *L, const char *path, int seeglb) {
237 (void)(path); (void)(seeglb); /* not used */
238 lua_pushliteral(L, DLMSG);
239 return NULL;
240}
241
242
243static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
244 (void)(lib); (void)(sym); /* not used */
245 lua_pushliteral(L, DLMSG);
246 return NULL;
247}
248
249/* }====================================================== */
250#endif /* } */
251
252
253/*
254** {==================================================================
255** Set Paths
256** ===================================================================
257*/
258
259/*
260** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
261** variables that Lua check to set its paths.
262*/
263#if !defined(LUA_PATH_VAR)
264#define LUA_PATH_VAR "LUA_PATH"
265#endif
266
267#if !defined(LUA_CPATH_VAR)
268#define LUA_CPATH_VAR "LUA_CPATH"
269#endif
270
271
272#define AUXMARK "\1" /* auxiliary mark */
273
274
275/*
276** return registry.LUA_NOENV as a boolean
277*/
278static int noenv (lua_State *L) {
279 int b;
280 lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
281 b = lua_toboolean(L, -1);
282 lua_pop(L, 1); /* remove value */
283 return b;
284}
285
286
287/*
288** Set a path
289*/
290static void setpath (lua_State *L, const char *fieldname,
291 const char *envname,
292 const char *dft) {
293 const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX);
294 const char *path = getenv(nver); /* use versioned name */
295 if (path == NULL) /* no environment variable? */
296 path = getenv(envname); /* try unversioned name */
297 if (path == NULL || noenv(L)) /* no environment variable? */
298 lua_pushstring(L, dft); /* use default */
299 else {
300 /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
301 path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
302 LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
303 luaL_gsub(L, path, AUXMARK, dft);
304 lua_remove(L, -2); /* remove result from 1st 'gsub' */
305 }
306 setprogdir(L);
307 lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */
308 lua_pop(L, 1); /* pop versioned variable name */
309}
310
311/* }================================================================== */
312
313
314/*
315** return registry.CLIBS[path]
316*/
317static void *checkclib (lua_State *L, const char *path) {
318 void *plib;
319 lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS);
320 lua_getfield(L, -1, path);
321 plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */
322 lua_pop(L, 2); /* pop CLIBS table and 'plib' */
323 return plib;
324}
325
326
327/*
328** registry.CLIBS[path] = plib -- for queries
329** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries
330*/
331static void addtoclib (lua_State *L, const char *path, void *plib) {
332 lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS);
333 lua_pushlightuserdata(L, plib);
334 lua_pushvalue(L, -1);
335 lua_setfield(L, -3, path); /* CLIBS[path] = plib */
336 lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */
337 lua_pop(L, 1); /* pop CLIBS table */
338}
339
340
341/*
342** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib
343** handles in list CLIBS
344*/
345static int gctm (lua_State *L) {
346 lua_Integer n = luaL_len(L, 1);
347 for (; n >= 1; n--) { /* for each handle, in reverse order */
348 lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */
349 lsys_unloadlib(lua_touserdata(L, -1));
350 lua_pop(L, 1); /* pop handle */
351 }
352 return 0;
353}
354
355
356
357/* error codes for 'lookforfunc' */
358#define ERRLIB 1
359#define ERRFUNC 2
360
361/*
362** Look for a C function named 'sym' in a dynamically loaded library
363** 'path'.
364** First, check whether the library is already loaded; if not, try
365** to load it.
366** Then, if 'sym' is '*', return true (as library has been loaded).
367** Otherwise, look for symbol 'sym' in the library and push a
368** C function with that symbol.
369** Return 0 and 'true' or a function in the stack; in case of
370** errors, return an error code and an error message in the stack.
371*/
372static int lookforfunc (lua_State *L, const char *path, const char *sym) {
373 void *reg = checkclib(L, path); /* check loaded C libraries */
374 if (reg == NULL) { /* must load library? */
375 reg = lsys_load(L, path, *sym == '*'); /* global symbols if 'sym'=='*' */
376 if (reg == NULL) return ERRLIB; /* unable to load library */
377 addtoclib(L, path, reg);
378 }
379 if (*sym == '*') { /* loading only library (no function)? */
380 lua_pushboolean(L, 1); /* return 'true' */
381 return 0; /* no errors */
382 }
383 else {
384 lua_CFunction f = lsys_sym(L, reg, sym);
385 if (f == NULL)
386 return ERRFUNC; /* unable to find function */
387 lua_pushcfunction(L, f); /* else create new function */
388 return 0; /* no errors */
389 }
390}
391
392
393static int ll_loadlib (lua_State *L) {
394 const char *path = luaL_checkstring(L, 1);
395 const char *init = luaL_checkstring(L, 2);
396 int stat = lookforfunc(L, path, init);
397 if (stat == 0) /* no errors? */
398 return 1; /* return the loaded function */
399 else { /* error; error message is on stack top */
400 lua_pushnil(L);
401 lua_insert(L, -2);
402 lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
403 return 3; /* return nil, error message, and where */
404 }
405}
406
407
408
409/*
410** {======================================================
411** 'require' function
412** =======================================================
413*/
414
415
416static int readable (const char *filename) {
417 FILE *f = fopen(filename, "r"); /* try to open file */
418 if (f == NULL) return 0; /* open failed */
419 fclose(f);
420 return 1;
421}
422
423
424static const char *pushnexttemplate (lua_State *L, const char *path) {
425 const char *l;
426 while (*path == *LUA_PATH_SEP) path++; /* skip separators */
427 if (*path == '\0') return NULL; /* no more templates */
428 l = strchr(path, *LUA_PATH_SEP); /* find next separator */
429 if (l == NULL) l = path + strlen(path);
430 lua_pushlstring(L, path, l - path); /* template */
431 return l;
432}
433
434
435static const char *searchpath (lua_State *L, const char *name,
436 const char *path,
437 const char *sep,
438 const char *dirsep) {
439 luaL_Buffer msg; /* to build error message */
440 luaL_buffinit(L, &msg);
441 if (*sep != '\0') /* non-empty separator? */
442 name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
443 while ((path = pushnexttemplate(L, path)) != NULL) {
444 const char *filename = luaL_gsub(L, lua_tostring(L, -1),
445 LUA_PATH_MARK, name);
446 lua_remove(L, -2); /* remove path template */
447 if (readable(filename)) /* does file exist and is readable? */
448 return filename; /* return that file name */
449 lua_pushfstring(L, "\n\tno file '%s'", filename);
450 lua_remove(L, -2); /* remove file name */
451 luaL_addvalue(&msg); /* concatenate error msg. entry */
452 }
453 luaL_pushresult(&msg); /* create error message */
454 return NULL; /* not found */
455}
456
457
458static int ll_searchpath (lua_State *L) {
459 const char *f = searchpath(L, luaL_checkstring(L, 1),
460 luaL_checkstring(L, 2),
461 luaL_optstring(L, 3, "."),
462 luaL_optstring(L, 4, LUA_DIRSEP));
463 if (f != NULL) return 1;
464 else { /* error message is on top of the stack */
465 lua_pushnil(L);
466 lua_insert(L, -2);
467 return 2; /* return nil + error message */
468 }
469}
470
471
472static const char *findfile (lua_State *L, const char *name,
473 const char *pname,
474 const char *dirsep) {
475 const char *path;
476 lua_getfield(L, lua_upvalueindex(1), pname);
477 path = lua_tostring(L, -1);
478 if (path == NULL)
479 luaL_error(L, "'package.%s' must be a string", pname);
480 return searchpath(L, name, path, ".", dirsep);
481}
482
483
484static int checkload (lua_State *L, int stat, const char *filename) {
485 if (stat) { /* module loaded successfully? */
486 lua_pushstring(L, filename); /* will be 2nd argument to module */
487 return 2; /* return open function and file name */
488 }
489 else
490 return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s",
491 lua_tostring(L, 1), filename, lua_tostring(L, -1));
492}
493
494
495static int searcher_Lua (lua_State *L) {
496 const char *filename;
497 const char *name = luaL_checkstring(L, 1);
498 filename = findfile(L, name, "path", LUA_LSUBSEP);
499 if (filename == NULL) return 1; /* module not found in this path */
500 return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
501}
502
503
504/*
505** Try to find a load function for module 'modname' at file 'filename'.
506** First, change '.' to '_' in 'modname'; then, if 'modname' has
507** the form X-Y (that is, it has an "ignore mark"), build a function
508** name "luaopen_X" and look for it. (For compatibility, if that
509** fails, it also tries "luaopen_Y".) If there is no ignore mark,
510** look for a function named "luaopen_modname".
511*/
512static int loadfunc (lua_State *L, const char *filename, const char *modname) {
513 const char *openfunc;
514 const char *mark;
515 modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
516 mark = strchr(modname, *LUA_IGMARK);
517 if (mark) {
518 int stat;
519 openfunc = lua_pushlstring(L, modname, mark - modname);
520 openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc);
521 stat = lookforfunc(L, filename, openfunc);
522 if (stat != ERRFUNC) return stat;
523 modname = mark + 1; /* else go ahead and try old-style name */
524 }
525 openfunc = lua_pushfstring(L, LUA_POF"%s", modname);
526 return lookforfunc(L, filename, openfunc);
527}
528
529
530static int searcher_C (lua_State *L) {
531 const char *name = luaL_checkstring(L, 1);
532 const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
533 if (filename == NULL) return 1; /* module not found in this path */
534 return checkload(L, (loadfunc(L, filename, name) == 0), filename);
535}
536
537
538static int searcher_Croot (lua_State *L) {
539 const char *filename;
540 const char *name = luaL_checkstring(L, 1);
541 const char *p = strchr(name, '.');
542 int stat;
543 if (p == NULL) return 0; /* is root */
544 lua_pushlstring(L, name, p - name);
545 filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
546 if (filename == NULL) return 1; /* root not found */
547 if ((stat = loadfunc(L, filename, name)) != 0) {
548 if (stat != ERRFUNC)
549 return checkload(L, 0, filename); /* real error */
550 else { /* open function not found */
551 lua_pushfstring(L, "\n\tno module '%s' in file '%s'", name, filename);
552 return 1;
553 }
554 }
555 lua_pushstring(L, filename); /* will be 2nd argument to module */
556 return 2;
557}
558
559
560static int searcher_preload (lua_State *L) {
561 const char *name = luaL_checkstring(L, 1);
562 lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
563 if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */
564 lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
565 return 1;
566}
567
568
569static void findloader (lua_State *L, const char *name) {
570 int i;
571 luaL_Buffer msg; /* to build error message */
572 luaL_buffinit(L, &msg);
573 /* push 'package.searchers' to index 3 in the stack */
574 if (lua_getfield(L, lua_upvalueindex(1), "searchers") != LUA_TTABLE)
575 luaL_error(L, "'package.searchers' must be a table");
576 /* iterate over available searchers to find a loader */
577 for (i = 1; ; i++) {
578 if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */
579 lua_pop(L, 1); /* remove nil */
580 luaL_pushresult(&msg); /* create error message */
581 luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1));
582 }
583 lua_pushstring(L, name);
584 lua_call(L, 1, 2); /* call it */
585 if (lua_isfunction(L, -2)) /* did it find a loader? */
586 return; /* module loader found */
587 else if (lua_isstring(L, -2)) { /* searcher returned error message? */
588 lua_pop(L, 1); /* remove extra return */
589 luaL_addvalue(&msg); /* concatenate error message */
590 }
591 else
592 lua_pop(L, 2); /* remove both returns */
593 }
594}
595
596
597static int ll_require (lua_State *L) {
598 const char *name = luaL_checkstring(L, 1);
599 lua_settop(L, 1); /* LOADED table will be at index 2 */
600 lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
601 lua_getfield(L, 2, name); /* LOADED[name] */
602 if (lua_toboolean(L, -1)) /* is it there? */
603 return 1; /* package is already loaded */
604 /* else must load package */
605 lua_pop(L, 1); /* remove 'getfield' result */
606 findloader(L, name);
607 lua_pushstring(L, name); /* pass name as argument to module loader */
608 lua_insert(L, -2); /* name is 1st argument (before search data) */
609 lua_call(L, 2, 1); /* run loader to load module */
610 if (!lua_isnil(L, -1)) /* non-nil return? */
611 lua_setfield(L, 2, name); /* LOADED[name] = returned value */
612 if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */
613 lua_pushboolean(L, 1); /* use true as result */
614 lua_pushvalue(L, -1); /* extra copy to be returned */
615 lua_setfield(L, 2, name); /* LOADED[name] = true */
616 }
617 return 1;
618}
619
620/* }====================================================== */
621
622
623
624/*
625** {======================================================
626** 'module' function
627** =======================================================
628*/
629#if defined(LUA_COMPAT_MODULE)
630
631/*
632** changes the environment variable of calling function
633*/
634static void set_env (lua_State *L) {
635 lua_Debug ar;
636 if (lua_getstack(L, 1, &ar) == 0 ||
637 lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
638 lua_iscfunction(L, -1))
639 luaL_error(L, "'module' not called from a Lua function");
640 lua_pushvalue(L, -2); /* copy new environment table to top */
641 lua_setupvalue(L, -2, 1);
642 lua_pop(L, 1); /* remove function */
643}
644
645
646static void dooptions (lua_State *L, int n) {
647 int i;
648 for (i = 2; i <= n; i++) {
649 if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */
650 lua_pushvalue(L, i); /* get option (a function) */
651 lua_pushvalue(L, -2); /* module */
652 lua_call(L, 1, 0);
653 }
654 }
655}
656
657
658static void modinit (lua_State *L, const char *modname) {
659 const char *dot;
660 lua_pushvalue(L, -1);
661 lua_setfield(L, -2, "_M"); /* module._M = module */
662 lua_pushstring(L, modname);
663 lua_setfield(L, -2, "_NAME");
664 dot = strrchr(modname, '.'); /* look for last dot in module name */
665 if (dot == NULL) dot = modname;
666 else dot++;
667 /* set _PACKAGE as package name (full module name minus last part) */
668 lua_pushlstring(L, modname, dot - modname);
669 lua_setfield(L, -2, "_PACKAGE");
670}
671
672
673static int ll_module (lua_State *L) {
674 const char *modname = luaL_checkstring(L, 1);
675 int lastarg = lua_gettop(L); /* last parameter */
676 luaL_pushmodule(L, modname, 1); /* get/create module table */
677 /* check whether table already has a _NAME field */
678 if (lua_getfield(L, -1, "_NAME") != LUA_TNIL)
679 lua_pop(L, 1); /* table is an initialized module */
680 else { /* no; initialize it */
681 lua_pop(L, 1);
682 modinit(L, modname);
683 }
684 lua_pushvalue(L, -1);
685 set_env(L);
686 dooptions(L, lastarg);
687 return 1;
688}
689
690
691static int ll_seeall (lua_State *L) {
692 luaL_checktype(L, 1, LUA_TTABLE);
693 if (!lua_getmetatable(L, 1)) {
694 lua_createtable(L, 0, 1); /* create new metatable */
695 lua_pushvalue(L, -1);
696 lua_setmetatable(L, 1);
697 }
698 lua_pushglobaltable(L);
699 lua_setfield(L, -2, "__index"); /* mt.__index = _G */
700 return 0;
701}
702
703#endif
704/* }====================================================== */
705
706
707
708static const luaL_Reg pk_funcs[] = {
709 {"loadlib", ll_loadlib},
710 {"searchpath", ll_searchpath},
711#if defined(LUA_COMPAT_MODULE)
712 {"seeall", ll_seeall},
713#endif
714 /* placeholders */
715 {"preload", NULL},
716 {"cpath", NULL},
717 {"path", NULL},
718 {"searchers", NULL},
719 {"loaded", NULL},
720 {NULL, NULL}
721};
722
723
724static const luaL_Reg ll_funcs[] = {
725#if defined(LUA_COMPAT_MODULE)
726 {"module", ll_module},
727#endif
728 {"require", ll_require},
729 {NULL, NULL}
730};
731
732
733static void createsearcherstable (lua_State *L) {
734 static const lua_CFunction searchers[] =
735 {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
736 int i;
737 /* create 'searchers' table */
738 lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
739 /* fill it with predefined searchers */
740 for (i=0; searchers[i] != NULL; i++) {
741 lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */
742 lua_pushcclosure(L, searchers[i], 1);
743 lua_rawseti(L, -2, i+1);
744 }
745#if defined(LUA_COMPAT_LOADERS)
746 lua_pushvalue(L, -1); /* make a copy of 'searchers' table */
747 lua_setfield(L, -3, "loaders"); /* put it in field 'loaders' */
748#endif
749 lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
750}
751
752
753/*
754** create table CLIBS to keep track of loaded C libraries,
755** setting a finalizer to close all libraries when closing state.
756*/
757static void createclibstable (lua_State *L) {
758 lua_newtable(L); /* create CLIBS table */
759 lua_createtable(L, 0, 1); /* create metatable for CLIBS */
760 lua_pushcfunction(L, gctm);
761 lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
762 lua_setmetatable(L, -2);
763 lua_rawsetp(L, LUA_REGISTRYINDEX, &CLIBS); /* set CLIBS table in registry */
764}
765
766
767LUAMOD_API int luaopen_package (lua_State *L) {
768 createclibstable(L);
769 luaL_newlib(L, pk_funcs); /* create 'package' table */
770 createsearcherstable(L);
771 /* set paths */
772 setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT);
773 setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
774 /* store config information */
775 lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
776 LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
777 lua_setfield(L, -2, "config");
778 /* set field 'loaded' */
779 luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
780 lua_setfield(L, -2, "loaded");
781 /* set field 'preload' */
782 luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
783 lua_setfield(L, -2, "preload");
784 lua_pushglobaltable(L);
785 lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */
786 luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */
787 lua_pop(L, 1); /* pop global table */
788 return 1; /* return 'package' table */
789}
790
diff --git a/src/lua-5.3/lobject.c b/src/lua-5.3/lobject.c
new file mode 100644
index 0000000..355bf58
--- /dev/null
+++ b/src/lua-5.3/lobject.c
@@ -0,0 +1,522 @@
1/*
2** $Id: lobject.c,v 2.113.1.1 2017/04/19 17:29:57 roberto Exp $
3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h
5*/
6
7#define lobject_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <locale.h>
14#include <math.h>
15#include <stdarg.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19
20#include "lua.h"
21
22#include "lctype.h"
23#include "ldebug.h"
24#include "ldo.h"
25#include "lmem.h"
26#include "lobject.h"
27#include "lstate.h"
28#include "lstring.h"
29#include "lvm.h"
30
31
32
33LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
34
35
36/*
37** converts an integer to a "floating point byte", represented as
38** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
39** eeeee != 0 and (xxx) otherwise.
40*/
41int luaO_int2fb (unsigned int x) {
42 int e = 0; /* exponent */
43 if (x < 8) return x;
44 while (x >= (8 << 4)) { /* coarse steps */
45 x = (x + 0xf) >> 4; /* x = ceil(x / 16) */
46 e += 4;
47 }
48 while (x >= (8 << 1)) { /* fine steps */
49 x = (x + 1) >> 1; /* x = ceil(x / 2) */
50 e++;
51 }
52 return ((e+1) << 3) | (cast_int(x) - 8);
53}
54
55
56/* converts back */
57int luaO_fb2int (int x) {
58 return (x < 8) ? x : ((x & 7) + 8) << ((x >> 3) - 1);
59}
60
61
62/*
63** Computes ceil(log2(x))
64*/
65int luaO_ceillog2 (unsigned int x) {
66 static const lu_byte log_2[256] = { /* log_2[i] = ceil(log2(i - 1)) */
67 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,
68 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,
69 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,
70 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,
71 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,
72 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,
73 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,
74 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
75 };
76 int l = 0;
77 x--;
78 while (x >= 256) { l += 8; x >>= 8; }
79 return l + log_2[x];
80}
81
82
83static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
84 lua_Integer v2) {
85 switch (op) {
86 case LUA_OPADD: return intop(+, v1, v2);
87 case LUA_OPSUB:return intop(-, v1, v2);
88 case LUA_OPMUL:return intop(*, v1, v2);
89 case LUA_OPMOD: return luaV_mod(L, v1, v2);
90 case LUA_OPIDIV: return luaV_div(L, v1, v2);
91 case LUA_OPBAND: return intop(&, v1, v2);
92 case LUA_OPBOR: return intop(|, v1, v2);
93 case LUA_OPBXOR: return intop(^, v1, v2);
94 case LUA_OPSHL: return luaV_shiftl(v1, v2);
95 case LUA_OPSHR: return luaV_shiftl(v1, -v2);
96 case LUA_OPUNM: return intop(-, 0, v1);
97 case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1);
98 default: lua_assert(0); return 0;
99 }
100}
101
102
103static lua_Number numarith (lua_State *L, int op, lua_Number v1,
104 lua_Number v2) {
105 switch (op) {
106 case LUA_OPADD: return luai_numadd(L, v1, v2);
107 case LUA_OPSUB: return luai_numsub(L, v1, v2);
108 case LUA_OPMUL: return luai_nummul(L, v1, v2);
109 case LUA_OPDIV: return luai_numdiv(L, v1, v2);
110 case LUA_OPPOW: return luai_numpow(L, v1, v2);
111 case LUA_OPIDIV: return luai_numidiv(L, v1, v2);
112 case LUA_OPUNM: return luai_numunm(L, v1);
113 case LUA_OPMOD: {
114 lua_Number m;
115 luai_nummod(L, v1, v2, m);
116 return m;
117 }
118 default: lua_assert(0); return 0;
119 }
120}
121
122
123void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
124 TValue *res) {
125 switch (op) {
126 case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
127 case LUA_OPSHL: case LUA_OPSHR:
128 case LUA_OPBNOT: { /* operate only on integers */
129 lua_Integer i1; lua_Integer i2;
130 if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
131 setivalue(res, intarith(L, op, i1, i2));
132 return;
133 }
134 else break; /* go to the end */
135 }
136 case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */
137 lua_Number n1; lua_Number n2;
138 if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
139 setfltvalue(res, numarith(L, op, n1, n2));
140 return;
141 }
142 else break; /* go to the end */
143 }
144 default: { /* other operations */
145 lua_Number n1; lua_Number n2;
146 if (ttisinteger(p1) && ttisinteger(p2)) {
147 setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
148 return;
149 }
150 else if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
151 setfltvalue(res, numarith(L, op, n1, n2));
152 return;
153 }
154 else break; /* go to the end */
155 }
156 }
157 /* could not perform raw operation; try metamethod */
158 lua_assert(L != NULL); /* should not fail when folding (compile time) */
159 luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD));
160}
161
162
163int luaO_hexavalue (int c) {
164 if (lisdigit(c)) return c - '0';
165 else return (ltolower(c) - 'a') + 10;
166}
167
168
169static int isneg (const char **s) {
170 if (**s == '-') { (*s)++; return 1; }
171 else if (**s == '+') (*s)++;
172 return 0;
173}
174
175
176
177/*
178** {==================================================================
179** Lua's implementation for 'lua_strx2number'
180** ===================================================================
181*/
182
183#if !defined(lua_strx2number)
184
185/* maximum number of significant digits to read (to avoid overflows
186 even with single floats) */
187#define MAXSIGDIG 30
188
189/*
190** convert an hexadecimal numeric string to a number, following
191** C99 specification for 'strtod'
192*/
193static lua_Number lua_strx2number (const char *s, char **endptr) {
194 int dot = lua_getlocaledecpoint();
195 lua_Number r = 0.0; /* result (accumulator) */
196 int sigdig = 0; /* number of significant digits */
197 int nosigdig = 0; /* number of non-significant digits */
198 int e = 0; /* exponent correction */
199 int neg; /* 1 if number is negative */
200 int hasdot = 0; /* true after seen a dot */
201 *endptr = cast(char *, s); /* nothing is valid yet */
202 while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
203 neg = isneg(&s); /* check signal */
204 if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
205 return 0.0; /* invalid format (no '0x') */
206 for (s += 2; ; s++) { /* skip '0x' and read numeral */
207 if (*s == dot) {
208 if (hasdot) break; /* second dot? stop loop */
209 else hasdot = 1;
210 }
211 else if (lisxdigit(cast_uchar(*s))) {
212 if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */
213 nosigdig++;
214 else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
215 r = (r * cast_num(16.0)) + luaO_hexavalue(*s);
216 else e++; /* too many digits; ignore, but still count for exponent */
217 if (hasdot) e--; /* decimal digit? correct exponent */
218 }
219 else break; /* neither a dot nor a digit */
220 }
221 if (nosigdig + sigdig == 0) /* no digits? */
222 return 0.0; /* invalid format */
223 *endptr = cast(char *, s); /* valid up to here */
224 e *= 4; /* each digit multiplies/divides value by 2^4 */
225 if (*s == 'p' || *s == 'P') { /* exponent part? */
226 int exp1 = 0; /* exponent value */
227 int neg1; /* exponent signal */
228 s++; /* skip 'p' */
229 neg1 = isneg(&s); /* signal */
230 if (!lisdigit(cast_uchar(*s)))
231 return 0.0; /* invalid; must have at least one digit */
232 while (lisdigit(cast_uchar(*s))) /* read exponent */
233 exp1 = exp1 * 10 + *(s++) - '0';
234 if (neg1) exp1 = -exp1;
235 e += exp1;
236 *endptr = cast(char *, s); /* valid up to here */
237 }
238 if (neg) r = -r;
239 return l_mathop(ldexp)(r, e);
240}
241
242#endif
243/* }====================================================== */
244
245
246/* maximum length of a numeral */
247#if !defined (L_MAXLENNUM)
248#define L_MAXLENNUM 200
249#endif
250
251static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
252 char *endptr;
253 *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */
254 : lua_str2number(s, &endptr);
255 if (endptr == s) return NULL; /* nothing recognized? */
256 while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */
257 return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */
258}
259
260
261/*
262** Convert string 's' to a Lua number (put in 'result'). Return NULL
263** on fail or the address of the ending '\0' on success.
264** 'pmode' points to (and 'mode' contains) special things in the string:
265** - 'x'/'X' means an hexadecimal numeral
266** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
267** - '.' just optimizes the search for the common case (nothing special)
268** This function accepts both the current locale or a dot as the radix
269** mark. If the conversion fails, it may mean number has a dot but
270** locale accepts something else. In that case, the code copies 's'
271** to a buffer (because 's' is read-only), changes the dot to the
272** current locale radix mark, and tries to convert again.
273*/
274static const char *l_str2d (const char *s, lua_Number *result) {
275 const char *endptr;
276 const char *pmode = strpbrk(s, ".xXnN");
277 int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
278 if (mode == 'n') /* reject 'inf' and 'nan' */
279 return NULL;
280 endptr = l_str2dloc(s, result, mode); /* try to convert */
281 if (endptr == NULL) { /* failed? may be a different locale */
282 char buff[L_MAXLENNUM + 1];
283 const char *pdot = strchr(s, '.');
284 if (strlen(s) > L_MAXLENNUM || pdot == NULL)
285 return NULL; /* string too long or no dot; fail */
286 strcpy(buff, s); /* copy string to buffer */
287 buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */
288 endptr = l_str2dloc(buff, result, mode); /* try again */
289 if (endptr != NULL)
290 endptr = s + (endptr - buff); /* make relative to 's' */
291 }
292 return endptr;
293}
294
295
296#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10)
297#define MAXLASTD cast_int(LUA_MAXINTEGER % 10)
298
299static const char *l_str2int (const char *s, lua_Integer *result) {
300 lua_Unsigned a = 0;
301 int empty = 1;
302 int neg;
303 while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
304 neg = isneg(&s);
305 if (s[0] == '0' &&
306 (s[1] == 'x' || s[1] == 'X')) { /* hex? */
307 s += 2; /* skip '0x' */
308 for (; lisxdigit(cast_uchar(*s)); s++) {
309 a = a * 16 + luaO_hexavalue(*s);
310 empty = 0;
311 }
312 }
313 else { /* decimal */
314 for (; lisdigit(cast_uchar(*s)); s++) {
315 int d = *s - '0';
316 if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */
317 return NULL; /* do not accept it (as integer) */
318 a = a * 10 + d;
319 empty = 0;
320 }
321 }
322 while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */
323 if (empty || *s != '\0') return NULL; /* something wrong in the numeral */
324 else {
325 *result = l_castU2S((neg) ? 0u - a : a);
326 return s;
327 }
328}
329
330
331size_t luaO_str2num (const char *s, TValue *o) {
332 lua_Integer i; lua_Number n;
333 const char *e;
334 if ((e = l_str2int(s, &i)) != NULL) { /* try as an integer */
335 setivalue(o, i);
336 }
337 else if ((e = l_str2d(s, &n)) != NULL) { /* else try as a float */
338 setfltvalue(o, n);
339 }
340 else
341 return 0; /* conversion failed */
342 return (e - s) + 1; /* success; return string size */
343}
344
345
346int luaO_utf8esc (char *buff, unsigned long x) {
347 int n = 1; /* number of bytes put in buffer (backwards) */
348 lua_assert(x <= 0x10FFFF);
349 if (x < 0x80) /* ascii? */
350 buff[UTF8BUFFSZ - 1] = cast(char, x);
351 else { /* need continuation bytes */
352 unsigned int mfb = 0x3f; /* maximum that fits in first byte */
353 do { /* add continuation bytes */
354 buff[UTF8BUFFSZ - (n++)] = cast(char, 0x80 | (x & 0x3f));
355 x >>= 6; /* remove added bits */
356 mfb >>= 1; /* now there is one less bit available in first byte */
357 } while (x > mfb); /* still needs continuation byte? */
358 buff[UTF8BUFFSZ - n] = cast(char, (~mfb << 1) | x); /* add first byte */
359 }
360 return n;
361}
362
363
364/* maximum length of the conversion of a number to a string */
365#define MAXNUMBER2STR 50
366
367
368/*
369** Convert a number object to a string
370*/
371void luaO_tostring (lua_State *L, StkId obj) {
372 char buff[MAXNUMBER2STR];
373 size_t len;
374 lua_assert(ttisnumber(obj));
375 if (ttisinteger(obj))
376 len = lua_integer2str(buff, sizeof(buff), ivalue(obj));
377 else {
378 len = lua_number2str(buff, sizeof(buff), fltvalue(obj));
379#if !defined(LUA_COMPAT_FLOATSTRING)
380 if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
381 buff[len++] = lua_getlocaledecpoint();
382 buff[len++] = '0'; /* adds '.0' to result */
383 }
384#endif
385 }
386 setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
387}
388
389
390static void pushstr (lua_State *L, const char *str, size_t l) {
391 setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
392 luaD_inctop(L);
393}
394
395
396/*
397** this function handles only '%d', '%c', '%f', '%p', and '%s'
398 conventional formats, plus Lua-specific '%I' and '%U'
399*/
400const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
401 int n = 0;
402 for (;;) {
403 const char *e = strchr(fmt, '%');
404 if (e == NULL) break;
405 pushstr(L, fmt, e - fmt);
406 switch (*(e+1)) {
407 case 's': { /* zero-terminated string */
408 const char *s = va_arg(argp, char *);
409 if (s == NULL) s = "(null)";
410 pushstr(L, s, strlen(s));
411 break;
412 }
413 case 'c': { /* an 'int' as a character */
414 char buff = cast(char, va_arg(argp, int));
415 if (lisprint(cast_uchar(buff)))
416 pushstr(L, &buff, 1);
417 else /* non-printable character; print its code */
418 luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
419 break;
420 }
421 case 'd': { /* an 'int' */
422 setivalue(L->top, va_arg(argp, int));
423 goto top2str;
424 }
425 case 'I': { /* a 'lua_Integer' */
426 setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt)));
427 goto top2str;
428 }
429 case 'f': { /* a 'lua_Number' */
430 setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
431 top2str: /* convert the top element to a string */
432 luaD_inctop(L);
433 luaO_tostring(L, L->top - 1);
434 break;
435 }
436 case 'p': { /* a pointer */
437 char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */
438 void *p = va_arg(argp, void *);
439 int l = lua_pointer2str(buff, sizeof(buff), p);
440 pushstr(L, buff, l);
441 break;
442 }
443 case 'U': { /* an 'int' as a UTF-8 sequence */
444 char buff[UTF8BUFFSZ];
445 int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
446 pushstr(L, buff + UTF8BUFFSZ - l, l);
447 break;
448 }
449 case '%': {
450 pushstr(L, "%", 1);
451 break;
452 }
453 default: {
454 luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'",
455 *(e + 1));
456 }
457 }
458 n += 2;
459 fmt = e+2;
460 }
461 luaD_checkstack(L, 1);
462 pushstr(L, fmt, strlen(fmt));
463 if (n > 0) luaV_concat(L, n + 1);
464 return svalue(L->top - 1);
465}
466
467
468const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
469 const char *msg;
470 va_list argp;
471 va_start(argp, fmt);
472 msg = luaO_pushvfstring(L, fmt, argp);
473 va_end(argp);
474 return msg;
475}
476
477
478/* number of chars of a literal string without the ending \0 */
479#define LL(x) (sizeof(x)/sizeof(char) - 1)
480
481#define RETS "..."
482#define PRE "[string \""
483#define POS "\"]"
484
485#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
486
487void luaO_chunkid (char *out, const char *source, size_t bufflen) {
488 size_t l = strlen(source);
489 if (*source == '=') { /* 'literal' source */
490 if (l <= bufflen) /* small enough? */
491 memcpy(out, source + 1, l * sizeof(char));
492 else { /* truncate it */
493 addstr(out, source + 1, bufflen - 1);
494 *out = '\0';
495 }
496 }
497 else if (*source == '@') { /* file name */
498 if (l <= bufflen) /* small enough? */
499 memcpy(out, source + 1, l * sizeof(char));
500 else { /* add '...' before rest of name */
501 addstr(out, RETS, LL(RETS));
502 bufflen -= LL(RETS);
503 memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
504 }
505 }
506 else { /* string; format as [string "source"] */
507 const char *nl = strchr(source, '\n'); /* find first new line (if any) */
508 addstr(out, PRE, LL(PRE)); /* add prefix */
509 bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
510 if (l < bufflen && nl == NULL) { /* small one-line source? */
511 addstr(out, source, l); /* keep it */
512 }
513 else {
514 if (nl != NULL) l = nl - source; /* stop at first newline */
515 if (l > bufflen) l = bufflen;
516 addstr(out, source, l);
517 addstr(out, RETS, LL(RETS));
518 }
519 memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
520 }
521}
522
diff --git a/src/lua-5.3/lobject.h b/src/lua-5.3/lobject.h
new file mode 100644
index 0000000..2408861
--- /dev/null
+++ b/src/lua-5.3/lobject.h
@@ -0,0 +1,549 @@
1/*
2** $Id: lobject.h,v 2.117.1.1 2017/04/19 17:39:34 roberto Exp $
3** Type definitions for Lua objects
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lobject_h
9#define lobject_h
10
11
12#include <stdarg.h>
13
14
15#include "llimits.h"
16#include "lua.h"
17
18
19/*
20** Extra tags for non-values
21*/
22#define LUA_TPROTO LUA_NUMTAGS /* function prototypes */
23#define LUA_TDEADKEY (LUA_NUMTAGS+1) /* removed keys in tables */
24
25/*
26** number of all possible tags (including LUA_TNONE but excluding DEADKEY)
27*/
28#define LUA_TOTALTAGS (LUA_TPROTO + 2)
29
30
31/*
32** tags for Tagged Values have the following use of bits:
33** bits 0-3: actual tag (a LUA_T* value)
34** bits 4-5: variant bits
35** bit 6: whether value is collectable
36*/
37
38
39/*
40** LUA_TFUNCTION variants:
41** 0 - Lua function
42** 1 - light C function
43** 2 - regular C function (closure)
44*/
45
46/* Variant tags for functions */
47#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */
48#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */
49#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */
50
51
52/* Variant tags for strings */
53#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */
54#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */
55
56
57/* Variant tags for numbers */
58#define LUA_TNUMFLT (LUA_TNUMBER | (0 << 4)) /* float numbers */
59#define LUA_TNUMINT (LUA_TNUMBER | (1 << 4)) /* integer numbers */
60
61
62/* Bit mark for collectable types */
63#define BIT_ISCOLLECTABLE (1 << 6)
64
65/* mark a tag as collectable */
66#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
67
68
69/*
70** Common type for all collectable objects
71*/
72typedef struct GCObject GCObject;
73
74
75/*
76** Common Header for all collectable objects (in macro form, to be
77** included in other objects)
78*/
79#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
80
81
82/*
83** Common type has only the common header
84*/
85struct GCObject {
86 CommonHeader;
87};
88
89
90
91
92/*
93** Tagged Values. This is the basic representation of values in Lua,
94** an actual value plus a tag with its type.
95*/
96
97/*
98** Union of all Lua values
99*/
100typedef union Value {
101 GCObject *gc; /* collectable objects */
102 void *p; /* light userdata */
103 int b; /* booleans */
104 lua_CFunction f; /* light C functions */
105 lua_Integer i; /* integer numbers */
106 lua_Number n; /* float numbers */
107} Value;
108
109
110#define TValuefields Value value_; int tt_
111
112
113typedef struct lua_TValue {
114 TValuefields;
115} TValue;
116
117
118
119/* macro defining a nil value */
120#define NILCONSTANT {NULL}, LUA_TNIL
121
122
123#define val_(o) ((o)->value_)
124
125
126/* raw type tag of a TValue */
127#define rttype(o) ((o)->tt_)
128
129/* tag with no variants (bits 0-3) */
130#define novariant(x) ((x) & 0x0F)
131
132/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
133#define ttype(o) (rttype(o) & 0x3F)
134
135/* type tag of a TValue with no variants (bits 0-3) */
136#define ttnov(o) (novariant(rttype(o)))
137
138
139/* Macros to test type */
140#define checktag(o,t) (rttype(o) == (t))
141#define checktype(o,t) (ttnov(o) == (t))
142#define ttisnumber(o) checktype((o), LUA_TNUMBER)
143#define ttisfloat(o) checktag((o), LUA_TNUMFLT)
144#define ttisinteger(o) checktag((o), LUA_TNUMINT)
145#define ttisnil(o) checktag((o), LUA_TNIL)
146#define ttisboolean(o) checktag((o), LUA_TBOOLEAN)
147#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
148#define ttisstring(o) checktype((o), LUA_TSTRING)
149#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR))
150#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR))
151#define ttistable(o) checktag((o), ctb(LUA_TTABLE))
152#define ttisfunction(o) checktype(o, LUA_TFUNCTION)
153#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)
154#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))
155#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))
156#define ttislcf(o) checktag((o), LUA_TLCF)
157#define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA))
158#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
159#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
160
161
162/* Macros to access values */
163#define ivalue(o) check_exp(ttisinteger(o), val_(o).i)
164#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
165#define nvalue(o) check_exp(ttisnumber(o), \
166 (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))
167#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
168#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
169#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))
170#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
171#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc))
172#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc))
173#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc))
174#define fvalue(o) check_exp(ttislcf(o), val_(o).f)
175#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc))
176#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
177#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))
178/* a dead value may get the 'gc' field, but cannot access its contents */
179#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
180
181#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
182
183
184#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)
185
186
187/* Macros for internal tests */
188#define righttt(obj) (ttype(obj) == gcvalue(obj)->tt)
189
190#define checkliveness(L,obj) \
191 lua_longassert(!iscollectable(obj) || \
192 (righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj)))))
193
194
195/* Macros to set values */
196#define settt_(o,t) ((o)->tt_=(t))
197
198#define setfltvalue(obj,x) \
199 { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); }
200
201#define chgfltvalue(obj,x) \
202 { TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); }
203
204#define setivalue(obj,x) \
205 { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }
206
207#define chgivalue(obj,x) \
208 { TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); }
209
210#define setnilvalue(obj) settt_(obj, LUA_TNIL)
211
212#define setfvalue(obj,x) \
213 { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); }
214
215#define setpvalue(obj,x) \
216 { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }
217
218#define setbvalue(obj,x) \
219 { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); }
220
221#define setgcovalue(L,obj,x) \
222 { TValue *io = (obj); GCObject *i_g=(x); \
223 val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); }
224
225#define setsvalue(L,obj,x) \
226 { TValue *io = (obj); TString *x_ = (x); \
227 val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \
228 checkliveness(L,io); }
229
230#define setuvalue(L,obj,x) \
231 { TValue *io = (obj); Udata *x_ = (x); \
232 val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TUSERDATA)); \
233 checkliveness(L,io); }
234
235#define setthvalue(L,obj,x) \
236 { TValue *io = (obj); lua_State *x_ = (x); \
237 val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTHREAD)); \
238 checkliveness(L,io); }
239
240#define setclLvalue(L,obj,x) \
241 { TValue *io = (obj); LClosure *x_ = (x); \
242 val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TLCL)); \
243 checkliveness(L,io); }
244
245#define setclCvalue(L,obj,x) \
246 { TValue *io = (obj); CClosure *x_ = (x); \
247 val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TCCL)); \
248 checkliveness(L,io); }
249
250#define sethvalue(L,obj,x) \
251 { TValue *io = (obj); Table *x_ = (x); \
252 val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \
253 checkliveness(L,io); }
254
255#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)
256
257
258
259#define setobj(L,obj1,obj2) \
260 { TValue *io1=(obj1); *io1 = *(obj2); \
261 (void)L; checkliveness(L,io1); }
262
263
264/*
265** different types of assignments, according to destination
266*/
267
268/* from stack to (same) stack */
269#define setobjs2s setobj
270/* to stack (not from same stack) */
271#define setobj2s setobj
272#define setsvalue2s setsvalue
273#define sethvalue2s sethvalue
274#define setptvalue2s setptvalue
275/* from table to same table */
276#define setobjt2t setobj
277/* to new object */
278#define setobj2n setobj
279#define setsvalue2n setsvalue
280
281/* to table (define it as an expression to be used in macros) */
282#define setobj2t(L,o1,o2) ((void)L, *(o1)=*(o2), checkliveness(L,(o1)))
283
284
285
286
287/*
288** {======================================================
289** types and prototypes
290** =======================================================
291*/
292
293
294typedef TValue *StkId; /* index to stack elements */
295
296
297
298
299/*
300** Header for string value; string bytes follow the end of this structure
301** (aligned according to 'UTString'; see next).
302*/
303typedef struct TString {
304 CommonHeader;
305 lu_byte extra; /* reserved words for short strings; "has hash" for longs */
306 lu_byte shrlen; /* length for short strings */
307 unsigned int hash;
308 union {
309 size_t lnglen; /* length for long strings */
310 struct TString *hnext; /* linked list for hash table */
311 } u;
312} TString;
313
314
315/*
316** Ensures that address after this type is always fully aligned.
317*/
318typedef union UTString {
319 L_Umaxalign dummy; /* ensures maximum alignment for strings */
320 TString tsv;
321} UTString;
322
323
324/*
325** Get the actual string (array of bytes) from a 'TString'.
326** (Access to 'extra' ensures that value is really a 'TString'.)
327*/
328#define getstr(ts) \
329 check_exp(sizeof((ts)->extra), cast(char *, (ts)) + sizeof(UTString))
330
331
332/* get the actual string (array of bytes) from a Lua value */
333#define svalue(o) getstr(tsvalue(o))
334
335/* get string length from 'TString *s' */
336#define tsslen(s) ((s)->tt == LUA_TSHRSTR ? (s)->shrlen : (s)->u.lnglen)
337
338/* get string length from 'TValue *o' */
339#define vslen(o) tsslen(tsvalue(o))
340
341
342/*
343** Header for userdata; memory area follows the end of this structure
344** (aligned according to 'UUdata'; see next).
345*/
346typedef struct Udata {
347 CommonHeader;
348 lu_byte ttuv_; /* user value's tag */
349 struct Table *metatable;
350 size_t len; /* number of bytes */
351 union Value user_; /* user value */
352} Udata;
353
354
355/*
356** Ensures that address after this type is always fully aligned.
357*/
358typedef union UUdata {
359 L_Umaxalign dummy; /* ensures maximum alignment for 'local' udata */
360 Udata uv;
361} UUdata;
362
363
364/*
365** Get the address of memory block inside 'Udata'.
366** (Access to 'ttuv_' ensures that value is really a 'Udata'.)
367*/
368#define getudatamem(u) \
369 check_exp(sizeof((u)->ttuv_), (cast(char*, (u)) + sizeof(UUdata)))
370
371#define setuservalue(L,u,o) \
372 { const TValue *io=(o); Udata *iu = (u); \
373 iu->user_ = io->value_; iu->ttuv_ = rttype(io); \
374 checkliveness(L,io); }
375
376
377#define getuservalue(L,u,o) \
378 { TValue *io=(o); const Udata *iu = (u); \
379 io->value_ = iu->user_; settt_(io, iu->ttuv_); \
380 checkliveness(L,io); }
381
382
383/*
384** Description of an upvalue for function prototypes
385*/
386typedef struct Upvaldesc {
387 TString *name; /* upvalue name (for debug information) */
388 lu_byte instack; /* whether it is in stack (register) */
389 lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
390} Upvaldesc;
391
392
393/*
394** Description of a local variable for function prototypes
395** (used for debug information)
396*/
397typedef struct LocVar {
398 TString *varname;
399 int startpc; /* first point where variable is active */
400 int endpc; /* first point where variable is dead */
401} LocVar;
402
403
404/*
405** Function Prototypes
406*/
407typedef struct Proto {
408 CommonHeader;
409 lu_byte numparams; /* number of fixed parameters */
410 lu_byte is_vararg;
411 lu_byte maxstacksize; /* number of registers needed by this function */
412 int sizeupvalues; /* size of 'upvalues' */
413 int sizek; /* size of 'k' */
414 int sizecode;
415 int sizelineinfo;
416 int sizep; /* size of 'p' */
417 int sizelocvars;
418 int linedefined; /* debug information */
419 int lastlinedefined; /* debug information */
420 TValue *k; /* constants used by the function */
421 Instruction *code; /* opcodes */
422 struct Proto **p; /* functions defined inside the function */
423 int *lineinfo; /* map from opcodes to source lines (debug information) */
424 LocVar *locvars; /* information about local variables (debug information) */
425 Upvaldesc *upvalues; /* upvalue information */
426 struct LClosure *cache; /* last-created closure with this prototype */
427 TString *source; /* used for debug information */
428 GCObject *gclist;
429} Proto;
430
431
432
433/*
434** Lua Upvalues
435*/
436typedef struct UpVal UpVal;
437
438
439/*
440** Closures
441*/
442
443#define ClosureHeader \
444 CommonHeader; lu_byte nupvalues; GCObject *gclist
445
446typedef struct CClosure {
447 ClosureHeader;
448 lua_CFunction f;
449 TValue upvalue[1]; /* list of upvalues */
450} CClosure;
451
452
453typedef struct LClosure {
454 ClosureHeader;
455 struct Proto *p;
456 UpVal *upvals[1]; /* list of upvalues */
457} LClosure;
458
459
460typedef union Closure {
461 CClosure c;
462 LClosure l;
463} Closure;
464
465
466#define isLfunction(o) ttisLclosure(o)
467
468#define getproto(o) (clLvalue(o)->p)
469
470
471/*
472** Tables
473*/
474
475typedef union TKey {
476 struct {
477 TValuefields;
478 int next; /* for chaining (offset for next node) */
479 } nk;
480 TValue tvk;
481} TKey;
482
483
484/* copy a value into a key without messing up field 'next' */
485#define setnodekey(L,key,obj) \
486 { TKey *k_=(key); const TValue *io_=(obj); \
487 k_->nk.value_ = io_->value_; k_->nk.tt_ = io_->tt_; \
488 (void)L; checkliveness(L,io_); }
489
490
491typedef struct Node {
492 TValue i_val;
493 TKey i_key;
494} Node;
495
496
497typedef struct Table {
498 CommonHeader;
499 lu_byte flags; /* 1<<p means tagmethod(p) is not present */
500 lu_byte lsizenode; /* log2 of size of 'node' array */
501 unsigned int sizearray; /* size of 'array' array */
502 TValue *array; /* array part */
503 Node *node;
504 Node *lastfree; /* any free position is before this position */
505 struct Table *metatable;
506 GCObject *gclist;
507} Table;
508
509
510
511/*
512** 'module' operation for hashing (size is always a power of 2)
513*/
514#define lmod(s,size) \
515 (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
516
517
518#define twoto(x) (1<<(x))
519#define sizenode(t) (twoto((t)->lsizenode))
520
521
522/*
523** (address of) a fixed nil value
524*/
525#define luaO_nilobject (&luaO_nilobject_)
526
527
528LUAI_DDEC const TValue luaO_nilobject_;
529
530/* size of buffer for 'luaO_utf8esc' function */
531#define UTF8BUFFSZ 8
532
533LUAI_FUNC int luaO_int2fb (unsigned int x);
534LUAI_FUNC int luaO_fb2int (int x);
535LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x);
536LUAI_FUNC int luaO_ceillog2 (unsigned int x);
537LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1,
538 const TValue *p2, TValue *res);
539LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o);
540LUAI_FUNC int luaO_hexavalue (int c);
541LUAI_FUNC void luaO_tostring (lua_State *L, StkId obj);
542LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
543 va_list argp);
544LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
545LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
546
547
548#endif
549
diff --git a/src/lua-5.3/lopcodes.c b/src/lua-5.3/lopcodes.c
new file mode 100644
index 0000000..5ca3eb2
--- /dev/null
+++ b/src/lua-5.3/lopcodes.c
@@ -0,0 +1,124 @@
1/*
2** $Id: lopcodes.c,v 1.55.1.1 2017/04/19 17:20:42 roberto Exp $
3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7#define lopcodes_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <stddef.h>
14
15#include "lopcodes.h"
16
17
18/* ORDER OP */
19
20LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
21 "MOVE",
22 "LOADK",
23 "LOADKX",
24 "LOADBOOL",
25 "LOADNIL",
26 "GETUPVAL",
27 "GETTABUP",
28 "GETTABLE",
29 "SETTABUP",
30 "SETUPVAL",
31 "SETTABLE",
32 "NEWTABLE",
33 "SELF",
34 "ADD",
35 "SUB",
36 "MUL",
37 "MOD",
38 "POW",
39 "DIV",
40 "IDIV",
41 "BAND",
42 "BOR",
43 "BXOR",
44 "SHL",
45 "SHR",
46 "UNM",
47 "BNOT",
48 "NOT",
49 "LEN",
50 "CONCAT",
51 "JMP",
52 "EQ",
53 "LT",
54 "LE",
55 "TEST",
56 "TESTSET",
57 "CALL",
58 "TAILCALL",
59 "RETURN",
60 "FORLOOP",
61 "FORPREP",
62 "TFORCALL",
63 "TFORLOOP",
64 "SETLIST",
65 "CLOSURE",
66 "VARARG",
67 "EXTRAARG",
68 NULL
69};
70
71
72#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
73
74LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
75/* T A B C mode opcode */
76 opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
77 ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
78 ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */
79 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
80 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */
81 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
82 ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */
83 ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
84 ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */
85 ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
86 ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
87 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
88 ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
89 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
90 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
91 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
92 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
93 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
94 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
95 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */
96 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */
97 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */
98 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */
99 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */
100 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */
101 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
102 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */
103 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
104 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
105 ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
106 ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
107 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
108 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
109 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
110 ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */
111 ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
112 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
113 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
114 ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
115 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
116 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
117 ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */
118 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */
119 ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
120 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
121 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
122 ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */
123};
124
diff --git a/src/lua-5.3/lopcodes.h b/src/lua-5.3/lopcodes.h
new file mode 100644
index 0000000..6feaa1c
--- /dev/null
+++ b/src/lua-5.3/lopcodes.h
@@ -0,0 +1,297 @@
1/*
2** $Id: lopcodes.h,v 1.149.1.1 2017/04/19 17:20:42 roberto Exp $
3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lopcodes_h
8#define lopcodes_h
9
10#include "llimits.h"
11
12
13/*===========================================================================
14 We assume that instructions are unsigned numbers.
15 All instructions have an opcode in the first 6 bits.
16 Instructions can have the following fields:
17 'A' : 8 bits
18 'B' : 9 bits
19 'C' : 9 bits
20 'Ax' : 26 bits ('A', 'B', and 'C' together)
21 'Bx' : 18 bits ('B' and 'C' together)
22 'sBx' : signed Bx
23
24 A signed argument is represented in excess K; that is, the number
25 value is the unsigned value minus K. K is exactly the maximum value
26 for that argument (so that -max is represented by 0, and +max is
27 represented by 2*max), which is half the maximum for the corresponding
28 unsigned argument.
29===========================================================================*/
30
31
32enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */
33
34
35/*
36** size and position of opcode arguments.
37*/
38#define SIZE_C 9
39#define SIZE_B 9
40#define SIZE_Bx (SIZE_C + SIZE_B)
41#define SIZE_A 8
42#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A)
43
44#define SIZE_OP 6
45
46#define POS_OP 0
47#define POS_A (POS_OP + SIZE_OP)
48#define POS_C (POS_A + SIZE_A)
49#define POS_B (POS_C + SIZE_C)
50#define POS_Bx POS_C
51#define POS_Ax POS_A
52
53
54/*
55** limits for opcode arguments.
56** we use (signed) int to manipulate most arguments,
57** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
58*/
59#if SIZE_Bx < LUAI_BITSINT-1
60#define MAXARG_Bx ((1<<SIZE_Bx)-1)
61#define MAXARG_sBx (MAXARG_Bx>>1) /* 'sBx' is signed */
62#else
63#define MAXARG_Bx MAX_INT
64#define MAXARG_sBx MAX_INT
65#endif
66
67#if SIZE_Ax < LUAI_BITSINT-1
68#define MAXARG_Ax ((1<<SIZE_Ax)-1)
69#else
70#define MAXARG_Ax MAX_INT
71#endif
72
73
74#define MAXARG_A ((1<<SIZE_A)-1)
75#define MAXARG_B ((1<<SIZE_B)-1)
76#define MAXARG_C ((1<<SIZE_C)-1)
77
78
79/* creates a mask with 'n' 1 bits at position 'p' */
80#define MASK1(n,p) ((~((~(Instruction)0)<<(n)))<<(p))
81
82/* creates a mask with 'n' 0 bits at position 'p' */
83#define MASK0(n,p) (~MASK1(n,p))
84
85/*
86** the following macros help to manipulate instructions
87*/
88
89#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
90#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
91 ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
92
93#define getarg(i,pos,size) (cast(int, ((i)>>pos) & MASK1(size,0)))
94#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \
95 ((cast(Instruction, v)<<pos)&MASK1(size,pos))))
96
97#define GETARG_A(i) getarg(i, POS_A, SIZE_A)
98#define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A)
99
100#define GETARG_B(i) getarg(i, POS_B, SIZE_B)
101#define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B)
102
103#define GETARG_C(i) getarg(i, POS_C, SIZE_C)
104#define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C)
105
106#define GETARG_Bx(i) getarg(i, POS_Bx, SIZE_Bx)
107#define SETARG_Bx(i,v) setarg(i, v, POS_Bx, SIZE_Bx)
108
109#define GETARG_Ax(i) getarg(i, POS_Ax, SIZE_Ax)
110#define SETARG_Ax(i,v) setarg(i, v, POS_Ax, SIZE_Ax)
111
112#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
113#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
114
115
116#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \
117 | (cast(Instruction, a)<<POS_A) \
118 | (cast(Instruction, b)<<POS_B) \
119 | (cast(Instruction, c)<<POS_C))
120
121#define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \
122 | (cast(Instruction, a)<<POS_A) \
123 | (cast(Instruction, bc)<<POS_Bx))
124
125#define CREATE_Ax(o,a) ((cast(Instruction, o)<<POS_OP) \
126 | (cast(Instruction, a)<<POS_Ax))
127
128
129/*
130** Macros to operate RK indices
131*/
132
133/* this bit 1 means constant (0 means register) */
134#define BITRK (1 << (SIZE_B - 1))
135
136/* test whether value is a constant */
137#define ISK(x) ((x) & BITRK)
138
139/* gets the index of the constant */
140#define INDEXK(r) ((int)(r) & ~BITRK)
141
142#if !defined(MAXINDEXRK) /* (for debugging only) */
143#define MAXINDEXRK (BITRK - 1)
144#endif
145
146/* code a constant index as a RK value */
147#define RKASK(x) ((x) | BITRK)
148
149
150/*
151** invalid register that fits in 8 bits
152*/
153#define NO_REG MAXARG_A
154
155
156/*
157** R(x) - register
158** Kst(x) - constant (in constant table)
159** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
160*/
161
162
163/*
164** grep "ORDER OP" if you change these enums
165*/
166
167typedef enum {
168/*----------------------------------------------------------------------
169name args description
170------------------------------------------------------------------------*/
171OP_MOVE,/* A B R(A) := R(B) */
172OP_LOADK,/* A Bx R(A) := Kst(Bx) */
173OP_LOADKX,/* A R(A) := Kst(extra arg) */
174OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
175OP_LOADNIL,/* A B R(A), R(A+1), ..., R(A+B) := nil */
176OP_GETUPVAL,/* A B R(A) := UpValue[B] */
177
178OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */
179OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
180
181OP_SETTABUP,/* A B C UpValue[A][RK(B)] := RK(C) */
182OP_SETUPVAL,/* A B UpValue[B] := R(A) */
183OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
184
185OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
186
187OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
188
189OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
190OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
191OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
192OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
193OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
194OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
195OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */
196OP_BAND,/* A B C R(A) := RK(B) & RK(C) */
197OP_BOR,/* A B C R(A) := RK(B) | RK(C) */
198OP_BXOR,/* A B C R(A) := RK(B) ~ RK(C) */
199OP_SHL,/* A B C R(A) := RK(B) << RK(C) */
200OP_SHR,/* A B C R(A) := RK(B) >> RK(C) */
201OP_UNM,/* A B R(A) := -R(B) */
202OP_BNOT,/* A B R(A) := ~R(B) */
203OP_NOT,/* A B R(A) := not R(B) */
204OP_LEN,/* A B R(A) := length of R(B) */
205
206OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
207
208OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
209OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
210OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
211OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
212
213OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
214OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
215
216OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
217OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
218OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
219
220OP_FORLOOP,/* A sBx R(A)+=R(A+2);
221 if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
222OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
223
224OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
225OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
226
227OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
228
229OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */
230
231OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
232
233OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
234} OpCode;
235
236
237#define NUM_OPCODES (cast(int, OP_EXTRAARG) + 1)
238
239
240
241/*===========================================================================
242 Notes:
243 (*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then 'top' is
244 set to last_result+1, so next open instruction (OP_CALL, OP_RETURN,
245 OP_SETLIST) may use 'top'.
246
247 (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
248 set top (like in OP_CALL with C == 0).
249
250 (*) In OP_RETURN, if (B == 0) then return up to 'top'.
251
252 (*) In OP_SETLIST, if (B == 0) then B = 'top'; if (C == 0) then next
253 'instruction' is EXTRAARG(real C).
254
255 (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG.
256
257 (*) For comparisons, A specifies what condition the test should accept
258 (true or false).
259
260 (*) All 'skips' (pc++) assume that next instruction is a jump.
261
262===========================================================================*/
263
264
265/*
266** masks for instruction properties. The format is:
267** bits 0-1: op mode
268** bits 2-3: C arg mode
269** bits 4-5: B arg mode
270** bit 6: instruction set register A
271** bit 7: operator is a test (next instruction must be a jump)
272*/
273
274enum OpArgMask {
275 OpArgN, /* argument is not used */
276 OpArgU, /* argument is used */
277 OpArgR, /* argument is a register or a jump offset */
278 OpArgK /* argument is a constant or register/constant */
279};
280
281LUAI_DDEC const lu_byte luaP_opmodes[NUM_OPCODES];
282
283#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
284#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
285#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
286#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
287#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
288
289
290LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
291
292
293/* number of list items to accumulate before a SETLIST instruction */
294#define LFIELDS_PER_FLUSH 50
295
296
297#endif
diff --git a/src/lua-5.3/loslib.c b/src/lua-5.3/loslib.c
new file mode 100644
index 0000000..de590c6
--- /dev/null
+++ b/src/lua-5.3/loslib.c
@@ -0,0 +1,409 @@
1/*
2** $Id: loslib.c,v 1.65.1.1 2017/04/19 17:29:57 roberto Exp $
3** Standard Operating System library
4** See Copyright Notice in lua.h
5*/
6
7#define loslib_c
8#define LUA_LIB
9
10#include "lprefix.h"
11
12
13#include <errno.h>
14#include <locale.h>
15#include <stdlib.h>
16#include <string.h>
17#include <time.h>
18
19#include "lua.h"
20
21#include "lauxlib.h"
22#include "lualib.h"
23
24
25/*
26** {==================================================================
27** List of valid conversion specifiers for the 'strftime' function;
28** options are grouped by length; group of length 2 start with '||'.
29** ===================================================================
30*/
31#if !defined(LUA_STRFTIMEOPTIONS) /* { */
32
33/* options for ANSI C 89 (only 1-char options) */
34#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%"
35
36/* options for ISO C 99 and POSIX */
37#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
38 "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */
39
40/* options for Windows */
41#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
42 "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */
43
44#if defined(LUA_USE_WINDOWS)
45#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN
46#elif defined(LUA_USE_C89)
47#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89
48#else /* C99 specification */
49#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99
50#endif
51
52#endif /* } */
53/* }================================================================== */
54
55
56/*
57** {==================================================================
58** Configuration for time-related stuff
59** ===================================================================
60*/
61
62#if !defined(l_time_t) /* { */
63/*
64** type to represent time_t in Lua
65*/
66#define l_timet lua_Integer
67#define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t))
68
69static time_t l_checktime (lua_State *L, int arg) {
70 lua_Integer t = luaL_checkinteger(L, arg);
71 luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds");
72 return (time_t)t;
73}
74
75#endif /* } */
76
77
78#if !defined(l_gmtime) /* { */
79/*
80** By default, Lua uses gmtime/localtime, except when POSIX is available,
81** where it uses gmtime_r/localtime_r
82*/
83
84#if defined(LUA_USE_POSIX) /* { */
85
86#define l_gmtime(t,r) gmtime_r(t,r)
87#define l_localtime(t,r) localtime_r(t,r)
88
89#else /* }{ */
90
91/* ISO C definitions */
92#define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t))
93#define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t))
94
95#endif /* } */
96
97#endif /* } */
98
99/* }================================================================== */
100
101
102/*
103** {==================================================================
104** Configuration for 'tmpnam':
105** By default, Lua uses tmpnam except when POSIX is available, where
106** it uses mkstemp.
107** ===================================================================
108*/
109#if !defined(lua_tmpnam) /* { */
110
111#if defined(LUA_USE_POSIX) /* { */
112
113#include <unistd.h>
114
115#define LUA_TMPNAMBUFSIZE 32
116
117#if !defined(LUA_TMPNAMTEMPLATE)
118#define LUA_TMPNAMTEMPLATE "/tmp/lua_XXXXXX"
119#endif
120
121#define lua_tmpnam(b,e) { \
122 strcpy(b, LUA_TMPNAMTEMPLATE); \
123 e = mkstemp(b); \
124 if (e != -1) close(e); \
125 e = (e == -1); }
126
127#else /* }{ */
128
129/* ISO C definitions */
130#define LUA_TMPNAMBUFSIZE L_tmpnam
131#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
132
133#endif /* } */
134
135#endif /* } */
136/* }================================================================== */
137
138
139
140
141static int os_execute (lua_State *L) {
142 const char *cmd = luaL_optstring(L, 1, NULL);
143 int stat = system(cmd);
144 if (cmd != NULL)
145 return luaL_execresult(L, stat);
146 else {
147 lua_pushboolean(L, stat); /* true if there is a shell */
148 return 1;
149 }
150}
151
152
153static int os_remove (lua_State *L) {
154 const char *filename = luaL_checkstring(L, 1);
155 return luaL_fileresult(L, remove(filename) == 0, filename);
156}
157
158
159static int os_rename (lua_State *L) {
160 const char *fromname = luaL_checkstring(L, 1);
161 const char *toname = luaL_checkstring(L, 2);
162 return luaL_fileresult(L, rename(fromname, toname) == 0, NULL);
163}
164
165
166static int os_tmpname (lua_State *L) {
167 char buff[LUA_TMPNAMBUFSIZE];
168 int err;
169 lua_tmpnam(buff, err);
170 if (err)
171 return luaL_error(L, "unable to generate a unique filename");
172 lua_pushstring(L, buff);
173 return 1;
174}
175
176
177static int os_getenv (lua_State *L) {
178 lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
179 return 1;
180}
181
182
183static int os_clock (lua_State *L) {
184 lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
185 return 1;
186}
187
188
189/*
190** {======================================================
191** Time/Date operations
192** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
193** wday=%w+1, yday=%j, isdst=? }
194** =======================================================
195*/
196
197static void setfield (lua_State *L, const char *key, int value) {
198 lua_pushinteger(L, value);
199 lua_setfield(L, -2, key);
200}
201
202static void setboolfield (lua_State *L, const char *key, int value) {
203 if (value < 0) /* undefined? */
204 return; /* does not set field */
205 lua_pushboolean(L, value);
206 lua_setfield(L, -2, key);
207}
208
209
210/*
211** Set all fields from structure 'tm' in the table on top of the stack
212*/
213static void setallfields (lua_State *L, struct tm *stm) {
214 setfield(L, "sec", stm->tm_sec);
215 setfield(L, "min", stm->tm_min);
216 setfield(L, "hour", stm->tm_hour);
217 setfield(L, "day", stm->tm_mday);
218 setfield(L, "month", stm->tm_mon + 1);
219 setfield(L, "year", stm->tm_year + 1900);
220 setfield(L, "wday", stm->tm_wday + 1);
221 setfield(L, "yday", stm->tm_yday + 1);
222 setboolfield(L, "isdst", stm->tm_isdst);
223}
224
225
226static int getboolfield (lua_State *L, const char *key) {
227 int res;
228 res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1);
229 lua_pop(L, 1);
230 return res;
231}
232
233
234/* maximum value for date fields (to avoid arithmetic overflows with 'int') */
235#if !defined(L_MAXDATEFIELD)
236#define L_MAXDATEFIELD (INT_MAX / 2)
237#endif
238
239static int getfield (lua_State *L, const char *key, int d, int delta) {
240 int isnum;
241 int t = lua_getfield(L, -1, key); /* get field and its type */
242 lua_Integer res = lua_tointegerx(L, -1, &isnum);
243 if (!isnum) { /* field is not an integer? */
244 if (t != LUA_TNIL) /* some other value? */
245 return luaL_error(L, "field '%s' is not an integer", key);
246 else if (d < 0) /* absent field; no default? */
247 return luaL_error(L, "field '%s' missing in date table", key);
248 res = d;
249 }
250 else {
251 if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD))
252 return luaL_error(L, "field '%s' is out-of-bound", key);
253 res -= delta;
254 }
255 lua_pop(L, 1);
256 return (int)res;
257}
258
259
260static const char *checkoption (lua_State *L, const char *conv,
261 ptrdiff_t convlen, char *buff) {
262 const char *option = LUA_STRFTIMEOPTIONS;
263 int oplen = 1; /* length of options being checked */
264 for (; *option != '\0' && oplen <= convlen; option += oplen) {
265 if (*option == '|') /* next block? */
266 oplen++; /* will check options with next length (+1) */
267 else if (memcmp(conv, option, oplen) == 0) { /* match? */
268 memcpy(buff, conv, oplen); /* copy valid option to buffer */
269 buff[oplen] = '\0';
270 return conv + oplen; /* return next item */
271 }
272 }
273 luaL_argerror(L, 1,
274 lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv));
275 return conv; /* to avoid warnings */
276}
277
278
279/* maximum size for an individual 'strftime' item */
280#define SIZETIMEFMT 250
281
282
283static int os_date (lua_State *L) {
284 size_t slen;
285 const char *s = luaL_optlstring(L, 1, "%c", &slen);
286 time_t t = luaL_opt(L, l_checktime, 2, time(NULL));
287 const char *se = s + slen; /* 's' end */
288 struct tm tmr, *stm;
289 if (*s == '!') { /* UTC? */
290 stm = l_gmtime(&t, &tmr);
291 s++; /* skip '!' */
292 }
293 else
294 stm = l_localtime(&t, &tmr);
295 if (stm == NULL) /* invalid date? */
296 return luaL_error(L,
297 "time result cannot be represented in this installation");
298 if (strcmp(s, "*t") == 0) {
299 lua_createtable(L, 0, 9); /* 9 = number of fields */
300 setallfields(L, stm);
301 }
302 else {
303 char cc[4]; /* buffer for individual conversion specifiers */
304 luaL_Buffer b;
305 cc[0] = '%';
306 luaL_buffinit(L, &b);
307 while (s < se) {
308 if (*s != '%') /* not a conversion specifier? */
309 luaL_addchar(&b, *s++);
310 else {
311 size_t reslen;
312 char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
313 s++; /* skip '%' */
314 s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */
315 reslen = strftime(buff, SIZETIMEFMT, cc, stm);
316 luaL_addsize(&b, reslen);
317 }
318 }
319 luaL_pushresult(&b);
320 }
321 return 1;
322}
323
324
325static int os_time (lua_State *L) {
326 time_t t;
327 if (lua_isnoneornil(L, 1)) /* called without args? */
328 t = time(NULL); /* get current time */
329 else {
330 struct tm ts;
331 luaL_checktype(L, 1, LUA_TTABLE);
332 lua_settop(L, 1); /* make sure table is at the top */
333 ts.tm_sec = getfield(L, "sec", 0, 0);
334 ts.tm_min = getfield(L, "min", 0, 0);
335 ts.tm_hour = getfield(L, "hour", 12, 0);
336 ts.tm_mday = getfield(L, "day", -1, 0);
337 ts.tm_mon = getfield(L, "month", -1, 1);
338 ts.tm_year = getfield(L, "year", -1, 1900);
339 ts.tm_isdst = getboolfield(L, "isdst");
340 t = mktime(&ts);
341 setallfields(L, &ts); /* update fields with normalized values */
342 }
343 if (t != (time_t)(l_timet)t || t == (time_t)(-1))
344 return luaL_error(L,
345 "time result cannot be represented in this installation");
346 l_pushtime(L, t);
347 return 1;
348}
349
350
351static int os_difftime (lua_State *L) {
352 time_t t1 = l_checktime(L, 1);
353 time_t t2 = l_checktime(L, 2);
354 lua_pushnumber(L, (lua_Number)difftime(t1, t2));
355 return 1;
356}
357
358/* }====================================================== */
359
360
361static int os_setlocale (lua_State *L) {
362 static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
363 LC_NUMERIC, LC_TIME};
364 static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
365 "numeric", "time", NULL};
366 const char *l = luaL_optstring(L, 1, NULL);
367 int op = luaL_checkoption(L, 2, "all", catnames);
368 lua_pushstring(L, setlocale(cat[op], l));
369 return 1;
370}
371
372
373static int os_exit (lua_State *L) {
374 int status;
375 if (lua_isboolean(L, 1))
376 status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
377 else
378 status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS);
379 if (lua_toboolean(L, 2))
380 lua_close(L);
381 if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */
382 return 0;
383}
384
385
386static const luaL_Reg syslib[] = {
387 {"clock", os_clock},
388 {"date", os_date},
389 {"difftime", os_difftime},
390 {"execute", os_execute},
391 {"exit", os_exit},
392 {"getenv", os_getenv},
393 {"remove", os_remove},
394 {"rename", os_rename},
395 {"setlocale", os_setlocale},
396 {"time", os_time},
397 {"tmpname", os_tmpname},
398 {NULL, NULL}
399};
400
401/* }====================================================== */
402
403
404
405LUAMOD_API int luaopen_os (lua_State *L) {
406 luaL_newlib(L, syslib);
407 return 1;
408}
409
diff --git a/src/lua-5.3/lparser.c b/src/lua-5.3/lparser.c
new file mode 100644
index 0000000..cc54de4
--- /dev/null
+++ b/src/lua-5.3/lparser.c
@@ -0,0 +1,1650 @@
1/*
2** $Id: lparser.c,v 2.155.1.2 2017/04/29 18:11:40 roberto Exp $
3** Lua Parser
4** See Copyright Notice in lua.h
5*/
6
7#define lparser_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <string.h>
14
15#include "lua.h"
16
17#include "lcode.h"
18#include "ldebug.h"
19#include "ldo.h"
20#include "lfunc.h"
21#include "llex.h"
22#include "lmem.h"
23#include "lobject.h"
24#include "lopcodes.h"
25#include "lparser.h"
26#include "lstate.h"
27#include "lstring.h"
28#include "ltable.h"
29
30
31
32/* maximum number of local variables per function (must be smaller
33 than 250, due to the bytecode format) */
34#define MAXVARS 200
35
36
37#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
38
39
40/* because all strings are unified by the scanner, the parser
41 can use pointer equality for string equality */
42#define eqstr(a,b) ((a) == (b))
43
44
45/*
46** nodes for block list (list of active blocks)
47*/
48typedef struct BlockCnt {
49 struct BlockCnt *previous; /* chain */
50 int firstlabel; /* index of first label in this block */
51 int firstgoto; /* index of first pending goto in this block */
52 lu_byte nactvar; /* # active locals outside the block */
53 lu_byte upval; /* true if some variable in the block is an upvalue */
54 lu_byte isloop; /* true if 'block' is a loop */
55} BlockCnt;
56
57
58
59/*
60** prototypes for recursive non-terminal functions
61*/
62static void statement (LexState *ls);
63static void expr (LexState *ls, expdesc *v);
64
65
66/* semantic error */
67static l_noret semerror (LexState *ls, const char *msg) {
68 ls->t.token = 0; /* remove "near <token>" from final message */
69 luaX_syntaxerror(ls, msg);
70}
71
72
73static l_noret error_expected (LexState *ls, int token) {
74 luaX_syntaxerror(ls,
75 luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));
76}
77
78
79static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
80 lua_State *L = fs->ls->L;
81 const char *msg;
82 int line = fs->f->linedefined;
83 const char *where = (line == 0)
84 ? "main function"
85 : luaO_pushfstring(L, "function at line %d", line);
86 msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",
87 what, limit, where);
88 luaX_syntaxerror(fs->ls, msg);
89}
90
91
92static void checklimit (FuncState *fs, int v, int l, const char *what) {
93 if (v > l) errorlimit(fs, l, what);
94}
95
96
97static int testnext (LexState *ls, int c) {
98 if (ls->t.token == c) {
99 luaX_next(ls);
100 return 1;
101 }
102 else return 0;
103}
104
105
106static void check (LexState *ls, int c) {
107 if (ls->t.token != c)
108 error_expected(ls, c);
109}
110
111
112static void checknext (LexState *ls, int c) {
113 check(ls, c);
114 luaX_next(ls);
115}
116
117
118#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
119
120
121
122static void check_match (LexState *ls, int what, int who, int where) {
123 if (!testnext(ls, what)) {
124 if (where == ls->linenumber)
125 error_expected(ls, what);
126 else {
127 luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
128 "%s expected (to close %s at line %d)",
129 luaX_token2str(ls, what), luaX_token2str(ls, who), where));
130 }
131 }
132}
133
134
135static TString *str_checkname (LexState *ls) {
136 TString *ts;
137 check(ls, TK_NAME);
138 ts = ls->t.seminfo.ts;
139 luaX_next(ls);
140 return ts;
141}
142
143
144static void init_exp (expdesc *e, expkind k, int i) {
145 e->f = e->t = NO_JUMP;
146 e->k = k;
147 e->u.info = i;
148}
149
150
151static void codestring (LexState *ls, expdesc *e, TString *s) {
152 init_exp(e, VK, luaK_stringK(ls->fs, s));
153}
154
155
156static void checkname (LexState *ls, expdesc *e) {
157 codestring(ls, e, str_checkname(ls));
158}
159
160
161static int registerlocalvar (LexState *ls, TString *varname) {
162 FuncState *fs = ls->fs;
163 Proto *f = fs->f;
164 int oldsize = f->sizelocvars;
165 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
166 LocVar, SHRT_MAX, "local variables");
167 while (oldsize < f->sizelocvars)
168 f->locvars[oldsize++].varname = NULL;
169 f->locvars[fs->nlocvars].varname = varname;
170 luaC_objbarrier(ls->L, f, varname);
171 return fs->nlocvars++;
172}
173
174
175static void new_localvar (LexState *ls, TString *name) {
176 FuncState *fs = ls->fs;
177 Dyndata *dyd = ls->dyd;
178 int reg = registerlocalvar(ls, name);
179 checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
180 MAXVARS, "local variables");
181 luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1,
182 dyd->actvar.size, Vardesc, MAX_INT, "local variables");
183 dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg);
184}
185
186
187static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) {
188 new_localvar(ls, luaX_newstring(ls, name, sz));
189}
190
191#define new_localvarliteral(ls,v) \
192 new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1)
193
194
195static LocVar *getlocvar (FuncState *fs, int i) {
196 int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
197 lua_assert(idx < fs->nlocvars);
198 return &fs->f->locvars[idx];
199}
200
201
202static void adjustlocalvars (LexState *ls, int nvars) {
203 FuncState *fs = ls->fs;
204 fs->nactvar = cast_byte(fs->nactvar + nvars);
205 for (; nvars; nvars--) {
206 getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc;
207 }
208}
209
210
211static void removevars (FuncState *fs, int tolevel) {
212 fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
213 while (fs->nactvar > tolevel)
214 getlocvar(fs, --fs->nactvar)->endpc = fs->pc;
215}
216
217
218static int searchupvalue (FuncState *fs, TString *name) {
219 int i;
220 Upvaldesc *up = fs->f->upvalues;
221 for (i = 0; i < fs->nups; i++) {
222 if (eqstr(up[i].name, name)) return i;
223 }
224 return -1; /* not found */
225}
226
227
228static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
229 Proto *f = fs->f;
230 int oldsize = f->sizeupvalues;
231 checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
232 luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
233 Upvaldesc, MAXUPVAL, "upvalues");
234 while (oldsize < f->sizeupvalues)
235 f->upvalues[oldsize++].name = NULL;
236 f->upvalues[fs->nups].instack = (v->k == VLOCAL);
237 f->upvalues[fs->nups].idx = cast_byte(v->u.info);
238 f->upvalues[fs->nups].name = name;
239 luaC_objbarrier(fs->ls->L, f, name);
240 return fs->nups++;
241}
242
243
244static int searchvar (FuncState *fs, TString *n) {
245 int i;
246 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
247 if (eqstr(n, getlocvar(fs, i)->varname))
248 return i;
249 }
250 return -1; /* not found */
251}
252
253
254/*
255 Mark block where variable at given level was defined
256 (to emit close instructions later).
257*/
258static void markupval (FuncState *fs, int level) {
259 BlockCnt *bl = fs->bl;
260 while (bl->nactvar > level)
261 bl = bl->previous;
262 bl->upval = 1;
263}
264
265
266/*
267 Find variable with given name 'n'. If it is an upvalue, add this
268 upvalue into all intermediate functions.
269*/
270static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
271 if (fs == NULL) /* no more levels? */
272 init_exp(var, VVOID, 0); /* default is global */
273 else {
274 int v = searchvar(fs, n); /* look up locals at current level */
275 if (v >= 0) { /* found? */
276 init_exp(var, VLOCAL, v); /* variable is local */
277 if (!base)
278 markupval(fs, v); /* local will be used as an upval */
279 }
280 else { /* not found as local at current level; try upvalues */
281 int idx = searchupvalue(fs, n); /* try existing upvalues */
282 if (idx < 0) { /* not found? */
283 singlevaraux(fs->prev, n, var, 0); /* try upper levels */
284 if (var->k == VVOID) /* not found? */
285 return; /* it is a global */
286 /* else was LOCAL or UPVAL */
287 idx = newupvalue(fs, n, var); /* will be a new upvalue */
288 }
289 init_exp(var, VUPVAL, idx); /* new or old upvalue */
290 }
291 }
292}
293
294
295static void singlevar (LexState *ls, expdesc *var) {
296 TString *varname = str_checkname(ls);
297 FuncState *fs = ls->fs;
298 singlevaraux(fs, varname, var, 1);
299 if (var->k == VVOID) { /* global name? */
300 expdesc key;
301 singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
302 lua_assert(var->k != VVOID); /* this one must exist */
303 codestring(ls, &key, varname); /* key is variable name */
304 luaK_indexed(fs, var, &key); /* env[varname] */
305 }
306}
307
308
309static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
310 FuncState *fs = ls->fs;
311 int extra = nvars - nexps;
312 if (hasmultret(e->k)) {
313 extra++; /* includes call itself */
314 if (extra < 0) extra = 0;
315 luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
316 if (extra > 1) luaK_reserveregs(fs, extra-1);
317 }
318 else {
319 if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
320 if (extra > 0) {
321 int reg = fs->freereg;
322 luaK_reserveregs(fs, extra);
323 luaK_nil(fs, reg, extra);
324 }
325 }
326 if (nexps > nvars)
327 ls->fs->freereg -= nexps - nvars; /* remove extra values */
328}
329
330
331static void enterlevel (LexState *ls) {
332 lua_State *L = ls->L;
333 ++L->nCcalls;
334 checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels");
335}
336
337
338#define leavelevel(ls) ((ls)->L->nCcalls--)
339
340
341static void closegoto (LexState *ls, int g, Labeldesc *label) {
342 int i;
343 FuncState *fs = ls->fs;
344 Labellist *gl = &ls->dyd->gt;
345 Labeldesc *gt = &gl->arr[g];
346 lua_assert(eqstr(gt->name, label->name));
347 if (gt->nactvar < label->nactvar) {
348 TString *vname = getlocvar(fs, gt->nactvar)->varname;
349 const char *msg = luaO_pushfstring(ls->L,
350 "<goto %s> at line %d jumps into the scope of local '%s'",
351 getstr(gt->name), gt->line, getstr(vname));
352 semerror(ls, msg);
353 }
354 luaK_patchlist(fs, gt->pc, label->pc);
355 /* remove goto from pending list */
356 for (i = g; i < gl->n - 1; i++)
357 gl->arr[i] = gl->arr[i + 1];
358 gl->n--;
359}
360
361
362/*
363** try to close a goto with existing labels; this solves backward jumps
364*/
365static int findlabel (LexState *ls, int g) {
366 int i;
367 BlockCnt *bl = ls->fs->bl;
368 Dyndata *dyd = ls->dyd;
369 Labeldesc *gt = &dyd->gt.arr[g];
370 /* check labels in current block for a match */
371 for (i = bl->firstlabel; i < dyd->label.n; i++) {
372 Labeldesc *lb = &dyd->label.arr[i];
373 if (eqstr(lb->name, gt->name)) { /* correct label? */
374 if (gt->nactvar > lb->nactvar &&
375 (bl->upval || dyd->label.n > bl->firstlabel))
376 luaK_patchclose(ls->fs, gt->pc, lb->nactvar);
377 closegoto(ls, g, lb); /* close it */
378 return 1;
379 }
380 }
381 return 0; /* label not found; cannot close goto */
382}
383
384
385static int newlabelentry (LexState *ls, Labellist *l, TString *name,
386 int line, int pc) {
387 int n = l->n;
388 luaM_growvector(ls->L, l->arr, n, l->size,
389 Labeldesc, SHRT_MAX, "labels/gotos");
390 l->arr[n].name = name;
391 l->arr[n].line = line;
392 l->arr[n].nactvar = ls->fs->nactvar;
393 l->arr[n].pc = pc;
394 l->n = n + 1;
395 return n;
396}
397
398
399/*
400** check whether new label 'lb' matches any pending gotos in current
401** block; solves forward jumps
402*/
403static void findgotos (LexState *ls, Labeldesc *lb) {
404 Labellist *gl = &ls->dyd->gt;
405 int i = ls->fs->bl->firstgoto;
406 while (i < gl->n) {
407 if (eqstr(gl->arr[i].name, lb->name))
408 closegoto(ls, i, lb);
409 else
410 i++;
411 }
412}
413
414
415/*
416** export pending gotos to outer level, to check them against
417** outer labels; if the block being exited has upvalues, and
418** the goto exits the scope of any variable (which can be the
419** upvalue), close those variables being exited.
420*/
421static void movegotosout (FuncState *fs, BlockCnt *bl) {
422 int i = bl->firstgoto;
423 Labellist *gl = &fs->ls->dyd->gt;
424 /* correct pending gotos to current block and try to close it
425 with visible labels */
426 while (i < gl->n) {
427 Labeldesc *gt = &gl->arr[i];
428 if (gt->nactvar > bl->nactvar) {
429 if (bl->upval)
430 luaK_patchclose(fs, gt->pc, bl->nactvar);
431 gt->nactvar = bl->nactvar;
432 }
433 if (!findlabel(fs->ls, i))
434 i++; /* move to next one */
435 }
436}
437
438
439static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
440 bl->isloop = isloop;
441 bl->nactvar = fs->nactvar;
442 bl->firstlabel = fs->ls->dyd->label.n;
443 bl->firstgoto = fs->ls->dyd->gt.n;
444 bl->upval = 0;
445 bl->previous = fs->bl;
446 fs->bl = bl;
447 lua_assert(fs->freereg == fs->nactvar);
448}
449
450
451/*
452** create a label named 'break' to resolve break statements
453*/
454static void breaklabel (LexState *ls) {
455 TString *n = luaS_new(ls->L, "break");
456 int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc);
457 findgotos(ls, &ls->dyd->label.arr[l]);
458}
459
460/*
461** generates an error for an undefined 'goto'; choose appropriate
462** message when label name is a reserved word (which can only be 'break')
463*/
464static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
465 const char *msg = isreserved(gt->name)
466 ? "<%s> at line %d not inside a loop"
467 : "no visible label '%s' for <goto> at line %d";
468 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
469 semerror(ls, msg);
470}
471
472
473static void leaveblock (FuncState *fs) {
474 BlockCnt *bl = fs->bl;
475 LexState *ls = fs->ls;
476 if (bl->previous && bl->upval) {
477 /* create a 'jump to here' to close upvalues */
478 int j = luaK_jump(fs);
479 luaK_patchclose(fs, j, bl->nactvar);
480 luaK_patchtohere(fs, j);
481 }
482 if (bl->isloop)
483 breaklabel(ls); /* close pending breaks */
484 fs->bl = bl->previous;
485 removevars(fs, bl->nactvar);
486 lua_assert(bl->nactvar == fs->nactvar);
487 fs->freereg = fs->nactvar; /* free registers */
488 ls->dyd->label.n = bl->firstlabel; /* remove local labels */
489 if (bl->previous) /* inner block? */
490 movegotosout(fs, bl); /* update pending gotos to outer block */
491 else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */
492 undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */
493}
494
495
496/*
497** adds a new prototype into list of prototypes
498*/
499static Proto *addprototype (LexState *ls) {
500 Proto *clp;
501 lua_State *L = ls->L;
502 FuncState *fs = ls->fs;
503 Proto *f = fs->f; /* prototype of current function */
504 if (fs->np >= f->sizep) {
505 int oldsize = f->sizep;
506 luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
507 while (oldsize < f->sizep)
508 f->p[oldsize++] = NULL;
509 }
510 f->p[fs->np++] = clp = luaF_newproto(L);
511 luaC_objbarrier(L, f, clp);
512 return clp;
513}
514
515
516/*
517** codes instruction to create new closure in parent function.
518** The OP_CLOSURE instruction must use the last available register,
519** so that, if it invokes the GC, the GC knows which registers
520** are in use at that time.
521*/
522static void codeclosure (LexState *ls, expdesc *v) {
523 FuncState *fs = ls->fs->prev;
524 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));
525 luaK_exp2nextreg(fs, v); /* fix it at the last register */
526}
527
528
529static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
530 Proto *f;
531 fs->prev = ls->fs; /* linked list of funcstates */
532 fs->ls = ls;
533 ls->fs = fs;
534 fs->pc = 0;
535 fs->lasttarget = 0;
536 fs->jpc = NO_JUMP;
537 fs->freereg = 0;
538 fs->nk = 0;
539 fs->np = 0;
540 fs->nups = 0;
541 fs->nlocvars = 0;
542 fs->nactvar = 0;
543 fs->firstlocal = ls->dyd->actvar.n;
544 fs->bl = NULL;
545 f = fs->f;
546 f->source = ls->source;
547 f->maxstacksize = 2; /* registers 0/1 are always valid */
548 enterblock(fs, bl, 0);
549}
550
551
552static void close_func (LexState *ls) {
553 lua_State *L = ls->L;
554 FuncState *fs = ls->fs;
555 Proto *f = fs->f;
556 luaK_ret(fs, 0, 0); /* final return */
557 leaveblock(fs);
558 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
559 f->sizecode = fs->pc;
560 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
561 f->sizelineinfo = fs->pc;
562 luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
563 f->sizek = fs->nk;
564 luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
565 f->sizep = fs->np;
566 luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
567 f->sizelocvars = fs->nlocvars;
568 luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
569 f->sizeupvalues = fs->nups;
570 lua_assert(fs->bl == NULL);
571 ls->fs = fs->prev;
572 luaC_checkGC(L);
573}
574
575
576
577/*============================================================*/
578/* GRAMMAR RULES */
579/*============================================================*/
580
581
582/*
583** check whether current token is in the follow set of a block.
584** 'until' closes syntactical blocks, but do not close scope,
585** so it is handled in separate.
586*/
587static int block_follow (LexState *ls, int withuntil) {
588 switch (ls->t.token) {
589 case TK_ELSE: case TK_ELSEIF:
590 case TK_END: case TK_EOS:
591 return 1;
592 case TK_UNTIL: return withuntil;
593 default: return 0;
594 }
595}
596
597
598static void statlist (LexState *ls) {
599 /* statlist -> { stat [';'] } */
600 while (!block_follow(ls, 1)) {
601 if (ls->t.token == TK_RETURN) {
602 statement(ls);
603 return; /* 'return' must be last statement */
604 }
605 statement(ls);
606 }
607}
608
609
610static void fieldsel (LexState *ls, expdesc *v) {
611 /* fieldsel -> ['.' | ':'] NAME */
612 FuncState *fs = ls->fs;
613 expdesc key;
614 luaK_exp2anyregup(fs, v);
615 luaX_next(ls); /* skip the dot or colon */
616 checkname(ls, &key);
617 luaK_indexed(fs, v, &key);
618}
619
620
621static void yindex (LexState *ls, expdesc *v) {
622 /* index -> '[' expr ']' */
623 luaX_next(ls); /* skip the '[' */
624 expr(ls, v);
625 luaK_exp2val(ls->fs, v);
626 checknext(ls, ']');
627}
628
629
630/*
631** {======================================================================
632** Rules for Constructors
633** =======================================================================
634*/
635
636
637struct ConsControl {
638 expdesc v; /* last list item read */
639 expdesc *t; /* table descriptor */
640 int nh; /* total number of 'record' elements */
641 int na; /* total number of array elements */
642 int tostore; /* number of array elements pending to be stored */
643};
644
645
646static void recfield (LexState *ls, struct ConsControl *cc) {
647 /* recfield -> (NAME | '['exp1']') = exp1 */
648 FuncState *fs = ls->fs;
649 int reg = ls->fs->freereg;
650 expdesc key, val;
651 int rkkey;
652 if (ls->t.token == TK_NAME) {
653 checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
654 checkname(ls, &key);
655 }
656 else /* ls->t.token == '[' */
657 yindex(ls, &key);
658 cc->nh++;
659 checknext(ls, '=');
660 rkkey = luaK_exp2RK(fs, &key);
661 expr(ls, &val);
662 luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val));
663 fs->freereg = reg; /* free registers */
664}
665
666
667static void closelistfield (FuncState *fs, struct ConsControl *cc) {
668 if (cc->v.k == VVOID) return; /* there is no list item */
669 luaK_exp2nextreg(fs, &cc->v);
670 cc->v.k = VVOID;
671 if (cc->tostore == LFIELDS_PER_FLUSH) {
672 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */
673 cc->tostore = 0; /* no more items pending */
674 }
675}
676
677
678static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
679 if (cc->tostore == 0) return;
680 if (hasmultret(cc->v.k)) {
681 luaK_setmultret(fs, &cc->v);
682 luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET);
683 cc->na--; /* do not count last expression (unknown number of elements) */
684 }
685 else {
686 if (cc->v.k != VVOID)
687 luaK_exp2nextreg(fs, &cc->v);
688 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);
689 }
690}
691
692
693static void listfield (LexState *ls, struct ConsControl *cc) {
694 /* listfield -> exp */
695 expr(ls, &cc->v);
696 checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
697 cc->na++;
698 cc->tostore++;
699}
700
701
702static void field (LexState *ls, struct ConsControl *cc) {
703 /* field -> listfield | recfield */
704 switch(ls->t.token) {
705 case TK_NAME: { /* may be 'listfield' or 'recfield' */
706 if (luaX_lookahead(ls) != '=') /* expression? */
707 listfield(ls, cc);
708 else
709 recfield(ls, cc);
710 break;
711 }
712 case '[': {
713 recfield(ls, cc);
714 break;
715 }
716 default: {
717 listfield(ls, cc);
718 break;
719 }
720 }
721}
722
723
724static void constructor (LexState *ls, expdesc *t) {
725 /* constructor -> '{' [ field { sep field } [sep] ] '}'
726 sep -> ',' | ';' */
727 FuncState *fs = ls->fs;
728 int line = ls->linenumber;
729 int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
730 struct ConsControl cc;
731 cc.na = cc.nh = cc.tostore = 0;
732 cc.t = t;
733 init_exp(t, VRELOCABLE, pc);
734 init_exp(&cc.v, VVOID, 0); /* no value (yet) */
735 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */
736 checknext(ls, '{');
737 do {
738 lua_assert(cc.v.k == VVOID || cc.tostore > 0);
739 if (ls->t.token == '}') break;
740 closelistfield(fs, &cc);
741 field(ls, &cc);
742 } while (testnext(ls, ',') || testnext(ls, ';'));
743 check_match(ls, '}', '{', line);
744 lastlistfield(fs, &cc);
745 SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
746 SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
747}
748
749/* }====================================================================== */
750
751
752
753static void parlist (LexState *ls) {
754 /* parlist -> [ param { ',' param } ] */
755 FuncState *fs = ls->fs;
756 Proto *f = fs->f;
757 int nparams = 0;
758 f->is_vararg = 0;
759 if (ls->t.token != ')') { /* is 'parlist' not empty? */
760 do {
761 switch (ls->t.token) {
762 case TK_NAME: { /* param -> NAME */
763 new_localvar(ls, str_checkname(ls));
764 nparams++;
765 break;
766 }
767 case TK_DOTS: { /* param -> '...' */
768 luaX_next(ls);
769 f->is_vararg = 1; /* declared vararg */
770 break;
771 }
772 default: luaX_syntaxerror(ls, "<name> or '...' expected");
773 }
774 } while (!f->is_vararg && testnext(ls, ','));
775 }
776 adjustlocalvars(ls, nparams);
777 f->numparams = cast_byte(fs->nactvar);
778 luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
779}
780
781
782static void body (LexState *ls, expdesc *e, int ismethod, int line) {
783 /* body -> '(' parlist ')' block END */
784 FuncState new_fs;
785 BlockCnt bl;
786 new_fs.f = addprototype(ls);
787 new_fs.f->linedefined = line;
788 open_func(ls, &new_fs, &bl);
789 checknext(ls, '(');
790 if (ismethod) {
791 new_localvarliteral(ls, "self"); /* create 'self' parameter */
792 adjustlocalvars(ls, 1);
793 }
794 parlist(ls);
795 checknext(ls, ')');
796 statlist(ls);
797 new_fs.f->lastlinedefined = ls->linenumber;
798 check_match(ls, TK_END, TK_FUNCTION, line);
799 codeclosure(ls, e);
800 close_func(ls);
801}
802
803
804static int explist (LexState *ls, expdesc *v) {
805 /* explist -> expr { ',' expr } */
806 int n = 1; /* at least one expression */
807 expr(ls, v);
808 while (testnext(ls, ',')) {
809 luaK_exp2nextreg(ls->fs, v);
810 expr(ls, v);
811 n++;
812 }
813 return n;
814}
815
816
817static void funcargs (LexState *ls, expdesc *f, int line) {
818 FuncState *fs = ls->fs;
819 expdesc args;
820 int base, nparams;
821 switch (ls->t.token) {
822 case '(': { /* funcargs -> '(' [ explist ] ')' */
823 luaX_next(ls);
824 if (ls->t.token == ')') /* arg list is empty? */
825 args.k = VVOID;
826 else {
827 explist(ls, &args);
828 luaK_setmultret(fs, &args);
829 }
830 check_match(ls, ')', '(', line);
831 break;
832 }
833 case '{': { /* funcargs -> constructor */
834 constructor(ls, &args);
835 break;
836 }
837 case TK_STRING: { /* funcargs -> STRING */
838 codestring(ls, &args, ls->t.seminfo.ts);
839 luaX_next(ls); /* must use 'seminfo' before 'next' */
840 break;
841 }
842 default: {
843 luaX_syntaxerror(ls, "function arguments expected");
844 }
845 }
846 lua_assert(f->k == VNONRELOC);
847 base = f->u.info; /* base register for call */
848 if (hasmultret(args.k))
849 nparams = LUA_MULTRET; /* open call */
850 else {
851 if (args.k != VVOID)
852 luaK_exp2nextreg(fs, &args); /* close last argument */
853 nparams = fs->freereg - (base+1);
854 }
855 init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
856 luaK_fixline(fs, line);
857 fs->freereg = base+1; /* call remove function and arguments and leaves
858 (unless changed) one result */
859}
860
861
862
863
864/*
865** {======================================================================
866** Expression parsing
867** =======================================================================
868*/
869
870
871static void primaryexp (LexState *ls, expdesc *v) {
872 /* primaryexp -> NAME | '(' expr ')' */
873 switch (ls->t.token) {
874 case '(': {
875 int line = ls->linenumber;
876 luaX_next(ls);
877 expr(ls, v);
878 check_match(ls, ')', '(', line);
879 luaK_dischargevars(ls->fs, v);
880 return;
881 }
882 case TK_NAME: {
883 singlevar(ls, v);
884 return;
885 }
886 default: {
887 luaX_syntaxerror(ls, "unexpected symbol");
888 }
889 }
890}
891
892
893static void suffixedexp (LexState *ls, expdesc *v) {
894 /* suffixedexp ->
895 primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
896 FuncState *fs = ls->fs;
897 int line = ls->linenumber;
898 primaryexp(ls, v);
899 for (;;) {
900 switch (ls->t.token) {
901 case '.': { /* fieldsel */
902 fieldsel(ls, v);
903 break;
904 }
905 case '[': { /* '[' exp1 ']' */
906 expdesc key;
907 luaK_exp2anyregup(fs, v);
908 yindex(ls, &key);
909 luaK_indexed(fs, v, &key);
910 break;
911 }
912 case ':': { /* ':' NAME funcargs */
913 expdesc key;
914 luaX_next(ls);
915 checkname(ls, &key);
916 luaK_self(fs, v, &key);
917 funcargs(ls, v, line);
918 break;
919 }
920 case '(': case TK_STRING: case '{': { /* funcargs */
921 luaK_exp2nextreg(fs, v);
922 funcargs(ls, v, line);
923 break;
924 }
925 default: return;
926 }
927 }
928}
929
930
931static void simpleexp (LexState *ls, expdesc *v) {
932 /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... |
933 constructor | FUNCTION body | suffixedexp */
934 switch (ls->t.token) {
935 case TK_FLT: {
936 init_exp(v, VKFLT, 0);
937 v->u.nval = ls->t.seminfo.r;
938 break;
939 }
940 case TK_INT: {
941 init_exp(v, VKINT, 0);
942 v->u.ival = ls->t.seminfo.i;
943 break;
944 }
945 case TK_STRING: {
946 codestring(ls, v, ls->t.seminfo.ts);
947 break;
948 }
949 case TK_NIL: {
950 init_exp(v, VNIL, 0);
951 break;
952 }
953 case TK_TRUE: {
954 init_exp(v, VTRUE, 0);
955 break;
956 }
957 case TK_FALSE: {
958 init_exp(v, VFALSE, 0);
959 break;
960 }
961 case TK_DOTS: { /* vararg */
962 FuncState *fs = ls->fs;
963 check_condition(ls, fs->f->is_vararg,
964 "cannot use '...' outside a vararg function");
965 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
966 break;
967 }
968 case '{': { /* constructor */
969 constructor(ls, v);
970 return;
971 }
972 case TK_FUNCTION: {
973 luaX_next(ls);
974 body(ls, v, 0, ls->linenumber);
975 return;
976 }
977 default: {
978 suffixedexp(ls, v);
979 return;
980 }
981 }
982 luaX_next(ls);
983}
984
985
986static UnOpr getunopr (int op) {
987 switch (op) {
988 case TK_NOT: return OPR_NOT;
989 case '-': return OPR_MINUS;
990 case '~': return OPR_BNOT;
991 case '#': return OPR_LEN;
992 default: return OPR_NOUNOPR;
993 }
994}
995
996
997static BinOpr getbinopr (int op) {
998 switch (op) {
999 case '+': return OPR_ADD;
1000 case '-': return OPR_SUB;
1001 case '*': return OPR_MUL;
1002 case '%': return OPR_MOD;
1003 case '^': return OPR_POW;
1004 case '/': return OPR_DIV;
1005 case TK_IDIV: return OPR_IDIV;
1006 case '&': return OPR_BAND;
1007 case '|': return OPR_BOR;
1008 case '~': return OPR_BXOR;
1009 case TK_SHL: return OPR_SHL;
1010 case TK_SHR: return OPR_SHR;
1011 case TK_CONCAT: return OPR_CONCAT;
1012 case TK_NE: return OPR_NE;
1013 case TK_EQ: return OPR_EQ;
1014 case '<': return OPR_LT;
1015 case TK_LE: return OPR_LE;
1016 case '>': return OPR_GT;
1017 case TK_GE: return OPR_GE;
1018 case TK_AND: return OPR_AND;
1019 case TK_OR: return OPR_OR;
1020 default: return OPR_NOBINOPR;
1021 }
1022}
1023
1024
1025static const struct {
1026 lu_byte left; /* left priority for each binary operator */
1027 lu_byte right; /* right priority */
1028} priority[] = { /* ORDER OPR */
1029 {10, 10}, {10, 10}, /* '+' '-' */
1030 {11, 11}, {11, 11}, /* '*' '%' */
1031 {14, 13}, /* '^' (right associative) */
1032 {11, 11}, {11, 11}, /* '/' '//' */
1033 {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */
1034 {7, 7}, {7, 7}, /* '<<' '>>' */
1035 {9, 8}, /* '..' (right associative) */
1036 {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */
1037 {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */
1038 {2, 2}, {1, 1} /* and, or */
1039};
1040
1041#define UNARY_PRIORITY 12 /* priority for unary operators */
1042
1043
1044/*
1045** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
1046** where 'binop' is any binary operator with a priority higher than 'limit'
1047*/
1048static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
1049 BinOpr op;
1050 UnOpr uop;
1051 enterlevel(ls);
1052 uop = getunopr(ls->t.token);
1053 if (uop != OPR_NOUNOPR) {
1054 int line = ls->linenumber;
1055 luaX_next(ls);
1056 subexpr(ls, v, UNARY_PRIORITY);
1057 luaK_prefix(ls->fs, uop, v, line);
1058 }
1059 else simpleexp(ls, v);
1060 /* expand while operators have priorities higher than 'limit' */
1061 op = getbinopr(ls->t.token);
1062 while (op != OPR_NOBINOPR && priority[op].left > limit) {
1063 expdesc v2;
1064 BinOpr nextop;
1065 int line = ls->linenumber;
1066 luaX_next(ls);
1067 luaK_infix(ls->fs, op, v);
1068 /* read sub-expression with higher priority */
1069 nextop = subexpr(ls, &v2, priority[op].right);
1070 luaK_posfix(ls->fs, op, v, &v2, line);
1071 op = nextop;
1072 }
1073 leavelevel(ls);
1074 return op; /* return first untreated operator */
1075}
1076
1077
1078static void expr (LexState *ls, expdesc *v) {
1079 subexpr(ls, v, 0);
1080}
1081
1082/* }==================================================================== */
1083
1084
1085
1086/*
1087** {======================================================================
1088** Rules for Statements
1089** =======================================================================
1090*/
1091
1092
1093static void block (LexState *ls) {
1094 /* block -> statlist */
1095 FuncState *fs = ls->fs;
1096 BlockCnt bl;
1097 enterblock(fs, &bl, 0);
1098 statlist(ls);
1099 leaveblock(fs);
1100}
1101
1102
1103/*
1104** structure to chain all variables in the left-hand side of an
1105** assignment
1106*/
1107struct LHS_assign {
1108 struct LHS_assign *prev;
1109 expdesc v; /* variable (global, local, upvalue, or indexed) */
1110};
1111
1112
1113/*
1114** check whether, in an assignment to an upvalue/local variable, the
1115** upvalue/local variable is begin used in a previous assignment to a
1116** table. If so, save original upvalue/local value in a safe place and
1117** use this safe copy in the previous assignment.
1118*/
1119static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
1120 FuncState *fs = ls->fs;
1121 int extra = fs->freereg; /* eventual position to save local variable */
1122 int conflict = 0;
1123 for (; lh; lh = lh->prev) { /* check all previous assignments */
1124 if (lh->v.k == VINDEXED) { /* assigning to a table? */
1125 /* table is the upvalue/local being assigned now? */
1126 if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
1127 conflict = 1;
1128 lh->v.u.ind.vt = VLOCAL;
1129 lh->v.u.ind.t = extra; /* previous assignment will use safe copy */
1130 }
1131 /* index is the local being assigned? (index cannot be upvalue) */
1132 if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
1133 conflict = 1;
1134 lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
1135 }
1136 }
1137 }
1138 if (conflict) {
1139 /* copy upvalue/local value to a temporary (in position 'extra') */
1140 OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
1141 luaK_codeABC(fs, op, extra, v->u.info, 0);
1142 luaK_reserveregs(fs, 1);
1143 }
1144}
1145
1146
1147static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
1148 expdesc e;
1149 check_condition(ls, vkisvar(lh->v.k), "syntax error");
1150 if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */
1151 struct LHS_assign nv;
1152 nv.prev = lh;
1153 suffixedexp(ls, &nv.v);
1154 if (nv.v.k != VINDEXED)
1155 check_conflict(ls, lh, &nv.v);
1156 checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS,
1157 "C levels");
1158 assignment(ls, &nv, nvars+1);
1159 }
1160 else { /* assignment -> '=' explist */
1161 int nexps;
1162 checknext(ls, '=');
1163 nexps = explist(ls, &e);
1164 if (nexps != nvars)
1165 adjust_assign(ls, nvars, nexps, &e);
1166 else {
1167 luaK_setoneret(ls->fs, &e); /* close last expression */
1168 luaK_storevar(ls->fs, &lh->v, &e);
1169 return; /* avoid default */
1170 }
1171 }
1172 init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
1173 luaK_storevar(ls->fs, &lh->v, &e);
1174}
1175
1176
1177static int cond (LexState *ls) {
1178 /* cond -> exp */
1179 expdesc v;
1180 expr(ls, &v); /* read condition */
1181 if (v.k == VNIL) v.k = VFALSE; /* 'falses' are all equal here */
1182 luaK_goiftrue(ls->fs, &v);
1183 return v.f;
1184}
1185
1186
1187static void gotostat (LexState *ls, int pc) {
1188 int line = ls->linenumber;
1189 TString *label;
1190 int g;
1191 if (testnext(ls, TK_GOTO))
1192 label = str_checkname(ls);
1193 else {
1194 luaX_next(ls); /* skip break */
1195 label = luaS_new(ls->L, "break");
1196 }
1197 g = newlabelentry(ls, &ls->dyd->gt, label, line, pc);
1198 findlabel(ls, g); /* close it if label already defined */
1199}
1200
1201
1202/* check for repeated labels on the same block */
1203static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
1204 int i;
1205 for (i = fs->bl->firstlabel; i < ll->n; i++) {
1206 if (eqstr(label, ll->arr[i].name)) {
1207 const char *msg = luaO_pushfstring(fs->ls->L,
1208 "label '%s' already defined on line %d",
1209 getstr(label), ll->arr[i].line);
1210 semerror(fs->ls, msg);
1211 }
1212 }
1213}
1214
1215
1216/* skip no-op statements */
1217static void skipnoopstat (LexState *ls) {
1218 while (ls->t.token == ';' || ls->t.token == TK_DBCOLON)
1219 statement(ls);
1220}
1221
1222
1223static void labelstat (LexState *ls, TString *label, int line) {
1224 /* label -> '::' NAME '::' */
1225 FuncState *fs = ls->fs;
1226 Labellist *ll = &ls->dyd->label;
1227 int l; /* index of new label being created */
1228 checkrepeated(fs, ll, label); /* check for repeated labels */
1229 checknext(ls, TK_DBCOLON); /* skip double colon */
1230 /* create new entry for this label */
1231 l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs));
1232 skipnoopstat(ls); /* skip other no-op statements */
1233 if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
1234 /* assume that locals are already out of scope */
1235 ll->arr[l].nactvar = fs->bl->nactvar;
1236 }
1237 findgotos(ls, &ll->arr[l]);
1238}
1239
1240
1241static void whilestat (LexState *ls, int line) {
1242 /* whilestat -> WHILE cond DO block END */
1243 FuncState *fs = ls->fs;
1244 int whileinit;
1245 int condexit;
1246 BlockCnt bl;
1247 luaX_next(ls); /* skip WHILE */
1248 whileinit = luaK_getlabel(fs);
1249 condexit = cond(ls);
1250 enterblock(fs, &bl, 1);
1251 checknext(ls, TK_DO);
1252 block(ls);
1253 luaK_jumpto(fs, whileinit);
1254 check_match(ls, TK_END, TK_WHILE, line);
1255 leaveblock(fs);
1256 luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
1257}
1258
1259
1260static void repeatstat (LexState *ls, int line) {
1261 /* repeatstat -> REPEAT block UNTIL cond */
1262 int condexit;
1263 FuncState *fs = ls->fs;
1264 int repeat_init = luaK_getlabel(fs);
1265 BlockCnt bl1, bl2;
1266 enterblock(fs, &bl1, 1); /* loop block */
1267 enterblock(fs, &bl2, 0); /* scope block */
1268 luaX_next(ls); /* skip REPEAT */
1269 statlist(ls);
1270 check_match(ls, TK_UNTIL, TK_REPEAT, line);
1271 condexit = cond(ls); /* read condition (inside scope block) */
1272 if (bl2.upval) /* upvalues? */
1273 luaK_patchclose(fs, condexit, bl2.nactvar);
1274 leaveblock(fs); /* finish scope */
1275 luaK_patchlist(fs, condexit, repeat_init); /* close the loop */
1276 leaveblock(fs); /* finish loop */
1277}
1278
1279
1280static int exp1 (LexState *ls) {
1281 expdesc e;
1282 int reg;
1283 expr(ls, &e);
1284 luaK_exp2nextreg(ls->fs, &e);
1285 lua_assert(e.k == VNONRELOC);
1286 reg = e.u.info;
1287 return reg;
1288}
1289
1290
1291static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
1292 /* forbody -> DO block */
1293 BlockCnt bl;
1294 FuncState *fs = ls->fs;
1295 int prep, endfor;
1296 adjustlocalvars(ls, 3); /* control variables */
1297 checknext(ls, TK_DO);
1298 prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
1299 enterblock(fs, &bl, 0); /* scope for declared variables */
1300 adjustlocalvars(ls, nvars);
1301 luaK_reserveregs(fs, nvars);
1302 block(ls);
1303 leaveblock(fs); /* end of scope for declared variables */
1304 luaK_patchtohere(fs, prep);
1305 if (isnum) /* numeric for? */
1306 endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP);
1307 else { /* generic for */
1308 luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars);
1309 luaK_fixline(fs, line);
1310 endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP);
1311 }
1312 luaK_patchlist(fs, endfor, prep + 1);
1313 luaK_fixline(fs, line);
1314}
1315
1316
1317static void fornum (LexState *ls, TString *varname, int line) {
1318 /* fornum -> NAME = exp1,exp1[,exp1] forbody */
1319 FuncState *fs = ls->fs;
1320 int base = fs->freereg;
1321 new_localvarliteral(ls, "(for index)");
1322 new_localvarliteral(ls, "(for limit)");
1323 new_localvarliteral(ls, "(for step)");
1324 new_localvar(ls, varname);
1325 checknext(ls, '=');
1326 exp1(ls); /* initial value */
1327 checknext(ls, ',');
1328 exp1(ls); /* limit */
1329 if (testnext(ls, ','))
1330 exp1(ls); /* optional step */
1331 else { /* default step = 1 */
1332 luaK_codek(fs, fs->freereg, luaK_intK(fs, 1));
1333 luaK_reserveregs(fs, 1);
1334 }
1335 forbody(ls, base, line, 1, 1);
1336}
1337
1338
1339static void forlist (LexState *ls, TString *indexname) {
1340 /* forlist -> NAME {,NAME} IN explist forbody */
1341 FuncState *fs = ls->fs;
1342 expdesc e;
1343 int nvars = 4; /* gen, state, control, plus at least one declared var */
1344 int line;
1345 int base = fs->freereg;
1346 /* create control variables */
1347 new_localvarliteral(ls, "(for generator)");
1348 new_localvarliteral(ls, "(for state)");
1349 new_localvarliteral(ls, "(for control)");
1350 /* create declared variables */
1351 new_localvar(ls, indexname);
1352 while (testnext(ls, ',')) {
1353 new_localvar(ls, str_checkname(ls));
1354 nvars++;
1355 }
1356 checknext(ls, TK_IN);
1357 line = ls->linenumber;
1358 adjust_assign(ls, 3, explist(ls, &e), &e);
1359 luaK_checkstack(fs, 3); /* extra space to call generator */
1360 forbody(ls, base, line, nvars - 3, 0);
1361}
1362
1363
1364static void forstat (LexState *ls, int line) {
1365 /* forstat -> FOR (fornum | forlist) END */
1366 FuncState *fs = ls->fs;
1367 TString *varname;
1368 BlockCnt bl;
1369 enterblock(fs, &bl, 1); /* scope for loop and control variables */
1370 luaX_next(ls); /* skip 'for' */
1371 varname = str_checkname(ls); /* first variable name */
1372 switch (ls->t.token) {
1373 case '=': fornum(ls, varname, line); break;
1374 case ',': case TK_IN: forlist(ls, varname); break;
1375 default: luaX_syntaxerror(ls, "'=' or 'in' expected");
1376 }
1377 check_match(ls, TK_END, TK_FOR, line);
1378 leaveblock(fs); /* loop scope ('break' jumps to this point) */
1379}
1380
1381
1382static void test_then_block (LexState *ls, int *escapelist) {
1383 /* test_then_block -> [IF | ELSEIF] cond THEN block */
1384 BlockCnt bl;
1385 FuncState *fs = ls->fs;
1386 expdesc v;
1387 int jf; /* instruction to skip 'then' code (if condition is false) */
1388 luaX_next(ls); /* skip IF or ELSEIF */
1389 expr(ls, &v); /* read condition */
1390 checknext(ls, TK_THEN);
1391 if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
1392 luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */
1393 enterblock(fs, &bl, 0); /* must enter block before 'goto' */
1394 gotostat(ls, v.t); /* handle goto/break */
1395 while (testnext(ls, ';')) {} /* skip colons */
1396 if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
1397 leaveblock(fs);
1398 return; /* and that is it */
1399 }
1400 else /* must skip over 'then' part if condition is false */
1401 jf = luaK_jump(fs);
1402 }
1403 else { /* regular case (not goto/break) */
1404 luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */
1405 enterblock(fs, &bl, 0);
1406 jf = v.f;
1407 }
1408 statlist(ls); /* 'then' part */
1409 leaveblock(fs);
1410 if (ls->t.token == TK_ELSE ||
1411 ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */
1412 luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */
1413 luaK_patchtohere(fs, jf);
1414}
1415
1416
1417static void ifstat (LexState *ls, int line) {
1418 /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
1419 FuncState *fs = ls->fs;
1420 int escapelist = NO_JUMP; /* exit list for finished parts */
1421 test_then_block(ls, &escapelist); /* IF cond THEN block */
1422 while (ls->t.token == TK_ELSEIF)
1423 test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */
1424 if (testnext(ls, TK_ELSE))
1425 block(ls); /* 'else' part */
1426 check_match(ls, TK_END, TK_IF, line);
1427 luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */
1428}
1429
1430
1431static void localfunc (LexState *ls) {
1432 expdesc b;
1433 FuncState *fs = ls->fs;
1434 new_localvar(ls, str_checkname(ls)); /* new local variable */
1435 adjustlocalvars(ls, 1); /* enter its scope */
1436 body(ls, &b, 0, ls->linenumber); /* function created in next register */
1437 /* debug information will only see the variable after this point! */
1438 getlocvar(fs, b.u.info)->startpc = fs->pc;
1439}
1440
1441
1442static void localstat (LexState *ls) {
1443 /* stat -> LOCAL NAME {',' NAME} ['=' explist] */
1444 int nvars = 0;
1445 int nexps;
1446 expdesc e;
1447 do {
1448 new_localvar(ls, str_checkname(ls));
1449 nvars++;
1450 } while (testnext(ls, ','));
1451 if (testnext(ls, '='))
1452 nexps = explist(ls, &e);
1453 else {
1454 e.k = VVOID;
1455 nexps = 0;
1456 }
1457 adjust_assign(ls, nvars, nexps, &e);
1458 adjustlocalvars(ls, nvars);
1459}
1460
1461
1462static int funcname (LexState *ls, expdesc *v) {
1463 /* funcname -> NAME {fieldsel} [':' NAME] */
1464 int ismethod = 0;
1465 singlevar(ls, v);
1466 while (ls->t.token == '.')
1467 fieldsel(ls, v);
1468 if (ls->t.token == ':') {
1469 ismethod = 1;
1470 fieldsel(ls, v);
1471 }
1472 return ismethod;
1473}
1474
1475
1476static void funcstat (LexState *ls, int line) {
1477 /* funcstat -> FUNCTION funcname body */
1478 int ismethod;
1479 expdesc v, b;
1480 luaX_next(ls); /* skip FUNCTION */
1481 ismethod = funcname(ls, &v);
1482 body(ls, &b, ismethod, line);
1483 luaK_storevar(ls->fs, &v, &b);
1484 luaK_fixline(ls->fs, line); /* definition "happens" in the first line */
1485}
1486
1487
1488static void exprstat (LexState *ls) {
1489 /* stat -> func | assignment */
1490 FuncState *fs = ls->fs;
1491 struct LHS_assign v;
1492 suffixedexp(ls, &v.v);
1493 if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */
1494 v.prev = NULL;
1495 assignment(ls, &v, 1);
1496 }
1497 else { /* stat -> func */
1498 check_condition(ls, v.v.k == VCALL, "syntax error");
1499 SETARG_C(getinstruction(fs, &v.v), 1); /* call statement uses no results */
1500 }
1501}
1502
1503
1504static void retstat (LexState *ls) {
1505 /* stat -> RETURN [explist] [';'] */
1506 FuncState *fs = ls->fs;
1507 expdesc e;
1508 int first, nret; /* registers with returned values */
1509 if (block_follow(ls, 1) || ls->t.token == ';')
1510 first = nret = 0; /* return no values */
1511 else {
1512 nret = explist(ls, &e); /* optional return values */
1513 if (hasmultret(e.k)) {
1514 luaK_setmultret(fs, &e);
1515 if (e.k == VCALL && nret == 1) { /* tail call? */
1516 SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL);
1517 lua_assert(GETARG_A(getinstruction(fs,&e)) == fs->nactvar);
1518 }
1519 first = fs->nactvar;
1520 nret = LUA_MULTRET; /* return all values */
1521 }
1522 else {
1523 if (nret == 1) /* only one single value? */
1524 first = luaK_exp2anyreg(fs, &e);
1525 else {
1526 luaK_exp2nextreg(fs, &e); /* values must go to the stack */
1527 first = fs->nactvar; /* return all active values */
1528 lua_assert(nret == fs->freereg - first);
1529 }
1530 }
1531 }
1532 luaK_ret(fs, first, nret);
1533 testnext(ls, ';'); /* skip optional semicolon */
1534}
1535
1536
1537static void statement (LexState *ls) {
1538 int line = ls->linenumber; /* may be needed for error messages */
1539 enterlevel(ls);
1540 switch (ls->t.token) {
1541 case ';': { /* stat -> ';' (empty statement) */
1542 luaX_next(ls); /* skip ';' */
1543 break;
1544 }
1545 case TK_IF: { /* stat -> ifstat */
1546 ifstat(ls, line);
1547 break;
1548 }
1549 case TK_WHILE: { /* stat -> whilestat */
1550 whilestat(ls, line);
1551 break;
1552 }
1553 case TK_DO: { /* stat -> DO block END */
1554 luaX_next(ls); /* skip DO */
1555 block(ls);
1556 check_match(ls, TK_END, TK_DO, line);
1557 break;
1558 }
1559 case TK_FOR: { /* stat -> forstat */
1560 forstat(ls, line);
1561 break;
1562 }
1563 case TK_REPEAT: { /* stat -> repeatstat */
1564 repeatstat(ls, line);
1565 break;
1566 }
1567 case TK_FUNCTION: { /* stat -> funcstat */
1568 funcstat(ls, line);
1569 break;
1570 }
1571 case TK_LOCAL: { /* stat -> localstat */
1572 luaX_next(ls); /* skip LOCAL */
1573 if (testnext(ls, TK_FUNCTION)) /* local function? */
1574 localfunc(ls);
1575 else
1576 localstat(ls);
1577 break;
1578 }
1579 case TK_DBCOLON: { /* stat -> label */
1580 luaX_next(ls); /* skip double colon */
1581 labelstat(ls, str_checkname(ls), line);
1582 break;
1583 }
1584 case TK_RETURN: { /* stat -> retstat */
1585 luaX_next(ls); /* skip RETURN */
1586 retstat(ls);
1587 break;
1588 }
1589 case TK_BREAK: /* stat -> breakstat */
1590 case TK_GOTO: { /* stat -> 'goto' NAME */
1591 gotostat(ls, luaK_jump(ls->fs));
1592 break;
1593 }
1594 default: { /* stat -> func | assignment */
1595 exprstat(ls);
1596 break;
1597 }
1598 }
1599 lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
1600 ls->fs->freereg >= ls->fs->nactvar);
1601 ls->fs->freereg = ls->fs->nactvar; /* free registers */
1602 leavelevel(ls);
1603}
1604
1605/* }====================================================================== */
1606
1607
1608/*
1609** compiles the main function, which is a regular vararg function with an
1610** upvalue named LUA_ENV
1611*/
1612static void mainfunc (LexState *ls, FuncState *fs) {
1613 BlockCnt bl;
1614 expdesc v;
1615 open_func(ls, fs, &bl);
1616 fs->f->is_vararg = 1; /* main function is always declared vararg */
1617 init_exp(&v, VLOCAL, 0); /* create and... */
1618 newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */
1619 luaX_next(ls); /* read first token */
1620 statlist(ls); /* parse main body */
1621 check(ls, TK_EOS);
1622 close_func(ls);
1623}
1624
1625
1626LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
1627 Dyndata *dyd, const char *name, int firstchar) {
1628 LexState lexstate;
1629 FuncState funcstate;
1630 LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */
1631 setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */
1632 luaD_inctop(L);
1633 lexstate.h = luaH_new(L); /* create table for scanner */
1634 sethvalue(L, L->top, lexstate.h); /* anchor it */
1635 luaD_inctop(L);
1636 funcstate.f = cl->p = luaF_newproto(L);
1637 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
1638 lua_assert(iswhite(funcstate.f)); /* do not need barrier here */
1639 lexstate.buff = buff;
1640 lexstate.dyd = dyd;
1641 dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
1642 luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
1643 mainfunc(&lexstate, &funcstate);
1644 lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
1645 /* all scopes should be correctly finished */
1646 lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
1647 L->top--; /* remove scanner's table */
1648 return cl; /* closure is on the stack, too */
1649}
1650
diff --git a/src/lua-5.3/lparser.h b/src/lua-5.3/lparser.h
new file mode 100644
index 0000000..f45b23c
--- /dev/null
+++ b/src/lua-5.3/lparser.h
@@ -0,0 +1,133 @@
1/*
2** $Id: lparser.h,v 1.76.1.1 2017/04/19 17:20:42 roberto Exp $
3** Lua Parser
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lparser_h
8#define lparser_h
9
10#include "llimits.h"
11#include "lobject.h"
12#include "lzio.h"
13
14
15/*
16** Expression and variable descriptor.
17** Code generation for variables and expressions can be delayed to allow
18** optimizations; An 'expdesc' structure describes a potentially-delayed
19** variable/expression. It has a description of its "main" value plus a
20** list of conditional jumps that can also produce its value (generated
21** by short-circuit operators 'and'/'or').
22*/
23
24/* kinds of variables/expressions */
25typedef enum {
26 VVOID, /* when 'expdesc' describes the last expression a list,
27 this kind means an empty list (so, no expression) */
28 VNIL, /* constant nil */
29 VTRUE, /* constant true */
30 VFALSE, /* constant false */
31 VK, /* constant in 'k'; info = index of constant in 'k' */
32 VKFLT, /* floating constant; nval = numerical float value */
33 VKINT, /* integer constant; nval = numerical integer value */
34 VNONRELOC, /* expression has its value in a fixed register;
35 info = result register */
36 VLOCAL, /* local variable; info = local register */
37 VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
38 VINDEXED, /* indexed variable;
39 ind.vt = whether 't' is register or upvalue;
40 ind.t = table register or upvalue;
41 ind.idx = key's R/K index */
42 VJMP, /* expression is a test/comparison;
43 info = pc of corresponding jump instruction */
44 VRELOCABLE, /* expression can put result in any register;
45 info = instruction pc */
46 VCALL, /* expression is a function call; info = instruction pc */
47 VVARARG /* vararg expression; info = instruction pc */
48} expkind;
49
50
51#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED)
52#define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL)
53
54typedef struct expdesc {
55 expkind k;
56 union {
57 lua_Integer ival; /* for VKINT */
58 lua_Number nval; /* for VKFLT */
59 int info; /* for generic use */
60 struct { /* for indexed variables (VINDEXED) */
61 short idx; /* index (R/K) */
62 lu_byte t; /* table (register or upvalue) */
63 lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
64 } ind;
65 } u;
66 int t; /* patch list of 'exit when true' */
67 int f; /* patch list of 'exit when false' */
68} expdesc;
69
70
71/* description of active local variable */
72typedef struct Vardesc {
73 short idx; /* variable index in stack */
74} Vardesc;
75
76
77/* description of pending goto statements and label statements */
78typedef struct Labeldesc {
79 TString *name; /* label identifier */
80 int pc; /* position in code */
81 int line; /* line where it appeared */
82 lu_byte nactvar; /* local level where it appears in current block */
83} Labeldesc;
84
85
86/* list of labels or gotos */
87typedef struct Labellist {
88 Labeldesc *arr; /* array */
89 int n; /* number of entries in use */
90 int size; /* array size */
91} Labellist;
92
93
94/* dynamic structures used by the parser */
95typedef struct Dyndata {
96 struct { /* list of active local variables */
97 Vardesc *arr;
98 int n;
99 int size;
100 } actvar;
101 Labellist gt; /* list of pending gotos */
102 Labellist label; /* list of active labels */
103} Dyndata;
104
105
106/* control of blocks */
107struct BlockCnt; /* defined in lparser.c */
108
109
110/* state needed to generate code for a given function */
111typedef struct FuncState {
112 Proto *f; /* current function header */
113 struct FuncState *prev; /* enclosing function */
114 struct LexState *ls; /* lexical state */
115 struct BlockCnt *bl; /* chain of current blocks */
116 int pc; /* next position to code (equivalent to 'ncode') */
117 int lasttarget; /* 'label' of last 'jump label' */
118 int jpc; /* list of pending jumps to 'pc' */
119 int nk; /* number of elements in 'k' */
120 int np; /* number of elements in 'p' */
121 int firstlocal; /* index of first local var (in Dyndata array) */
122 short nlocvars; /* number of elements in 'f->locvars' */
123 lu_byte nactvar; /* number of active local variables */
124 lu_byte nups; /* number of upvalues */
125 lu_byte freereg; /* first free register */
126} FuncState;
127
128
129LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
130 Dyndata *dyd, const char *name, int firstchar);
131
132
133#endif
diff --git a/src/lua-5.3/lprefix.h b/src/lua-5.3/lprefix.h
new file mode 100644
index 0000000..9a749a3
--- /dev/null
+++ b/src/lua-5.3/lprefix.h
@@ -0,0 +1,45 @@
1/*
2** $Id: lprefix.h,v 1.2.1.1 2017/04/19 17:20:42 roberto Exp $
3** Definitions for Lua code that must come before any other header file
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lprefix_h
8#define lprefix_h
9
10
11/*
12** Allows POSIX/XSI stuff
13*/
14#if !defined(LUA_USE_C89) /* { */
15
16#if !defined(_XOPEN_SOURCE)
17#define _XOPEN_SOURCE 600
18#elif _XOPEN_SOURCE == 0
19#undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */
20#endif
21
22/*
23** Allows manipulation of large files in gcc and some other compilers
24*/
25#if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS)
26#define _LARGEFILE_SOURCE 1
27#define _FILE_OFFSET_BITS 64
28#endif
29
30#endif /* } */
31
32
33/*
34** Windows stuff
35*/
36#if defined(_WIN32) /* { */
37
38#if !defined(_CRT_SECURE_NO_WARNINGS)
39#define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */
40#endif
41
42#endif /* } */
43
44#endif
45
diff --git a/src/lua-5.3/lstate.c b/src/lua-5.3/lstate.c
new file mode 100644
index 0000000..c1a7664
--- /dev/null
+++ b/src/lua-5.3/lstate.c
@@ -0,0 +1,347 @@
1/*
2** $Id: lstate.c,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $
3** Global State
4** See Copyright Notice in lua.h
5*/
6
7#define lstate_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <stddef.h>
14#include <string.h>
15
16#include "lua.h"
17
18#include "lapi.h"
19#include "ldebug.h"
20#include "ldo.h"
21#include "lfunc.h"
22#include "lgc.h"
23#include "llex.h"
24#include "lmem.h"
25#include "lstate.h"
26#include "lstring.h"
27#include "ltable.h"
28#include "ltm.h"
29
30
31#if !defined(LUAI_GCPAUSE)
32#define LUAI_GCPAUSE 200 /* 200% */
33#endif
34
35#if !defined(LUAI_GCMUL)
36#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
37#endif
38
39
40/*
41** a macro to help the creation of a unique random seed when a state is
42** created; the seed is used to randomize hashes.
43*/
44#if !defined(luai_makeseed)
45#include <time.h>
46#define luai_makeseed() cast(unsigned int, time(NULL))
47#endif
48
49
50
51/*
52** thread state + extra space
53*/
54typedef struct LX {
55 lu_byte extra_[LUA_EXTRASPACE];
56 lua_State l;
57} LX;
58
59
60/*
61** Main thread combines a thread state and the global state
62*/
63typedef struct LG {
64 LX l;
65 global_State g;
66} LG;
67
68
69
70#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
71
72
73/*
74** Compute an initial seed as random as possible. Rely on Address Space
75** Layout Randomization (if present) to increase randomness..
76*/
77#define addbuff(b,p,e) \
78 { size_t t = cast(size_t, e); \
79 memcpy(b + p, &t, sizeof(t)); p += sizeof(t); }
80
81static unsigned int makeseed (lua_State *L) {
82 char buff[4 * sizeof(size_t)];
83 unsigned int h = luai_makeseed();
84 int p = 0;
85 addbuff(buff, p, L); /* heap variable */
86 addbuff(buff, p, &h); /* local variable */
87 addbuff(buff, p, luaO_nilobject); /* global variable */
88 addbuff(buff, p, &lua_newstate); /* public function */
89 lua_assert(p == sizeof(buff));
90 return luaS_hash(buff, p, h);
91}
92
93
94/*
95** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
96** invariant (and avoiding underflows in 'totalbytes')
97*/
98void luaE_setdebt (global_State *g, l_mem debt) {
99 l_mem tb = gettotalbytes(g);
100 lua_assert(tb > 0);
101 if (debt < tb - MAX_LMEM)
102 debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */
103 g->totalbytes = tb - debt;
104 g->GCdebt = debt;
105}
106
107
108CallInfo *luaE_extendCI (lua_State *L) {
109 CallInfo *ci = luaM_new(L, CallInfo);
110 lua_assert(L->ci->next == NULL);
111 L->ci->next = ci;
112 ci->previous = L->ci;
113 ci->next = NULL;
114 L->nci++;
115 return ci;
116}
117
118
119/*
120** free all CallInfo structures not in use by a thread
121*/
122void luaE_freeCI (lua_State *L) {
123 CallInfo *ci = L->ci;
124 CallInfo *next = ci->next;
125 ci->next = NULL;
126 while ((ci = next) != NULL) {
127 next = ci->next;
128 luaM_free(L, ci);
129 L->nci--;
130 }
131}
132
133
134/*
135** free half of the CallInfo structures not in use by a thread
136*/
137void luaE_shrinkCI (lua_State *L) {
138 CallInfo *ci = L->ci;
139 CallInfo *next2; /* next's next */
140 /* while there are two nexts */
141 while (ci->next != NULL && (next2 = ci->next->next) != NULL) {
142 luaM_free(L, ci->next); /* free next */
143 L->nci--;
144 ci->next = next2; /* remove 'next' from the list */
145 next2->previous = ci;
146 ci = next2; /* keep next's next */
147 }
148}
149
150
151static void stack_init (lua_State *L1, lua_State *L) {
152 int i; CallInfo *ci;
153 /* initialize stack array */
154 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
155 L1->stacksize = BASIC_STACK_SIZE;
156 for (i = 0; i < BASIC_STACK_SIZE; i++)
157 setnilvalue(L1->stack + i); /* erase new stack */
158 L1->top = L1->stack;
159 L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
160 /* initialize first ci */
161 ci = &L1->base_ci;
162 ci->next = ci->previous = NULL;
163 ci->callstatus = 0;
164 ci->func = L1->top;
165 setnilvalue(L1->top++); /* 'function' entry for this 'ci' */
166 ci->top = L1->top + LUA_MINSTACK;
167 L1->ci = ci;
168}
169
170
171static void freestack (lua_State *L) {
172 if (L->stack == NULL)
173 return; /* stack not completely built yet */
174 L->ci = &L->base_ci; /* free the entire 'ci' list */
175 luaE_freeCI(L);
176 lua_assert(L->nci == 0);
177 luaM_freearray(L, L->stack, L->stacksize); /* free stack array */
178}
179
180
181/*
182** Create registry table and its predefined values
183*/
184static void init_registry (lua_State *L, global_State *g) {
185 TValue temp;
186 /* create registry */
187 Table *registry = luaH_new(L);
188 sethvalue(L, &g->l_registry, registry);
189 luaH_resize(L, registry, LUA_RIDX_LAST, 0);
190 /* registry[LUA_RIDX_MAINTHREAD] = L */
191 setthvalue(L, &temp, L); /* temp = L */
192 luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp);
193 /* registry[LUA_RIDX_GLOBALS] = table of globals */
194 sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */
195 luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp);
196}
197
198
199/*
200** open parts of the state that may cause memory-allocation errors.
201** ('g->version' != NULL flags that the state was completely build)
202*/
203static void f_luaopen (lua_State *L, void *ud) {
204 global_State *g = G(L);
205 UNUSED(ud);
206 stack_init(L, L); /* init stack */
207 init_registry(L, g);
208 luaS_init(L);
209 luaT_init(L);
210 luaX_init(L);
211 g->gcrunning = 1; /* allow gc */
212 g->version = lua_version(NULL);
213 luai_userstateopen(L);
214}
215
216
217/*
218** preinitialize a thread with consistent values without allocating
219** any memory (to avoid errors)
220*/
221static void preinit_thread (lua_State *L, global_State *g) {
222 G(L) = g;
223 L->stack = NULL;
224 L->ci = NULL;
225 L->nci = 0;
226 L->stacksize = 0;
227 L->twups = L; /* thread has no upvalues */
228 L->errorJmp = NULL;
229 L->nCcalls = 0;
230 L->hook = NULL;
231 L->hookmask = 0;
232 L->basehookcount = 0;
233 L->allowhook = 1;
234 resethookcount(L);
235 L->openupval = NULL;
236 L->nny = 1;
237 L->status = LUA_OK;
238 L->errfunc = 0;
239}
240
241
242static void close_state (lua_State *L) {
243 global_State *g = G(L);
244 luaF_close(L, L->stack); /* close all upvalues for this thread */
245 luaC_freeallobjects(L); /* collect all objects */
246 if (g->version) /* closing a fully built state? */
247 luai_userstateclose(L);
248 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
249 freestack(L);
250 lua_assert(gettotalbytes(g) == sizeof(LG));
251 (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
252}
253
254
255LUA_API lua_State *lua_newthread (lua_State *L) {
256 global_State *g = G(L);
257 lua_State *L1;
258 lua_lock(L);
259 luaC_checkGC(L);
260 /* create new thread */
261 L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l;
262 L1->marked = luaC_white(g);
263 L1->tt = LUA_TTHREAD;
264 /* link it on list 'allgc' */
265 L1->next = g->allgc;
266 g->allgc = obj2gco(L1);
267 /* anchor it on L stack */
268 setthvalue(L, L->top, L1);
269 api_incr_top(L);
270 preinit_thread(L1, g);
271 L1->hookmask = L->hookmask;
272 L1->basehookcount = L->basehookcount;
273 L1->hook = L->hook;
274 resethookcount(L1);
275 /* initialize L1 extra space */
276 memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread),
277 LUA_EXTRASPACE);
278 luai_userstatethread(L, L1);
279 stack_init(L1, L); /* init stack */
280 lua_unlock(L);
281 return L1;
282}
283
284
285void luaE_freethread (lua_State *L, lua_State *L1) {
286 LX *l = fromstate(L1);
287 luaF_close(L1, L1->stack); /* close all upvalues for this thread */
288 lua_assert(L1->openupval == NULL);
289 luai_userstatefree(L, L1);
290 freestack(L1);
291 luaM_free(L, l);
292}
293
294
295LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
296 int i;
297 lua_State *L;
298 global_State *g;
299 LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
300 if (l == NULL) return NULL;
301 L = &l->l.l;
302 g = &l->g;
303 L->next = NULL;
304 L->tt = LUA_TTHREAD;
305 g->currentwhite = bitmask(WHITE0BIT);
306 L->marked = luaC_white(g);
307 preinit_thread(L, g);
308 g->frealloc = f;
309 g->ud = ud;
310 g->mainthread = L;
311 g->seed = makeseed(L);
312 g->gcrunning = 0; /* no GC while building state */
313 g->GCestimate = 0;
314 g->strt.size = g->strt.nuse = 0;
315 g->strt.hash = NULL;
316 setnilvalue(&g->l_registry);
317 g->panic = NULL;
318 g->version = NULL;
319 g->gcstate = GCSpause;
320 g->gckind = KGC_NORMAL;
321 g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL;
322 g->sweepgc = NULL;
323 g->gray = g->grayagain = NULL;
324 g->weak = g->ephemeron = g->allweak = NULL;
325 g->twups = NULL;
326 g->totalbytes = sizeof(LG);
327 g->GCdebt = 0;
328 g->gcfinnum = 0;
329 g->gcpause = LUAI_GCPAUSE;
330 g->gcstepmul = LUAI_GCMUL;
331 for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
332 if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
333 /* memory allocation error: free partial state */
334 close_state(L);
335 L = NULL;
336 }
337 return L;
338}
339
340
341LUA_API void lua_close (lua_State *L) {
342 L = G(L)->mainthread; /* only the main thread can be closed */
343 lua_lock(L);
344 close_state(L);
345}
346
347
diff --git a/src/lua-5.3/lstate.h b/src/lua-5.3/lstate.h
new file mode 100644
index 0000000..56b3741
--- /dev/null
+++ b/src/lua-5.3/lstate.h
@@ -0,0 +1,253 @@
1/*
2** $Id: lstate.h,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $
3** Global State
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lstate_h
8#define lstate_h
9
10#include "lua.h"
11
12#include "lobject.h"
13#include "ltm.h"
14#include "lzio.h"
15
16
17/*
18
19** Some notes about garbage-collected objects: All objects in Lua must
20** be kept somehow accessible until being freed, so all objects always
21** belong to one (and only one) of these lists, using field 'next' of
22** the 'CommonHeader' for the link:
23**
24** 'allgc': all objects not marked for finalization;
25** 'finobj': all objects marked for finalization;
26** 'tobefnz': all objects ready to be finalized;
27** 'fixedgc': all objects that are not to be collected (currently
28** only small strings, such as reserved words).
29**
30** Moreover, there is another set of lists that control gray objects.
31** These lists are linked by fields 'gclist'. (All objects that
32** can become gray have such a field. The field is not the same
33** in all objects, but it always has this name.) Any gray object
34** must belong to one of these lists, and all objects in these lists
35** must be gray:
36**
37** 'gray': regular gray objects, still waiting to be visited.
38** 'grayagain': objects that must be revisited at the atomic phase.
39** That includes
40** - black objects got in a write barrier;
41** - all kinds of weak tables during propagation phase;
42** - all threads.
43** 'weak': tables with weak values to be cleared;
44** 'ephemeron': ephemeron tables with white->white entries;
45** 'allweak': tables with weak keys and/or weak values to be cleared.
46** The last three lists are used only during the atomic phase.
47
48*/
49
50
51struct lua_longjmp; /* defined in ldo.c */
52
53
54/*
55** Atomic type (relative to signals) to better ensure that 'lua_sethook'
56** is thread safe
57*/
58#if !defined(l_signalT)
59#include <signal.h>
60#define l_signalT sig_atomic_t
61#endif
62
63
64/* extra stack space to handle TM calls and some other extras */
65#define EXTRA_STACK 5
66
67
68#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
69
70
71/* kinds of Garbage Collection */
72#define KGC_NORMAL 0
73#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */
74
75
76typedef struct stringtable {
77 TString **hash;
78 int nuse; /* number of elements */
79 int size;
80} stringtable;
81
82
83/*
84** Information about a call.
85** When a thread yields, 'func' is adjusted to pretend that the
86** top function has only the yielded values in its stack; in that
87** case, the actual 'func' value is saved in field 'extra'.
88** When a function calls another with a continuation, 'extra' keeps
89** the function index so that, in case of errors, the continuation
90** function can be called with the correct top.
91*/
92typedef struct CallInfo {
93 StkId func; /* function index in the stack */
94 StkId top; /* top for this function */
95 struct CallInfo *previous, *next; /* dynamic call link */
96 union {
97 struct { /* only for Lua functions */
98 StkId base; /* base for this function */
99 const Instruction *savedpc;
100 } l;
101 struct { /* only for C functions */
102 lua_KFunction k; /* continuation in case of yields */
103 ptrdiff_t old_errfunc;
104 lua_KContext ctx; /* context info. in case of yields */
105 } c;
106 } u;
107 ptrdiff_t extra;
108 short nresults; /* expected number of results from this function */
109 unsigned short callstatus;
110} CallInfo;
111
112
113/*
114** Bits in CallInfo status
115*/
116#define CIST_OAH (1<<0) /* original value of 'allowhook' */
117#define CIST_LUA (1<<1) /* call is running a Lua function */
118#define CIST_HOOKED (1<<2) /* call is running a debug hook */
119#define CIST_FRESH (1<<3) /* call is running on a fresh invocation
120 of luaV_execute */
121#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */
122#define CIST_TAIL (1<<5) /* call was tail called */
123#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
124#define CIST_LEQ (1<<7) /* using __lt for __le */
125#define CIST_FIN (1<<8) /* call is running a finalizer */
126
127#define isLua(ci) ((ci)->callstatus & CIST_LUA)
128
129/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */
130#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v))
131#define getoah(st) ((st) & CIST_OAH)
132
133
134/*
135** 'global state', shared by all threads of this state
136*/
137typedef struct global_State {
138 lua_Alloc frealloc; /* function to reallocate memory */
139 void *ud; /* auxiliary data to 'frealloc' */
140 l_mem totalbytes; /* number of bytes currently allocated - GCdebt */
141 l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
142 lu_mem GCmemtrav; /* memory traversed by the GC */
143 lu_mem GCestimate; /* an estimate of the non-garbage memory in use */
144 stringtable strt; /* hash table for strings */
145 TValue l_registry;
146 unsigned int seed; /* randomized seed for hashes */
147 lu_byte currentwhite;
148 lu_byte gcstate; /* state of garbage collector */
149 lu_byte gckind; /* kind of GC running */
150 lu_byte gcrunning; /* true if GC is running */
151 GCObject *allgc; /* list of all collectable objects */
152 GCObject **sweepgc; /* current position of sweep in list */
153 GCObject *finobj; /* list of collectable objects with finalizers */
154 GCObject *gray; /* list of gray objects */
155 GCObject *grayagain; /* list of objects to be traversed atomically */
156 GCObject *weak; /* list of tables with weak values */
157 GCObject *ephemeron; /* list of ephemeron tables (weak keys) */
158 GCObject *allweak; /* list of all-weak tables */
159 GCObject *tobefnz; /* list of userdata to be GC */
160 GCObject *fixedgc; /* list of objects not to be collected */
161 struct lua_State *twups; /* list of threads with open upvalues */
162 unsigned int gcfinnum; /* number of finalizers to call in each GC step */
163 int gcpause; /* size of pause between successive GCs */
164 int gcstepmul; /* GC 'granularity' */
165 lua_CFunction panic; /* to be called in unprotected errors */
166 struct lua_State *mainthread;
167 const lua_Number *version; /* pointer to version number */
168 TString *memerrmsg; /* memory-error message */
169 TString *tmname[TM_N]; /* array with tag-method names */
170 struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
171 TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */
172} global_State;
173
174
175/*
176** 'per thread' state
177*/
178struct lua_State {
179 CommonHeader;
180 unsigned short nci; /* number of items in 'ci' list */
181 lu_byte status;
182 StkId top; /* first free slot in the stack */
183 global_State *l_G;
184 CallInfo *ci; /* call info for current function */
185 const Instruction *oldpc; /* last pc traced */
186 StkId stack_last; /* last free slot in the stack */
187 StkId stack; /* stack base */
188 UpVal *openupval; /* list of open upvalues in this stack */
189 GCObject *gclist;
190 struct lua_State *twups; /* list of threads with open upvalues */
191 struct lua_longjmp *errorJmp; /* current error recover point */
192 CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
193 volatile lua_Hook hook;
194 ptrdiff_t errfunc; /* current error handling function (stack index) */
195 int stacksize;
196 int basehookcount;
197 int hookcount;
198 unsigned short nny; /* number of non-yieldable calls in stack */
199 unsigned short nCcalls; /* number of nested C calls */
200 l_signalT hookmask;
201 lu_byte allowhook;
202};
203
204
205#define G(L) (L->l_G)
206
207
208/*
209** Union of all collectable objects (only for conversions)
210*/
211union GCUnion {
212 GCObject gc; /* common header */
213 struct TString ts;
214 struct Udata u;
215 union Closure cl;
216 struct Table h;
217 struct Proto p;
218 struct lua_State th; /* thread */
219};
220
221
222#define cast_u(o) cast(union GCUnion *, (o))
223
224/* macros to convert a GCObject into a specific value */
225#define gco2ts(o) \
226 check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts))
227#define gco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u))
228#define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l))
229#define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c))
230#define gco2cl(o) \
231 check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl))
232#define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h))
233#define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p))
234#define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th))
235
236
237/* macro to convert a Lua object into a GCObject */
238#define obj2gco(v) \
239 check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc)))
240
241
242/* actual number of total bytes allocated */
243#define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt)
244
245LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
246LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
247LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
248LUAI_FUNC void luaE_freeCI (lua_State *L);
249LUAI_FUNC void luaE_shrinkCI (lua_State *L);
250
251
252#endif
253
diff --git a/src/lua-5.3/lstring.c b/src/lua-5.3/lstring.c
new file mode 100644
index 0000000..6257f21
--- /dev/null
+++ b/src/lua-5.3/lstring.c
@@ -0,0 +1,248 @@
1/*
2** $Id: lstring.c,v 2.56.1.1 2017/04/19 17:20:42 roberto Exp $
3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h
5*/
6
7#define lstring_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <string.h>
14
15#include "lua.h"
16
17#include "ldebug.h"
18#include "ldo.h"
19#include "lmem.h"
20#include "lobject.h"
21#include "lstate.h"
22#include "lstring.h"
23
24
25#define MEMERRMSG "not enough memory"
26
27
28/*
29** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
30** compute its hash
31*/
32#if !defined(LUAI_HASHLIMIT)
33#define LUAI_HASHLIMIT 5
34#endif
35
36
37/*
38** equality for long strings
39*/
40int luaS_eqlngstr (TString *a, TString *b) {
41 size_t len = a->u.lnglen;
42 lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
43 return (a == b) || /* same instance or... */
44 ((len == b->u.lnglen) && /* equal length and ... */
45 (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
46}
47
48
49unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) {
50 unsigned int h = seed ^ cast(unsigned int, l);
51 size_t step = (l >> LUAI_HASHLIMIT) + 1;
52 for (; l >= step; l -= step)
53 h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1]));
54 return h;
55}
56
57
58unsigned int luaS_hashlongstr (TString *ts) {
59 lua_assert(ts->tt == LUA_TLNGSTR);
60 if (ts->extra == 0) { /* no hash? */
61 ts->hash = luaS_hash(getstr(ts), ts->u.lnglen, ts->hash);
62 ts->extra = 1; /* now it has its hash */
63 }
64 return ts->hash;
65}
66
67
68/*
69** resizes the string table
70*/
71void luaS_resize (lua_State *L, int newsize) {
72 int i;
73 stringtable *tb = &G(L)->strt;
74 if (newsize > tb->size) { /* grow table if needed */
75 luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
76 for (i = tb->size; i < newsize; i++)
77 tb->hash[i] = NULL;
78 }
79 for (i = 0; i < tb->size; i++) { /* rehash */
80 TString *p = tb->hash[i];
81 tb->hash[i] = NULL;
82 while (p) { /* for each node in the list */
83 TString *hnext = p->u.hnext; /* save next */
84 unsigned int h = lmod(p->hash, newsize); /* new position */
85 p->u.hnext = tb->hash[h]; /* chain it */
86 tb->hash[h] = p;
87 p = hnext;
88 }
89 }
90 if (newsize < tb->size) { /* shrink table if needed */
91 /* vanishing slice should be empty */
92 lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
93 luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
94 }
95 tb->size = newsize;
96}
97
98
99/*
100** Clear API string cache. (Entries cannot be empty, so fill them with
101** a non-collectable string.)
102*/
103void luaS_clearcache (global_State *g) {
104 int i, j;
105 for (i = 0; i < STRCACHE_N; i++)
106 for (j = 0; j < STRCACHE_M; j++) {
107 if (iswhite(g->strcache[i][j])) /* will entry be collected? */
108 g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */
109 }
110}
111
112
113/*
114** Initialize the string table and the string cache
115*/
116void luaS_init (lua_State *L) {
117 global_State *g = G(L);
118 int i, j;
119 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
120 /* pre-create memory-error message */
121 g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
122 luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */
123 for (i = 0; i < STRCACHE_N; i++) /* fill cache with valid strings */
124 for (j = 0; j < STRCACHE_M; j++)
125 g->strcache[i][j] = g->memerrmsg;
126}
127
128
129
130/*
131** creates a new string object
132*/
133static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) {
134 TString *ts;
135 GCObject *o;
136 size_t totalsize; /* total size of TString object */
137 totalsize = sizelstring(l);
138 o = luaC_newobj(L, tag, totalsize);
139 ts = gco2ts(o);
140 ts->hash = h;
141 ts->extra = 0;
142 getstr(ts)[l] = '\0'; /* ending 0 */
143 return ts;
144}
145
146
147TString *luaS_createlngstrobj (lua_State *L, size_t l) {
148 TString *ts = createstrobj(L, l, LUA_TLNGSTR, G(L)->seed);
149 ts->u.lnglen = l;
150 return ts;
151}
152
153
154void luaS_remove (lua_State *L, TString *ts) {
155 stringtable *tb = &G(L)->strt;
156 TString **p = &tb->hash[lmod(ts->hash, tb->size)];
157 while (*p != ts) /* find previous element */
158 p = &(*p)->u.hnext;
159 *p = (*p)->u.hnext; /* remove element from its list */
160 tb->nuse--;
161}
162
163
164/*
165** checks whether short string exists and reuses it or creates a new one
166*/
167static TString *internshrstr (lua_State *L, const char *str, size_t l) {
168 TString *ts;
169 global_State *g = G(L);
170 unsigned int h = luaS_hash(str, l, g->seed);
171 TString **list = &g->strt.hash[lmod(h, g->strt.size)];
172 lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */
173 for (ts = *list; ts != NULL; ts = ts->u.hnext) {
174 if (l == ts->shrlen &&
175 (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
176 /* found! */
177 if (isdead(g, ts)) /* dead (but not collected yet)? */
178 changewhite(ts); /* resurrect it */
179 return ts;
180 }
181 }
182 if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT/2) {
183 luaS_resize(L, g->strt.size * 2);
184 list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
185 }
186 ts = createstrobj(L, l, LUA_TSHRSTR, h);
187 memcpy(getstr(ts), str, l * sizeof(char));
188 ts->shrlen = cast_byte(l);
189 ts->u.hnext = *list;
190 *list = ts;
191 g->strt.nuse++;
192 return ts;
193}
194
195
196/*
197** new string (with explicit length)
198*/
199TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
200 if (l <= LUAI_MAXSHORTLEN) /* short string? */
201 return internshrstr(L, str, l);
202 else {
203 TString *ts;
204 if (l >= (MAX_SIZE - sizeof(TString))/sizeof(char))
205 luaM_toobig(L);
206 ts = luaS_createlngstrobj(L, l);
207 memcpy(getstr(ts), str, l * sizeof(char));
208 return ts;
209 }
210}
211
212
213/*
214** Create or reuse a zero-terminated string, first checking in the
215** cache (using the string address as a key). The cache can contain
216** only zero-terminated strings, so it is safe to use 'strcmp' to
217** check hits.
218*/
219TString *luaS_new (lua_State *L, const char *str) {
220 unsigned int i = point2uint(str) % STRCACHE_N; /* hash */
221 int j;
222 TString **p = G(L)->strcache[i];
223 for (j = 0; j < STRCACHE_M; j++) {
224 if (strcmp(str, getstr(p[j])) == 0) /* hit? */
225 return p[j]; /* that is it */
226 }
227 /* normal route */
228 for (j = STRCACHE_M - 1; j > 0; j--)
229 p[j] = p[j - 1]; /* move out last element */
230 /* new element is first in the list */
231 p[0] = luaS_newlstr(L, str, strlen(str));
232 return p[0];
233}
234
235
236Udata *luaS_newudata (lua_State *L, size_t s) {
237 Udata *u;
238 GCObject *o;
239 if (s > MAX_SIZE - sizeof(Udata))
240 luaM_toobig(L);
241 o = luaC_newobj(L, LUA_TUSERDATA, sizeludata(s));
242 u = gco2u(o);
243 u->len = s;
244 u->metatable = NULL;
245 setuservalue(L, u, luaO_nilobject);
246 return u;
247}
248
diff --git a/src/lua-5.3/lstring.h b/src/lua-5.3/lstring.h
new file mode 100644
index 0000000..d612abd
--- /dev/null
+++ b/src/lua-5.3/lstring.h
@@ -0,0 +1,49 @@
1/*
2** $Id: lstring.h,v 1.61.1.1 2017/04/19 17:20:42 roberto Exp $
3** String table (keep all strings handled by Lua)
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lstring_h
8#define lstring_h
9
10#include "lgc.h"
11#include "lobject.h"
12#include "lstate.h"
13
14
15#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char))
16
17#define sizeludata(l) (sizeof(union UUdata) + (l))
18#define sizeudata(u) sizeludata((u)->len)
19
20#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
21 (sizeof(s)/sizeof(char))-1))
22
23
24/*
25** test whether a string is a reserved word
26*/
27#define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0)
28
29
30/*
31** equality for short strings, which are always internalized
32*/
33#define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b))
34
35
36LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
37LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts);
38LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
39LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
40LUAI_FUNC void luaS_clearcache (global_State *g);
41LUAI_FUNC void luaS_init (lua_State *L);
42LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
43LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
44LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
45LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);
46LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l);
47
48
49#endif
diff --git a/src/lua-5.3/lstrlib.c b/src/lua-5.3/lstrlib.c
new file mode 100644
index 0000000..b4bed7e
--- /dev/null
+++ b/src/lua-5.3/lstrlib.c
@@ -0,0 +1,1584 @@
1/*
2** $Id: lstrlib.c,v 1.254.1.1 2017/04/19 17:29:57 roberto Exp $
3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h
5*/
6
7#define lstrlib_c
8#define LUA_LIB
9
10#include "lprefix.h"
11
12
13#include <ctype.h>
14#include <float.h>
15#include <limits.h>
16#include <locale.h>
17#include <stddef.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22#include "lua.h"
23
24#include "lauxlib.h"
25#include "lualib.h"
26
27
28/*
29** maximum number of captures that a pattern can do during
30** pattern-matching. This limit is arbitrary, but must fit in
31** an unsigned char.
32*/
33#if !defined(LUA_MAXCAPTURES)
34#define LUA_MAXCAPTURES 32
35#endif
36
37
38/* macro to 'unsign' a character */
39#define uchar(c) ((unsigned char)(c))
40
41
42/*
43** Some sizes are better limited to fit in 'int', but must also fit in
44** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.)
45*/
46#define MAX_SIZET ((size_t)(~(size_t)0))
47
48#define MAXSIZE \
49 (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX))
50
51
52
53
54static int str_len (lua_State *L) {
55 size_t l;
56 luaL_checklstring(L, 1, &l);
57 lua_pushinteger(L, (lua_Integer)l);
58 return 1;
59}
60
61
62/* translate a relative string position: negative means back from end */
63static lua_Integer posrelat (lua_Integer pos, size_t len) {
64 if (pos >= 0) return pos;
65 else if (0u - (size_t)pos > len) return 0;
66 else return (lua_Integer)len + pos + 1;
67}
68
69
70static int str_sub (lua_State *L) {
71 size_t l;
72 const char *s = luaL_checklstring(L, 1, &l);
73 lua_Integer start = posrelat(luaL_checkinteger(L, 2), l);
74 lua_Integer end = posrelat(luaL_optinteger(L, 3, -1), l);
75 if (start < 1) start = 1;
76 if (end > (lua_Integer)l) end = l;
77 if (start <= end)
78 lua_pushlstring(L, s + start - 1, (size_t)(end - start) + 1);
79 else lua_pushliteral(L, "");
80 return 1;
81}
82
83
84static int str_reverse (lua_State *L) {
85 size_t l, i;
86 luaL_Buffer b;
87 const char *s = luaL_checklstring(L, 1, &l);
88 char *p = luaL_buffinitsize(L, &b, l);
89 for (i = 0; i < l; i++)
90 p[i] = s[l - i - 1];
91 luaL_pushresultsize(&b, l);
92 return 1;
93}
94
95
96static int str_lower (lua_State *L) {
97 size_t l;
98 size_t i;
99 luaL_Buffer b;
100 const char *s = luaL_checklstring(L, 1, &l);
101 char *p = luaL_buffinitsize(L, &b, l);
102 for (i=0; i<l; i++)
103 p[i] = tolower(uchar(s[i]));
104 luaL_pushresultsize(&b, l);
105 return 1;
106}
107
108
109static int str_upper (lua_State *L) {
110 size_t l;
111 size_t i;
112 luaL_Buffer b;
113 const char *s = luaL_checklstring(L, 1, &l);
114 char *p = luaL_buffinitsize(L, &b, l);
115 for (i=0; i<l; i++)
116 p[i] = toupper(uchar(s[i]));
117 luaL_pushresultsize(&b, l);
118 return 1;
119}
120
121
122static int str_rep (lua_State *L) {
123 size_t l, lsep;
124 const char *s = luaL_checklstring(L, 1, &l);
125 lua_Integer n = luaL_checkinteger(L, 2);
126 const char *sep = luaL_optlstring(L, 3, "", &lsep);
127 if (n <= 0) lua_pushliteral(L, "");
128 else if (l + lsep < l || l + lsep > MAXSIZE / n) /* may overflow? */
129 return luaL_error(L, "resulting string too large");
130 else {
131 size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep;
132 luaL_Buffer b;
133 char *p = luaL_buffinitsize(L, &b, totallen);
134 while (n-- > 1) { /* first n-1 copies (followed by separator) */
135 memcpy(p, s, l * sizeof(char)); p += l;
136 if (lsep > 0) { /* empty 'memcpy' is not that cheap */
137 memcpy(p, sep, lsep * sizeof(char));
138 p += lsep;
139 }
140 }
141 memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */
142 luaL_pushresultsize(&b, totallen);
143 }
144 return 1;
145}
146
147
148static int str_byte (lua_State *L) {
149 size_t l;
150 const char *s = luaL_checklstring(L, 1, &l);
151 lua_Integer posi = posrelat(luaL_optinteger(L, 2, 1), l);
152 lua_Integer pose = posrelat(luaL_optinteger(L, 3, posi), l);
153 int n, i;
154 if (posi < 1) posi = 1;
155 if (pose > (lua_Integer)l) pose = l;
156 if (posi > pose) return 0; /* empty interval; return no values */
157 if (pose - posi >= INT_MAX) /* arithmetic overflow? */
158 return luaL_error(L, "string slice too long");
159 n = (int)(pose - posi) + 1;
160 luaL_checkstack(L, n, "string slice too long");
161 for (i=0; i<n; i++)
162 lua_pushinteger(L, uchar(s[posi+i-1]));
163 return n;
164}
165
166
167static int str_char (lua_State *L) {
168 int n = lua_gettop(L); /* number of arguments */
169 int i;
170 luaL_Buffer b;
171 char *p = luaL_buffinitsize(L, &b, n);
172 for (i=1; i<=n; i++) {
173 lua_Integer c = luaL_checkinteger(L, i);
174 luaL_argcheck(L, uchar(c) == c, i, "value out of range");
175 p[i - 1] = uchar(c);
176 }
177 luaL_pushresultsize(&b, n);
178 return 1;
179}
180
181
182static int writer (lua_State *L, const void *b, size_t size, void *B) {
183 (void)L;
184 luaL_addlstring((luaL_Buffer *) B, (const char *)b, size);
185 return 0;
186}
187
188
189static int str_dump (lua_State *L) {
190 luaL_Buffer b;
191 int strip = lua_toboolean(L, 2);
192 luaL_checktype(L, 1, LUA_TFUNCTION);
193 lua_settop(L, 1);
194 luaL_buffinit(L,&b);
195 if (lua_dump(L, writer, &b, strip) != 0)
196 return luaL_error(L, "unable to dump given function");
197 luaL_pushresult(&b);
198 return 1;
199}
200
201
202
203/*
204** {======================================================
205** PATTERN MATCHING
206** =======================================================
207*/
208
209
210#define CAP_UNFINISHED (-1)
211#define CAP_POSITION (-2)
212
213
214typedef struct MatchState {
215 const char *src_init; /* init of source string */
216 const char *src_end; /* end ('\0') of source string */
217 const char *p_end; /* end ('\0') of pattern */
218 lua_State *L;
219 int matchdepth; /* control for recursive depth (to avoid C stack overflow) */
220 unsigned char level; /* total number of captures (finished or unfinished) */
221 struct {
222 const char *init;
223 ptrdiff_t len;
224 } capture[LUA_MAXCAPTURES];
225} MatchState;
226
227
228/* recursive function */
229static const char *match (MatchState *ms, const char *s, const char *p);
230
231
232/* maximum recursion depth for 'match' */
233#if !defined(MAXCCALLS)
234#define MAXCCALLS 200
235#endif
236
237
238#define L_ESC '%'
239#define SPECIALS "^$*+?.([%-"
240
241
242static int check_capture (MatchState *ms, int l) {
243 l -= '1';
244 if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
245 return luaL_error(ms->L, "invalid capture index %%%d", l + 1);
246 return l;
247}
248
249
250static int capture_to_close (MatchState *ms) {
251 int level = ms->level;
252 for (level--; level>=0; level--)
253 if (ms->capture[level].len == CAP_UNFINISHED) return level;
254 return luaL_error(ms->L, "invalid pattern capture");
255}
256
257
258static const char *classend (MatchState *ms, const char *p) {
259 switch (*p++) {
260 case L_ESC: {
261 if (p == ms->p_end)
262 luaL_error(ms->L, "malformed pattern (ends with '%%')");
263 return p+1;
264 }
265 case '[': {
266 if (*p == '^') p++;
267 do { /* look for a ']' */
268 if (p == ms->p_end)
269 luaL_error(ms->L, "malformed pattern (missing ']')");
270 if (*(p++) == L_ESC && p < ms->p_end)
271 p++; /* skip escapes (e.g. '%]') */
272 } while (*p != ']');
273 return p+1;
274 }
275 default: {
276 return p;
277 }
278 }
279}
280
281
282static int match_class (int c, int cl) {
283 int res;
284 switch (tolower(cl)) {
285 case 'a' : res = isalpha(c); break;
286 case 'c' : res = iscntrl(c); break;
287 case 'd' : res = isdigit(c); break;
288 case 'g' : res = isgraph(c); break;
289 case 'l' : res = islower(c); break;
290 case 'p' : res = ispunct(c); break;
291 case 's' : res = isspace(c); break;
292 case 'u' : res = isupper(c); break;
293 case 'w' : res = isalnum(c); break;
294 case 'x' : res = isxdigit(c); break;
295 case 'z' : res = (c == 0); break; /* deprecated option */
296 default: return (cl == c);
297 }
298 return (islower(cl) ? res : !res);
299}
300
301
302static int matchbracketclass (int c, const char *p, const char *ec) {
303 int sig = 1;
304 if (*(p+1) == '^') {
305 sig = 0;
306 p++; /* skip the '^' */
307 }
308 while (++p < ec) {
309 if (*p == L_ESC) {
310 p++;
311 if (match_class(c, uchar(*p)))
312 return sig;
313 }
314 else if ((*(p+1) == '-') && (p+2 < ec)) {
315 p+=2;
316 if (uchar(*(p-2)) <= c && c <= uchar(*p))
317 return sig;
318 }
319 else if (uchar(*p) == c) return sig;
320 }
321 return !sig;
322}
323
324
325static int singlematch (MatchState *ms, const char *s, const char *p,
326 const char *ep) {
327 if (s >= ms->src_end)
328 return 0;
329 else {
330 int c = uchar(*s);
331 switch (*p) {
332 case '.': return 1; /* matches any char */
333 case L_ESC: return match_class(c, uchar(*(p+1)));
334 case '[': return matchbracketclass(c, p, ep-1);
335 default: return (uchar(*p) == c);
336 }
337 }
338}
339
340
341static const char *matchbalance (MatchState *ms, const char *s,
342 const char *p) {
343 if (p >= ms->p_end - 1)
344 luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')");
345 if (*s != *p) return NULL;
346 else {
347 int b = *p;
348 int e = *(p+1);
349 int cont = 1;
350 while (++s < ms->src_end) {
351 if (*s == e) {
352 if (--cont == 0) return s+1;
353 }
354 else if (*s == b) cont++;
355 }
356 }
357 return NULL; /* string ends out of balance */
358}
359
360
361static const char *max_expand (MatchState *ms, const char *s,
362 const char *p, const char *ep) {
363 ptrdiff_t i = 0; /* counts maximum expand for item */
364 while (singlematch(ms, s + i, p, ep))
365 i++;
366 /* keeps trying to match with the maximum repetitions */
367 while (i>=0) {
368 const char *res = match(ms, (s+i), ep+1);
369 if (res) return res;
370 i--; /* else didn't match; reduce 1 repetition to try again */
371 }
372 return NULL;
373}
374
375
376static const char *min_expand (MatchState *ms, const char *s,
377 const char *p, const char *ep) {
378 for (;;) {
379 const char *res = match(ms, s, ep+1);
380 if (res != NULL)
381 return res;
382 else if (singlematch(ms, s, p, ep))
383 s++; /* try with one more repetition */
384 else return NULL;
385 }
386}
387
388
389static const char *start_capture (MatchState *ms, const char *s,
390 const char *p, int what) {
391 const char *res;
392 int level = ms->level;
393 if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
394 ms->capture[level].init = s;
395 ms->capture[level].len = what;
396 ms->level = level+1;
397 if ((res=match(ms, s, p)) == NULL) /* match failed? */
398 ms->level--; /* undo capture */
399 return res;
400}
401
402
403static const char *end_capture (MatchState *ms, const char *s,
404 const char *p) {
405 int l = capture_to_close(ms);
406 const char *res;
407 ms->capture[l].len = s - ms->capture[l].init; /* close capture */
408 if ((res = match(ms, s, p)) == NULL) /* match failed? */
409 ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
410 return res;
411}
412
413
414static const char *match_capture (MatchState *ms, const char *s, int l) {
415 size_t len;
416 l = check_capture(ms, l);
417 len = ms->capture[l].len;
418 if ((size_t)(ms->src_end-s) >= len &&
419 memcmp(ms->capture[l].init, s, len) == 0)
420 return s+len;
421 else return NULL;
422}
423
424
425static const char *match (MatchState *ms, const char *s, const char *p) {
426 if (ms->matchdepth-- == 0)
427 luaL_error(ms->L, "pattern too complex");
428 init: /* using goto's to optimize tail recursion */
429 if (p != ms->p_end) { /* end of pattern? */
430 switch (*p) {
431 case '(': { /* start capture */
432 if (*(p + 1) == ')') /* position capture? */
433 s = start_capture(ms, s, p + 2, CAP_POSITION);
434 else
435 s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
436 break;
437 }
438 case ')': { /* end capture */
439 s = end_capture(ms, s, p + 1);
440 break;
441 }
442 case '$': {
443 if ((p + 1) != ms->p_end) /* is the '$' the last char in pattern? */
444 goto dflt; /* no; go to default */
445 s = (s == ms->src_end) ? s : NULL; /* check end of string */
446 break;
447 }
448 case L_ESC: { /* escaped sequences not in the format class[*+?-]? */
449 switch (*(p + 1)) {
450 case 'b': { /* balanced string? */
451 s = matchbalance(ms, s, p + 2);
452 if (s != NULL) {
453 p += 4; goto init; /* return match(ms, s, p + 4); */
454 } /* else fail (s == NULL) */
455 break;
456 }
457 case 'f': { /* frontier? */
458 const char *ep; char previous;
459 p += 2;
460 if (*p != '[')
461 luaL_error(ms->L, "missing '[' after '%%f' in pattern");
462 ep = classend(ms, p); /* points to what is next */
463 previous = (s == ms->src_init) ? '\0' : *(s - 1);
464 if (!matchbracketclass(uchar(previous), p, ep - 1) &&
465 matchbracketclass(uchar(*s), p, ep - 1)) {
466 p = ep; goto init; /* return match(ms, s, ep); */
467 }
468 s = NULL; /* match failed */
469 break;
470 }
471 case '0': case '1': case '2': case '3':
472 case '4': case '5': case '6': case '7':
473 case '8': case '9': { /* capture results (%0-%9)? */
474 s = match_capture(ms, s, uchar(*(p + 1)));
475 if (s != NULL) {
476 p += 2; goto init; /* return match(ms, s, p + 2) */
477 }
478 break;
479 }
480 default: goto dflt;
481 }
482 break;
483 }
484 default: dflt: { /* pattern class plus optional suffix */
485 const char *ep = classend(ms, p); /* points to optional suffix */
486 /* does not match at least once? */
487 if (!singlematch(ms, s, p, ep)) {
488 if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */
489 p = ep + 1; goto init; /* return match(ms, s, ep + 1); */
490 }
491 else /* '+' or no suffix */
492 s = NULL; /* fail */
493 }
494 else { /* matched once */
495 switch (*ep) { /* handle optional suffix */
496 case '?': { /* optional */
497 const char *res;
498 if ((res = match(ms, s + 1, ep + 1)) != NULL)
499 s = res;
500 else {
501 p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */
502 }
503 break;
504 }
505 case '+': /* 1 or more repetitions */
506 s++; /* 1 match already done */
507 /* FALLTHROUGH */
508 case '*': /* 0 or more repetitions */
509 s = max_expand(ms, s, p, ep);
510 break;
511 case '-': /* 0 or more repetitions (minimum) */
512 s = min_expand(ms, s, p, ep);
513 break;
514 default: /* no suffix */
515 s++; p = ep; goto init; /* return match(ms, s + 1, ep); */
516 }
517 }
518 break;
519 }
520 }
521 }
522 ms->matchdepth++;
523 return s;
524}
525
526
527
528static const char *lmemfind (const char *s1, size_t l1,
529 const char *s2, size_t l2) {
530 if (l2 == 0) return s1; /* empty strings are everywhere */
531 else if (l2 > l1) return NULL; /* avoids a negative 'l1' */
532 else {
533 const char *init; /* to search for a '*s2' inside 's1' */
534 l2--; /* 1st char will be checked by 'memchr' */
535 l1 = l1-l2; /* 's2' cannot be found after that */
536 while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
537 init++; /* 1st char is already checked */
538 if (memcmp(init, s2+1, l2) == 0)
539 return init-1;
540 else { /* correct 'l1' and 's1' to try again */
541 l1 -= init-s1;
542 s1 = init;
543 }
544 }
545 return NULL; /* not found */
546 }
547}
548
549
550static void push_onecapture (MatchState *ms, int i, const char *s,
551 const char *e) {
552 if (i >= ms->level) {
553 if (i == 0) /* ms->level == 0, too */
554 lua_pushlstring(ms->L, s, e - s); /* add whole match */
555 else
556 luaL_error(ms->L, "invalid capture index %%%d", i + 1);
557 }
558 else {
559 ptrdiff_t l = ms->capture[i].len;
560 if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
561 if (l == CAP_POSITION)
562 lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1);
563 else
564 lua_pushlstring(ms->L, ms->capture[i].init, l);
565 }
566}
567
568
569static int push_captures (MatchState *ms, const char *s, const char *e) {
570 int i;
571 int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
572 luaL_checkstack(ms->L, nlevels, "too many captures");
573 for (i = 0; i < nlevels; i++)
574 push_onecapture(ms, i, s, e);
575 return nlevels; /* number of strings pushed */
576}
577
578
579/* check whether pattern has no special characters */
580static int nospecials (const char *p, size_t l) {
581 size_t upto = 0;
582 do {
583 if (strpbrk(p + upto, SPECIALS))
584 return 0; /* pattern has a special character */
585 upto += strlen(p + upto) + 1; /* may have more after \0 */
586 } while (upto <= l);
587 return 1; /* no special chars found */
588}
589
590
591static void prepstate (MatchState *ms, lua_State *L,
592 const char *s, size_t ls, const char *p, size_t lp) {
593 ms->L = L;
594 ms->matchdepth = MAXCCALLS;
595 ms->src_init = s;
596 ms->src_end = s + ls;
597 ms->p_end = p + lp;
598}
599
600
601static void reprepstate (MatchState *ms) {
602 ms->level = 0;
603 lua_assert(ms->matchdepth == MAXCCALLS);
604}
605
606
607static int str_find_aux (lua_State *L, int find) {
608 size_t ls, lp;
609 const char *s = luaL_checklstring(L, 1, &ls);
610 const char *p = luaL_checklstring(L, 2, &lp);
611 lua_Integer init = posrelat(luaL_optinteger(L, 3, 1), ls);
612 if (init < 1) init = 1;
613 else if (init > (lua_Integer)ls + 1) { /* start after string's end? */
614 lua_pushnil(L); /* cannot find anything */
615 return 1;
616 }
617 /* explicit request or no special characters? */
618 if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) {
619 /* do a plain search */
620 const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp);
621 if (s2) {
622 lua_pushinteger(L, (s2 - s) + 1);
623 lua_pushinteger(L, (s2 - s) + lp);
624 return 2;
625 }
626 }
627 else {
628 MatchState ms;
629 const char *s1 = s + init - 1;
630 int anchor = (*p == '^');
631 if (anchor) {
632 p++; lp--; /* skip anchor character */
633 }
634 prepstate(&ms, L, s, ls, p, lp);
635 do {
636 const char *res;
637 reprepstate(&ms);
638 if ((res=match(&ms, s1, p)) != NULL) {
639 if (find) {
640 lua_pushinteger(L, (s1 - s) + 1); /* start */
641 lua_pushinteger(L, res - s); /* end */
642 return push_captures(&ms, NULL, 0) + 2;
643 }
644 else
645 return push_captures(&ms, s1, res);
646 }
647 } while (s1++ < ms.src_end && !anchor);
648 }
649 lua_pushnil(L); /* not found */
650 return 1;
651}
652
653
654static int str_find (lua_State *L) {
655 return str_find_aux(L, 1);
656}
657
658
659static int str_match (lua_State *L) {
660 return str_find_aux(L, 0);
661}
662
663
664/* state for 'gmatch' */
665typedef struct GMatchState {
666 const char *src; /* current position */
667 const char *p; /* pattern */
668 const char *lastmatch; /* end of last match */
669 MatchState ms; /* match state */
670} GMatchState;
671
672
673static int gmatch_aux (lua_State *L) {
674 GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3));
675 const char *src;
676 gm->ms.L = L;
677 for (src = gm->src; src <= gm->ms.src_end; src++) {
678 const char *e;
679 reprepstate(&gm->ms);
680 if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) {
681 gm->src = gm->lastmatch = e;
682 return push_captures(&gm->ms, src, e);
683 }
684 }
685 return 0; /* not found */
686}
687
688
689static int gmatch (lua_State *L) {
690 size_t ls, lp;
691 const char *s = luaL_checklstring(L, 1, &ls);
692 const char *p = luaL_checklstring(L, 2, &lp);
693 GMatchState *gm;
694 lua_settop(L, 2); /* keep them on closure to avoid being collected */
695 gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState));
696 prepstate(&gm->ms, L, s, ls, p, lp);
697 gm->src = s; gm->p = p; gm->lastmatch = NULL;
698 lua_pushcclosure(L, gmatch_aux, 3);
699 return 1;
700}
701
702
703static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
704 const char *e) {
705 size_t l, i;
706 lua_State *L = ms->L;
707 const char *news = lua_tolstring(L, 3, &l);
708 for (i = 0; i < l; i++) {
709 if (news[i] != L_ESC)
710 luaL_addchar(b, news[i]);
711 else {
712 i++; /* skip ESC */
713 if (!isdigit(uchar(news[i]))) {
714 if (news[i] != L_ESC)
715 luaL_error(L, "invalid use of '%c' in replacement string", L_ESC);
716 luaL_addchar(b, news[i]);
717 }
718 else if (news[i] == '0')
719 luaL_addlstring(b, s, e - s);
720 else {
721 push_onecapture(ms, news[i] - '1', s, e);
722 luaL_tolstring(L, -1, NULL); /* if number, convert it to string */
723 lua_remove(L, -2); /* remove original value */
724 luaL_addvalue(b); /* add capture to accumulated result */
725 }
726 }
727 }
728}
729
730
731static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
732 const char *e, int tr) {
733 lua_State *L = ms->L;
734 switch (tr) {
735 case LUA_TFUNCTION: {
736 int n;
737 lua_pushvalue(L, 3);
738 n = push_captures(ms, s, e);
739 lua_call(L, n, 1);
740 break;
741 }
742 case LUA_TTABLE: {
743 push_onecapture(ms, 0, s, e);
744 lua_gettable(L, 3);
745 break;
746 }
747 default: { /* LUA_TNUMBER or LUA_TSTRING */
748 add_s(ms, b, s, e);
749 return;
750 }
751 }
752 if (!lua_toboolean(L, -1)) { /* nil or false? */
753 lua_pop(L, 1);
754 lua_pushlstring(L, s, e - s); /* keep original text */
755 }
756 else if (!lua_isstring(L, -1))
757 luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
758 luaL_addvalue(b); /* add result to accumulator */
759}
760
761
762static int str_gsub (lua_State *L) {
763 size_t srcl, lp;
764 const char *src = luaL_checklstring(L, 1, &srcl); /* subject */
765 const char *p = luaL_checklstring(L, 2, &lp); /* pattern */
766 const char *lastmatch = NULL; /* end of last match */
767 int tr = lua_type(L, 3); /* replacement type */
768 lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */
769 int anchor = (*p == '^');
770 lua_Integer n = 0; /* replacement count */
771 MatchState ms;
772 luaL_Buffer b;
773 luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
774 tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
775 "string/function/table expected");
776 luaL_buffinit(L, &b);
777 if (anchor) {
778 p++; lp--; /* skip anchor character */
779 }
780 prepstate(&ms, L, src, srcl, p, lp);
781 while (n < max_s) {
782 const char *e;
783 reprepstate(&ms); /* (re)prepare state for new match */
784 if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */
785 n++;
786 add_value(&ms, &b, src, e, tr); /* add replacement to buffer */
787 src = lastmatch = e;
788 }
789 else if (src < ms.src_end) /* otherwise, skip one character */
790 luaL_addchar(&b, *src++);
791 else break; /* end of subject */
792 if (anchor) break;
793 }
794 luaL_addlstring(&b, src, ms.src_end-src);
795 luaL_pushresult(&b);
796 lua_pushinteger(L, n); /* number of substitutions */
797 return 2;
798}
799
800/* }====================================================== */
801
802
803
804/*
805** {======================================================
806** STRING FORMAT
807** =======================================================
808*/
809
810#if !defined(lua_number2strx) /* { */
811
812/*
813** Hexadecimal floating-point formatter
814*/
815
816#include <math.h>
817
818#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
819
820
821/*
822** Number of bits that goes into the first digit. It can be any value
823** between 1 and 4; the following definition tries to align the number
824** to nibble boundaries by making what is left after that first digit a
825** multiple of 4.
826*/
827#define L_NBFD ((l_mathlim(MANT_DIG) - 1)%4 + 1)
828
829
830/*
831** Add integer part of 'x' to buffer and return new 'x'
832*/
833static lua_Number adddigit (char *buff, int n, lua_Number x) {
834 lua_Number dd = l_mathop(floor)(x); /* get integer part from 'x' */
835 int d = (int)dd;
836 buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */
837 return x - dd; /* return what is left */
838}
839
840
841static int num2straux (char *buff, int sz, lua_Number x) {
842 /* if 'inf' or 'NaN', format it like '%g' */
843 if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL)
844 return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x);
845 else if (x == 0) { /* can be -0... */
846 /* create "0" or "-0" followed by exponent */
847 return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x);
848 }
849 else {
850 int e;
851 lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */
852 int n = 0; /* character count */
853 if (m < 0) { /* is number negative? */
854 buff[n++] = '-'; /* add signal */
855 m = -m; /* make it positive */
856 }
857 buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */
858 m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */
859 e -= L_NBFD; /* this digit goes before the radix point */
860 if (m > 0) { /* more digits? */
861 buff[n++] = lua_getlocaledecpoint(); /* add radix point */
862 do { /* add as many digits as needed */
863 m = adddigit(buff, n++, m * 16);
864 } while (m > 0);
865 }
866 n += l_sprintf(buff + n, sz - n, "p%+d", e); /* add exponent */
867 lua_assert(n < sz);
868 return n;
869 }
870}
871
872
873static int lua_number2strx (lua_State *L, char *buff, int sz,
874 const char *fmt, lua_Number x) {
875 int n = num2straux(buff, sz, x);
876 if (fmt[SIZELENMOD] == 'A') {
877 int i;
878 for (i = 0; i < n; i++)
879 buff[i] = toupper(uchar(buff[i]));
880 }
881 else if (fmt[SIZELENMOD] != 'a')
882 return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
883 return n;
884}
885
886#endif /* } */
887
888
889/*
890** Maximum size of each formatted item. This maximum size is produced
891** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.',
892** and '\0') + number of decimal digits to represent maxfloat (which
893** is maximum exponent + 1). (99+3+1 then rounded to 120 for "extra
894** expenses", such as locale-dependent stuff)
895*/
896#define MAX_ITEM (120 + l_mathlim(MAX_10_EXP))
897
898
899/* valid flags in a format specification */
900#define FLAGS "-+ #0"
901
902/*
903** maximum size of each format specification (such as "%-099.99d")
904*/
905#define MAX_FORMAT 32
906
907
908static void addquoted (luaL_Buffer *b, const char *s, size_t len) {
909 luaL_addchar(b, '"');
910 while (len--) {
911 if (*s == '"' || *s == '\\' || *s == '\n') {
912 luaL_addchar(b, '\\');
913 luaL_addchar(b, *s);
914 }
915 else if (iscntrl(uchar(*s))) {
916 char buff[10];
917 if (!isdigit(uchar(*(s+1))))
918 l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s));
919 else
920 l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s));
921 luaL_addstring(b, buff);
922 }
923 else
924 luaL_addchar(b, *s);
925 s++;
926 }
927 luaL_addchar(b, '"');
928}
929
930
931/*
932** Ensures the 'buff' string uses a dot as the radix character.
933*/
934static void checkdp (char *buff, int nb) {
935 if (memchr(buff, '.', nb) == NULL) { /* no dot? */
936 char point = lua_getlocaledecpoint(); /* try locale point */
937 char *ppoint = (char *)memchr(buff, point, nb);
938 if (ppoint) *ppoint = '.'; /* change it to a dot */
939 }
940}
941
942
943static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
944 switch (lua_type(L, arg)) {
945 case LUA_TSTRING: {
946 size_t len;
947 const char *s = lua_tolstring(L, arg, &len);
948 addquoted(b, s, len);
949 break;
950 }
951 case LUA_TNUMBER: {
952 char *buff = luaL_prepbuffsize(b, MAX_ITEM);
953 int nb;
954 if (!lua_isinteger(L, arg)) { /* float? */
955 lua_Number n = lua_tonumber(L, arg); /* write as hexa ('%a') */
956 nb = lua_number2strx(L, buff, MAX_ITEM, "%" LUA_NUMBER_FRMLEN "a", n);
957 checkdp(buff, nb); /* ensure it uses a dot */
958 }
959 else { /* integers */
960 lua_Integer n = lua_tointeger(L, arg);
961 const char *format = (n == LUA_MININTEGER) /* corner case? */
962 ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hexa */
963 : LUA_INTEGER_FMT; /* else use default format */
964 nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n);
965 }
966 luaL_addsize(b, nb);
967 break;
968 }
969 case LUA_TNIL: case LUA_TBOOLEAN: {
970 luaL_tolstring(L, arg, NULL);
971 luaL_addvalue(b);
972 break;
973 }
974 default: {
975 luaL_argerror(L, arg, "value has no literal form");
976 }
977 }
978}
979
980
981static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
982 const char *p = strfrmt;
983 while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
984 if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char))
985 luaL_error(L, "invalid format (repeated flags)");
986 if (isdigit(uchar(*p))) p++; /* skip width */
987 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
988 if (*p == '.') {
989 p++;
990 if (isdigit(uchar(*p))) p++; /* skip precision */
991 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
992 }
993 if (isdigit(uchar(*p)))
994 luaL_error(L, "invalid format (width or precision too long)");
995 *(form++) = '%';
996 memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char));
997 form += (p - strfrmt) + 1;
998 *form = '\0';
999 return p;
1000}
1001
1002
1003/*
1004** add length modifier into formats
1005*/
1006static void addlenmod (char *form, const char *lenmod) {
1007 size_t l = strlen(form);
1008 size_t lm = strlen(lenmod);
1009 char spec = form[l - 1];
1010 strcpy(form + l - 1, lenmod);
1011 form[l + lm - 1] = spec;
1012 form[l + lm] = '\0';
1013}
1014
1015
1016static int str_format (lua_State *L) {
1017 int top = lua_gettop(L);
1018 int arg = 1;
1019 size_t sfl;
1020 const char *strfrmt = luaL_checklstring(L, arg, &sfl);
1021 const char *strfrmt_end = strfrmt+sfl;
1022 luaL_Buffer b;
1023 luaL_buffinit(L, &b);
1024 while (strfrmt < strfrmt_end) {
1025 if (*strfrmt != L_ESC)
1026 luaL_addchar(&b, *strfrmt++);
1027 else if (*++strfrmt == L_ESC)
1028 luaL_addchar(&b, *strfrmt++); /* %% */
1029 else { /* format item */
1030 char form[MAX_FORMAT]; /* to store the format ('%...') */
1031 char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */
1032 int nb = 0; /* number of bytes in added item */
1033 if (++arg > top)
1034 luaL_argerror(L, arg, "no value");
1035 strfrmt = scanformat(L, strfrmt, form);
1036 switch (*strfrmt++) {
1037 case 'c': {
1038 nb = l_sprintf(buff, MAX_ITEM, form, (int)luaL_checkinteger(L, arg));
1039 break;
1040 }
1041 case 'd': case 'i':
1042 case 'o': case 'u': case 'x': case 'X': {
1043 lua_Integer n = luaL_checkinteger(L, arg);
1044 addlenmod(form, LUA_INTEGER_FRMLEN);
1045 nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACINT)n);
1046 break;
1047 }
1048 case 'a': case 'A':
1049 addlenmod(form, LUA_NUMBER_FRMLEN);
1050 nb = lua_number2strx(L, buff, MAX_ITEM, form,
1051 luaL_checknumber(L, arg));
1052 break;
1053 case 'e': case 'E': case 'f':
1054 case 'g': case 'G': {
1055 lua_Number n = luaL_checknumber(L, arg);
1056 addlenmod(form, LUA_NUMBER_FRMLEN);
1057 nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n);
1058 break;
1059 }
1060 case 'q': {
1061 addliteral(L, &b, arg);
1062 break;
1063 }
1064 case 's': {
1065 size_t l;
1066 const char *s = luaL_tolstring(L, arg, &l);
1067 if (form[2] == '\0') /* no modifiers? */
1068 luaL_addvalue(&b); /* keep entire string */
1069 else {
1070 luaL_argcheck(L, l == strlen(s), arg, "string contains zeros");
1071 if (!strchr(form, '.') && l >= 100) {
1072 /* no precision and string is too long to be formatted */
1073 luaL_addvalue(&b); /* keep entire string */
1074 }
1075 else { /* format the string into 'buff' */
1076 nb = l_sprintf(buff, MAX_ITEM, form, s);
1077 lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
1078 }
1079 }
1080 break;
1081 }
1082 default: { /* also treat cases 'pnLlh' */
1083 return luaL_error(L, "invalid option '%%%c' to 'format'",
1084 *(strfrmt - 1));
1085 }
1086 }
1087 lua_assert(nb < MAX_ITEM);
1088 luaL_addsize(&b, nb);
1089 }
1090 }
1091 luaL_pushresult(&b);
1092 return 1;
1093}
1094
1095/* }====================================================== */
1096
1097
1098/*
1099** {======================================================
1100** PACK/UNPACK
1101** =======================================================
1102*/
1103
1104
1105/* value used for padding */
1106#if !defined(LUAL_PACKPADBYTE)
1107#define LUAL_PACKPADBYTE 0x00
1108#endif
1109
1110/* maximum size for the binary representation of an integer */
1111#define MAXINTSIZE 16
1112
1113/* number of bits in a character */
1114#define NB CHAR_BIT
1115
1116/* mask for one character (NB 1's) */
1117#define MC ((1 << NB) - 1)
1118
1119/* size of a lua_Integer */
1120#define SZINT ((int)sizeof(lua_Integer))
1121
1122
1123/* dummy union to get native endianness */
1124static const union {
1125 int dummy;
1126 char little; /* true iff machine is little endian */
1127} nativeendian = {1};
1128
1129
1130/* dummy structure to get native alignment requirements */
1131struct cD {
1132 char c;
1133 union { double d; void *p; lua_Integer i; lua_Number n; } u;
1134};
1135
1136#define MAXALIGN (offsetof(struct cD, u))
1137
1138
1139/*
1140** Union for serializing floats
1141*/
1142typedef union Ftypes {
1143 float f;
1144 double d;
1145 lua_Number n;
1146 char buff[5 * sizeof(lua_Number)]; /* enough for any float type */
1147} Ftypes;
1148
1149
1150/*
1151** information to pack/unpack stuff
1152*/
1153typedef struct Header {
1154 lua_State *L;
1155 int islittle;
1156 int maxalign;
1157} Header;
1158
1159
1160/*
1161** options for pack/unpack
1162*/
1163typedef enum KOption {
1164 Kint, /* signed integers */
1165 Kuint, /* unsigned integers */
1166 Kfloat, /* floating-point numbers */
1167 Kchar, /* fixed-length strings */
1168 Kstring, /* strings with prefixed length */
1169 Kzstr, /* zero-terminated strings */
1170 Kpadding, /* padding */
1171 Kpaddalign, /* padding for alignment */
1172 Knop /* no-op (configuration or spaces) */
1173} KOption;
1174
1175
1176/*
1177** Read an integer numeral from string 'fmt' or return 'df' if
1178** there is no numeral
1179*/
1180static int digit (int c) { return '0' <= c && c <= '9'; }
1181
1182static int getnum (const char **fmt, int df) {
1183 if (!digit(**fmt)) /* no number? */
1184 return df; /* return default value */
1185 else {
1186 int a = 0;
1187 do {
1188 a = a*10 + (*((*fmt)++) - '0');
1189 } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10);
1190 return a;
1191 }
1192}
1193
1194
1195/*
1196** Read an integer numeral and raises an error if it is larger
1197** than the maximum size for integers.
1198*/
1199static int getnumlimit (Header *h, const char **fmt, int df) {
1200 int sz = getnum(fmt, df);
1201 if (sz > MAXINTSIZE || sz <= 0)
1202 return luaL_error(h->L, "integral size (%d) out of limits [1,%d]",
1203 sz, MAXINTSIZE);
1204 return sz;
1205}
1206
1207
1208/*
1209** Initialize Header
1210*/
1211static void initheader (lua_State *L, Header *h) {
1212 h->L = L;
1213 h->islittle = nativeendian.little;
1214 h->maxalign = 1;
1215}
1216
1217
1218/*
1219** Read and classify next option. 'size' is filled with option's size.
1220*/
1221static KOption getoption (Header *h, const char **fmt, int *size) {
1222 int opt = *((*fmt)++);
1223 *size = 0; /* default */
1224 switch (opt) {
1225 case 'b': *size = sizeof(char); return Kint;
1226 case 'B': *size = sizeof(char); return Kuint;
1227 case 'h': *size = sizeof(short); return Kint;
1228 case 'H': *size = sizeof(short); return Kuint;
1229 case 'l': *size = sizeof(long); return Kint;
1230 case 'L': *size = sizeof(long); return Kuint;
1231 case 'j': *size = sizeof(lua_Integer); return Kint;
1232 case 'J': *size = sizeof(lua_Integer); return Kuint;
1233 case 'T': *size = sizeof(size_t); return Kuint;
1234 case 'f': *size = sizeof(float); return Kfloat;
1235 case 'd': *size = sizeof(double); return Kfloat;
1236 case 'n': *size = sizeof(lua_Number); return Kfloat;
1237 case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint;
1238 case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint;
1239 case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring;
1240 case 'c':
1241 *size = getnum(fmt, -1);
1242 if (*size == -1)
1243 luaL_error(h->L, "missing size for format option 'c'");
1244 return Kchar;
1245 case 'z': return Kzstr;
1246 case 'x': *size = 1; return Kpadding;
1247 case 'X': return Kpaddalign;
1248 case ' ': break;
1249 case '<': h->islittle = 1; break;
1250 case '>': h->islittle = 0; break;
1251 case '=': h->islittle = nativeendian.little; break;
1252 case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break;
1253 default: luaL_error(h->L, "invalid format option '%c'", opt);
1254 }
1255 return Knop;
1256}
1257
1258
1259/*
1260** Read, classify, and fill other details about the next option.
1261** 'psize' is filled with option's size, 'notoalign' with its
1262** alignment requirements.
1263** Local variable 'size' gets the size to be aligned. (Kpadal option
1264** always gets its full alignment, other options are limited by
1265** the maximum alignment ('maxalign'). Kchar option needs no alignment
1266** despite its size.
1267*/
1268static KOption getdetails (Header *h, size_t totalsize,
1269 const char **fmt, int *psize, int *ntoalign) {
1270 KOption opt = getoption(h, fmt, psize);
1271 int align = *psize; /* usually, alignment follows size */
1272 if (opt == Kpaddalign) { /* 'X' gets alignment from following option */
1273 if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0)
1274 luaL_argerror(h->L, 1, "invalid next option for option 'X'");
1275 }
1276 if (align <= 1 || opt == Kchar) /* need no alignment? */
1277 *ntoalign = 0;
1278 else {
1279 if (align > h->maxalign) /* enforce maximum alignment */
1280 align = h->maxalign;
1281 if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */
1282 luaL_argerror(h->L, 1, "format asks for alignment not power of 2");
1283 *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1);
1284 }
1285 return opt;
1286}
1287
1288
1289/*
1290** Pack integer 'n' with 'size' bytes and 'islittle' endianness.
1291** The final 'if' handles the case when 'size' is larger than
1292** the size of a Lua integer, correcting the extra sign-extension
1293** bytes if necessary (by default they would be zeros).
1294*/
1295static void packint (luaL_Buffer *b, lua_Unsigned n,
1296 int islittle, int size, int neg) {
1297 char *buff = luaL_prepbuffsize(b, size);
1298 int i;
1299 buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */
1300 for (i = 1; i < size; i++) {
1301 n >>= NB;
1302 buff[islittle ? i : size - 1 - i] = (char)(n & MC);
1303 }
1304 if (neg && size > SZINT) { /* negative number need sign extension? */
1305 for (i = SZINT; i < size; i++) /* correct extra bytes */
1306 buff[islittle ? i : size - 1 - i] = (char)MC;
1307 }
1308 luaL_addsize(b, size); /* add result to buffer */
1309}
1310
1311
1312/*
1313** Copy 'size' bytes from 'src' to 'dest', correcting endianness if
1314** given 'islittle' is different from native endianness.
1315*/
1316static void copywithendian (volatile char *dest, volatile const char *src,
1317 int size, int islittle) {
1318 if (islittle == nativeendian.little) {
1319 while (size-- != 0)
1320 *(dest++) = *(src++);
1321 }
1322 else {
1323 dest += size - 1;
1324 while (size-- != 0)
1325 *(dest--) = *(src++);
1326 }
1327}
1328
1329
1330static int str_pack (lua_State *L) {
1331 luaL_Buffer b;
1332 Header h;
1333 const char *fmt = luaL_checkstring(L, 1); /* format string */
1334 int arg = 1; /* current argument to pack */
1335 size_t totalsize = 0; /* accumulate total size of result */
1336 initheader(L, &h);
1337 lua_pushnil(L); /* mark to separate arguments from string buffer */
1338 luaL_buffinit(L, &b);
1339 while (*fmt != '\0') {
1340 int size, ntoalign;
1341 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1342 totalsize += ntoalign + size;
1343 while (ntoalign-- > 0)
1344 luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */
1345 arg++;
1346 switch (opt) {
1347 case Kint: { /* signed integers */
1348 lua_Integer n = luaL_checkinteger(L, arg);
1349 if (size < SZINT) { /* need overflow check? */
1350 lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1);
1351 luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow");
1352 }
1353 packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0));
1354 break;
1355 }
1356 case Kuint: { /* unsigned integers */
1357 lua_Integer n = luaL_checkinteger(L, arg);
1358 if (size < SZINT) /* need overflow check? */
1359 luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)),
1360 arg, "unsigned overflow");
1361 packint(&b, (lua_Unsigned)n, h.islittle, size, 0);
1362 break;
1363 }
1364 case Kfloat: { /* floating-point options */
1365 volatile Ftypes u;
1366 char *buff = luaL_prepbuffsize(&b, size);
1367 lua_Number n = luaL_checknumber(L, arg); /* get argument */
1368 if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */
1369 else if (size == sizeof(u.d)) u.d = (double)n;
1370 else u.n = n;
1371 /* move 'u' to final result, correcting endianness if needed */
1372 copywithendian(buff, u.buff, size, h.islittle);
1373 luaL_addsize(&b, size);
1374 break;
1375 }
1376 case Kchar: { /* fixed-size string */
1377 size_t len;
1378 const char *s = luaL_checklstring(L, arg, &len);
1379 luaL_argcheck(L, len <= (size_t)size, arg,
1380 "string longer than given size");
1381 luaL_addlstring(&b, s, len); /* add string */
1382 while (len++ < (size_t)size) /* pad extra space */
1383 luaL_addchar(&b, LUAL_PACKPADBYTE);
1384 break;
1385 }
1386 case Kstring: { /* strings with length count */
1387 size_t len;
1388 const char *s = luaL_checklstring(L, arg, &len);
1389 luaL_argcheck(L, size >= (int)sizeof(size_t) ||
1390 len < ((size_t)1 << (size * NB)),
1391 arg, "string length does not fit in given size");
1392 packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */
1393 luaL_addlstring(&b, s, len);
1394 totalsize += len;
1395 break;
1396 }
1397 case Kzstr: { /* zero-terminated string */
1398 size_t len;
1399 const char *s = luaL_checklstring(L, arg, &len);
1400 luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros");
1401 luaL_addlstring(&b, s, len);
1402 luaL_addchar(&b, '\0'); /* add zero at the end */
1403 totalsize += len + 1;
1404 break;
1405 }
1406 case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */
1407 case Kpaddalign: case Knop:
1408 arg--; /* undo increment */
1409 break;
1410 }
1411 }
1412 luaL_pushresult(&b);
1413 return 1;
1414}
1415
1416
1417static int str_packsize (lua_State *L) {
1418 Header h;
1419 const char *fmt = luaL_checkstring(L, 1); /* format string */
1420 size_t totalsize = 0; /* accumulate total size of result */
1421 initheader(L, &h);
1422 while (*fmt != '\0') {
1423 int size, ntoalign;
1424 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1425 size += ntoalign; /* total space used by option */
1426 luaL_argcheck(L, totalsize <= MAXSIZE - size, 1,
1427 "format result too large");
1428 totalsize += size;
1429 switch (opt) {
1430 case Kstring: /* strings with length count */
1431 case Kzstr: /* zero-terminated string */
1432 luaL_argerror(L, 1, "variable-length format");
1433 /* call never return, but to avoid warnings: *//* FALLTHROUGH */
1434 default: break;
1435 }
1436 }
1437 lua_pushinteger(L, (lua_Integer)totalsize);
1438 return 1;
1439}
1440
1441
1442/*
1443** Unpack an integer with 'size' bytes and 'islittle' endianness.
1444** If size is smaller than the size of a Lua integer and integer
1445** is signed, must do sign extension (propagating the sign to the
1446** higher bits); if size is larger than the size of a Lua integer,
1447** it must check the unread bytes to see whether they do not cause an
1448** overflow.
1449*/
1450static lua_Integer unpackint (lua_State *L, const char *str,
1451 int islittle, int size, int issigned) {
1452 lua_Unsigned res = 0;
1453 int i;
1454 int limit = (size <= SZINT) ? size : SZINT;
1455 for (i = limit - 1; i >= 0; i--) {
1456 res <<= NB;
1457 res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i];
1458 }
1459 if (size < SZINT) { /* real size smaller than lua_Integer? */
1460 if (issigned) { /* needs sign extension? */
1461 lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1);
1462 res = ((res ^ mask) - mask); /* do sign extension */
1463 }
1464 }
1465 else if (size > SZINT) { /* must check unread bytes */
1466 int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC;
1467 for (i = limit; i < size; i++) {
1468 if ((unsigned char)str[islittle ? i : size - 1 - i] != mask)
1469 luaL_error(L, "%d-byte integer does not fit into Lua Integer", size);
1470 }
1471 }
1472 return (lua_Integer)res;
1473}
1474
1475
1476static int str_unpack (lua_State *L) {
1477 Header h;
1478 const char *fmt = luaL_checkstring(L, 1);
1479 size_t ld;
1480 const char *data = luaL_checklstring(L, 2, &ld);
1481 size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1;
1482 int n = 0; /* number of results */
1483 luaL_argcheck(L, pos <= ld, 3, "initial position out of string");
1484 initheader(L, &h);
1485 while (*fmt != '\0') {
1486 int size, ntoalign;
1487 KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign);
1488 if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld)
1489 luaL_argerror(L, 2, "data string too short");
1490 pos += ntoalign; /* skip alignment */
1491 /* stack space for item + next position */
1492 luaL_checkstack(L, 2, "too many results");
1493 n++;
1494 switch (opt) {
1495 case Kint:
1496 case Kuint: {
1497 lua_Integer res = unpackint(L, data + pos, h.islittle, size,
1498 (opt == Kint));
1499 lua_pushinteger(L, res);
1500 break;
1501 }
1502 case Kfloat: {
1503 volatile Ftypes u;
1504 lua_Number num;
1505 copywithendian(u.buff, data + pos, size, h.islittle);
1506 if (size == sizeof(u.f)) num = (lua_Number)u.f;
1507 else if (size == sizeof(u.d)) num = (lua_Number)u.d;
1508 else num = u.n;
1509 lua_pushnumber(L, num);
1510 break;
1511 }
1512 case Kchar: {
1513 lua_pushlstring(L, data + pos, size);
1514 break;
1515 }
1516 case Kstring: {
1517 size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0);
1518 luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short");
1519 lua_pushlstring(L, data + pos + size, len);
1520 pos += len; /* skip string */
1521 break;
1522 }
1523 case Kzstr: {
1524 size_t len = (int)strlen(data + pos);
1525 lua_pushlstring(L, data + pos, len);
1526 pos += len + 1; /* skip string plus final '\0' */
1527 break;
1528 }
1529 case Kpaddalign: case Kpadding: case Knop:
1530 n--; /* undo increment */
1531 break;
1532 }
1533 pos += size;
1534 }
1535 lua_pushinteger(L, pos + 1); /* next position */
1536 return n + 1;
1537}
1538
1539/* }====================================================== */
1540
1541
1542static const luaL_Reg strlib[] = {
1543 {"byte", str_byte},
1544 {"char", str_char},
1545 {"dump", str_dump},
1546 {"find", str_find},
1547 {"format", str_format},
1548 {"gmatch", gmatch},
1549 {"gsub", str_gsub},
1550 {"len", str_len},
1551 {"lower", str_lower},
1552 {"match", str_match},
1553 {"rep", str_rep},
1554 {"reverse", str_reverse},
1555 {"sub", str_sub},
1556 {"upper", str_upper},
1557 {"pack", str_pack},
1558 {"packsize", str_packsize},
1559 {"unpack", str_unpack},
1560 {NULL, NULL}
1561};
1562
1563
1564static void createmetatable (lua_State *L) {
1565 lua_createtable(L, 0, 1); /* table to be metatable for strings */
1566 lua_pushliteral(L, ""); /* dummy string */
1567 lua_pushvalue(L, -2); /* copy table */
1568 lua_setmetatable(L, -2); /* set table as metatable for strings */
1569 lua_pop(L, 1); /* pop dummy string */
1570 lua_pushvalue(L, -2); /* get string library */
1571 lua_setfield(L, -2, "__index"); /* metatable.__index = string */
1572 lua_pop(L, 1); /* pop metatable */
1573}
1574
1575
1576/*
1577** Open string library
1578*/
1579LUAMOD_API int luaopen_string (lua_State *L) {
1580 luaL_newlib(L, strlib);
1581 createmetatable(L);
1582 return 1;
1583}
1584
diff --git a/src/lua-5.3/ltable.c b/src/lua-5.3/ltable.c
new file mode 100644
index 0000000..ea4fe7f
--- /dev/null
+++ b/src/lua-5.3/ltable.c
@@ -0,0 +1,688 @@
1/*
2** $Id: ltable.c,v 2.118.1.4 2018/06/08 16:22:51 roberto Exp $
3** Lua tables (hash)
4** See Copyright Notice in lua.h
5*/
6
7#define ltable_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13/*
14** Implementation of tables (aka arrays, objects, or hash tables).
15** Tables keep its elements in two parts: an array part and a hash part.
16** Non-negative integer keys are all candidates to be kept in the array
17** part. The actual size of the array is the largest 'n' such that
18** more than half the slots between 1 and n are in use.
19** Hash uses a mix of chained scatter table with Brent's variation.
20** A main invariant of these tables is that, if an element is not
21** in its main position (i.e. the 'original' position that its hash gives
22** to it), then the colliding element is in its own main position.
23** Hence even when the load factor reaches 100%, performance remains good.
24*/
25
26#include <math.h>
27#include <limits.h>
28
29#include "lua.h"
30
31#include "ldebug.h"
32#include "ldo.h"
33#include "lgc.h"
34#include "lmem.h"
35#include "lobject.h"
36#include "lstate.h"
37#include "lstring.h"
38#include "ltable.h"
39#include "lvm.h"
40
41
42/*
43** Maximum size of array part (MAXASIZE) is 2^MAXABITS. MAXABITS is
44** the largest integer such that MAXASIZE fits in an unsigned int.
45*/
46#define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1)
47#define MAXASIZE (1u << MAXABITS)
48
49/*
50** Maximum size of hash part is 2^MAXHBITS. MAXHBITS is the largest
51** integer such that 2^MAXHBITS fits in a signed int. (Note that the
52** maximum number of elements in a table, 2^MAXABITS + 2^MAXHBITS, still
53** fits comfortably in an unsigned int.)
54*/
55#define MAXHBITS (MAXABITS - 1)
56
57
58#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
59
60#define hashstr(t,str) hashpow2(t, (str)->hash)
61#define hashboolean(t,p) hashpow2(t, p)
62#define hashint(t,i) hashpow2(t, i)
63
64
65/*
66** for some types, it is better to avoid modulus by power of 2, as
67** they tend to have many 2 factors.
68*/
69#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
70
71
72#define hashpointer(t,p) hashmod(t, point2uint(p))
73
74
75#define dummynode (&dummynode_)
76
77static const Node dummynode_ = {
78 {NILCONSTANT}, /* value */
79 {{NILCONSTANT, 0}} /* key */
80};
81
82
83/*
84** Hash for floating-point numbers.
85** The main computation should be just
86** n = frexp(n, &i); return (n * INT_MAX) + i
87** but there are some numerical subtleties.
88** In a two-complement representation, INT_MAX does not has an exact
89** representation as a float, but INT_MIN does; because the absolute
90** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the
91** absolute value of the product 'frexp * -INT_MIN' is smaller or equal
92** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when
93** adding 'i'; the use of '~u' (instead of '-u') avoids problems with
94** INT_MIN.
95*/
96#if !defined(l_hashfloat)
97static int l_hashfloat (lua_Number n) {
98 int i;
99 lua_Integer ni;
100 n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN);
101 if (!lua_numbertointeger(n, &ni)) { /* is 'n' inf/-inf/NaN? */
102 lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == cast_num(HUGE_VAL));
103 return 0;
104 }
105 else { /* normal case */
106 unsigned int u = cast(unsigned int, i) + cast(unsigned int, ni);
107 return cast_int(u <= cast(unsigned int, INT_MAX) ? u : ~u);
108 }
109}
110#endif
111
112
113/*
114** returns the 'main' position of an element in a table (that is, the index
115** of its hash value)
116*/
117static Node *mainposition (const Table *t, const TValue *key) {
118 switch (ttype(key)) {
119 case LUA_TNUMINT:
120 return hashint(t, ivalue(key));
121 case LUA_TNUMFLT:
122 return hashmod(t, l_hashfloat(fltvalue(key)));
123 case LUA_TSHRSTR:
124 return hashstr(t, tsvalue(key));
125 case LUA_TLNGSTR:
126 return hashpow2(t, luaS_hashlongstr(tsvalue(key)));
127 case LUA_TBOOLEAN:
128 return hashboolean(t, bvalue(key));
129 case LUA_TLIGHTUSERDATA:
130 return hashpointer(t, pvalue(key));
131 case LUA_TLCF:
132 return hashpointer(t, fvalue(key));
133 default:
134 lua_assert(!ttisdeadkey(key));
135 return hashpointer(t, gcvalue(key));
136 }
137}
138
139
140/*
141** returns the index for 'key' if 'key' is an appropriate key to live in
142** the array part of the table, 0 otherwise.
143*/
144static unsigned int arrayindex (const TValue *key) {
145 if (ttisinteger(key)) {
146 lua_Integer k = ivalue(key);
147 if (0 < k && (lua_Unsigned)k <= MAXASIZE)
148 return cast(unsigned int, k); /* 'key' is an appropriate array index */
149 }
150 return 0; /* 'key' did not match some condition */
151}
152
153
154/*
155** returns the index of a 'key' for table traversals. First goes all
156** elements in the array part, then elements in the hash part. The
157** beginning of a traversal is signaled by 0.
158*/
159static unsigned int findindex (lua_State *L, Table *t, StkId key) {
160 unsigned int i;
161 if (ttisnil(key)) return 0; /* first iteration */
162 i = arrayindex(key);
163 if (i != 0 && i <= t->sizearray) /* is 'key' inside array part? */
164 return i; /* yes; that's the index */
165 else {
166 int nx;
167 Node *n = mainposition(t, key);
168 for (;;) { /* check whether 'key' is somewhere in the chain */
169 /* key may be dead already, but it is ok to use it in 'next' */
170 if (luaV_rawequalobj(gkey(n), key) ||
171 (ttisdeadkey(gkey(n)) && iscollectable(key) &&
172 deadvalue(gkey(n)) == gcvalue(key))) {
173 i = cast_int(n - gnode(t, 0)); /* key index in hash table */
174 /* hash elements are numbered after array ones */
175 return (i + 1) + t->sizearray;
176 }
177 nx = gnext(n);
178 if (nx == 0)
179 luaG_runerror(L, "invalid key to 'next'"); /* key not found */
180 else n += nx;
181 }
182 }
183}
184
185
186int luaH_next (lua_State *L, Table *t, StkId key) {
187 unsigned int i = findindex(L, t, key); /* find original element */
188 for (; i < t->sizearray; i++) { /* try first array part */
189 if (!ttisnil(&t->array[i])) { /* a non-nil value? */
190 setivalue(key, i + 1);
191 setobj2s(L, key+1, &t->array[i]);
192 return 1;
193 }
194 }
195 for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */
196 if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
197 setobj2s(L, key, gkey(gnode(t, i)));
198 setobj2s(L, key+1, gval(gnode(t, i)));
199 return 1;
200 }
201 }
202 return 0; /* no more elements */
203}
204
205
206/*
207** {=============================================================
208** Rehash
209** ==============================================================
210*/
211
212/*
213** Compute the optimal size for the array part of table 't'. 'nums' is a
214** "count array" where 'nums[i]' is the number of integers in the table
215** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of
216** integer keys in the table and leaves with the number of keys that
217** will go to the array part; return the optimal size.
218*/
219static unsigned int computesizes (unsigned int nums[], unsigned int *pna) {
220 int i;
221 unsigned int twotoi; /* 2^i (candidate for optimal size) */
222 unsigned int a = 0; /* number of elements smaller than 2^i */
223 unsigned int na = 0; /* number of elements to go to array part */
224 unsigned int optimal = 0; /* optimal size for array part */
225 /* loop while keys can fill more than half of total size */
226 for (i = 0, twotoi = 1;
227 twotoi > 0 && *pna > twotoi / 2;
228 i++, twotoi *= 2) {
229 if (nums[i] > 0) {
230 a += nums[i];
231 if (a > twotoi/2) { /* more than half elements present? */
232 optimal = twotoi; /* optimal size (till now) */
233 na = a; /* all elements up to 'optimal' will go to array part */
234 }
235 }
236 }
237 lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal);
238 *pna = na;
239 return optimal;
240}
241
242
243static int countint (const TValue *key, unsigned int *nums) {
244 unsigned int k = arrayindex(key);
245 if (k != 0) { /* is 'key' an appropriate array index? */
246 nums[luaO_ceillog2(k)]++; /* count as such */
247 return 1;
248 }
249 else
250 return 0;
251}
252
253
254/*
255** Count keys in array part of table 't': Fill 'nums[i]' with
256** number of keys that will go into corresponding slice and return
257** total number of non-nil keys.
258*/
259static unsigned int numusearray (const Table *t, unsigned int *nums) {
260 int lg;
261 unsigned int ttlg; /* 2^lg */
262 unsigned int ause = 0; /* summation of 'nums' */
263 unsigned int i = 1; /* count to traverse all array keys */
264 /* traverse each slice */
265 for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) {
266 unsigned int lc = 0; /* counter */
267 unsigned int lim = ttlg;
268 if (lim > t->sizearray) {
269 lim = t->sizearray; /* adjust upper limit */
270 if (i > lim)
271 break; /* no more elements to count */
272 }
273 /* count elements in range (2^(lg - 1), 2^lg] */
274 for (; i <= lim; i++) {
275 if (!ttisnil(&t->array[i-1]))
276 lc++;
277 }
278 nums[lg] += lc;
279 ause += lc;
280 }
281 return ause;
282}
283
284
285static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) {
286 int totaluse = 0; /* total number of elements */
287 int ause = 0; /* elements added to 'nums' (can go to array part) */
288 int i = sizenode(t);
289 while (i--) {
290 Node *n = &t->node[i];
291 if (!ttisnil(gval(n))) {
292 ause += countint(gkey(n), nums);
293 totaluse++;
294 }
295 }
296 *pna += ause;
297 return totaluse;
298}
299
300
301static void setarrayvector (lua_State *L, Table *t, unsigned int size) {
302 unsigned int i;
303 luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
304 for (i=t->sizearray; i<size; i++)
305 setnilvalue(&t->array[i]);
306 t->sizearray = size;
307}
308
309
310static void setnodevector (lua_State *L, Table *t, unsigned int size) {
311 if (size == 0) { /* no elements to hash part? */
312 t->node = cast(Node *, dummynode); /* use common 'dummynode' */
313 t->lsizenode = 0;
314 t->lastfree = NULL; /* signal that it is using dummy node */
315 }
316 else {
317 int i;
318 int lsize = luaO_ceillog2(size);
319 if (lsize > MAXHBITS)
320 luaG_runerror(L, "table overflow");
321 size = twoto(lsize);
322 t->node = luaM_newvector(L, size, Node);
323 for (i = 0; i < (int)size; i++) {
324 Node *n = gnode(t, i);
325 gnext(n) = 0;
326 setnilvalue(wgkey(n));
327 setnilvalue(gval(n));
328 }
329 t->lsizenode = cast_byte(lsize);
330 t->lastfree = gnode(t, size); /* all positions are free */
331 }
332}
333
334
335typedef struct {
336 Table *t;
337 unsigned int nhsize;
338} AuxsetnodeT;
339
340
341static void auxsetnode (lua_State *L, void *ud) {
342 AuxsetnodeT *asn = cast(AuxsetnodeT *, ud);
343 setnodevector(L, asn->t, asn->nhsize);
344}
345
346
347void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
348 unsigned int nhsize) {
349 unsigned int i;
350 int j;
351 AuxsetnodeT asn;
352 unsigned int oldasize = t->sizearray;
353 int oldhsize = allocsizenode(t);
354 Node *nold = t->node; /* save old hash ... */
355 if (nasize > oldasize) /* array part must grow? */
356 setarrayvector(L, t, nasize);
357 /* create new hash part with appropriate size */
358 asn.t = t; asn.nhsize = nhsize;
359 if (luaD_rawrunprotected(L, auxsetnode, &asn) != LUA_OK) { /* mem. error? */
360 setarrayvector(L, t, oldasize); /* array back to its original size */
361 luaD_throw(L, LUA_ERRMEM); /* rethrow memory error */
362 }
363 if (nasize < oldasize) { /* array part must shrink? */
364 t->sizearray = nasize;
365 /* re-insert elements from vanishing slice */
366 for (i=nasize; i<oldasize; i++) {
367 if (!ttisnil(&t->array[i]))
368 luaH_setint(L, t, i + 1, &t->array[i]);
369 }
370 /* shrink array */
371 luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
372 }
373 /* re-insert elements from hash part */
374 for (j = oldhsize - 1; j >= 0; j--) {
375 Node *old = nold + j;
376 if (!ttisnil(gval(old))) {
377 /* doesn't need barrier/invalidate cache, as entry was
378 already present in the table */
379 setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
380 }
381 }
382 if (oldhsize > 0) /* not the dummy node? */
383 luaM_freearray(L, nold, cast(size_t, oldhsize)); /* free old hash */
384}
385
386
387void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
388 int nsize = allocsizenode(t);
389 luaH_resize(L, t, nasize, nsize);
390}
391
392/*
393** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i
394*/
395static void rehash (lua_State *L, Table *t, const TValue *ek) {
396 unsigned int asize; /* optimal size for array part */
397 unsigned int na; /* number of keys in the array part */
398 unsigned int nums[MAXABITS + 1];
399 int i;
400 int totaluse;
401 for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */
402 na = numusearray(t, nums); /* count keys in array part */
403 totaluse = na; /* all those keys are integer keys */
404 totaluse += numusehash(t, nums, &na); /* count keys in hash part */
405 /* count extra key */
406 na += countint(ek, nums);
407 totaluse++;
408 /* compute new size for array part */
409 asize = computesizes(nums, &na);
410 /* resize the table to new computed sizes */
411 luaH_resize(L, t, asize, totaluse - na);
412}
413
414
415
416/*
417** }=============================================================
418*/
419
420
421Table *luaH_new (lua_State *L) {
422 GCObject *o = luaC_newobj(L, LUA_TTABLE, sizeof(Table));
423 Table *t = gco2t(o);
424 t->metatable = NULL;
425 t->flags = cast_byte(~0);
426 t->array = NULL;
427 t->sizearray = 0;
428 setnodevector(L, t, 0);
429 return t;
430}
431
432
433void luaH_free (lua_State *L, Table *t) {
434 if (!isdummy(t))
435 luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
436 luaM_freearray(L, t->array, t->sizearray);
437 luaM_free(L, t);
438}
439
440
441static Node *getfreepos (Table *t) {
442 if (!isdummy(t)) {
443 while (t->lastfree > t->node) {
444 t->lastfree--;
445 if (ttisnil(gkey(t->lastfree)))
446 return t->lastfree;
447 }
448 }
449 return NULL; /* could not find a free place */
450}
451
452
453
454/*
455** inserts a new key into a hash table; first, check whether key's main
456** position is free. If not, check whether colliding node is in its main
457** position or not: if it is not, move colliding node to an empty place and
458** put new key in its main position; otherwise (colliding node is in its main
459** position), new key goes to an empty position.
460*/
461TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
462 Node *mp;
463 TValue aux;
464 if (ttisnil(key)) luaG_runerror(L, "table index is nil");
465 else if (ttisfloat(key)) {
466 lua_Integer k;
467 if (luaV_tointeger(key, &k, 0)) { /* does index fit in an integer? */
468 setivalue(&aux, k);
469 key = &aux; /* insert it as an integer */
470 }
471 else if (luai_numisnan(fltvalue(key)))
472 luaG_runerror(L, "table index is NaN");
473 }
474 mp = mainposition(t, key);
475 if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */
476 Node *othern;
477 Node *f = getfreepos(t); /* get a free place */
478 if (f == NULL) { /* cannot find a free place? */
479 rehash(L, t, key); /* grow table */
480 /* whatever called 'newkey' takes care of TM cache */
481 return luaH_set(L, t, key); /* insert key into grown table */
482 }
483 lua_assert(!isdummy(t));
484 othern = mainposition(t, gkey(mp));
485 if (othern != mp) { /* is colliding node out of its main position? */
486 /* yes; move colliding node into free position */
487 while (othern + gnext(othern) != mp) /* find previous */
488 othern += gnext(othern);
489 gnext(othern) = cast_int(f - othern); /* rechain to point to 'f' */
490 *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */
491 if (gnext(mp) != 0) {
492 gnext(f) += cast_int(mp - f); /* correct 'next' */
493 gnext(mp) = 0; /* now 'mp' is free */
494 }
495 setnilvalue(gval(mp));
496 }
497 else { /* colliding node is in its own main position */
498 /* new node will go into free position */
499 if (gnext(mp) != 0)
500 gnext(f) = cast_int((mp + gnext(mp)) - f); /* chain new position */
501 else lua_assert(gnext(f) == 0);
502 gnext(mp) = cast_int(f - mp);
503 mp = f;
504 }
505 }
506 setnodekey(L, &mp->i_key, key);
507 luaC_barrierback(L, t, key);
508 lua_assert(ttisnil(gval(mp)));
509 return gval(mp);
510}
511
512
513/*
514** search function for integers
515*/
516const TValue *luaH_getint (Table *t, lua_Integer key) {
517 /* (1 <= key && key <= t->sizearray) */
518 if (l_castS2U(key) - 1 < t->sizearray)
519 return &t->array[key - 1];
520 else {
521 Node *n = hashint(t, key);
522 for (;;) { /* check whether 'key' is somewhere in the chain */
523 if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key)
524 return gval(n); /* that's it */
525 else {
526 int nx = gnext(n);
527 if (nx == 0) break;
528 n += nx;
529 }
530 }
531 return luaO_nilobject;
532 }
533}
534
535
536/*
537** search function for short strings
538*/
539const TValue *luaH_getshortstr (Table *t, TString *key) {
540 Node *n = hashstr(t, key);
541 lua_assert(key->tt == LUA_TSHRSTR);
542 for (;;) { /* check whether 'key' is somewhere in the chain */
543 const TValue *k = gkey(n);
544 if (ttisshrstring(k) && eqshrstr(tsvalue(k), key))
545 return gval(n); /* that's it */
546 else {
547 int nx = gnext(n);
548 if (nx == 0)
549 return luaO_nilobject; /* not found */
550 n += nx;
551 }
552 }
553}
554
555
556/*
557** "Generic" get version. (Not that generic: not valid for integers,
558** which may be in array part, nor for floats with integral values.)
559*/
560static const TValue *getgeneric (Table *t, const TValue *key) {
561 Node *n = mainposition(t, key);
562 for (;;) { /* check whether 'key' is somewhere in the chain */
563 if (luaV_rawequalobj(gkey(n), key))
564 return gval(n); /* that's it */
565 else {
566 int nx = gnext(n);
567 if (nx == 0)
568 return luaO_nilobject; /* not found */
569 n += nx;
570 }
571 }
572}
573
574
575const TValue *luaH_getstr (Table *t, TString *key) {
576 if (key->tt == LUA_TSHRSTR)
577 return luaH_getshortstr(t, key);
578 else { /* for long strings, use generic case */
579 TValue ko;
580 setsvalue(cast(lua_State *, NULL), &ko, key);
581 return getgeneric(t, &ko);
582 }
583}
584
585
586/*
587** main search function
588*/
589const TValue *luaH_get (Table *t, const TValue *key) {
590 switch (ttype(key)) {
591 case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key));
592 case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
593 case LUA_TNIL: return luaO_nilobject;
594 case LUA_TNUMFLT: {
595 lua_Integer k;
596 if (luaV_tointeger(key, &k, 0)) /* index is int? */
597 return luaH_getint(t, k); /* use specialized version */
598 /* else... */
599 } /* FALLTHROUGH */
600 default:
601 return getgeneric(t, key);
602 }
603}
604
605
606/*
607** beware: when using this function you probably need to check a GC
608** barrier and invalidate the TM cache.
609*/
610TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
611 const TValue *p = luaH_get(t, key);
612 if (p != luaO_nilobject)
613 return cast(TValue *, p);
614 else return luaH_newkey(L, t, key);
615}
616
617
618void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
619 const TValue *p = luaH_getint(t, key);
620 TValue *cell;
621 if (p != luaO_nilobject)
622 cell = cast(TValue *, p);
623 else {
624 TValue k;
625 setivalue(&k, key);
626 cell = luaH_newkey(L, t, &k);
627 }
628 setobj2t(L, cell, value);
629}
630
631
632static lua_Unsigned unbound_search (Table *t, lua_Unsigned j) {
633 lua_Unsigned i = j; /* i is zero or a present index */
634 j++;
635 /* find 'i' and 'j' such that i is present and j is not */
636 while (!ttisnil(luaH_getint(t, j))) {
637 i = j;
638 if (j > l_castS2U(LUA_MAXINTEGER) / 2) { /* overflow? */
639 /* table was built with bad purposes: resort to linear search */
640 i = 1;
641 while (!ttisnil(luaH_getint(t, i))) i++;
642 return i - 1;
643 }
644 j *= 2;
645 }
646 /* now do a binary search between them */
647 while (j - i > 1) {
648 lua_Unsigned m = (i+j)/2;
649 if (ttisnil(luaH_getint(t, m))) j = m;
650 else i = m;
651 }
652 return i;
653}
654
655
656/*
657** Try to find a boundary in table 't'. A 'boundary' is an integer index
658** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
659*/
660lua_Unsigned luaH_getn (Table *t) {
661 unsigned int j = t->sizearray;
662 if (j > 0 && ttisnil(&t->array[j - 1])) {
663 /* there is a boundary in the array part: (binary) search for it */
664 unsigned int i = 0;
665 while (j - i > 1) {
666 unsigned int m = (i+j)/2;
667 if (ttisnil(&t->array[m - 1])) j = m;
668 else i = m;
669 }
670 return i;
671 }
672 /* else must find a boundary in hash part */
673 else if (isdummy(t)) /* hash part is empty? */
674 return j; /* that is easy... */
675 else return unbound_search(t, j);
676}
677
678
679
680#if defined(LUA_DEBUG)
681
682Node *luaH_mainposition (const Table *t, const TValue *key) {
683 return mainposition(t, key);
684}
685
686int luaH_isdummy (const Table *t) { return isdummy(t); }
687
688#endif
diff --git a/src/lua-5.3/ltable.h b/src/lua-5.3/ltable.h
new file mode 100644
index 0000000..92db0ac
--- /dev/null
+++ b/src/lua-5.3/ltable.h
@@ -0,0 +1,66 @@
1/*
2** $Id: ltable.h,v 2.23.1.2 2018/05/24 19:39:05 roberto Exp $
3** Lua tables (hash)
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ltable_h
8#define ltable_h
9
10#include "lobject.h"
11
12
13#define gnode(t,i) (&(t)->node[i])
14#define gval(n) (&(n)->i_val)
15#define gnext(n) ((n)->i_key.nk.next)
16
17
18/* 'const' to avoid wrong writings that can mess up field 'next' */
19#define gkey(n) cast(const TValue*, (&(n)->i_key.tvk))
20
21/*
22** writable version of 'gkey'; allows updates to individual fields,
23** but not to the whole (which has incompatible type)
24*/
25#define wgkey(n) (&(n)->i_key.nk)
26
27#define invalidateTMcache(t) ((t)->flags = 0)
28
29
30/* true when 't' is using 'dummynode' as its hash part */
31#define isdummy(t) ((t)->lastfree == NULL)
32
33
34/* allocated size for hash nodes */
35#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t))
36
37
38/* returns the key, given the value of a table entry */
39#define keyfromval(v) \
40 (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
41
42
43LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
44LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
45 TValue *value);
46LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key);
47LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
48LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
49LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);
50LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
51LUAI_FUNC Table *luaH_new (lua_State *L);
52LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
53 unsigned int nhsize);
54LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize);
55LUAI_FUNC void luaH_free (lua_State *L, Table *t);
56LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
57LUAI_FUNC lua_Unsigned luaH_getn (Table *t);
58
59
60#if defined(LUA_DEBUG)
61LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
62LUAI_FUNC int luaH_isdummy (const Table *t);
63#endif
64
65
66#endif
diff --git a/src/lua-5.3/ltablib.c b/src/lua-5.3/ltablib.c
new file mode 100644
index 0000000..c534957
--- /dev/null
+++ b/src/lua-5.3/ltablib.c
@@ -0,0 +1,450 @@
1/*
2** $Id: ltablib.c,v 1.93.1.1 2017/04/19 17:20:42 roberto Exp $
3** Library for Table Manipulation
4** See Copyright Notice in lua.h
5*/
6
7#define ltablib_c
8#define LUA_LIB
9
10#include "lprefix.h"
11
12
13#include <limits.h>
14#include <stddef.h>
15#include <string.h>
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21
22
23/*
24** Operations that an object must define to mimic a table
25** (some functions only need some of them)
26*/
27#define TAB_R 1 /* read */
28#define TAB_W 2 /* write */
29#define TAB_L 4 /* length */
30#define TAB_RW (TAB_R | TAB_W) /* read/write */
31
32
33#define aux_getn(L,n,w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n))
34
35
36static int checkfield (lua_State *L, const char *key, int n) {
37 lua_pushstring(L, key);
38 return (lua_rawget(L, -n) != LUA_TNIL);
39}
40
41
42/*
43** Check that 'arg' either is a table or can behave like one (that is,
44** has a metatable with the required metamethods)
45*/
46static void checktab (lua_State *L, int arg, int what) {
47 if (lua_type(L, arg) != LUA_TTABLE) { /* is it not a table? */
48 int n = 1; /* number of elements to pop */
49 if (lua_getmetatable(L, arg) && /* must have metatable */
50 (!(what & TAB_R) || checkfield(L, "__index", ++n)) &&
51 (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) &&
52 (!(what & TAB_L) || checkfield(L, "__len", ++n))) {
53 lua_pop(L, n); /* pop metatable and tested metamethods */
54 }
55 else
56 luaL_checktype(L, arg, LUA_TTABLE); /* force an error */
57 }
58}
59
60
61#if defined(LUA_COMPAT_MAXN)
62static int maxn (lua_State *L) {
63 lua_Number max = 0;
64 luaL_checktype(L, 1, LUA_TTABLE);
65 lua_pushnil(L); /* first key */
66 while (lua_next(L, 1)) {
67 lua_pop(L, 1); /* remove value */
68 if (lua_type(L, -1) == LUA_TNUMBER) {
69 lua_Number v = lua_tonumber(L, -1);
70 if (v > max) max = v;
71 }
72 }
73 lua_pushnumber(L, max);
74 return 1;
75}
76#endif
77
78
79static int tinsert (lua_State *L) {
80 lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */
81 lua_Integer pos; /* where to insert new element */
82 switch (lua_gettop(L)) {
83 case 2: { /* called with only 2 arguments */
84 pos = e; /* insert new element at the end */
85 break;
86 }
87 case 3: {
88 lua_Integer i;
89 pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */
90 luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds");
91 for (i = e; i > pos; i--) { /* move up elements */
92 lua_geti(L, 1, i - 1);
93 lua_seti(L, 1, i); /* t[i] = t[i - 1] */
94 }
95 break;
96 }
97 default: {
98 return luaL_error(L, "wrong number of arguments to 'insert'");
99 }
100 }
101 lua_seti(L, 1, pos); /* t[pos] = v */
102 return 0;
103}
104
105
106static int tremove (lua_State *L) {
107 lua_Integer size = aux_getn(L, 1, TAB_RW);
108 lua_Integer pos = luaL_optinteger(L, 2, size);
109 if (pos != size) /* validate 'pos' if given */
110 luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds");
111 lua_geti(L, 1, pos); /* result = t[pos] */
112 for ( ; pos < size; pos++) {
113 lua_geti(L, 1, pos + 1);
114 lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */
115 }
116 lua_pushnil(L);
117 lua_seti(L, 1, pos); /* t[pos] = nil */
118 return 1;
119}
120
121
122/*
123** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever
124** possible, copy in increasing order, which is better for rehashing.
125** "possible" means destination after original range, or smaller
126** than origin, or copying to another table.
127*/
128static int tmove (lua_State *L) {
129 lua_Integer f = luaL_checkinteger(L, 2);
130 lua_Integer e = luaL_checkinteger(L, 3);
131 lua_Integer t = luaL_checkinteger(L, 4);
132 int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */
133 checktab(L, 1, TAB_R);
134 checktab(L, tt, TAB_W);
135 if (e >= f) { /* otherwise, nothing to move */
136 lua_Integer n, i;
137 luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3,
138 "too many elements to move");
139 n = e - f + 1; /* number of elements to move */
140 luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
141 "destination wrap around");
142 if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) {
143 for (i = 0; i < n; i++) {
144 lua_geti(L, 1, f + i);
145 lua_seti(L, tt, t + i);
146 }
147 }
148 else {
149 for (i = n - 1; i >= 0; i--) {
150 lua_geti(L, 1, f + i);
151 lua_seti(L, tt, t + i);
152 }
153 }
154 }
155 lua_pushvalue(L, tt); /* return destination table */
156 return 1;
157}
158
159
160static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) {
161 lua_geti(L, 1, i);
162 if (!lua_isstring(L, -1))
163 luaL_error(L, "invalid value (%s) at index %d in table for 'concat'",
164 luaL_typename(L, -1), i);
165 luaL_addvalue(b);
166}
167
168
169static int tconcat (lua_State *L) {
170 luaL_Buffer b;
171 lua_Integer last = aux_getn(L, 1, TAB_R);
172 size_t lsep;
173 const char *sep = luaL_optlstring(L, 2, "", &lsep);
174 lua_Integer i = luaL_optinteger(L, 3, 1);
175 last = luaL_optinteger(L, 4, last);
176 luaL_buffinit(L, &b);
177 for (; i < last; i++) {
178 addfield(L, &b, i);
179 luaL_addlstring(&b, sep, lsep);
180 }
181 if (i == last) /* add last value (if interval was not empty) */
182 addfield(L, &b, i);
183 luaL_pushresult(&b);
184 return 1;
185}
186
187
188/*
189** {======================================================
190** Pack/unpack
191** =======================================================
192*/
193
194static int pack (lua_State *L) {
195 int i;
196 int n = lua_gettop(L); /* number of elements to pack */
197 lua_createtable(L, n, 1); /* create result table */
198 lua_insert(L, 1); /* put it at index 1 */
199 for (i = n; i >= 1; i--) /* assign elements */
200 lua_seti(L, 1, i);
201 lua_pushinteger(L, n);
202 lua_setfield(L, 1, "n"); /* t.n = number of elements */
203 return 1; /* return table */
204}
205
206
207static int unpack (lua_State *L) {
208 lua_Unsigned n;
209 lua_Integer i = luaL_optinteger(L, 2, 1);
210 lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1));
211 if (i > e) return 0; /* empty range */
212 n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */
213 if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n)))
214 return luaL_error(L, "too many results to unpack");
215 for (; i < e; i++) { /* push arg[i..e - 1] (to avoid overflows) */
216 lua_geti(L, 1, i);
217 }
218 lua_geti(L, 1, e); /* push last element */
219 return (int)n;
220}
221
222/* }====================================================== */
223
224
225
226/*
227** {======================================================
228** Quicksort
229** (based on 'Algorithms in MODULA-3', Robert Sedgewick;
230** Addison-Wesley, 1993.)
231** =======================================================
232*/
233
234
235/* type for array indices */
236typedef unsigned int IdxT;
237
238
239/*
240** Produce a "random" 'unsigned int' to randomize pivot choice. This
241** macro is used only when 'sort' detects a big imbalance in the result
242** of a partition. (If you don't want/need this "randomness", ~0 is a
243** good choice.)
244*/
245#if !defined(l_randomizePivot) /* { */
246
247#include <time.h>
248
249/* size of 'e' measured in number of 'unsigned int's */
250#define sof(e) (sizeof(e) / sizeof(unsigned int))
251
252/*
253** Use 'time' and 'clock' as sources of "randomness". Because we don't
254** know the types 'clock_t' and 'time_t', we cannot cast them to
255** anything without risking overflows. A safe way to use their values
256** is to copy them to an array of a known type and use the array values.
257*/
258static unsigned int l_randomizePivot (void) {
259 clock_t c = clock();
260 time_t t = time(NULL);
261 unsigned int buff[sof(c) + sof(t)];
262 unsigned int i, rnd = 0;
263 memcpy(buff, &c, sof(c) * sizeof(unsigned int));
264 memcpy(buff + sof(c), &t, sof(t) * sizeof(unsigned int));
265 for (i = 0; i < sof(buff); i++)
266 rnd += buff[i];
267 return rnd;
268}
269
270#endif /* } */
271
272
273/* arrays larger than 'RANLIMIT' may use randomized pivots */
274#define RANLIMIT 100u
275
276
277static void set2 (lua_State *L, IdxT i, IdxT j) {
278 lua_seti(L, 1, i);
279 lua_seti(L, 1, j);
280}
281
282
283/*
284** Return true iff value at stack index 'a' is less than the value at
285** index 'b' (according to the order of the sort).
286*/
287static int sort_comp (lua_State *L, int a, int b) {
288 if (lua_isnil(L, 2)) /* no function? */
289 return lua_compare(L, a, b, LUA_OPLT); /* a < b */
290 else { /* function */
291 int res;
292 lua_pushvalue(L, 2); /* push function */
293 lua_pushvalue(L, a-1); /* -1 to compensate function */
294 lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */
295 lua_call(L, 2, 1); /* call function */
296 res = lua_toboolean(L, -1); /* get result */
297 lua_pop(L, 1); /* pop result */
298 return res;
299 }
300}
301
302
303/*
304** Does the partition: Pivot P is at the top of the stack.
305** precondition: a[lo] <= P == a[up-1] <= a[up],
306** so it only needs to do the partition from lo + 1 to up - 2.
307** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up]
308** returns 'i'.
309*/
310static IdxT partition (lua_State *L, IdxT lo, IdxT up) {
311 IdxT i = lo; /* will be incremented before first use */
312 IdxT j = up - 1; /* will be decremented before first use */
313 /* loop invariant: a[lo .. i] <= P <= a[j .. up] */
314 for (;;) {
315 /* next loop: repeat ++i while a[i] < P */
316 while (lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) {
317 if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */
318 luaL_error(L, "invalid order function for sorting");
319 lua_pop(L, 1); /* remove a[i] */
320 }
321 /* after the loop, a[i] >= P and a[lo .. i - 1] < P */
322 /* next loop: repeat --j while P < a[j] */
323 while (lua_geti(L, 1, --j), sort_comp(L, -3, -1)) {
324 if (j < i) /* j < i but a[j] > P ?? */
325 luaL_error(L, "invalid order function for sorting");
326 lua_pop(L, 1); /* remove a[j] */
327 }
328 /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */
329 if (j < i) { /* no elements out of place? */
330 /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */
331 lua_pop(L, 1); /* pop a[j] */
332 /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */
333 set2(L, up - 1, i);
334 return i;
335 }
336 /* otherwise, swap a[i] - a[j] to restore invariant and repeat */
337 set2(L, i, j);
338 }
339}
340
341
342/*
343** Choose an element in the middle (2nd-3th quarters) of [lo,up]
344** "randomized" by 'rnd'
345*/
346static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) {
347 IdxT r4 = (up - lo) / 4; /* range/4 */
348 IdxT p = rnd % (r4 * 2) + (lo + r4);
349 lua_assert(lo + r4 <= p && p <= up - r4);
350 return p;
351}
352
353
354/*
355** QuickSort algorithm (recursive function)
356*/
357static void auxsort (lua_State *L, IdxT lo, IdxT up,
358 unsigned int rnd) {
359 while (lo < up) { /* loop for tail recursion */
360 IdxT p; /* Pivot index */
361 IdxT n; /* to be used later */
362 /* sort elements 'lo', 'p', and 'up' */
363 lua_geti(L, 1, lo);
364 lua_geti(L, 1, up);
365 if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */
366 set2(L, lo, up); /* swap a[lo] - a[up] */
367 else
368 lua_pop(L, 2); /* remove both values */
369 if (up - lo == 1) /* only 2 elements? */
370 return; /* already sorted */
371 if (up - lo < RANLIMIT || rnd == 0) /* small interval or no randomize? */
372 p = (lo + up)/2; /* middle element is a good pivot */
373 else /* for larger intervals, it is worth a random pivot */
374 p = choosePivot(lo, up, rnd);
375 lua_geti(L, 1, p);
376 lua_geti(L, 1, lo);
377 if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */
378 set2(L, p, lo); /* swap a[p] - a[lo] */
379 else {
380 lua_pop(L, 1); /* remove a[lo] */
381 lua_geti(L, 1, up);
382 if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */
383 set2(L, p, up); /* swap a[up] - a[p] */
384 else
385 lua_pop(L, 2);
386 }
387 if (up - lo == 2) /* only 3 elements? */
388 return; /* already sorted */
389 lua_geti(L, 1, p); /* get middle element (Pivot) */
390 lua_pushvalue(L, -1); /* push Pivot */
391 lua_geti(L, 1, up - 1); /* push a[up - 1] */
392 set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */
393 p = partition(L, lo, up);
394 /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */
395 if (p - lo < up - p) { /* lower interval is smaller? */
396 auxsort(L, lo, p - 1, rnd); /* call recursively for lower interval */
397 n = p - lo; /* size of smaller interval */
398 lo = p + 1; /* tail call for [p + 1 .. up] (upper interval) */
399 }
400 else {
401 auxsort(L, p + 1, up, rnd); /* call recursively for upper interval */
402 n = up - p; /* size of smaller interval */
403 up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */
404 }
405 if ((up - lo) / 128 > n) /* partition too imbalanced? */
406 rnd = l_randomizePivot(); /* try a new randomization */
407 } /* tail call auxsort(L, lo, up, rnd) */
408}
409
410
411static int sort (lua_State *L) {
412 lua_Integer n = aux_getn(L, 1, TAB_RW);
413 if (n > 1) { /* non-trivial interval? */
414 luaL_argcheck(L, n < INT_MAX, 1, "array too big");
415 if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
416 luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */
417 lua_settop(L, 2); /* make sure there are two arguments */
418 auxsort(L, 1, (IdxT)n, 0);
419 }
420 return 0;
421}
422
423/* }====================================================== */
424
425
426static const luaL_Reg tab_funcs[] = {
427 {"concat", tconcat},
428#if defined(LUA_COMPAT_MAXN)
429 {"maxn", maxn},
430#endif
431 {"insert", tinsert},
432 {"pack", pack},
433 {"unpack", unpack},
434 {"remove", tremove},
435 {"move", tmove},
436 {"sort", sort},
437 {NULL, NULL}
438};
439
440
441LUAMOD_API int luaopen_table (lua_State *L) {
442 luaL_newlib(L, tab_funcs);
443#if defined(LUA_COMPAT_UNPACK)
444 /* _G.unpack = table.unpack */
445 lua_getfield(L, -1, "unpack");
446 lua_setglobal(L, "unpack");
447#endif
448 return 1;
449}
450
diff --git a/src/lua-5.3/ltm.c b/src/lua-5.3/ltm.c
new file mode 100644
index 0000000..0e7c713
--- /dev/null
+++ b/src/lua-5.3/ltm.c
@@ -0,0 +1,165 @@
1/*
2** $Id: ltm.c,v 2.38.1.1 2017/04/19 17:39:34 roberto Exp $
3** Tag methods
4** See Copyright Notice in lua.h
5*/
6
7#define ltm_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <string.h>
14
15#include "lua.h"
16
17#include "ldebug.h"
18#include "ldo.h"
19#include "lobject.h"
20#include "lstate.h"
21#include "lstring.h"
22#include "ltable.h"
23#include "ltm.h"
24#include "lvm.h"
25
26
27static const char udatatypename[] = "userdata";
28
29LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = {
30 "no value",
31 "nil", "boolean", udatatypename, "number",
32 "string", "table", "function", udatatypename, "thread",
33 "proto" /* this last case is used for tests only */
34};
35
36
37void luaT_init (lua_State *L) {
38 static const char *const luaT_eventname[] = { /* ORDER TM */
39 "__index", "__newindex",
40 "__gc", "__mode", "__len", "__eq",
41 "__add", "__sub", "__mul", "__mod", "__pow",
42 "__div", "__idiv",
43 "__band", "__bor", "__bxor", "__shl", "__shr",
44 "__unm", "__bnot", "__lt", "__le",
45 "__concat", "__call"
46 };
47 int i;
48 for (i=0; i<TM_N; i++) {
49 G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
50 luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */
51 }
52}
53
54
55/*
56** function to be used with macro "fasttm": optimized for absence of
57** tag methods
58*/
59const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
60 const TValue *tm = luaH_getshortstr(events, ename);
61 lua_assert(event <= TM_EQ);
62 if (ttisnil(tm)) { /* no tag method? */
63 events->flags |= cast_byte(1u<<event); /* cache this fact */
64 return NULL;
65 }
66 else return tm;
67}
68
69
70const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
71 Table *mt;
72 switch (ttnov(o)) {
73 case LUA_TTABLE:
74 mt = hvalue(o)->metatable;
75 break;
76 case LUA_TUSERDATA:
77 mt = uvalue(o)->metatable;
78 break;
79 default:
80 mt = G(L)->mt[ttnov(o)];
81 }
82 return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject);
83}
84
85
86/*
87** Return the name of the type of an object. For tables and userdata
88** with metatable, use their '__name' metafield, if present.
89*/
90const char *luaT_objtypename (lua_State *L, const TValue *o) {
91 Table *mt;
92 if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
93 (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
94 const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
95 if (ttisstring(name)) /* is '__name' a string? */
96 return getstr(tsvalue(name)); /* use it as type name */
97 }
98 return ttypename(ttnov(o)); /* else use standard type name */
99}
100
101
102void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
103 const TValue *p2, TValue *p3, int hasres) {
104 ptrdiff_t result = savestack(L, p3);
105 StkId func = L->top;
106 setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
107 setobj2s(L, func + 1, p1); /* 1st argument */
108 setobj2s(L, func + 2, p2); /* 2nd argument */
109 L->top += 3;
110 if (!hasres) /* no result? 'p3' is third argument */
111 setobj2s(L, L->top++, p3); /* 3rd argument */
112 /* metamethod may yield only when called from Lua code */
113 if (isLua(L->ci))
114 luaD_call(L, func, hasres);
115 else
116 luaD_callnoyield(L, func, hasres);
117 if (hasres) { /* if has result, move it to its place */
118 p3 = restorestack(L, result);
119 setobjs2s(L, p3, --L->top);
120 }
121}
122
123
124int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
125 StkId res, TMS event) {
126 const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
127 if (ttisnil(tm))
128 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
129 if (ttisnil(tm)) return 0;
130 luaT_callTM(L, tm, p1, p2, res, 1);
131 return 1;
132}
133
134
135void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
136 StkId res, TMS event) {
137 if (!luaT_callbinTM(L, p1, p2, res, event)) {
138 switch (event) {
139 case TM_CONCAT:
140 luaG_concaterror(L, p1, p2);
141 /* call never returns, but to avoid warnings: *//* FALLTHROUGH */
142 case TM_BAND: case TM_BOR: case TM_BXOR:
143 case TM_SHL: case TM_SHR: case TM_BNOT: {
144 lua_Number dummy;
145 if (tonumber(p1, &dummy) && tonumber(p2, &dummy))
146 luaG_tointerror(L, p1, p2);
147 else
148 luaG_opinterror(L, p1, p2, "perform bitwise operation on");
149 }
150 /* calls never return, but to avoid warnings: *//* FALLTHROUGH */
151 default:
152 luaG_opinterror(L, p1, p2, "perform arithmetic on");
153 }
154 }
155}
156
157
158int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
159 TMS event) {
160 if (!luaT_callbinTM(L, p1, p2, L->top, event))
161 return -1; /* no metamethod */
162 else
163 return !l_isfalse(L->top);
164}
165
diff --git a/src/lua-5.3/ltm.h b/src/lua-5.3/ltm.h
new file mode 100644
index 0000000..8170688
--- /dev/null
+++ b/src/lua-5.3/ltm.h
@@ -0,0 +1,76 @@
1/*
2** $Id: ltm.h,v 2.22.1.1 2017/04/19 17:20:42 roberto Exp $
3** Tag methods
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ltm_h
8#define ltm_h
9
10
11#include "lobject.h"
12
13
14/*
15* WARNING: if you change the order of this enumeration,
16* grep "ORDER TM" and "ORDER OP"
17*/
18typedef enum {
19 TM_INDEX,
20 TM_NEWINDEX,
21 TM_GC,
22 TM_MODE,
23 TM_LEN,
24 TM_EQ, /* last tag method with fast access */
25 TM_ADD,
26 TM_SUB,
27 TM_MUL,
28 TM_MOD,
29 TM_POW,
30 TM_DIV,
31 TM_IDIV,
32 TM_BAND,
33 TM_BOR,
34 TM_BXOR,
35 TM_SHL,
36 TM_SHR,
37 TM_UNM,
38 TM_BNOT,
39 TM_LT,
40 TM_LE,
41 TM_CONCAT,
42 TM_CALL,
43 TM_N /* number of elements in the enum */
44} TMS;
45
46
47
48#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
49 ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
50
51#define fasttm(l,et,e) gfasttm(G(l), et, e)
52
53#define ttypename(x) luaT_typenames_[(x) + 1]
54
55LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
56
57
58LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o);
59
60LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
61LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
62 TMS event);
63LUAI_FUNC void luaT_init (lua_State *L);
64
65LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
66 const TValue *p2, TValue *p3, int hasres);
67LUAI_FUNC int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
68 StkId res, TMS event);
69LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
70 StkId res, TMS event);
71LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1,
72 const TValue *p2, TMS event);
73
74
75
76#endif
diff --git a/src/lua-5.3/lua.h b/src/lua-5.3/lua.h
new file mode 100644
index 0000000..c236e36
--- /dev/null
+++ b/src/lua-5.3/lua.h
@@ -0,0 +1,486 @@
1/*
2** $Id: lua.h,v 1.332.1.2 2018/06/13 16:58:17 roberto Exp $
3** Lua - A Scripting Language
4** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
5** See Copyright Notice at the end of this file
6*/
7
8
9#ifndef lua_h
10#define lua_h
11
12#include <stdarg.h>
13#include <stddef.h>
14
15
16#include "luaconf.h"
17
18
19#define LUA_VERSION_MAJOR "5"
20#define LUA_VERSION_MINOR "3"
21#define LUA_VERSION_NUM 503
22#define LUA_VERSION_RELEASE "5"
23
24#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
25#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
26#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2018 Lua.org, PUC-Rio"
27#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
28
29
30/* mark for precompiled code ('<esc>Lua') */
31#define LUA_SIGNATURE "\x1bLua"
32
33/* option for multiple returns in 'lua_pcall' and 'lua_call' */
34#define LUA_MULTRET (-1)
35
36
37/*
38** Pseudo-indices
39** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
40** space after that to help overflow detection)
41*/
42#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000)
43#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
44
45
46/* thread status */
47#define LUA_OK 0
48#define LUA_YIELD 1
49#define LUA_ERRRUN 2
50#define LUA_ERRSYNTAX 3
51#define LUA_ERRMEM 4
52#define LUA_ERRGCMM 5
53#define LUA_ERRERR 6
54
55
56typedef struct lua_State lua_State;
57
58
59/*
60** basic types
61*/
62#define LUA_TNONE (-1)
63
64#define LUA_TNIL 0
65#define LUA_TBOOLEAN 1
66#define LUA_TLIGHTUSERDATA 2
67#define LUA_TNUMBER 3
68#define LUA_TSTRING 4
69#define LUA_TTABLE 5
70#define LUA_TFUNCTION 6
71#define LUA_TUSERDATA 7
72#define LUA_TTHREAD 8
73
74#define LUA_NUMTAGS 9
75
76
77
78/* minimum Lua stack available to a C function */
79#define LUA_MINSTACK 20
80
81
82/* predefined values in the registry */
83#define LUA_RIDX_MAINTHREAD 1
84#define LUA_RIDX_GLOBALS 2
85#define LUA_RIDX_LAST LUA_RIDX_GLOBALS
86
87
88/* type of numbers in Lua */
89typedef LUA_NUMBER lua_Number;
90
91
92/* type for integer functions */
93typedef LUA_INTEGER lua_Integer;
94
95/* unsigned integer type */
96typedef LUA_UNSIGNED lua_Unsigned;
97
98/* type for continuation-function contexts */
99typedef LUA_KCONTEXT lua_KContext;
100
101
102/*
103** Type for C functions registered with Lua
104*/
105typedef int (*lua_CFunction) (lua_State *L);
106
107/*
108** Type for continuation functions
109*/
110typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
111
112
113/*
114** Type for functions that read/write blocks when loading/dumping Lua chunks
115*/
116typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
117
118typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud);
119
120
121/*
122** Type for memory-allocation functions
123*/
124typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
125
126
127
128/*
129** generic extra include file
130*/
131#if defined(LUA_USER_H)
132#include LUA_USER_H
133#endif
134
135
136/*
137** RCS ident string
138*/
139extern const char lua_ident[];
140
141
142/*
143** state manipulation
144*/
145LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
146LUA_API void (lua_close) (lua_State *L);
147LUA_API lua_State *(lua_newthread) (lua_State *L);
148
149LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
150
151
152LUA_API const lua_Number *(lua_version) (lua_State *L);
153
154
155/*
156** basic stack manipulation
157*/
158LUA_API int (lua_absindex) (lua_State *L, int idx);
159LUA_API int (lua_gettop) (lua_State *L);
160LUA_API void (lua_settop) (lua_State *L, int idx);
161LUA_API void (lua_pushvalue) (lua_State *L, int idx);
162LUA_API void (lua_rotate) (lua_State *L, int idx, int n);
163LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx);
164LUA_API int (lua_checkstack) (lua_State *L, int n);
165
166LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
167
168
169/*
170** access functions (stack -> C)
171*/
172
173LUA_API int (lua_isnumber) (lua_State *L, int idx);
174LUA_API int (lua_isstring) (lua_State *L, int idx);
175LUA_API int (lua_iscfunction) (lua_State *L, int idx);
176LUA_API int (lua_isinteger) (lua_State *L, int idx);
177LUA_API int (lua_isuserdata) (lua_State *L, int idx);
178LUA_API int (lua_type) (lua_State *L, int idx);
179LUA_API const char *(lua_typename) (lua_State *L, int tp);
180
181LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum);
182LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum);
183LUA_API int (lua_toboolean) (lua_State *L, int idx);
184LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
185LUA_API size_t (lua_rawlen) (lua_State *L, int idx);
186LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
187LUA_API void *(lua_touserdata) (lua_State *L, int idx);
188LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
189LUA_API const void *(lua_topointer) (lua_State *L, int idx);
190
191
192/*
193** Comparison and arithmetic functions
194*/
195
196#define LUA_OPADD 0 /* ORDER TM, ORDER OP */
197#define LUA_OPSUB 1
198#define LUA_OPMUL 2
199#define LUA_OPMOD 3
200#define LUA_OPPOW 4
201#define LUA_OPDIV 5
202#define LUA_OPIDIV 6
203#define LUA_OPBAND 7
204#define LUA_OPBOR 8
205#define LUA_OPBXOR 9
206#define LUA_OPSHL 10
207#define LUA_OPSHR 11
208#define LUA_OPUNM 12
209#define LUA_OPBNOT 13
210
211LUA_API void (lua_arith) (lua_State *L, int op);
212
213#define LUA_OPEQ 0
214#define LUA_OPLT 1
215#define LUA_OPLE 2
216
217LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
218LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op);
219
220
221/*
222** push functions (C -> stack)
223*/
224LUA_API void (lua_pushnil) (lua_State *L);
225LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
226LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
227LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t len);
228LUA_API const char *(lua_pushstring) (lua_State *L, const char *s);
229LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
230 va_list argp);
231LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
232LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
233LUA_API void (lua_pushboolean) (lua_State *L, int b);
234LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
235LUA_API int (lua_pushthread) (lua_State *L);
236
237
238/*
239** get functions (Lua -> stack)
240*/
241LUA_API int (lua_getglobal) (lua_State *L, const char *name);
242LUA_API int (lua_gettable) (lua_State *L, int idx);
243LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k);
244LUA_API int (lua_geti) (lua_State *L, int idx, lua_Integer n);
245LUA_API int (lua_rawget) (lua_State *L, int idx);
246LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
247LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p);
248
249LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
250LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
251LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
252LUA_API int (lua_getuservalue) (lua_State *L, int idx);
253
254
255/*
256** set functions (stack -> Lua)
257*/
258LUA_API void (lua_setglobal) (lua_State *L, const char *name);
259LUA_API void (lua_settable) (lua_State *L, int idx);
260LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
261LUA_API void (lua_seti) (lua_State *L, int idx, lua_Integer n);
262LUA_API void (lua_rawset) (lua_State *L, int idx);
263LUA_API void (lua_rawseti) (lua_State *L, int idx, lua_Integer n);
264LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p);
265LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
266LUA_API void (lua_setuservalue) (lua_State *L, int idx);
267
268
269/*
270** 'load' and 'call' functions (load and run Lua code)
271*/
272LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults,
273 lua_KContext ctx, lua_KFunction k);
274#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
275
276LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
277 lua_KContext ctx, lua_KFunction k);
278#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL)
279
280LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
281 const char *chunkname, const char *mode);
282
283LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
284
285
286/*
287** coroutine functions
288*/
289LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx,
290 lua_KFunction k);
291LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg);
292LUA_API int (lua_status) (lua_State *L);
293LUA_API int (lua_isyieldable) (lua_State *L);
294
295#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL)
296
297
298/*
299** garbage-collection function and options
300*/
301
302#define LUA_GCSTOP 0
303#define LUA_GCRESTART 1
304#define LUA_GCCOLLECT 2
305#define LUA_GCCOUNT 3
306#define LUA_GCCOUNTB 4
307#define LUA_GCSTEP 5
308#define LUA_GCSETPAUSE 6
309#define LUA_GCSETSTEPMUL 7
310#define LUA_GCISRUNNING 9
311
312LUA_API int (lua_gc) (lua_State *L, int what, int data);
313
314
315/*
316** miscellaneous functions
317*/
318
319LUA_API int (lua_error) (lua_State *L);
320
321LUA_API int (lua_next) (lua_State *L, int idx);
322
323LUA_API void (lua_concat) (lua_State *L, int n);
324LUA_API void (lua_len) (lua_State *L, int idx);
325
326LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s);
327
328LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
329LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
330
331
332
333/*
334** {==============================================================
335** some useful macros
336** ===============================================================
337*/
338
339#define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE))
340
341#define lua_tonumber(L,i) lua_tonumberx(L,(i),NULL)
342#define lua_tointeger(L,i) lua_tointegerx(L,(i),NULL)
343
344#define lua_pop(L,n) lua_settop(L, -(n)-1)
345
346#define lua_newtable(L) lua_createtable(L, 0, 0)
347
348#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
349
350#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
351
352#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
353#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
354#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
355#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
356#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
357#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
358#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
359#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
360
361#define lua_pushliteral(L, s) lua_pushstring(L, "" s)
362
363#define lua_pushglobaltable(L) \
364 ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
365
366#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
367
368
369#define lua_insert(L,idx) lua_rotate(L, (idx), 1)
370
371#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))
372
373#define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1))
374
375/* }============================================================== */
376
377
378/*
379** {==============================================================
380** compatibility macros for unsigned conversions
381** ===============================================================
382*/
383#if defined(LUA_COMPAT_APIINTCASTS)
384
385#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
386#define lua_tounsignedx(L,i,is) ((lua_Unsigned)lua_tointegerx(L,i,is))
387#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL)
388
389#endif
390/* }============================================================== */
391
392/*
393** {======================================================================
394** Debug API
395** =======================================================================
396*/
397
398
399/*
400** Event codes
401*/
402#define LUA_HOOKCALL 0
403#define LUA_HOOKRET 1
404#define LUA_HOOKLINE 2
405#define LUA_HOOKCOUNT 3
406#define LUA_HOOKTAILCALL 4
407
408
409/*
410** Event masks
411*/
412#define LUA_MASKCALL (1 << LUA_HOOKCALL)
413#define LUA_MASKRET (1 << LUA_HOOKRET)
414#define LUA_MASKLINE (1 << LUA_HOOKLINE)
415#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
416
417typedef struct lua_Debug lua_Debug; /* activation record */
418
419
420/* Functions to be called by the debugger in specific events */
421typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
422
423
424LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
425LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
426LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n);
427LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n);
428LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n);
429LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n);
430
431LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n);
432LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1,
433 int fidx2, int n2);
434
435LUA_API void (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
436LUA_API lua_Hook (lua_gethook) (lua_State *L);
437LUA_API int (lua_gethookmask) (lua_State *L);
438LUA_API int (lua_gethookcount) (lua_State *L);
439
440
441struct lua_Debug {
442 int event;
443 const char *name; /* (n) */
444 const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */
445 const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */
446 const char *source; /* (S) */
447 int currentline; /* (l) */
448 int linedefined; /* (S) */
449 int lastlinedefined; /* (S) */
450 unsigned char nups; /* (u) number of upvalues */
451 unsigned char nparams;/* (u) number of parameters */
452 char isvararg; /* (u) */
453 char istailcall; /* (t) */
454 char short_src[LUA_IDSIZE]; /* (S) */
455 /* private part */
456 struct CallInfo *i_ci; /* active function */
457};
458
459/* }====================================================================== */
460
461
462/******************************************************************************
463* Copyright (C) 1994-2018 Lua.org, PUC-Rio.
464*
465* Permission is hereby granted, free of charge, to any person obtaining
466* a copy of this software and associated documentation files (the
467* "Software"), to deal in the Software without restriction, including
468* without limitation the rights to use, copy, modify, merge, publish,
469* distribute, sublicense, and/or sell copies of the Software, and to
470* permit persons to whom the Software is furnished to do so, subject to
471* the following conditions:
472*
473* The above copyright notice and this permission notice shall be
474* included in all copies or substantial portions of the Software.
475*
476* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
477* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
478* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
479* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
480* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
481* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
482* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
483******************************************************************************/
484
485
486#endif
diff --git a/src/lua-5.3/luaconf.h b/src/lua-5.3/luaconf.h
new file mode 100644
index 0000000..9eeeea6
--- /dev/null
+++ b/src/lua-5.3/luaconf.h
@@ -0,0 +1,790 @@
1/*
2** $Id: luaconf.h,v 1.259.1.1 2017/04/19 17:29:57 roberto Exp $
3** Configuration file for Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef luaconf_h
9#define luaconf_h
10
11#include <limits.h>
12#include <stddef.h>
13
14
15/*
16** ===================================================================
17** Search for "@@" to find all configurable definitions.
18** ===================================================================
19*/
20
21
22/*
23** {====================================================================
24** System Configuration: macros to adapt (if needed) Lua to some
25** particular platform, for instance compiling it with 32-bit numbers or
26** restricting it to C89.
27** =====================================================================
28*/
29
30/*
31@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. You
32** can also define LUA_32BITS in the make file, but changing here you
33** ensure that all software connected to Lua will be compiled with the
34** same configuration.
35*/
36/* #define LUA_32BITS */
37
38
39/*
40@@ LUA_USE_C89 controls the use of non-ISO-C89 features.
41** Define it if you want Lua to avoid the use of a few C99 features
42** or Windows-specific features on Windows.
43*/
44/* #define LUA_USE_C89 */
45
46
47/*
48** By default, Lua on Windows use (some) specific Windows features
49*/
50#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE)
51#define LUA_USE_WINDOWS /* enable goodies for regular Windows */
52#endif
53
54
55#if defined(LUA_USE_WINDOWS)
56#define LUA_DL_DLL /* enable support for DLL */
57#define LUA_USE_C89 /* broadly, Windows is C89 */
58#endif
59
60
61#if defined(LUA_USE_LINUX)
62#define LUA_USE_POSIX
63#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
64#define LUA_USE_READLINE /* needs some extra libraries */
65#endif
66
67
68#if defined(LUA_USE_MACOSX)
69#define LUA_USE_POSIX
70#define LUA_USE_DLOPEN /* MacOS does not need -ldl */
71#define LUA_USE_READLINE /* needs an extra library: -lreadline */
72#endif
73
74
75/*
76@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for
77** C89 ('long' and 'double'); Windows always has '__int64', so it does
78** not need to use this case.
79*/
80#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS)
81#define LUA_C89_NUMBERS
82#endif
83
84
85
86/*
87@@ LUAI_BITSINT defines the (minimum) number of bits in an 'int'.
88*/
89/* avoid undefined shifts */
90#if ((INT_MAX >> 15) >> 15) >= 1
91#define LUAI_BITSINT 32
92#else
93/* 'int' always must have at least 16 bits */
94#define LUAI_BITSINT 16
95#endif
96
97
98/*
99@@ LUA_INT_TYPE defines the type for Lua integers.
100@@ LUA_FLOAT_TYPE defines the type for Lua floats.
101** Lua should work fine with any mix of these options (if supported
102** by your C compiler). The usual configurations are 64-bit integers
103** and 'double' (the default), 32-bit integers and 'float' (for
104** restricted platforms), and 'long'/'double' (for C compilers not
105** compliant with C99, which may not have support for 'long long').
106*/
107
108/* predefined options for LUA_INT_TYPE */
109#define LUA_INT_INT 1
110#define LUA_INT_LONG 2
111#define LUA_INT_LONGLONG 3
112
113/* predefined options for LUA_FLOAT_TYPE */
114#define LUA_FLOAT_FLOAT 1
115#define LUA_FLOAT_DOUBLE 2
116#define LUA_FLOAT_LONGDOUBLE 3
117
118#if defined(LUA_32BITS) /* { */
119/*
120** 32-bit integers and 'float'
121*/
122#if LUAI_BITSINT >= 32 /* use 'int' if big enough */
123#define LUA_INT_TYPE LUA_INT_INT
124#else /* otherwise use 'long' */
125#define LUA_INT_TYPE LUA_INT_LONG
126#endif
127#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT
128
129#elif defined(LUA_C89_NUMBERS) /* }{ */
130/*
131** largest types available for C89 ('long' and 'double')
132*/
133#define LUA_INT_TYPE LUA_INT_LONG
134#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
135
136#endif /* } */
137
138
139/*
140** default configuration for 64-bit Lua ('long long' and 'double')
141*/
142#if !defined(LUA_INT_TYPE)
143#define LUA_INT_TYPE LUA_INT_LONGLONG
144#endif
145
146#if !defined(LUA_FLOAT_TYPE)
147#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
148#endif
149
150/* }================================================================== */
151
152
153
154
155/*
156** {==================================================================
157** Configuration for Paths.
158** ===================================================================
159*/
160
161/*
162** LUA_PATH_SEP is the character that separates templates in a path.
163** LUA_PATH_MARK is the string that marks the substitution points in a
164** template.
165** LUA_EXEC_DIR in a Windows path is replaced by the executable's
166** directory.
167*/
168#define LUA_PATH_SEP ";"
169#define LUA_PATH_MARK "?"
170#define LUA_EXEC_DIR "!"
171
172
173/*
174@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
175** Lua libraries.
176@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
177** C libraries.
178** CHANGE them if your machine has a non-conventional directory
179** hierarchy or if you want to install your libraries in
180** non-conventional directories.
181*/
182#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
183#if defined(_WIN32) /* { */
184/*
185** In Windows, any exclamation mark ('!') in the path is replaced by the
186** path of the directory of the executable file of the current process.
187*/
188#define LUA_LDIR "!\\lua\\"
189#define LUA_CDIR "!\\"
190#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\"
191#define LUA_PATH_DEFAULT \
192 LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
193 LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \
194 LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \
195 ".\\?.lua;" ".\\?\\init.lua"
196#define LUA_CPATH_DEFAULT \
197 LUA_CDIR"?.dll;" \
198 LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \
199 LUA_CDIR"loadall.dll;" ".\\?.dll"
200
201#else /* }{ */
202
203#define LUA_ROOT "/usr/local/"
204#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/"
205#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/"
206#define LUA_PATH_DEFAULT \
207 LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
208 LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \
209 "./?.lua;" "./?/init.lua"
210#define LUA_CPATH_DEFAULT \
211 LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
212#endif /* } */
213
214
215/*
216@@ LUA_DIRSEP is the directory separator (for submodules).
217** CHANGE it if your machine does not use "/" as the directory separator
218** and is not Windows. (On Windows Lua automatically uses "\".)
219*/
220#if defined(_WIN32)
221#define LUA_DIRSEP "\\"
222#else
223#define LUA_DIRSEP "/"
224#endif
225
226/* }================================================================== */
227
228
229/*
230** {==================================================================
231** Marks for exported symbols in the C code
232** ===================================================================
233*/
234
235/*
236@@ LUA_API is a mark for all core API functions.
237@@ LUALIB_API is a mark for all auxiliary library functions.
238@@ LUAMOD_API is a mark for all standard library opening functions.
239** CHANGE them if you need to define those functions in some special way.
240** For instance, if you want to create one Windows DLL with the core and
241** the libraries, you may want to use the following definition (define
242** LUA_BUILD_AS_DLL to get it).
243*/
244#if defined(LUA_BUILD_AS_DLL) /* { */
245
246#if defined(LUA_CORE) || defined(LUA_LIB) /* { */
247#define LUA_API __declspec(dllexport)
248#else /* }{ */
249#define LUA_API __declspec(dllimport)
250#endif /* } */
251
252#else /* }{ */
253
254#define LUA_API extern
255
256#endif /* } */
257
258
259/* more often than not the libs go together with the core */
260#define LUALIB_API LUA_API
261#define LUAMOD_API LUALIB_API
262
263
264/*
265@@ LUAI_FUNC is a mark for all extern functions that are not to be
266** exported to outside modules.
267@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables
268** that are not to be exported to outside modules (LUAI_DDEF for
269** definitions and LUAI_DDEC for declarations).
270** CHANGE them if you need to mark them in some special way. Elf/gcc
271** (versions 3.2 and later) mark them as "hidden" to optimize access
272** when Lua is compiled as a shared library. Not all elf targets support
273** this attribute. Unfortunately, gcc does not offer a way to check
274** whether the target offers that support, and those without support
275** give a warning about it. To avoid these warnings, change to the
276** default definition.
277*/
278#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
279 defined(__ELF__) /* { */
280#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
281#else /* }{ */
282#define LUAI_FUNC extern
283#endif /* } */
284
285#define LUAI_DDEC LUAI_FUNC
286#define LUAI_DDEF /* empty */
287
288/* }================================================================== */
289
290
291/*
292** {==================================================================
293** Compatibility with previous versions
294** ===================================================================
295*/
296
297/*
298@@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2.
299@@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1.
300** You can define it to get all options, or change specific options
301** to fit your specific needs.
302*/
303#if defined(LUA_COMPAT_5_2) /* { */
304
305/*
306@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated
307** functions in the mathematical library.
308*/
309#define LUA_COMPAT_MATHLIB
310
311/*
312@@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'.
313*/
314#define LUA_COMPAT_BITLIB
315
316/*
317@@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod.
318*/
319#define LUA_COMPAT_IPAIRS
320
321/*
322@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for
323** manipulating other integer types (lua_pushunsigned, lua_tounsigned,
324** luaL_checkint, luaL_checklong, etc.)
325*/
326#define LUA_COMPAT_APIINTCASTS
327
328#endif /* } */
329
330
331#if defined(LUA_COMPAT_5_1) /* { */
332
333/* Incompatibilities from 5.2 -> 5.3 */
334#define LUA_COMPAT_MATHLIB
335#define LUA_COMPAT_APIINTCASTS
336
337/*
338@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
339** You can replace it with 'table.unpack'.
340*/
341#define LUA_COMPAT_UNPACK
342
343/*
344@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'.
345** You can replace it with 'package.searchers'.
346*/
347#define LUA_COMPAT_LOADERS
348
349/*
350@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall.
351** You can call your C function directly (with light C functions).
352*/
353#define lua_cpcall(L,f,u) \
354 (lua_pushcfunction(L, (f)), \
355 lua_pushlightuserdata(L,(u)), \
356 lua_pcall(L,1,0,0))
357
358
359/*
360@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library.
361** You can rewrite 'log10(x)' as 'log(x, 10)'.
362*/
363#define LUA_COMPAT_LOG10
364
365/*
366@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base
367** library. You can rewrite 'loadstring(s)' as 'load(s)'.
368*/
369#define LUA_COMPAT_LOADSTRING
370
371/*
372@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library.
373*/
374#define LUA_COMPAT_MAXN
375
376/*
377@@ The following macros supply trivial compatibility for some
378** changes in the API. The macros themselves document how to
379** change your code to avoid using them.
380*/
381#define lua_strlen(L,i) lua_rawlen(L, (i))
382
383#define lua_objlen(L,i) lua_rawlen(L, (i))
384
385#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
386#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT)
387
388/*
389@@ LUA_COMPAT_MODULE controls compatibility with previous
390** module functions 'module' (Lua) and 'luaL_register' (C).
391*/
392#define LUA_COMPAT_MODULE
393
394#endif /* } */
395
396
397/*
398@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
399@@ a float mark ('.0').
400** This macro is not on by default even in compatibility mode,
401** because this is not really an incompatibility.
402*/
403/* #define LUA_COMPAT_FLOATSTRING */
404
405/* }================================================================== */
406
407
408
409/*
410** {==================================================================
411** Configuration for Numbers.
412** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
413** satisfy your needs.
414** ===================================================================
415*/
416
417/*
418@@ LUA_NUMBER is the floating-point type used by Lua.
419@@ LUAI_UACNUMBER is the result of a 'default argument promotion'
420@@ over a floating number.
421@@ l_mathlim(x) corrects limit name 'x' to the proper float type
422** by prefixing it with one of FLT/DBL/LDBL.
423@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
424@@ LUA_NUMBER_FMT is the format for writing floats.
425@@ lua_number2str converts a float to a string.
426@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
427@@ l_floor takes the floor of a float.
428@@ lua_str2number converts a decimal numeric string to a number.
429*/
430
431
432/* The following definitions are good for most cases here */
433
434#define l_floor(x) (l_mathop(floor)(x))
435
436#define lua_number2str(s,sz,n) \
437 l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n))
438
439/*
440@@ lua_numbertointeger converts a float number to an integer, or
441** returns 0 if float is not within the range of a lua_Integer.
442** (The range comparisons are tricky because of rounding. The tests
443** here assume a two-complement representation, where MININTEGER always
444** has an exact representation as a float; MAXINTEGER may not have one,
445** and therefore its conversion to float may have an ill-defined value.)
446*/
447#define lua_numbertointeger(n,p) \
448 ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \
449 (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \
450 (*(p) = (LUA_INTEGER)(n), 1))
451
452
453/* now the variable definitions */
454
455#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */
456
457#define LUA_NUMBER float
458
459#define l_mathlim(n) (FLT_##n)
460
461#define LUAI_UACNUMBER double
462
463#define LUA_NUMBER_FRMLEN ""
464#define LUA_NUMBER_FMT "%.7g"
465
466#define l_mathop(op) op##f
467
468#define lua_str2number(s,p) strtof((s), (p))
469
470
471#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */
472
473#define LUA_NUMBER long double
474
475#define l_mathlim(n) (LDBL_##n)
476
477#define LUAI_UACNUMBER long double
478
479#define LUA_NUMBER_FRMLEN "L"
480#define LUA_NUMBER_FMT "%.19Lg"
481
482#define l_mathop(op) op##l
483
484#define lua_str2number(s,p) strtold((s), (p))
485
486#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */
487
488#define LUA_NUMBER double
489
490#define l_mathlim(n) (DBL_##n)
491
492#define LUAI_UACNUMBER double
493
494#define LUA_NUMBER_FRMLEN ""
495#define LUA_NUMBER_FMT "%.14g"
496
497#define l_mathop(op) op
498
499#define lua_str2number(s,p) strtod((s), (p))
500
501#else /* }{ */
502
503#error "numeric float type not defined"
504
505#endif /* } */
506
507
508
509/*
510@@ LUA_INTEGER is the integer type used by Lua.
511**
512@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
513**
514@@ LUAI_UACINT is the result of a 'default argument promotion'
515@@ over a lUA_INTEGER.
516@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
517@@ LUA_INTEGER_FMT is the format for writing integers.
518@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
519@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
520@@ lua_integer2str converts an integer to a string.
521*/
522
523
524/* The following definitions are good for most cases here */
525
526#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d"
527
528#define LUAI_UACINT LUA_INTEGER
529
530#define lua_integer2str(s,sz,n) \
531 l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n))
532
533/*
534** use LUAI_UACINT here to avoid problems with promotions (which
535** can turn a comparison between unsigneds into a signed comparison)
536*/
537#define LUA_UNSIGNED unsigned LUAI_UACINT
538
539
540/* now the variable definitions */
541
542#if LUA_INT_TYPE == LUA_INT_INT /* { int */
543
544#define LUA_INTEGER int
545#define LUA_INTEGER_FRMLEN ""
546
547#define LUA_MAXINTEGER INT_MAX
548#define LUA_MININTEGER INT_MIN
549
550#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */
551
552#define LUA_INTEGER long
553#define LUA_INTEGER_FRMLEN "l"
554
555#define LUA_MAXINTEGER LONG_MAX
556#define LUA_MININTEGER LONG_MIN
557
558#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */
559
560/* use presence of macro LLONG_MAX as proxy for C99 compliance */
561#if defined(LLONG_MAX) /* { */
562/* use ISO C99 stuff */
563
564#define LUA_INTEGER long long
565#define LUA_INTEGER_FRMLEN "ll"
566
567#define LUA_MAXINTEGER LLONG_MAX
568#define LUA_MININTEGER LLONG_MIN
569
570#elif defined(LUA_USE_WINDOWS) /* }{ */
571/* in Windows, can use specific Windows types */
572
573#define LUA_INTEGER __int64
574#define LUA_INTEGER_FRMLEN "I64"
575
576#define LUA_MAXINTEGER _I64_MAX
577#define LUA_MININTEGER _I64_MIN
578
579#else /* }{ */
580
581#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \
582 or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)"
583
584#endif /* } */
585
586#else /* }{ */
587
588#error "numeric integer type not defined"
589
590#endif /* } */
591
592/* }================================================================== */
593
594
595/*
596** {==================================================================
597** Dependencies with C99 and other C details
598** ===================================================================
599*/
600
601/*
602@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89.
603** (All uses in Lua have only one format item.)
604*/
605#if !defined(LUA_USE_C89)
606#define l_sprintf(s,sz,f,i) snprintf(s,sz,f,i)
607#else
608#define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i))
609#endif
610
611
612/*
613@@ lua_strx2number converts an hexadecimal numeric string to a number.
614** In C99, 'strtod' does that conversion. Otherwise, you can
615** leave 'lua_strx2number' undefined and Lua will provide its own
616** implementation.
617*/
618#if !defined(LUA_USE_C89)
619#define lua_strx2number(s,p) lua_str2number(s,p)
620#endif
621
622
623/*
624@@ lua_pointer2str converts a pointer to a readable string in a
625** non-specified way.
626*/
627#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p)
628
629
630/*
631@@ lua_number2strx converts a float to an hexadecimal numeric string.
632** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
633** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
634** provide its own implementation.
635*/
636#if !defined(LUA_USE_C89)
637#define lua_number2strx(L,b,sz,f,n) \
638 ((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n)))
639#endif
640
641
642/*
643** 'strtof' and 'opf' variants for math functions are not valid in
644** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the
645** availability of these variants. ('math.h' is already included in
646** all files that use these macros.)
647*/
648#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF))
649#undef l_mathop /* variants not available */
650#undef lua_str2number
651#define l_mathop(op) (lua_Number)op /* no variant */
652#define lua_str2number(s,p) ((lua_Number)strtod((s), (p)))
653#endif
654
655
656/*
657@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation
658** functions. It must be a numerical type; Lua will use 'intptr_t' if
659** available, otherwise it will use 'ptrdiff_t' (the nearest thing to
660** 'intptr_t' in C89)
661*/
662#define LUA_KCONTEXT ptrdiff_t
663
664#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
665 __STDC_VERSION__ >= 199901L
666#include <stdint.h>
667#if defined(INTPTR_MAX) /* even in C99 this type is optional */
668#undef LUA_KCONTEXT
669#define LUA_KCONTEXT intptr_t
670#endif
671#endif
672
673
674/*
675@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
676** Change that if you do not want to use C locales. (Code using this
677** macro must include header 'locale.h'.)
678*/
679#if !defined(lua_getlocaledecpoint)
680#define lua_getlocaledecpoint() (localeconv()->decimal_point[0])
681#endif
682
683/* }================================================================== */
684
685
686/*
687** {==================================================================
688** Language Variations
689** =====================================================================
690*/
691
692/*
693@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some
694** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from
695** numbers to strings. Define LUA_NOCVTS2N to turn off automatic
696** coercion from strings to numbers.
697*/
698/* #define LUA_NOCVTN2S */
699/* #define LUA_NOCVTS2N */
700
701
702/*
703@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
704** Define it as a help when debugging C code.
705*/
706#if defined(LUA_USE_APICHECK)
707#include <assert.h>
708#define luai_apicheck(l,e) assert(e)
709#endif
710
711/* }================================================================== */
712
713
714/*
715** {==================================================================
716** Macros that affect the API and must be stable (that is, must be the
717** same when you compile Lua and when you compile code that links to
718** Lua). You probably do not want/need to change them.
719** =====================================================================
720*/
721
722/*
723@@ LUAI_MAXSTACK limits the size of the Lua stack.
724** CHANGE it if you need a different limit. This limit is arbitrary;
725** its only purpose is to stop Lua from consuming unlimited stack
726** space (and to reserve some numbers for pseudo-indices).
727*/
728#if LUAI_BITSINT >= 32
729#define LUAI_MAXSTACK 1000000
730#else
731#define LUAI_MAXSTACK 15000
732#endif
733
734
735/*
736@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
737** a Lua state with very fast access.
738** CHANGE it if you need a different size.
739*/
740#define LUA_EXTRASPACE (sizeof(void *))
741
742
743/*
744@@ LUA_IDSIZE gives the maximum size for the description of the source
745@@ of a function in debug information.
746** CHANGE it if you want a different size.
747*/
748#define LUA_IDSIZE 60
749
750
751/*
752@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
753** CHANGE it if it uses too much C-stack space. (For long double,
754** 'string.format("%.99f", -1e4932)' needs 5034 bytes, so a
755** smaller buffer would force a memory allocation for each call to
756** 'string.format'.)
757*/
758#if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE
759#define LUAL_BUFFERSIZE 8192
760#else
761#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
762#endif
763
764/* }================================================================== */
765
766
767/*
768@@ LUA_QL describes how error messages quote program elements.
769** Lua does not use these macros anymore; they are here for
770** compatibility only.
771*/
772#define LUA_QL(x) "'" x "'"
773#define LUA_QS LUA_QL("%s")
774
775
776
777
778/* =================================================================== */
779
780/*
781** Local configuration. You can use this space to add your redefinitions
782** without modifying the main part of the file.
783*/
784
785
786
787
788
789#endif
790
diff --git a/src/lua-5.3/lualib.h b/src/lua-5.3/lualib.h
new file mode 100644
index 0000000..f5304aa
--- /dev/null
+++ b/src/lua-5.3/lualib.h
@@ -0,0 +1,61 @@
1/*
2** $Id: lualib.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
3** Lua standard libraries
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lualib_h
9#define lualib_h
10
11#include "lua.h"
12
13
14/* version suffix for environment variable names */
15#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
16
17
18LUAMOD_API int (luaopen_base) (lua_State *L);
19
20#define LUA_COLIBNAME "coroutine"
21LUAMOD_API int (luaopen_coroutine) (lua_State *L);
22
23#define LUA_TABLIBNAME "table"
24LUAMOD_API int (luaopen_table) (lua_State *L);
25
26#define LUA_IOLIBNAME "io"
27LUAMOD_API int (luaopen_io) (lua_State *L);
28
29#define LUA_OSLIBNAME "os"
30LUAMOD_API int (luaopen_os) (lua_State *L);
31
32#define LUA_STRLIBNAME "string"
33LUAMOD_API int (luaopen_string) (lua_State *L);
34
35#define LUA_UTF8LIBNAME "utf8"
36LUAMOD_API int (luaopen_utf8) (lua_State *L);
37
38#define LUA_BITLIBNAME "bit32"
39LUAMOD_API int (luaopen_bit32) (lua_State *L);
40
41#define LUA_MATHLIBNAME "math"
42LUAMOD_API int (luaopen_math) (lua_State *L);
43
44#define LUA_DBLIBNAME "debug"
45LUAMOD_API int (luaopen_debug) (lua_State *L);
46
47#define LUA_LOADLIBNAME "package"
48LUAMOD_API int (luaopen_package) (lua_State *L);
49
50
51/* open all previous libraries */
52LUALIB_API void (luaL_openlibs) (lua_State *L);
53
54
55
56#if !defined(lua_assert)
57#define lua_assert(x) ((void)0)
58#endif
59
60
61#endif
diff --git a/src/lua-5.3/lundump.c b/src/lua-5.3/lundump.c
new file mode 100644
index 0000000..7a67d75
--- /dev/null
+++ b/src/lua-5.3/lundump.c
@@ -0,0 +1,279 @@
1/*
2** $Id: lundump.c,v 2.44.1.1 2017/04/19 17:20:42 roberto Exp $
3** load precompiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#define lundump_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <string.h>
14
15#include "lua.h"
16
17#include "ldebug.h"
18#include "ldo.h"
19#include "lfunc.h"
20#include "lmem.h"
21#include "lobject.h"
22#include "lstring.h"
23#include "lundump.h"
24#include "lzio.h"
25
26
27#if !defined(luai_verifycode)
28#define luai_verifycode(L,b,f) /* empty */
29#endif
30
31
32typedef struct {
33 lua_State *L;
34 ZIO *Z;
35 const char *name;
36} LoadState;
37
38
39static l_noret error(LoadState *S, const char *why) {
40 luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why);
41 luaD_throw(S->L, LUA_ERRSYNTAX);
42}
43
44
45/*
46** All high-level loads go through LoadVector; you can change it to
47** adapt to the endianness of the input
48*/
49#define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0]))
50
51static void LoadBlock (LoadState *S, void *b, size_t size) {
52 if (luaZ_read(S->Z, b, size) != 0)
53 error(S, "truncated");
54}
55
56
57#define LoadVar(S,x) LoadVector(S,&x,1)
58
59
60static lu_byte LoadByte (LoadState *S) {
61 lu_byte x;
62 LoadVar(S, x);
63 return x;
64}
65
66
67static int LoadInt (LoadState *S) {
68 int x;
69 LoadVar(S, x);
70 return x;
71}
72
73
74static lua_Number LoadNumber (LoadState *S) {
75 lua_Number x;
76 LoadVar(S, x);
77 return x;
78}
79
80
81static lua_Integer LoadInteger (LoadState *S) {
82 lua_Integer x;
83 LoadVar(S, x);
84 return x;
85}
86
87
88static TString *LoadString (LoadState *S) {
89 size_t size = LoadByte(S);
90 if (size == 0xFF)
91 LoadVar(S, size);
92 if (size == 0)
93 return NULL;
94 else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */
95 char buff[LUAI_MAXSHORTLEN];
96 LoadVector(S, buff, size);
97 return luaS_newlstr(S->L, buff, size);
98 }
99 else { /* long string */
100 TString *ts = luaS_createlngstrobj(S->L, size);
101 LoadVector(S, getstr(ts), size); /* load directly in final place */
102 return ts;
103 }
104}
105
106
107static void LoadCode (LoadState *S, Proto *f) {
108 int n = LoadInt(S);
109 f->code = luaM_newvector(S->L, n, Instruction);
110 f->sizecode = n;
111 LoadVector(S, f->code, n);
112}
113
114
115static void LoadFunction(LoadState *S, Proto *f, TString *psource);
116
117
118static void LoadConstants (LoadState *S, Proto *f) {
119 int i;
120 int n = LoadInt(S);
121 f->k = luaM_newvector(S->L, n, TValue);
122 f->sizek = n;
123 for (i = 0; i < n; i++)
124 setnilvalue(&f->k[i]);
125 for (i = 0; i < n; i++) {
126 TValue *o = &f->k[i];
127 int t = LoadByte(S);
128 switch (t) {
129 case LUA_TNIL:
130 setnilvalue(o);
131 break;
132 case LUA_TBOOLEAN:
133 setbvalue(o, LoadByte(S));
134 break;
135 case LUA_TNUMFLT:
136 setfltvalue(o, LoadNumber(S));
137 break;
138 case LUA_TNUMINT:
139 setivalue(o, LoadInteger(S));
140 break;
141 case LUA_TSHRSTR:
142 case LUA_TLNGSTR:
143 setsvalue2n(S->L, o, LoadString(S));
144 break;
145 default:
146 lua_assert(0);
147 }
148 }
149}
150
151
152static void LoadProtos (LoadState *S, Proto *f) {
153 int i;
154 int n = LoadInt(S);
155 f->p = luaM_newvector(S->L, n, Proto *);
156 f->sizep = n;
157 for (i = 0; i < n; i++)
158 f->p[i] = NULL;
159 for (i = 0; i < n; i++) {
160 f->p[i] = luaF_newproto(S->L);
161 LoadFunction(S, f->p[i], f->source);
162 }
163}
164
165
166static void LoadUpvalues (LoadState *S, Proto *f) {
167 int i, n;
168 n = LoadInt(S);
169 f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
170 f->sizeupvalues = n;
171 for (i = 0; i < n; i++)
172 f->upvalues[i].name = NULL;
173 for (i = 0; i < n; i++) {
174 f->upvalues[i].instack = LoadByte(S);
175 f->upvalues[i].idx = LoadByte(S);
176 }
177}
178
179
180static void LoadDebug (LoadState *S, Proto *f) {
181 int i, n;
182 n = LoadInt(S);
183 f->lineinfo = luaM_newvector(S->L, n, int);
184 f->sizelineinfo = n;
185 LoadVector(S, f->lineinfo, n);
186 n = LoadInt(S);
187 f->locvars = luaM_newvector(S->L, n, LocVar);
188 f->sizelocvars = n;
189 for (i = 0; i < n; i++)
190 f->locvars[i].varname = NULL;
191 for (i = 0; i < n; i++) {
192 f->locvars[i].varname = LoadString(S);
193 f->locvars[i].startpc = LoadInt(S);
194 f->locvars[i].endpc = LoadInt(S);
195 }
196 n = LoadInt(S);
197 for (i = 0; i < n; i++)
198 f->upvalues[i].name = LoadString(S);
199}
200
201
202static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
203 f->source = LoadString(S);
204 if (f->source == NULL) /* no source in dump? */
205 f->source = psource; /* reuse parent's source */
206 f->linedefined = LoadInt(S);
207 f->lastlinedefined = LoadInt(S);
208 f->numparams = LoadByte(S);
209 f->is_vararg = LoadByte(S);
210 f->maxstacksize = LoadByte(S);
211 LoadCode(S, f);
212 LoadConstants(S, f);
213 LoadUpvalues(S, f);
214 LoadProtos(S, f);
215 LoadDebug(S, f);
216}
217
218
219static void checkliteral (LoadState *S, const char *s, const char *msg) {
220 char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
221 size_t len = strlen(s);
222 LoadVector(S, buff, len);
223 if (memcmp(s, buff, len) != 0)
224 error(S, msg);
225}
226
227
228static void fchecksize (LoadState *S, size_t size, const char *tname) {
229 if (LoadByte(S) != size)
230 error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname));
231}
232
233
234#define checksize(S,t) fchecksize(S,sizeof(t),#t)
235
236static void checkHeader (LoadState *S) {
237 checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */
238 if (LoadByte(S) != LUAC_VERSION)
239 error(S, "version mismatch in");
240 if (LoadByte(S) != LUAC_FORMAT)
241 error(S, "format mismatch in");
242 checkliteral(S, LUAC_DATA, "corrupted");
243 checksize(S, int);
244 checksize(S, size_t);
245 checksize(S, Instruction);
246 checksize(S, lua_Integer);
247 checksize(S, lua_Number);
248 if (LoadInteger(S) != LUAC_INT)
249 error(S, "endianness mismatch in");
250 if (LoadNumber(S) != LUAC_NUM)
251 error(S, "float format mismatch in");
252}
253
254
255/*
256** load precompiled chunk
257*/
258LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
259 LoadState S;
260 LClosure *cl;
261 if (*name == '@' || *name == '=')
262 S.name = name + 1;
263 else if (*name == LUA_SIGNATURE[0])
264 S.name = "binary string";
265 else
266 S.name = name;
267 S.L = L;
268 S.Z = Z;
269 checkHeader(&S);
270 cl = luaF_newLclosure(L, LoadByte(&S));
271 setclLvalue(L, L->top, cl);
272 luaD_inctop(L);
273 cl->p = luaF_newproto(L);
274 LoadFunction(&S, cl->p, NULL);
275 lua_assert(cl->nupvalues == cl->p->sizeupvalues);
276 luai_verifycode(L, buff, cl->p);
277 return cl;
278}
279
diff --git a/src/lua-5.3/lundump.h b/src/lua-5.3/lundump.h
new file mode 100644
index 0000000..ce492d6
--- /dev/null
+++ b/src/lua-5.3/lundump.h
@@ -0,0 +1,32 @@
1/*
2** $Id: lundump.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
3** load precompiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lundump_h
8#define lundump_h
9
10#include "llimits.h"
11#include "lobject.h"
12#include "lzio.h"
13
14
15/* data to catch conversion errors */
16#define LUAC_DATA "\x19\x93\r\n\x1a\n"
17
18#define LUAC_INT 0x5678
19#define LUAC_NUM cast_num(370.5)
20
21#define MYINT(s) (s[0]-'0')
22#define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR))
23#define LUAC_FORMAT 0 /* this is the official format */
24
25/* load one chunk; from lundump.c */
26LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name);
27
28/* dump one chunk; from ldump.c */
29LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w,
30 void* data, int strip);
31
32#endif
diff --git a/src/lua-5.3/lutf8lib.c b/src/lua-5.3/lutf8lib.c
new file mode 100644
index 0000000..10bd238
--- /dev/null
+++ b/src/lua-5.3/lutf8lib.c
@@ -0,0 +1,256 @@
1/*
2** $Id: lutf8lib.c,v 1.16.1.1 2017/04/19 17:29:57 roberto Exp $
3** Standard library for UTF-8 manipulation
4** See Copyright Notice in lua.h
5*/
6
7#define lutf8lib_c
8#define LUA_LIB
9
10#include "lprefix.h"
11
12
13#include <assert.h>
14#include <limits.h>
15#include <stdlib.h>
16#include <string.h>
17
18#include "lua.h"
19
20#include "lauxlib.h"
21#include "lualib.h"
22
23#define MAXUNICODE 0x10FFFF
24
25#define iscont(p) ((*(p) & 0xC0) == 0x80)
26
27
28/* from strlib */
29/* translate a relative string position: negative means back from end */
30static lua_Integer u_posrelat (lua_Integer pos, size_t len) {
31 if (pos >= 0) return pos;
32 else if (0u - (size_t)pos > len) return 0;
33 else return (lua_Integer)len + pos + 1;
34}
35
36
37/*
38** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid.
39*/
40static const char *utf8_decode (const char *o, int *val) {
41 static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
42 const unsigned char *s = (const unsigned char *)o;
43 unsigned int c = s[0];
44 unsigned int res = 0; /* final result */
45 if (c < 0x80) /* ascii? */
46 res = c;
47 else {
48 int count = 0; /* to count number of continuation bytes */
49 while (c & 0x40) { /* still have continuation bytes? */
50 int cc = s[++count]; /* read next byte */
51 if ((cc & 0xC0) != 0x80) /* not a continuation byte? */
52 return NULL; /* invalid byte sequence */
53 res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */
54 c <<= 1; /* to test next bit */
55 }
56 res |= ((c & 0x7F) << (count * 5)); /* add first byte */
57 if (count > 3 || res > MAXUNICODE || res <= limits[count])
58 return NULL; /* invalid byte sequence */
59 s += count; /* skip continuation bytes read */
60 }
61 if (val) *val = res;
62 return (const char *)s + 1; /* +1 to include first byte */
63}
64
65
66/*
67** utf8len(s [, i [, j]]) --> number of characters that start in the
68** range [i,j], or nil + current position if 's' is not well formed in
69** that interval
70*/
71static int utflen (lua_State *L) {
72 int n = 0;
73 size_t len;
74 const char *s = luaL_checklstring(L, 1, &len);
75 lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len);
76 lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len);
77 luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2,
78 "initial position out of string");
79 luaL_argcheck(L, --posj < (lua_Integer)len, 3,
80 "final position out of string");
81 while (posi <= posj) {
82 const char *s1 = utf8_decode(s + posi, NULL);
83 if (s1 == NULL) { /* conversion error? */
84 lua_pushnil(L); /* return nil ... */
85 lua_pushinteger(L, posi + 1); /* ... and current position */
86 return 2;
87 }
88 posi = s1 - s;
89 n++;
90 }
91 lua_pushinteger(L, n);
92 return 1;
93}
94
95
96/*
97** codepoint(s, [i, [j]]) -> returns codepoints for all characters
98** that start in the range [i,j]
99*/
100static int codepoint (lua_State *L) {
101 size_t len;
102 const char *s = luaL_checklstring(L, 1, &len);
103 lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len);
104 lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len);
105 int n;
106 const char *se;
107 luaL_argcheck(L, posi >= 1, 2, "out of range");
108 luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range");
109 if (posi > pose) return 0; /* empty interval; return no values */
110 if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */
111 return luaL_error(L, "string slice too long");
112 n = (int)(pose - posi) + 1;
113 luaL_checkstack(L, n, "string slice too long");
114 n = 0;
115 se = s + pose;
116 for (s += posi - 1; s < se;) {
117 int code;
118 s = utf8_decode(s, &code);
119 if (s == NULL)
120 return luaL_error(L, "invalid UTF-8 code");
121 lua_pushinteger(L, code);
122 n++;
123 }
124 return n;
125}
126
127
128static void pushutfchar (lua_State *L, int arg) {
129 lua_Integer code = luaL_checkinteger(L, arg);
130 luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range");
131 lua_pushfstring(L, "%U", (long)code);
132}
133
134
135/*
136** utfchar(n1, n2, ...) -> char(n1)..char(n2)...
137*/
138static int utfchar (lua_State *L) {
139 int n = lua_gettop(L); /* number of arguments */
140 if (n == 1) /* optimize common case of single char */
141 pushutfchar(L, 1);
142 else {
143 int i;
144 luaL_Buffer b;
145 luaL_buffinit(L, &b);
146 for (i = 1; i <= n; i++) {
147 pushutfchar(L, i);
148 luaL_addvalue(&b);
149 }
150 luaL_pushresult(&b);
151 }
152 return 1;
153}
154
155
156/*
157** offset(s, n, [i]) -> index where n-th character counting from
158** position 'i' starts; 0 means character at 'i'.
159*/
160static int byteoffset (lua_State *L) {
161 size_t len;
162 const char *s = luaL_checklstring(L, 1, &len);
163 lua_Integer n = luaL_checkinteger(L, 2);
164 lua_Integer posi = (n >= 0) ? 1 : len + 1;
165 posi = u_posrelat(luaL_optinteger(L, 3, posi), len);
166 luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3,
167 "position out of range");
168 if (n == 0) {
169 /* find beginning of current byte sequence */
170 while (posi > 0 && iscont(s + posi)) posi--;
171 }
172 else {
173 if (iscont(s + posi))
174 return luaL_error(L, "initial position is a continuation byte");
175 if (n < 0) {
176 while (n < 0 && posi > 0) { /* move back */
177 do { /* find beginning of previous character */
178 posi--;
179 } while (posi > 0 && iscont(s + posi));
180 n++;
181 }
182 }
183 else {
184 n--; /* do not move for 1st character */
185 while (n > 0 && posi < (lua_Integer)len) {
186 do { /* find beginning of next character */
187 posi++;
188 } while (iscont(s + posi)); /* (cannot pass final '\0') */
189 n--;
190 }
191 }
192 }
193 if (n == 0) /* did it find given character? */
194 lua_pushinteger(L, posi + 1);
195 else /* no such character */
196 lua_pushnil(L);
197 return 1;
198}
199
200
201static int iter_aux (lua_State *L) {
202 size_t len;
203 const char *s = luaL_checklstring(L, 1, &len);
204 lua_Integer n = lua_tointeger(L, 2) - 1;
205 if (n < 0) /* first iteration? */
206 n = 0; /* start from here */
207 else if (n < (lua_Integer)len) {
208 n++; /* skip current byte */
209 while (iscont(s + n)) n++; /* and its continuations */
210 }
211 if (n >= (lua_Integer)len)
212 return 0; /* no more codepoints */
213 else {
214 int code;
215 const char *next = utf8_decode(s + n, &code);
216 if (next == NULL || iscont(next))
217 return luaL_error(L, "invalid UTF-8 code");
218 lua_pushinteger(L, n + 1);
219 lua_pushinteger(L, code);
220 return 2;
221 }
222}
223
224
225static int iter_codes (lua_State *L) {
226 luaL_checkstring(L, 1);
227 lua_pushcfunction(L, iter_aux);
228 lua_pushvalue(L, 1);
229 lua_pushinteger(L, 0);
230 return 3;
231}
232
233
234/* pattern to match a single UTF-8 character */
235#define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
236
237
238static const luaL_Reg funcs[] = {
239 {"offset", byteoffset},
240 {"codepoint", codepoint},
241 {"char", utfchar},
242 {"len", utflen},
243 {"codes", iter_codes},
244 /* placeholders */
245 {"charpattern", NULL},
246 {NULL, NULL}
247};
248
249
250LUAMOD_API int luaopen_utf8 (lua_State *L) {
251 luaL_newlib(L, funcs);
252 lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1);
253 lua_setfield(L, -2, "charpattern");
254 return 1;
255}
256
diff --git a/src/lua-5.3/lvm.c b/src/lua-5.3/lvm.c
new file mode 100644
index 0000000..cc43d87
--- /dev/null
+++ b/src/lua-5.3/lvm.c
@@ -0,0 +1,1322 @@
1/*
2** $Id: lvm.c,v 2.268.1.1 2017/04/19 17:39:34 roberto Exp $
3** Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7#define lvm_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12#include <float.h>
13#include <limits.h>
14#include <math.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18
19#include "lua.h"
20
21#include "ldebug.h"
22#include "ldo.h"
23#include "lfunc.h"
24#include "lgc.h"
25#include "lobject.h"
26#include "lopcodes.h"
27#include "lstate.h"
28#include "lstring.h"
29#include "ltable.h"
30#include "ltm.h"
31#include "lvm.h"
32
33
34/* limit for table tag-method chains (to avoid loops) */
35#define MAXTAGLOOP 2000
36
37
38
39/*
40** 'l_intfitsf' checks whether a given integer can be converted to a
41** float without rounding. Used in comparisons. Left undefined if
42** all integers fit in a float precisely.
43*/
44#if !defined(l_intfitsf)
45
46/* number of bits in the mantissa of a float */
47#define NBM (l_mathlim(MANT_DIG))
48
49/*
50** Check whether some integers may not fit in a float, that is, whether
51** (maxinteger >> NBM) > 0 (that implies (1 << NBM) <= maxinteger).
52** (The shifts are done in parts to avoid shifting by more than the size
53** of an integer. In a worst case, NBM == 113 for long double and
54** sizeof(integer) == 32.)
55*/
56#if ((((LUA_MAXINTEGER >> (NBM / 4)) >> (NBM / 4)) >> (NBM / 4)) \
57 >> (NBM - (3 * (NBM / 4)))) > 0
58
59#define l_intfitsf(i) \
60 (-((lua_Integer)1 << NBM) <= (i) && (i) <= ((lua_Integer)1 << NBM))
61
62#endif
63
64#endif
65
66
67
68/*
69** Try to convert a value to a float. The float case is already handled
70** by the macro 'tonumber'.
71*/
72int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
73 TValue v;
74 if (ttisinteger(obj)) {
75 *n = cast_num(ivalue(obj));
76 return 1;
77 }
78 else if (cvt2num(obj) && /* string convertible to number? */
79 luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
80 *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */
81 return 1;
82 }
83 else
84 return 0; /* conversion failed */
85}
86
87
88/*
89** try to convert a value to an integer, rounding according to 'mode':
90** mode == 0: accepts only integral values
91** mode == 1: takes the floor of the number
92** mode == 2: takes the ceil of the number
93*/
94int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
95 TValue v;
96 again:
97 if (ttisfloat(obj)) {
98 lua_Number n = fltvalue(obj);
99 lua_Number f = l_floor(n);
100 if (n != f) { /* not an integral value? */
101 if (mode == 0) return 0; /* fails if mode demands integral value */
102 else if (mode > 1) /* needs ceil? */
103 f += 1; /* convert floor to ceil (remember: n != f) */
104 }
105 return lua_numbertointeger(f, p);
106 }
107 else if (ttisinteger(obj)) {
108 *p = ivalue(obj);
109 return 1;
110 }
111 else if (cvt2num(obj) &&
112 luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
113 obj = &v;
114 goto again; /* convert result from 'luaO_str2num' to an integer */
115 }
116 return 0; /* conversion failed */
117}
118
119
120/*
121** Try to convert a 'for' limit to an integer, preserving the
122** semantics of the loop.
123** (The following explanation assumes a non-negative step; it is valid
124** for negative steps mutatis mutandis.)
125** If the limit can be converted to an integer, rounding down, that is
126** it.
127** Otherwise, check whether the limit can be converted to a number. If
128** the number is too large, it is OK to set the limit as LUA_MAXINTEGER,
129** which means no limit. If the number is too negative, the loop
130** should not run, because any initial integer value is larger than the
131** limit. So, it sets the limit to LUA_MININTEGER. 'stopnow' corrects
132** the extreme case when the initial value is LUA_MININTEGER, in which
133** case the LUA_MININTEGER limit would still run the loop once.
134*/
135static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
136 int *stopnow) {
137 *stopnow = 0; /* usually, let loops run */
138 if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) { /* not fit in integer? */
139 lua_Number n; /* try to convert to float */
140 if (!tonumber(obj, &n)) /* cannot convert to float? */
141 return 0; /* not a number */
142 if (luai_numlt(0, n)) { /* if true, float is larger than max integer */
143 *p = LUA_MAXINTEGER;
144 if (step < 0) *stopnow = 1;
145 }
146 else { /* float is smaller than min integer */
147 *p = LUA_MININTEGER;
148 if (step >= 0) *stopnow = 1;
149 }
150 }
151 return 1;
152}
153
154
155/*
156** Finish the table access 'val = t[key]'.
157** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
158** t[k] entry (which must be nil).
159*/
160void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
161 const TValue *slot) {
162 int loop; /* counter to avoid infinite loops */
163 const TValue *tm; /* metamethod */
164 for (loop = 0; loop < MAXTAGLOOP; loop++) {
165 if (slot == NULL) { /* 't' is not a table? */
166 lua_assert(!ttistable(t));
167 tm = luaT_gettmbyobj(L, t, TM_INDEX);
168 if (ttisnil(tm))
169 luaG_typeerror(L, t, "index"); /* no metamethod */
170 /* else will try the metamethod */
171 }
172 else { /* 't' is a table */
173 lua_assert(ttisnil(slot));
174 tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */
175 if (tm == NULL) { /* no metamethod? */
176 setnilvalue(val); /* result is nil */
177 return;
178 }
179 /* else will try the metamethod */
180 }
181 if (ttisfunction(tm)) { /* is metamethod a function? */
182 luaT_callTM(L, tm, t, key, val, 1); /* call it */
183 return;
184 }
185 t = tm; /* else try to access 'tm[key]' */
186 if (luaV_fastget(L,t,key,slot,luaH_get)) { /* fast track? */
187 setobj2s(L, val, slot); /* done */
188 return;
189 }
190 /* else repeat (tail call 'luaV_finishget') */
191 }
192 luaG_runerror(L, "'__index' chain too long; possible loop");
193}
194
195
196/*
197** Finish a table assignment 't[key] = val'.
198** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points
199** to the entry 't[key]', or to 'luaO_nilobject' if there is no such
200** entry. (The value at 'slot' must be nil, otherwise 'luaV_fastset'
201** would have done the job.)
202*/
203void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
204 StkId val, const TValue *slot) {
205 int loop; /* counter to avoid infinite loops */
206 for (loop = 0; loop < MAXTAGLOOP; loop++) {
207 const TValue *tm; /* '__newindex' metamethod */
208 if (slot != NULL) { /* is 't' a table? */
209 Table *h = hvalue(t); /* save 't' table */
210 lua_assert(ttisnil(slot)); /* old value must be nil */
211 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
212 if (tm == NULL) { /* no metamethod? */
213 if (slot == luaO_nilobject) /* no previous entry? */
214 slot = luaH_newkey(L, h, key); /* create one */
215 /* no metamethod and (now) there is an entry with given key */
216 setobj2t(L, cast(TValue *, slot), val); /* set its new value */
217 invalidateTMcache(h);
218 luaC_barrierback(L, h, val);
219 return;
220 }
221 /* else will try the metamethod */
222 }
223 else { /* not a table; check metamethod */
224 if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
225 luaG_typeerror(L, t, "index");
226 }
227 /* try the metamethod */
228 if (ttisfunction(tm)) {
229 luaT_callTM(L, tm, t, key, val, 0);
230 return;
231 }
232 t = tm; /* else repeat assignment over 'tm' */
233 if (luaV_fastset(L, t, key, slot, luaH_get, val))
234 return; /* done */
235 /* else loop */
236 }
237 luaG_runerror(L, "'__newindex' chain too long; possible loop");
238}
239
240
241/*
242** Compare two strings 'ls' x 'rs', returning an integer smaller-equal-
243** -larger than zero if 'ls' is smaller-equal-larger than 'rs'.
244** The code is a little tricky because it allows '\0' in the strings
245** and it uses 'strcoll' (to respect locales) for each segments
246** of the strings.
247*/
248static int l_strcmp (const TString *ls, const TString *rs) {
249 const char *l = getstr(ls);
250 size_t ll = tsslen(ls);
251 const char *r = getstr(rs);
252 size_t lr = tsslen(rs);
253 for (;;) { /* for each segment */
254 int temp = strcoll(l, r);
255 if (temp != 0) /* not equal? */
256 return temp; /* done */
257 else { /* strings are equal up to a '\0' */
258 size_t len = strlen(l); /* index of first '\0' in both strings */
259 if (len == lr) /* 'rs' is finished? */
260 return (len == ll) ? 0 : 1; /* check 'ls' */
261 else if (len == ll) /* 'ls' is finished? */
262 return -1; /* 'ls' is smaller than 'rs' ('rs' is not finished) */
263 /* both strings longer than 'len'; go on comparing after the '\0' */
264 len++;
265 l += len; ll -= len; r += len; lr -= len;
266 }
267 }
268}
269
270
271/*
272** Check whether integer 'i' is less than float 'f'. If 'i' has an
273** exact representation as a float ('l_intfitsf'), compare numbers as
274** floats. Otherwise, if 'f' is outside the range for integers, result
275** is trivial. Otherwise, compare them as integers. (When 'i' has no
276** float representation, either 'f' is "far away" from 'i' or 'f' has
277** no precision left for a fractional part; either way, how 'f' is
278** truncated is irrelevant.) When 'f' is NaN, comparisons must result
279** in false.
280*/
281static int LTintfloat (lua_Integer i, lua_Number f) {
282#if defined(l_intfitsf)
283 if (!l_intfitsf(i)) {
284 if (f >= -cast_num(LUA_MININTEGER)) /* -minint == maxint + 1 */
285 return 1; /* f >= maxint + 1 > i */
286 else if (f > cast_num(LUA_MININTEGER)) /* minint < f <= maxint ? */
287 return (i < cast(lua_Integer, f)); /* compare them as integers */
288 else /* f <= minint <= i (or 'f' is NaN) --> not(i < f) */
289 return 0;
290 }
291#endif
292 return luai_numlt(cast_num(i), f); /* compare them as floats */
293}
294
295
296/*
297** Check whether integer 'i' is less than or equal to float 'f'.
298** See comments on previous function.
299*/
300static int LEintfloat (lua_Integer i, lua_Number f) {
301#if defined(l_intfitsf)
302 if (!l_intfitsf(i)) {
303 if (f >= -cast_num(LUA_MININTEGER)) /* -minint == maxint + 1 */
304 return 1; /* f >= maxint + 1 > i */
305 else if (f >= cast_num(LUA_MININTEGER)) /* minint <= f <= maxint ? */
306 return (i <= cast(lua_Integer, f)); /* compare them as integers */
307 else /* f < minint <= i (or 'f' is NaN) --> not(i <= f) */
308 return 0;
309 }
310#endif
311 return luai_numle(cast_num(i), f); /* compare them as floats */
312}
313
314
315/*
316** Return 'l < r', for numbers.
317*/
318static int LTnum (const TValue *l, const TValue *r) {
319 if (ttisinteger(l)) {
320 lua_Integer li = ivalue(l);
321 if (ttisinteger(r))
322 return li < ivalue(r); /* both are integers */
323 else /* 'l' is int and 'r' is float */
324 return LTintfloat(li, fltvalue(r)); /* l < r ? */
325 }
326 else {
327 lua_Number lf = fltvalue(l); /* 'l' must be float */
328 if (ttisfloat(r))
329 return luai_numlt(lf, fltvalue(r)); /* both are float */
330 else if (luai_numisnan(lf)) /* 'r' is int and 'l' is float */
331 return 0; /* NaN < i is always false */
332 else /* without NaN, (l < r) <--> not(r <= l) */
333 return !LEintfloat(ivalue(r), lf); /* not (r <= l) ? */
334 }
335}
336
337
338/*
339** Return 'l <= r', for numbers.
340*/
341static int LEnum (const TValue *l, const TValue *r) {
342 if (ttisinteger(l)) {
343 lua_Integer li = ivalue(l);
344 if (ttisinteger(r))
345 return li <= ivalue(r); /* both are integers */
346 else /* 'l' is int and 'r' is float */
347 return LEintfloat(li, fltvalue(r)); /* l <= r ? */
348 }
349 else {
350 lua_Number lf = fltvalue(l); /* 'l' must be float */
351 if (ttisfloat(r))
352 return luai_numle(lf, fltvalue(r)); /* both are float */
353 else if (luai_numisnan(lf)) /* 'r' is int and 'l' is float */
354 return 0; /* NaN <= i is always false */
355 else /* without NaN, (l <= r) <--> not(r < l) */
356 return !LTintfloat(ivalue(r), lf); /* not (r < l) ? */
357 }
358}
359
360
361/*
362** Main operation less than; return 'l < r'.
363*/
364int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
365 int res;
366 if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */
367 return LTnum(l, r);
368 else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
369 return l_strcmp(tsvalue(l), tsvalue(r)) < 0;
370 else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */
371 luaG_ordererror(L, l, r); /* error */
372 return res;
373}
374
375
376/*
377** Main operation less than or equal to; return 'l <= r'. If it needs
378** a metamethod and there is no '__le', try '__lt', based on
379** l <= r iff !(r < l) (assuming a total order). If the metamethod
380** yields during this substitution, the continuation has to know
381** about it (to negate the result of r<l); bit CIST_LEQ in the call
382** status keeps that information.
383*/
384int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
385 int res;
386 if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */
387 return LEnum(l, r);
388 else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
389 return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
390 else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */
391 return res;
392 else { /* try 'lt': */
393 L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
394 res = luaT_callorderTM(L, r, l, TM_LT);
395 L->ci->callstatus ^= CIST_LEQ; /* clear mark */
396 if (res < 0)
397 luaG_ordererror(L, l, r);
398 return !res; /* result is negated */
399 }
400}
401
402
403/*
404** Main operation for equality of Lua values; return 't1 == t2'.
405** L == NULL means raw equality (no metamethods)
406*/
407int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
408 const TValue *tm;
409 if (ttype(t1) != ttype(t2)) { /* not the same variant? */
410 if (ttnov(t1) != ttnov(t2) || ttnov(t1) != LUA_TNUMBER)
411 return 0; /* only numbers can be equal with different variants */
412 else { /* two numbers with different variants */
413 lua_Integer i1, i2; /* compare them as integers */
414 return (tointeger(t1, &i1) && tointeger(t2, &i2) && i1 == i2);
415 }
416 }
417 /* values have same type and same variant */
418 switch (ttype(t1)) {
419 case LUA_TNIL: return 1;
420 case LUA_TNUMINT: return (ivalue(t1) == ivalue(t2));
421 case LUA_TNUMFLT: return luai_numeq(fltvalue(t1), fltvalue(t2));
422 case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
423 case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
424 case LUA_TLCF: return fvalue(t1) == fvalue(t2);
425 case LUA_TSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2));
426 case LUA_TLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2));
427 case LUA_TUSERDATA: {
428 if (uvalue(t1) == uvalue(t2)) return 1;
429 else if (L == NULL) return 0;
430 tm = fasttm(L, uvalue(t1)->metatable, TM_EQ);
431 if (tm == NULL)
432 tm = fasttm(L, uvalue(t2)->metatable, TM_EQ);
433 break; /* will try TM */
434 }
435 case LUA_TTABLE: {
436 if (hvalue(t1) == hvalue(t2)) return 1;
437 else if (L == NULL) return 0;
438 tm = fasttm(L, hvalue(t1)->metatable, TM_EQ);
439 if (tm == NULL)
440 tm = fasttm(L, hvalue(t2)->metatable, TM_EQ);
441 break; /* will try TM */
442 }
443 default:
444 return gcvalue(t1) == gcvalue(t2);
445 }
446 if (tm == NULL) /* no TM? */
447 return 0; /* objects are different */
448 luaT_callTM(L, tm, t1, t2, L->top, 1); /* call TM */
449 return !l_isfalse(L->top);
450}
451
452
453/* macro used by 'luaV_concat' to ensure that element at 'o' is a string */
454#define tostring(L,o) \
455 (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
456
457#define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0)
458
459/* copy strings in stack from top - n up to top - 1 to buffer */
460static void copy2buff (StkId top, int n, char *buff) {
461 size_t tl = 0; /* size already copied */
462 do {
463 size_t l = vslen(top - n); /* length of string being copied */
464 memcpy(buff + tl, svalue(top - n), l * sizeof(char));
465 tl += l;
466 } while (--n > 0);
467}
468
469
470/*
471** Main operation for concatenation: concat 'total' values in the stack,
472** from 'L->top - total' up to 'L->top - 1'.
473*/
474void luaV_concat (lua_State *L, int total) {
475 lua_assert(total >= 2);
476 do {
477 StkId top = L->top;
478 int n = 2; /* number of elements handled in this pass (at least 2) */
479 if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
480 luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
481 else if (isemptystr(top - 1)) /* second operand is empty? */
482 cast_void(tostring(L, top - 2)); /* result is first operand */
483 else if (isemptystr(top - 2)) { /* first operand is an empty string? */
484 setobjs2s(L, top - 2, top - 1); /* result is second op. */
485 }
486 else {
487 /* at least two non-empty string values; get as many as possible */
488 size_t tl = vslen(top - 1);
489 TString *ts;
490 /* collect total length and number of strings */
491 for (n = 1; n < total && tostring(L, top - n - 1); n++) {
492 size_t l = vslen(top - n - 1);
493 if (l >= (MAX_SIZE/sizeof(char)) - tl)
494 luaG_runerror(L, "string length overflow");
495 tl += l;
496 }
497 if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */
498 char buff[LUAI_MAXSHORTLEN];
499 copy2buff(top, n, buff); /* copy strings to buffer */
500 ts = luaS_newlstr(L, buff, tl);
501 }
502 else { /* long string; copy strings directly to final result */
503 ts = luaS_createlngstrobj(L, tl);
504 copy2buff(top, n, getstr(ts));
505 }
506 setsvalue2s(L, top - n, ts); /* create result */
507 }
508 total -= n-1; /* got 'n' strings to create 1 new */
509 L->top -= n-1; /* popped 'n' strings and pushed one */
510 } while (total > 1); /* repeat until only 1 result left */
511}
512
513
514/*
515** Main operation 'ra' = #rb'.
516*/
517void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
518 const TValue *tm;
519 switch (ttype(rb)) {
520 case LUA_TTABLE: {
521 Table *h = hvalue(rb);
522 tm = fasttm(L, h->metatable, TM_LEN);
523 if (tm) break; /* metamethod? break switch to call it */
524 setivalue(ra, luaH_getn(h)); /* else primitive len */
525 return;
526 }
527 case LUA_TSHRSTR: {
528 setivalue(ra, tsvalue(rb)->shrlen);
529 return;
530 }
531 case LUA_TLNGSTR: {
532 setivalue(ra, tsvalue(rb)->u.lnglen);
533 return;
534 }
535 default: { /* try metamethod */
536 tm = luaT_gettmbyobj(L, rb, TM_LEN);
537 if (ttisnil(tm)) /* no metamethod? */
538 luaG_typeerror(L, rb, "get length of");
539 break;
540 }
541 }
542 luaT_callTM(L, tm, rb, rb, ra, 1);
543}
544
545
546/*
547** Integer division; return 'm // n', that is, floor(m/n).
548** C division truncates its result (rounds towards zero).
549** 'floor(q) == trunc(q)' when 'q >= 0' or when 'q' is integer,
550** otherwise 'floor(q) == trunc(q) - 1'.
551*/
552lua_Integer luaV_div (lua_State *L, lua_Integer m, lua_Integer n) {
553 if (l_castS2U(n) + 1u <= 1u) { /* special cases: -1 or 0 */
554 if (n == 0)
555 luaG_runerror(L, "attempt to divide by zero");
556 return intop(-, 0, m); /* n==-1; avoid overflow with 0x80000...//-1 */
557 }
558 else {
559 lua_Integer q = m / n; /* perform C division */
560 if ((m ^ n) < 0 && m % n != 0) /* 'm/n' would be negative non-integer? */
561 q -= 1; /* correct result for different rounding */
562 return q;
563 }
564}
565
566
567/*
568** Integer modulus; return 'm % n'. (Assume that C '%' with
569** negative operands follows C99 behavior. See previous comment
570** about luaV_div.)
571*/
572lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) {
573 if (l_castS2U(n) + 1u <= 1u) { /* special cases: -1 or 0 */
574 if (n == 0)
575 luaG_runerror(L, "attempt to perform 'n%%0'");
576 return 0; /* m % -1 == 0; avoid overflow with 0x80000...%-1 */
577 }
578 else {
579 lua_Integer r = m % n;
580 if (r != 0 && (m ^ n) < 0) /* 'm/n' would be non-integer negative? */
581 r += n; /* correct result for different rounding */
582 return r;
583 }
584}
585
586
587/* number of bits in an integer */
588#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT)
589
590/*
591** Shift left operation. (Shift right just negates 'y'.)
592*/
593lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
594 if (y < 0) { /* shift right? */
595 if (y <= -NBITS) return 0;
596 else return intop(>>, x, -y);
597 }
598 else { /* shift left */
599 if (y >= NBITS) return 0;
600 else return intop(<<, x, y);
601 }
602}
603
604
605/*
606** check whether cached closure in prototype 'p' may be reused, that is,
607** whether there is a cached closure with the same upvalues needed by
608** new closure to be created.
609*/
610static LClosure *getcached (Proto *p, UpVal **encup, StkId base) {
611 LClosure *c = p->cache;
612 if (c != NULL) { /* is there a cached closure? */
613 int nup = p->sizeupvalues;
614 Upvaldesc *uv = p->upvalues;
615 int i;
616 for (i = 0; i < nup; i++) { /* check whether it has right upvalues */
617 TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v;
618 if (c->upvals[i]->v != v)
619 return NULL; /* wrong upvalue; cannot reuse closure */
620 }
621 }
622 return c; /* return cached closure (or NULL if no cached closure) */
623}
624
625
626/*
627** create a new Lua closure, push it in the stack, and initialize
628** its upvalues. Note that the closure is not cached if prototype is
629** already black (which means that 'cache' was already cleared by the
630** GC).
631*/
632static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
633 StkId ra) {
634 int nup = p->sizeupvalues;
635 Upvaldesc *uv = p->upvalues;
636 int i;
637 LClosure *ncl = luaF_newLclosure(L, nup);
638 ncl->p = p;
639 setclLvalue(L, ra, ncl); /* anchor new closure in stack */
640 for (i = 0; i < nup; i++) { /* fill in its upvalues */
641 if (uv[i].instack) /* upvalue refers to local variable? */
642 ncl->upvals[i] = luaF_findupval(L, base + uv[i].idx);
643 else /* get upvalue from enclosing function */
644 ncl->upvals[i] = encup[uv[i].idx];
645 ncl->upvals[i]->refcount++;
646 /* new closure is white, so we do not need a barrier here */
647 }
648 if (!isblack(p)) /* cache will not break GC invariant? */
649 p->cache = ncl; /* save it on cache for reuse */
650}
651
652
653/*
654** finish execution of an opcode interrupted by an yield
655*/
656void luaV_finishOp (lua_State *L) {
657 CallInfo *ci = L->ci;
658 StkId base = ci->u.l.base;
659 Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */
660 OpCode op = GET_OPCODE(inst);
661 switch (op) { /* finish its execution */
662 case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV:
663 case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR:
664 case OP_MOD: case OP_POW:
665 case OP_UNM: case OP_BNOT: case OP_LEN:
666 case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
667 setobjs2s(L, base + GETARG_A(inst), --L->top);
668 break;
669 }
670 case OP_LE: case OP_LT: case OP_EQ: {
671 int res = !l_isfalse(L->top - 1);
672 L->top--;
673 if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
674 lua_assert(op == OP_LE);
675 ci->callstatus ^= CIST_LEQ; /* clear mark */
676 res = !res; /* negate result */
677 }
678 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
679 if (res != GETARG_A(inst)) /* condition failed? */
680 ci->u.l.savedpc++; /* skip jump instruction */
681 break;
682 }
683 case OP_CONCAT: {
684 StkId top = L->top - 1; /* top when 'luaT_trybinTM' was called */
685 int b = GETARG_B(inst); /* first element to concatenate */
686 int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */
687 setobj2s(L, top - 2, top); /* put TM result in proper position */
688 if (total > 1) { /* are there elements to concat? */
689 L->top = top - 1; /* top is one after last element (at top-2) */
690 luaV_concat(L, total); /* concat them (may yield again) */
691 }
692 /* move final result to final position */
693 setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1);
694 L->top = ci->top; /* restore top */
695 break;
696 }
697 case OP_TFORCALL: {
698 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
699 L->top = ci->top; /* correct top */
700 break;
701 }
702 case OP_CALL: {
703 if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */
704 L->top = ci->top; /* adjust results */
705 break;
706 }
707 case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
708 break;
709 default: lua_assert(0);
710 }
711}
712
713
714
715
716/*
717** {==================================================================
718** Function 'luaV_execute': main interpreter loop
719** ===================================================================
720*/
721
722
723/*
724** some macros for common tasks in 'luaV_execute'
725*/
726
727
728#define RA(i) (base+GETARG_A(i))
729#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
730#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
731#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
732 ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
733#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
734 ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
735
736
737/* execute a jump instruction */
738#define dojump(ci,i,e) \
739 { int a = GETARG_A(i); \
740 if (a != 0) luaF_close(L, ci->u.l.base + a - 1); \
741 ci->u.l.savedpc += GETARG_sBx(i) + e; }
742
743/* for test instructions, execute the jump instruction that follows it */
744#define donextjump(ci) { i = *ci->u.l.savedpc; dojump(ci, i, 1); }
745
746
747#define Protect(x) { {x;}; base = ci->u.l.base; }
748
749#define checkGC(L,c) \
750 { luaC_condGC(L, L->top = (c), /* limit of live values */ \
751 Protect(L->top = ci->top)); /* restore top */ \
752 luai_threadyield(L); }
753
754
755/* fetch an instruction and prepare its execution */
756#define vmfetch() { \
757 i = *(ci->u.l.savedpc++); \
758 if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) \
759 Protect(luaG_traceexec(L)); \
760 ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \
761 lua_assert(base == ci->u.l.base); \
762 lua_assert(base <= L->top && L->top < L->stack + L->stacksize); \
763}
764
765#define vmdispatch(o) switch(o)
766#define vmcase(l) case l:
767#define vmbreak break
768
769
770/*
771** copy of 'luaV_gettable', but protecting the call to potential
772** metamethod (which can reallocate the stack)
773*/
774#define gettableProtected(L,t,k,v) { const TValue *slot; \
775 if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
776 else Protect(luaV_finishget(L,t,k,v,slot)); }
777
778
779/* same for 'luaV_settable' */
780#define settableProtected(L,t,k,v) { const TValue *slot; \
781 if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \
782 Protect(luaV_finishset(L,t,k,v,slot)); }
783
784
785
786void luaV_execute (lua_State *L) {
787 CallInfo *ci = L->ci;
788 LClosure *cl;
789 TValue *k;
790 StkId base;
791 ci->callstatus |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */
792 newframe: /* reentry point when frame changes (call/return) */
793 lua_assert(ci == L->ci);
794 cl = clLvalue(ci->func); /* local reference to function's closure */
795 k = cl->p->k; /* local reference to function's constant table */
796 base = ci->u.l.base; /* local copy of function's base */
797 /* main loop of interpreter */
798 for (;;) {
799 Instruction i;
800 StkId ra;
801 vmfetch();
802 vmdispatch (GET_OPCODE(i)) {
803 vmcase(OP_MOVE) {
804 setobjs2s(L, ra, RB(i));
805 vmbreak;
806 }
807 vmcase(OP_LOADK) {
808 TValue *rb = k + GETARG_Bx(i);
809 setobj2s(L, ra, rb);
810 vmbreak;
811 }
812 vmcase(OP_LOADKX) {
813 TValue *rb;
814 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
815 rb = k + GETARG_Ax(*ci->u.l.savedpc++);
816 setobj2s(L, ra, rb);
817 vmbreak;
818 }
819 vmcase(OP_LOADBOOL) {
820 setbvalue(ra, GETARG_B(i));
821 if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */
822 vmbreak;
823 }
824 vmcase(OP_LOADNIL) {
825 int b = GETARG_B(i);
826 do {
827 setnilvalue(ra++);
828 } while (b--);
829 vmbreak;
830 }
831 vmcase(OP_GETUPVAL) {
832 int b = GETARG_B(i);
833 setobj2s(L, ra, cl->upvals[b]->v);
834 vmbreak;
835 }
836 vmcase(OP_GETTABUP) {
837 TValue *upval = cl->upvals[GETARG_B(i)]->v;
838 TValue *rc = RKC(i);
839 gettableProtected(L, upval, rc, ra);
840 vmbreak;
841 }
842 vmcase(OP_GETTABLE) {
843 StkId rb = RB(i);
844 TValue *rc = RKC(i);
845 gettableProtected(L, rb, rc, ra);
846 vmbreak;
847 }
848 vmcase(OP_SETTABUP) {
849 TValue *upval = cl->upvals[GETARG_A(i)]->v;
850 TValue *rb = RKB(i);
851 TValue *rc = RKC(i);
852 settableProtected(L, upval, rb, rc);
853 vmbreak;
854 }
855 vmcase(OP_SETUPVAL) {
856 UpVal *uv = cl->upvals[GETARG_B(i)];
857 setobj(L, uv->v, ra);
858 luaC_upvalbarrier(L, uv);
859 vmbreak;
860 }
861 vmcase(OP_SETTABLE) {
862 TValue *rb = RKB(i);
863 TValue *rc = RKC(i);
864 settableProtected(L, ra, rb, rc);
865 vmbreak;
866 }
867 vmcase(OP_NEWTABLE) {
868 int b = GETARG_B(i);
869 int c = GETARG_C(i);
870 Table *t = luaH_new(L);
871 sethvalue(L, ra, t);
872 if (b != 0 || c != 0)
873 luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c));
874 checkGC(L, ra + 1);
875 vmbreak;
876 }
877 vmcase(OP_SELF) {
878 const TValue *aux;
879 StkId rb = RB(i);
880 TValue *rc = RKC(i);
881 TString *key = tsvalue(rc); /* key must be a string */
882 setobjs2s(L, ra + 1, rb);
883 if (luaV_fastget(L, rb, key, aux, luaH_getstr)) {
884 setobj2s(L, ra, aux);
885 }
886 else Protect(luaV_finishget(L, rb, rc, ra, aux));
887 vmbreak;
888 }
889 vmcase(OP_ADD) {
890 TValue *rb = RKB(i);
891 TValue *rc = RKC(i);
892 lua_Number nb; lua_Number nc;
893 if (ttisinteger(rb) && ttisinteger(rc)) {
894 lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
895 setivalue(ra, intop(+, ib, ic));
896 }
897 else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
898 setfltvalue(ra, luai_numadd(L, nb, nc));
899 }
900 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); }
901 vmbreak;
902 }
903 vmcase(OP_SUB) {
904 TValue *rb = RKB(i);
905 TValue *rc = RKC(i);
906 lua_Number nb; lua_Number nc;
907 if (ttisinteger(rb) && ttisinteger(rc)) {
908 lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
909 setivalue(ra, intop(-, ib, ic));
910 }
911 else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
912 setfltvalue(ra, luai_numsub(L, nb, nc));
913 }
914 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SUB)); }
915 vmbreak;
916 }
917 vmcase(OP_MUL) {
918 TValue *rb = RKB(i);
919 TValue *rc = RKC(i);
920 lua_Number nb; lua_Number nc;
921 if (ttisinteger(rb) && ttisinteger(rc)) {
922 lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
923 setivalue(ra, intop(*, ib, ic));
924 }
925 else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
926 setfltvalue(ra, luai_nummul(L, nb, nc));
927 }
928 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MUL)); }
929 vmbreak;
930 }
931 vmcase(OP_DIV) { /* float division (always with floats) */
932 TValue *rb = RKB(i);
933 TValue *rc = RKC(i);
934 lua_Number nb; lua_Number nc;
935 if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
936 setfltvalue(ra, luai_numdiv(L, nb, nc));
937 }
938 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_DIV)); }
939 vmbreak;
940 }
941 vmcase(OP_BAND) {
942 TValue *rb = RKB(i);
943 TValue *rc = RKC(i);
944 lua_Integer ib; lua_Integer ic;
945 if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
946 setivalue(ra, intop(&, ib, ic));
947 }
948 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); }
949 vmbreak;
950 }
951 vmcase(OP_BOR) {
952 TValue *rb = RKB(i);
953 TValue *rc = RKC(i);
954 lua_Integer ib; lua_Integer ic;
955 if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
956 setivalue(ra, intop(|, ib, ic));
957 }
958 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); }
959 vmbreak;
960 }
961 vmcase(OP_BXOR) {
962 TValue *rb = RKB(i);
963 TValue *rc = RKC(i);
964 lua_Integer ib; lua_Integer ic;
965 if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
966 setivalue(ra, intop(^, ib, ic));
967 }
968 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); }
969 vmbreak;
970 }
971 vmcase(OP_SHL) {
972 TValue *rb = RKB(i);
973 TValue *rc = RKC(i);
974 lua_Integer ib; lua_Integer ic;
975 if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
976 setivalue(ra, luaV_shiftl(ib, ic));
977 }
978 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); }
979 vmbreak;
980 }
981 vmcase(OP_SHR) {
982 TValue *rb = RKB(i);
983 TValue *rc = RKC(i);
984 lua_Integer ib; lua_Integer ic;
985 if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
986 setivalue(ra, luaV_shiftl(ib, -ic));
987 }
988 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); }
989 vmbreak;
990 }
991 vmcase(OP_MOD) {
992 TValue *rb = RKB(i);
993 TValue *rc = RKC(i);
994 lua_Number nb; lua_Number nc;
995 if (ttisinteger(rb) && ttisinteger(rc)) {
996 lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
997 setivalue(ra, luaV_mod(L, ib, ic));
998 }
999 else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
1000 lua_Number m;
1001 luai_nummod(L, nb, nc, m);
1002 setfltvalue(ra, m);
1003 }
1004 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MOD)); }
1005 vmbreak;
1006 }
1007 vmcase(OP_IDIV) { /* floor division */
1008 TValue *rb = RKB(i);
1009 TValue *rc = RKC(i);
1010 lua_Number nb; lua_Number nc;
1011 if (ttisinteger(rb) && ttisinteger(rc)) {
1012 lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
1013 setivalue(ra, luaV_div(L, ib, ic));
1014 }
1015 else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
1016 setfltvalue(ra, luai_numidiv(L, nb, nc));
1017 }
1018 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); }
1019 vmbreak;
1020 }
1021 vmcase(OP_POW) {
1022 TValue *rb = RKB(i);
1023 TValue *rc = RKC(i);
1024 lua_Number nb; lua_Number nc;
1025 if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
1026 setfltvalue(ra, luai_numpow(L, nb, nc));
1027 }
1028 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_POW)); }
1029 vmbreak;
1030 }
1031 vmcase(OP_UNM) {
1032 TValue *rb = RB(i);
1033 lua_Number nb;
1034 if (ttisinteger(rb)) {
1035 lua_Integer ib = ivalue(rb);
1036 setivalue(ra, intop(-, 0, ib));
1037 }
1038 else if (tonumber(rb, &nb)) {
1039 setfltvalue(ra, luai_numunm(L, nb));
1040 }
1041 else {
1042 Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM));
1043 }
1044 vmbreak;
1045 }
1046 vmcase(OP_BNOT) {
1047 TValue *rb = RB(i);
1048 lua_Integer ib;
1049 if (tointeger(rb, &ib)) {
1050 setivalue(ra, intop(^, ~l_castS2U(0), ib));
1051 }
1052 else {
1053 Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT));
1054 }
1055 vmbreak;
1056 }
1057 vmcase(OP_NOT) {
1058 TValue *rb = RB(i);
1059 int res = l_isfalse(rb); /* next assignment may change this value */
1060 setbvalue(ra, res);
1061 vmbreak;
1062 }
1063 vmcase(OP_LEN) {
1064 Protect(luaV_objlen(L, ra, RB(i)));
1065 vmbreak;
1066 }
1067 vmcase(OP_CONCAT) {
1068 int b = GETARG_B(i);
1069 int c = GETARG_C(i);
1070 StkId rb;
1071 L->top = base + c + 1; /* mark the end of concat operands */
1072 Protect(luaV_concat(L, c - b + 1));
1073 ra = RA(i); /* 'luaV_concat' may invoke TMs and move the stack */
1074 rb = base + b;
1075 setobjs2s(L, ra, rb);
1076 checkGC(L, (ra >= rb ? ra + 1 : rb));
1077 L->top = ci->top; /* restore top */
1078 vmbreak;
1079 }
1080 vmcase(OP_JMP) {
1081 dojump(ci, i, 0);
1082 vmbreak;
1083 }
1084 vmcase(OP_EQ) {
1085 TValue *rb = RKB(i);
1086 TValue *rc = RKC(i);
1087 Protect(
1088 if (luaV_equalobj(L, rb, rc) != GETARG_A(i))
1089 ci->u.l.savedpc++;
1090 else
1091 donextjump(ci);
1092 )
1093 vmbreak;
1094 }
1095 vmcase(OP_LT) {
1096 Protect(
1097 if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i))
1098 ci->u.l.savedpc++;
1099 else
1100 donextjump(ci);
1101 )
1102 vmbreak;
1103 }
1104 vmcase(OP_LE) {
1105 Protect(
1106 if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i))
1107 ci->u.l.savedpc++;
1108 else
1109 donextjump(ci);
1110 )
1111 vmbreak;
1112 }
1113 vmcase(OP_TEST) {
1114 if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra))
1115 ci->u.l.savedpc++;
1116 else
1117 donextjump(ci);
1118 vmbreak;
1119 }
1120 vmcase(OP_TESTSET) {
1121 TValue *rb = RB(i);
1122 if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb))
1123 ci->u.l.savedpc++;
1124 else {
1125 setobjs2s(L, ra, rb);
1126 donextjump(ci);
1127 }
1128 vmbreak;
1129 }
1130 vmcase(OP_CALL) {
1131 int b = GETARG_B(i);
1132 int nresults = GETARG_C(i) - 1;
1133 if (b != 0) L->top = ra+b; /* else previous instruction set top */
1134 if (luaD_precall(L, ra, nresults)) { /* C function? */
1135 if (nresults >= 0)
1136 L->top = ci->top; /* adjust results */
1137 Protect((void)0); /* update 'base' */
1138 }
1139 else { /* Lua function */
1140 ci = L->ci;
1141 goto newframe; /* restart luaV_execute over new Lua function */
1142 }
1143 vmbreak;
1144 }
1145 vmcase(OP_TAILCALL) {
1146 int b = GETARG_B(i);
1147 if (b != 0) L->top = ra+b; /* else previous instruction set top */
1148 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
1149 if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */
1150 Protect((void)0); /* update 'base' */
1151 }
1152 else {
1153 /* tail call: put called frame (n) in place of caller one (o) */
1154 CallInfo *nci = L->ci; /* called frame */
1155 CallInfo *oci = nci->previous; /* caller frame */
1156 StkId nfunc = nci->func; /* called function */
1157 StkId ofunc = oci->func; /* caller function */
1158 /* last stack slot filled by 'precall' */
1159 StkId lim = nci->u.l.base + getproto(nfunc)->numparams;
1160 int aux;
1161 /* close all upvalues from previous call */
1162 if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base);
1163 /* move new frame into old one */
1164 for (aux = 0; nfunc + aux < lim; aux++)
1165 setobjs2s(L, ofunc + aux, nfunc + aux);
1166 oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */
1167 oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */
1168 oci->u.l.savedpc = nci->u.l.savedpc;
1169 oci->callstatus |= CIST_TAIL; /* function was tail called */
1170 ci = L->ci = oci; /* remove new frame */
1171 lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize);
1172 goto newframe; /* restart luaV_execute over new Lua function */
1173 }
1174 vmbreak;
1175 }
1176 vmcase(OP_RETURN) {
1177 int b = GETARG_B(i);
1178 if (cl->p->sizep > 0) luaF_close(L, base);
1179 b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
1180 if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */
1181 return; /* external invocation: return */
1182 else { /* invocation via reentry: continue execution */
1183 ci = L->ci;
1184 if (b) L->top = ci->top;
1185 lua_assert(isLua(ci));
1186 lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
1187 goto newframe; /* restart luaV_execute over new Lua function */
1188 }
1189 }
1190 vmcase(OP_FORLOOP) {
1191 if (ttisinteger(ra)) { /* integer loop? */
1192 lua_Integer step = ivalue(ra + 2);
1193 lua_Integer idx = intop(+, ivalue(ra), step); /* increment index */
1194 lua_Integer limit = ivalue(ra + 1);
1195 if ((0 < step) ? (idx <= limit) : (limit <= idx)) {
1196 ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
1197 chgivalue(ra, idx); /* update internal index... */
1198 setivalue(ra + 3, idx); /* ...and external index */
1199 }
1200 }
1201 else { /* floating loop */
1202 lua_Number step = fltvalue(ra + 2);
1203 lua_Number idx = luai_numadd(L, fltvalue(ra), step); /* inc. index */
1204 lua_Number limit = fltvalue(ra + 1);
1205 if (luai_numlt(0, step) ? luai_numle(idx, limit)
1206 : luai_numle(limit, idx)) {
1207 ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
1208 chgfltvalue(ra, idx); /* update internal index... */
1209 setfltvalue(ra + 3, idx); /* ...and external index */
1210 }
1211 }
1212 vmbreak;
1213 }
1214 vmcase(OP_FORPREP) {
1215 TValue *init = ra;
1216 TValue *plimit = ra + 1;
1217 TValue *pstep = ra + 2;
1218 lua_Integer ilimit;
1219 int stopnow;
1220 if (ttisinteger(init) && ttisinteger(pstep) &&
1221 forlimit(plimit, &ilimit, ivalue(pstep), &stopnow)) {
1222 /* all values are integer */
1223 lua_Integer initv = (stopnow ? 0 : ivalue(init));
1224 setivalue(plimit, ilimit);
1225 setivalue(init, intop(-, initv, ivalue(pstep)));
1226 }
1227 else { /* try making all values floats */
1228 lua_Number ninit; lua_Number nlimit; lua_Number nstep;
1229 if (!tonumber(plimit, &nlimit))
1230 luaG_runerror(L, "'for' limit must be a number");
1231 setfltvalue(plimit, nlimit);
1232 if (!tonumber(pstep, &nstep))
1233 luaG_runerror(L, "'for' step must be a number");
1234 setfltvalue(pstep, nstep);
1235 if (!tonumber(init, &ninit))
1236 luaG_runerror(L, "'for' initial value must be a number");
1237 setfltvalue(init, luai_numsub(L, ninit, nstep));
1238 }
1239 ci->u.l.savedpc += GETARG_sBx(i);
1240 vmbreak;
1241 }
1242 vmcase(OP_TFORCALL) {
1243 StkId cb = ra + 3; /* call base */
1244 setobjs2s(L, cb+2, ra+2);
1245 setobjs2s(L, cb+1, ra+1);
1246 setobjs2s(L, cb, ra);
1247 L->top = cb + 3; /* func. + 2 args (state and index) */
1248 Protect(luaD_call(L, cb, GETARG_C(i)));
1249 L->top = ci->top;
1250 i = *(ci->u.l.savedpc++); /* go to next instruction */
1251 ra = RA(i);
1252 lua_assert(GET_OPCODE(i) == OP_TFORLOOP);
1253 goto l_tforloop;
1254 }
1255 vmcase(OP_TFORLOOP) {
1256 l_tforloop:
1257 if (!ttisnil(ra + 1)) { /* continue loop? */
1258 setobjs2s(L, ra, ra + 1); /* save control variable */
1259 ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
1260 }
1261 vmbreak;
1262 }
1263 vmcase(OP_SETLIST) {
1264 int n = GETARG_B(i);
1265 int c = GETARG_C(i);
1266 unsigned int last;
1267 Table *h;
1268 if (n == 0) n = cast_int(L->top - ra) - 1;
1269 if (c == 0) {
1270 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
1271 c = GETARG_Ax(*ci->u.l.savedpc++);
1272 }
1273 h = hvalue(ra);
1274 last = ((c-1)*LFIELDS_PER_FLUSH) + n;
1275 if (last > h->sizearray) /* needs more space? */
1276 luaH_resizearray(L, h, last); /* preallocate it at once */
1277 for (; n > 0; n--) {
1278 TValue *val = ra+n;
1279 luaH_setint(L, h, last--, val);
1280 luaC_barrierback(L, h, val);
1281 }
1282 L->top = ci->top; /* correct top (in case of previous open call) */
1283 vmbreak;
1284 }
1285 vmcase(OP_CLOSURE) {
1286 Proto *p = cl->p->p[GETARG_Bx(i)];
1287 LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */
1288 if (ncl == NULL) /* no match? */
1289 pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
1290 else
1291 setclLvalue(L, ra, ncl); /* push cashed closure */
1292 checkGC(L, ra + 1);
1293 vmbreak;
1294 }
1295 vmcase(OP_VARARG) {
1296 int b = GETARG_B(i) - 1; /* required results */
1297 int j;
1298 int n = cast_int(base - ci->func) - cl->p->numparams - 1;
1299 if (n < 0) /* less arguments than parameters? */
1300 n = 0; /* no vararg arguments */
1301 if (b < 0) { /* B == 0? */
1302 b = n; /* get all var. arguments */
1303 Protect(luaD_checkstack(L, n));
1304 ra = RA(i); /* previous call may change the stack */
1305 L->top = ra + n;
1306 }
1307 for (j = 0; j < b && j < n; j++)
1308 setobjs2s(L, ra + j, base - n + j);
1309 for (; j < b; j++) /* complete required results with nil */
1310 setnilvalue(ra + j);
1311 vmbreak;
1312 }
1313 vmcase(OP_EXTRAARG) {
1314 lua_assert(0);
1315 vmbreak;
1316 }
1317 }
1318 }
1319}
1320
1321/* }================================================================== */
1322
diff --git a/src/lua-5.3/lvm.h b/src/lua-5.3/lvm.h
new file mode 100644
index 0000000..a8f954f
--- /dev/null
+++ b/src/lua-5.3/lvm.h
@@ -0,0 +1,113 @@
1/*
2** $Id: lvm.h,v 2.41.1.1 2017/04/19 17:20:42 roberto Exp $
3** Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lvm_h
8#define lvm_h
9
10
11#include "ldo.h"
12#include "lobject.h"
13#include "ltm.h"
14
15
16#if !defined(LUA_NOCVTN2S)
17#define cvt2str(o) ttisnumber(o)
18#else
19#define cvt2str(o) 0 /* no conversion from numbers to strings */
20#endif
21
22
23#if !defined(LUA_NOCVTS2N)
24#define cvt2num(o) ttisstring(o)
25#else
26#define cvt2num(o) 0 /* no conversion from strings to numbers */
27#endif
28
29
30/*
31** You can define LUA_FLOORN2I if you want to convert floats to integers
32** by flooring them (instead of raising an error if they are not
33** integral values)
34*/
35#if !defined(LUA_FLOORN2I)
36#define LUA_FLOORN2I 0
37#endif
38
39
40#define tonumber(o,n) \
41 (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
42
43#define tointeger(o,i) \
44 (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I))
45
46#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))
47
48#define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2)
49
50
51/*
52** fast track for 'gettable': if 't' is a table and 't[k]' is not nil,
53** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise,
54** return 0 (meaning it will have to check metamethod) with 'slot'
55** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise).
56** 'f' is the raw get function to use.
57*/
58#define luaV_fastget(L,t,k,slot,f) \
59 (!ttistable(t) \
60 ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
61 : (slot = f(hvalue(t), k), /* else, do raw access */ \
62 !ttisnil(slot))) /* result not nil? */
63
64/*
65** standard implementation for 'gettable'
66*/
67#define luaV_gettable(L,t,k,v) { const TValue *slot; \
68 if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
69 else luaV_finishget(L,t,k,v,slot); }
70
71
72/*
73** Fast track for set table. If 't' is a table and 't[k]' is not nil,
74** call GC barrier, do a raw 't[k]=v', and return true; otherwise,
75** return false with 'slot' equal to NULL (if 't' is not a table) or
76** 'nil'. (This is needed by 'luaV_finishget'.) Note that, if the macro
77** returns true, there is no need to 'invalidateTMcache', because the
78** call is not creating a new entry.
79*/
80#define luaV_fastset(L,t,k,slot,f,v) \
81 (!ttistable(t) \
82 ? (slot = NULL, 0) \
83 : (slot = f(hvalue(t), k), \
84 ttisnil(slot) ? 0 \
85 : (luaC_barrierback(L, hvalue(t), v), \
86 setobj2t(L, cast(TValue *,slot), v), \
87 1)))
88
89
90#define luaV_settable(L,t,k,v) { const TValue *slot; \
91 if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \
92 luaV_finishset(L,t,k,v,slot); }
93
94
95
96LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
97LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
98LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
99LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
100LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
101LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
102 StkId val, const TValue *slot);
103LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
104 StkId val, const TValue *slot);
105LUAI_FUNC void luaV_finishOp (lua_State *L);
106LUAI_FUNC void luaV_execute (lua_State *L);
107LUAI_FUNC void luaV_concat (lua_State *L, int total);
108LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);
109LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);
110LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y);
111LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
112
113#endif
diff --git a/src/lua-5.3/lzio.c b/src/lua-5.3/lzio.c
new file mode 100644
index 0000000..6f79094
--- /dev/null
+++ b/src/lua-5.3/lzio.c
@@ -0,0 +1,68 @@
1/*
2** $Id: lzio.c,v 1.37.1.1 2017/04/19 17:20:42 roberto Exp $
3** Buffered streams
4** See Copyright Notice in lua.h
5*/
6
7#define lzio_c
8#define LUA_CORE
9
10#include "lprefix.h"
11
12
13#include <string.h>
14
15#include "lua.h"
16
17#include "llimits.h"
18#include "lmem.h"
19#include "lstate.h"
20#include "lzio.h"
21
22
23int luaZ_fill (ZIO *z) {
24 size_t size;
25 lua_State *L = z->L;
26 const char *buff;
27 lua_unlock(L);
28 buff = z->reader(L, z->data, &size);
29 lua_lock(L);
30 if (buff == NULL || size == 0)
31 return EOZ;
32 z->n = size - 1; /* discount char being returned */
33 z->p = buff;
34 return cast_uchar(*(z->p++));
35}
36
37
38void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
39 z->L = L;
40 z->reader = reader;
41 z->data = data;
42 z->n = 0;
43 z->p = NULL;
44}
45
46
47/* --------------------------------------------------------------- read --- */
48size_t luaZ_read (ZIO *z, void *b, size_t n) {
49 while (n) {
50 size_t m;
51 if (z->n == 0) { /* no bytes in buffer? */
52 if (luaZ_fill(z) == EOZ) /* try to read more */
53 return n; /* no more input; return number of missing bytes */
54 else {
55 z->n++; /* luaZ_fill consumed first byte; put it back */
56 z->p--;
57 }
58 }
59 m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
60 memcpy(b, z->p, m);
61 z->n -= m;
62 z->p += m;
63 b = (char *)b + m;
64 n -= m;
65 }
66 return 0;
67}
68
diff --git a/src/lua-5.3/lzio.h b/src/lua-5.3/lzio.h
new file mode 100644
index 0000000..d897870
--- /dev/null
+++ b/src/lua-5.3/lzio.h
@@ -0,0 +1,66 @@
1/*
2** $Id: lzio.h,v 1.31.1.1 2017/04/19 17:20:42 roberto Exp $
3** Buffered streams
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lzio_h
9#define lzio_h
10
11#include "lua.h"
12
13#include "lmem.h"
14
15
16#define EOZ (-1) /* end of stream */
17
18typedef struct Zio ZIO;
19
20#define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z))
21
22
23typedef struct Mbuffer {
24 char *buffer;
25 size_t n;
26 size_t buffsize;
27} Mbuffer;
28
29#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
30
31#define luaZ_buffer(buff) ((buff)->buffer)
32#define luaZ_sizebuffer(buff) ((buff)->buffsize)
33#define luaZ_bufflen(buff) ((buff)->n)
34
35#define luaZ_buffremove(buff,i) ((buff)->n -= (i))
36#define luaZ_resetbuffer(buff) ((buff)->n = 0)
37
38
39#define luaZ_resizebuffer(L, buff, size) \
40 ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \
41 (buff)->buffsize, size), \
42 (buff)->buffsize = size)
43
44#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
45
46
47LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
48 void *data);
49LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */
50
51
52
53/* --------- Private Part ------------------ */
54
55struct Zio {
56 size_t n; /* bytes still unread */
57 const char *p; /* current position in buffer */
58 lua_Reader reader; /* reader function */
59 void *data; /* additional data */
60 lua_State *L; /* Lua state (for reader) */
61};
62
63
64LUAI_FUNC int luaZ_fill (ZIO *z);
65
66#endif
diff --git a/src/lua-5.3/makefile b/src/lua-5.3/makefile
new file mode 100644
index 0000000..0835d9c
--- /dev/null
+++ b/src/lua-5.3/makefile
@@ -0,0 +1,177 @@
1# makefile for building Lua
2# see INSTALL for installation instructions
3# see ../Makefile and luaconf.h for further customization
4
5# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
6
7# Warnings valid for both C and C++
8CWARNSCPP= \
9 -pedantic \
10 -Wextra \
11 -Wshadow \
12 -Wsign-compare \
13 -Wundef \
14 -Wwrite-strings \
15 -Wredundant-decls \
16 -Wdisabled-optimization \
17 -Waggregate-return \
18 -Wdouble-promotion \
19 #-Wno-aggressive-loop-optimizations # not accepted by clang \
20 #-Wlogical-op # not accepted by clang \
21 # the next warnings generate too much noise, so they are disabled
22 # -Wconversion -Wno-sign-conversion \
23 # -Wsign-conversion \
24 # -Wconversion \
25 # -Wstrict-overflow=2 \
26 # -Wformat=2 \
27 # -Wcast-qual \
28
29# The next warnings are neither valid nor needed for C++
30CWARNSC= -Wdeclaration-after-statement \
31 -Wmissing-prototypes \
32 -Wnested-externs \
33 -Wstrict-prototypes \
34 -Wc++-compat \
35 -Wold-style-definition \
36
37
38CWARNS= $(CWARNSCPP) $(CWARNSC)
39
40# -mtune=native -fomit-frame-pointer
41# -fno-stack-protector
42LOCAL = $(TESTS) $(CWARNS) -g
43
44
45
46# enable Linux goodies
47MYCFLAGS= $(LOCAL) -std=c99 -DLUA_COMPAT_5_2 -DLUA_COMPAT_5_1
48MYLDFLAGS= $(LOCAL) -Wl
49MYLIBS= -ldl -lreadline
50
51
52CC= gcc
53CFLAGS= -Wall -O2 $(MYCFLAGS)
54AR= ar rc
55RANLIB= ranlib
56RM= rm -f
57
58
59
60# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
61
62
63LIBS = -lm
64
65CORE_T= liblua.a
66CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
67 lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
68 ltm.o lundump.o lvm.o lzio.o
69AUX_O= lauxlib.o
70LIB_O= lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o \
71 lutf8lib.o lbitlib.o loadlib.o lcorolib.o linit.o
72
73ALL_T= $(CORE_T)
74ALL_O= $(CORE_O) $(AUX_O) $(LIB_O)
75ALL_A= $(CORE_T)
76
77all: $(ALL_T)
78
79o: $(ALL_O)
80
81a: $(ALL_A)
82
83$(CORE_T): $(CORE_O) $(AUX_O) $(LIB_O)
84 $(AR) $@ $?
85 $(RANLIB) $@
86
87$(LUA_T): $(LUA_O) $(CORE_T)
88 $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(CORE_T) $(LIBS) $(MYLIBS) $(DL)
89
90$(LUAC_T): $(LUAC_O) $(CORE_T)
91 $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(CORE_T) $(LIBS) $(MYLIBS)
92
93clean:
94 $(RM) $(ALL_T) $(ALL_O)
95
96depend:
97 @$(CC) $(CFLAGS) -MM *.c
98
99echo:
100 @echo "CC = $(CC)"
101 @echo "CFLAGS = $(CFLAGS)"
102 @echo "AR = $(AR)"
103 @echo "RANLIB = $(RANLIB)"
104 @echo "RM = $(RM)"
105 @echo "MYCFLAGS = $(MYCFLAGS)"
106 @echo "MYLDFLAGS = $(MYLDFLAGS)"
107 @echo "MYLIBS = $(MYLIBS)"
108 @echo "DL = $(DL)"
109
110$(ALL_O): makefile
111
112# DO NOT EDIT
113# automatically made with 'gcc -MM l*.c'
114
115lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
116 lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
117 ltable.h lundump.h lvm.h
118lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h
119lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
120lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
121lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
122 llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
123 ldo.h lgc.h lstring.h ltable.h lvm.h
124lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
125lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h
126ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
127ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
128 lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \
129 ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h
130ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
131 lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \
132 lparser.h lstring.h ltable.h lundump.h lvm.h
133ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \
134 ltm.h lzio.h lmem.h lundump.h
135lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \
136 lgc.h lstate.h ltm.h lzio.h lmem.h
137lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
138 llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
139linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h
140liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
141llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \
142 lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \
143 lstring.h ltable.h
144lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
145lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
146 llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h
147loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
148lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \
149 ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \
150 lvm.h
151lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h
152loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
153lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
154 llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
155 ldo.h lfunc.h lstring.h lgc.h ltable.h
156lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
157 lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
158 lstring.h ltable.h
159lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
160 lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
161lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
162ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
163 llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
164ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
165ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
166 llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
167lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
168 lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
169 lundump.h
170lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
171lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
172 llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
173 ltable.h lvm.h
174lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
175 lobject.h ltm.h lzio.h
176
177# (end of Makefile)
diff --git a/src/moonp.cpp b/src/moonp.cpp
index a4bc1fa..a43f11c 100644
--- a/src/moonp.cpp
+++ b/src/moonp.cpp
@@ -10,10 +10,25 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
10#include <fstream> 10#include <fstream>
11#include <chrono> 11#include <chrono>
12#include <future> 12#include <future>
13#include <sstream>
14#include <tuple>
13#include "MoonP/moon_compiler.h" 15#include "MoonP/moon_compiler.h"
14#include "MoonP/moon_parser.h" 16#include "MoonP/moon_parser.h"
15 17
16#ifndef LIBMOONP 18extern "C" {
19
20#include "lua.h"
21#include "lauxlib.h"
22#include "lualib.h"
23int luaopen_moonp(lua_State* L);
24
25} // extern "C"
26
27static void openlibs(void* state) {
28 lua_State* L = static_cast<lua_State*>(state);
29 luaL_openlibs(L);
30 luaopen_moonp(L);
31}
17 32
18int main(int narg, const char** args) { 33int main(int narg, const char** args) {
19 const char* help = 34 const char* help =
@@ -81,7 +96,7 @@ int main(int narg, const char** args) {
81 if (!targetPath.empty() && targetPath.back() != '/' && targetPath.back() != '\\') { 96 if (!targetPath.empty() && targetPath.back() != '/' && targetPath.back() != '\\') {
82 targetPath.append("/"); 97 targetPath.append("/");
83 } 98 }
84 std::list<std::future<int>> results; 99 std::list<std::future<std::pair<int,std::string>>> results;
85 for (const auto& file : files) { 100 for (const auto& file : files) {
86 auto task = std::async(std::launch::async, [=]() { 101 auto task = std::async(std::launch::async, [=]() {
87 std::ifstream input(file, std::ios::in); 102 std::ifstream input(file, std::ios::in);
@@ -91,7 +106,7 @@ int main(int narg, const char** args) {
91 std::istreambuf_iterator<char>()); 106 std::istreambuf_iterator<char>());
92 if (dumpCompileTime) { 107 if (dumpCompileTime) {
93 auto start = std::chrono::high_resolution_clock::now(); 108 auto start = std::chrono::high_resolution_clock::now();
94 auto result = MoonP::MoonCompiler{}.compile(s, config); 109 auto result = MoonP::MoonCompiler{nullptr,openlibs}.compile(s, config);
95 auto end = std::chrono::high_resolution_clock::now(); 110 auto end = std::chrono::high_resolution_clock::now();
96 if (!std::get<0>(result).empty()) { 111 if (!std::get<0>(result).empty()) {
97 std::chrono::duration<double> diff = end - start; 112 std::chrono::duration<double> diff = end - start;
@@ -99,21 +114,22 @@ int main(int narg, const char** args) {
99 MoonP::MoonParser{}.parse<MoonP::File_t>(s); 114 MoonP::MoonParser{}.parse<MoonP::File_t>(s);
100 end = std::chrono::high_resolution_clock::now(); 115 end = std::chrono::high_resolution_clock::now();
101 std::chrono::duration<double> parseDiff = end - start; 116 std::chrono::duration<double> parseDiff = end - start;
102 std::cout << file << " \n"; 117 std::ostringstream buf;
103 std::cout << "Parse time: " << std::setprecision(5) << parseDiff.count() * 1000 << " ms\n"; 118 buf << file << " \n";
104 std::cout << "Compile time: " << std::setprecision(5) << (diff.count() - parseDiff.count()) * 1000 << " ms\n\n"; 119 buf << "Parse time: " << std::setprecision(5) << parseDiff.count() * 1000 << " ms\n";
105 return 0; 120 buf << "Compile time: " << std::setprecision(5) << (diff.count() - parseDiff.count()) * 1000 << " ms\n\n";
121 return std::pair{0, buf.str()};
106 } else { 122 } else {
107 std::cout << "Fail to compile: " << file << ".\n"; 123 std::ostringstream buf;
108 std::cout << std::get<1>(result) << '\n'; 124 buf << "Fail to compile: " << file << ".\n";
109 return 1; 125 buf << std::get<1>(result) << '\n';
126 return std::pair{1, buf.str()};
110 } 127 }
111 } 128 }
112 auto result = MoonP::MoonCompiler{}.compile(s, config); 129 auto result = MoonP::MoonCompiler{nullptr,openlibs}.compile(s, config);
113 if (!std::get<0>(result).empty()) { 130 if (!std::get<0>(result).empty()) {
114 if (!writeToFile) { 131 if (!writeToFile) {
115 std::cout << std::get<0>(result) << '\n'; 132 return std::pair{1, std::get<0>(result) + '\n'};
116 return 1;
117 } else { 133 } else {
118 std::string targetFile; 134 std::string targetFile;
119 if (resultFile.empty()) { 135 if (resultFile.empty()) {
@@ -139,149 +155,33 @@ int main(int narg, const char** args) {
139 if (output) { 155 if (output) {
140 const auto& codes = std::get<0>(result); 156 const auto& codes = std::get<0>(result);
141 output.write(codes.c_str(), codes.size()); 157 output.write(codes.c_str(), codes.size());
142 std::cout << "Built " << file << '\n'; 158 return std::pair{0, std::string("Built ") + file + '\n'};
143 return 0;
144 } else { 159 } else {
145 std::cout << "Fail to write file: " << targetFile << ".\n"; 160 return std::pair{1, std::string("Fail to write file: ") + targetFile + '\n'};
146 return 1;
147 } 161 }
148 } 162 }
149 } else { 163 } else {
150 std::cout << "Fail to compile: " << file << ".\n"; 164 std::ostringstream buf;
151 std::cout << std::get<1>(result) << '\n'; 165 buf << "Fail to compile: " << file << ".\n";
152 return 1; 166 buf << std::get<1>(result) << '\n';
167 return std::pair{1, buf.str()};
153 } 168 }
154 } else { 169 } else {
155 std::cout << "Fail to read file: " << file << ".\n"; 170 return std::pair{1, std::string("Fail to read file: ") + file + ".\n"};
156 return 1;
157 } 171 }
158 }); 172 });
159 results.push_back(std::move(task)); 173 results.push_back(std::move(task));
160 } 174 }
161 int ret = 0; 175 int ret = 0;
176 std::string msg;
162 for (auto& result : results) { 177 for (auto& result : results) {
163 int val = result.get(); 178 int val = 0;
179 std::tie(val, msg) = result.get();
164 if (val != 0) { 180 if (val != 0) {
165 ret = val; 181 ret = val;
166 } 182 }
183 std::cout << msg;
167 } 184 }
168 return ret; 185 return ret;
169} 186}
170 187
171#else
172
173extern "C" {
174
175#include "lua.h"
176#include "lauxlib.h"
177
178static const char moonplusCodes[] =
179#include "Moonscript.h"
180
181static int init_moonplus(lua_State* L) {
182 MoonP::MoonConfig config;
183 std::string s(moonplusCodes, sizeof(moonplusCodes) / sizeof(moonplusCodes[0]) - 1);
184 std::string codes, err;
185 MoonP::GlobalVars globals;
186 std::tie(codes, err, globals) = MoonP::MoonCompiler{}.compile(s, config);
187 if (codes.empty()) {
188 luaL_error(L, "fail to compile moonplus init codes.\n%s", err.c_str());
189 }
190 int top = lua_gettop(L);
191 if (luaL_loadbuffer(L, codes.c_str(), codes.size(), "=(moonplus)") != 0) {
192 luaL_error(L, "fail to init moonplus module.");
193 } else {
194 lua_call(L, 0, 0);
195 }
196 lua_settop(L, top);
197 return 0;
198}
199
200static const char stpCodes[] =
201#include "StackTracePlus.h"
202
203static int init_stacktraceplus(lua_State* L) {
204 if (luaL_loadbuffer(L, stpCodes, sizeof(stpCodes) / sizeof(stpCodes[0]) - 1, "=(stacktraceplus)") != 0) {
205 luaL_error(L, "fail to init stacktraceplus module.");
206 } else {
207 lua_call(L, 0, 1);
208 }
209 return 1;
210}
211
212static int moontolua(lua_State* L) {
213 size_t size = 0;
214 const char* input = luaL_checklstring(L, 1, &size);
215 MoonP::MoonConfig config;
216 if (lua_gettop(L) == 2) {
217 lua_pushstring(L, "lint_global");
218 lua_gettable(L, -2);
219 if (!lua_isnil(L, -1)) {
220 config.lintGlobalVariable = lua_toboolean(L, -1) != 0;
221 }
222 lua_pop(L, 1);
223 lua_pushstring(L, "implicit_return_root");
224 lua_gettable(L, -2);
225 if (!lua_isnil(L, -1)) {
226 config.implicitReturnRoot = lua_toboolean(L, -1) != 0;
227 }
228 lua_pop(L, 1);
229 lua_pushstring(L, "reserve_line_number");
230 lua_gettable(L, -2);
231 if (!lua_isnil(L, -1)) {
232 config.reserveLineNumber = lua_toboolean(L, -1) != 0;
233 }
234 lua_pop(L, 1);
235 }
236 std::string s(input, size);
237 std::string codes, err;
238 MoonP::GlobalVars globals;
239 std::tie(codes, err, globals) = MoonP::MoonCompiler{}.compile(s, config);
240 if (codes.empty()) {
241 lua_pushnil(L);
242 } else {
243 lua_pushlstring(L, codes.c_str(), codes.size());
244 }
245 if (err.empty()) {
246 lua_pushnil(L);
247 } else {
248 lua_pushlstring(L, err.c_str(), err.size());
249 }
250 if (globals) {
251 lua_createtable(L, static_cast<int>(globals->size()), 0);
252 int i = 1;
253 for (const auto& var : *globals) {
254 lua_createtable(L, 3, 0);
255 lua_pushlstring(L, var.name.c_str(), var.name.size());
256 lua_rawseti(L, -2, 1);
257 lua_pushinteger(L, var.line);
258 lua_rawseti(L, -2, 2);
259 lua_pushinteger(L, var.col);
260 lua_rawseti(L, -2, 3);
261 lua_rawseti(L, -2, i);
262 i++;
263 }
264 } else {
265 lua_pushnil(L);
266 }
267 return 3;
268}
269
270int luaopen_moonp(lua_State* L) {
271 lua_getglobal(L, "package");
272 lua_getfield(L, -1, "loaded");
273 lua_createtable(L, 0, 0);
274 lua_pushcfunction(L, moontolua);
275 lua_setfield(L, -2, "to_lua");
276 lua_pushcfunction(L, init_stacktraceplus);
277 lua_setfield(L, -2, "load_stacktraceplus");
278 lua_setfield(L, -2, "moonp");
279 lua_pop(L, 2);
280 init_moonplus(L);
281 return 0;
282}
283
284} // extern "C"
285
286#endif // LIBMOONP
287