Commit 68bdf7fa authored by Megax's avatar Megax Committed by Megax
Browse files

* Autotols alapú Makefile generátor hozzáadva a kódhoz.

parent 856d0cb7
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
using System.Threading; using System.Threading;
using LuaInterface; using LuaInterface;
/* /*
* Application to run Lua scripts that can use LuaInterface * Application to run Lua scripts that can use LuaInterface
* from the console * from the console
* *
* Author: Fabio Mascarenhas * Author: Fabio Mascarenhas
* Version: 1.0 * Version: 1.0
*/ */
namespace LuaRunner namespace LuaRunner
{ {
public class LuaNetRunner public class LuaNetRunner
{ {
/* /*
* Runs the Lua script passed as the first command-line argument. * Runs the Lua script passed as the first command-line argument.
* It passed all the command-line arguments to the script. * It passed all the command-line arguments to the script.
*/ */
[STAThread] // steffenj: testluaform.lua "Load" button complained with an exception that STAThread was missing [STAThread] // steffenj: testluaform.lua "Load" button complained with an exception that STAThread was missing
public static void Main(string[] args) public static void Main(string[] args)
{ {
if(args.Length > 0) if(args.Length > 0)
{ {
// For attaching from the debugger // For attaching from the debugger
// Thread.Sleep(20000); // Thread.Sleep(20000);
using(Lua lua = new Lua()) using(Lua lua = new Lua())
{ {
//lua.OpenLibs(); // steffenj: Lua 5.1.1 API change (all libs already opened in Lua constructor!) //lua.OpenLibs(); // steffenj: Lua 5.1.1 API change (all libs already opened in Lua constructor!)
lua.NewTable("arg"); lua.NewTable("arg");
LuaTable argc = (LuaTable)lua["arg"]; LuaTable argc = (LuaTable)lua["arg"];
argc[-1] = "LuaRunner"; argc[-1] = "LuaRunner";
argc[0] = args[0]; argc[0] = args[0];
for(int i = 1; i < args.Length; i++) for(int i = 1; i < args.Length; i++)
argc[i] = args[i]; argc[i] = args[i];
argc["n"] = args.Length - 1; argc["n"] = args.Length - 1;
try try
{ {
//Console.WriteLine("DoFile(" + args[0] + ");"); //Console.WriteLine("DoFile(" + args[0] + ");");
lua.DoFile(args[0]); lua.DoFile(args[0]);
} }
catch(Exception e) catch(Exception e)
{ {
// steffenj: BEGIN error message improved, output is now in decending order of importance (message, where, stacktrace) // steffenj: BEGIN error message improved, output is now in decending order of importance (message, where, stacktrace)
// limit size of strack traceback message to roughly 1 console screen height // limit size of strack traceback message to roughly 1 console screen height
string trace = e.StackTrace; string trace = e.StackTrace;
if(e.StackTrace.Length > 1300) if(e.StackTrace.Length > 1300)
trace = e.StackTrace.Substring(0, 1300) + " [...] (traceback cut short)"; trace = e.StackTrace.Substring(0, 1300) + " [...] (traceback cut short)";
Console.WriteLine(); Console.WriteLine();
Console.WriteLine(e.Message); Console.WriteLine(e.Message);
Console.WriteLine(e.Source + " raised a " + e.GetType().ToString()); Console.WriteLine(e.Source + " raised a " + e.GetType().ToString());
Console.WriteLine(trace); Console.WriteLine(trace);
// wait for keypress if there is an error // wait for keypress if there is an error
Console.ReadKey(); Console.ReadKey();
// steffenj: END error message improved // steffenj: END error message improved
} }
} }
} }
else else
{ {
Console.WriteLine("LuaRunner -- runs Lua scripts with CLR access"); Console.WriteLine("LuaRunner -- runs Lua scripts with CLR access");
Console.WriteLine("Usage: luarunner <script.lua> [{<arg>}]"); Console.WriteLine("Usage: luarunner <script.lua> [{<arg>}]");
} }
} }
} }
} }
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform> <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>9.0.21022</ProductVersion> <ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}</ProjectGuid> <ProjectGuid>{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}</ProjectGuid>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LuaRunner</RootNamespace> <RootNamespace>LuaRunner</RootNamespace>
<AssemblyName>LuaRunner</AssemblyName> <AssemblyName>LuaRunner</AssemblyName>
<ReleaseVersion>2.x</ReleaseVersion> <ReleaseVersion>2.x</ReleaseVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>..\..\Run\Debug</OutputPath> <OutputPath>..\..\Run\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants> <DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>none</DebugType> <DebugType>none</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>..\..\Run\Release</OutputPath> <OutputPath>..\..\Run\Release</OutputPath>
<DefineConstants>RELEASE</DefineConstants> <DefineConstants>RELEASE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>..\..\Run\Debug_x64</OutputPath> <OutputPath>..\..\Run\Debug_x64</OutputPath>
<DefineConstants>DEBUG</DefineConstants> <DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<DebugType>none</DebugType> <DebugType>none</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>..\..\Run\Release_x64</OutputPath> <OutputPath>..\..\Run\Release_x64</OutputPath>
<DefineConstants>RELEASE</DefineConstants> <DefineConstants>RELEASE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="LuaNetRunner.cs" /> <Compile Include="LuaNetRunner.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Core\LuaInterface\LuaInterface.csproj"> <ProjectReference Include="..\..\Core\LuaInterface\LuaInterface.csproj">
<Project>{F55CABBB-4108-4A39-94E1-581FD46DC021}</Project> <Project>{F55CABBB-4108-4A39-94E1-581FD46DC021}</Project>
<Name>LuaInterface</Name> <Name>LuaInterface</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5"> <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible> <Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName> <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install> <Install>false</Install>
</BootstrapperPackage> </BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible> <Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName> <ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install> <Install>true</Install>
</BootstrapperPackage> </BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1"> <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible> <Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName> <ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install> <Install>true</Install>
</BootstrapperPackage> </BootstrapperPackage>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild"> <Target Name="BeforeBuild">
</Target> </Target>
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
</Project> </Project>
\ No newline at end of file
# Warning: This is an automatically generated file, do not edit!
if ENABLE_DEBUG_X86
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- -debug "-define:DEBUG"
ASSEMBLY = ../../Run/Debug/LuaRunner.exe
ASSEMBLY_MDB = $(ASSEMBLY).mdb
COMPILE_TARGET = exe
PROJECT_REFERENCES = \
../../Run/Debug/LuaInterface.dll
BUILD_DIR = ../../Run/Debug
LUARUNNER_EXE_MDB_SOURCE=../../Run/Debug/LuaRunner.exe.mdb
LUARUNNER_EXE_MDB=$(BUILD_DIR)/LuaRunner.exe.mdb
LUAINTERFACE_DLL_SOURCE=../../Run/Debug/LuaInterface.dll
KOPILUA_DLL_SOURCE=../../Run/Debug/KopiLua.dll
endif
if ENABLE_RELEASE_X86
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ "-define:RELEASE"
ASSEMBLY = ../../Run/Release/LuaRunner.exe
ASSEMBLY_MDB =
COMPILE_TARGET = exe
PROJECT_REFERENCES = \
../../Run/Release/LuaInterface.dll
BUILD_DIR = ../../Run/Release
LUARUNNER_EXE_MDB=
LUAINTERFACE_DLL_SOURCE=../../Run/Release/LuaInterface.dll
KOPILUA_DLL_SOURCE=../../Run/Release/KopiLua.dll
endif
if ENABLE_DEBUG_X64
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- -debug "-define:DEBUG"
ASSEMBLY = ../../Run/Debug_x64/LuaRunner.exe
ASSEMBLY_MDB = $(ASSEMBLY).mdb
COMPILE_TARGET = exe
PROJECT_REFERENCES = \
../../Run/Debug_x64/LuaInterface.dll
BUILD_DIR = ../../Run/Debug_x64
LUARUNNER_EXE_MDB_SOURCE=../../Run/Debug_x64/LuaRunner.exe.mdb
LUARUNNER_EXE_MDB=$(BUILD_DIR)/LuaRunner.exe.mdb
LUAINTERFACE_DLL_SOURCE=../../Run/Debug_x64/LuaInterface.dll
KOPILUA_DLL_SOURCE=../../Run/Debug_x64/KopiLua.dll
endif
if ENABLE_RELEASE_X64
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ "-define:RELEASE"
ASSEMBLY = ../../Run/Release_x64/LuaRunner.exe
ASSEMBLY_MDB =
COMPILE_TARGET = exe
PROJECT_REFERENCES = \
../../Run/Release_x64/LuaInterface.dll
BUILD_DIR = ../../Run/Release_x64
LUARUNNER_EXE_MDB=
LUAINTERFACE_DLL_SOURCE=../../Run/Release_x64/LuaInterface.dll
KOPILUA_DLL_SOURCE=../../Run/Release_x64/KopiLua.dll
endif
AL=al
SATELLITE_ASSEMBLY_NAME=$(notdir $(basename $(ASSEMBLY))).resources.dll
PROGRAMFILES = \
$(LUARUNNER_EXE_MDB) \
$(LUAINTERFACE_DLL) \
$(KOPILUA_DLL)
BINARIES = \
$(LUARUNNER)
RESGEN=resgen2
all: $(ASSEMBLY) $(PROGRAMFILES) $(BINARIES)
FILES = \
LuaNetRunner.cs \
Properties/AssemblyInfo.cs
DATA_FILES =
RESOURCES =
EXTRAS = \
luarunner.in
REFERENCES = \
System \
System.Data \
System.Xml
DLL_REFERENCES =
CLEANFILES = $(PROGRAMFILES) $(BINARIES)
include $(top_srcdir)/Makefile.include
LUAINTERFACE_DLL = $(BUILD_DIR)/LuaInterface.dll
KOPILUA_DLL = $(BUILD_DIR)/KopiLua.dll
LUARUNNER = $(BUILD_DIR)/luarunner
$(eval $(call emit-deploy-wrapper,LUARUNNER,luarunner,x))
$(eval $(call emit_resgen_targets))
$(build_xamlg_list): %.xaml.g.cs: %.xaml
xamlg '$<'
$(ASSEMBLY_MDB): $(ASSEMBLY)
$(ASSEMBLY): $(build_sources) $(build_resources) $(build_datafiles) $(DLL_REFERENCES) $(PROJECT_REFERENCES) $(build_xamlg_list) $(build_satellite_assembly_list)
mkdir -p $(shell dirname $(ASSEMBLY))
$(ASSEMBLY_COMPILER_COMMAND) $(ASSEMBLY_COMPILER_FLAGS) -out:$(ASSEMBLY) -target:$(COMPILE_TARGET) $(build_sources_embed) $(build_resources_embed) $(build_references_ref)
EXTRA_DIST =
#Warning: This is an automatically generated file, do not edit!
if ENABLE_DEBUG_X86
SUBDIRS = .
endif
if ENABLE_RELEASE_X86
SUBDIRS = .
endif
if ENABLE_DEBUG_X64
SUBDIRS = .
endif
if ENABLE_RELEASE_X64
SUBDIRS = .
endif
# Projekt-specifikus makefile beszúrása
include LuaRunner.make
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using LuaInterface.Config; using LuaInterface.Config;
// Information about this assembly is defined by the following attributes. // Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project. // Change them to the values specific to your project.
[assembly: AssemblyTitle("LuaRunner")] [assembly: AssemblyTitle("LuaRunner")]
[assembly: AssemblyDescription(Consts.LuaInterfaceDescription)] [assembly: AssemblyDescription(Consts.LuaInterfaceDescription)]
[assembly: AssemblyConfiguration(Consts.LuaInterfaceConfiguration)] [assembly: AssemblyConfiguration(Consts.LuaInterfaceConfiguration)]
[assembly: AssemblyCompany(Consts.LuaInterfaceCompany)] [assembly: AssemblyCompany(Consts.LuaInterfaceCompany)]
[assembly: AssemblyProduct(Consts.LuaInterfaceProduct)] [assembly: AssemblyProduct(Consts.LuaInterfaceProduct)]
[assembly: AssemblyCopyright(Consts.LuaInterfaceCopyright)] [assembly: AssemblyCopyright(Consts.LuaInterfaceCopyright)]
[assembly: AssemblyTrademark(Consts.LuaInterfaceTrademark)] [assembly: AssemblyTrademark(Consts.LuaInterfaceTrademark)]
// Setting ComVisible to false makes the types in this assembly not visible // Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from // to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. // COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
// Version information for an assembly consists of the following four values: // Version information for an assembly consists of the following four values:
// //
// Major Version // Major Version
// Minor Version // Minor Version
// Build Number // Build Number
// Revision // Revision
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.5.2")] [assembly: AssemblyVersion("1.5.2")]
[assembly: AssemblyFileVersion("1.5.2")] [assembly: AssemblyFileVersion("1.5.2")]
\ No newline at end of file
#!/bin/sh
exec mono "@expanded_libdir@/@PACKAGE@/LuaRunner.exe" "$@"
LuaInterface License LuaInterface License
-------------------- --------------------
LuaInterface is licensed under the terms of the MIT license reproduced below. LuaInterface is licensed under the terms of the MIT license reproduced below.
This mean that LuaInterface is free software and can be used for both academic and This mean that LuaInterface is free software and can be used for both academic and
commercial purposes at absolutely no cost. commercial purposes at absolutely no cost.
=============================================================================== ===============================================================================
Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
=============================================================================== ===============================================================================
Kopi Lua License Kopi Lua License
---------------- ----------------
Kopi Lua is licensed under the terms of the MIT license. Both the MIT Kopi Lua is licensed under the terms of the MIT license. Both the MIT
license and the original Lua copyright notice are reproduced below. license and the original Lua copyright notice are reproduced below.
Please see http://www.ppl-pilot.com/KopiLua for details. Please see http://www.ppl-pilot.com/KopiLua for details.
=============================================================================== ===============================================================================
Lua License Lua License
----------- -----------
Lua is licensed under the terms of the MIT license reproduced below. Lua is licensed under the terms of the MIT license reproduced below.
This means that Lua is free software and can be used for both academic This means that Lua is free software and can be used for both academic
and commercial purposes at absolutely no cost. and commercial purposes at absolutely no cost.
For details and rationale, see http://www.lua.org/license.html . For details and rationale, see http://www.lua.org/license.html .
=============================================================================== ===============================================================================
Copyright (C) 1994-2008 Lua.org, PUC-Rio. Copyright (C) 1994-2008 Lua.org, PUC-Rio.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
=============================================================================== ===============================================================================
(end of COPYRIGHT) (end of COPYRIGHT)
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform> <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>9.0.30729</ProductVersion> <ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}</ProjectGuid> <ProjectGuid>{E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Lua</RootNamespace> <RootNamespace>Lua</RootNamespace>
<AssemblyName>KopiLua</AssemblyName> <AssemblyName>KopiLua</AssemblyName>
<ReleaseVersion>2.x</ReleaseVersion> <ReleaseVersion>2.x</ReleaseVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>..\..\Run\Debug</OutputPath> <OutputPath>..\..\Run\Debug</OutputPath>
<DefineConstants>TRACE;DEBUG;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS</DefineConstants> <DefineConstants>TRACE;DEBUG;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>none</DebugType> <DebugType>none</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>..\..\Run\Release</OutputPath> <OutputPath>..\..\Run\Release</OutputPath>
<DefineConstants>TRACE;RELEASE;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS</DefineConstants> <DefineConstants>TRACE;RELEASE;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>..\..\Run\Debug_x64</OutputPath> <OutputPath>..\..\Run\Debug_x64</OutputPath>
<DefineConstants>TRACE;DEBUG;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS</DefineConstants> <DefineConstants>TRACE;DEBUG;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<DebugType>none</DebugType> <DebugType>none</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>..\..\Run\Release_x64</OutputPath> <OutputPath>..\..\Run\Release_x64</OutputPath>
<DefineConstants>TRACE;RELEASE;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS</DefineConstants> <DefineConstants>TRACE;RELEASE;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="lapi.cs" /> <Compile Include="lapi.cs" />
<Compile Include="lauxlib.cs" /> <Compile Include="lauxlib.cs" />
<Compile Include="lbaselib.cs" /> <Compile Include="lbaselib.cs" />
<Compile Include="lcode.cs" /> <Compile Include="lcode.cs" />
<Compile Include="ldblib.cs" /> <Compile Include="ldblib.cs" />
<Compile Include="ldebug.cs" /> <Compile Include="ldebug.cs" />
<Compile Include="ldo.cs" /> <Compile Include="ldo.cs" />
<Compile Include="ldump.cs" /> <Compile Include="ldump.cs" />
<Compile Include="lfunc.cs" /> <Compile Include="lfunc.cs" />
<Compile Include="lgc.cs" /> <Compile Include="lgc.cs" />
<Compile Include="linit.cs" /> <Compile Include="linit.cs" />
<Compile Include="liolib.cs" /> <Compile Include="liolib.cs" />
<Compile Include="llex.cs" /> <Compile Include="llex.cs" />
<Compile Include="llimits.cs" /> <Compile Include="llimits.cs" />
<Compile Include="lmathlib.cs" /> <Compile Include="lmathlib.cs" />
<Compile Include="lmem.cs" /> <Compile Include="lmem.cs" />
<Compile Include="loadlib.cs" /> <Compile Include="loadlib.cs" />
<Compile Include="lobject.cs" /> <Compile Include="lobject.cs" />
<Compile Include="lopcodes.cs" /> <Compile Include="lopcodes.cs" />
<Compile Include="loslib.cs" /> <Compile Include="loslib.cs" />
<Compile Include="lparser.cs" /> <Compile Include="lparser.cs" />
<Compile Include="lstate.cs" /> <Compile Include="lstate.cs" />
<Compile Include="lstring.cs" /> <Compile Include="lstring.cs" />
<Compile Include="lstrlib.cs" /> <Compile Include="lstrlib.cs" />
<Compile Include="ltable.cs" /> <Compile Include="ltable.cs" />
<Compile Include="ltablib.cs" /> <Compile Include="ltablib.cs" />
<Compile Include="ltm.cs" /> <Compile Include="ltm.cs" />
<Compile Include="lua.cs" /> <Compile Include="lua.cs" />
<Compile Include="luaconf.cs" /> <Compile Include="luaconf.cs" />
<Compile Include="lualib.cs" /> <Compile Include="lualib.cs" />
<Compile Include="lundump.cs" /> <Compile Include="lundump.cs" />
<Compile Include="lvm.cs" /> <Compile Include="lvm.cs" />
<Compile Include="lzio.cs" /> <Compile Include="lzio.cs" />
<Compile Include="print.cs" /> <Compile Include="print.cs" />
<Compile Include="printf\Tools.cs" /> <Compile Include="printf\Tools.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5"> <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible> <Visible>False</Visible>
<ProductName>Клиентский профиль .NET Framework 3.5 SP1</ProductName> <ProductName>Клиентский профиль .NET Framework 3.5 SP1</ProductName>
<Install>false</Install> <Install>false</Install>
</BootstrapperPackage> </BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible> <Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName> <ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install> <Install>true</Install>
</BootstrapperPackage> </BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1"> <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible> <Visible>False</Visible>
<ProductName>Установщик Windows 3.1</ProductName> <ProductName>Установщик Windows 3.1</ProductName>
<Install>true</Install> <Install>true</Install>
</BootstrapperPackage> </BootstrapperPackage>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild"> <Target Name="BeforeBuild">
</Target> </Target>
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
</Project> </Project>
\ No newline at end of file
EXTRA_DIST =
# Warning: This is an automatically generated file, do not edit!
if ENABLE_DEBUG_X86
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- -debug "-define:TRACE;DEBUG;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS"
ASSEMBLY = ../../Run/Debug/KopiLua.dll
ASSEMBLY_MDB = $(ASSEMBLY).mdb
COMPILE_TARGET = library
PROJECT_REFERENCES =
BUILD_DIR = ../../Run/Debug
KOPILUA_DLL_MDB_SOURCE=../../Run/Debug/KopiLua.dll.mdb
KOPILUA_DLL_MDB=$(BUILD_DIR)/KopiLua.dll.mdb
endif
if ENABLE_RELEASE_X86
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ "-define:TRACE;RELEASE;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS"
ASSEMBLY = ../../Run/Release/KopiLua.dll
ASSEMBLY_MDB =
COMPILE_TARGET = library
PROJECT_REFERENCES =
BUILD_DIR = ../../Run/Release
KOPILUA_DLL_MDB=
endif
if ENABLE_DEBUG_X64
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- -debug "-define:TRACE;DEBUG;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS"
ASSEMBLY = ../../Run/Debug_x64/KopiLua.dll
ASSEMBLY_MDB = $(ASSEMBLY).mdb
COMPILE_TARGET = library
PROJECT_REFERENCES =
BUILD_DIR = ../../Run/Debug_x64
KOPILUA_DLL_MDB_SOURCE=../../Run/Debug_x64/KopiLua.dll.mdb
KOPILUA_DLL_MDB=$(BUILD_DIR)/KopiLua.dll.mdb
endif
if ENABLE_RELEASE_X64
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ "-define:TRACE;RELEASE;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS"
ASSEMBLY = ../../Run/Release_x64/KopiLua.dll
ASSEMBLY_MDB =
COMPILE_TARGET = library
PROJECT_REFERENCES =
BUILD_DIR = ../../Run/Release_x64
KOPILUA_DLL_MDB=
endif
AL=al
SATELLITE_ASSEMBLY_NAME=$(notdir $(basename $(ASSEMBLY))).resources.dll
PROGRAMFILES = \
$(KOPILUA_DLL_MDB)
LINUX_PKGCONFIG = \
$(KOPILUA_PC)
RESGEN=resgen2
all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_PKGCONFIG)
FILES = \
lapi.cs \
lauxlib.cs \
lbaselib.cs \
lcode.cs \
ldblib.cs \
ldebug.cs \
ldo.cs \
ldump.cs \
lfunc.cs \
lgc.cs \
linit.cs \
liolib.cs \
llex.cs \
llimits.cs \
lmathlib.cs \
lmem.cs \
loadlib.cs \
lobject.cs \
lopcodes.cs \
loslib.cs \
lparser.cs \
lstate.cs \
lstring.cs \
lstrlib.cs \
ltable.cs \
ltablib.cs \
ltm.cs \
lua.cs \
luaconf.cs \
lualib.cs \
lundump.cs \
lvm.cs \
lzio.cs \
print.cs \
printf/Tools.cs \
Properties/AssemblyInfo.cs
DATA_FILES =
RESOURCES =
EXTRAS = \
kopilua.pc.in
REFERENCES = \
System \
System.Core \
System.Data.DataSetExtensions \
System.Data
DLL_REFERENCES =
CLEANFILES = $(PROGRAMFILES) $(LINUX_PKGCONFIG)
include $(top_srcdir)/Makefile.include
KOPILUA_PC = $(BUILD_DIR)/kopilua.pc
$(eval $(call emit-deploy-wrapper,KOPILUA_PC,kopilua.pc))
$(eval $(call emit_resgen_targets))
$(build_xamlg_list): %.xaml.g.cs: %.xaml
xamlg '$<'
$(ASSEMBLY_MDB): $(ASSEMBLY)
$(ASSEMBLY): $(build_sources) $(build_resources) $(build_datafiles) $(DLL_REFERENCES) $(PROJECT_REFERENCES) $(build_xamlg_list) $(build_satellite_assembly_list)
mkdir -p $(shell dirname $(ASSEMBLY))
$(ASSEMBLY_COMPILER_COMMAND) $(ASSEMBLY_COMPILER_FLAGS) -out:$(ASSEMBLY) -target:$(COMPILE_TARGET) $(build_sources_embed) $(build_resources_embed) $(build_references_ref)
using System; using System;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("KopiLua")] [assembly: AssemblyTitle("KopiLua")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("KopiLua")] [assembly: AssemblyProduct("KopiLua")]
[assembly: AssemblyCopyright("Copyright © 2009 Mark Feldman")] [assembly: AssemblyCopyright("Copyright © 2009 Mark Feldman")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: CLSCompliantAttribute(true)] [assembly: CLSCompliantAttribute(true)]
// Setting ComVisible to false makes the types in this assembly not visible // Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from // to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. // COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM // The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1a9cd761-692f-40db-8566-c0217e5d3e0a")] [assembly: Guid("1a9cd761-692f-40db-8566-c0217e5d3e0a")]
// Version information for an assembly consists of the following four values: // Version information for an assembly consists of the following four values:
// //
// Major Version // Major Version
// Minor Version // Minor Version
// Build Number // Build Number
// Revision // Revision
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Resources; using System.Resources;
// Управление общими сведениями о сборке осуществляется с помощью следующего // Управление общими сведениями о сборке осуществляется с помощью следующего
// набора атрибутов. Измените значения этих атрибутов для изменения // набора атрибутов. Измените значения этих атрибутов для изменения
// сведений о сборке. // сведений о сборке.
[assembly: AssemblyTitle("KopiLua_wp7")] [assembly: AssemblyTitle("KopiLua_wp7")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("MICROSOFT")] [assembly: AssemblyCompany("MICROSOFT")]
[assembly: AssemblyProduct("KopiLua_wp7")] [assembly: AssemblyProduct("KopiLua_wp7")]
[assembly: AssemblyCopyright("Copyright © 2012 Gerasimov Sergey")] [assembly: AssemblyCopyright("Copyright © 2012 Gerasimov Sergey")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
// Если для ComVisible установить значение false, типы в этой сборке не будут поддерживаться // Если для ComVisible установить значение false, типы в этой сборке не будут поддерживаться
// COM-компонентами. При необходимости доступа к какому-либо типу в этой сборке // COM-компонентами. При необходимости доступа к какому-либо типу в этой сборке
// из модели COM задайте для атрибута ComVisible этого типа значение true. // из модели COM задайте для атрибута ComVisible этого типа значение true.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
// Следующий GUID служит для идентификации библиотеки типов, если данный проект видим для COM // Следующий GUID служит для идентификации библиотеки типов, если данный проект видим для COM
[assembly: Guid("63906a16-e4d0-4ad7-ba8f-cb4d6c29d2d5")] [assembly: Guid("63906a16-e4d0-4ad7-ba8f-cb4d6c29d2d5")]
// Сведения о версии сборки состоят из следующих четырех значений: // Сведения о версии сборки состоят из следующих четырех значений:
// //
// Основной номер версии // Основной номер версии
// Дополнительный номер версии // Дополнительный номер версии
// Номер построения // Номер построения
// Редакция // Редакция
// //
// Можно указать все значения или задать для номеров редакции и построения значения по умолчанию // Можно указать все значения или задать для номеров редакции и построения значения по умолчанию
// с помощью символа '*', как показано ниже: // с помощью символа '*', как показано ниже:
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: NeutralResourcesLanguageAttribute("ru-RU")] [assembly: NeutralResourcesLanguageAttribute("ru-RU")]
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("Lua")] [assembly: AssemblyTitle("Lua")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Lua")] [assembly: AssemblyProduct("Lua")]
[assembly: AssemblyCopyright("Copyright © Mark Feldman 2009")] [assembly: AssemblyCopyright("Copyright © Mark Feldman 2009")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible // Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from // to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. // COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM // The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("42f29687-47be-4860-a332-c7c4c75b7119")] [assembly: Guid("42f29687-47be-4860-a332-c7c4c75b7119")]
// Version information for an assembly consists of the following four values: // Version information for an assembly consists of the following four values:
// //
// Major Version // Major Version
// Minor Version // Minor Version
// Build Number // Build Number
// Revision // Revision
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("Luac")] [assembly: AssemblyTitle("Luac")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Luac")] [assembly: AssemblyProduct("Luac")]
[assembly: AssemblyCopyright("Copyright © Mark Feldman 2009")] [assembly: AssemblyCopyright("Copyright © Mark Feldman 2009")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible // Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from // to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. // COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM // The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("403d5192-280f-4171-98e6-c818dd6b9981")] [assembly: Guid("403d5192-280f-4171-98e6-c818dd6b9981")]
// Version information for an assembly consists of the following four values: // Version information for an assembly consists of the following four values:
// //
// Major Version // Major Version
// Minor Version // Minor Version
// Build Number // Build Number
// Revision // Revision
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]
Name: KopiLua
Description: KopiLua
Version: 2.x
Requires:
Libs: -r:@expanded_libdir@/@PACKAGE@/KopiLua.dll
/* /*
** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $ ** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $
** Lua API ** Lua API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Diagnostics; using System.Diagnostics;
namespace KopiLua namespace KopiLua
{ {
using lu_mem = System.UInt32; using lu_mem = System.UInt32;
using TValue = Lua.lua_TValue; using TValue = Lua.lua_TValue;
using StkId = Lua.lua_TValue; using StkId = Lua.lua_TValue;
using lua_Integer = System.Int32; using lua_Integer = System.Int32;
using lua_Number = System.Double; using lua_Number = System.Double;
using ptrdiff_t = System.Int32; using ptrdiff_t = System.Int32;
using ZIO = Lua.Zio; using ZIO = Lua.Zio;
public partial class Lua public partial class Lua
{ {
public const string lua_ident = public const string lua_ident =
"$Lua: " + LUA_RELEASE + " " + LUA_COPYRIGHT + " $\n" + "$Lua: " + LUA_RELEASE + " " + LUA_COPYRIGHT + " $\n" +
"$Authors: " + LUA_AUTHORS + " $\n" + "$Authors: " + LUA_AUTHORS + " $\n" +
"$URL: www.lua.org $\n"; "$URL: www.lua.org $\n";
public static void api_checknelems(lua_State L, int n) public static void api_checknelems(lua_State L, int n)
{ {
api_check(L, n <= L.top - L.base_); api_check(L, n <= L.top - L.base_);
} }
public static void api_checkvalidindex(lua_State L, StkId i) public static void api_checkvalidindex(lua_State L, StkId i)
{ {
api_check(L, i != luaO_nilobject); api_check(L, i != luaO_nilobject);
} }
public static void api_incr_top(lua_State L) public static void api_incr_top(lua_State L)
{ {
api_check(L, L.top < L.ci.top); api_check(L, L.top < L.ci.top);
StkId.inc(ref L.top); StkId.inc(ref L.top);
} }
static TValue index2adr (lua_State L, int idx) { static TValue index2adr (lua_State L, int idx) {
if (idx > 0) { if (idx > 0) {
TValue o = L.base_ + (idx - 1); TValue o = L.base_ + (idx - 1);
api_check(L, idx <= L.ci.top - L.base_); api_check(L, idx <= L.ci.top - L.base_);
if (o >= L.top) return luaO_nilobject; if (o >= L.top) return luaO_nilobject;
else return o; else return o;
} }
else if (idx > LUA_REGISTRYINDEX) { else if (idx > LUA_REGISTRYINDEX) {
api_check(L, idx != 0 && -idx <= L.top - L.base_); api_check(L, idx != 0 && -idx <= L.top - L.base_);
return L.top + idx; return L.top + idx;
} }
else switch (idx) { /* pseudo-indices */ else switch (idx) { /* pseudo-indices */
case LUA_REGISTRYINDEX: return registry(L); case LUA_REGISTRYINDEX: return registry(L);
case LUA_ENVIRONINDEX: { case LUA_ENVIRONINDEX: {
Closure func = curr_func(L); Closure func = curr_func(L);
sethvalue(L, L.env, func.c.env); sethvalue(L, L.env, func.c.env);
return L.env; return L.env;
} }
case LUA_GLOBALSINDEX: return gt(L); case LUA_GLOBALSINDEX: return gt(L);
default: { default: {
Closure func = curr_func(L); Closure func = curr_func(L);
idx = LUA_GLOBALSINDEX - idx; idx = LUA_GLOBALSINDEX - idx;
return (idx <= func.c.nupvalues) return (idx <= func.c.nupvalues)
? func.c.upvalue[idx-1] ? func.c.upvalue[idx-1]
: (TValue)luaO_nilobject; : (TValue)luaO_nilobject;
} }
} }
} }
private static Table getcurrenv (lua_State L) { private static Table getcurrenv (lua_State L) {
if (L.ci == L.base_ci[0]) /* no enclosing function? */ if (L.ci == L.base_ci[0]) /* no enclosing function? */
return hvalue(gt(L)); /* use global table as environment */ return hvalue(gt(L)); /* use global table as environment */
else { else {
Closure func = curr_func(L); Closure func = curr_func(L);
return func.c.env; return func.c.env;
} }
} }
public static void luaA_pushobject (lua_State L, TValue o) { public static void luaA_pushobject (lua_State L, TValue o) {
setobj2s(L, L.top, o); setobj2s(L, L.top, o);
api_incr_top(L); api_incr_top(L);
} }
public static int lua_checkstack (lua_State L, int size) { public static int lua_checkstack (lua_State L, int size) {
int res = 1; int res = 1;
lua_lock(L); lua_lock(L);
if (size > LUAI_MAXCSTACK || (L.top - L.base_ + size) > LUAI_MAXCSTACK) if (size > LUAI_MAXCSTACK || (L.top - L.base_ + size) > LUAI_MAXCSTACK)
res = 0; /* stack overflow */ res = 0; /* stack overflow */
else if (size > 0) { else if (size > 0) {
luaD_checkstack(L, size); luaD_checkstack(L, size);
if (L.ci.top < L.top + size) if (L.ci.top < L.top + size)
L.ci.top = L.top + size; L.ci.top = L.top + size;
} }
lua_unlock(L); lua_unlock(L);
return res; return res;
} }
public static void lua_xmove (lua_State from, lua_State to, int n) { public static void lua_xmove (lua_State from, lua_State to, int n) {
int i; int i;
if (from == to) return; if (from == to) return;
lua_lock(to); lua_lock(to);
api_checknelems(from, n); api_checknelems(from, n);
api_check(from, G(from) == G(to)); api_check(from, G(from) == G(to));
api_check(from, to.ci.top - to.top >= n); api_check(from, to.ci.top - to.top >= n);
from.top -= n; from.top -= n;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
setobj2s(to, StkId.inc(ref to.top), from.top + i); setobj2s(to, StkId.inc(ref to.top), from.top + i);
} }
lua_unlock(to); lua_unlock(to);
} }
public static void lua_setlevel (lua_State from, lua_State to) { public static void lua_setlevel (lua_State from, lua_State to) {
to.nCcalls = from.nCcalls; to.nCcalls = from.nCcalls;
} }
public static lua_CFunction lua_atpanic (lua_State L, lua_CFunction panicf) { public static lua_CFunction lua_atpanic (lua_State L, lua_CFunction panicf) {
lua_CFunction old; lua_CFunction old;
lua_lock(L); lua_lock(L);
old = G(L).panic; old = G(L).panic;
G(L).panic = panicf; G(L).panic = panicf;
lua_unlock(L); lua_unlock(L);
return old; return old;
} }
public static lua_State lua_newthread (lua_State L) { public static lua_State lua_newthread (lua_State L) {
lua_State L1; lua_State L1;
lua_lock(L); lua_lock(L);
luaC_checkGC(L); luaC_checkGC(L);
L1 = luaE_newthread(L); L1 = luaE_newthread(L);
setthvalue(L, L.top, L1); setthvalue(L, L.top, L1);
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
luai_userstatethread(L, L1); luai_userstatethread(L, L1);
return L1; return L1;
} }
/* /*
** basic stack manipulation ** basic stack manipulation
*/ */
public static int lua_gettop (lua_State L) { public static int lua_gettop (lua_State L) {
return cast_int(L.top - L.base_); return cast_int(L.top - L.base_);
} }
public static void lua_settop (lua_State L, int idx) { public static void lua_settop (lua_State L, int idx) {
lua_lock(L); lua_lock(L);
if (idx >= 0) { if (idx >= 0) {
api_check(L, idx <= L.stack_last - L.base_); api_check(L, idx <= L.stack_last - L.base_);
while (L.top < L.base_ + idx) while (L.top < L.base_ + idx)
setnilvalue(StkId.inc(ref L.top)); setnilvalue(StkId.inc(ref L.top));
L.top = L.base_ + idx; L.top = L.base_ + idx;
} }
else { else {
api_check(L, -(idx+1) <= (L.top - L.base_)); api_check(L, -(idx+1) <= (L.top - L.base_));
L.top += idx+1; /* `subtract' index (index is negative) */ L.top += idx+1; /* `subtract' index (index is negative) */
} }
lua_unlock(L); lua_unlock(L);
} }
public static void lua_remove (lua_State L, int idx) { public static void lua_remove (lua_State L, int idx) {
StkId p; StkId p;
lua_lock(L); lua_lock(L);
p = index2adr(L, idx); p = index2adr(L, idx);
api_checkvalidindex(L, p); api_checkvalidindex(L, p);
while ((p=p[1]) < L.top) setobjs2s(L, p-1, p); while ((p=p[1]) < L.top) setobjs2s(L, p-1, p);
StkId.dec(ref L.top); StkId.dec(ref L.top);
lua_unlock(L); lua_unlock(L);
} }
public static void lua_insert (lua_State L, int idx) { public static void lua_insert (lua_State L, int idx) {
StkId p; StkId p;
StkId q; StkId q;
lua_lock(L); lua_lock(L);
p = index2adr(L, idx); p = index2adr(L, idx);
api_checkvalidindex(L, p); api_checkvalidindex(L, p);
for (q = L.top; q>p; StkId.dec(ref q)) setobjs2s(L, q, q-1); for (q = L.top; q>p; StkId.dec(ref q)) setobjs2s(L, q, q-1);
setobjs2s(L, p, L.top); setobjs2s(L, p, L.top);
lua_unlock(L); lua_unlock(L);
} }
public static void lua_replace (lua_State L, int idx) { public static void lua_replace (lua_State L, int idx) {
StkId o; StkId o;
lua_lock(L); lua_lock(L);
/* explicit test for incompatible code */ /* explicit test for incompatible code */
if (idx == LUA_ENVIRONINDEX && L.ci == L.base_ci[0]) if (idx == LUA_ENVIRONINDEX && L.ci == L.base_ci[0])
luaG_runerror(L, "no calling environment"); luaG_runerror(L, "no calling environment");
api_checknelems(L, 1); api_checknelems(L, 1);
o = index2adr(L, idx); o = index2adr(L, idx);
api_checkvalidindex(L, o); api_checkvalidindex(L, o);
if (idx == LUA_ENVIRONINDEX) { if (idx == LUA_ENVIRONINDEX) {
Closure func = curr_func(L); Closure func = curr_func(L);
api_check(L, ttistable(L.top - 1)); api_check(L, ttistable(L.top - 1));
func.c.env = hvalue(L.top - 1); func.c.env = hvalue(L.top - 1);
luaC_barrier(L, func, L.top - 1); luaC_barrier(L, func, L.top - 1);
} }
else { else {
setobj(L, o, L.top - 1); setobj(L, o, L.top - 1);
if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
luaC_barrier(L, curr_func(L), L.top - 1); luaC_barrier(L, curr_func(L), L.top - 1);
} }
StkId.dec(ref L.top); StkId.dec(ref L.top);
lua_unlock(L); lua_unlock(L);
} }
public static void lua_pushvalue (lua_State L, int idx) { public static void lua_pushvalue (lua_State L, int idx) {
lua_lock(L); lua_lock(L);
setobj2s(L, L.top, index2adr(L, idx)); setobj2s(L, L.top, index2adr(L, idx));
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
/* /*
** access functions (stack . C) ** access functions (stack . C)
*/ */
public static int lua_type (lua_State L, int idx) { public static int lua_type (lua_State L, int idx) {
StkId o = index2adr(L, idx); StkId o = index2adr(L, idx);
return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
} }
public static CharPtr lua_typename (lua_State L, int t) { public static CharPtr lua_typename (lua_State L, int t) {
//UNUSED(L); //UNUSED(L);
return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
} }
public static bool lua_iscfunction (lua_State L, int idx) { public static bool lua_iscfunction (lua_State L, int idx) {
StkId o = index2adr(L, idx); StkId o = index2adr(L, idx);
return iscfunction(o); return iscfunction(o);
} }
public static int lua_isnumber (lua_State L, int idx) { public static int lua_isnumber (lua_State L, int idx) {
TValue n = new TValue(); TValue n = new TValue();
TValue o = index2adr(L, idx); TValue o = index2adr(L, idx);
return tonumber(ref o, n); return tonumber(ref o, n);
} }
public static int lua_isstring (lua_State L, int idx) { public static int lua_isstring (lua_State L, int idx) {
int t = lua_type(L, idx); int t = lua_type(L, idx);
return (t == LUA_TSTRING || t == LUA_TNUMBER) ? 1 : 0; return (t == LUA_TSTRING || t == LUA_TNUMBER) ? 1 : 0;
} }
public static int lua_isuserdata (lua_State L, int idx) { public static int lua_isuserdata (lua_State L, int idx) {
TValue o = index2adr(L, idx); TValue o = index2adr(L, idx);
return (ttisuserdata(o) || ttislightuserdata(o)) ? 1 : 0; return (ttisuserdata(o) || ttislightuserdata(o)) ? 1 : 0;
} }
public static int lua_rawequal (lua_State L, int index1, int index2) { public static int lua_rawequal (lua_State L, int index1, int index2) {
StkId o1 = index2adr(L, index1); StkId o1 = index2adr(L, index1);
StkId o2 = index2adr(L, index2); StkId o2 = index2adr(L, index2);
return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
: luaO_rawequalObj(o1, o2); : luaO_rawequalObj(o1, o2);
} }
public static int lua_equal (lua_State L, int index1, int index2) { public static int lua_equal (lua_State L, int index1, int index2) {
StkId o1, o2; StkId o1, o2;
int i; int i;
lua_lock(L); /* may call tag method */ lua_lock(L); /* may call tag method */
o1 = index2adr(L, index1); o1 = index2adr(L, index1);
o2 = index2adr(L, index2); o2 = index2adr(L, index2);
i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
lua_unlock(L); lua_unlock(L);
return i; return i;
} }
public static int lua_lessthan (lua_State L, int index1, int index2) { public static int lua_lessthan (lua_State L, int index1, int index2) {
StkId o1, o2; StkId o1, o2;
int i; int i;
lua_lock(L); /* may call tag method */ lua_lock(L); /* may call tag method */
o1 = index2adr(L, index1); o1 = index2adr(L, index1);
o2 = index2adr(L, index2); o2 = index2adr(L, index2);
i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
: luaV_lessthan(L, o1, o2); : luaV_lessthan(L, o1, o2);
lua_unlock(L); lua_unlock(L);
return i; return i;
} }
public static lua_Number lua_tonumber (lua_State L, int idx) { public static lua_Number lua_tonumber (lua_State L, int idx) {
TValue n = new TValue(); TValue n = new TValue();
TValue o = index2adr(L, idx); TValue o = index2adr(L, idx);
if (tonumber(ref o, n) != 0) if (tonumber(ref o, n) != 0)
return nvalue(o); return nvalue(o);
else else
return 0; return 0;
} }
public static lua_Integer lua_tointeger (lua_State L, int idx) { public static lua_Integer lua_tointeger (lua_State L, int idx) {
TValue n = new TValue(); TValue n = new TValue();
TValue o = index2adr(L, idx); TValue o = index2adr(L, idx);
if (tonumber(ref o, n) != 0) { if (tonumber(ref o, n) != 0) {
lua_Integer res; lua_Integer res;
lua_Number num = nvalue(o); lua_Number num = nvalue(o);
lua_number2integer(out res, num); lua_number2integer(out res, num);
return res; return res;
} }
else else
return 0; return 0;
} }
public static int lua_toboolean (lua_State L, int idx) { public static int lua_toboolean (lua_State L, int idx) {
TValue o = index2adr(L, idx); TValue o = index2adr(L, idx);
return (l_isfalse(o) == 0) ? 1 : 0; return (l_isfalse(o) == 0) ? 1 : 0;
} }
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public static CharPtr lua_tolstring (lua_State L, int idx, out uint len) { public static CharPtr lua_tolstring (lua_State L, int idx, out uint len) {
StkId o = index2adr(L, idx); StkId o = index2adr(L, idx);
if (!ttisstring(o)) { if (!ttisstring(o)) {
lua_lock(L); /* `luaV_tostring' may create a new string */ lua_lock(L); /* `luaV_tostring' may create a new string */
if (luaV_tostring(L, o)==0) { /* conversion failed? */ if (luaV_tostring(L, o)==0) { /* conversion failed? */
len = 0; len = 0;
lua_unlock(L); lua_unlock(L);
return null; return null;
} }
luaC_checkGC(L); luaC_checkGC(L);
o = index2adr(L, idx); /* previous call may reallocate the stack */ o = index2adr(L, idx); /* previous call may reallocate the stack */
lua_unlock(L); lua_unlock(L);
} }
len = tsvalue(o).len; len = tsvalue(o).len;
return svalue(o); return svalue(o);
} }
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public static uint lua_objlen (lua_State L, int idx) { public static uint lua_objlen (lua_State L, int idx) {
StkId o = index2adr(L, idx); StkId o = index2adr(L, idx);
switch (ttype(o)) { switch (ttype(o)) {
case LUA_TSTRING: return tsvalue(o).len; case LUA_TSTRING: return tsvalue(o).len;
case LUA_TUSERDATA: return uvalue(o).len; case LUA_TUSERDATA: return uvalue(o).len;
case LUA_TTABLE: return (uint)luaH_getn(hvalue(o)); case LUA_TTABLE: return (uint)luaH_getn(hvalue(o));
case LUA_TNUMBER: { case LUA_TNUMBER: {
uint l; uint l;
lua_lock(L); /* `luaV_tostring' may create a new string */ lua_lock(L); /* `luaV_tostring' may create a new string */
l = (luaV_tostring(L, o) != 0 ? tsvalue(o).len : 0); l = (luaV_tostring(L, o) != 0 ? tsvalue(o).len : 0);
lua_unlock(L); lua_unlock(L);
return l; return l;
} }
default: return 0; default: return 0;
} }
} }
public static lua_CFunction lua_tocfunction (lua_State L, int idx) { public static lua_CFunction lua_tocfunction (lua_State L, int idx) {
StkId o = index2adr(L, idx); StkId o = index2adr(L, idx);
return (!iscfunction(o)) ? null : clvalue(o).c.f; return (!iscfunction(o)) ? null : clvalue(o).c.f;
} }
public static object lua_touserdata (lua_State L, int idx) { public static object lua_touserdata (lua_State L, int idx) {
StkId o = index2adr(L, idx); StkId o = index2adr(L, idx);
switch (ttype(o)) { switch (ttype(o)) {
case LUA_TUSERDATA: return (rawuvalue(o).user_data); case LUA_TUSERDATA: return (rawuvalue(o).user_data);
case LUA_TLIGHTUSERDATA: return pvalue(o); case LUA_TLIGHTUSERDATA: return pvalue(o);
default: return null; default: return null;
} }
} }
public static lua_State lua_tothread (lua_State L, int idx) { public static lua_State lua_tothread (lua_State L, int idx) {
StkId o = index2adr(L, idx); StkId o = index2adr(L, idx);
return (!ttisthread(o)) ? null : thvalue(o); return (!ttisthread(o)) ? null : thvalue(o);
} }
public static object lua_topointer (lua_State L, int idx) { public static object lua_topointer (lua_State L, int idx) {
StkId o = index2adr(L, idx); StkId o = index2adr(L, idx);
switch (ttype(o)) { switch (ttype(o)) {
case LUA_TTABLE: return hvalue(o); case LUA_TTABLE: return hvalue(o);
case LUA_TFUNCTION: return clvalue(o); case LUA_TFUNCTION: return clvalue(o);
case LUA_TTHREAD: return thvalue(o); case LUA_TTHREAD: return thvalue(o);
case LUA_TUSERDATA: case LUA_TUSERDATA:
case LUA_TLIGHTUSERDATA: case LUA_TLIGHTUSERDATA:
return lua_touserdata(L, idx); return lua_touserdata(L, idx);
default: return null; default: return null;
} }
} }
/* /*
** push functions (C . stack) ** push functions (C . stack)
*/ */
public static void lua_pushnil (lua_State L) { public static void lua_pushnil (lua_State L) {
lua_lock(L); lua_lock(L);
setnilvalue(L.top); setnilvalue(L.top);
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
public static void lua_pushnumber (lua_State L, lua_Number n) { public static void lua_pushnumber (lua_State L, lua_Number n) {
lua_lock(L); lua_lock(L);
setnvalue(L.top, n); setnvalue(L.top, n);
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
public static void lua_pushinteger (lua_State L, lua_Integer n) { public static void lua_pushinteger (lua_State L, lua_Integer n) {
lua_lock(L); lua_lock(L);
setnvalue(L.top, cast_num(n)); setnvalue(L.top, cast_num(n));
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public static void lua_pushlstring (lua_State L, CharPtr s, uint len) { public static void lua_pushlstring (lua_State L, CharPtr s, uint len) {
lua_lock(L); lua_lock(L);
luaC_checkGC(L); luaC_checkGC(L);
setsvalue2s(L, L.top, luaS_newlstr(L, s, len)); setsvalue2s(L, L.top, luaS_newlstr(L, s, len));
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
public static void lua_pushstring (lua_State L, CharPtr s) { public static void lua_pushstring (lua_State L, CharPtr s) {
if (s == null) if (s == null)
lua_pushnil(L); lua_pushnil(L);
else else
lua_pushlstring(L, s, (uint)strlen(s)); lua_pushlstring(L, s, (uint)strlen(s));
} }
public static CharPtr lua_pushvfstring (lua_State L, CharPtr fmt, public static CharPtr lua_pushvfstring (lua_State L, CharPtr fmt,
object[] argp) { object[] argp) {
CharPtr ret; CharPtr ret;
lua_lock(L); lua_lock(L);
luaC_checkGC(L); luaC_checkGC(L);
ret = luaO_pushvfstring(L, fmt, argp); ret = luaO_pushvfstring(L, fmt, argp);
lua_unlock(L); lua_unlock(L);
return ret; return ret;
} }
public static CharPtr lua_pushfstring (lua_State L, CharPtr fmt) { public static CharPtr lua_pushfstring (lua_State L, CharPtr fmt) {
CharPtr ret; CharPtr ret;
lua_lock(L); lua_lock(L);
luaC_checkGC(L); luaC_checkGC(L);
ret = luaO_pushvfstring(L, fmt, null); ret = luaO_pushvfstring(L, fmt, null);
lua_unlock(L); lua_unlock(L);
return ret; return ret;
} }
public static CharPtr lua_pushfstring(lua_State L, CharPtr fmt, params object[] p) public static CharPtr lua_pushfstring(lua_State L, CharPtr fmt, params object[] p)
{ {
CharPtr ret; CharPtr ret;
lua_lock(L); lua_lock(L);
luaC_checkGC(L); luaC_checkGC(L);
ret = luaO_pushvfstring(L, fmt, p); ret = luaO_pushvfstring(L, fmt, p);
lua_unlock(L); lua_unlock(L);
return ret; return ret;
} }
public static void lua_pushcclosure (lua_State L, lua_CFunction fn, int n) { public static void lua_pushcclosure (lua_State L, lua_CFunction fn, int n) {
Closure cl; Closure cl;
lua_lock(L); lua_lock(L);
luaC_checkGC(L); luaC_checkGC(L);
api_checknelems(L, n); api_checknelems(L, n);
cl = luaF_newCclosure(L, n, getcurrenv(L)); cl = luaF_newCclosure(L, n, getcurrenv(L));
cl.c.f = fn; cl.c.f = fn;
L.top -= n; L.top -= n;
while (n-- != 0) while (n-- != 0)
setobj2n(L, cl.c.upvalue[n], L.top+n); setobj2n(L, cl.c.upvalue[n], L.top+n);
setclvalue(L, L.top, cl); setclvalue(L, L.top, cl);
lua_assert(iswhite(obj2gco(cl))); lua_assert(iswhite(obj2gco(cl)));
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
public static void lua_pushboolean (lua_State L, int b) { public static void lua_pushboolean (lua_State L, int b) {
lua_lock(L); lua_lock(L);
setbvalue(L.top, (b != 0) ? 1 : 0); /* ensure that true is 1 */ setbvalue(L.top, (b != 0) ? 1 : 0); /* ensure that true is 1 */
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
public static void lua_pushlightuserdata (lua_State L, object p) { public static void lua_pushlightuserdata (lua_State L, object p) {
lua_lock(L); lua_lock(L);
setpvalue(L.top, p); setpvalue(L.top, p);
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
public static int lua_pushthread (lua_State L) { public static int lua_pushthread (lua_State L) {
lua_lock(L); lua_lock(L);
setthvalue(L, L.top, L); setthvalue(L, L.top, L);
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
return (G(L).mainthread == L) ? 1 : 0; return (G(L).mainthread == L) ? 1 : 0;
} }
/* /*
** get functions (Lua . stack) ** get functions (Lua . stack)
*/ */
public static void lua_gettable (lua_State L, int idx) { public static void lua_gettable (lua_State L, int idx) {
StkId t; StkId t;
lua_lock(L); lua_lock(L);
t = index2adr(L, idx); t = index2adr(L, idx);
api_checkvalidindex(L, t); api_checkvalidindex(L, t);
luaV_gettable(L, t, L.top - 1, L.top - 1); luaV_gettable(L, t, L.top - 1, L.top - 1);
lua_unlock(L); lua_unlock(L);
} }
public static void lua_getfield (lua_State L, int idx, CharPtr k) { public static void lua_getfield (lua_State L, int idx, CharPtr k) {
StkId t; StkId t;
TValue key = new TValue(); TValue key = new TValue();
lua_lock(L); lua_lock(L);
t = index2adr(L, idx); t = index2adr(L, idx);
api_checkvalidindex(L, t); api_checkvalidindex(L, t);
setsvalue(L, key, luaS_new(L, k)); setsvalue(L, key, luaS_new(L, k));
luaV_gettable(L, t, key, L.top); luaV_gettable(L, t, key, L.top);
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
public static void lua_rawget (lua_State L, int idx) { public static void lua_rawget (lua_State L, int idx) {
StkId t; StkId t;
lua_lock(L); lua_lock(L);
t = index2adr(L, idx); t = index2adr(L, idx);
api_check(L, ttistable(t)); api_check(L, ttistable(t));
setobj2s(L, L.top - 1, luaH_get(hvalue(t), L.top - 1)); setobj2s(L, L.top - 1, luaH_get(hvalue(t), L.top - 1));
lua_unlock(L); lua_unlock(L);
} }
public static void lua_rawgeti (lua_State L, int idx, int n) { public static void lua_rawgeti (lua_State L, int idx, int n) {
StkId o; StkId o;
lua_lock(L); lua_lock(L);
o = index2adr(L, idx); o = index2adr(L, idx);
api_check(L, ttistable(o)); api_check(L, ttistable(o));
setobj2s(L, L.top, luaH_getnum(hvalue(o), n)); setobj2s(L, L.top, luaH_getnum(hvalue(o), n));
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
public static void lua_createtable (lua_State L, int narray, int nrec) { public static void lua_createtable (lua_State L, int narray, int nrec) {
lua_lock(L); lua_lock(L);
luaC_checkGC(L); luaC_checkGC(L);
sethvalue(L, L.top, luaH_new(L, narray, nrec)); sethvalue(L, L.top, luaH_new(L, narray, nrec));
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
public static int lua_getmetatable (lua_State L, int objindex) { public static int lua_getmetatable (lua_State L, int objindex) {
TValue obj; TValue obj;
Table mt = null; Table mt = null;
int res; int res;
lua_lock(L); lua_lock(L);
obj = index2adr(L, objindex); obj = index2adr(L, objindex);
switch (ttype(obj)) { switch (ttype(obj)) {
case LUA_TTABLE: case LUA_TTABLE:
mt = hvalue(obj).metatable; mt = hvalue(obj).metatable;
break; break;
case LUA_TUSERDATA: case LUA_TUSERDATA:
mt = uvalue(obj).metatable; mt = uvalue(obj).metatable;
break; break;
default: default:
mt = G(L).mt[ttype(obj)]; mt = G(L).mt[ttype(obj)];
break; break;
} }
if (mt == null) if (mt == null)
res = 0; res = 0;
else { else {
sethvalue(L, L.top, mt); sethvalue(L, L.top, mt);
api_incr_top(L); api_incr_top(L);
res = 1; res = 1;
} }
lua_unlock(L); lua_unlock(L);
return res; return res;
} }
public static void lua_getfenv (lua_State L, int idx) { public static void lua_getfenv (lua_State L, int idx) {
StkId o; StkId o;
lua_lock(L); lua_lock(L);
o = index2adr(L, idx); o = index2adr(L, idx);
api_checkvalidindex(L, o); api_checkvalidindex(L, o);
switch (ttype(o)) { switch (ttype(o)) {
case LUA_TFUNCTION: case LUA_TFUNCTION:
sethvalue(L, L.top, clvalue(o).c.env); sethvalue(L, L.top, clvalue(o).c.env);
break; break;
case LUA_TUSERDATA: case LUA_TUSERDATA:
sethvalue(L, L.top, uvalue(o).env); sethvalue(L, L.top, uvalue(o).env);
break; break;
case LUA_TTHREAD: case LUA_TTHREAD:
setobj2s(L, L.top, gt(thvalue(o))); setobj2s(L, L.top, gt(thvalue(o)));
break; break;
default: default:
setnilvalue(L.top); setnilvalue(L.top);
break; break;
} }
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
/* /*
** set functions (stack . Lua) ** set functions (stack . Lua)
*/ */
public static void lua_settable (lua_State L, int idx) { public static void lua_settable (lua_State L, int idx) {
StkId t; StkId t;
lua_lock(L); lua_lock(L);
api_checknelems(L, 2); api_checknelems(L, 2);
t = index2adr(L, idx); t = index2adr(L, idx);
api_checkvalidindex(L, t); api_checkvalidindex(L, t);
luaV_settable(L, t, L.top - 2, L.top - 1); luaV_settable(L, t, L.top - 2, L.top - 1);
L.top -= 2; /* pop index and value */ L.top -= 2; /* pop index and value */
lua_unlock(L); lua_unlock(L);
} }
public static void lua_setfield (lua_State L, int idx, CharPtr k) { public static void lua_setfield (lua_State L, int idx, CharPtr k) {
StkId t; StkId t;
TValue key = new TValue(); TValue key = new TValue();
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
t = index2adr(L, idx); t = index2adr(L, idx);
api_checkvalidindex(L, t); api_checkvalidindex(L, t);
setsvalue(L, key, luaS_new(L, k)); setsvalue(L, key, luaS_new(L, k));
luaV_settable(L, t, key, L.top - 1); luaV_settable(L, t, key, L.top - 1);
StkId.dec(ref L.top); /* pop value */ StkId.dec(ref L.top); /* pop value */
lua_unlock(L); lua_unlock(L);
} }
public static void lua_rawset (lua_State L, int idx) { public static void lua_rawset (lua_State L, int idx) {
StkId t; StkId t;
lua_lock(L); lua_lock(L);
api_checknelems(L, 2); api_checknelems(L, 2);
t = index2adr(L, idx); t = index2adr(L, idx);
api_check(L, ttistable(t)); api_check(L, ttistable(t));
setobj2t(L, luaH_set(L, hvalue(t), L.top-2), L.top-1); setobj2t(L, luaH_set(L, hvalue(t), L.top-2), L.top-1);
luaC_barriert(L, hvalue(t), L.top-1); luaC_barriert(L, hvalue(t), L.top-1);
L.top -= 2; L.top -= 2;
lua_unlock(L); lua_unlock(L);
} }
public static void lua_rawseti (lua_State L, int idx, int n) { public static void lua_rawseti (lua_State L, int idx, int n) {
StkId o; StkId o;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
o = index2adr(L, idx); o = index2adr(L, idx);
api_check(L, ttistable(o)); api_check(L, ttistable(o));
setobj2t(L, luaH_setnum(L, hvalue(o), n), L.top-1); setobj2t(L, luaH_setnum(L, hvalue(o), n), L.top-1);
luaC_barriert(L, hvalue(o), L.top-1); luaC_barriert(L, hvalue(o), L.top-1);
StkId.dec(ref L.top); StkId.dec(ref L.top);
lua_unlock(L); lua_unlock(L);
} }
public static int lua_setmetatable (lua_State L, int objindex) { public static int lua_setmetatable (lua_State L, int objindex) {
TValue obj; TValue obj;
Table mt; Table mt;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
obj = index2adr(L, objindex); obj = index2adr(L, objindex);
api_checkvalidindex(L, obj); api_checkvalidindex(L, obj);
if (ttisnil(L.top - 1)) if (ttisnil(L.top - 1))
mt = null; mt = null;
else { else {
api_check(L, ttistable(L.top - 1)); api_check(L, ttistable(L.top - 1));
mt = hvalue(L.top - 1); mt = hvalue(L.top - 1);
} }
switch (ttype(obj)) { switch (ttype(obj)) {
case LUA_TTABLE: { case LUA_TTABLE: {
hvalue(obj).metatable = mt; hvalue(obj).metatable = mt;
if (mt != null) if (mt != null)
luaC_objbarriert(L, hvalue(obj), mt); luaC_objbarriert(L, hvalue(obj), mt);
break; break;
} }
case LUA_TUSERDATA: { case LUA_TUSERDATA: {
uvalue(obj).metatable = mt; uvalue(obj).metatable = mt;
if (mt != null) if (mt != null)
luaC_objbarrier(L, rawuvalue(obj), mt); luaC_objbarrier(L, rawuvalue(obj), mt);
break; break;
} }
default: { default: {
G(L).mt[ttype(obj)] = mt; G(L).mt[ttype(obj)] = mt;
break; break;
} }
} }
StkId.dec(ref L.top); StkId.dec(ref L.top);
lua_unlock(L); lua_unlock(L);
return 1; return 1;
} }
public static int lua_setfenv (lua_State L, int idx) { public static int lua_setfenv (lua_State L, int idx) {
StkId o; StkId o;
int res = 1; int res = 1;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
o = index2adr(L, idx); o = index2adr(L, idx);
api_checkvalidindex(L, o); api_checkvalidindex(L, o);
api_check(L, ttistable(L.top - 1)); api_check(L, ttistable(L.top - 1));
switch (ttype(o)) { switch (ttype(o)) {
case LUA_TFUNCTION: case LUA_TFUNCTION:
clvalue(o).c.env = hvalue(L.top - 1); clvalue(o).c.env = hvalue(L.top - 1);
break; break;
case LUA_TUSERDATA: case LUA_TUSERDATA:
uvalue(o).env = hvalue(L.top - 1); uvalue(o).env = hvalue(L.top - 1);
break; break;
case LUA_TTHREAD: case LUA_TTHREAD:
sethvalue(L, gt(thvalue(o)), hvalue(L.top - 1)); sethvalue(L, gt(thvalue(o)), hvalue(L.top - 1));
break; break;
default: default:
res = 0; res = 0;
break; break;
} }
if (res != 0) luaC_objbarrier(L, gcvalue(o), hvalue(L.top - 1)); if (res != 0) luaC_objbarrier(L, gcvalue(o), hvalue(L.top - 1));
StkId.dec(ref L.top); StkId.dec(ref L.top);
lua_unlock(L); lua_unlock(L);
return res; return res;
} }
/* /*
** `load' and `call' functions (run Lua code) ** `load' and `call' functions (run Lua code)
*/ */
public static void adjustresults(lua_State L, int nres) { public static void adjustresults(lua_State L, int nres) {
if (nres == LUA_MULTRET && L.top >= L.ci.top) if (nres == LUA_MULTRET && L.top >= L.ci.top)
L.ci.top = L.top; L.ci.top = L.top;
} }
public static void checkresults(lua_State L, int na, int nr) { public static void checkresults(lua_State L, int na, int nr) {
api_check(L, (nr) == LUA_MULTRET || (L.ci.top - L.top >= (nr) - (na))); api_check(L, (nr) == LUA_MULTRET || (L.ci.top - L.top >= (nr) - (na)));
} }
public static void lua_call (lua_State L, int nargs, int nresults) { public static void lua_call (lua_State L, int nargs, int nresults) {
StkId func; StkId func;
lua_lock(L); lua_lock(L);
api_checknelems(L, nargs+1); api_checknelems(L, nargs+1);
checkresults(L, nargs, nresults); checkresults(L, nargs, nresults);
func = L.top - (nargs+1); func = L.top - (nargs+1);
luaD_call(L, func, nresults); luaD_call(L, func, nresults);
adjustresults(L, nresults); adjustresults(L, nresults);
lua_unlock(L); lua_unlock(L);
} }
/* /*
** Execute a protected call. ** Execute a protected call.
*/ */
public class CallS { /* data to `f_call' */ public class CallS { /* data to `f_call' */
public StkId func; public StkId func;
public int nresults; public int nresults;
}; };
static void f_call (lua_State L, object ud) { static void f_call (lua_State L, object ud) {
CallS c = ud as CallS; CallS c = ud as CallS;
luaD_call(L, c.func, c.nresults); luaD_call(L, c.func, c.nresults);
} }
public static int lua_pcall (lua_State L, int nargs, int nresults, int errfunc) { public static int lua_pcall (lua_State L, int nargs, int nresults, int errfunc) {
CallS c = new CallS(); CallS c = new CallS();
int status; int status;
ptrdiff_t func; ptrdiff_t func;
lua_lock(L); lua_lock(L);
api_checknelems(L, nargs+1); api_checknelems(L, nargs+1);
checkresults(L, nargs, nresults); checkresults(L, nargs, nresults);
if (errfunc == 0) if (errfunc == 0)
func = 0; func = 0;
else { else {
StkId o = index2adr(L, errfunc); StkId o = index2adr(L, errfunc);
api_checkvalidindex(L, o); api_checkvalidindex(L, o);
func = savestack(L, o); func = savestack(L, o);
} }
c.func = L.top - (nargs+1); /* function to be called */ c.func = L.top - (nargs+1); /* function to be called */
c.nresults = nresults; c.nresults = nresults;
status = luaD_pcall(L, f_call, c, savestack(L, c.func), func); status = luaD_pcall(L, f_call, c, savestack(L, c.func), func);
adjustresults(L, nresults); adjustresults(L, nresults);
lua_unlock(L); lua_unlock(L);
return status; return status;
} }
/* /*
** Execute a protected C call. ** Execute a protected C call.
*/ */
public class CCallS { /* data to `f_Ccall' */ public class CCallS { /* data to `f_Ccall' */
public lua_CFunction func; public lua_CFunction func;
public object ud; public object ud;
}; };
static void f_Ccall (lua_State L, object ud) { static void f_Ccall (lua_State L, object ud) {
CCallS c = ud as CCallS; CCallS c = ud as CCallS;
Closure cl; Closure cl;
cl = luaF_newCclosure(L, 0, getcurrenv(L)); cl = luaF_newCclosure(L, 0, getcurrenv(L));
cl.c.f = c.func; cl.c.f = c.func;
setclvalue(L, L.top, cl); /* push function */ setclvalue(L, L.top, cl); /* push function */
api_incr_top(L); api_incr_top(L);
setpvalue(L.top, c.ud); /* push only argument */ setpvalue(L.top, c.ud); /* push only argument */
api_incr_top(L); api_incr_top(L);
luaD_call(L, L.top - 2, 0); luaD_call(L, L.top - 2, 0);
} }
public static int lua_cpcall (lua_State L, lua_CFunction func, object ud) { public static int lua_cpcall (lua_State L, lua_CFunction func, object ud) {
CCallS c = new CCallS(); CCallS c = new CCallS();
int status; int status;
lua_lock(L); lua_lock(L);
c.func = func; c.func = func;
c.ud = ud; c.ud = ud;
status = luaD_pcall(L, f_Ccall, c, savestack(L, L.top), 0); status = luaD_pcall(L, f_Ccall, c, savestack(L, L.top), 0);
lua_unlock(L); lua_unlock(L);
return status; return status;
} }
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public static int lua_load (lua_State L, lua_Reader reader, object data, public static int lua_load (lua_State L, lua_Reader reader, object data,
CharPtr chunkname) { CharPtr chunkname) {
ZIO z = new ZIO(); ZIO z = new ZIO();
int status; int status;
lua_lock(L); lua_lock(L);
if (chunkname == null) chunkname = "?"; if (chunkname == null) chunkname = "?";
luaZ_init(L, z, reader, data); luaZ_init(L, z, reader, data);
status = luaD_protectedparser(L, z, chunkname); status = luaD_protectedparser(L, z, chunkname);
lua_unlock(L); lua_unlock(L);
return status; return status;
} }
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public static int lua_dump (lua_State L, lua_Writer writer, object data) { public static int lua_dump (lua_State L, lua_Writer writer, object data) {
int status; int status;
TValue o; TValue o;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
o = L.top - 1; o = L.top - 1;
if (isLfunction(o)) if (isLfunction(o))
status = luaU_dump(L, clvalue(o).l.p, writer, data, 0); status = luaU_dump(L, clvalue(o).l.p, writer, data, 0);
else else
status = 1; status = 1;
lua_unlock(L); lua_unlock(L);
return status; return status;
} }
public static int lua_status (lua_State L) { public static int lua_status (lua_State L) {
return L.status; return L.status;
} }
/* /*
** Garbage-collection function ** Garbage-collection function
*/ */
public static int lua_gc (lua_State L, int what, int data) { public static int lua_gc (lua_State L, int what, int data) {
int res = 0; int res = 0;
global_State g; global_State g;
lua_lock(L); lua_lock(L);
g = G(L); g = G(L);
switch (what) { switch (what) {
case LUA_GCSTOP: { case LUA_GCSTOP: {
g.GCthreshold = MAX_LUMEM; g.GCthreshold = MAX_LUMEM;
break; break;
} }
case LUA_GCRESTART: { case LUA_GCRESTART: {
g.GCthreshold = g.totalbytes; g.GCthreshold = g.totalbytes;
break; break;
} }
case LUA_GCCOLLECT: { case LUA_GCCOLLECT: {
luaC_fullgc(L); luaC_fullgc(L);
break; break;
} }
case LUA_GCCOUNT: { case LUA_GCCOUNT: {
/* GC values are expressed in Kbytes: #bytes/2^10 */ /* GC values are expressed in Kbytes: #bytes/2^10 */
res = cast_int(g.totalbytes >> 10); res = cast_int(g.totalbytes >> 10);
break; break;
} }
case LUA_GCCOUNTB: { case LUA_GCCOUNTB: {
res = cast_int(g.totalbytes & 0x3ff); res = cast_int(g.totalbytes & 0x3ff);
break; break;
} }
case LUA_GCSTEP: { case LUA_GCSTEP: {
lu_mem a = ((lu_mem)data << 10); lu_mem a = ((lu_mem)data << 10);
if (a <= g.totalbytes) if (a <= g.totalbytes)
g.GCthreshold = (uint)(g.totalbytes - a); g.GCthreshold = (uint)(g.totalbytes - a);
else else
g.GCthreshold = 0; g.GCthreshold = 0;
while (g.GCthreshold <= g.totalbytes) { while (g.GCthreshold <= g.totalbytes) {
luaC_step(L); luaC_step(L);
if (g.gcstate == GCSpause) { /* end of cycle? */ if (g.gcstate == GCSpause) { /* end of cycle? */
res = 1; /* signal it */ res = 1; /* signal it */
break; break;
} }
} }
break; break;
} }
case LUA_GCSETPAUSE: { case LUA_GCSETPAUSE: {
res = g.gcpause; res = g.gcpause;
g.gcpause = data; g.gcpause = data;
break; break;
} }
case LUA_GCSETSTEPMUL: { case LUA_GCSETSTEPMUL: {
res = g.gcstepmul; res = g.gcstepmul;
g.gcstepmul = data; g.gcstepmul = data;
break; break;
} }
default: default:
res = -1; /* invalid option */ res = -1; /* invalid option */
break; break;
} }
lua_unlock(L); lua_unlock(L);
return res; return res;
} }
/* /*
** miscellaneous functions ** miscellaneous functions
*/ */
public static int lua_error (lua_State L) { public static int lua_error (lua_State L) {
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
luaG_errormsg(L); luaG_errormsg(L);
lua_unlock(L); lua_unlock(L);
return 0; /* to avoid warnings */ return 0; /* to avoid warnings */
} }
public static int lua_next (lua_State L, int idx) { public static int lua_next (lua_State L, int idx) {
StkId t; StkId t;
int more; int more;
lua_lock(L); lua_lock(L);
t = index2adr(L, idx); t = index2adr(L, idx);
api_check(L, ttistable(t)); api_check(L, ttistable(t));
more = luaH_next(L, hvalue(t), L.top - 1); more = luaH_next(L, hvalue(t), L.top - 1);
if (more != 0) { if (more != 0) {
api_incr_top(L); api_incr_top(L);
} }
else /* no more elements */ else /* no more elements */
StkId.dec(ref L.top); /* remove key */ StkId.dec(ref L.top); /* remove key */
lua_unlock(L); lua_unlock(L);
return more; return more;
} }
public static void lua_concat (lua_State L, int n) { public static void lua_concat (lua_State L, int n) {
lua_lock(L); lua_lock(L);
api_checknelems(L, n); api_checknelems(L, n);
if (n >= 2) { if (n >= 2) {
luaC_checkGC(L); luaC_checkGC(L);
luaV_concat(L, n, cast_int(L.top - L.base_) - 1); luaV_concat(L, n, cast_int(L.top - L.base_) - 1);
L.top -= (n-1); L.top -= (n-1);
} }
else if (n == 0) { /* push empty string */ else if (n == 0) { /* push empty string */
setsvalue2s(L, L.top, luaS_newlstr(L, "", 0)); setsvalue2s(L, L.top, luaS_newlstr(L, "", 0));
api_incr_top(L); api_incr_top(L);
} }
/* else n == 1; nothing to do */ /* else n == 1; nothing to do */
lua_unlock(L); lua_unlock(L);
} }
public static lua_Alloc lua_getallocf (lua_State L, ref object ud) { public static lua_Alloc lua_getallocf (lua_State L, ref object ud) {
lua_Alloc f; lua_Alloc f;
lua_lock(L); lua_lock(L);
if (ud != null) ud = G(L).ud; if (ud != null) ud = G(L).ud;
f = G(L).frealloc; f = G(L).frealloc;
lua_unlock(L); lua_unlock(L);
return f; return f;
} }
public static void lua_setallocf (lua_State L, lua_Alloc f, object ud) { public static void lua_setallocf (lua_State L, lua_Alloc f, object ud) {
lua_lock(L); lua_lock(L);
G(L).ud = ud; G(L).ud = ud;
G(L).frealloc = f; G(L).frealloc = f;
lua_unlock(L); lua_unlock(L);
} }
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public static object lua_newuserdata(lua_State L, uint size) public static object lua_newuserdata(lua_State L, uint size)
{ {
Udata u; Udata u;
lua_lock(L); lua_lock(L);
luaC_checkGC(L); luaC_checkGC(L);
u = luaS_newudata(L, size, getcurrenv(L)); u = luaS_newudata(L, size, getcurrenv(L));
setuvalue(L, L.top, u); setuvalue(L, L.top, u);
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
return u.user_data; return u.user_data;
} }
// this one is used internally only // this one is used internally only
internal static object lua_newuserdata(lua_State L, Type t) internal static object lua_newuserdata(lua_State L, Type t)
{ {
Udata u; Udata u;
lua_lock(L); lua_lock(L);
luaC_checkGC(L); luaC_checkGC(L);
u = luaS_newudata(L, t, getcurrenv(L)); u = luaS_newudata(L, t, getcurrenv(L));
setuvalue(L, L.top, u); setuvalue(L, L.top, u);
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
return u.user_data; return u.user_data;
} }
static CharPtr aux_upvalue (StkId fi, int n, ref TValue val) { static CharPtr aux_upvalue (StkId fi, int n, ref TValue val) {
Closure f; Closure f;
if (!ttisfunction(fi)) return null; if (!ttisfunction(fi)) return null;
f = clvalue(fi); f = clvalue(fi);
if (f.c.isC != 0) { if (f.c.isC != 0) {
if (!(1 <= n && n <= f.c.nupvalues)) return null; if (!(1 <= n && n <= f.c.nupvalues)) return null;
val = f.c.upvalue[n-1]; val = f.c.upvalue[n-1];
return ""; return "";
} }
else { else {
Proto p = f.l.p; Proto p = f.l.p;
if (!(1 <= n && n <= p.sizeupvalues)) return null; if (!(1 <= n && n <= p.sizeupvalues)) return null;
val = f.l.upvals[n-1].v; val = f.l.upvals[n-1].v;
return getstr(p.upvalues[n-1]); return getstr(p.upvalues[n-1]);
} }
} }
public static CharPtr lua_getupvalue (lua_State L, int funcindex, int n) { public static CharPtr lua_getupvalue (lua_State L, int funcindex, int n) {
CharPtr name; CharPtr name;
TValue val = new TValue(); TValue val = new TValue();
lua_lock(L); lua_lock(L);
name = aux_upvalue(index2adr(L, funcindex), n, ref val); name = aux_upvalue(index2adr(L, funcindex), n, ref val);
if (name != null) { if (name != null) {
setobj2s(L, L.top, val); setobj2s(L, L.top, val);
api_incr_top(L); api_incr_top(L);
} }
lua_unlock(L); lua_unlock(L);
return name; return name;
} }
public static CharPtr lua_setupvalue (lua_State L, int funcindex, int n) { public static CharPtr lua_setupvalue (lua_State L, int funcindex, int n) {
CharPtr name; CharPtr name;
TValue val = new TValue(); TValue val = new TValue();
StkId fi; StkId fi;
lua_lock(L); lua_lock(L);
fi = index2adr(L, funcindex); fi = index2adr(L, funcindex);
api_checknelems(L, 1); api_checknelems(L, 1);
name = aux_upvalue(fi, n, ref val); name = aux_upvalue(fi, n, ref val);
if (name != null) { if (name != null) {
StkId.dec(ref L.top); StkId.dec(ref L.top);
setobj(L, val, L.top); setobj(L, val, L.top);
luaC_barrier(L, clvalue(fi), L.top); luaC_barrier(L, clvalue(fi), L.top);
} }
lua_unlock(L); lua_unlock(L);
return name; return name;
} }
} }
} }
/* /*
** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $ ** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $
** Auxiliary functions for building Lua libraries ** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
#define lauxlib_c #define lauxlib_c
#define LUA_LIB #define LUA_LIB
using System; using System;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace KopiLua namespace KopiLua
{ {
using lua_Number = System.Double; using lua_Number = System.Double;
using lua_Integer = System.Int32; using lua_Integer = System.Int32;
public partial class Lua public partial class Lua
{ {
#if LUA_COMPAT_GETN #if LUA_COMPAT_GETN
public static int luaL_getn(lua_State L, int t); public static int luaL_getn(lua_State L, int t);
public static void luaL_setn(lua_State L, int t, int n); public static void luaL_setn(lua_State L, int t, int n);
#else #else
public static int luaL_getn(lua_State L, int i) {return (int)lua_objlen(L, i);} public static int luaL_getn(lua_State L, int i) {return (int)lua_objlen(L, i);}
public static void luaL_setn(lua_State L, int i, int j) {} /* no op! */ public static void luaL_setn(lua_State L, int i, int j) {} /* no op! */
#endif #endif
#if LUA_COMPAT_OPENLIB #if LUA_COMPAT_OPENLIB
//#define luaI_openlib luaL_openlib //#define luaI_openlib luaL_openlib
#endif #endif
/* extra error code for `luaL_load' */ /* extra error code for `luaL_load' */
public const int LUA_ERRFILE = (LUA_ERRERR+1); public const int LUA_ERRFILE = (LUA_ERRERR+1);
public class luaL_Reg { public class luaL_Reg {
public luaL_Reg(CharPtr name, lua_CFunction func) { public luaL_Reg(CharPtr name, lua_CFunction func) {
this.name = name; this.name = name;
this.func = func; this.func = func;
} }
public CharPtr name; public CharPtr name;
public lua_CFunction func; public lua_CFunction func;
}; };
/* /*
** =============================================================== ** ===============================================================
** some useful macros ** some useful macros
** =============================================================== ** ===============================================================
*/ */
public static void luaL_argcheck(lua_State L, bool cond, int numarg, string extramsg) { public static void luaL_argcheck(lua_State L, bool cond, int numarg, string extramsg) {
if (!cond) if (!cond)
luaL_argerror(L, numarg, extramsg); luaL_argerror(L, numarg, extramsg);
} }
public static CharPtr luaL_checkstring(lua_State L, int n) { return luaL_checklstring(L, n); } public static CharPtr luaL_checkstring(lua_State L, int n) { return luaL_checklstring(L, n); }
public static CharPtr luaL_optstring(lua_State L, int n, CharPtr d) { uint len; return luaL_optlstring(L, n, d, out len); } public static CharPtr luaL_optstring(lua_State L, int n, CharPtr d) { uint len; return luaL_optlstring(L, n, d, out len); }
public static int luaL_checkint(lua_State L, int n) {return (int)luaL_checkinteger(L, n);} public static int luaL_checkint(lua_State L, int n) {return (int)luaL_checkinteger(L, n);}
public static int luaL_optint(lua_State L, int n, lua_Integer d) {return (int)luaL_optinteger(L, n, d);} public static int luaL_optint(lua_State L, int n, lua_Integer d) {return (int)luaL_optinteger(L, n, d);}
public static long luaL_checklong(lua_State L, int n) {return luaL_checkinteger(L, n);} public static long luaL_checklong(lua_State L, int n) {return luaL_checkinteger(L, n);}
public static long luaL_optlong(lua_State L, int n, lua_Integer d) {return luaL_optinteger(L, n, d);} public static long luaL_optlong(lua_State L, int n, lua_Integer d) {return luaL_optinteger(L, n, d);}
public static CharPtr luaL_typename(lua_State L, int i) {return lua_typename(L, lua_type(L,i));} public static CharPtr luaL_typename(lua_State L, int i) {return lua_typename(L, lua_type(L,i));}
//#define luaL_dofile(L, fn) \ //#define luaL_dofile(L, fn) \
// (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) // (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
//#define luaL_dostring(L, s) \ //#define luaL_dostring(L, s) \
// (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) // (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
public static void luaL_getmetatable(lua_State L, CharPtr n) { lua_getfield(L, LUA_REGISTRYINDEX, n); } public static void luaL_getmetatable(lua_State L, CharPtr n) { lua_getfield(L, LUA_REGISTRYINDEX, n); }
public delegate lua_Number luaL_opt_delegate (lua_State L, int narg); public delegate lua_Number luaL_opt_delegate (lua_State L, int narg);
public static lua_Number luaL_opt(lua_State L, luaL_opt_delegate f, int n, lua_Number d) { public static lua_Number luaL_opt(lua_State L, luaL_opt_delegate f, int n, lua_Number d) {
return lua_isnoneornil(L, (n != 0) ? d : f(L, n)) ? 1 : 0;} return lua_isnoneornil(L, (n != 0) ? d : f(L, n)) ? 1 : 0;}
public delegate lua_Integer luaL_opt_delegate_integer(lua_State L, int narg); public delegate lua_Integer luaL_opt_delegate_integer(lua_State L, int narg);
public static lua_Integer luaL_opt_integer(lua_State L, luaL_opt_delegate_integer f, int n, lua_Number d) { public static lua_Integer luaL_opt_integer(lua_State L, luaL_opt_delegate_integer f, int n, lua_Number d) {
return (lua_Integer)(lua_isnoneornil(L, n) ? d : f(L, (n))); return (lua_Integer)(lua_isnoneornil(L, n) ? d : f(L, (n)));
} }
/* /*
** {====================================================== ** {======================================================
** Generic Buffer manipulation ** Generic Buffer manipulation
** ======================================================= ** =======================================================
*/ */
public class luaL_Buffer { public class luaL_Buffer {
public int p; /* current position in buffer */ public int p; /* current position in buffer */
public int lvl; /* number of strings in the stack (level) */ public int lvl; /* number of strings in the stack (level) */
public lua_State L; public lua_State L;
public CharPtr buffer = new char[LUAL_BUFFERSIZE]; public CharPtr buffer = new char[LUAL_BUFFERSIZE];
}; };
public static void luaL_addchar(luaL_Buffer B, char c) { public static void luaL_addchar(luaL_Buffer B, char c) {
if (B.p >= LUAL_BUFFERSIZE) if (B.p >= LUAL_BUFFERSIZE)
luaL_prepbuffer(B); luaL_prepbuffer(B);
B.buffer[B.p++] = c; B.buffer[B.p++] = c;
} }
///* compatibility only */ ///* compatibility only */
public static void luaL_putchar(luaL_Buffer B, char c) {luaL_addchar(B,c);} public static void luaL_putchar(luaL_Buffer B, char c) {luaL_addchar(B,c);}
public static void luaL_addsize(luaL_Buffer B, int n) {B.p += n;} public static void luaL_addsize(luaL_Buffer B, int n) {B.p += n;}
/* }====================================================== */ /* }====================================================== */
/* compatibility with ref system */ /* compatibility with ref system */
/* pre-defined references */ /* pre-defined references */
public const int LUA_NOREF = (-2); public const int LUA_NOREF = (-2);
public const int LUA_REFNIL = (-1); public const int LUA_REFNIL = (-1);
//#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ //#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
// (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) // (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
//#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) //#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
//#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) //#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
//#define luaL_reg luaL_Reg //#define luaL_reg luaL_Reg
/* This file uses only the official API of Lua. /* This file uses only the official API of Lua.
** Any function declared here could be written as an application function. ** Any function declared here could be written as an application function.
*/ */
//#define lauxlib_c //#define lauxlib_c
//#define LUA_LIB //#define LUA_LIB
public const int FREELIST_REF = 0; /* free list of references */ public const int FREELIST_REF = 0; /* free list of references */
/* convert a stack index to positive */ /* convert a stack index to positive */
public static int abs_index(lua_State L, int i) public static int abs_index(lua_State L, int i)
{ {
return ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1); return ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1);
} }
/* /*
** {====================================================== ** {======================================================
** Error-report functions ** Error-report functions
** ======================================================= ** =======================================================
*/ */
public static int luaL_argerror (lua_State L, int narg, CharPtr extramsg) { public static int luaL_argerror (lua_State L, int narg, CharPtr extramsg) {
lua_Debug ar = new lua_Debug(); lua_Debug ar = new lua_Debug();
if (lua_getstack(L, 0, ar)==0) /* no stack frame? */ if (lua_getstack(L, 0, ar)==0) /* no stack frame? */
return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
lua_getinfo(L, "n", ar); lua_getinfo(L, "n", ar);
if (strcmp(ar.namewhat, "method") == 0) { if (strcmp(ar.namewhat, "method") == 0) {
narg--; /* do not count `self' */ narg--; /* do not count `self' */
if (narg == 0) /* error is in the self argument itself? */ if (narg == 0) /* error is in the self argument itself? */
return luaL_error(L, "calling " + LUA_QS + " on bad self ({1})", return luaL_error(L, "calling " + LUA_QS + " on bad self ({1})",
ar.name, extramsg); ar.name, extramsg);
} }
if (ar.name == null) if (ar.name == null)
ar.name = "?"; ar.name = "?";
return luaL_error(L, "bad argument #%d to " + LUA_QS + " (%s)", return luaL_error(L, "bad argument #%d to " + LUA_QS + " (%s)",
narg, ar.name, extramsg); narg, ar.name, extramsg);
} }
public static int luaL_typerror (lua_State L, int narg, CharPtr tname) { public static int luaL_typerror (lua_State L, int narg, CharPtr tname) {
CharPtr msg = lua_pushfstring(L, "%s expected, got %s", CharPtr msg = lua_pushfstring(L, "%s expected, got %s",
tname, luaL_typename(L, narg)); tname, luaL_typename(L, narg));
return luaL_argerror(L, narg, msg); return luaL_argerror(L, narg, msg);
} }
private static void tag_error (lua_State L, int narg, int tag) { private static void tag_error (lua_State L, int narg, int tag) {
luaL_typerror(L, narg, lua_typename(L, tag)); luaL_typerror(L, narg, lua_typename(L, tag));
} }
public static void luaL_where (lua_State L, int level) { public static void luaL_where (lua_State L, int level) {
lua_Debug ar = new lua_Debug(); lua_Debug ar = new lua_Debug();
if (lua_getstack(L, level, ar) != 0) { /* check function at level */ if (lua_getstack(L, level, ar) != 0) { /* check function at level */
lua_getinfo(L, "Sl", ar); /* get info about it */ lua_getinfo(L, "Sl", ar); /* get info about it */
if (ar.currentline > 0) { /* is there info? */ if (ar.currentline > 0) { /* is there info? */
lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
return; return;
} }
} }
lua_pushliteral(L, ""); /* else, no information available... */ lua_pushliteral(L, ""); /* else, no information available... */
} }
public static int luaL_error(lua_State L, CharPtr fmt, params object[] p) public static int luaL_error(lua_State L, CharPtr fmt, params object[] p)
{ {
luaL_where(L, 1); luaL_where(L, 1);
lua_pushvfstring(L, fmt, p); lua_pushvfstring(L, fmt, p);
lua_concat(L, 2); lua_concat(L, 2);
return lua_error(L); return lua_error(L);
} }
/* }====================================================== */ /* }====================================================== */
public static int luaL_checkoption (lua_State L, int narg, CharPtr def, public static int luaL_checkoption (lua_State L, int narg, CharPtr def,
CharPtr [] lst) { CharPtr [] lst) {
CharPtr name = (def != null) ? luaL_optstring(L, narg, def) : CharPtr name = (def != null) ? luaL_optstring(L, narg, def) :
luaL_checkstring(L, narg); luaL_checkstring(L, narg);
int i; int i;
for (i=0; i<lst.Length; i++) for (i=0; i<lst.Length; i++)
if (strcmp(lst[i], name)==0) if (strcmp(lst[i], name)==0)
return i; return i;
return luaL_argerror(L, narg, return luaL_argerror(L, narg,
lua_pushfstring(L, "invalid option " + LUA_QS, name)); lua_pushfstring(L, "invalid option " + LUA_QS, name));
} }
public static int luaL_newmetatable (lua_State L, CharPtr tname) { public static int luaL_newmetatable (lua_State L, CharPtr tname) {
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
if (!lua_isnil(L, -1)) /* name already in use? */ if (!lua_isnil(L, -1)) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */ return 0; /* leave previous value on top, but return 0 */
lua_pop(L, 1); lua_pop(L, 1);
lua_newtable(L); /* create metatable */ lua_newtable(L); /* create metatable */
lua_pushvalue(L, -1); lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
return 1; return 1;
} }
public static object luaL_checkudata (lua_State L, int ud, CharPtr tname) { public static object luaL_checkudata (lua_State L, int ud, CharPtr tname) {
object p = lua_touserdata(L, ud); object p = lua_touserdata(L, ud);
if (p != null) { /* value is a userdata? */ if (p != null) { /* value is a userdata? */
if (lua_getmetatable(L, ud) != 0) { /* does it have a metatable? */ if (lua_getmetatable(L, ud) != 0) { /* does it have a metatable? */
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
if (lua_rawequal(L, -1, -2) != 0) { /* does it have the correct mt? */ if (lua_rawequal(L, -1, -2) != 0) { /* does it have the correct mt? */
lua_pop(L, 2); /* remove both metatables */ lua_pop(L, 2); /* remove both metatables */
return p; return p;
} }
} }
} }
luaL_typerror(L, ud, tname); /* else error */ luaL_typerror(L, ud, tname); /* else error */
return null; /* to avoid warnings */ return null; /* to avoid warnings */
} }
public static void luaL_checkstack (lua_State L, int space, CharPtr mes) { public static void luaL_checkstack (lua_State L, int space, CharPtr mes) {
if (lua_checkstack(L, space) == 0) if (lua_checkstack(L, space) == 0)
luaL_error(L, "stack overflow (%s)", mes); luaL_error(L, "stack overflow (%s)", mes);
} }
public static void luaL_checktype (lua_State L, int narg, int t) { public static void luaL_checktype (lua_State L, int narg, int t) {
if (lua_type(L, narg) != t) if (lua_type(L, narg) != t)
tag_error(L, narg, t); tag_error(L, narg, t);
} }
public static void luaL_checkany (lua_State L, int narg) { public static void luaL_checkany (lua_State L, int narg) {
if (lua_type(L, narg) == LUA_TNONE) if (lua_type(L, narg) == LUA_TNONE)
luaL_argerror(L, narg, "value expected"); luaL_argerror(L, narg, "value expected");
} }
public static CharPtr luaL_checklstring(lua_State L, int narg) {uint len; return luaL_checklstring(L, narg, out len);} public static CharPtr luaL_checklstring(lua_State L, int narg) {uint len; return luaL_checklstring(L, narg, out len);}
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public static CharPtr luaL_checklstring (lua_State L, int narg, out uint len) { public static CharPtr luaL_checklstring (lua_State L, int narg, out uint len) {
CharPtr s = lua_tolstring(L, narg, out len); CharPtr s = lua_tolstring(L, narg, out len);
if (s==null) tag_error(L, narg, LUA_TSTRING); if (s==null) tag_error(L, narg, LUA_TSTRING);
return s; return s;
} }
public static CharPtr luaL_optlstring (lua_State L, int narg, CharPtr def) { public static CharPtr luaL_optlstring (lua_State L, int narg, CharPtr def) {
uint len; return luaL_optlstring (L, narg, def, out len); } uint len; return luaL_optlstring (L, narg, def, out len); }
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public static CharPtr luaL_optlstring (lua_State L, int narg, CharPtr def, out uint len) { public static CharPtr luaL_optlstring (lua_State L, int narg, CharPtr def, out uint len) {
if (lua_isnoneornil(L, narg)) { if (lua_isnoneornil(L, narg)) {
len = (uint)((def != null) ? strlen(def) : 0); len = (uint)((def != null) ? strlen(def) : 0);
return def; return def;
} }
else return luaL_checklstring(L, narg, out len); else return luaL_checklstring(L, narg, out len);
} }
public static lua_Number luaL_checknumber (lua_State L, int narg) { public static lua_Number luaL_checknumber (lua_State L, int narg) {
lua_Number d = lua_tonumber(L, narg); lua_Number d = lua_tonumber(L, narg);
if ((d == 0) && (lua_isnumber(L, narg)==0)) /* avoid extra test when d is not 0 */ if ((d == 0) && (lua_isnumber(L, narg)==0)) /* avoid extra test when d is not 0 */
tag_error(L, narg, LUA_TNUMBER); tag_error(L, narg, LUA_TNUMBER);
return d; return d;
} }
public static lua_Number luaL_optnumber (lua_State L, int narg, lua_Number def) { public static lua_Number luaL_optnumber (lua_State L, int narg, lua_Number def) {
return luaL_opt(L, luaL_checknumber, narg, def); return luaL_opt(L, luaL_checknumber, narg, def);
} }
public static lua_Integer luaL_checkinteger (lua_State L, int narg) { public static lua_Integer luaL_checkinteger (lua_State L, int narg) {
lua_Integer d = lua_tointeger(L, narg); lua_Integer d = lua_tointeger(L, narg);
if (d == 0 && lua_isnumber(L, narg)==0) /* avoid extra test when d is not 0 */ if (d == 0 && lua_isnumber(L, narg)==0) /* avoid extra test when d is not 0 */
tag_error(L, narg, LUA_TNUMBER); tag_error(L, narg, LUA_TNUMBER);
return d; return d;
} }
public static lua_Integer luaL_optinteger (lua_State L, int narg, lua_Integer def) { public static lua_Integer luaL_optinteger (lua_State L, int narg, lua_Integer def) {
return luaL_opt_integer(L, luaL_checkinteger, narg, def); return luaL_opt_integer(L, luaL_checkinteger, narg, def);
} }
public static int luaL_getmetafield (lua_State L, int obj, CharPtr event_) { public static int luaL_getmetafield (lua_State L, int obj, CharPtr event_) {
if (lua_getmetatable(L, obj)==0) /* no metatable? */ if (lua_getmetatable(L, obj)==0) /* no metatable? */
return 0; return 0;
lua_pushstring(L, event_); lua_pushstring(L, event_);
lua_rawget(L, -2); lua_rawget(L, -2);
if (lua_isnil(L, -1)) { if (lua_isnil(L, -1)) {
lua_pop(L, 2); /* remove metatable and metafield */ lua_pop(L, 2); /* remove metatable and metafield */
return 0; return 0;
} }
else { else {
lua_remove(L, -2); /* remove only metatable */ lua_remove(L, -2); /* remove only metatable */
return 1; return 1;
} }
} }
public static int luaL_callmeta (lua_State L, int obj, CharPtr event_) { public static int luaL_callmeta (lua_State L, int obj, CharPtr event_) {
obj = abs_index(L, obj); obj = abs_index(L, obj);
if (luaL_getmetafield(L, obj, event_)==0) /* no metafield? */ if (luaL_getmetafield(L, obj, event_)==0) /* no metafield? */
return 0; return 0;
lua_pushvalue(L, obj); lua_pushvalue(L, obj);
lua_call(L, 1, 1); lua_call(L, 1, 1);
return 1; return 1;
} }
public static void luaL_register(lua_State L, CharPtr libname, public static void luaL_register(lua_State L, CharPtr libname,
luaL_Reg[] l) { luaL_Reg[] l) {
luaI_openlib(L, libname, l, 0); luaI_openlib(L, libname, l, 0);
} }
// we could just take the .Length member here, but let's try // we could just take the .Length member here, but let's try
// to keep it as close to the C implementation as possible. // to keep it as close to the C implementation as possible.
private static int libsize (luaL_Reg[] l) { private static int libsize (luaL_Reg[] l) {
int size = 0; int size = 0;
for (; l[size].name!=null; size++); for (; l[size].name!=null; size++);
return size; return size;
} }
public static void luaI_openlib (lua_State L, CharPtr libname, public static void luaI_openlib (lua_State L, CharPtr libname,
luaL_Reg[] l, int nup) { luaL_Reg[] l, int nup) {
if (libname!=null) { if (libname!=null) {
int size = libsize(l); int size = libsize(l);
/* check whether lib already exists */ /* check whether lib already exists */
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
lua_getfield(L, -1, libname); /* get _LOADED[libname] */ lua_getfield(L, -1, libname); /* get _LOADED[libname] */
if (!lua_istable(L, -1)) { /* not found? */ if (!lua_istable(L, -1)) { /* not found? */
lua_pop(L, 1); /* remove previous result */ lua_pop(L, 1); /* remove previous result */
/* try global variable (and create one if it does not exist) */ /* try global variable (and create one if it does not exist) */
if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != null) if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != null)
luaL_error(L, "name conflict for module " + LUA_QS, libname); luaL_error(L, "name conflict for module " + LUA_QS, libname);
lua_pushvalue(L, -1); lua_pushvalue(L, -1);
lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
} }
lua_remove(L, -2); /* remove _LOADED table */ lua_remove(L, -2); /* remove _LOADED table */
lua_insert(L, -(nup+1)); /* move library table to below upvalues */ lua_insert(L, -(nup+1)); /* move library table to below upvalues */
} }
int reg_num = 0; int reg_num = 0;
for (; l[reg_num].name!=null; reg_num++) { for (; l[reg_num].name!=null; reg_num++) {
int i; int i;
for (i=0; i<nup; i++) /* copy upvalues to the top */ for (i=0; i<nup; i++) /* copy upvalues to the top */
lua_pushvalue(L, -nup); lua_pushvalue(L, -nup);
lua_pushcclosure(L, l[reg_num].func, nup); lua_pushcclosure(L, l[reg_num].func, nup);
lua_setfield(L, -(nup+2), l[reg_num].name); lua_setfield(L, -(nup+2), l[reg_num].name);
} }
lua_pop(L, nup); /* remove upvalues */ lua_pop(L, nup); /* remove upvalues */
} }
/* /*
** {====================================================== ** {======================================================
** getn-setn: size for arrays ** getn-setn: size for arrays
** ======================================================= ** =======================================================
*/ */
#if LUA_COMPAT_GETN #if LUA_COMPAT_GETN
static int checkint (lua_State L, int topop) { static int checkint (lua_State L, int topop) {
int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
lua_pop(L, topop); lua_pop(L, topop);
return n; return n;
} }
static void getsizes (lua_State L) { static void getsizes (lua_State L) {
lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
if (lua_isnil(L, -1)) { /* no `size' table? */ if (lua_isnil(L, -1)) { /* no `size' table? */
lua_pop(L, 1); /* remove nil */ lua_pop(L, 1); /* remove nil */
lua_newtable(L); /* create it */ lua_newtable(L); /* create it */
lua_pushvalue(L, -1); /* `size' will be its own metatable */ lua_pushvalue(L, -1); /* `size' will be its own metatable */
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
lua_pushliteral(L, "kv"); lua_pushliteral(L, "kv");
lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */
lua_pushvalue(L, -1); lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */
} }
} }
public static void luaL_setn (lua_State L, int t, int n) { public static void luaL_setn (lua_State L, int t, int n) {
t = abs_index(L, t); t = abs_index(L, t);
lua_pushliteral(L, "n"); lua_pushliteral(L, "n");
lua_rawget(L, t); lua_rawget(L, t);
if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
lua_pushliteral(L, "n"); /* use it */ lua_pushliteral(L, "n"); /* use it */
lua_pushinteger(L, n); lua_pushinteger(L, n);
lua_rawset(L, t); lua_rawset(L, t);
} }
else { /* use `sizes' */ else { /* use `sizes' */
getsizes(L); getsizes(L);
lua_pushvalue(L, t); lua_pushvalue(L, t);
lua_pushinteger(L, n); lua_pushinteger(L, n);
lua_rawset(L, -3); /* sizes[t] = n */ lua_rawset(L, -3); /* sizes[t] = n */
lua_pop(L, 1); /* remove `sizes' */ lua_pop(L, 1); /* remove `sizes' */
} }
} }
public static int luaL_getn (lua_State L, int t) { public static int luaL_getn (lua_State L, int t) {
int n; int n;
t = abs_index(L, t); t = abs_index(L, t);
lua_pushliteral(L, "n"); /* try t.n */ lua_pushliteral(L, "n"); /* try t.n */
lua_rawget(L, t); lua_rawget(L, t);
if ((n = checkint(L, 1)) >= 0) return n; if ((n = checkint(L, 1)) >= 0) return n;
getsizes(L); /* else try sizes[t] */ getsizes(L); /* else try sizes[t] */
lua_pushvalue(L, t); lua_pushvalue(L, t);
lua_rawget(L, -2); lua_rawget(L, -2);
if ((n = checkint(L, 2)) >= 0) return n; if ((n = checkint(L, 2)) >= 0) return n;
return (int)lua_objlen(L, t); return (int)lua_objlen(L, t);
} }
#endif #endif
/* }====================================================== */ /* }====================================================== */
public static CharPtr luaL_gsub (lua_State L, CharPtr s, CharPtr p, public static CharPtr luaL_gsub (lua_State L, CharPtr s, CharPtr p,
CharPtr r) { CharPtr r) {
CharPtr wild; CharPtr wild;
uint l = (uint)strlen(p); uint l = (uint)strlen(p);
luaL_Buffer b = new luaL_Buffer(); luaL_Buffer b = new luaL_Buffer();
luaL_buffinit(L, b); luaL_buffinit(L, b);
while ((wild = strstr(s, p)) != null) { while ((wild = strstr(s, p)) != null) {
luaL_addlstring(b, s, (uint)(wild - s)); /* push prefix */ luaL_addlstring(b, s, (uint)(wild - s)); /* push prefix */
luaL_addstring(b, r); /* push replacement in place of pattern */ luaL_addstring(b, r); /* push replacement in place of pattern */
s = wild + l; /* continue after `p' */ s = wild + l; /* continue after `p' */
} }
luaL_addstring(b, s); /* push last suffix */ luaL_addstring(b, s); /* push last suffix */
luaL_pushresult(b); luaL_pushresult(b);
return lua_tostring(L, -1); return lua_tostring(L, -1);
} }
public static CharPtr luaL_findtable (lua_State L, int idx, public static CharPtr luaL_findtable (lua_State L, int idx,
CharPtr fname, int szhint) { CharPtr fname, int szhint) {
CharPtr e; CharPtr e;
lua_pushvalue(L, idx); lua_pushvalue(L, idx);
do { do {
e = strchr(fname, '.'); e = strchr(fname, '.');
if (e == null) e = fname + strlen(fname); if (e == null) e = fname + strlen(fname);
lua_pushlstring(L, fname, (uint)(e - fname)); lua_pushlstring(L, fname, (uint)(e - fname));
lua_rawget(L, -2); lua_rawget(L, -2);
if (lua_isnil(L, -1)) { /* no such field? */ if (lua_isnil(L, -1)) { /* no such field? */
lua_pop(L, 1); /* remove this nil */ lua_pop(L, 1); /* remove this nil */
lua_createtable(L, 0, (e == '.' ? 1 : szhint)); /* new table for field */ lua_createtable(L, 0, (e == '.' ? 1 : szhint)); /* new table for field */
lua_pushlstring(L, fname, (uint)(e - fname)); lua_pushlstring(L, fname, (uint)(e - fname));
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
lua_settable(L, -4); /* set new table into field */ lua_settable(L, -4); /* set new table into field */
} }
else if (!lua_istable(L, -1)) { /* field has a non-table value? */ else if (!lua_istable(L, -1)) { /* field has a non-table value? */
lua_pop(L, 2); /* remove table and value */ lua_pop(L, 2); /* remove table and value */
return fname; /* return problematic part of the name */ return fname; /* return problematic part of the name */
} }
lua_remove(L, -2); /* remove previous table */ lua_remove(L, -2); /* remove previous table */
fname = e + 1; fname = e + 1;
} while (e == '.'); } while (e == '.');
return null; return null;
} }
/* /*
** {====================================================== ** {======================================================
** Generic Buffer manipulation ** Generic Buffer manipulation
** ======================================================= ** =======================================================
*/ */
private static int bufflen(luaL_Buffer B) {return B.p;} private static int bufflen(luaL_Buffer B) {return B.p;}
private static int bufffree(luaL_Buffer B) {return LUAL_BUFFERSIZE - bufflen(B);} private static int bufffree(luaL_Buffer B) {return LUAL_BUFFERSIZE - bufflen(B);}
public const int LIMIT = LUA_MINSTACK / 2; public const int LIMIT = LUA_MINSTACK / 2;
private static int emptybuffer (luaL_Buffer B) { private static int emptybuffer (luaL_Buffer B) {
uint l = (uint)bufflen(B); uint l = (uint)bufflen(B);
if (l == 0) return 0; /* put nothing on stack */ if (l == 0) return 0; /* put nothing on stack */
else { else {
lua_pushlstring(B.L, B.buffer, l); lua_pushlstring(B.L, B.buffer, l);
B.p = 0; B.p = 0;
B.lvl++; B.lvl++;
return 1; return 1;
} }
} }
private static void adjuststack (luaL_Buffer B) { private static void adjuststack (luaL_Buffer B) {
if (B.lvl > 1) { if (B.lvl > 1) {
lua_State L = B.L; lua_State L = B.L;
int toget = 1; /* number of levels to concat */ int toget = 1; /* number of levels to concat */
uint toplen = lua_strlen(L, -1); uint toplen = lua_strlen(L, -1);
do { do {
uint l = lua_strlen(L, -(toget+1)); uint l = lua_strlen(L, -(toget+1));
if (B.lvl - toget + 1 >= LIMIT || toplen > l) { if (B.lvl - toget + 1 >= LIMIT || toplen > l) {
toplen += l; toplen += l;
toget++; toget++;
} }
else break; else break;
} while (toget < B.lvl); } while (toget < B.lvl);
lua_concat(L, toget); lua_concat(L, toget);
B.lvl = B.lvl - toget + 1; B.lvl = B.lvl - toget + 1;
} }
} }
public static CharPtr luaL_prepbuffer (luaL_Buffer B) { public static CharPtr luaL_prepbuffer (luaL_Buffer B) {
if (emptybuffer(B) != 0) if (emptybuffer(B) != 0)
adjuststack(B); adjuststack(B);
return new CharPtr(B.buffer, B.p); return new CharPtr(B.buffer, B.p);
} }
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public static void luaL_addlstring (luaL_Buffer B, CharPtr s, uint l) { public static void luaL_addlstring (luaL_Buffer B, CharPtr s, uint l) {
while (l-- != 0) while (l-- != 0)
{ {
char c = s[0]; char c = s[0];
s = s.next(); s = s.next();
luaL_addchar(B, c); luaL_addchar(B, c);
} }
} }
public static void luaL_addstring (luaL_Buffer B, CharPtr s) { public static void luaL_addstring (luaL_Buffer B, CharPtr s) {
luaL_addlstring(B, s, (uint)strlen(s)); luaL_addlstring(B, s, (uint)strlen(s));
} }
public static void luaL_pushresult (luaL_Buffer B) { public static void luaL_pushresult (luaL_Buffer B) {
emptybuffer(B); emptybuffer(B);
lua_concat(B.L, B.lvl); lua_concat(B.L, B.lvl);
B.lvl = 1; B.lvl = 1;
} }
public static void luaL_addvalue (luaL_Buffer B) { public static void luaL_addvalue (luaL_Buffer B) {
lua_State L = B.L; lua_State L = B.L;
uint vl; uint vl;
CharPtr s = lua_tolstring(L, -1, out vl); CharPtr s = lua_tolstring(L, -1, out vl);
if (vl <= bufffree(B)) { /* fit into buffer? */ if (vl <= bufffree(B)) { /* fit into buffer? */
CharPtr dst = new CharPtr(B.buffer.chars, B.buffer.index + B.p); CharPtr dst = new CharPtr(B.buffer.chars, B.buffer.index + B.p);
CharPtr src = new CharPtr(s.chars, s.index); CharPtr src = new CharPtr(s.chars, s.index);
for (uint i = 0; i < vl; i++) for (uint i = 0; i < vl; i++)
dst[i] = src[i]; dst[i] = src[i];
B.p += (int)vl; B.p += (int)vl;
lua_pop(L, 1); /* remove from stack */ lua_pop(L, 1); /* remove from stack */
} }
else { else {
if (emptybuffer(B) != 0) if (emptybuffer(B) != 0)
lua_insert(L, -2); /* put buffer before new value */ lua_insert(L, -2); /* put buffer before new value */
B.lvl++; /* add new value into B stack */ B.lvl++; /* add new value into B stack */
adjuststack(B); adjuststack(B);
} }
} }
public static void luaL_buffinit (lua_State L, luaL_Buffer B) { public static void luaL_buffinit (lua_State L, luaL_Buffer B) {
B.L = L; B.L = L;
B.p = /*B.buffer*/ 0; B.p = /*B.buffer*/ 0;
B.lvl = 0; B.lvl = 0;
} }
/* }====================================================== */ /* }====================================================== */
public static int luaL_ref (lua_State L, int t) { public static int luaL_ref (lua_State L, int t) {
int ref_; int ref_;
t = abs_index(L, t); t = abs_index(L, t);
if (lua_isnil(L, -1)) { if (lua_isnil(L, -1)) {
lua_pop(L, 1); /* remove from stack */ lua_pop(L, 1); /* remove from stack */
return LUA_REFNIL; /* `nil' has a unique fixed reference */ return LUA_REFNIL; /* `nil' has a unique fixed reference */
} }
lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
ref_ = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ ref_ = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
lua_pop(L, 1); /* remove it from stack */ lua_pop(L, 1); /* remove it from stack */
if (ref_ != 0) { /* any free element? */ if (ref_ != 0) { /* any free element? */
lua_rawgeti(L, t, ref_); /* remove it from list */ lua_rawgeti(L, t, ref_); /* remove it from list */
lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
} }
else { /* no free elements */ else { /* no free elements */
ref_ = (int)lua_objlen(L, t); ref_ = (int)lua_objlen(L, t);
ref_++; /* create new reference */ ref_++; /* create new reference */
} }
lua_rawseti(L, t, ref_); lua_rawseti(L, t, ref_);
return ref_; return ref_;
} }
public static void luaL_unref (lua_State L, int t, int ref_) { public static void luaL_unref (lua_State L, int t, int ref_) {
if (ref_ >= 0) { if (ref_ >= 0) {
t = abs_index(L, t); t = abs_index(L, t);
lua_rawgeti(L, t, FREELIST_REF); lua_rawgeti(L, t, FREELIST_REF);
lua_rawseti(L, t, ref_); /* t[ref] = t[FREELIST_REF] */ lua_rawseti(L, t, ref_); /* t[ref] = t[FREELIST_REF] */
lua_pushinteger(L, ref_); lua_pushinteger(L, ref_);
lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
} }
} }
/* /*
** {====================================================== ** {======================================================
** Load functions ** Load functions
** ======================================================= ** =======================================================
*/ */
public class LoadF { public class LoadF {
public int extraline; public int extraline;
public Stream f; public Stream f;
public CharPtr buff = new char[LUAL_BUFFERSIZE]; public CharPtr buff = new char[LUAL_BUFFERSIZE];
}; };
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public static CharPtr getF (lua_State L, object ud, out uint size) { public static CharPtr getF (lua_State L, object ud, out uint size) {
size = 0; size = 0;
LoadF lf = (LoadF)ud; LoadF lf = (LoadF)ud;
//(void)L; //(void)L;
if (lf.extraline != 0) { if (lf.extraline != 0) {
lf.extraline = 0; lf.extraline = 0;
size = 1; size = 1;
return "\n"; return "\n";
} }
if (feof(lf.f) != 0) return null; if (feof(lf.f) != 0) return null;
size = (uint)fread(lf.buff, 1, lf.buff.chars.Length, lf.f); size = (uint)fread(lf.buff, 1, lf.buff.chars.Length, lf.f);
return (size > 0) ? new CharPtr(lf.buff) : null; return (size > 0) ? new CharPtr(lf.buff) : null;
} }
private static int errfile (lua_State L, CharPtr what, int fnameindex) { private static int errfile (lua_State L, CharPtr what, int fnameindex) {
CharPtr serr = strerror(errno()); CharPtr serr = strerror(errno());
CharPtr filename = lua_tostring(L, fnameindex) + 1; CharPtr filename = lua_tostring(L, fnameindex) + 1;
lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
lua_remove(L, fnameindex); lua_remove(L, fnameindex);
return LUA_ERRFILE; return LUA_ERRFILE;
} }
public static int luaL_loadfile (lua_State L, CharPtr filename) { public static int luaL_loadfile (lua_State L, CharPtr filename) {
LoadF lf = new LoadF(); LoadF lf = new LoadF();
int status, readstatus; int status, readstatus;
int c; int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0; lf.extraline = 0;
if (filename == null) { if (filename == null) {
lua_pushliteral(L, "=stdin"); lua_pushliteral(L, "=stdin");
lf.f = stdin; lf.f = stdin;
} }
else { else {
lua_pushfstring(L, "@%s", filename); lua_pushfstring(L, "@%s", filename);
lf.f = fopen(filename, "r"); lf.f = fopen(filename, "r");
if (lf.f == null) return errfile(L, "open", fnameindex); if (lf.f == null) return errfile(L, "open", fnameindex);
} }
c = getc(lf.f); c = getc(lf.f);
if (c == '#') { /* Unix exec. file? */ if (c == '#') { /* Unix exec. file? */
lf.extraline = 1; lf.extraline = 1;
while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */
if (c == '\n') c = getc(lf.f); if (c == '\n') c = getc(lf.f);
} }
if (c == LUA_SIGNATURE[0] && (filename!=null)) { /* binary file? */ if (c == LUA_SIGNATURE[0] && (filename!=null)) { /* binary file? */
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
if (lf.f == null) return errfile(L, "reopen", fnameindex); if (lf.f == null) return errfile(L, "reopen", fnameindex);
/* skip eventual `#!...' */ /* skip eventual `#!...' */
while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
lf.extraline = 0; lf.extraline = 0;
} }
ungetc(c, lf.f); ungetc(c, lf.f);
status = lua_load(L, getF, lf, lua_tostring(L, -1)); status = lua_load(L, getF, lf, lua_tostring(L, -1));
readstatus = ferror(lf.f); readstatus = ferror(lf.f);
if (filename != null) fclose(lf.f); /* close file (even in case of errors) */ if (filename != null) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus != 0) { if (readstatus != 0) {
lua_settop(L, fnameindex); /* ignore results from `lua_load' */ lua_settop(L, fnameindex); /* ignore results from `lua_load' */
return errfile(L, "read", fnameindex); return errfile(L, "read", fnameindex);
} }
lua_remove(L, fnameindex); lua_remove(L, fnameindex);
return status; return status;
} }
public class LoadS { public class LoadS {
public CharPtr s; public CharPtr s;
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public uint size; public uint size;
}; };
static CharPtr getS (lua_State L, object ud, out uint size) { static CharPtr getS (lua_State L, object ud, out uint size) {
LoadS ls = (LoadS)ud; LoadS ls = (LoadS)ud;
//(void)L; //(void)L;
//if (ls.size == 0) return null; //if (ls.size == 0) return null;
size = ls.size; size = ls.size;
ls.size = 0; ls.size = 0;
return ls.s; return ls.s;
} }
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public static int luaL_loadbuffer(lua_State L, CharPtr buff, uint size, public static int luaL_loadbuffer(lua_State L, CharPtr buff, uint size,
CharPtr name) { CharPtr name) {
LoadS ls = new LoadS(); LoadS ls = new LoadS();
ls.s = new CharPtr(buff); ls.s = new CharPtr(buff);
ls.size = size; ls.size = size;
return lua_load(L, getS, ls, name); return lua_load(L, getS, ls, name);
} }
public static int luaL_loadstring(lua_State L, CharPtr s) { public static int luaL_loadstring(lua_State L, CharPtr s) {
return luaL_loadbuffer(L, s, (uint)strlen(s), s); return luaL_loadbuffer(L, s, (uint)strlen(s), s);
} }
/* }====================================================== */ /* }====================================================== */
private static object l_alloc (Type t) { private static object l_alloc (Type t) {
return System.Activator.CreateInstance(t); return System.Activator.CreateInstance(t);
} }
private static int panic (lua_State L) { private static int panic (lua_State L) {
//(void)L; /* to avoid warnings */ //(void)L; /* to avoid warnings */
fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1)); lua_tostring(L, -1));
return 0; return 0;
} }
public static lua_State luaL_newstate() public static lua_State luaL_newstate()
{ {
lua_State L = lua_newstate(l_alloc, null); lua_State L = lua_newstate(l_alloc, null);
if (L != null) lua_atpanic(L, panic); if (L != null) lua_atpanic(L, panic);
return L; return L;
} }
} }
} }
/* /*
** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $ ** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $
** Basic library ** Basic library
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace KopiLua namespace KopiLua
{ {
using lua_Number = System.Double; using lua_Number = System.Double;
public partial class Lua public partial class Lua
{ {
/* /*
** If your system does not support `stdout', you can just remove this function. ** If your system does not support `stdout', you can just remove this function.
** If you need, you can define your own `print' function, following this ** If you need, you can define your own `print' function, following this
** model but changing `fputs' to put the strings at a proper place ** model but changing `fputs' to put the strings at a proper place
** (a console window or a log file, for instance). ** (a console window or a log file, for instance).
*/ */
private static int luaB_print (lua_State L) { private static int luaB_print (lua_State L) {
int n = lua_gettop(L); /* number of arguments */ int n = lua_gettop(L); /* number of arguments */
int i; int i;
lua_getglobal(L, "tostring"); lua_getglobal(L, "tostring");
for (i=1; i<=n; i++) { for (i=1; i<=n; i++) {
CharPtr s; CharPtr s;
lua_pushvalue(L, -1); /* function to be called */ lua_pushvalue(L, -1); /* function to be called */
lua_pushvalue(L, i); /* value to print */ lua_pushvalue(L, i); /* value to print */
lua_call(L, 1, 1); lua_call(L, 1, 1);
s = lua_tostring(L, -1); /* get result */ s = lua_tostring(L, -1); /* get result */
if (s == null) if (s == null)
return luaL_error(L, LUA_QL("tostring") + " must return a string to " + return luaL_error(L, LUA_QL("tostring") + " must return a string to " +
LUA_QL("print")); LUA_QL("print"));
if (i > 1) fputs("\t", stdout); if (i > 1) fputs("\t", stdout);
fputs(s, stdout); fputs(s, stdout);
lua_pop(L, 1); /* pop result */ lua_pop(L, 1); /* pop result */
} }
Console.Write("\n", stdout); Console.Write("\n", stdout);
return 0; return 0;
} }
private static int luaB_tonumber (lua_State L) { private static int luaB_tonumber (lua_State L) {
int base_ = luaL_optint(L, 2, 10); int base_ = luaL_optint(L, 2, 10);
if (base_ == 10) { /* standard conversion */ if (base_ == 10) { /* standard conversion */
luaL_checkany(L, 1); luaL_checkany(L, 1);
if (lua_isnumber(L, 1) != 0) { if (lua_isnumber(L, 1) != 0) {
lua_pushnumber(L, lua_tonumber(L, 1)); lua_pushnumber(L, lua_tonumber(L, 1));
return 1; return 1;
} }
} }
else { else {
CharPtr s1 = luaL_checkstring(L, 1); CharPtr s1 = luaL_checkstring(L, 1);
CharPtr s2; CharPtr s2;
ulong n; ulong n;
luaL_argcheck(L, 2 <= base_ && base_ <= 36, 2, "base out of range"); luaL_argcheck(L, 2 <= base_ && base_ <= 36, 2, "base out of range");
n = strtoul(s1, out s2, base_); n = strtoul(s1, out s2, base_);
if (s1 != s2) { /* at least one valid digit? */ if (s1 != s2) { /* at least one valid digit? */
while (isspace((byte)(s2[0]))) s2 = s2.next(); /* skip trailing spaces */ while (isspace((byte)(s2[0]))) s2 = s2.next(); /* skip trailing spaces */
if (s2[0] == '\0') { /* no invalid trailing characters? */ if (s2[0] == '\0') { /* no invalid trailing characters? */
lua_pushnumber(L, (lua_Number)n); lua_pushnumber(L, (lua_Number)n);
return 1; return 1;
} }
} }
} }
lua_pushnil(L); /* else not a number */ lua_pushnil(L); /* else not a number */
return 1; return 1;
} }
private static int luaB_error (lua_State L) { private static int luaB_error (lua_State L) {
int level = luaL_optint(L, 2, 1); int level = luaL_optint(L, 2, 1);
lua_settop(L, 1); lua_settop(L, 1);
if ((lua_isstring(L, 1)!=0) && (level > 0)) { /* add extra information? */ if ((lua_isstring(L, 1)!=0) && (level > 0)) { /* add extra information? */
luaL_where(L, level); luaL_where(L, level);
lua_pushvalue(L, 1); lua_pushvalue(L, 1);
lua_concat(L, 2); lua_concat(L, 2);
} }
return lua_error(L); return lua_error(L);
} }
private static int luaB_getmetatable (lua_State L) { private static int luaB_getmetatable (lua_State L) {
luaL_checkany(L, 1); luaL_checkany(L, 1);
if (lua_getmetatable(L, 1)==0) { if (lua_getmetatable(L, 1)==0) {
lua_pushnil(L); lua_pushnil(L);
return 1; /* no metatable */ return 1; /* no metatable */
} }
luaL_getmetafield(L, 1, "__metatable"); luaL_getmetafield(L, 1, "__metatable");
return 1; /* returns either __metatable field (if present) or metatable */ return 1; /* returns either __metatable field (if present) or metatable */
} }
private static int luaB_setmetatable (lua_State L) { private static int luaB_setmetatable (lua_State L) {
int t = lua_type(L, 2); int t = lua_type(L, 2);
luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 1, LUA_TTABLE);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected"); "nil or table expected");
if (luaL_getmetafield(L, 1, "__metatable") != 0) if (luaL_getmetafield(L, 1, "__metatable") != 0)
luaL_error(L, "cannot change a protected metatable"); luaL_error(L, "cannot change a protected metatable");
lua_settop(L, 2); lua_settop(L, 2);
lua_setmetatable(L, 1); lua_setmetatable(L, 1);
return 1; return 1;
} }
private static void getfunc (lua_State L, int opt) { private static void getfunc (lua_State L, int opt) {
if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
else { else {
lua_Debug ar = new lua_Debug(); lua_Debug ar = new lua_Debug();
int level = (opt != 0) ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); int level = (opt != 0) ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
if (lua_getstack(L, level, ar) == 0) if (lua_getstack(L, level, ar) == 0)
luaL_argerror(L, 1, "invalid level"); luaL_argerror(L, 1, "invalid level");
lua_getinfo(L, "f", ar); lua_getinfo(L, "f", ar);
if (lua_isnil(L, -1)) if (lua_isnil(L, -1))
luaL_error(L, "no function environment for tail call at level %d", luaL_error(L, "no function environment for tail call at level %d",
level); level);
} }
} }
private static int luaB_getfenv (lua_State L) { private static int luaB_getfenv (lua_State L) {
getfunc(L, 1); getfunc(L, 1);
if (lua_iscfunction(L, -1)) /* is a C function? */ if (lua_iscfunction(L, -1)) /* is a C function? */
lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
else else
lua_getfenv(L, -1); lua_getfenv(L, -1);
return 1; return 1;
} }
private static int luaB_setfenv (lua_State L) { private static int luaB_setfenv (lua_State L) {
luaL_checktype(L, 2, LUA_TTABLE); luaL_checktype(L, 2, LUA_TTABLE);
getfunc(L, 0); getfunc(L, 0);
lua_pushvalue(L, 2); lua_pushvalue(L, 2);
if ((lua_isnumber(L, 1)!=0) && (lua_tonumber(L, 1) == 0)) { if ((lua_isnumber(L, 1)!=0) && (lua_tonumber(L, 1) == 0)) {
/* change environment of current thread */ /* change environment of current thread */
lua_pushthread(L); lua_pushthread(L);
lua_insert(L, -2); lua_insert(L, -2);
lua_setfenv(L, -2); lua_setfenv(L, -2);
return 0; return 0;
} }
else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
luaL_error(L, luaL_error(L,
LUA_QL("setfenv") + " cannot change environment of given object"); LUA_QL("setfenv") + " cannot change environment of given object");
return 1; return 1;
} }
private static int luaB_rawequal (lua_State L) { private static int luaB_rawequal (lua_State L) {
luaL_checkany(L, 1); luaL_checkany(L, 1);
luaL_checkany(L, 2); luaL_checkany(L, 2);
lua_pushboolean(L, lua_rawequal(L, 1, 2)); lua_pushboolean(L, lua_rawequal(L, 1, 2));
return 1; return 1;
} }
private static int luaB_rawget (lua_State L) { private static int luaB_rawget (lua_State L) {
luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkany(L, 2); luaL_checkany(L, 2);
lua_settop(L, 2); lua_settop(L, 2);
lua_rawget(L, 1); lua_rawget(L, 1);
return 1; return 1;
} }
private static int luaB_rawset (lua_State L) { private static int luaB_rawset (lua_State L) {
luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkany(L, 2); luaL_checkany(L, 2);
luaL_checkany(L, 3); luaL_checkany(L, 3);
lua_settop(L, 3); lua_settop(L, 3);
lua_rawset(L, 1); lua_rawset(L, 1);
return 1; return 1;
} }
private static int luaB_gcinfo (lua_State L) { private static int luaB_gcinfo (lua_State L) {
lua_pushinteger(L, lua_getgccount(L)); lua_pushinteger(L, lua_getgccount(L));
return 1; return 1;
} }
public static readonly CharPtr[] opts = {"stop", "restart", "collect", public static readonly CharPtr[] opts = {"stop", "restart", "collect",
"count", "step", "setpause", "setstepmul", null}; "count", "step", "setpause", "setstepmul", null};
public readonly static int[] optsnum = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, public readonly static int[] optsnum = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL}; LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
private static int luaB_collectgarbage (lua_State L) { private static int luaB_collectgarbage (lua_State L) {
int o = luaL_checkoption(L, 1, "collect", opts); int o = luaL_checkoption(L, 1, "collect", opts);
int ex = luaL_optint(L, 2, 0); int ex = luaL_optint(L, 2, 0);
int res = lua_gc(L, optsnum[o], ex); int res = lua_gc(L, optsnum[o], ex);
switch (optsnum[o]) { switch (optsnum[o]) {
case LUA_GCCOUNT: { case LUA_GCCOUNT: {
int b = lua_gc(L, LUA_GCCOUNTB, 0); int b = lua_gc(L, LUA_GCCOUNTB, 0);
lua_pushnumber(L, res + ((lua_Number)b/1024)); lua_pushnumber(L, res + ((lua_Number)b/1024));
return 1; return 1;
} }
case LUA_GCSTEP: { case LUA_GCSTEP: {
lua_pushboolean(L, res); lua_pushboolean(L, res);
return 1; return 1;
} }
default: { default: {
lua_pushnumber(L, res); lua_pushnumber(L, res);
return 1; return 1;
} }
} }
} }
private static int luaB_type (lua_State L) { private static int luaB_type (lua_State L) {
luaL_checkany(L, 1); luaL_checkany(L, 1);
lua_pushstring(L, luaL_typename(L, 1)); lua_pushstring(L, luaL_typename(L, 1));
return 1; return 1;
} }
private static int luaB_next (lua_State L) { private static int luaB_next (lua_State L) {
luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 2); /* create a 2nd argument if there isn't one */ lua_settop(L, 2); /* create a 2nd argument if there isn't one */
if (lua_next(L, 1) != 0) if (lua_next(L, 1) != 0)
return 2; return 2;
else { else {
lua_pushnil(L); lua_pushnil(L);
return 1; return 1;
} }
} }
private static int luaB_pairs (lua_State L) { private static int luaB_pairs (lua_State L) {
luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 1, LUA_TTABLE);
lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */ lua_pushvalue(L, 1); /* state, */
lua_pushnil(L); /* and initial value */ lua_pushnil(L); /* and initial value */
return 3; return 3;
} }
private static int ipairsaux (lua_State L) { private static int ipairsaux (lua_State L) {
int i = luaL_checkint(L, 2); int i = luaL_checkint(L, 2);
luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 1, LUA_TTABLE);
i++; /* next value */ i++; /* next value */
lua_pushinteger(L, i); lua_pushinteger(L, i);
lua_rawgeti(L, 1, i); lua_rawgeti(L, 1, i);
return (lua_isnil(L, -1)) ? 0 : 2; return (lua_isnil(L, -1)) ? 0 : 2;
} }
private static int luaB_ipairs (lua_State L) { private static int luaB_ipairs (lua_State L) {
luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 1, LUA_TTABLE);
lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */ lua_pushvalue(L, 1); /* state, */
lua_pushinteger(L, 0); /* and initial value */ lua_pushinteger(L, 0); /* and initial value */
return 3; return 3;
} }
private static int load_aux (lua_State L, int status) { private static int load_aux (lua_State L, int status) {
if (status == 0) /* OK? */ if (status == 0) /* OK? */
return 1; return 1;
else { else {
lua_pushnil(L); lua_pushnil(L);
lua_insert(L, -2); /* put before error message */ lua_insert(L, -2); /* put before error message */
return 2; /* return nil plus error message */ return 2; /* return nil plus error message */
} }
} }
private static int luaB_loadstring (lua_State L) { private static int luaB_loadstring (lua_State L) {
uint l; uint l;
CharPtr s = luaL_checklstring(L, 1, out l); CharPtr s = luaL_checklstring(L, 1, out l);
CharPtr chunkname = luaL_optstring(L, 2, s); CharPtr chunkname = luaL_optstring(L, 2, s);
return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
} }
private static int luaB_loadfile (lua_State L) { private static int luaB_loadfile (lua_State L) {
CharPtr fname = luaL_optstring(L, 1, null); CharPtr fname = luaL_optstring(L, 1, null);
return load_aux(L, luaL_loadfile(L, fname)); return load_aux(L, luaL_loadfile(L, fname));
} }
/* /*
** Reader for generic `load' function: `lua_load' uses the ** Reader for generic `load' function: `lua_load' uses the
** stack for internal stuff, so the reader cannot change the ** stack for internal stuff, so the reader cannot change the
** stack top. Instead, it keeps its resulting string in a ** stack top. Instead, it keeps its resulting string in a
** reserved slot inside the stack. ** reserved slot inside the stack.
*/ */
private static CharPtr generic_reader (lua_State L, object ud, out uint size) { private static CharPtr generic_reader (lua_State L, object ud, out uint size) {
//(void)ud; /* to avoid warnings */ //(void)ud; /* to avoid warnings */
luaL_checkstack(L, 2, "too many nested functions"); luaL_checkstack(L, 2, "too many nested functions");
lua_pushvalue(L, 1); /* get function */ lua_pushvalue(L, 1); /* get function */
lua_call(L, 0, 1); /* call it */ lua_call(L, 0, 1); /* call it */
if (lua_isnil(L, -1)) { if (lua_isnil(L, -1)) {
size = 0; size = 0;
return null; return null;
} }
else if (lua_isstring(L, -1) != 0) else if (lua_isstring(L, -1) != 0)
{ {
lua_replace(L, 3); /* save string in a reserved stack slot */ lua_replace(L, 3); /* save string in a reserved stack slot */
return lua_tolstring(L, 3, out size); return lua_tolstring(L, 3, out size);
} }
else else
{ {
size = 0; size = 0;
luaL_error(L, "reader function must return a string"); luaL_error(L, "reader function must return a string");
} }
return null; /* to avoid warnings */ return null; /* to avoid warnings */
} }
private static int luaB_load (lua_State L) { private static int luaB_load (lua_State L) {
int status; int status;
CharPtr cname = luaL_optstring(L, 2, "=(load)"); CharPtr cname = luaL_optstring(L, 2, "=(load)");
luaL_checktype(L, 1, LUA_TFUNCTION); luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ lua_settop(L, 3); /* function, eventual name, plus one reserved slot */
status = lua_load(L, generic_reader, null, cname); status = lua_load(L, generic_reader, null, cname);
return load_aux(L, status); return load_aux(L, status);
} }
private static int luaB_dofile (lua_State L) { private static int luaB_dofile (lua_State L) {
CharPtr fname = luaL_optstring(L, 1, null); CharPtr fname = luaL_optstring(L, 1, null);
int n = lua_gettop(L); int n = lua_gettop(L);
if (luaL_loadfile(L, fname) != 0) lua_error(L); if (luaL_loadfile(L, fname) != 0) lua_error(L);
lua_call(L, 0, LUA_MULTRET); lua_call(L, 0, LUA_MULTRET);
return lua_gettop(L) - n; return lua_gettop(L) - n;
} }
private static int luaB_assert (lua_State L) { private static int luaB_assert (lua_State L) {
luaL_checkany(L, 1); luaL_checkany(L, 1);
if (lua_toboolean(L, 1)==0) if (lua_toboolean(L, 1)==0)
return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
return lua_gettop(L); return lua_gettop(L);
} }
private static int luaB_unpack (lua_State L) { private static int luaB_unpack (lua_State L) {
int i, e, n; int i, e, n;
luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 1, LUA_TTABLE);
i = luaL_optint(L, 2, 1); i = luaL_optint(L, 2, 1);
e = luaL_opt_integer(L, luaL_checkint, 3, luaL_getn(L, 1)); e = luaL_opt_integer(L, luaL_checkint, 3, luaL_getn(L, 1));
if (i > e) return 0; /* empty range */ if (i > e) return 0; /* empty range */
n = e - i + 1; /* number of elements */ n = e - i + 1; /* number of elements */
if (n <= 0 || (lua_checkstack(L, n)==0)) /* n <= 0 means arith. overflow */ if (n <= 0 || (lua_checkstack(L, n)==0)) /* n <= 0 means arith. overflow */
return luaL_error(L, "too many results to unpack"); return luaL_error(L, "too many results to unpack");
lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
while (i++ < e) /* push arg[i + 1...e] */ while (i++ < e) /* push arg[i + 1...e] */
lua_rawgeti(L, 1, i); lua_rawgeti(L, 1, i);
return n; return n;
} }
private static int luaB_select (lua_State L) { private static int luaB_select (lua_State L) {
int n = lua_gettop(L); int n = lua_gettop(L);
if (lua_type(L, 1) == LUA_TSTRING && lua_tostring(L, 1)[0] == '#') { if (lua_type(L, 1) == LUA_TSTRING && lua_tostring(L, 1)[0] == '#') {
lua_pushinteger(L, n-1); lua_pushinteger(L, n-1);
return 1; return 1;
} }
else { else {
int i = luaL_checkint(L, 1); int i = luaL_checkint(L, 1);
if (i < 0) i = n + i; if (i < 0) i = n + i;
else if (i > n) i = n; else if (i > n) i = n;
luaL_argcheck(L, 1 <= i, 1, "index out of range"); luaL_argcheck(L, 1 <= i, 1, "index out of range");
return n - i; return n - i;
} }
} }
private static int luaB_pcall (lua_State L) { private static int luaB_pcall (lua_State L) {
int status; int status;
luaL_checkany(L, 1); luaL_checkany(L, 1);
status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
lua_pushboolean(L, (status == 0) ? 1 : 0); lua_pushboolean(L, (status == 0) ? 1 : 0);
lua_insert(L, 1); lua_insert(L, 1);
return lua_gettop(L); /* return status + all results */ return lua_gettop(L); /* return status + all results */
} }
private static int luaB_xpcall (lua_State L) { private static int luaB_xpcall (lua_State L) {
int status; int status;
luaL_checkany(L, 2); luaL_checkany(L, 2);
lua_settop(L, 2); lua_settop(L, 2);
lua_insert(L, 1); /* put error function under function to be called */ lua_insert(L, 1); /* put error function under function to be called */
status = lua_pcall(L, 0, LUA_MULTRET, 1); status = lua_pcall(L, 0, LUA_MULTRET, 1);
lua_pushboolean(L, (status == 0) ? 1 : 0); lua_pushboolean(L, (status == 0) ? 1 : 0);
lua_replace(L, 1); lua_replace(L, 1);
return lua_gettop(L); /* return status + all results */ return lua_gettop(L); /* return status + all results */
} }
private static int luaB_tostring (lua_State L) { private static int luaB_tostring (lua_State L) {
luaL_checkany(L, 1); luaL_checkany(L, 1);
if (luaL_callmeta(L, 1, "__tostring") != 0) /* is there a metafield? */ if (luaL_callmeta(L, 1, "__tostring") != 0) /* is there a metafield? */
return 1; /* use its value */ return 1; /* use its value */
switch (lua_type(L, 1)) { switch (lua_type(L, 1)) {
case LUA_TNUMBER: case LUA_TNUMBER:
lua_pushstring(L, lua_tostring(L, 1)); lua_pushstring(L, lua_tostring(L, 1));
break; break;
case LUA_TSTRING: case LUA_TSTRING:
lua_pushvalue(L, 1); lua_pushvalue(L, 1);
break; break;
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
lua_pushstring(L, (lua_toboolean(L, 1) != 0 ? "true" : "false")); lua_pushstring(L, (lua_toboolean(L, 1) != 0 ? "true" : "false"));
break; break;
case LUA_TNIL: case LUA_TNIL:
lua_pushliteral(L, "nil"); lua_pushliteral(L, "nil");
break; break;
default: default:
lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
break; break;
} }
return 1; return 1;
} }
private static int luaB_newproxy (lua_State L) { private static int luaB_newproxy (lua_State L) {
lua_settop(L, 1); lua_settop(L, 1);
lua_newuserdata(L, 0); /* create proxy */ lua_newuserdata(L, 0); /* create proxy */
if (lua_toboolean(L, 1) == 0) if (lua_toboolean(L, 1) == 0)
return 1; /* no metatable */ return 1; /* no metatable */
else if (lua_isboolean(L, 1)) { else if (lua_isboolean(L, 1)) {
lua_newtable(L); /* create a new metatable `m' ... */ lua_newtable(L); /* create a new metatable `m' ... */
lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
lua_pushboolean(L, 1); lua_pushboolean(L, 1);
lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
} }
else { else {
int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
if (lua_getmetatable(L, 1) != 0) { if (lua_getmetatable(L, 1) != 0) {
lua_rawget(L, lua_upvalueindex(1)); lua_rawget(L, lua_upvalueindex(1));
validproxy = lua_toboolean(L, -1); validproxy = lua_toboolean(L, -1);
lua_pop(L, 1); /* remove value */ lua_pop(L, 1); /* remove value */
} }
luaL_argcheck(L, validproxy!=0, 1, "boolean or proxy expected"); luaL_argcheck(L, validproxy!=0, 1, "boolean or proxy expected");
lua_getmetatable(L, 1); /* metatable is valid; get it */ lua_getmetatable(L, 1); /* metatable is valid; get it */
} }
lua_setmetatable(L, 2); lua_setmetatable(L, 2);
return 1; return 1;
} }
private readonly static luaL_Reg[] base_funcs = { private readonly static luaL_Reg[] base_funcs = {
new luaL_Reg("assert", luaB_assert), new luaL_Reg("assert", luaB_assert),
new luaL_Reg("collectgarbage", luaB_collectgarbage), new luaL_Reg("collectgarbage", luaB_collectgarbage),
new luaL_Reg("dofile", luaB_dofile), new luaL_Reg("dofile", luaB_dofile),
new luaL_Reg("error", luaB_error), new luaL_Reg("error", luaB_error),
new luaL_Reg("gcinfo", luaB_gcinfo), new luaL_Reg("gcinfo", luaB_gcinfo),
new luaL_Reg("getfenv", luaB_getfenv), new luaL_Reg("getfenv", luaB_getfenv),
new luaL_Reg("getmetatable", luaB_getmetatable), new luaL_Reg("getmetatable", luaB_getmetatable),
new luaL_Reg("loadfile", luaB_loadfile), new luaL_Reg("loadfile", luaB_loadfile),
new luaL_Reg("load", luaB_load), new luaL_Reg("load", luaB_load),
new luaL_Reg("loadstring", luaB_loadstring), new luaL_Reg("loadstring", luaB_loadstring),
new luaL_Reg("next", luaB_next), new luaL_Reg("next", luaB_next),
new luaL_Reg("pcall", luaB_pcall), new luaL_Reg("pcall", luaB_pcall),
new luaL_Reg("print", luaB_print), new luaL_Reg("print", luaB_print),
new luaL_Reg("rawequal", luaB_rawequal), new luaL_Reg("rawequal", luaB_rawequal),
new luaL_Reg("rawget", luaB_rawget), new luaL_Reg("rawget", luaB_rawget),
new luaL_Reg("rawset", luaB_rawset), new luaL_Reg("rawset", luaB_rawset),
new luaL_Reg("select", luaB_select), new luaL_Reg("select", luaB_select),
new luaL_Reg("setfenv", luaB_setfenv), new luaL_Reg("setfenv", luaB_setfenv),
new luaL_Reg("setmetatable", luaB_setmetatable), new luaL_Reg("setmetatable", luaB_setmetatable),
new luaL_Reg("tonumber", luaB_tonumber), new luaL_Reg("tonumber", luaB_tonumber),
new luaL_Reg("tostring", luaB_tostring), new luaL_Reg("tostring", luaB_tostring),
new luaL_Reg("type", luaB_type), new luaL_Reg("type", luaB_type),
new luaL_Reg("unpack", luaB_unpack), new luaL_Reg("unpack", luaB_unpack),
new luaL_Reg("xpcall", luaB_xpcall), new luaL_Reg("xpcall", luaB_xpcall),
new luaL_Reg(null, null) new luaL_Reg(null, null)
}; };
/* /*
** {====================================================== ** {======================================================
** Coroutine library ** Coroutine library
** ======================================================= ** =======================================================
*/ */
public const int CO_RUN = 0; /* running */ public const int CO_RUN = 0; /* running */
public const int CO_SUS = 1; /* suspended */ public const int CO_SUS = 1; /* suspended */
public const int CO_NOR = 2; /* 'normal' (it resumed another coroutine) */ public const int CO_NOR = 2; /* 'normal' (it resumed another coroutine) */
public const int CO_DEAD = 3; public const int CO_DEAD = 3;
private static readonly string[] statnames = private static readonly string[] statnames =
{"running", "suspended", "normal", "dead"}; {"running", "suspended", "normal", "dead"};
private static int costatus (lua_State L, lua_State co) { private static int costatus (lua_State L, lua_State co) {
if (L == co) return CO_RUN; if (L == co) return CO_RUN;
switch (lua_status(co)) { switch (lua_status(co)) {
case LUA_YIELD: case LUA_YIELD:
return CO_SUS; return CO_SUS;
case 0: { case 0: {
lua_Debug ar = new lua_Debug(); lua_Debug ar = new lua_Debug();
if (lua_getstack(co, 0, ar) > 0) /* does it have frames? */ if (lua_getstack(co, 0, ar) > 0) /* does it have frames? */
return CO_NOR; /* it is running */ return CO_NOR; /* it is running */
else if (lua_gettop(co) == 0) else if (lua_gettop(co) == 0)
return CO_DEAD; return CO_DEAD;
else else
return CO_SUS; /* initial state */ return CO_SUS; /* initial state */
} }
default: /* some error occured */ default: /* some error occured */
return CO_DEAD; return CO_DEAD;
} }
} }
private static int luaB_costatus (lua_State L) { private static int luaB_costatus (lua_State L) {
lua_State co = lua_tothread(L, 1); lua_State co = lua_tothread(L, 1);
luaL_argcheck(L, co!=null, 1, "coroutine expected"); luaL_argcheck(L, co!=null, 1, "coroutine expected");
lua_pushstring(L, statnames[costatus(L, co)]); lua_pushstring(L, statnames[costatus(L, co)]);
return 1; return 1;
} }
private static int auxresume (lua_State L, lua_State co, int narg) { private static int auxresume (lua_State L, lua_State co, int narg) {
int status = costatus(L, co); int status = costatus(L, co);
if (lua_checkstack(co, narg)==0) if (lua_checkstack(co, narg)==0)
luaL_error(L, "too many arguments to resume"); luaL_error(L, "too many arguments to resume");
if (status != CO_SUS) { if (status != CO_SUS) {
lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
return -1; /* error flag */ return -1; /* error flag */
} }
lua_xmove(L, co, narg); lua_xmove(L, co, narg);
lua_setlevel(L, co); lua_setlevel(L, co);
status = lua_resume(co, narg); status = lua_resume(co, narg);
if (status == 0 || status == LUA_YIELD) { if (status == 0 || status == LUA_YIELD) {
int nres = lua_gettop(co); int nres = lua_gettop(co);
if (lua_checkstack(L, nres + 1)==0) if (lua_checkstack(L, nres + 1)==0)
luaL_error(L, "too many results to resume"); luaL_error(L, "too many results to resume");
lua_xmove(co, L, nres); /* move yielded values */ lua_xmove(co, L, nres); /* move yielded values */
return nres; return nres;
} }
else { else {
lua_xmove(co, L, 1); /* move error message */ lua_xmove(co, L, 1); /* move error message */
return -1; /* error flag */ return -1; /* error flag */
} }
} }
private static int luaB_coresume (lua_State L) { private static int luaB_coresume (lua_State L) {
lua_State co = lua_tothread(L, 1); lua_State co = lua_tothread(L, 1);
int r; int r;
luaL_argcheck(L, co!=null, 1, "coroutine expected"); luaL_argcheck(L, co!=null, 1, "coroutine expected");
r = auxresume(L, co, lua_gettop(L) - 1); r = auxresume(L, co, lua_gettop(L) - 1);
if (r < 0) { if (r < 0) {
lua_pushboolean(L, 0); lua_pushboolean(L, 0);
lua_insert(L, -2); lua_insert(L, -2);
return 2; /* return false + error message */ return 2; /* return false + error message */
} }
else { else {
lua_pushboolean(L, 1); lua_pushboolean(L, 1);
lua_insert(L, -(r + 1)); lua_insert(L, -(r + 1));
return r + 1; /* return true + `resume' returns */ return r + 1; /* return true + `resume' returns */
} }
} }
private static int luaB_auxwrap (lua_State L) { private static int luaB_auxwrap (lua_State L) {
lua_State co = lua_tothread(L, lua_upvalueindex(1)); lua_State co = lua_tothread(L, lua_upvalueindex(1));
int r = auxresume(L, co, lua_gettop(L)); int r = auxresume(L, co, lua_gettop(L));
if (r < 0) { if (r < 0) {
if (lua_isstring(L, -1) != 0) { /* error object is a string? */ if (lua_isstring(L, -1) != 0) { /* error object is a string? */
luaL_where(L, 1); /* add extra info */ luaL_where(L, 1); /* add extra info */
lua_insert(L, -2); lua_insert(L, -2);
lua_concat(L, 2); lua_concat(L, 2);
} }
lua_error(L); /* propagate error */ lua_error(L); /* propagate error */
} }
return r; return r;
} }
private static int luaB_cocreate (lua_State L) { private static int luaB_cocreate (lua_State L) {
lua_State NL = lua_newthread(L); lua_State NL = lua_newthread(L);
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
"Lua function expected"); "Lua function expected");
lua_pushvalue(L, 1); /* move function to top */ lua_pushvalue(L, 1); /* move function to top */
lua_xmove(L, NL, 1); /* move function from L to NL */ lua_xmove(L, NL, 1); /* move function from L to NL */
return 1; return 1;
} }
private static int luaB_cowrap (lua_State L) { private static int luaB_cowrap (lua_State L) {
luaB_cocreate(L); luaB_cocreate(L);
lua_pushcclosure(L, luaB_auxwrap, 1); lua_pushcclosure(L, luaB_auxwrap, 1);
return 1; return 1;
} }
private static int luaB_yield (lua_State L) { private static int luaB_yield (lua_State L) {
return lua_yield(L, lua_gettop(L)); return lua_yield(L, lua_gettop(L));
} }
private static int luaB_corunning (lua_State L) { private static int luaB_corunning (lua_State L) {
if (lua_pushthread(L) != 0) if (lua_pushthread(L) != 0)
lua_pushnil(L); /* main thread is not a coroutine */ lua_pushnil(L); /* main thread is not a coroutine */
return 1; return 1;
} }
private readonly static luaL_Reg[] co_funcs = { private readonly static luaL_Reg[] co_funcs = {
new luaL_Reg("create", luaB_cocreate), new luaL_Reg("create", luaB_cocreate),
new luaL_Reg("resume", luaB_coresume), new luaL_Reg("resume", luaB_coresume),
new luaL_Reg("running", luaB_corunning), new luaL_Reg("running", luaB_corunning),
new luaL_Reg("status", luaB_costatus), new luaL_Reg("status", luaB_costatus),
new luaL_Reg("wrap", luaB_cowrap), new luaL_Reg("wrap", luaB_cowrap),
new luaL_Reg("yield", luaB_yield), new luaL_Reg("yield", luaB_yield),
new luaL_Reg(null, null) new luaL_Reg(null, null)
}; };
/* }====================================================== */ /* }====================================================== */
private static void auxopen (lua_State L, CharPtr name, private static void auxopen (lua_State L, CharPtr name,
lua_CFunction f, lua_CFunction u) { lua_CFunction f, lua_CFunction u) {
lua_pushcfunction(L, u); lua_pushcfunction(L, u);
lua_pushcclosure(L, f, 1); lua_pushcclosure(L, f, 1);
lua_setfield(L, -2, name); lua_setfield(L, -2, name);
} }
private static void base_open (lua_State L) { private static void base_open (lua_State L) {
/* set global _G */ /* set global _G */
lua_pushvalue(L, LUA_GLOBALSINDEX); lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setglobal(L, "_G"); lua_setglobal(L, "_G");
/* open lib into global table */ /* open lib into global table */
luaL_register(L, "_G", base_funcs); luaL_register(L, "_G", base_funcs);
lua_pushliteral(L, LUA_VERSION); lua_pushliteral(L, LUA_VERSION);
lua_setglobal(L, "_VERSION"); /* set global _VERSION */ lua_setglobal(L, "_VERSION"); /* set global _VERSION */
/* `ipairs' and `pairs' need auxliliary functions as upvalues */ /* `ipairs' and `pairs' need auxliliary functions as upvalues */
auxopen(L, "ipairs", luaB_ipairs, ipairsaux); auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
auxopen(L, "pairs", luaB_pairs, luaB_next); auxopen(L, "pairs", luaB_pairs, luaB_next);
/* `newproxy' needs a weaktable as upvalue */ /* `newproxy' needs a weaktable as upvalue */
lua_createtable(L, 0, 1); /* new table `w' */ lua_createtable(L, 0, 1); /* new table `w' */
lua_pushvalue(L, -1); /* `w' will be its own metatable */ lua_pushvalue(L, -1); /* `w' will be its own metatable */
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
lua_pushliteral(L, "kv"); lua_pushliteral(L, "kv");
lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
lua_pushcclosure(L, luaB_newproxy, 1); lua_pushcclosure(L, luaB_newproxy, 1);
lua_setglobal(L, "newproxy"); /* set global `newproxy' */ lua_setglobal(L, "newproxy"); /* set global `newproxy' */
} }
public static int luaopen_base (lua_State L) { public static int luaopen_base (lua_State L) {
base_open(L); base_open(L);
luaL_register(L, LUA_COLIBNAME, co_funcs); luaL_register(L, LUA_COLIBNAME, co_funcs);
return 2; return 2;
} }
} }
} }
/* /*
** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $ ** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $
** Code generator for Lua ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Diagnostics; using System.Diagnostics;
namespace KopiLua namespace KopiLua
{ {
using TValue = Lua.lua_TValue; using TValue = Lua.lua_TValue;
using lua_Number = System.Double; using lua_Number = System.Double;
using Instruction = System.UInt32; using Instruction = System.UInt32;
public class InstructionPtr public class InstructionPtr
{ {
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public Instruction[] codes; public Instruction[] codes;
public int pc; public int pc;
public InstructionPtr() { this.codes = null; ; this.pc = -1; } public InstructionPtr() { this.codes = null; ; this.pc = -1; }
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public InstructionPtr(Instruction[] codes, int pc) { public InstructionPtr(Instruction[] codes, int pc) {
this.codes = codes; this.pc = pc; } this.codes = codes; this.pc = pc; }
public static InstructionPtr Assign(InstructionPtr ptr) public static InstructionPtr Assign(InstructionPtr ptr)
{ {
if (ptr == null) return null; if (ptr == null) return null;
return new InstructionPtr(ptr.codes, ptr.pc); return new InstructionPtr(ptr.codes, ptr.pc);
} }
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public Instruction this[int index] public Instruction this[int index]
{ {
get { return this.codes[pc + index]; } get { return this.codes[pc + index]; }
set { this.codes[pc + index] = value; } set { this.codes[pc + index] = value; }
} }
public static InstructionPtr inc(ref InstructionPtr ptr) public static InstructionPtr inc(ref InstructionPtr ptr)
{ {
InstructionPtr result = new InstructionPtr(ptr.codes, ptr.pc); InstructionPtr result = new InstructionPtr(ptr.codes, ptr.pc);
ptr.pc++; ptr.pc++;
return result; return result;
} }
public static InstructionPtr dec(ref InstructionPtr ptr) public static InstructionPtr dec(ref InstructionPtr ptr)
{ {
InstructionPtr result = new InstructionPtr(ptr.codes, ptr.pc); InstructionPtr result = new InstructionPtr(ptr.codes, ptr.pc);
ptr.pc--; ptr.pc--;
return result; return result;
} }
public static bool operator <(InstructionPtr p1, InstructionPtr p2) public static bool operator <(InstructionPtr p1, InstructionPtr p2)
{ {
Debug.Assert(p1.codes == p2.codes); Debug.Assert(p1.codes == p2.codes);
return p1.pc < p2.pc; return p1.pc < p2.pc;
} }
public static bool operator >(InstructionPtr p1, InstructionPtr p2) public static bool operator >(InstructionPtr p1, InstructionPtr p2)
{ {
Debug.Assert(p1.codes == p2.codes); Debug.Assert(p1.codes == p2.codes);
return p1.pc > p2.pc; return p1.pc > p2.pc;
} }
public static bool operator <=(InstructionPtr p1, InstructionPtr p2) public static bool operator <=(InstructionPtr p1, InstructionPtr p2)
{ {
Debug.Assert(p1.codes == p2.codes); Debug.Assert(p1.codes == p2.codes);
return p1.pc < p2.pc; return p1.pc < p2.pc;
} }
public static bool operator >=(InstructionPtr p1, InstructionPtr p2) public static bool operator >=(InstructionPtr p1, InstructionPtr p2)
{ {
Debug.Assert(p1.codes == p2.codes); Debug.Assert(p1.codes == p2.codes);
return p1.pc > p2.pc; return p1.pc > p2.pc;
} }
}; };
public partial class Lua public partial class Lua
{ {
/* /*
** Marks the end of a patch list. It is an invalid value both as an absolute ** Marks the end of a patch list. It is an invalid value both as an absolute
** address, and as a list link (would link an element to itself). ** address, and as a list link (would link an element to itself).
*/ */
public const int NO_JUMP = (-1); public const int NO_JUMP = (-1);
/* /*
** grep "ORDER OPR" if you change these enums ** grep "ORDER OPR" if you change these enums
*/ */
public enum BinOpr { public enum BinOpr {
OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
OPR_CONCAT, OPR_CONCAT,
OPR_NE, OPR_EQ, OPR_NE, OPR_EQ,
OPR_LT, OPR_LE, OPR_GT, OPR_GE, OPR_LT, OPR_LE, OPR_GT, OPR_GE,
OPR_AND, OPR_OR, OPR_AND, OPR_OR,
OPR_NOBINOPR OPR_NOBINOPR
}; };
public enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR }; public enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR };
public static InstructionPtr getcode(FuncState fs, expdesc e) {return new InstructionPtr(fs.f.code, e.u.s.info);} public static InstructionPtr getcode(FuncState fs, expdesc e) {return new InstructionPtr(fs.f.code, e.u.s.info);}
public static int luaK_codeAsBx(FuncState fs, OpCode o, int A, int sBx) {return luaK_codeABx(fs,o,A,sBx+MAXARG_sBx);} public static int luaK_codeAsBx(FuncState fs, OpCode o, int A, int sBx) {return luaK_codeABx(fs,o,A,sBx+MAXARG_sBx);}
public static void luaK_setmultret(FuncState fs, expdesc e) {luaK_setreturns(fs, e, LUA_MULTRET);} public static void luaK_setmultret(FuncState fs, expdesc e) {luaK_setreturns(fs, e, LUA_MULTRET);}
public static bool hasjumps(expdesc e) {return e.t != e.f;} public static bool hasjumps(expdesc e) {return e.t != e.f;}
private static int isnumeral(expdesc e) { private static int isnumeral(expdesc e) {
return (e.k == expkind.VKNUM && e.t == NO_JUMP && e.f == NO_JUMP) ? 1 : 0; return (e.k == expkind.VKNUM && e.t == NO_JUMP && e.f == NO_JUMP) ? 1 : 0;
} }
public static void luaK_nil (FuncState fs, int from, int n) { public static void luaK_nil (FuncState fs, int from, int n) {
InstructionPtr previous; InstructionPtr previous;
if (fs.pc > fs.lasttarget) { /* no jumps to current position? */ if (fs.pc > fs.lasttarget) { /* no jumps to current position? */
if (fs.pc == 0) { /* function start? */ if (fs.pc == 0) { /* function start? */
if (from >= fs.nactvar) if (from >= fs.nactvar)
return; /* positions are already clean */ return; /* positions are already clean */
} }
else { else {
previous = new InstructionPtr(fs.f.code, fs.pc-1); previous = new InstructionPtr(fs.f.code, fs.pc-1);
if (GET_OPCODE(previous) == OpCode.OP_LOADNIL) { if (GET_OPCODE(previous) == OpCode.OP_LOADNIL) {
int pfrom = GETARG_A(previous); int pfrom = GETARG_A(previous);
int pto = GETARG_B(previous); int pto = GETARG_B(previous);
if (pfrom <= from && from <= pto+1) { /* can connect both? */ if (pfrom <= from && from <= pto+1) { /* can connect both? */
if (from+n-1 > pto) if (from+n-1 > pto)
SETARG_B(previous, from+n-1); SETARG_B(previous, from+n-1);
return; return;
} }
} }
} }
} }
luaK_codeABC(fs, OpCode.OP_LOADNIL, from, from + n - 1, 0); /* else no optimization */ luaK_codeABC(fs, OpCode.OP_LOADNIL, from, from + n - 1, 0); /* else no optimization */
} }
public static int luaK_jump (FuncState fs) { public static int luaK_jump (FuncState fs) {
int jpc = fs.jpc; /* save list of jumps to here */ int jpc = fs.jpc; /* save list of jumps to here */
int j; int j;
fs.jpc = NO_JUMP; fs.jpc = NO_JUMP;
j = luaK_codeAsBx(fs, OpCode.OP_JMP, 0, NO_JUMP); j = luaK_codeAsBx(fs, OpCode.OP_JMP, 0, NO_JUMP);
luaK_concat(fs, ref j, jpc); /* keep them on hold */ luaK_concat(fs, ref j, jpc); /* keep them on hold */
return j; return j;
} }
public static void luaK_ret (FuncState fs, int first, int nret) { public static void luaK_ret (FuncState fs, int first, int nret) {
luaK_codeABC(fs, OpCode.OP_RETURN, first, nret + 1, 0); luaK_codeABC(fs, OpCode.OP_RETURN, first, nret + 1, 0);
} }
private static int condjump (FuncState fs, OpCode op, int A, int B, int C) { private static int condjump (FuncState fs, OpCode op, int A, int B, int C) {
luaK_codeABC(fs, op, A, B, C); luaK_codeABC(fs, op, A, B, C);
return luaK_jump(fs); return luaK_jump(fs);
} }
private static void fixjump (FuncState fs, int pc, int dest) { private static void fixjump (FuncState fs, int pc, int dest) {
InstructionPtr jmp = new InstructionPtr(fs.f.code, pc); InstructionPtr jmp = new InstructionPtr(fs.f.code, pc);
int offset = dest-(pc+1); int offset = dest-(pc+1);
lua_assert(dest != NO_JUMP); lua_assert(dest != NO_JUMP);
if (Math.Abs(offset) > MAXARG_sBx) if (Math.Abs(offset) > MAXARG_sBx)
luaX_syntaxerror(fs.ls, "control structure too long"); luaX_syntaxerror(fs.ls, "control structure too long");
SETARG_sBx(jmp, offset); SETARG_sBx(jmp, offset);
} }
/* /*
** returns current `pc' and marks it as a jump target (to avoid wrong ** returns current `pc' and marks it as a jump target (to avoid wrong
** optimizations with consecutive instructions not in the same basic block). ** optimizations with consecutive instructions not in the same basic block).
*/ */
public static int luaK_getlabel (FuncState fs) { public static int luaK_getlabel (FuncState fs) {
fs.lasttarget = fs.pc; fs.lasttarget = fs.pc;
return fs.pc; return fs.pc;
} }
private static int getjump (FuncState fs, int pc) { private static int getjump (FuncState fs, int pc) {
int offset = GETARG_sBx(fs.f.code[pc]); int offset = GETARG_sBx(fs.f.code[pc]);
if (offset == NO_JUMP) /* point to itself represents end of list */ if (offset == NO_JUMP) /* point to itself represents end of list */
return NO_JUMP; /* end of list */ return NO_JUMP; /* end of list */
else else
return (pc+1)+offset; /* turn offset into absolute position */ return (pc+1)+offset; /* turn offset into absolute position */
} }
private static InstructionPtr getjumpcontrol (FuncState fs, int pc) { private static InstructionPtr getjumpcontrol (FuncState fs, int pc) {
InstructionPtr pi = new InstructionPtr(fs.f.code, pc); InstructionPtr pi = new InstructionPtr(fs.f.code, pc);
if (pc >= 1 && (testTMode(GET_OPCODE(pi[-1]))!=0)) if (pc >= 1 && (testTMode(GET_OPCODE(pi[-1]))!=0))
return new InstructionPtr(pi.codes, pi.pc-1); return new InstructionPtr(pi.codes, pi.pc-1);
else else
return new InstructionPtr(pi.codes, pi.pc); return new InstructionPtr(pi.codes, pi.pc);
} }
/* /*
** check whether list has any jump that do not produce a value ** check whether list has any jump that do not produce a value
** (or produce an inverted value) ** (or produce an inverted value)
*/ */
private static int need_value (FuncState fs, int list) { private static int need_value (FuncState fs, int list) {
for (; list != NO_JUMP; list = getjump(fs, list)) { for (; list != NO_JUMP; list = getjump(fs, list)) {
InstructionPtr i = getjumpcontrol(fs, list); InstructionPtr i = getjumpcontrol(fs, list);
if (GET_OPCODE(i[0]) != OpCode.OP_TESTSET) return 1; if (GET_OPCODE(i[0]) != OpCode.OP_TESTSET) return 1;
} }
return 0; /* not found */ return 0; /* not found */
} }
private static int patchtestreg (FuncState fs, int node, int reg) { private static int patchtestreg (FuncState fs, int node, int reg) {
InstructionPtr i = getjumpcontrol(fs, node); InstructionPtr i = getjumpcontrol(fs, node);
if (GET_OPCODE(i[0]) != OpCode.OP_TESTSET) if (GET_OPCODE(i[0]) != OpCode.OP_TESTSET)
return 0; /* cannot patch other instructions */ return 0; /* cannot patch other instructions */
if (reg != NO_REG && reg != GETARG_B(i[0])) if (reg != NO_REG && reg != GETARG_B(i[0]))
SETARG_A(i, reg); SETARG_A(i, reg);
else /* no register to put value or register already has the value */ else /* no register to put value or register already has the value */
i[0] = (uint)CREATE_ABC(OpCode.OP_TEST, GETARG_B(i[0]), 0, GETARG_C(i[0])); i[0] = (uint)CREATE_ABC(OpCode.OP_TEST, GETARG_B(i[0]), 0, GETARG_C(i[0]));
return 1; return 1;
} }
private static void removevalues (FuncState fs, int list) { private static void removevalues (FuncState fs, int list) {
for (; list != NO_JUMP; list = getjump(fs, list)) for (; list != NO_JUMP; list = getjump(fs, list))
patchtestreg(fs, list, NO_REG); patchtestreg(fs, list, NO_REG);
} }
private static void patchlistaux (FuncState fs, int list, int vtarget, int reg, private static void patchlistaux (FuncState fs, int list, int vtarget, int reg,
int dtarget) { int dtarget) {
while (list != NO_JUMP) { while (list != NO_JUMP) {
int next = getjump(fs, list); int next = getjump(fs, list);
if (patchtestreg(fs, list, reg) != 0) if (patchtestreg(fs, list, reg) != 0)
fixjump(fs, list, vtarget); fixjump(fs, list, vtarget);
else else
fixjump(fs, list, dtarget); /* jump to default target */ fixjump(fs, list, dtarget); /* jump to default target */
list = next; list = next;
} }
} }
private static void dischargejpc (FuncState fs) { private static void dischargejpc (FuncState fs) {
patchlistaux(fs, fs.jpc, fs.pc, NO_REG, fs.pc); patchlistaux(fs, fs.jpc, fs.pc, NO_REG, fs.pc);
fs.jpc = NO_JUMP; fs.jpc = NO_JUMP;
} }
public static void luaK_patchlist (FuncState fs, int list, int target) { public static void luaK_patchlist (FuncState fs, int list, int target) {
if (target == fs.pc) if (target == fs.pc)
luaK_patchtohere(fs, list); luaK_patchtohere(fs, list);
else { else {
lua_assert(target < fs.pc); lua_assert(target < fs.pc);
patchlistaux(fs, list, target, NO_REG, target); patchlistaux(fs, list, target, NO_REG, target);
} }
} }
public static void luaK_patchtohere (FuncState fs, int list) { public static void luaK_patchtohere (FuncState fs, int list) {
luaK_getlabel(fs); luaK_getlabel(fs);
luaK_concat(fs, ref fs.jpc, list); luaK_concat(fs, ref fs.jpc, list);
} }
public static void luaK_concat(FuncState fs, ref int l1, int l2) public static void luaK_concat(FuncState fs, ref int l1, int l2)
{ {
if (l2 == NO_JUMP) return; if (l2 == NO_JUMP) return;
else if (l1 == NO_JUMP) else if (l1 == NO_JUMP)
l1 = l2; l1 = l2;
else { else {
int list = l1; int list = l1;
int next; int next;
while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
list = next; list = next;
fixjump(fs, list, l2); fixjump(fs, list, l2);
} }
} }
public static void luaK_checkstack (FuncState fs, int n) { public static void luaK_checkstack (FuncState fs, int n) {
int newstack = fs.freereg + n; int newstack = fs.freereg + n;
if (newstack > fs.f.maxstacksize) { if (newstack > fs.f.maxstacksize) {
if (newstack >= MAXSTACK) if (newstack >= MAXSTACK)
luaX_syntaxerror(fs.ls, "function or expression too complex"); luaX_syntaxerror(fs.ls, "function or expression too complex");
fs.f.maxstacksize = cast_byte(newstack); fs.f.maxstacksize = cast_byte(newstack);
} }
} }
public static void luaK_reserveregs (FuncState fs, int n) { public static void luaK_reserveregs (FuncState fs, int n) {
luaK_checkstack(fs, n); luaK_checkstack(fs, n);
fs.freereg += n; fs.freereg += n;
} }
private static void freereg (FuncState fs, int reg) { private static void freereg (FuncState fs, int reg) {
if ((ISK(reg)==0) && reg >= fs.nactvar) { if ((ISK(reg)==0) && reg >= fs.nactvar) {
fs.freereg--; fs.freereg--;
lua_assert(reg == fs.freereg); lua_assert(reg == fs.freereg);
} }
} }
private static void freeexp (FuncState fs, expdesc e) { private static void freeexp (FuncState fs, expdesc e) {
if (e.k == expkind.VNONRELOC) if (e.k == expkind.VNONRELOC)
freereg(fs, e.u.s.info); freereg(fs, e.u.s.info);
} }
private static int addk (FuncState fs, TValue k, TValue v) { private static int addk (FuncState fs, TValue k, TValue v) {
lua_State L = fs.L; lua_State L = fs.L;
TValue idx = luaH_set(L, fs.h, k); TValue idx = luaH_set(L, fs.h, k);
Proto f = fs.f; Proto f = fs.f;
int oldsize = f.sizek; int oldsize = f.sizek;
if (ttisnumber(idx)) { if (ttisnumber(idx)) {
lua_assert(luaO_rawequalObj(fs.f.k[cast_int(nvalue(idx))], v)); lua_assert(luaO_rawequalObj(fs.f.k[cast_int(nvalue(idx))], v));
return cast_int(nvalue(idx)); return cast_int(nvalue(idx));
} }
else { /* constant not found; create a new entry */ else { /* constant not found; create a new entry */
setnvalue(idx, cast_num(fs.nk)); setnvalue(idx, cast_num(fs.nk));
luaM_growvector(L, ref f.k, fs.nk, ref f.sizek, luaM_growvector(L, ref f.k, fs.nk, ref f.sizek,
MAXARG_Bx, "constant table overflow"); MAXARG_Bx, "constant table overflow");
while (oldsize < f.sizek) setnilvalue(f.k[oldsize++]); while (oldsize < f.sizek) setnilvalue(f.k[oldsize++]);
setobj(L, f.k[fs.nk], v); setobj(L, f.k[fs.nk], v);
luaC_barrier(L, f, v); luaC_barrier(L, f, v);
return fs.nk++; return fs.nk++;
} }
} }
public static int luaK_stringK (FuncState fs, TString s) { public static int luaK_stringK (FuncState fs, TString s) {
TValue o = new TValue(); TValue o = new TValue();
setsvalue(fs.L, o, s); setsvalue(fs.L, o, s);
return addk(fs, o, o); return addk(fs, o, o);
} }
public static int luaK_numberK (FuncState fs, lua_Number r) { public static int luaK_numberK (FuncState fs, lua_Number r) {
TValue o = new TValue(); TValue o = new TValue();
setnvalue(o, r); setnvalue(o, r);
return addk(fs, o, o); return addk(fs, o, o);
} }
private static int boolK (FuncState fs, int b) { private static int boolK (FuncState fs, int b) {
TValue o = new TValue(); TValue o = new TValue();
setbvalue(o, b); setbvalue(o, b);
return addk(fs, o, o); return addk(fs, o, o);
} }
private static int nilK (FuncState fs) { private static int nilK (FuncState fs) {
TValue k = new TValue(), v = new TValue(); TValue k = new TValue(), v = new TValue();
setnilvalue(v); setnilvalue(v);
/* cannot use nil as key; instead use table itself to represent nil */ /* cannot use nil as key; instead use table itself to represent nil */
sethvalue(fs.L, k, fs.h); sethvalue(fs.L, k, fs.h);
return addk(fs, k, v); return addk(fs, k, v);
} }
public static void luaK_setreturns (FuncState fs, expdesc e, int nresults) { public static void luaK_setreturns (FuncState fs, expdesc e, int nresults) {
if (e.k == expkind.VCALL) { /* expression is an open function call? */ if (e.k == expkind.VCALL) { /* expression is an open function call? */
SETARG_C(getcode(fs, e), nresults+1); SETARG_C(getcode(fs, e), nresults+1);
} }
else if (e.k == expkind.VVARARG) { else if (e.k == expkind.VVARARG) {
SETARG_B(getcode(fs, e), nresults+1); SETARG_B(getcode(fs, e), nresults+1);
SETARG_A(getcode(fs, e), fs.freereg); SETARG_A(getcode(fs, e), fs.freereg);
luaK_reserveregs(fs, 1); luaK_reserveregs(fs, 1);
} }
} }
public static void luaK_setoneret (FuncState fs, expdesc e) { public static void luaK_setoneret (FuncState fs, expdesc e) {
if (e.k == expkind.VCALL) { /* expression is an open function call? */ if (e.k == expkind.VCALL) { /* expression is an open function call? */
e.k = expkind.VNONRELOC; e.k = expkind.VNONRELOC;
e.u.s.info = GETARG_A(getcode(fs, e)); e.u.s.info = GETARG_A(getcode(fs, e));
} }
else if (e.k == expkind.VVARARG) { else if (e.k == expkind.VVARARG) {
SETARG_B(getcode(fs, e), 2); SETARG_B(getcode(fs, e), 2);
e.k = expkind.VRELOCABLE; /* can relocate its simple result */ e.k = expkind.VRELOCABLE; /* can relocate its simple result */
} }
} }
public static void luaK_dischargevars (FuncState fs, expdesc e) { public static void luaK_dischargevars (FuncState fs, expdesc e) {
switch (e.k) { switch (e.k) {
case expkind.VLOCAL: { case expkind.VLOCAL: {
e.k = expkind.VNONRELOC; e.k = expkind.VNONRELOC;
break; break;
} }
case expkind.VUPVAL: { case expkind.VUPVAL: {
e.u.s.info = luaK_codeABC(fs, OpCode.OP_GETUPVAL, 0, e.u.s.info, 0); e.u.s.info = luaK_codeABC(fs, OpCode.OP_GETUPVAL, 0, e.u.s.info, 0);
e.k = expkind.VRELOCABLE; e.k = expkind.VRELOCABLE;
break; break;
} }
case expkind.VGLOBAL: { case expkind.VGLOBAL: {
e.u.s.info = luaK_codeABx(fs, OpCode.OP_GETGLOBAL, 0, e.u.s.info); e.u.s.info = luaK_codeABx(fs, OpCode.OP_GETGLOBAL, 0, e.u.s.info);
e.k = expkind.VRELOCABLE; e.k = expkind.VRELOCABLE;
break; break;
} }
case expkind.VINDEXED: { case expkind.VINDEXED: {
freereg(fs, e.u.s.aux); freereg(fs, e.u.s.aux);
freereg(fs, e.u.s.info); freereg(fs, e.u.s.info);
e.u.s.info = luaK_codeABC(fs, OpCode.OP_GETTABLE, 0, e.u.s.info, e.u.s.aux); e.u.s.info = luaK_codeABC(fs, OpCode.OP_GETTABLE, 0, e.u.s.info, e.u.s.aux);
e.k = expkind.VRELOCABLE; e.k = expkind.VRELOCABLE;
break; break;
} }
case expkind.VVARARG: case expkind.VVARARG:
case expkind.VCALL: { case expkind.VCALL: {
luaK_setoneret(fs, e); luaK_setoneret(fs, e);
break; break;
} }
default: break; /* there is one value available (somewhere) */ default: break; /* there is one value available (somewhere) */
} }
} }
private static int code_label (FuncState fs, int A, int b, int jump) { private static int code_label (FuncState fs, int A, int b, int jump) {
luaK_getlabel(fs); /* those instructions may be jump targets */ luaK_getlabel(fs); /* those instructions may be jump targets */
return luaK_codeABC(fs, OpCode.OP_LOADBOOL, A, b, jump); return luaK_codeABC(fs, OpCode.OP_LOADBOOL, A, b, jump);
} }
private static void discharge2reg (FuncState fs, expdesc e, int reg) { private static void discharge2reg (FuncState fs, expdesc e, int reg) {
luaK_dischargevars(fs, e); luaK_dischargevars(fs, e);
switch (e.k) { switch (e.k) {
case expkind.VNIL: { case expkind.VNIL: {
luaK_nil(fs, reg, 1); luaK_nil(fs, reg, 1);
break; break;
} }
case expkind.VFALSE: case expkind.VTRUE: { case expkind.VFALSE: case expkind.VTRUE: {
luaK_codeABC(fs, OpCode.OP_LOADBOOL, reg, (e.k == expkind.VTRUE) ? 1 : 0, 0); luaK_codeABC(fs, OpCode.OP_LOADBOOL, reg, (e.k == expkind.VTRUE) ? 1 : 0, 0);
break; break;
} }
case expkind.VK: { case expkind.VK: {
luaK_codeABx(fs, OpCode.OP_LOADK, reg, e.u.s.info); luaK_codeABx(fs, OpCode.OP_LOADK, reg, e.u.s.info);
break; break;
} }
case expkind.VKNUM: { case expkind.VKNUM: {
luaK_codeABx(fs, OpCode.OP_LOADK, reg, luaK_numberK(fs, e.u.nval)); luaK_codeABx(fs, OpCode.OP_LOADK, reg, luaK_numberK(fs, e.u.nval));
break; break;
} }
case expkind.VRELOCABLE: { case expkind.VRELOCABLE: {
InstructionPtr pc = getcode(fs, e); InstructionPtr pc = getcode(fs, e);
SETARG_A(pc, reg); SETARG_A(pc, reg);
break; break;
} }
case expkind.VNONRELOC: { case expkind.VNONRELOC: {
if (reg != e.u.s.info) if (reg != e.u.s.info)
luaK_codeABC(fs, OpCode.OP_MOVE, reg, e.u.s.info, 0); luaK_codeABC(fs, OpCode.OP_MOVE, reg, e.u.s.info, 0);
break; break;
} }
default: { default: {
lua_assert(e.k == expkind.VVOID || e.k == expkind.VJMP); lua_assert(e.k == expkind.VVOID || e.k == expkind.VJMP);
return; /* nothing to do... */ return; /* nothing to do... */
} }
} }
e.u.s.info = reg; e.u.s.info = reg;
e.k = expkind.VNONRELOC; e.k = expkind.VNONRELOC;
} }
private static void discharge2anyreg (FuncState fs, expdesc e) { private static void discharge2anyreg (FuncState fs, expdesc e) {
if (e.k != expkind.VNONRELOC) { if (e.k != expkind.VNONRELOC) {
luaK_reserveregs(fs, 1); luaK_reserveregs(fs, 1);
discharge2reg(fs, e, fs.freereg-1); discharge2reg(fs, e, fs.freereg-1);
} }
} }
private static void exp2reg (FuncState fs, expdesc e, int reg) { private static void exp2reg (FuncState fs, expdesc e, int reg) {
discharge2reg(fs, e, reg); discharge2reg(fs, e, reg);
if (e.k == expkind.VJMP) if (e.k == expkind.VJMP)
luaK_concat(fs, ref e.t, e.u.s.info); /* put this jump in `t' list */ luaK_concat(fs, ref e.t, e.u.s.info); /* put this jump in `t' list */
if (hasjumps(e)) { if (hasjumps(e)) {
int final; /* position after whole expression */ int final; /* position after whole expression */
int p_f = NO_JUMP; /* position of an eventual LOAD false */ int p_f = NO_JUMP; /* position of an eventual LOAD false */
int p_t = NO_JUMP; /* position of an eventual LOAD true */ int p_t = NO_JUMP; /* position of an eventual LOAD true */
if (need_value(fs, e.t)!=0 || need_value(fs, e.f)!=0) { if (need_value(fs, e.t)!=0 || need_value(fs, e.f)!=0) {
int fj = (e.k == expkind.VJMP) ? NO_JUMP : luaK_jump(fs); int fj = (e.k == expkind.VJMP) ? NO_JUMP : luaK_jump(fs);
p_f = code_label(fs, reg, 0, 1); p_f = code_label(fs, reg, 0, 1);
p_t = code_label(fs, reg, 1, 0); p_t = code_label(fs, reg, 1, 0);
luaK_patchtohere(fs, fj); luaK_patchtohere(fs, fj);
} }
final = luaK_getlabel(fs); final = luaK_getlabel(fs);
patchlistaux(fs, e.f, final, reg, p_f); patchlistaux(fs, e.f, final, reg, p_f);
patchlistaux(fs, e.t, final, reg, p_t); patchlistaux(fs, e.t, final, reg, p_t);
} }
e.f = e.t = NO_JUMP; e.f = e.t = NO_JUMP;
e.u.s.info = reg; e.u.s.info = reg;
e.k = expkind.VNONRELOC; e.k = expkind.VNONRELOC;
} }
public static void luaK_exp2nextreg (FuncState fs, expdesc e) { public static void luaK_exp2nextreg (FuncState fs, expdesc e) {
luaK_dischargevars(fs, e); luaK_dischargevars(fs, e);
freeexp(fs, e); freeexp(fs, e);
luaK_reserveregs(fs, 1); luaK_reserveregs(fs, 1);
exp2reg(fs, e, fs.freereg - 1); exp2reg(fs, e, fs.freereg - 1);
} }
public static int luaK_exp2anyreg (FuncState fs, expdesc e) { public static int luaK_exp2anyreg (FuncState fs, expdesc e) {
luaK_dischargevars(fs, e); luaK_dischargevars(fs, e);
if (e.k == expkind.VNONRELOC) { if (e.k == expkind.VNONRELOC) {
if (!hasjumps(e)) return e.u.s.info; /* exp is already in a register */ if (!hasjumps(e)) return e.u.s.info; /* exp is already in a register */
if (e.u.s.info >= fs.nactvar) { /* reg. is not a local? */ if (e.u.s.info >= fs.nactvar) { /* reg. is not a local? */
exp2reg(fs, e, e.u.s.info); /* put value on it */ exp2reg(fs, e, e.u.s.info); /* put value on it */
return e.u.s.info; return e.u.s.info;
} }
} }
luaK_exp2nextreg(fs, e); /* default */ luaK_exp2nextreg(fs, e); /* default */
return e.u.s.info; return e.u.s.info;
} }
public static void luaK_exp2val (FuncState fs, expdesc e) { public static void luaK_exp2val (FuncState fs, expdesc e) {
if (hasjumps(e)) if (hasjumps(e))
luaK_exp2anyreg(fs, e); luaK_exp2anyreg(fs, e);
else else
luaK_dischargevars(fs, e); luaK_dischargevars(fs, e);
} }
public static int luaK_exp2RK (FuncState fs, expdesc e) { public static int luaK_exp2RK (FuncState fs, expdesc e) {
luaK_exp2val(fs, e); luaK_exp2val(fs, e);
switch (e.k) { switch (e.k) {
case expkind.VKNUM: case expkind.VKNUM:
case expkind.VTRUE: case expkind.VTRUE:
case expkind.VFALSE: case expkind.VFALSE:
case expkind.VNIL: { case expkind.VNIL: {
if (fs.nk <= MAXINDEXRK) { /* constant fit in RK operand? */ if (fs.nk <= MAXINDEXRK) { /* constant fit in RK operand? */
e.u.s.info = (e.k == expkind.VNIL) ? nilK(fs) : e.u.s.info = (e.k == expkind.VNIL) ? nilK(fs) :
(e.k == expkind.VKNUM) ? luaK_numberK(fs, e.u.nval) : (e.k == expkind.VKNUM) ? luaK_numberK(fs, e.u.nval) :
boolK(fs, (e.k == expkind.VTRUE) ? 1 : 0); boolK(fs, (e.k == expkind.VTRUE) ? 1 : 0);
e.k = expkind.VK; e.k = expkind.VK;
return RKASK(e.u.s.info); return RKASK(e.u.s.info);
} }
else break; else break;
} }
case expkind.VK: { case expkind.VK: {
if (e.u.s.info <= MAXINDEXRK) /* constant fit in argC? */ if (e.u.s.info <= MAXINDEXRK) /* constant fit in argC? */
return RKASK(e.u.s.info); return RKASK(e.u.s.info);
else break; else break;
} }
default: break; default: break;
} }
/* not a constant in the right range: put it in a register */ /* not a constant in the right range: put it in a register */
return luaK_exp2anyreg(fs, e); return luaK_exp2anyreg(fs, e);
} }
public static void luaK_storevar (FuncState fs, expdesc var, expdesc ex) { public static void luaK_storevar (FuncState fs, expdesc var, expdesc ex) {
switch (var.k) { switch (var.k) {
case expkind.VLOCAL: { case expkind.VLOCAL: {
freeexp(fs, ex); freeexp(fs, ex);
exp2reg(fs, ex, var.u.s.info); exp2reg(fs, ex, var.u.s.info);
return; return;
} }
case expkind.VUPVAL: { case expkind.VUPVAL: {
int e = luaK_exp2anyreg(fs, ex); int e = luaK_exp2anyreg(fs, ex);
luaK_codeABC(fs, OpCode.OP_SETUPVAL, e, var.u.s.info, 0); luaK_codeABC(fs, OpCode.OP_SETUPVAL, e, var.u.s.info, 0);
break; break;
} }
case expkind.VGLOBAL: { case expkind.VGLOBAL: {
int e = luaK_exp2anyreg(fs, ex); int e = luaK_exp2anyreg(fs, ex);
luaK_codeABx(fs, OpCode.OP_SETGLOBAL, e, var.u.s.info); luaK_codeABx(fs, OpCode.OP_SETGLOBAL, e, var.u.s.info);
break; break;
} }
case expkind.VINDEXED: { case expkind.VINDEXED: {
int e = luaK_exp2RK(fs, ex); int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, OpCode.OP_SETTABLE, var.u.s.info, var.u.s.aux, e); luaK_codeABC(fs, OpCode.OP_SETTABLE, var.u.s.info, var.u.s.aux, e);
break; break;
} }
default: { default: {
lua_assert(0); /* invalid var kind to store */ lua_assert(0); /* invalid var kind to store */
break; break;
} }
} }
freeexp(fs, ex); freeexp(fs, ex);
} }
public static void luaK_self (FuncState fs, expdesc e, expdesc key) { public static void luaK_self (FuncState fs, expdesc e, expdesc key) {
int func; int func;
luaK_exp2anyreg(fs, e); luaK_exp2anyreg(fs, e);
freeexp(fs, e); freeexp(fs, e);
func = fs.freereg; func = fs.freereg;
luaK_reserveregs(fs, 2); luaK_reserveregs(fs, 2);
luaK_codeABC(fs, OpCode.OP_SELF, func, e.u.s.info, luaK_exp2RK(fs, key)); luaK_codeABC(fs, OpCode.OP_SELF, func, e.u.s.info, luaK_exp2RK(fs, key));
freeexp(fs, key); freeexp(fs, key);
e.u.s.info = func; e.u.s.info = func;
e.k = expkind.VNONRELOC; e.k = expkind.VNONRELOC;
} }
private static void invertjump (FuncState fs, expdesc e) { private static void invertjump (FuncState fs, expdesc e) {
InstructionPtr pc = getjumpcontrol(fs, e.u.s.info); InstructionPtr pc = getjumpcontrol(fs, e.u.s.info);
lua_assert(testTMode(GET_OPCODE(pc[0])) != 0 && GET_OPCODE(pc[0]) != OpCode.OP_TESTSET && lua_assert(testTMode(GET_OPCODE(pc[0])) != 0 && GET_OPCODE(pc[0]) != OpCode.OP_TESTSET &&
GET_OPCODE(pc[0]) != OpCode.OP_TEST); GET_OPCODE(pc[0]) != OpCode.OP_TEST);
SETARG_A(pc, (GETARG_A(pc[0]) == 0) ? 1 : 0); SETARG_A(pc, (GETARG_A(pc[0]) == 0) ? 1 : 0);
} }
private static int jumponcond (FuncState fs, expdesc e, int cond) { private static int jumponcond (FuncState fs, expdesc e, int cond) {
if (e.k == expkind.VRELOCABLE) { if (e.k == expkind.VRELOCABLE) {
InstructionPtr ie = getcode(fs, e); InstructionPtr ie = getcode(fs, e);
if (GET_OPCODE(ie) == OpCode.OP_NOT) { if (GET_OPCODE(ie) == OpCode.OP_NOT) {
fs.pc--; /* remove previous OpCode.OP_NOT */ fs.pc--; /* remove previous OpCode.OP_NOT */
return condjump(fs, OpCode.OP_TEST, GETARG_B(ie), 0, (cond==0) ? 1 : 0); return condjump(fs, OpCode.OP_TEST, GETARG_B(ie), 0, (cond==0) ? 1 : 0);
} }
/* else go through */ /* else go through */
} }
discharge2anyreg(fs, e); discharge2anyreg(fs, e);
freeexp(fs, e); freeexp(fs, e);
return condjump(fs, OpCode.OP_TESTSET, NO_REG, e.u.s.info, cond); return condjump(fs, OpCode.OP_TESTSET, NO_REG, e.u.s.info, cond);
} }
public static void luaK_goiftrue (FuncState fs, expdesc e) { public static void luaK_goiftrue (FuncState fs, expdesc e) {
int pc; /* pc of last jump */ int pc; /* pc of last jump */
luaK_dischargevars(fs, e); luaK_dischargevars(fs, e);
switch (e.k) { switch (e.k) {
case expkind.VK: case expkind.VKNUM: case expkind.VTRUE: { case expkind.VK: case expkind.VKNUM: case expkind.VTRUE: {
pc = NO_JUMP; /* always true; do nothing */ pc = NO_JUMP; /* always true; do nothing */
break; break;
} }
case expkind.VFALSE: { case expkind.VFALSE: {
pc = luaK_jump(fs); /* always jump */ pc = luaK_jump(fs); /* always jump */
break; break;
} }
case expkind.VJMP: { case expkind.VJMP: {
invertjump(fs, e); invertjump(fs, e);
pc = e.u.s.info; pc = e.u.s.info;
break; break;
} }
default: { default: {
pc = jumponcond(fs, e, 0); pc = jumponcond(fs, e, 0);
break; break;
} }
} }
luaK_concat(fs, ref e.f, pc); /* insert last jump in `f' list */ luaK_concat(fs, ref e.f, pc); /* insert last jump in `f' list */
luaK_patchtohere(fs, e.t); luaK_patchtohere(fs, e.t);
e.t = NO_JUMP; e.t = NO_JUMP;
} }
private static void luaK_goiffalse (FuncState fs, expdesc e) { private static void luaK_goiffalse (FuncState fs, expdesc e) {
int pc; /* pc of last jump */ int pc; /* pc of last jump */
luaK_dischargevars(fs, e); luaK_dischargevars(fs, e);
switch (e.k) { switch (e.k) {
case expkind.VNIL: case expkind.VFALSE: { case expkind.VNIL: case expkind.VFALSE: {
pc = NO_JUMP; /* always false; do nothing */ pc = NO_JUMP; /* always false; do nothing */
break; break;
} }
case expkind.VTRUE: { case expkind.VTRUE: {
pc = luaK_jump(fs); /* always jump */ pc = luaK_jump(fs); /* always jump */
break; break;
} }
case expkind.VJMP: { case expkind.VJMP: {
pc = e.u.s.info; pc = e.u.s.info;
break; break;
} }
default: { default: {
pc = jumponcond(fs, e, 1); pc = jumponcond(fs, e, 1);
break; break;
} }
} }
luaK_concat(fs, ref e.t, pc); /* insert last jump in `t' list */ luaK_concat(fs, ref e.t, pc); /* insert last jump in `t' list */
luaK_patchtohere(fs, e.f); luaK_patchtohere(fs, e.f);
e.f = NO_JUMP; e.f = NO_JUMP;
} }
private static void codenot (FuncState fs, expdesc e) { private static void codenot (FuncState fs, expdesc e) {
luaK_dischargevars(fs, e); luaK_dischargevars(fs, e);
switch (e.k) { switch (e.k) {
case expkind.VNIL: case expkind.VFALSE: { case expkind.VNIL: case expkind.VFALSE: {
e.k = expkind.VTRUE; e.k = expkind.VTRUE;
break; break;
} }
case expkind.VK: case expkind.VKNUM: case expkind.VTRUE: { case expkind.VK: case expkind.VKNUM: case expkind.VTRUE: {
e.k = expkind.VFALSE; e.k = expkind.VFALSE;
break; break;
} }
case expkind.VJMP: { case expkind.VJMP: {
invertjump(fs, e); invertjump(fs, e);
break; break;
} }
case expkind.VRELOCABLE: case expkind.VRELOCABLE:
case expkind.VNONRELOC: { case expkind.VNONRELOC: {
discharge2anyreg(fs, e); discharge2anyreg(fs, e);
freeexp(fs, e); freeexp(fs, e);
e.u.s.info = luaK_codeABC(fs, OpCode.OP_NOT, 0, e.u.s.info, 0); e.u.s.info = luaK_codeABC(fs, OpCode.OP_NOT, 0, e.u.s.info, 0);
e.k = expkind.VRELOCABLE; e.k = expkind.VRELOCABLE;
break; break;
} }
default: { default: {
lua_assert(0); /* cannot happen */ lua_assert(0); /* cannot happen */
break; break;
} }
} }
/* interchange true and false lists */ /* interchange true and false lists */
{ int temp = e.f; e.f = e.t; e.t = temp; } { int temp = e.f; e.f = e.t; e.t = temp; }
removevalues(fs, e.f); removevalues(fs, e.f);
removevalues(fs, e.t); removevalues(fs, e.t);
} }
public static void luaK_indexed (FuncState fs, expdesc t, expdesc k) { public static void luaK_indexed (FuncState fs, expdesc t, expdesc k) {
t.u.s.aux = luaK_exp2RK(fs, k); t.u.s.aux = luaK_exp2RK(fs, k);
t.k = expkind.VINDEXED; t.k = expkind.VINDEXED;
} }
private static int constfolding (OpCode op, expdesc e1, expdesc e2) { private static int constfolding (OpCode op, expdesc e1, expdesc e2) {
lua_Number v1, v2, r; lua_Number v1, v2, r;
if ((isnumeral(e1)==0) || (isnumeral(e2)==0)) return 0; if ((isnumeral(e1)==0) || (isnumeral(e2)==0)) return 0;
v1 = e1.u.nval; v1 = e1.u.nval;
v2 = e2.u.nval; v2 = e2.u.nval;
switch (op) { switch (op) {
case OpCode.OP_ADD: r = luai_numadd(v1, v2); break; case OpCode.OP_ADD: r = luai_numadd(v1, v2); break;
case OpCode.OP_SUB: r = luai_numsub(v1, v2); break; case OpCode.OP_SUB: r = luai_numsub(v1, v2); break;
case OpCode.OP_MUL: r = luai_nummul(v1, v2); break; case OpCode.OP_MUL: r = luai_nummul(v1, v2); break;
case OpCode.OP_DIV: case OpCode.OP_DIV:
if (v2 == 0) return 0; /* do not attempt to divide by 0 */ if (v2 == 0) return 0; /* do not attempt to divide by 0 */
r = luai_numdiv(v1, v2); break; r = luai_numdiv(v1, v2); break;
case OpCode.OP_MOD: case OpCode.OP_MOD:
if (v2 == 0) return 0; /* do not attempt to divide by 0 */ if (v2 == 0) return 0; /* do not attempt to divide by 0 */
r = luai_nummod(v1, v2); break; r = luai_nummod(v1, v2); break;
case OpCode.OP_POW: r = luai_numpow(v1, v2); break; case OpCode.OP_POW: r = luai_numpow(v1, v2); break;
case OpCode.OP_UNM: r = luai_numunm(v1); break; case OpCode.OP_UNM: r = luai_numunm(v1); break;
case OpCode.OP_LEN: return 0; /* no constant folding for 'len' */ case OpCode.OP_LEN: return 0; /* no constant folding for 'len' */
default: lua_assert(0); r = 0; break; default: lua_assert(0); r = 0; break;
} }
if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */ if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
e1.u.nval = r; e1.u.nval = r;
return 1; return 1;
} }
private static void codearith (FuncState fs, OpCode op, expdesc e1, expdesc e2) { private static void codearith (FuncState fs, OpCode op, expdesc e1, expdesc e2) {
if (constfolding(op, e1, e2) != 0) if (constfolding(op, e1, e2) != 0)
return; return;
else { else {
int o2 = (op != OpCode.OP_UNM && op != OpCode.OP_LEN) ? luaK_exp2RK(fs, e2) : 0; int o2 = (op != OpCode.OP_UNM && op != OpCode.OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
int o1 = luaK_exp2RK(fs, e1); int o1 = luaK_exp2RK(fs, e1);
if (o1 > o2) { if (o1 > o2) {
freeexp(fs, e1); freeexp(fs, e1);
freeexp(fs, e2); freeexp(fs, e2);
} }
else { else {
freeexp(fs, e2); freeexp(fs, e2);
freeexp(fs, e1); freeexp(fs, e1);
} }
e1.u.s.info = luaK_codeABC(fs, op, 0, o1, o2); e1.u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
e1.k = expkind.VRELOCABLE; e1.k = expkind.VRELOCABLE;
} }
} }
private static void codecomp (FuncState fs, OpCode op, int cond, expdesc e1, private static void codecomp (FuncState fs, OpCode op, int cond, expdesc e1,
expdesc e2) { expdesc e2) {
int o1 = luaK_exp2RK(fs, e1); int o1 = luaK_exp2RK(fs, e1);
int o2 = luaK_exp2RK(fs, e2); int o2 = luaK_exp2RK(fs, e2);
freeexp(fs, e2); freeexp(fs, e2);
freeexp(fs, e1); freeexp(fs, e1);
if (cond == 0 && op != OpCode.OP_EQ) { if (cond == 0 && op != OpCode.OP_EQ) {
int temp; /* exchange args to replace by `<' or `<=' */ int temp; /* exchange args to replace by `<' or `<=' */
temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
cond = 1; cond = 1;
} }
e1.u.s.info = condjump(fs, op, cond, o1, o2); e1.u.s.info = condjump(fs, op, cond, o1, o2);
e1.k = expkind.VJMP; e1.k = expkind.VJMP;
} }
public static void luaK_prefix (FuncState fs, UnOpr op, expdesc e) { public static void luaK_prefix (FuncState fs, UnOpr op, expdesc e) {
expdesc e2 = new expdesc(); expdesc e2 = new expdesc();
e2.t = e2.f = NO_JUMP; e2.k = expkind.VKNUM; e2.u.nval = 0; e2.t = e2.f = NO_JUMP; e2.k = expkind.VKNUM; e2.u.nval = 0;
switch (op) { switch (op) {
case UnOpr.OPR_MINUS: { case UnOpr.OPR_MINUS: {
if (isnumeral(e)==0) if (isnumeral(e)==0)
luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
codearith(fs, OpCode.OP_UNM, e, e2); codearith(fs, OpCode.OP_UNM, e, e2);
break; break;
} }
case UnOpr.OPR_NOT: codenot(fs, e); break; case UnOpr.OPR_NOT: codenot(fs, e); break;
case UnOpr.OPR_LEN: { case UnOpr.OPR_LEN: {
luaK_exp2anyreg(fs, e); /* cannot operate on constants */ luaK_exp2anyreg(fs, e); /* cannot operate on constants */
codearith(fs, OpCode.OP_LEN, e, e2); codearith(fs, OpCode.OP_LEN, e, e2);
break; break;
} }
default: lua_assert(0); break; default: lua_assert(0); break;
} }
} }
public static void luaK_infix (FuncState fs, BinOpr op, expdesc v) { public static void luaK_infix (FuncState fs, BinOpr op, expdesc v) {
switch (op) { switch (op) {
case BinOpr.OPR_AND: { case BinOpr.OPR_AND: {
luaK_goiftrue(fs, v); luaK_goiftrue(fs, v);
break; break;
} }
case BinOpr.OPR_OR: { case BinOpr.OPR_OR: {
luaK_goiffalse(fs, v); luaK_goiffalse(fs, v);
break; break;
} }
case BinOpr.OPR_CONCAT: { case BinOpr.OPR_CONCAT: {
luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
break; break;
} }
case BinOpr.OPR_ADD: case BinOpr.OPR_SUB: case BinOpr.OPR_MUL: case BinOpr.OPR_DIV: case BinOpr.OPR_ADD: case BinOpr.OPR_SUB: case BinOpr.OPR_MUL: case BinOpr.OPR_DIV:
case BinOpr.OPR_MOD: case BinOpr.OPR_POW: { case BinOpr.OPR_MOD: case BinOpr.OPR_POW: {
if ((isnumeral(v)==0)) luaK_exp2RK(fs, v); if ((isnumeral(v)==0)) luaK_exp2RK(fs, v);
break; break;
} }
default: { default: {
luaK_exp2RK(fs, v); luaK_exp2RK(fs, v);
break; break;
} }
} }
} }
public static void luaK_posfix (FuncState fs, BinOpr op, expdesc e1, expdesc e2) { public static void luaK_posfix (FuncState fs, BinOpr op, expdesc e1, expdesc e2) {
switch (op) { switch (op) {
case BinOpr.OPR_AND: { case BinOpr.OPR_AND: {
lua_assert(e1.t == NO_JUMP); /* list must be closed */ lua_assert(e1.t == NO_JUMP); /* list must be closed */
luaK_dischargevars(fs, e2); luaK_dischargevars(fs, e2);
luaK_concat(fs, ref e2.f, e1.f); luaK_concat(fs, ref e2.f, e1.f);
e1.Copy(e2); e1.Copy(e2);
break; break;
} }
case BinOpr.OPR_OR: { case BinOpr.OPR_OR: {
lua_assert(e1.f == NO_JUMP); /* list must be closed */ lua_assert(e1.f == NO_JUMP); /* list must be closed */
luaK_dischargevars(fs, e2); luaK_dischargevars(fs, e2);
luaK_concat(fs, ref e2.t, e1.t); luaK_concat(fs, ref e2.t, e1.t);
e1.Copy(e2); e1.Copy(e2);
break; break;
} }
case BinOpr.OPR_CONCAT: { case BinOpr.OPR_CONCAT: {
luaK_exp2val(fs, e2); luaK_exp2val(fs, e2);
if (e2.k == expkind.VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OpCode.OP_CONCAT) { if (e2.k == expkind.VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OpCode.OP_CONCAT) {
lua_assert(e1.u.s.info == GETARG_B(getcode(fs, e2))-1); lua_assert(e1.u.s.info == GETARG_B(getcode(fs, e2))-1);
freeexp(fs, e1); freeexp(fs, e1);
SETARG_B(getcode(fs, e2), e1.u.s.info); SETARG_B(getcode(fs, e2), e1.u.s.info);
e1.k = expkind.VRELOCABLE; e1.u.s.info = e2.u.s.info; e1.k = expkind.VRELOCABLE; e1.u.s.info = e2.u.s.info;
} }
else { else {
luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
codearith(fs, OpCode.OP_CONCAT, e1, e2); codearith(fs, OpCode.OP_CONCAT, e1, e2);
} }
break; break;
} }
case BinOpr.OPR_ADD: codearith(fs, OpCode.OP_ADD, e1, e2); break; case BinOpr.OPR_ADD: codearith(fs, OpCode.OP_ADD, e1, e2); break;
case BinOpr.OPR_SUB: codearith(fs, OpCode.OP_SUB, e1, e2); break; case BinOpr.OPR_SUB: codearith(fs, OpCode.OP_SUB, e1, e2); break;
case BinOpr.OPR_MUL: codearith(fs, OpCode.OP_MUL, e1, e2); break; case BinOpr.OPR_MUL: codearith(fs, OpCode.OP_MUL, e1, e2); break;
case BinOpr.OPR_DIV: codearith(fs, OpCode.OP_DIV, e1, e2); break; case BinOpr.OPR_DIV: codearith(fs, OpCode.OP_DIV, e1, e2); break;
case BinOpr.OPR_MOD: codearith(fs, OpCode.OP_MOD, e1, e2); break; case BinOpr.OPR_MOD: codearith(fs, OpCode.OP_MOD, e1, e2); break;
case BinOpr.OPR_POW: codearith(fs, OpCode.OP_POW, e1, e2); break; case BinOpr.OPR_POW: codearith(fs, OpCode.OP_POW, e1, e2); break;
case BinOpr.OPR_EQ: codecomp(fs, OpCode.OP_EQ, 1, e1, e2); break; case BinOpr.OPR_EQ: codecomp(fs, OpCode.OP_EQ, 1, e1, e2); break;
case BinOpr.OPR_NE: codecomp(fs, OpCode.OP_EQ, 0, e1, e2); break; case BinOpr.OPR_NE: codecomp(fs, OpCode.OP_EQ, 0, e1, e2); break;
case BinOpr.OPR_LT: codecomp(fs, OpCode.OP_LT, 1, e1, e2); break; case BinOpr.OPR_LT: codecomp(fs, OpCode.OP_LT, 1, e1, e2); break;
case BinOpr.OPR_LE: codecomp(fs, OpCode.OP_LE, 1, e1, e2); break; case BinOpr.OPR_LE: codecomp(fs, OpCode.OP_LE, 1, e1, e2); break;
case BinOpr.OPR_GT: codecomp(fs, OpCode.OP_LT, 0, e1, e2); break; case BinOpr.OPR_GT: codecomp(fs, OpCode.OP_LT, 0, e1, e2); break;
case BinOpr.OPR_GE: codecomp(fs, OpCode.OP_LE, 0, e1, e2); break; case BinOpr.OPR_GE: codecomp(fs, OpCode.OP_LE, 0, e1, e2); break;
default: lua_assert(0); break; default: lua_assert(0); break;
} }
} }
public static void luaK_fixline (FuncState fs, int line) { public static void luaK_fixline (FuncState fs, int line) {
fs.f.lineinfo[fs.pc - 1] = line; fs.f.lineinfo[fs.pc - 1] = line;
} }
private static int luaK_code (FuncState fs, int i, int line) { private static int luaK_code (FuncState fs, int i, int line) {
Proto f = fs.f; Proto f = fs.f;
dischargejpc(fs); /* `pc' will change */ dischargejpc(fs); /* `pc' will change */
/* put new instruction in code array */ /* put new instruction in code array */
luaM_growvector(fs.L, ref f.code, fs.pc, ref f.sizecode, luaM_growvector(fs.L, ref f.code, fs.pc, ref f.sizecode,
MAX_INT, "code size overflow"); MAX_INT, "code size overflow");
f.code[fs.pc] = (uint)i; f.code[fs.pc] = (uint)i;
/* save corresponding line information */ /* save corresponding line information */
luaM_growvector(fs.L, ref f.lineinfo, fs.pc, ref f.sizelineinfo, luaM_growvector(fs.L, ref f.lineinfo, fs.pc, ref f.sizelineinfo,
MAX_INT, "code size overflow"); MAX_INT, "code size overflow");
f.lineinfo[fs.pc] = line; f.lineinfo[fs.pc] = line;
return fs.pc++; return fs.pc++;
} }
public static int luaK_codeABC (FuncState fs, OpCode o, int a, int b, int c) { public static int luaK_codeABC (FuncState fs, OpCode o, int a, int b, int c) {
lua_assert(getOpMode(o) == OpMode.iABC); lua_assert(getOpMode(o) == OpMode.iABC);
lua_assert(getBMode(o) != OpArgMask.OpArgN || b == 0); lua_assert(getBMode(o) != OpArgMask.OpArgN || b == 0);
lua_assert(getCMode(o) != OpArgMask.OpArgN || c == 0); lua_assert(getCMode(o) != OpArgMask.OpArgN || c == 0);
return luaK_code(fs, CREATE_ABC(o, a, b, c), fs.ls.lastline); return luaK_code(fs, CREATE_ABC(o, a, b, c), fs.ls.lastline);
} }
public static int luaK_codeABx (FuncState fs, OpCode o, int a, int bc) { public static int luaK_codeABx (FuncState fs, OpCode o, int a, int bc) {
lua_assert(getOpMode(o) == OpMode.iABx || getOpMode(o) == OpMode.iAsBx); lua_assert(getOpMode(o) == OpMode.iABx || getOpMode(o) == OpMode.iAsBx);
lua_assert(getCMode(o) == OpArgMask.OpArgN); lua_assert(getCMode(o) == OpArgMask.OpArgN);
return luaK_code(fs, CREATE_ABx(o, a, bc), fs.ls.lastline); return luaK_code(fs, CREATE_ABx(o, a, bc), fs.ls.lastline);
} }
public static void luaK_setlist (FuncState fs, int base_, int nelems, int tostore) { public static void luaK_setlist (FuncState fs, int base_, int nelems, int tostore) {
int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
int b = (tostore == LUA_MULTRET) ? 0 : tostore; int b = (tostore == LUA_MULTRET) ? 0 : tostore;
lua_assert(tostore != 0); lua_assert(tostore != 0);
if (c <= MAXARG_C) if (c <= MAXARG_C)
luaK_codeABC(fs, OpCode.OP_SETLIST, base_, b, c); luaK_codeABC(fs, OpCode.OP_SETLIST, base_, b, c);
else { else {
luaK_codeABC(fs, OpCode.OP_SETLIST, base_, b, 0); luaK_codeABC(fs, OpCode.OP_SETLIST, base_, b, 0);
luaK_code(fs, c, fs.ls.lastline); luaK_code(fs, c, fs.ls.lastline);
} }
fs.freereg = base_ + 1; /* free registers with list values */ fs.freereg = base_ + 1; /* free registers with list values */
} }
} }
} }
/* /*
** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $ ** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $
** Interface from Lua to its debug API ** Interface from Lua to its debug API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace KopiLua namespace KopiLua
{ {
public partial class Lua public partial class Lua
{ {
private static int db_getregistry (lua_State L) { private static int db_getregistry (lua_State L) {
lua_pushvalue(L, LUA_REGISTRYINDEX); lua_pushvalue(L, LUA_REGISTRYINDEX);
return 1; return 1;
} }
private static int db_getmetatable (lua_State L) { private static int db_getmetatable (lua_State L) {
luaL_checkany(L, 1); luaL_checkany(L, 1);
if (lua_getmetatable(L, 1) == 0) { if (lua_getmetatable(L, 1) == 0) {
lua_pushnil(L); /* no metatable */ lua_pushnil(L); /* no metatable */
} }
return 1; return 1;
} }
private static int db_setmetatable (lua_State L) { private static int db_setmetatable (lua_State L) {
int t = lua_type(L, 2); int t = lua_type(L, 2);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected"); "nil or table expected");
lua_settop(L, 2); lua_settop(L, 2);
lua_pushboolean(L, lua_setmetatable(L, 1)); lua_pushboolean(L, lua_setmetatable(L, 1));
return 1; return 1;
} }
private static int db_getfenv (lua_State L) { private static int db_getfenv (lua_State L) {
lua_getfenv(L, 1); lua_getfenv(L, 1);
return 1; return 1;
} }
private static int db_setfenv (lua_State L) { private static int db_setfenv (lua_State L) {
luaL_checktype(L, 2, LUA_TTABLE); luaL_checktype(L, 2, LUA_TTABLE);
lua_settop(L, 2); lua_settop(L, 2);
if (lua_setfenv(L, 1) == 0) if (lua_setfenv(L, 1) == 0)
luaL_error(L, LUA_QL("setfenv") + luaL_error(L, LUA_QL("setfenv") +
" cannot change environment of given object"); " cannot change environment of given object");
return 1; return 1;
} }
private static void settabss (lua_State L, CharPtr i, CharPtr v) { private static void settabss (lua_State L, CharPtr i, CharPtr v) {
lua_pushstring(L, v); lua_pushstring(L, v);
lua_setfield(L, -2, i); lua_setfield(L, -2, i);
} }
private static void settabsi (lua_State L, CharPtr i, int v) { private static void settabsi (lua_State L, CharPtr i, int v) {
lua_pushinteger(L, v); lua_pushinteger(L, v);
lua_setfield(L, -2, i); lua_setfield(L, -2, i);
} }
private static lua_State getthread (lua_State L, out int arg) { private static lua_State getthread (lua_State L, out int arg) {
if (lua_isthread(L, 1)) { if (lua_isthread(L, 1)) {
arg = 1; arg = 1;
return lua_tothread(L, 1); return lua_tothread(L, 1);
} }
else { else {
arg = 0; arg = 0;
return L; return L;
} }
} }
private static void treatstackoption (lua_State L, lua_State L1, CharPtr fname) { private static void treatstackoption (lua_State L, lua_State L1, CharPtr fname) {
if (L == L1) { if (L == L1) {
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
lua_remove(L, -3); lua_remove(L, -3);
} }
else else
lua_xmove(L1, L, 1); lua_xmove(L1, L, 1);
lua_setfield(L, -2, fname); lua_setfield(L, -2, fname);
} }
private static int db_getinfo (lua_State L) { private static int db_getinfo (lua_State L) {
lua_Debug ar = new lua_Debug(); lua_Debug ar = new lua_Debug();
int arg; int arg;
lua_State L1 = getthread(L, out arg); lua_State L1 = getthread(L, out arg);
CharPtr options = luaL_optstring(L, arg+2, "flnSu"); CharPtr options = luaL_optstring(L, arg+2, "flnSu");
if (lua_isnumber(L, arg+1) != 0) { if (lua_isnumber(L, arg+1) != 0) {
if (lua_getstack(L1, (int)lua_tointeger(L, arg+1), ar)==0) { if (lua_getstack(L1, (int)lua_tointeger(L, arg+1), ar)==0) {
lua_pushnil(L); /* level out of range */ lua_pushnil(L); /* level out of range */
return 1; return 1;
} }
} }
else if (lua_isfunction(L, arg+1)) { else if (lua_isfunction(L, arg+1)) {
lua_pushfstring(L, ">%s", options); lua_pushfstring(L, ">%s", options);
options = lua_tostring(L, -1); options = lua_tostring(L, -1);
lua_pushvalue(L, arg+1); lua_pushvalue(L, arg+1);
lua_xmove(L, L1, 1); lua_xmove(L, L1, 1);
} }
else else
return luaL_argerror(L, arg+1, "function or level expected"); return luaL_argerror(L, arg+1, "function or level expected");
if (lua_getinfo(L1, options, ar)==0) if (lua_getinfo(L1, options, ar)==0)
return luaL_argerror(L, arg+2, "invalid option"); return luaL_argerror(L, arg+2, "invalid option");
lua_createtable(L, 0, 2); lua_createtable(L, 0, 2);
if (strchr(options, 'S') != null) { if (strchr(options, 'S') != null) {
settabss(L, "source", ar.source); settabss(L, "source", ar.source);
settabss(L, "short_src", ar.short_src); settabss(L, "short_src", ar.short_src);
settabsi(L, "linedefined", ar.linedefined); settabsi(L, "linedefined", ar.linedefined);
settabsi(L, "lastlinedefined", ar.lastlinedefined); settabsi(L, "lastlinedefined", ar.lastlinedefined);
settabss(L, "what", ar.what); settabss(L, "what", ar.what);
} }
if (strchr(options, 'l') != null) if (strchr(options, 'l') != null)
settabsi(L, "currentline", ar.currentline); settabsi(L, "currentline", ar.currentline);
if (strchr(options, 'u') != null) if (strchr(options, 'u') != null)
settabsi(L, "nups", ar.nups); settabsi(L, "nups", ar.nups);
if (strchr(options, 'n') != null) { if (strchr(options, 'n') != null) {
settabss(L, "name", ar.name); settabss(L, "name", ar.name);
settabss(L, "namewhat", ar.namewhat); settabss(L, "namewhat", ar.namewhat);
} }
if (strchr(options, 'L') != null) if (strchr(options, 'L') != null)
treatstackoption(L, L1, "activelines"); treatstackoption(L, L1, "activelines");
if (strchr(options, 'f') != null) if (strchr(options, 'f') != null)
treatstackoption(L, L1, "func"); treatstackoption(L, L1, "func");
return 1; /* return table */ return 1; /* return table */
} }
private static int db_getlocal (lua_State L) { private static int db_getlocal (lua_State L) {
int arg; int arg;
lua_State L1 = getthread(L, out arg); lua_State L1 = getthread(L, out arg);
lua_Debug ar = new lua_Debug(); lua_Debug ar = new lua_Debug();
CharPtr name; CharPtr name;
if (lua_getstack(L1, luaL_checkint(L, arg+1), ar)==0) /* out of range? */ if (lua_getstack(L1, luaL_checkint(L, arg+1), ar)==0) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range"); return luaL_argerror(L, arg+1, "level out of range");
name = lua_getlocal(L1, ar, luaL_checkint(L, arg+2)); name = lua_getlocal(L1, ar, luaL_checkint(L, arg+2));
if (name != null) { if (name != null) {
lua_xmove(L1, L, 1); lua_xmove(L1, L, 1);
lua_pushstring(L, name); lua_pushstring(L, name);
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
return 2; return 2;
} }
else { else {
lua_pushnil(L); lua_pushnil(L);
return 1; return 1;
} }
} }
private static int db_setlocal (lua_State L) { private static int db_setlocal (lua_State L) {
int arg; int arg;
lua_State L1 = getthread(L, out arg); lua_State L1 = getthread(L, out arg);
lua_Debug ar = new lua_Debug(); lua_Debug ar = new lua_Debug();
if (lua_getstack(L1, luaL_checkint(L, arg+1), ar)==0) /* out of range? */ if (lua_getstack(L1, luaL_checkint(L, arg+1), ar)==0) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range"); return luaL_argerror(L, arg+1, "level out of range");
luaL_checkany(L, arg+3); luaL_checkany(L, arg+3);
lua_settop(L, arg+3); lua_settop(L, arg+3);
lua_xmove(L, L1, 1); lua_xmove(L, L1, 1);
lua_pushstring(L, lua_setlocal(L1, ar, luaL_checkint(L, arg+2))); lua_pushstring(L, lua_setlocal(L1, ar, luaL_checkint(L, arg+2)));
return 1; return 1;
} }
private static int auxupvalue (lua_State L, int get) { private static int auxupvalue (lua_State L, int get) {
CharPtr name; CharPtr name;
int n = luaL_checkint(L, 2); int n = luaL_checkint(L, 2);
luaL_checktype(L, 1, LUA_TFUNCTION); luaL_checktype(L, 1, LUA_TFUNCTION);
if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
name = (get!=0) ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); name = (get!=0) ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
if (name == null) return 0; if (name == null) return 0;
lua_pushstring(L, name); lua_pushstring(L, name);
lua_insert(L, -(get+1)); lua_insert(L, -(get+1));
return get + 1; return get + 1;
} }
private static int db_getupvalue (lua_State L) { private static int db_getupvalue (lua_State L) {
return auxupvalue(L, 1); return auxupvalue(L, 1);
} }
private static int db_setupvalue (lua_State L) { private static int db_setupvalue (lua_State L) {
luaL_checkany(L, 3); luaL_checkany(L, 3);
return auxupvalue(L, 0); return auxupvalue(L, 0);
} }
private const string KEY_HOOK = "h"; private const string KEY_HOOK = "h";
private static readonly string[] hooknames = private static readonly string[] hooknames =
{"call", "return", "line", "count", "tail return"}; {"call", "return", "line", "count", "tail return"};
private static void hookf (lua_State L, lua_Debug ar) { private static void hookf (lua_State L, lua_Debug ar) {
lua_pushlightuserdata(L, KEY_HOOK); lua_pushlightuserdata(L, KEY_HOOK);
lua_rawget(L, LUA_REGISTRYINDEX); lua_rawget(L, LUA_REGISTRYINDEX);
lua_pushlightuserdata(L, L); lua_pushlightuserdata(L, L);
lua_rawget(L, -2); lua_rawget(L, -2);
if (lua_isfunction(L, -1)) { if (lua_isfunction(L, -1)) {
lua_pushstring(L, hooknames[(int)ar.event_]); lua_pushstring(L, hooknames[(int)ar.event_]);
if (ar.currentline >= 0) if (ar.currentline >= 0)
lua_pushinteger(L, ar.currentline); lua_pushinteger(L, ar.currentline);
else lua_pushnil(L); else lua_pushnil(L);
lua_assert(lua_getinfo(L, "lS", ar)); lua_assert(lua_getinfo(L, "lS", ar));
lua_call(L, 2, 0); lua_call(L, 2, 0);
} }
} }
private static int makemask (CharPtr smask, int count) { private static int makemask (CharPtr smask, int count) {
int mask = 0; int mask = 0;
if (strchr(smask, 'c') != null) mask |= LUA_MASKCALL; if (strchr(smask, 'c') != null) mask |= LUA_MASKCALL;
if (strchr(smask, 'r') != null) mask |= LUA_MASKRET; if (strchr(smask, 'r') != null) mask |= LUA_MASKRET;
if (strchr(smask, 'l') != null) mask |= LUA_MASKLINE; if (strchr(smask, 'l') != null) mask |= LUA_MASKLINE;
if (count > 0) mask |= LUA_MASKCOUNT; if (count > 0) mask |= LUA_MASKCOUNT;
return mask; return mask;
} }
private static CharPtr unmakemask (int mask, CharPtr smask) { private static CharPtr unmakemask (int mask, CharPtr smask) {
int i = 0; int i = 0;
if ((mask & LUA_MASKCALL) != 0) smask[i++] = 'c'; if ((mask & LUA_MASKCALL) != 0) smask[i++] = 'c';
if ((mask & LUA_MASKRET) != 0) smask[i++] = 'r'; if ((mask & LUA_MASKRET) != 0) smask[i++] = 'r';
if ((mask & LUA_MASKLINE) != 0) smask[i++] = 'l'; if ((mask & LUA_MASKLINE) != 0) smask[i++] = 'l';
smask[i] = '\0'; smask[i] = '\0';
return smask; return smask;
} }
private static void gethooktable (lua_State L) { private static void gethooktable (lua_State L) {
lua_pushlightuserdata(L, KEY_HOOK); lua_pushlightuserdata(L, KEY_HOOK);
lua_rawget(L, LUA_REGISTRYINDEX); lua_rawget(L, LUA_REGISTRYINDEX);
if (!lua_istable(L, -1)) { if (!lua_istable(L, -1)) {
lua_pop(L, 1); lua_pop(L, 1);
lua_createtable(L, 0, 1); lua_createtable(L, 0, 1);
lua_pushlightuserdata(L, KEY_HOOK); lua_pushlightuserdata(L, KEY_HOOK);
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
lua_rawset(L, LUA_REGISTRYINDEX); lua_rawset(L, LUA_REGISTRYINDEX);
} }
} }
private static int db_sethook (lua_State L) { private static int db_sethook (lua_State L) {
int arg, mask, count; int arg, mask, count;
lua_Hook func; lua_Hook func;
lua_State L1 = getthread(L, out arg); lua_State L1 = getthread(L, out arg);
if (lua_isnoneornil(L, arg+1)) { if (lua_isnoneornil(L, arg+1)) {
lua_settop(L, arg+1); lua_settop(L, arg+1);
func = null; mask = 0; count = 0; /* turn off hooks */ func = null; mask = 0; count = 0; /* turn off hooks */
} }
else { else {
CharPtr smask = luaL_checkstring(L, arg+2); CharPtr smask = luaL_checkstring(L, arg+2);
luaL_checktype(L, arg+1, LUA_TFUNCTION); luaL_checktype(L, arg+1, LUA_TFUNCTION);
count = luaL_optint(L, arg+3, 0); count = luaL_optint(L, arg+3, 0);
func = hookf; mask = makemask(smask, count); func = hookf; mask = makemask(smask, count);
} }
gethooktable(L); gethooktable(L);
lua_pushlightuserdata(L, L1); lua_pushlightuserdata(L, L1);
lua_pushvalue(L, arg+1); lua_pushvalue(L, arg+1);
lua_rawset(L, -3); /* set new hook */ lua_rawset(L, -3); /* set new hook */
lua_pop(L, 1); /* remove hook table */ lua_pop(L, 1); /* remove hook table */
lua_sethook(L1, func, mask, count); /* set hooks */ lua_sethook(L1, func, mask, count); /* set hooks */
return 0; return 0;
} }
private static int db_gethook (lua_State L) { private static int db_gethook (lua_State L) {
int arg; int arg;
lua_State L1 = getthread(L, out arg); lua_State L1 = getthread(L, out arg);
CharPtr buff = new char[5]; CharPtr buff = new char[5];
int mask = lua_gethookmask(L1); int mask = lua_gethookmask(L1);
lua_Hook hook = lua_gethook(L1); lua_Hook hook = lua_gethook(L1);
if (hook != null && hook != hookf) /* external hook? */ if (hook != null && hook != hookf) /* external hook? */
lua_pushliteral(L, "external hook"); lua_pushliteral(L, "external hook");
else { else {
gethooktable(L); gethooktable(L);
lua_pushlightuserdata(L, L1); lua_pushlightuserdata(L, L1);
lua_rawget(L, -2); /* get hook */ lua_rawget(L, -2); /* get hook */
lua_remove(L, -2); /* remove hook table */ lua_remove(L, -2); /* remove hook table */
} }
lua_pushstring(L, unmakemask(mask, buff)); lua_pushstring(L, unmakemask(mask, buff));
lua_pushinteger(L, lua_gethookcount(L1)); lua_pushinteger(L, lua_gethookcount(L1));
return 3; return 3;
} }
private static int db_debug (lua_State L) { private static int db_debug (lua_State L) {
for (;;) { for (;;) {
CharPtr buffer = new char[250]; CharPtr buffer = new char[250];
fputs("lua_debug> ", stderr); fputs("lua_debug> ", stderr);
if (fgets(buffer, stdin) == null || if (fgets(buffer, stdin) == null ||
strcmp(buffer, "cont\n") == 0) strcmp(buffer, "cont\n") == 0)
return 0; return 0;
if (luaL_loadbuffer(L, buffer, (uint)strlen(buffer), "=(debug command)")!=0 || if (luaL_loadbuffer(L, buffer, (uint)strlen(buffer), "=(debug command)")!=0 ||
lua_pcall(L, 0, 0, 0)!=0) { lua_pcall(L, 0, 0, 0)!=0) {
fputs(lua_tostring(L, -1), stderr); fputs(lua_tostring(L, -1), stderr);
fputs("\n", stderr); fputs("\n", stderr);
} }
lua_settop(L, 0); /* remove eventual returns */ lua_settop(L, 0); /* remove eventual returns */
} }
} }
public const int LEVELS1 = 12; /* size of the first part of the stack */ public const int LEVELS1 = 12; /* size of the first part of the stack */
public const int LEVELS2 = 10; /* size of the second part of the stack */ public const int LEVELS2 = 10; /* size of the second part of the stack */
private static int db_errorfb (lua_State L) { private static int db_errorfb (lua_State L) {
int level; int level;
bool firstpart = true; /* still before eventual `...' */ bool firstpart = true; /* still before eventual `...' */
int arg; int arg;
lua_State L1 = getthread(L, out arg); lua_State L1 = getthread(L, out arg);
lua_Debug ar = new lua_Debug(); lua_Debug ar = new lua_Debug();
if (lua_isnumber(L, arg+2) != 0) { if (lua_isnumber(L, arg+2) != 0) {
level = (int)lua_tointeger(L, arg+2); level = (int)lua_tointeger(L, arg+2);
lua_pop(L, 1); lua_pop(L, 1);
} }
else else
level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
if (lua_gettop(L) == arg) if (lua_gettop(L) == arg)
lua_pushliteral(L, ""); lua_pushliteral(L, "");
else if (lua_isstring(L, arg+1)==0) return 1; /* message is not a string */ else if (lua_isstring(L, arg+1)==0) return 1; /* message is not a string */
else lua_pushliteral(L, "\n"); else lua_pushliteral(L, "\n");
lua_pushliteral(L, "stack traceback:"); lua_pushliteral(L, "stack traceback:");
while (lua_getstack(L1, level++, ar) != 0) { while (lua_getstack(L1, level++, ar) != 0) {
if (level > LEVELS1 && firstpart) { if (level > LEVELS1 && firstpart) {
/* no more than `LEVELS2' more levels? */ /* no more than `LEVELS2' more levels? */
if (lua_getstack(L1, level+LEVELS2, ar)==0) if (lua_getstack(L1, level+LEVELS2, ar)==0)
level--; /* keep going */ level--; /* keep going */
else { else {
lua_pushliteral(L, "\n\t..."); /* too many levels */ lua_pushliteral(L, "\n\t..."); /* too many levels */
while (lua_getstack(L1, level+LEVELS2, ar) != 0) /* find last levels */ while (lua_getstack(L1, level+LEVELS2, ar) != 0) /* find last levels */
level++; level++;
} }
firstpart = false; firstpart = false;
continue; continue;
} }
lua_pushliteral(L, "\n\t"); lua_pushliteral(L, "\n\t");
lua_getinfo(L1, "Snl", ar); lua_getinfo(L1, "Snl", ar);
lua_pushfstring(L, "%s:", ar.short_src); lua_pushfstring(L, "%s:", ar.short_src);
if (ar.currentline > 0) if (ar.currentline > 0)
lua_pushfstring(L, "%d:", ar.currentline); lua_pushfstring(L, "%d:", ar.currentline);
if (ar.namewhat != '\0') /* is there a name? */ if (ar.namewhat != '\0') /* is there a name? */
lua_pushfstring(L, " in function " + LUA_QS, ar.name); lua_pushfstring(L, " in function " + LUA_QS, ar.name);
else { else {
if (ar.what == 'm') /* main? */ if (ar.what == 'm') /* main? */
lua_pushfstring(L, " in main chunk"); lua_pushfstring(L, " in main chunk");
else if (ar.what == 'C' || ar.what == 't') else if (ar.what == 'C' || ar.what == 't')
lua_pushliteral(L, " ?"); /* C function or tail call */ lua_pushliteral(L, " ?"); /* C function or tail call */
else else
lua_pushfstring(L, " in function <%s:%d>", lua_pushfstring(L, " in function <%s:%d>",
ar.short_src, ar.linedefined); ar.short_src, ar.linedefined);
} }
lua_concat(L, lua_gettop(L) - arg); lua_concat(L, lua_gettop(L) - arg);
} }
lua_concat(L, lua_gettop(L) - arg); lua_concat(L, lua_gettop(L) - arg);
return 1; return 1;
} }
private readonly static luaL_Reg[] dblib = { private readonly static luaL_Reg[] dblib = {
new luaL_Reg("debug", db_debug), new luaL_Reg("debug", db_debug),
new luaL_Reg("getfenv", db_getfenv), new luaL_Reg("getfenv", db_getfenv),
new luaL_Reg("gethook", db_gethook), new luaL_Reg("gethook", db_gethook),
new luaL_Reg("getinfo", db_getinfo), new luaL_Reg("getinfo", db_getinfo),
new luaL_Reg("getlocal", db_getlocal), new luaL_Reg("getlocal", db_getlocal),
new luaL_Reg("getregistry", db_getregistry), new luaL_Reg("getregistry", db_getregistry),
new luaL_Reg("getmetatable", db_getmetatable), new luaL_Reg("getmetatable", db_getmetatable),
new luaL_Reg("getupvalue", db_getupvalue), new luaL_Reg("getupvalue", db_getupvalue),
new luaL_Reg("setfenv", db_setfenv), new luaL_Reg("setfenv", db_setfenv),
new luaL_Reg("sethook", db_sethook), new luaL_Reg("sethook", db_sethook),
new luaL_Reg("setlocal", db_setlocal), new luaL_Reg("setlocal", db_setlocal),
new luaL_Reg("setmetatable", db_setmetatable), new luaL_Reg("setmetatable", db_setmetatable),
new luaL_Reg("setupvalue", db_setupvalue), new luaL_Reg("setupvalue", db_setupvalue),
new luaL_Reg("traceback", db_errorfb), new luaL_Reg("traceback", db_errorfb),
new luaL_Reg(null, null) new luaL_Reg(null, null)
}; };
public static int luaopen_debug (lua_State L) { public static int luaopen_debug (lua_State L) {
luaL_register(L, LUA_DBLIBNAME, dblib); luaL_register(L, LUA_DBLIBNAME, dblib);
return 1; return 1;
} }
} }
} }
/* /*
** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $ ** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $
** Debug Interface ** Debug Interface
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Diagnostics; using System.Diagnostics;
namespace KopiLua namespace KopiLua
{ {
using TValue = Lua.lua_TValue; using TValue = Lua.lua_TValue;
using StkId = Lua.lua_TValue; using StkId = Lua.lua_TValue;
using Instruction = System.UInt32; using Instruction = System.UInt32;
public partial class Lua public partial class Lua
{ {
public static int pcRel(InstructionPtr pc, Proto p) public static int pcRel(InstructionPtr pc, Proto p)
{ {
Debug.Assert(pc.codes == p.code); Debug.Assert(pc.codes == p.code);
return pc.pc - 1; return pc.pc - 1;
} }
public static int getline(Proto f, int pc) { return (f.lineinfo != null) ? f.lineinfo[pc] : 0; } public static int getline(Proto f, int pc) { return (f.lineinfo != null) ? f.lineinfo[pc] : 0; }
public static void resethookcount(lua_State L) { L.hookcount = L.basehookcount; } public static void resethookcount(lua_State L) { L.hookcount = L.basehookcount; }
private static int currentpc (lua_State L, CallInfo ci) { private static int currentpc (lua_State L, CallInfo ci) {
if (!isLua(ci)) return -1; /* function is not a Lua function? */ if (!isLua(ci)) return -1; /* function is not a Lua function? */
if (ci == L.ci) if (ci == L.ci)
ci.savedpc = InstructionPtr.Assign(L.savedpc); ci.savedpc = InstructionPtr.Assign(L.savedpc);
return pcRel(ci.savedpc, ci_func(ci).l.p); return pcRel(ci.savedpc, ci_func(ci).l.p);
} }
private static int currentline (lua_State L, CallInfo ci) { private static int currentline (lua_State L, CallInfo ci) {
int pc = currentpc(L, ci); int pc = currentpc(L, ci);
if (pc < 0) if (pc < 0)
return -1; /* only active lua functions have current-line information */ return -1; /* only active lua functions have current-line information */
else else
return getline(ci_func(ci).l.p, pc); return getline(ci_func(ci).l.p, pc);
} }
/* /*
** this function can be called asynchronous (e.g. during a signal) ** this function can be called asynchronous (e.g. during a signal)
*/ */
public static int lua_sethook (lua_State L, lua_Hook func, int mask, int count) { public static int lua_sethook (lua_State L, lua_Hook func, int mask, int count) {
if (func == null || mask == 0) { /* turn off hooks? */ if (func == null || mask == 0) { /* turn off hooks? */
mask = 0; mask = 0;
func = null; func = null;
} }
L.hook = func; L.hook = func;
L.basehookcount = count; L.basehookcount = count;
resethookcount(L); resethookcount(L);
L.hookmask = cast_byte(mask); L.hookmask = cast_byte(mask);
return 1; return 1;
} }
public static lua_Hook lua_gethook (lua_State L) { public static lua_Hook lua_gethook (lua_State L) {
return L.hook; return L.hook;
} }
public static int lua_gethookmask (lua_State L) { public static int lua_gethookmask (lua_State L) {
return L.hookmask; return L.hookmask;
} }
public static int lua_gethookcount (lua_State L) { public static int lua_gethookcount (lua_State L) {
return L.basehookcount; return L.basehookcount;
} }
public static int lua_getstack (lua_State L, int level, lua_Debug ar) { public static int lua_getstack (lua_State L, int level, lua_Debug ar) {
int status; int status;
CallInfo ci; CallInfo ci;
lua_lock(L); lua_lock(L);
for (ci = L.ci; level > 0 && ci > L.base_ci[0]; CallInfo.dec(ref ci)) { for (ci = L.ci; level > 0 && ci > L.base_ci[0]; CallInfo.dec(ref ci)) {
level--; level--;
if (f_isLua(ci)) /* Lua function? */ if (f_isLua(ci)) /* Lua function? */
level -= ci.tailcalls; /* skip lost tail calls */ level -= ci.tailcalls; /* skip lost tail calls */
} }
if (level == 0 && ci > L.base_ci[0]) { /* level found? */ if (level == 0 && ci > L.base_ci[0]) { /* level found? */
status = 1; status = 1;
ar.i_ci = ci - L.base_ci[0]; ar.i_ci = ci - L.base_ci[0];
} }
else if (level < 0) { /* level is of a lost tail call? */ else if (level < 0) { /* level is of a lost tail call? */
status = 1; status = 1;
ar.i_ci = 0; ar.i_ci = 0;
} }
else status = 0; /* no such level */ else status = 0; /* no such level */
lua_unlock(L); lua_unlock(L);
return status; return status;
} }
private static Proto getluaproto (CallInfo ci) { private static Proto getluaproto (CallInfo ci) {
return (isLua(ci) ? ci_func(ci).l.p : null); return (isLua(ci) ? ci_func(ci).l.p : null);
} }
private static CharPtr findlocal (lua_State L, CallInfo ci, int n) { private static CharPtr findlocal (lua_State L, CallInfo ci, int n) {
CharPtr name; CharPtr name;
Proto fp = getluaproto(ci); Proto fp = getluaproto(ci);
if ((fp!=null) && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != null) if ((fp!=null) && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != null)
return name; /* is a local variable in a Lua function */ return name; /* is a local variable in a Lua function */
else { else {
StkId limit = (ci == L.ci) ? L.top : (ci+1).func; StkId limit = (ci == L.ci) ? L.top : (ci+1).func;
if (limit - ci.base_ >= n && n > 0) /* is 'n' inside 'ci' stack? */ if (limit - ci.base_ >= n && n > 0) /* is 'n' inside 'ci' stack? */
return "(*temporary)"; return "(*temporary)";
else else
return null; return null;
} }
} }
public static CharPtr lua_getlocal (lua_State L, lua_Debug ar, int n) { public static CharPtr lua_getlocal (lua_State L, lua_Debug ar, int n) {
CallInfo ci = L.base_ci[ar.i_ci]; CallInfo ci = L.base_ci[ar.i_ci];
CharPtr name = findlocal(L, ci, n); CharPtr name = findlocal(L, ci, n);
lua_lock(L); lua_lock(L);
if (name != null) if (name != null)
luaA_pushobject(L, ci.base_[n - 1]); luaA_pushobject(L, ci.base_[n - 1]);
lua_unlock(L); lua_unlock(L);
return name; return name;
} }
public static CharPtr lua_setlocal (lua_State L, lua_Debug ar, int n) { public static CharPtr lua_setlocal (lua_State L, lua_Debug ar, int n) {
CallInfo ci = L.base_ci[ar.i_ci]; CallInfo ci = L.base_ci[ar.i_ci];
CharPtr name = findlocal(L, ci, n); CharPtr name = findlocal(L, ci, n);
lua_lock(L); lua_lock(L);
if (name != null) if (name != null)
setobjs2s(L, ci.base_[n - 1], L.top-1); setobjs2s(L, ci.base_[n - 1], L.top-1);
StkId.dec(ref L.top); /* pop value */ StkId.dec(ref L.top); /* pop value */
lua_unlock(L); lua_unlock(L);
return name; return name;
} }
private static void funcinfo (lua_Debug ar, Closure cl) { private static void funcinfo (lua_Debug ar, Closure cl) {
if (cl.c.isC != 0) { if (cl.c.isC != 0) {
ar.source = "=[C]"; ar.source = "=[C]";
ar.linedefined = -1; ar.linedefined = -1;
ar.lastlinedefined = -1; ar.lastlinedefined = -1;
ar.what = "C"; ar.what = "C";
} }
else { else {
ar.source = getstr(cl.l.p.source); ar.source = getstr(cl.l.p.source);
ar.linedefined = cl.l.p.linedefined; ar.linedefined = cl.l.p.linedefined;
ar.lastlinedefined = cl.l.p.lastlinedefined; ar.lastlinedefined = cl.l.p.lastlinedefined;
ar.what = (ar.linedefined == 0) ? "main" : "Lua"; ar.what = (ar.linedefined == 0) ? "main" : "Lua";
} }
luaO_chunkid(ar.short_src, ar.source, LUA_IDSIZE); luaO_chunkid(ar.short_src, ar.source, LUA_IDSIZE);
} }
private static void info_tailcall (lua_Debug ar) { private static void info_tailcall (lua_Debug ar) {
ar.name = ar.namewhat = ""; ar.name = ar.namewhat = "";
ar.what = "tail"; ar.what = "tail";
ar.lastlinedefined = ar.linedefined = ar.currentline = -1; ar.lastlinedefined = ar.linedefined = ar.currentline = -1;
ar.source = "=(tail call)"; ar.source = "=(tail call)";
luaO_chunkid(ar.short_src, ar.source, LUA_IDSIZE); luaO_chunkid(ar.short_src, ar.source, LUA_IDSIZE);
ar.nups = 0; ar.nups = 0;
} }
private static void collectvalidlines (lua_State L, Closure f) { private static void collectvalidlines (lua_State L, Closure f) {
if (f == null || (f.c.isC!=0)) { if (f == null || (f.c.isC!=0)) {
setnilvalue(L.top); setnilvalue(L.top);
} }
else { else {
Table t = luaH_new(L, 0, 0); Table t = luaH_new(L, 0, 0);
int[] lineinfo = f.l.p.lineinfo; int[] lineinfo = f.l.p.lineinfo;
int i; int i;
for (i=0; i<f.l.p.sizelineinfo; i++) for (i=0; i<f.l.p.sizelineinfo; i++)
setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
sethvalue(L, L.top, t); sethvalue(L, L.top, t);
} }
incr_top(L); incr_top(L);
} }
private static int auxgetinfo (lua_State L, CharPtr what, lua_Debug ar, private static int auxgetinfo (lua_State L, CharPtr what, lua_Debug ar,
Closure f, CallInfo ci) { Closure f, CallInfo ci) {
int status = 1; int status = 1;
if (f == null) { if (f == null) {
info_tailcall(ar); info_tailcall(ar);
return status; return status;
} }
for (; what[0] != 0; what = what.next()) { for (; what[0] != 0; what = what.next()) {
switch (what[0]) { switch (what[0]) {
case 'S': { case 'S': {
funcinfo(ar, f); funcinfo(ar, f);
break; break;
} }
case 'l': { case 'l': {
ar.currentline = (ci != null) ? currentline(L, ci) : -1; ar.currentline = (ci != null) ? currentline(L, ci) : -1;
break; break;
} }
case 'u': { case 'u': {
ar.nups = f.c.nupvalues; ar.nups = f.c.nupvalues;
break; break;
} }
case 'n': { case 'n': {
ar.namewhat = (ci!=null) ? getfuncname(L, ci, ref ar.name) : null; ar.namewhat = (ci!=null) ? getfuncname(L, ci, ref ar.name) : null;
if (ar.namewhat == null) { if (ar.namewhat == null) {
ar.namewhat = ""; /* not found */ ar.namewhat = ""; /* not found */
ar.name = null; ar.name = null;
} }
break; break;
} }
case 'L': case 'L':
case 'f': /* handled by lua_getinfo */ case 'f': /* handled by lua_getinfo */
break; break;
default: status = 0; break;/* invalid option */ default: status = 0; break;/* invalid option */
} }
} }
return status; return status;
} }
public static int lua_getinfo (lua_State L, CharPtr what, lua_Debug ar) { public static int lua_getinfo (lua_State L, CharPtr what, lua_Debug ar) {
int status; int status;
Closure f = null; Closure f = null;
CallInfo ci = null; CallInfo ci = null;
lua_lock(L); lua_lock(L);
if (what == '>') { if (what == '>') {
StkId func = L.top - 1; StkId func = L.top - 1;
luai_apicheck(L, ttisfunction(func)); luai_apicheck(L, ttisfunction(func));
what = what.next(); /* skip the '>' */ what = what.next(); /* skip the '>' */
f = clvalue(func); f = clvalue(func);
StkId.dec(ref L.top); /* pop function */ StkId.dec(ref L.top); /* pop function */
} }
else if (ar.i_ci != 0) { /* no tail call? */ else if (ar.i_ci != 0) { /* no tail call? */
ci = L.base_ci[ar.i_ci]; ci = L.base_ci[ar.i_ci];
lua_assert(ttisfunction(ci.func)); lua_assert(ttisfunction(ci.func));
f = clvalue(ci.func); f = clvalue(ci.func);
} }
status = auxgetinfo(L, what, ar, f, ci); status = auxgetinfo(L, what, ar, f, ci);
if (strchr(what, 'f') != null) { if (strchr(what, 'f') != null) {
if (f == null) setnilvalue(L.top); if (f == null) setnilvalue(L.top);
else setclvalue(L, L.top, f); else setclvalue(L, L.top, f);
incr_top(L); incr_top(L);
} }
if (strchr(what, 'L') != null) if (strchr(what, 'L') != null)
collectvalidlines(L, f); collectvalidlines(L, f);
lua_unlock(L); lua_unlock(L);
return status; return status;
} }
/* /*
** {====================================================== ** {======================================================
** Symbolic Execution and code checker ** Symbolic Execution and code checker
** ======================================================= ** =======================================================
*/ */
private static int checkjump(Proto pt, int pc) { if (!(0 <= pc && pc < pt.sizecode)) return 0; return 1; } private static int checkjump(Proto pt, int pc) { if (!(0 <= pc && pc < pt.sizecode)) return 0; return 1; }
private static int checkreg(Proto pt, int reg) { if (!((reg) < (pt).maxstacksize)) return 0; return 1; } private static int checkreg(Proto pt, int reg) { if (!((reg) < (pt).maxstacksize)) return 0; return 1; }
private static int precheck (Proto pt) { private static int precheck (Proto pt) {
if (!(pt.maxstacksize <= MAXSTACK)) return 0; if (!(pt.maxstacksize <= MAXSTACK)) return 0;
if (!(pt.numparams+(pt.is_vararg & VARARG_HASARG) <= pt.maxstacksize)) return 0; if (!(pt.numparams+(pt.is_vararg & VARARG_HASARG) <= pt.maxstacksize)) return 0;
if (!(((pt.is_vararg & VARARG_NEEDSARG)==0) || if (!(((pt.is_vararg & VARARG_NEEDSARG)==0) ||
((pt.is_vararg & VARARG_HASARG)!=0))) return 0; ((pt.is_vararg & VARARG_HASARG)!=0))) return 0;
if (!(pt.sizeupvalues <= pt.nups)) return 0; if (!(pt.sizeupvalues <= pt.nups)) return 0;
if (!(pt.sizelineinfo == pt.sizecode || pt.sizelineinfo == 0)) return 0; if (!(pt.sizelineinfo == pt.sizecode || pt.sizelineinfo == 0)) return 0;
if (!(pt.sizecode > 0 && GET_OPCODE(pt.code[pt.sizecode - 1]) == OpCode.OP_RETURN)) return 0; if (!(pt.sizecode > 0 && GET_OPCODE(pt.code[pt.sizecode - 1]) == OpCode.OP_RETURN)) return 0;
return 1; return 1;
} }
public static int checkopenop(Proto pt, int pc) { return luaG_checkopenop(pt.code[pc + 1]); } public static int checkopenop(Proto pt, int pc) { return luaG_checkopenop(pt.code[pc + 1]); }
[CLSCompliantAttribute(false)] [CLSCompliantAttribute(false)]
public static int luaG_checkopenop (Instruction i) { public static int luaG_checkopenop (Instruction i) {
switch (GET_OPCODE(i)) { switch (GET_OPCODE(i)) {
case OpCode.OP_CALL: case OpCode.OP_CALL:
case OpCode.OP_TAILCALL: case OpCode.OP_TAILCALL:
case OpCode.OP_RETURN: case OpCode.OP_RETURN:
case OpCode.OP_SETLIST: { case OpCode.OP_SETLIST: {
if (!(GETARG_B(i) == 0)) return 0; if (!(GETARG_B(i) == 0)) return 0;
return 1; return 1;
} }
default: return 0; /* invalid instruction after an open call */ default: return 0; /* invalid instruction after an open call */
} }
} }
private static int checkArgMode (Proto pt, int r, OpArgMask mode) { private static int checkArgMode (Proto pt, int r, OpArgMask mode) {
switch (mode) { switch (mode) {
case OpArgMask.OpArgN: if (r!=0) return 0; break; case OpArgMask.OpArgN: if (r!=0) return 0; break;
case OpArgMask.OpArgU: break; case OpArgMask.OpArgU: break;
case OpArgMask.OpArgR: checkreg(pt, r); break; case OpArgMask.OpArgR: checkreg(pt, r); break;
case OpArgMask.OpArgK: case OpArgMask.OpArgK:
if (!( (ISK(r) != 0) ? INDEXK(r) < pt.sizek : r < pt.maxstacksize)) return 0; if (!( (ISK(r) != 0) ? INDEXK(r) < pt.sizek : r < pt.maxstacksize)) return 0;
break; break;
} }
return 1; return 1;
} }
private static Instruction symbexec (Proto pt, int lastpc, int reg) { private static Instruction symbexec (Proto pt, int lastpc, int reg) {
int pc; int pc;
int last; /* stores position of last instruction that changed `reg' */ int last; /* stores position of last instruction that changed `reg' */
int dest; int dest;
last = pt.sizecode-1; /* points to final return (a `neutral' instruction) */ last = pt.sizecode-1; /* points to final return (a `neutral' instruction) */
if (precheck(pt)==0) return 0; if (precheck(pt)==0) return 0;
for (pc = 0; pc < lastpc; pc++) { for (pc = 0; pc < lastpc; pc++) {
Instruction i = pt.code[pc]; Instruction i = pt.code[pc];
OpCode op = GET_OPCODE(i); OpCode op = GET_OPCODE(i);
int a = GETARG_A(i); int a = GETARG_A(i);
int b = 0; int b = 0;
int c = 0; int c = 0;
if (!((int)op < NUM_OPCODES)) return 0; if (!((int)op < NUM_OPCODES)) return 0;
checkreg(pt, a); checkreg(pt, a);
switch (getOpMode(op)) { switch (getOpMode(op)) {
case OpMode.iABC: { case OpMode.iABC: {
b = GETARG_B(i); b = GETARG_B(i);
c = GETARG_C(i); c = GETARG_C(i);
if (checkArgMode(pt, b, getBMode(op))==0) return 0; if (checkArgMode(pt, b, getBMode(op))==0) return 0;
if (checkArgMode(pt, c, getCMode(op))==0) return 0; if (checkArgMode(pt, c, getCMode(op))==0) return 0;
break; break;
} }
case OpMode.iABx: { case OpMode.iABx: {
b = GETARG_Bx(i); b = GETARG_Bx(i);
if (getBMode(op) == OpArgMask.OpArgK) if (!(b < pt.sizek)) return 0; if (getBMode(op) == OpArgMask.OpArgK) if (!(b < pt.sizek)) return 0;
break; break;
} }
case OpMode.iAsBx: { case OpMode.iAsBx: {
b = GETARG_sBx(i); b = GETARG_sBx(i);
if (getBMode(op) == OpArgMask.OpArgR) { if (getBMode(op) == OpArgMask.OpArgR) {
dest = pc+1+b; dest = pc+1+b;
if (!((0 <= dest && dest < pt.sizecode))) return 0; if (!((0 <= dest && dest < pt.sizecode))) return 0;
if (dest > 0) { if (dest > 0) {
int j; int j;
/* check that it does not jump to a setlist count; this /* check that it does not jump to a setlist count; this
is tricky, because the count from a previous setlist may is tricky, because the count from a previous setlist may
have the same value of an invalid setlist; so, we must have the same value of an invalid setlist; so, we must
go all the way back to the first of them (if any) */ go all the way back to the first of them (if any) */
for (j = 0; j < dest; j++) { for (j = 0; j < dest; j++) {
Instruction d = pt.code[dest-1-j]; Instruction d = pt.code[dest-1-j];
if (!(GET_OPCODE(d) == OpCode.OP_SETLIST && GETARG_C(d) == 0)) break; if (!(GET_OPCODE(d) == OpCode.OP_SETLIST && GETARG_C(d) == 0)) break;
} }
/* if 'j' is even, previous value is not a setlist (even if /* if 'j' is even, previous value is not a setlist (even if
it looks like one) */ it looks like one) */
if ((j&1)!=0) return 0; if ((j&1)!=0) return 0;
} }
} }
break; break;
} }
} }
if (testAMode(op) != 0) { if (testAMode(op) != 0) {
if (a == reg) last = pc; /* change register `a' */ if (a == reg) last = pc; /* change register `a' */
} }
if (testTMode(op) != 0) { if (testTMode(op) != 0) {
if (!(pc+2 < pt.sizecode)) return 0; /* check skip */ if (!(pc+2 < pt.sizecode)) return 0; /* check skip */
if (!(GET_OPCODE(pt.code[pc + 1]) == OpCode.OP_JMP)) return 0; if (!(GET_OPCODE(pt.code[pc + 1]) == OpCode.OP_JMP)) return 0;
} }
switch (op) { switch (op) {
case OpCode.OP_LOADBOOL: { case OpCode.OP_LOADBOOL: {
if (c == 1) { /* does it jump? */ if (c == 1) { /* does it jump? */
if (!(pc+2 < pt.sizecode)) return 0; /* check its jump */ if (!(pc+2 < pt.sizecode)) return 0; /* check its jump */
if (!(GET_OPCODE(pt.code[pc + 1]) != OpCode.OP_SETLIST || if (!(GET_OPCODE(pt.code[pc + 1]) != OpCode.OP_SETLIST ||
GETARG_C(pt.code[pc + 1]) != 0)) return 0; GETARG_C(pt.code[pc + 1]) != 0)) return 0;
} }
break; break;
} }
case OpCode.OP_LOADNIL: { case OpCode.OP_LOADNIL: {
if (a <= reg && reg <= b) if (a <= reg && reg <= b)
last = pc; /* set registers from `a' to `b' */ last = pc; /* set registers from `a' to `b' */
break; break;
} }
case OpCode.OP_GETUPVAL: case OpCode.OP_GETUPVAL:
case OpCode.OP_SETUPVAL: { case OpCode.OP_SETUPVAL: {
if (!(b < pt.nups)) return 0; if (!(b < pt.nups)) return 0;
break; break;
} }
case OpCode.OP_GETGLOBAL: case OpCode.OP_GETGLOBAL:
case OpCode.OP_SETGLOBAL: { case OpCode.OP_SETGLOBAL: {
if (!(ttisstring(pt.k[b]))) return 0; if (!(ttisstring(pt.k[b]))) return 0;
break; break;
} }
case OpCode.OP_SELF: { case OpCode.OP_SELF: {
checkreg(pt, a+1); checkreg(pt, a+1);
if (reg == a+1) last = pc; if (reg == a+1) last = pc;
break; break;
} }
case OpCode.OP_CONCAT: { case OpCode.OP_CONCAT: {
if (!(b < c)) return 0; /* at least two operands */ if (!(b < c)) return 0; /* at least two operands */
break; break;
} }
case OpCode.OP_TFORLOOP: { case OpCode.OP_TFORLOOP: {
if (!(c >= 1)) return 0; /* at least one result (control variable) */ if (!(c >= 1)) return 0; /* at least one result (control variable) */
checkreg(pt, a+2+c); /* space for results */ checkreg(pt, a+2+c); /* space for results */
if (reg >= a+2) last = pc; /* affect all regs above its base */ if (reg >= a+2) last = pc; /* affect all regs above its base */
break; break;
} }
case OpCode.OP_FORLOOP: case OpCode.OP_FORLOOP:
case OpCode.OP_FORPREP: case OpCode.OP_FORPREP:
checkreg(pt, a+3); checkreg(pt, a+3);
/* go through ...no, on second thoughts don't, because this is C# */ /* go through ...no, on second thoughts don't, because this is C# */
dest = pc + 1 + b; dest = pc + 1 + b;
/* not full check and jump is forward and do not skip `lastpc'? */ /* not full check and jump is forward and do not skip `lastpc'? */
if (reg != NO_REG && pc < dest && dest <= lastpc) if (reg != NO_REG && pc < dest && dest <= lastpc)
pc += b; /* do the jump */ pc += b; /* do the jump */
break; break;
case OpCode.OP_JMP: { case OpCode.OP_JMP: {
dest = pc+1+b; dest = pc+1+b;
/* not full check and jump is forward and do not skip `lastpc'? */ /* not full check and jump is forward and do not skip `lastpc'? */
if (reg != NO_REG && pc < dest && dest <= lastpc) if (reg != NO_REG && pc < dest && dest <= lastpc)
pc += b; /* do the jump */ pc += b; /* do the jump */
break; break;
} }
case OpCode.OP_CALL: case OpCode.OP_CALL:
case OpCode.OP_TAILCALL: { case OpCode.OP_TAILCALL: {
if (b != 0) { if (b != 0) {
checkreg(pt, a+b-1); checkreg(pt, a+b-1);
} }
c--; /* c = num. returns */ c--; /* c = num. returns */
if (c == LUA_MULTRET) { if (c == LUA_MULTRET) {
if (checkopenop(pt, pc)==0) return 0; if (checkopenop(pt, pc)==0) return 0;
} }
else if (c != 0) else if (c != 0)
checkreg(pt, a+c-1); checkreg(pt, a+c-1);
if (reg >= a) last = pc; /* affect all registers above base */ if (reg >= a) last = pc; /* affect all registers above base */
break; break;
} }
case OpCode.OP_RETURN: { case OpCode.OP_RETURN: {
b--; /* b = num. returns */ b--; /* b = num. returns */
if (b > 0) checkreg(pt, a+b-1); if (b > 0) checkreg(pt, a+b-1);
break; break;
} }
case OpCode.OP_SETLIST: { case OpCode.OP_SETLIST: {
if (b > 0) checkreg(pt, a + b); if (b > 0) checkreg(pt, a + b);
if (c == 0) { if (c == 0) {
pc++; pc++;
if (!(pc < pt.sizecode - 1)) return 0; if (!(pc < pt.sizecode - 1)) return 0;
} }
break; break;
} }
case OpCode.OP_CLOSURE: { case OpCode.OP_CLOSURE: {
int nup, j; int nup, j;
if (!(b < pt.sizep)) return 0; if (!(b < pt.sizep)) return 0;
nup = pt.p[b].nups; nup = pt.p[b].nups;
if (!(pc + nup < pt.sizecode)) return 0; if (!(pc + nup < pt.sizecode)) return 0;
for (j = 1; j <= nup; j++) { for (j = 1; j <= nup; j++) {
OpCode op1 = GET_OPCODE(pt.code[pc + j]); OpCode op1 = GET_OPCODE(pt.code[pc + j]);
if (!(op1 == OpCode.OP_GETUPVAL || op1 == OpCode.OP_MOVE)) return 0; if (!(op1 == OpCode.OP_GETUPVAL || op1 == OpCode.OP_MOVE)) return 0;
} }
if (reg != NO_REG) /* tracing? */ if (reg != NO_REG) /* tracing? */
pc += nup; /* do not 'execute' these pseudo-instructions */ pc += nup; /* do not 'execute' these pseudo-instructions */
break; break;
} }
case OpCode.OP_VARARG: { case OpCode.OP_VARARG: {
if (!( (pt.is_vararg & VARARG_ISVARARG)!=0 && if (!( (pt.is_vararg & VARARG_ISVARARG)!=0 &&
(pt.is_vararg & VARARG_NEEDSARG)==0 )) return 0; (pt.is_vararg & VARARG_NEEDSARG)==0 )) return 0;
b--; b--;
if (b == LUA_MULTRET) if (checkopenop(pt, pc)==0) return 0; if (b == LUA_MULTRET) if (checkopenop(pt, pc)==0) return 0;
checkreg(pt, a+b-1); checkreg(pt, a+b-1);
break; break;
} }
default: default:
break; break;
} }
} }
return pt.code[last]; return pt.code[last];
} }
//#undef check //#undef check
//#undef checkjump //#undef checkjump
//#undef checkreg //#undef checkreg
/* }====================================================== */ /* }====================================================== */
public static int luaG_checkcode (Proto pt) { public static int luaG_checkcode (Proto pt) {
return (symbexec(pt, pt.sizecode, NO_REG) != 0) ? 1 : 0; return (symbexec(pt, pt.sizecode, NO_REG) != 0) ? 1 : 0;
} }
private static CharPtr kname (Proto p, int c) { private static CharPtr kname (Proto p, int c) {
if (ISK(c)!=0 && ttisstring(p.k[INDEXK(c)])) if (ISK(c)!=0 && ttisstring(p.k[INDEXK(c)]))
return svalue(p.k[INDEXK(c)]); return svalue(p.k[INDEXK(c)]);
else else
return "?"; return "?";
} }
private static CharPtr getobjname (lua_State L, CallInfo ci, int stackpos, private static CharPtr getobjname (lua_State L, CallInfo ci, int stackpos,
ref CharPtr name) { ref CharPtr name) {
if (isLua(ci)) { /* a Lua function? */ if (isLua(ci)) { /* a Lua function? */
Proto p = ci_func(ci).l.p; Proto p = ci_func(ci).l.p;
int pc = currentpc(L, ci); int pc = currentpc(L, ci);
Instruction i; Instruction i;
name = luaF_getlocalname(p, stackpos+1, pc); name = luaF_getlocalname(p, stackpos+1, pc);
if (name!=null) /* is a local? */ if (name!=null) /* is a local? */
return "local"; return "local";
i = symbexec(p, pc, stackpos); /* try symbolic execution */ i = symbexec(p, pc, stackpos); /* try symbolic execution */
lua_assert(pc != -1); lua_assert(pc != -1);
switch (GET_OPCODE(i)) { switch (GET_OPCODE(i)) {
case OpCode.OP_GETGLOBAL: { case OpCode.OP_GETGLOBAL: {
int g = GETARG_Bx(i); /* global index */ int g = GETARG_Bx(i); /* global index */
lua_assert(ttisstring(p.k[g])); lua_assert(ttisstring(p.k[g]));
name = svalue(p.k[g]); name = svalue(p.k[g]);
return "global"; return "global";
} }
case OpCode.OP_MOVE: { case OpCode.OP_MOVE: {
int a = GETARG_A(i); int a = GETARG_A(i);
int b = GETARG_B(i); /* move from `b' to `a' */ int b = GETARG_B(i); /* move from `b' to `a' */
if (b < a) if (b < a)
return getobjname(L, ci, b, ref name); /* get name for `b' */ return getobjname(L, ci, b, ref name); /* get name for `b' */
break; break;
} }
case OpCode.OP_GETTABLE: { case OpCode.OP_GETTABLE: {
int k = GETARG_C(i); /* key index */ int k = GETARG_C(i); /* key index */
name = kname(p, k); name = kname(p, k);
return "field"; return "field";
} }
case OpCode.OP_GETUPVAL: { case OpCode.OP_GETUPVAL: {
int u = GETARG_B(i); /* upvalue index */ int u = GETARG_B(i); /* upvalue index */
name = (p.upvalues!=null) ? getstr(p.upvalues[u]) : "?"; name = (p.upvalues!=null) ? getstr(p.upvalues[u]) : "?";
return "upvalue"; return "upvalue";
} }
case OpCode.OP_SELF: { case OpCode.OP_SELF: {
int k = GETARG_C(i); /* key index */ int k = GETARG_C(i); /* key index */
name = kname(p, k); name = kname(p, k);
return "method"; return "method";
} }
default: break; default: break;
} }
} }
return null; /* no useful name found */ return null; /* no useful name found */
} }
private static CharPtr getfuncname (lua_State L, CallInfo ci, ref CharPtr name) { private static CharPtr getfuncname (lua_State L, CallInfo ci, ref CharPtr name) {
Instruction i; Instruction i;
if ((isLua(ci) && ci.tailcalls > 0) || !isLua(ci - 1)) if ((isLua(ci) && ci.tailcalls > 0) || !isLua(ci - 1))
return null; /* calling function is not Lua (or is unknown) */ return null; /* calling function is not Lua (or is unknown) */
CallInfo.dec(ref ci); /* calling function */ CallInfo.dec(ref ci); /* calling function */
i = ci_func(ci).l.p.code[currentpc(L, ci)]; i = ci_func(ci).l.p.code[currentpc(L, ci)];
if (GET_OPCODE(i) == OpCode.OP_CALL || GET_OPCODE(i) == OpCode.OP_TAILCALL || if (GET_OPCODE(i) == OpCode.OP_CALL || GET_OPCODE(i) == OpCode.OP_TAILCALL ||
GET_OPCODE(i) == OpCode.OP_TFORLOOP) GET_OPCODE(i) == OpCode.OP_TFORLOOP)
return getobjname(L, ci, GETARG_A(i), ref name); return getobjname(L, ci, GETARG_A(i), ref name);
else else
return null; /* no useful name can be found */ return null; /* no useful name can be found */
} }
/* only ANSI way to check whether a pointer points to an array */ /* only ANSI way to check whether a pointer points to an array */
private static int isinstack (CallInfo ci, TValue o) { private static int isinstack (CallInfo ci, TValue o) {
StkId p; StkId p;
for (p = ci.base_; p < ci.top; StkId.inc(ref p)) for (p = ci.base_; p < ci.top; StkId.inc(ref p))
if (o == p) return 1; if (o == p) return 1;
return 0; return 0;
} }
public static void luaG_typeerror (lua_State L, TValue o, CharPtr op) { public static void luaG_typeerror (lua_State L, TValue o, CharPtr op) {
CharPtr name = null; CharPtr name = null;
CharPtr t = luaT_typenames[ttype(o)]; CharPtr t = luaT_typenames[ttype(o)];
CharPtr kind = (isinstack(L.ci, o)) != 0 ? CharPtr kind = (isinstack(L.ci, o)) != 0 ?
getobjname(L, L.ci, cast_int(o - L.base_), ref name) : getobjname(L, L.ci, cast_int(o - L.base_), ref name) :
null; null;
if (kind != null) if (kind != null)
luaG_runerror(L, "attempt to %s %s " + LUA_QS + " (a %s value)", luaG_runerror(L, "attempt to %s %s " + LUA_QS + " (a %s value)",
op, kind, name, t); op, kind, name, t);
else else
luaG_runerror(L, "attempt to %s a %s value", op, t); luaG_runerror(L, "attempt to %s a %s value", op, t);
} }
public static void luaG_concaterror (lua_State L, StkId p1, StkId p2) { public static void luaG_concaterror (lua_State L, StkId p1, StkId p2) {
if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
lua_assert(!ttisstring(p1) && !ttisnumber(p1)); lua_assert(!ttisstring(p1) && !ttisnumber(p1));
luaG_typeerror(L, p1, "concatenate"); luaG_typeerror(L, p1, "concatenate");
} }
public static void luaG_aritherror (lua_State L, TValue p1, TValue p2) { public static void luaG_aritherror (lua_State L, TValue p1, TValue p2) {
TValue temp = new TValue(); TValue temp = new TValue();
if (luaV_tonumber(p1, temp) == null) if (luaV_tonumber(p1, temp) == null)
p2 = p1; /* first operand is wrong */ p2 = p1; /* first operand is wrong */
luaG_typeerror(L, p2, "perform arithmetic on"); luaG_typeerror(L, p2, "perform arithmetic on");
} }
public static int luaG_ordererror (lua_State L, TValue p1, TValue p2) { public static int luaG_ordererror (lua_State L, TValue p1, TValue p2) {
CharPtr t1 = luaT_typenames[ttype(p1)]; CharPtr t1 = luaT_typenames[ttype(p1)];
CharPtr t2 = luaT_typenames[ttype(p2)]; CharPtr t2 = luaT_typenames[ttype(p2)];
if (t1[2] == t2[2]) if (t1[2] == t2[2])
luaG_runerror(L, "attempt to compare two %s values", t1); luaG_runerror(L, "attempt to compare two %s values", t1);
else else
luaG_runerror(L, "attempt to compare %s with %s", t1, t2); luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
return 0; return 0;
} }
private static void addinfo (lua_State L, CharPtr msg) { private static void addinfo (lua_State L, CharPtr msg) {
CallInfo ci = L.ci; CallInfo ci = L.ci;
if (isLua(ci)) { /* is Lua code? */ if (isLua(ci)) { /* is Lua code? */
CharPtr buff = new CharPtr(new char[LUA_IDSIZE]); /* add file:line information */ CharPtr buff = new CharPtr(new char[LUA_IDSIZE]); /* add file:line information */
int line = currentline(L, ci); int line = currentline(L, ci);
luaO_chunkid(buff, getstr(getluaproto(ci).source), LUA_IDSIZE); luaO_chunkid(buff, getstr(getluaproto(ci).source), LUA_IDSIZE);
luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
} }
} }
public static void luaG_errormsg (lua_State L) { public static void luaG_errormsg (lua_State L) {
if (L.errfunc != 0) { /* is there an error handling function? */ if (L.errfunc != 0) { /* is there an error handling function? */
StkId errfunc = restorestack(L, L.errfunc); StkId errfunc = restorestack(L, L.errfunc);
if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
setobjs2s(L, L.top, L.top - 1); /* move argument */ setobjs2s(L, L.top, L.top - 1); /* move argument */
setobjs2s(L, L.top - 1, errfunc); /* push function */ setobjs2s(L, L.top - 1, errfunc); /* push function */
incr_top(L); incr_top(L);
luaD_call(L, L.top - 2, 1); /* call it */ luaD_call(L, L.top - 2, 1); /* call it */
} }
luaD_throw(L, LUA_ERRRUN); luaD_throw(L, LUA_ERRRUN);
} }
public static void luaG_runerror(lua_State L, CharPtr fmt, params object[] argp) public static void luaG_runerror(lua_State L, CharPtr fmt, params object[] argp)
{ {
addinfo(L, luaO_pushvfstring(L, fmt, argp)); addinfo(L, luaO_pushvfstring(L, fmt, argp));
luaG_errormsg(L); luaG_errormsg(L);
} }
} }
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment