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