Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
NLua
Commits
e593fb8d
Commit
e593fb8d
authored
Feb 07, 2013
by
Vinicius Jarina
Browse files
Removed local KopiLua
parent
8d677060
Changes
43
Show whitespace changes
Inline
Side-by-side
Core/KopiLua/KopiLua.IOS.csproj
deleted
100644 → 0
View file @
8d677060
<?xml version="1.0" encoding="utf-8"?>
<Project
DefaultTargets=
"Build"
ToolsVersion=
"4.0"
xmlns=
"http://schemas.microsoft.com/developer/msbuild/2003"
>
<PropertyGroup>
<Configuration
Condition=
" '$(Configuration)' == '' "
>
Debug
</Configuration>
<Platform
Condition=
" '$(Platform)' == '' "
>
AnyCPU
</Platform>
<ProductVersion>
10.0.0
</ProductVersion>
<SchemaVersion>
2.0
</SchemaVersion>
<ProjectGuid>
{23997AB1-C4A3-49BA-A7B5-4C14F97C236B}
</ProjectGuid>
<ProjectTypeGuids>
{6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
</ProjectTypeGuids>
<OutputType>
Library
</OutputType>
<RootNamespace>
KopiLua
</RootNamespace>
<IPhoneResourcePrefix>
Resources
</IPhoneResourcePrefix>
<AssemblyName>
KopiLua
</AssemblyName>
</PropertyGroup>
<PropertyGroup
Condition=
" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "
>
<DebugSymbols>
True
</DebugSymbols>
<DebugType>
full
</DebugType>
<Optimize>
False
</Optimize>
<OutputPath>
bin\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>
<ConsolePause>
False
</ConsolePause>
</PropertyGroup>
<PropertyGroup
Condition=
" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "
>
<DebugType>
none
</DebugType>
<Optimize>
True
</Optimize>
<OutputPath>
bin\Release
</OutputPath>
<ErrorReport>
prompt
</ErrorReport>
<WarningLevel>
4
</WarningLevel>
<ConsolePause>
False
</ConsolePause>
<DefineConstants>
TRACE;LUA_CORE;_WIN32;LUA_COMPAT_VARARG;LUA_COMPAT_MOD;LUA_COMPAT_GFIND;CATCH_EXCEPTIONS
</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Reference
Include=
"System"
/>
<Reference
Include=
"System.Core"
/>
<Reference
Include=
"System.Data"
/>
</ItemGroup>
<Import
Project=
"$(MSBuildBinPath)\Microsoft.CSharp.targets"
/>
<ItemGroup>
<Folder
Include=
"printf\"
/>
<Folder
Include=
"Properties\"
/>
</ItemGroup>
<ItemGroup>
<Compile
Include=
"printf\Tools.cs"
/>
<Compile
Include=
"Properties\AssemblyInfo.cs"
/>
<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=
"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=
"luaconf.cs"
/>
<Compile
Include=
"lualib.cs"
/>
<Compile
Include=
"lundump.cs"
/>
<Compile
Include=
"lvm.cs"
/>
<Compile
Include=
"lzio.cs"
/>
<Compile
Include=
"print.cs"
/>
<Compile
Include=
"loadlib.cs"
/>
<Compile
Include=
"lua.cs"
/>
</ItemGroup>
</Project>
\ No newline at end of file
Core/KopiLua/KopiLua.csproj
deleted
100644 → 0
View file @
8d677060
<?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)' == '' "
>
AnyCPU
</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>
<TargetFrameworkVersion>
v2.0
</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup
Condition=
" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "
>
<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>
AnyCPU
</PlatformTarget>
<CodeAnalysisRuleSet>
AllRules.ruleset
</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup
Condition=
" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "
>
<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>
AnyCPU
</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
Core/KopiLua/Makefile.am
deleted
100644 → 0
View file @
8d677060
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)
Core/KopiLua/Properties/AssemblyInfo.cs
deleted
100644 → 0
View file @
8d677060
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
Core/KopiLua/Properties/AssemblyInfo_KopiLua_wp7.cs
deleted
100644 → 0
View file @
8d677060
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"
)]
Core/KopiLua/Properties/AssemblyInfo_Lua.cs
deleted
100644 → 0
View file @
8d677060
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"
)]
Core/KopiLua/Properties/AssemblyInfo_Luac.cs
deleted
100644 → 0
View file @
8d677060
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"
)]
Core/KopiLua/kopilua.pc.in
deleted
100644 → 0
View file @
8d677060
Name: KopiLua
Description: KopiLua
Version: 2.x
Requires:
Libs: -r:@expanded_libdir@/@PACKAGE@/KopiLua.dll
Core/KopiLua/lapi.cs
deleted
100644 → 0
View file @
8d677060
/*
** $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
;
}
}
}
Core/KopiLua/lauxlib.cs
deleted
100644 → 0
View file @
8d677060
/*
** $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
;
}
}
}
Core/KopiLua/lbaselib.cs
deleted
100644 → 0
View file @
8d677060
/*
** $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
;
}
}
}
Core/KopiLua/lcode.cs
deleted
100644 → 0
View file @
8d677060
/*
** $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 */
}
}
}
Core/KopiLua/ldblib.cs
deleted
100644 → 0
View file @
8d677060
/*
** $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
;
}
}
}
Core/KopiLua/ldebug.cs
deleted
100644 → 0
View file @
8d677060
/*
** $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
);
}
}
}
Core/KopiLua/ldo.cs
deleted
100644 → 0
View file @
8d677060
/*
** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
System.Diagnostics
;
using
System.Threading
;
#if XBOX
using
Microsoft.Xna.Framework
;
using
Microsoft.Xna.Framework.Audio
;
using
Microsoft.Xna.Framework.Content
;
using
Microsoft.Xna.Framework.GamerServices
;
using
Microsoft.Xna.Framework.Graphics
;
using
Microsoft.Xna.Framework.Input
;
using
Microsoft.Xna.Framework.Media
;
using
Microsoft.Xna.Framework.Net
;
using
Microsoft.Xna.Framework.Storage
;
#endif
namespace
KopiLua
{
using
lua_Integer
=
System
.
Int32
;
using
ptrdiff_t
=
System
.
Int32
;
using
TValue
=
Lua
.
lua_TValue
;
using
StkId
=
Lua
.
lua_TValue
;
using
lu_byte
=
System
.
Byte
;
using
ZIO
=
Lua
.
Zio
;
public
partial
class
Lua
{
public
static
void
luaD_checkstack
(
lua_State
L
,
int
n
)
{
if
((
L
.
stack_last
-
L
.
top
)
<=
n
)
luaD_growstack
(
L
,
n
);
else
{
#
if
HARDSTACKTESTS
luaD_reallocstack
(
L
,
L
.
stacksize
-
EXTRA_STACK
-
1
);
#
endif
}
}
public
static
void
incr_top
(
lua_State
L
)
{
luaD_checkstack
(
L
,
1
);
StkId
.
inc
(
ref
L
.
top
);
}
// in the original C code these values save and restore the stack by number of bytes. marshalling sizeof
// isn't that straightforward in managed languages, so i implement these by index instead.
public
static
int
savestack
(
lua_State
L
,
StkId
p
)
{
return
p
;}
public
static
StkId
restorestack
(
lua_State
L
,
int
n
)
{
return
L
.
stack
[
n
];}
public
static
int
saveci
(
lua_State
L
,
CallInfo
p
)
{
return
p
-
L
.
base_ci
;}
public
static
CallInfo
restoreci
(
lua_State
L
,
int
n
)
{
return
L
.
base_ci
[
n
];
}
/* results from luaD_precall */
public
const
int
PCRLUA
=
0
;
/* initiated a call to a Lua function */
public
const
int
PCRC
=
1
;
/* did a call to a C function */
public
const
int
PCRYIELD
=
2
;
/* C funtion yielded */
/* type of protected functions, to be ran by `runprotected' */
public
delegate
void
Pfunc
(
lua_State
L
,
object
ud
);
/*
** {======================================================
** Error-recovery functions
** =======================================================
*/
public
delegate
void
luai_jmpbuf
(
lua_Integer
b
);
/* chain list of long jump buffers */
public
class
lua_longjmp
{
public
lua_longjmp
previous
;
public
luai_jmpbuf
b
;
[
CLSCompliantAttribute
(
false
)]
public
volatile
int
status
;
/* error code */
};
public
static
void
luaD_seterrorobj
(
lua_State
L
,
int
errcode
,
StkId
oldtop
)
{
switch
(
errcode
)
{
case
LUA_ERRMEM
:
{
setsvalue2s
(
L
,
oldtop
,
luaS_newliteral
(
L
,
MEMERRMSG
));
break
;
}
case
LUA_ERRERR
:
{
setsvalue2s
(
L
,
oldtop
,
luaS_newliteral
(
L
,
"error in error handling"
));
break
;
}
case
LUA_ERRSYNTAX
:
case
LUA_ERRRUN
:
{
setobjs2s
(
L
,
oldtop
,
L
.
top
-
1
);
/* error message on current top */
break
;
}
}
L
.
top
=
oldtop
+
1
;
}
private
static
void
restore_stack_limit
(
lua_State
L
)
{
lua_assert
(
L
.
stack_last
==
L
.
stacksize
-
EXTRA_STACK
-
1
);
if
(
L
.
size_ci
>
LUAI_MAXCALLS
)
{
/* there was an overflow? */
int
inuse
=
L
.
ci
-
L
.
base_ci
;
if
(
inuse
+
1
<
LUAI_MAXCALLS
)
/* can `undo' overflow? */
luaD_reallocCI
(
L
,
LUAI_MAXCALLS
);
}
}
private
static
void
resetstack
(
lua_State
L
,
int
status
)
{
L
.
ci
=
L
.
base_ci
[
0
];
L
.
base_
=
L
.
ci
.
base_
;
luaF_close
(
L
,
L
.
base_
);
/* close eventual pending closures */
luaD_seterrorobj
(
L
,
status
,
L
.
base_
);
L
.
nCcalls
=
L
.
baseCcalls
;
L
.
allowhook
=
1
;
restore_stack_limit
(
L
);
L
.
errfunc
=
0
;
L
.
errorJmp
=
null
;
}
public
static
void
luaD_throw
(
lua_State
L
,
int
errcode
)
{
if
(
L
.
errorJmp
!=
null
)
{
L
.
errorJmp
.
status
=
errcode
;
LUAI_THROW
(
L
,
L
.
errorJmp
);
}
else
{
L
.
status
=
cast_byte
(
errcode
);
if
(
G
(
L
).
panic
!=
null
)
{
resetstack
(
L
,
errcode
);
lua_unlock
(
L
);
G
(
L
).
panic
(
L
);
}
#if XBOX
throw
new
ApplicationException
();
#else
#if SILVERLIGHT
throw
new
SystemException
();
#else
Environment
.
Exit
(
EXIT_FAILURE
);
#endif
#endif
}
}
public
static
int
luaD_rawrunprotected
(
lua_State
L
,
Pfunc
f
,
object
ud
)
{
lua_longjmp
lj
=
new
lua_longjmp
();
lj
.
status
=
0
;
lj
.
previous
=
L
.
errorJmp
;
/* chain new error handler */
L
.
errorJmp
=
lj
;
/*
LUAI_TRY(L, lj,
f(L, ud)
);
* */
#if CATCH_EXCEPTIONS
try
#endif
{
f
(
L
,
ud
);
}
#if CATCH_EXCEPTIONS
catch
{
if
(
lj
.
status
==
0
)
lj
.
status
=
-
1
;
}
#endif
L
.
errorJmp
=
lj
.
previous
;
/* restore old error handler */
return
lj
.
status
;
}
/* }====================================================== */
private
static
void
correctstack
(
lua_State
L
,
TValue
[]
oldstack
)
{
/* don't need to do this
CallInfo ci;
GCObject up;
L.top = L.stack[L.top - oldstack];
for (up = L.openupval; up != null; up = up.gch.next)
gco2uv(up).v = L.stack[gco2uv(up).v - oldstack];
for (ci = L.base_ci[0]; ci <= L.ci; CallInfo.inc(ref ci)) {
ci.top = L.stack[ci.top - oldstack];
ci.base_ = L.stack[ci.base_ - oldstack];
ci.func = L.stack[ci.func - oldstack];
}
L.base_ = L.stack[L.base_ - oldstack];
* */
}
public
static
void
luaD_reallocstack
(
lua_State
L
,
int
newsize
)
{
TValue
[]
oldstack
=
L
.
stack
;
int
realsize
=
newsize
+
1
+
EXTRA_STACK
;
lua_assert
(
L
.
stack_last
==
L
.
stacksize
-
EXTRA_STACK
-
1
);
luaM_reallocvector
(
L
,
ref
L
.
stack
,
L
.
stacksize
,
realsize
/*, TValue*/
);
L
.
stacksize
=
realsize
;
L
.
stack_last
=
L
.
stack
[
newsize
];
correctstack
(
L
,
oldstack
);
}
public
static
void
luaD_reallocCI
(
lua_State
L
,
int
newsize
)
{
CallInfo
oldci
=
L
.
base_ci
[
0
];
luaM_reallocvector
(
L
,
ref
L
.
base_ci
,
L
.
size_ci
,
newsize
/*, CallInfo*/
);
L
.
size_ci
=
newsize
;
L
.
ci
=
L
.
base_ci
[
L
.
ci
-
oldci
];
L
.
end_ci
=
L
.
base_ci
[
L
.
size_ci
-
1
];
}
public
static
void
luaD_growstack
(
lua_State
L
,
int
n
)
{
if
(
n
<=
L
.
stacksize
)
/* double size is enough? */
luaD_reallocstack
(
L
,
2
*
L
.
stacksize
);
else
luaD_reallocstack
(
L
,
L
.
stacksize
+
n
);
}
private
static
CallInfo
growCI
(
lua_State
L
)
{
if
(
L
.
size_ci
>
LUAI_MAXCALLS
)
/* overflow while handling overflow? */
luaD_throw
(
L
,
LUA_ERRERR
);
else
{
luaD_reallocCI
(
L
,
2
*
L
.
size_ci
);
if
(
L
.
size_ci
>
LUAI_MAXCALLS
)
luaG_runerror
(
L
,
"stack overflow"
);
}
CallInfo
.
inc
(
ref
L
.
ci
);
return
L
.
ci
;
}
public
static
void
luaD_callhook
(
lua_State
L
,
int
event_
,
int
line
)
{
lua_Hook
hook
=
L
.
hook
;
if
((
hook
!=
null
)
&&
(
L
.
allowhook
!=
0
))
{
ptrdiff_t
top
=
savestack
(
L
,
L
.
top
);
ptrdiff_t
ci_top
=
savestack
(
L
,
L
.
ci
.
top
);
lua_Debug
ar
=
new
lua_Debug
();
ar
.
event_
=
event_
;
ar
.
currentline
=
line
;
if
(
event_
==
LUA_HOOKTAILRET
)
ar
.
i_ci
=
0
;
/* tail call; no debug information about it */
else
ar
.
i_ci
=
L
.
ci
-
L
.
base_ci
;
luaD_checkstack
(
L
,
LUA_MINSTACK
);
/* ensure minimum stack size */
L
.
ci
.
top
=
L
.
top
+
LUA_MINSTACK
;
lua_assert
(
L
.
ci
.
top
<=
L
.
stack_last
);
L
.
allowhook
=
0
;
/* cannot call hooks inside a hook */
lua_unlock
(
L
);
hook
(
L
,
ar
);
lua_lock
(
L
);
lua_assert
(
L
.
allowhook
==
0
);
L
.
allowhook
=
1
;
L
.
ci
.
top
=
restorestack
(
L
,
ci_top
);
L
.
top
=
restorestack
(
L
,
top
);
}
}
private
static
StkId
adjust_varargs
(
lua_State
L
,
Proto
p
,
int
actual
)
{
int
i
;
int
nfixargs
=
p
.
numparams
;
Table
htab
=
null
;
StkId
base_
,
fixed_
;
for
(;
actual
<
nfixargs
;
++
actual
)
setnilvalue
(
StkId
.
inc
(
ref
L
.
top
));
#
if
LUA_COMPAT_VARARG
if
((
p
.
is_vararg
&
VARARG_NEEDSARG
)
!=
0
)
{
/* compat. with old-style vararg? */
int
nvar
=
actual
-
nfixargs
;
/* number of extra arguments */
lua_assert
(
p
.
is_vararg
&
VARARG_HASARG
);
luaC_checkGC
(
L
);
htab
=
luaH_new
(
L
,
nvar
,
1
);
/* create `arg' table */
for
(
i
=
0
;
i
<
nvar
;
i
++)
/* put extra arguments into `arg' table */
setobj2n
(
L
,
luaH_setnum
(
L
,
htab
,
i
+
1
),
L
.
top
-
nvar
+
i
);
/* store counter in field `n' */
setnvalue
(
luaH_setstr
(
L
,
htab
,
luaS_newliteral
(
L
,
"n"
)),
cast_num
(
nvar
));
}
#
endif
/* move fixed parameters to final position */
fixed_
=
L
.
top
-
actual
;
/* first fixed argument */
base_
=
L
.
top
;
/* final position of first argument */
for
(
i
=
0
;
i
<
nfixargs
;
i
++)
{
setobjs2s
(
L
,
StkId
.
inc
(
ref
L
.
top
),
fixed_
+
i
);
setnilvalue
(
fixed_
+
i
);
}
/* add `arg' parameter */
if
(
htab
!=
null
)
{
StkId
top
=
L
.
top
;
StkId
.
inc
(
ref
L
.
top
);
sethvalue
(
L
,
top
,
htab
);
lua_assert
(
iswhite
(
obj2gco
(
htab
)));
}
return
base_
;
}
static
StkId
tryfuncTM
(
lua_State
L
,
StkId
func
)
{
/*const*/
TValue
tm
=
luaT_gettmbyobj
(
L
,
func
,
TMS
.
TM_CALL
);
StkId
p
;
ptrdiff_t
funcr
=
savestack
(
L
,
func
);
if
(!
ttisfunction
(
tm
))
luaG_typeerror
(
L
,
func
,
"call"
);
/* Open a hole inside the stack at `func' */
for
(
p
=
L
.
top
;
p
>
func
;
StkId
.
dec
(
ref
p
))
setobjs2s
(
L
,
p
,
p
-
1
);
incr_top
(
L
);
func
=
restorestack
(
L
,
funcr
);
/* previous call may change stack */
setobj2s
(
L
,
func
,
tm
);
/* tag method is the new function to be called */
return
func
;
}
public
static
CallInfo
inc_ci
(
lua_State
L
)
{
if
(
L
.
ci
==
L
.
end_ci
)
return
growCI
(
L
);
// (condhardstacktests(luaD_reallocCI(L, L.size_ci)), ++L.ci))
CallInfo
.
inc
(
ref
L
.
ci
);
return
L
.
ci
;
}
public
static
int
luaD_precall
(
lua_State
L
,
StkId
func
,
int
nresults
)
{
LClosure
cl
;
ptrdiff_t
funcr
;
if
(!
ttisfunction
(
func
))
/* `func' is not a function? */
func
=
tryfuncTM
(
L
,
func
);
/* check the `function' tag method */
funcr
=
savestack
(
L
,
func
);
cl
=
clvalue
(
func
).
l
;
L
.
ci
.
savedpc
=
InstructionPtr
.
Assign
(
L
.
savedpc
);
if
(
cl
.
isC
==
0
)
{
/* Lua function? prepare its call */
CallInfo
ci
;
StkId
st
,
base_
;
Proto
p
=
cl
.
p
;
luaD_checkstack
(
L
,
p
.
maxstacksize
);
func
=
restorestack
(
L
,
funcr
);
if
(
p
.
is_vararg
==
0
)
{
/* no varargs? */
base_
=
L
.
stack
[
func
+
1
];
if
(
L
.
top
>
base_
+
p
.
numparams
)
L
.
top
=
base_
+
p
.
numparams
;
}
else
{
/* vararg function */
int
nargs
=
L
.
top
-
func
-
1
;
base_
=
adjust_varargs
(
L
,
p
,
nargs
);
func
=
restorestack
(
L
,
funcr
);
/* previous call may change the stack */
}
ci
=
inc_ci
(
L
);
/* now `enter' new function */
ci
.
func
=
func
;
L
.
base_
=
ci
.
base_
=
base_
;
ci
.
top
=
L
.
base_
+
p
.
maxstacksize
;
lua_assert
(
ci
.
top
<=
L
.
stack_last
);
L
.
savedpc
=
new
InstructionPtr
(
p
.
code
,
0
);
/* starting point */
ci
.
tailcalls
=
0
;
ci
.
nresults
=
nresults
;
for
(
st
=
L
.
top
;
st
<
ci
.
top
;
StkId
.
inc
(
ref
st
))
setnilvalue
(
st
);
L
.
top
=
ci
.
top
;
if
((
L
.
hookmask
&
LUA_MASKCALL
)
!=
0
)
{
InstructionPtr
.
inc
(
ref
L
.
savedpc
);
/* hooks assume 'pc' is already incremented */
luaD_callhook
(
L
,
LUA_HOOKCALL
,
-
1
);
InstructionPtr
.
dec
(
ref
L
.
savedpc
);
/* correct 'pc' */
}
return
PCRLUA
;
}
else
{
/* if is a C function, call it */
CallInfo
ci
;
int
n
;
luaD_checkstack
(
L
,
LUA_MINSTACK
);
/* ensure minimum stack size */
ci
=
inc_ci
(
L
);
/* now `enter' new function */
ci
.
func
=
restorestack
(
L
,
funcr
);
L
.
base_
=
ci
.
base_
=
ci
.
func
+
1
;
ci
.
top
=
L
.
top
+
LUA_MINSTACK
;
lua_assert
(
ci
.
top
<=
L
.
stack_last
);
ci
.
nresults
=
nresults
;
if
((
L
.
hookmask
&
LUA_MASKCALL
)
!=
0
)
luaD_callhook
(
L
,
LUA_HOOKCALL
,
-
1
);
lua_unlock
(
L
);
n
=
curr_func
(
L
).
c
.
f
(
L
);
/* do the actual call */
lua_lock
(
L
);
if
(
n
<
0
)
/* yielding? */
return
PCRYIELD
;
else
{
luaD_poscall
(
L
,
L
.
top
-
n
);
return
PCRC
;
}
}
}
private
static
StkId
callrethooks
(
lua_State
L
,
StkId
firstResult
)
{
ptrdiff_t
fr
=
savestack
(
L
,
firstResult
);
/* next call may change stack */
luaD_callhook
(
L
,
LUA_HOOKRET
,
-
1
);
if
(
f_isLua
(
L
.
ci
))
{
/* Lua function? */
while
(
((
L
.
hookmask
&
LUA_MASKRET
)!=
0
)
&&
(
L
.
ci
.
tailcalls
--
!=
0
))
/* tail calls */
luaD_callhook
(
L
,
LUA_HOOKTAILRET
,
-
1
);
}
return
restorestack
(
L
,
fr
);
}
public
static
int
luaD_poscall
(
lua_State
L
,
StkId
firstResult
)
{
StkId
res
;
int
wanted
,
i
;
CallInfo
ci
;
if
((
L
.
hookmask
&
LUA_MASKRET
)
!=
0
)
firstResult
=
callrethooks
(
L
,
firstResult
);
ci
=
CallInfo
.
dec
(
ref
L
.
ci
);
res
=
ci
.
func
;
/* res == final position of 1st result */
wanted
=
ci
.
nresults
;
L
.
base_
=
(
ci
-
1
).
base_
;
/* restore base */
L
.
savedpc
=
InstructionPtr
.
Assign
((
ci
-
1
).
savedpc
);
/* restore savedpc */
/* move results to correct place */
for
(
i
=
wanted
;
i
!=
0
&&
firstResult
<
L
.
top
;
i
--)
{
setobjs2s
(
L
,
res
,
firstResult
);
res
=
res
+
1
;
firstResult
=
firstResult
+
1
;
}
while
(
i
--
>
0
)
setnilvalue
(
StkId
.
inc
(
ref
res
));
L
.
top
=
res
;
return
(
wanted
-
LUA_MULTRET
);
/* 0 iff wanted == LUA_MULTRET */
}
/*
** Call a function (C or Lua). The function to be called is at *func.
** The arguments are on the stack, right after the function.
** When returns, all the results are on the stack, starting at the original
** function position.
*/
private
static
void
luaD_call
(
lua_State
L
,
StkId
func
,
int
nResults
)
{
if
(++
L
.
nCcalls
>=
LUAI_MAXCCALLS
)
{
if
(
L
.
nCcalls
==
LUAI_MAXCCALLS
)
luaG_runerror
(
L
,
"C stack overflow"
);
else
if
(
L
.
nCcalls
>=
(
LUAI_MAXCCALLS
+
(
LUAI_MAXCCALLS
>>
3
)))
luaD_throw
(
L
,
LUA_ERRERR
);
/* error while handing stack error */
}
if
(
luaD_precall
(
L
,
func
,
nResults
)
==
PCRLUA
)
/* is a Lua function? */
luaV_execute
(
L
,
1
);
/* call it */
L
.
nCcalls
--;
luaC_checkGC
(
L
);
}
private
static
void
resume
(
lua_State
L
,
object
ud
)
{
StkId
firstArg
=
(
StkId
)
ud
;
CallInfo
ci
=
L
.
ci
;
if
(
L
.
status
==
0
)
{
/* start coroutine? */
lua_assert
(
ci
==
L
.
base_ci
[
0
]
&&
firstArg
>
L
.
base_
);
if
(
luaD_precall
(
L
,
firstArg
-
1
,
LUA_MULTRET
)
!=
PCRLUA
)
return
;
}
else
{
/* resuming from previous yield */
lua_assert
(
L
.
status
==
LUA_YIELD
);
L
.
status
=
0
;
if
(!
f_isLua
(
ci
))
{
/* `common' yield? */
/* finish interrupted execution of `OP_CALL' */
lua_assert
(
GET_OPCODE
((
ci
-
1
).
savedpc
[-
1
])
==
OpCode
.
OP_CALL
||
GET_OPCODE
((
ci
-
1
).
savedpc
[-
1
])
==
OpCode
.
OP_TAILCALL
);
if
(
luaD_poscall
(
L
,
firstArg
)
!=
0
)
/* complete it... */
L
.
top
=
L
.
ci
.
top
;
/* and correct top if not multiple results */
}
else
/* yielded inside a hook: just continue its execution */
L
.
base_
=
L
.
ci
.
base_
;
}
luaV_execute
(
L
,
L
.
ci
-
L
.
base_ci
);
}
private
static
int
resume_error
(
lua_State
L
,
CharPtr
msg
)
{
L
.
top
=
L
.
ci
.
base_
;
setsvalue2s
(
L
,
L
.
top
,
luaS_new
(
L
,
msg
));
incr_top
(
L
);
lua_unlock
(
L
);
return
LUA_ERRRUN
;
}
public
static
int
lua_resume
(
lua_State
L
,
int
nargs
)
{
int
status
;
lua_lock
(
L
);
if
(
L
.
status
!=
LUA_YIELD
&&
(
L
.
status
!=
0
||
(
L
.
ci
!=
L
.
base_ci
[
0
])))
return
resume_error
(
L
,
"cannot resume non-suspended coroutine"
);
if
(
L
.
nCcalls
>=
LUAI_MAXCCALLS
)
return
resume_error
(
L
,
"C stack overflow"
);
luai_userstateresume
(
L
,
nargs
);
lua_assert
(
L
.
errfunc
==
0
);
L
.
baseCcalls
=
++
L
.
nCcalls
;
status
=
luaD_rawrunprotected
(
L
,
resume
,
L
.
top
-
nargs
);
if
(
status
!=
0
)
{
/* error? */
L
.
status
=
cast_byte
(
status
);
/* mark thread as `dead' */
luaD_seterrorobj
(
L
,
status
,
L
.
top
);
L
.
ci
.
top
=
L
.
top
;
}
else
{
lua_assert
(
L
.
nCcalls
==
L
.
baseCcalls
);
status
=
L
.
status
;
}
--
L
.
nCcalls
;
lua_unlock
(
L
);
return
status
;
}
[
CLSCompliantAttribute
(
false
)]
public
static
int
lua_yield
(
lua_State
L
,
int
nresults
)
{
luai_userstateyield
(
L
,
nresults
);
lua_lock
(
L
);
if
(
L
.
nCcalls
>
L
.
baseCcalls
)
luaG_runerror
(
L
,
"attempt to yield across metamethod/C-call boundary"
);
L
.
base_
=
L
.
top
-
nresults
;
/* protect stack slots below */
L
.
status
=
LUA_YIELD
;
lua_unlock
(
L
);
return
-
1
;
}
public
static
int
luaD_pcall
(
lua_State
L
,
Pfunc
func
,
object
u
,
ptrdiff_t
old_top
,
ptrdiff_t
ef
)
{
int
status
;
ushort
oldnCcalls
=
L
.
nCcalls
;
ptrdiff_t
old_ci
=
saveci
(
L
,
L
.
ci
);
lu_byte
old_allowhooks
=
L
.
allowhook
;
ptrdiff_t
old_errfunc
=
L
.
errfunc
;
L
.
errfunc
=
ef
;
status
=
luaD_rawrunprotected
(
L
,
func
,
u
);
if
(
status
!=
0
)
{
/* an error occurred? */
StkId
oldtop
=
restorestack
(
L
,
old_top
);
luaF_close
(
L
,
oldtop
);
/* close eventual pending closures */
luaD_seterrorobj
(
L
,
status
,
oldtop
);
L
.
nCcalls
=
oldnCcalls
;
L
.
ci
=
restoreci
(
L
,
old_ci
);
L
.
base_
=
L
.
ci
.
base_
;
L
.
savedpc
=
InstructionPtr
.
Assign
(
L
.
ci
.
savedpc
);
L
.
allowhook
=
old_allowhooks
;
restore_stack_limit
(
L
);
}
L
.
errfunc
=
old_errfunc
;
return
status
;
}
/*
** Execute a protected parser.
*/
public
class
SParser
{
/* data to `f_parser' */
public
ZIO
z
;
public
Mbuffer
buff
=
new
Mbuffer
();
/* buffer to be used by the scanner */
public
CharPtr
name
;
};
private
static
void
f_parser
(
lua_State
L
,
object
ud
)
{
int
i
;
Proto
tf
;
Closure
cl
;
SParser
p
=
(
SParser
)
ud
;
int
c
=
luaZ_lookahead
(
p
.
z
);
luaC_checkGC
(
L
);
tf
=
(
c
==
LUA_SIGNATURE
[
0
])
?
luaU_undump
(
L
,
p
.
z
,
p
.
buff
,
p
.
name
)
:
luaY_parser
(
L
,
p
.
z
,
p
.
buff
,
p
.
name
);
cl
=
luaF_newLclosure
(
L
,
tf
.
nups
,
hvalue
(
gt
(
L
)));
cl
.
l
.
p
=
tf
;
for
(
i
=
0
;
i
<
tf
.
nups
;
i
++)
/* initialize eventual upvalues */
cl
.
l
.
upvals
[
i
]
=
luaF_newupval
(
L
);
setclvalue
(
L
,
L
.
top
,
cl
);
incr_top
(
L
);
}
public
static
int
luaD_protectedparser
(
lua_State
L
,
ZIO
z
,
CharPtr
name
)
{
SParser
p
=
new
SParser
();
int
status
;
p
.
z
=
z
;
p
.
name
=
new
CharPtr
(
name
);
luaZ_initbuffer
(
L
,
p
.
buff
);
status
=
luaD_pcall
(
L
,
f_parser
,
p
,
savestack
(
L
,
L
.
top
),
L
.
errfunc
);
luaZ_freebuffer
(
L
,
p
.
buff
);
return
status
;
}
}
}
Core/KopiLua/ldump.cs
deleted
100644 → 0
View file @
8d677060
/*
** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/
using
System
;
using
System.IO
;
using
System.Collections.Generic
;
using
System.Text
;
using
System.Runtime.InteropServices
;
using
System.Diagnostics
;
using
System.Runtime.Serialization
;
namespace
KopiLua
{
using
lua_Number
=
System
.
Double
;
using
TValue
=
Lua
.
lua_TValue
;
public
partial
class
Lua
{
public
class
DumpState
{
public
lua_State
L
;
[
CLSCompliantAttribute
(
false
)]
public
lua_Writer
writer
;
public
object
data
;
public
int
strip
;
public
int
status
;
};
public
static
void
DumpMem
(
object
b
,
DumpState
D
)
{
#if XBOX || SILVERLIGHT
// todo: implement this - mjf
Debug
.
Assert
(
false
);
#else
int
size
=
Marshal
.
SizeOf
(
b
);
IntPtr
ptr
=
Marshal
.
AllocHGlobal
(
size
);
Marshal
.
StructureToPtr
(
b
,
ptr
,
false
);
byte
[]
bytes
=
new
byte
[
size
];
Marshal
.
Copy
(
ptr
,
bytes
,
0
,
size
);
char
[]
ch
=
new
char
[
bytes
.
Length
];
for
(
int
i
=
0
;
i
<
bytes
.
Length
;
i
++)
ch
[
i
]
=
(
char
)
bytes
[
i
];
CharPtr
str
=
ch
;
DumpBlock
(
str
,
(
uint
)
str
.
chars
.
Length
,
D
);
Marshal
.
Release
(
ptr
);
#endif
}
public
static
void
DumpMem
(
object
b
,
int
n
,
DumpState
D
)
{
Array
array
=
b
as
Array
;
Debug
.
Assert
(
array
.
Length
==
n
);
for
(
int
i
=
0
;
i
<
n
;
i
++)
DumpMem
(
array
.
GetValue
(
i
),
D
);
}
public
static
void
DumpVar
(
object
x
,
DumpState
D
)
{
DumpMem
(
x
,
D
);
}
private
static
void
DumpBlock
(
CharPtr
b
,
uint
size
,
DumpState
D
)
{
if
(
D
.
status
==
0
)
{
lua_unlock
(
D
.
L
);
D
.
status
=
D
.
writer
(
D
.
L
,
b
,
size
,
D
.
data
);
lua_lock
(
D
.
L
);
}
}
private
static
void
DumpChar
(
int
y
,
DumpState
D
)
{
char
x
=(
char
)
y
;
DumpVar
(
x
,
D
);
}
private
static
void
DumpInt
(
int
x
,
DumpState
D
)
{
DumpVar
(
x
,
D
);
}
private
static
void
DumpNumber
(
lua_Number
x
,
DumpState
D
)
{
DumpVar
(
x
,
D
);
}
static
void
DumpVector
(
object
b
,
int
n
,
DumpState
D
)
{
DumpInt
(
n
,
D
);
DumpMem
(
b
,
n
,
D
);
}
private
static
void
DumpString
(
TString
s
,
DumpState
D
)
{
if
(
s
==
null
||
getstr
(
s
)==
null
)
{
uint
size
=
0
;
DumpVar
(
size
,
D
);
}
else
{
uint
size
=
s
.
tsv
.
len
+
1
;
/* include trailing '\0' */
DumpVar
(
size
,
D
);
DumpBlock
(
getstr
(
s
),
size
,
D
);
}
}
private
static
void
DumpCode
(
Proto
f
,
DumpState
D
)
{
DumpVector
(
f
.
code
,
f
.
sizecode
,
D
);
}
private
static
void
DumpConstants
(
Proto
f
,
DumpState
D
)
{
int
i
,
n
=
f
.
sizek
;
DumpInt
(
n
,
D
);
for
(
i
=
0
;
i
<
n
;
i
++)
{
/*const*/
TValue
o
=
f
.
k
[
i
];
DumpChar
(
ttype
(
o
),
D
);
switch
(
ttype
(
o
))
{
case
LUA_TNIL
:
break
;
case
LUA_TBOOLEAN
:
DumpChar
(
bvalue
(
o
),
D
);
break
;
case
LUA_TNUMBER
:
DumpNumber
(
nvalue
(
o
),
D
);
break
;
case
LUA_TSTRING
:
DumpString
(
rawtsvalue
(
o
),
D
);
break
;
default
:
lua_assert
(
0
);
/* cannot happen */
break
;
}
}
n
=
f
.
sizep
;
DumpInt
(
n
,
D
);
for
(
i
=
0
;
i
<
n
;
i
++)
DumpFunction
(
f
.
p
[
i
],
f
.
source
,
D
);
}
private
static
void
DumpDebug
(
Proto
f
,
DumpState
D
)
{
int
i
,
n
;
n
=
(
D
.
strip
!=
0
)
?
0
:
f
.
sizelineinfo
;
DumpVector
(
f
.
lineinfo
,
n
,
D
);
n
=
(
D
.
strip
!=
0
)
?
0
:
f
.
sizelocvars
;
DumpInt
(
n
,
D
);
for
(
i
=
0
;
i
<
n
;
i
++)
{
DumpString
(
f
.
locvars
[
i
].
varname
,
D
);
DumpInt
(
f
.
locvars
[
i
].
startpc
,
D
);
DumpInt
(
f
.
locvars
[
i
].
endpc
,
D
);
}
n
=
(
D
.
strip
!=
0
)
?
0
:
f
.
sizeupvalues
;
DumpInt
(
n
,
D
);
for
(
i
=
0
;
i
<
n
;
i
++)
DumpString
(
f
.
upvalues
[
i
],
D
);
}
private
static
void
DumpFunction
(
Proto
f
,
TString
p
,
DumpState
D
)
{
DumpString
(
((
f
.
source
==
p
)
||
(
D
.
strip
!=
0
))
?
null
:
f
.
source
,
D
);
DumpInt
(
f
.
linedefined
,
D
);
DumpInt
(
f
.
lastlinedefined
,
D
);
DumpChar
(
f
.
nups
,
D
);
DumpChar
(
f
.
numparams
,
D
);
DumpChar
(
f
.
is_vararg
,
D
);
DumpChar
(
f
.
maxstacksize
,
D
);
DumpCode
(
f
,
D
);
DumpConstants
(
f
,
D
);
DumpDebug
(
f
,
D
);
}
private
static
void
DumpHeader
(
DumpState
D
)
{
CharPtr
h
=
new
char
[
LUAC_HEADERSIZE
];
luaU_header
(
h
);
DumpBlock
(
h
,
LUAC_HEADERSIZE
,
D
);
}
/*
** dump Lua function as precompiled chunk
*/
[
CLSCompliantAttribute
(
false
)]
public
static
int
luaU_dump
(
lua_State
L
,
Proto
f
,
lua_Writer
w
,
object
data
,
int
strip
)
{
DumpState
D
=
new
DumpState
();
D
.
L
=
L
;
D
.
writer
=
w
;
D
.
data
=
data
;
D
.
strip
=
strip
;
D
.
status
=
0
;
DumpHeader
(
D
);
DumpFunction
(
f
,
null
,
D
);
return
D
.
status
;
}
}
}
Core/KopiLua/lfunc.cs
deleted
100644 → 0
View file @
8d677060
/*
** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
System.Diagnostics
;
using
System.Runtime.InteropServices
;
namespace
KopiLua
{
using
TValue
=
Lua
.
lua_TValue
;
using
StkId
=
Lua
.
lua_TValue
;
using
Instruction
=
System
.
UInt32
;
public
partial
class
Lua
{
public
static
int
sizeCclosure
(
int
n
)
{
return
GetUnmanagedSize
(
typeof
(
CClosure
))
+
GetUnmanagedSize
(
typeof
(
TValue
))
*
(
n
-
1
);
}
public
static
int
sizeLclosure
(
int
n
)
{
return
GetUnmanagedSize
(
typeof
(
LClosure
))
+
GetUnmanagedSize
(
typeof
(
TValue
))
*
(
n
-
1
);
}
public
static
Closure
luaF_newCclosure
(
lua_State
L
,
int
nelems
,
Table
e
)
{
//Closure c = (Closure)luaM_malloc(L, sizeCclosure(nelems));
Closure
c
=
luaM_new
<
Closure
>(
L
);
AddTotalBytes
(
L
,
sizeCclosure
(
nelems
));
luaC_link
(
L
,
obj2gco
(
c
),
LUA_TFUNCTION
);
c
.
c
.
isC
=
1
;
c
.
c
.
env
=
e
;
c
.
c
.
nupvalues
=
cast_byte
(
nelems
);
c
.
c
.
upvalue
=
new
TValue
[
nelems
];
for
(
int
i
=
0
;
i
<
nelems
;
i
++)
c
.
c
.
upvalue
[
i
]
=
new
lua_TValue
();
return
c
;
}
public
static
Closure
luaF_newLclosure
(
lua_State
L
,
int
nelems
,
Table
e
)
{
//Closure c = (Closure)luaM_malloc(L, sizeLclosure(nelems));
Closure
c
=
luaM_new
<
Closure
>(
L
);
AddTotalBytes
(
L
,
sizeLclosure
(
nelems
));
luaC_link
(
L
,
obj2gco
(
c
),
LUA_TFUNCTION
);
c
.
l
.
isC
=
0
;
c
.
l
.
env
=
e
;
c
.
l
.
nupvalues
=
cast_byte
(
nelems
);
c
.
l
.
upvals
=
new
UpVal
[
nelems
];
for
(
int
i
=
0
;
i
<
nelems
;
i
++)
c
.
l
.
upvals
[
i
]
=
new
UpVal
();
while
(
nelems
--
>
0
)
c
.
l
.
upvals
[
nelems
]
=
null
;
return
c
;
}
public
static
UpVal
luaF_newupval
(
lua_State
L
)
{
UpVal
uv
=
luaM_new
<
UpVal
>(
L
);
luaC_link
(
L
,
obj2gco
(
uv
),
LUA_TUPVAL
);
uv
.
v
=
uv
.
u
.
value
;
setnilvalue
(
uv
.
v
);
return
uv
;
}
public
static
UpVal
luaF_findupval
(
lua_State
L
,
StkId
level
)
{
global_State
g
=
G
(
L
);
GCObjectRef
pp
=
new
OpenValRef
(
L
);
UpVal
p
;
UpVal
uv
;
while
(
pp
.
get
()
!=
null
&&
(
p
=
ngcotouv
(
pp
.
get
())).
v
>=
level
)
{
lua_assert
(
p
.
v
!=
p
.
u
.
value
);
if
(
p
.
v
==
level
)
{
/* found a corresponding upvalue? */
if
(
isdead
(
g
,
obj2gco
(
p
)))
/* is it dead? */
changewhite
(
obj2gco
(
p
));
/* ressurect it */
return
p
;
}
pp
=
new
NextRef
(
p
);
}
uv
=
luaM_new
<
UpVal
>(
L
);
/* not found: create a new one */
uv
.
tt
=
LUA_TUPVAL
;
uv
.
marked
=
luaC_white
(
g
);
uv
.
v
=
level
;
/* current value lives in the stack */
uv
.
next
=
pp
.
get
();
/* chain it in the proper position */
pp
.
set
(
obj2gco
(
uv
)
);
uv
.
u
.
l
.
prev
=
g
.
uvhead
;
/* double link it in `uvhead' list */
uv
.
u
.
l
.
next
=
g
.
uvhead
.
u
.
l
.
next
;
uv
.
u
.
l
.
next
.
u
.
l
.
prev
=
uv
;
g
.
uvhead
.
u
.
l
.
next
=
uv
;
lua_assert
(
uv
.
u
.
l
.
next
.
u
.
l
.
prev
==
uv
&&
uv
.
u
.
l
.
prev
.
u
.
l
.
next
==
uv
);
return
uv
;
}
private
static
void
unlinkupval
(
UpVal
uv
)
{
lua_assert
(
uv
.
u
.
l
.
next
.
u
.
l
.
prev
==
uv
&&
uv
.
u
.
l
.
prev
.
u
.
l
.
next
==
uv
);
uv
.
u
.
l
.
next
.
u
.
l
.
prev
=
uv
.
u
.
l
.
prev
;
/* remove from `uvhead' list */
uv
.
u
.
l
.
prev
.
u
.
l
.
next
=
uv
.
u
.
l
.
next
;
}
public
static
void
luaF_freeupval
(
lua_State
L
,
UpVal
uv
)
{
if
(
uv
.
v
!=
uv
.
u
.
value
)
/* is it open? */
unlinkupval
(
uv
);
/* remove from open list */
luaM_free
(
L
,
uv
);
/* free upvalue */
}
public
static
void
luaF_close
(
lua_State
L
,
StkId
level
)
{
UpVal
uv
;
global_State
g
=
G
(
L
);
while
(
L
.
openupval
!=
null
&&
(
uv
=
ngcotouv
(
L
.
openupval
)).
v
>=
level
)
{
GCObject
o
=
obj2gco
(
uv
);
lua_assert
(!
isblack
(
o
)
&&
uv
.
v
!=
uv
.
u
.
value
);
L
.
openupval
=
uv
.
next
;
/* remove from `open' list */
if
(
isdead
(
g
,
o
))
luaF_freeupval
(
L
,
uv
);
/* free upvalue */
else
{
unlinkupval
(
uv
);
setobj
(
L
,
uv
.
u
.
value
,
uv
.
v
);
uv
.
v
=
uv
.
u
.
value
;
/* now current value lives here */
luaC_linkupval
(
L
,
uv
);
/* link upvalue into `gcroot' list */
}
}
}
public
static
Proto
luaF_newproto
(
lua_State
L
)
{
Proto
f
=
luaM_new
<
Proto
>(
L
);
luaC_link
(
L
,
obj2gco
(
f
),
LUA_TPROTO
);
f
.
k
=
null
;
f
.
sizek
=
0
;
f
.
p
=
null
;
f
.
sizep
=
0
;
f
.
code
=
null
;
f
.
sizecode
=
0
;
f
.
sizelineinfo
=
0
;
f
.
sizeupvalues
=
0
;
f
.
nups
=
0
;
f
.
upvalues
=
null
;
f
.
numparams
=
0
;
f
.
is_vararg
=
0
;
f
.
maxstacksize
=
0
;
f
.
lineinfo
=
null
;
f
.
sizelocvars
=
0
;
f
.
locvars
=
null
;
f
.
linedefined
=
0
;
f
.
lastlinedefined
=
0
;
f
.
source
=
null
;
return
f
;
}
public
static
void
luaF_freeproto
(
lua_State
L
,
Proto
f
)
{
luaM_freearray
<
Instruction
>(
L
,
f
.
code
);
luaM_freearray
<
Proto
>(
L
,
f
.
p
);
luaM_freearray
<
TValue
>(
L
,
f
.
k
);
luaM_freearray
<
Int32
>(
L
,
f
.
lineinfo
);
luaM_freearray
<
LocVar
>(
L
,
f
.
locvars
);
luaM_freearray
<
TString
>(
L
,
f
.
upvalues
);
luaM_free
(
L
,
f
);
}
// we have a gc, so nothing to do
public
static
void
luaF_freeclosure
(
lua_State
L
,
Closure
c
)
{
int
size
=
(
c
.
c
.
isC
!=
0
)
?
sizeCclosure
(
c
.
c
.
nupvalues
)
:
sizeLclosure
(
c
.
l
.
nupvalues
);
//luaM_freemem(L, c, size);
SubtractTotalBytes
(
L
,
size
);
}
/*
** Look for n-th local variable at line `line' in function `func'.
** Returns null if not found.
*/
public
static
CharPtr
luaF_getlocalname
(
Proto
f
,
int
local_number
,
int
pc
)
{
int
i
;
for
(
i
=
0
;
i
<
f
.
sizelocvars
&&
f
.
locvars
[
i
].
startpc
<=
pc
;
i
++)
{
if
(
pc
<
f
.
locvars
[
i
].
endpc
)
{
/* is variable active? */
local_number
--;
if
(
local_number
==
0
)
return
getstr
(
f
.
locvars
[
i
].
varname
);
}
}
return
null
;
/* not found */
}
}
}
Core/KopiLua/lgc.cs
deleted
100644 → 0
View file @
8d677060
/*
** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
System.Runtime.InteropServices
;
using
System.Diagnostics
;
namespace
KopiLua
{
using
lu_int32
=
System
.
UInt32
;
using
l_mem
=
System
.
Int32
;
using
lu_mem
=
System
.
UInt32
;
using
TValue
=
Lua
.
lua_TValue
;
using
StkId
=
Lua
.
lua_TValue
;
using
lu_byte
=
System
.
Byte
;
using
Instruction
=
System
.
UInt32
;
public
partial
class
Lua
{
/*
** Possible states of the Garbage Collector
*/
public
const
int
GCSpause
=
0
;
public
const
int
GCSpropagate
=
1
;
public
const
int
GCSsweepstring
=
2
;
public
const
int
GCSsweep
=
3
;
public
const
int
GCSfinalize
=
4
;
/*
** some userful bit tricks
*/
public
static
int
resetbits
(
ref
lu_byte
x
,
int
m
)
{
x
&=
(
lu_byte
)~
m
;
return
x
;
}
public
static
int
setbits
(
ref
lu_byte
x
,
int
m
)
{
x
|=
(
lu_byte
)
m
;
return
x
;
}
public
static
bool
testbits
(
lu_byte
x
,
int
m
)
{
return
(
x
&
(
lu_byte
)
m
)
!=
0
;
}
public
static
int
bitmask
(
int
b
)
{
return
1
<<
b
;}
public
static
int
bit2mask
(
int
b1
,
int
b2
)
{
return
(
bitmask
(
b1
)
|
bitmask
(
b2
));}
public
static
int
l_setbit
(
ref
lu_byte
x
,
int
b
)
{
return
setbits
(
ref
x
,
bitmask
(
b
));
}
public
static
int
resetbit
(
ref
lu_byte
x
,
int
b
)
{
return
resetbits
(
ref
x
,
bitmask
(
b
));
}
public
static
bool
testbit
(
lu_byte
x
,
int
b
)
{
return
testbits
(
x
,
bitmask
(
b
));
}
public
static
int
set2bits
(
ref
lu_byte
x
,
int
b1
,
int
b2
)
{
return
setbits
(
ref
x
,
(
bit2mask
(
b1
,
b2
)));
}
public
static
int
reset2bits
(
ref
lu_byte
x
,
int
b1
,
int
b2
)
{
return
resetbits
(
ref
x
,
(
bit2mask
(
b1
,
b2
)));
}
public
static
bool
test2bits
(
lu_byte
x
,
int
b1
,
int
b2
)
{
return
testbits
(
x
,
(
bit2mask
(
b1
,
b2
)));
}
/*
** Layout for bit use in `marked' field:
** bit 0 - object is white (type 0)
** bit 1 - object is white (type 1)
** bit 2 - object is black
** bit 3 - for userdata: has been finalized
** bit 3 - for tables: has weak keys
** bit 4 - for tables: has weak values
** bit 5 - object is fixed (should not be collected)
** bit 6 - object is "super" fixed (only the main thread)
*/
public
const
int
WHITE0BIT
=
0
;
public
const
int
WHITE1BIT
=
1
;
public
const
int
BLACKBIT
=
2
;
public
const
int
FINALIZEDBIT
=
3
;
public
const
int
KEYWEAKBIT
=
3
;
public
const
int
VALUEWEAKBIT
=
4
;
public
const
int
FIXEDBIT
=
5
;
public
const
int
SFIXEDBIT
=
6
;
public
readonly
static
int
WHITEBITS
=
bit2mask
(
WHITE0BIT
,
WHITE1BIT
);
public
static
bool
iswhite
(
GCObject
x
)
{
return
test2bits
(
x
.
gch
.
marked
,
WHITE0BIT
,
WHITE1BIT
);
}
public
static
bool
isblack
(
GCObject
x
)
{
return
testbit
(
x
.
gch
.
marked
,
BLACKBIT
);
}
public
static
bool
isgray
(
GCObject
x
)
{
return
(!
isblack
(
x
)
&&
!
iswhite
(
x
));
}
public
static
int
otherwhite
(
global_State
g
)
{
return
g
.
currentwhite
^
WHITEBITS
;
}
public
static
bool
isdead
(
global_State
g
,
GCObject
v
)
{
return
(
v
.
gch
.
marked
&
otherwhite
(
g
)
&
WHITEBITS
)
!=
0
;
}
public
static
void
changewhite
(
GCObject
x
)
{
x
.
gch
.
marked
^=
(
byte
)
WHITEBITS
;
}
public
static
void
gray2black
(
GCObject
x
)
{
l_setbit
(
ref
x
.
gch
.
marked
,
BLACKBIT
);
}
public
static
bool
valiswhite
(
TValue
x
)
{
return
(
iscollectable
(
x
)
&&
iswhite
(
gcvalue
(
x
)));
}
public
static
byte
luaC_white
(
global_State
g
)
{
return
(
byte
)(
g
.
currentwhite
&
WHITEBITS
);
}
public
static
void
luaC_checkGC
(
lua_State
L
)
{
//condhardstacktests(luaD_reallocstack(L, L.stacksize - EXTRA_STACK - 1));
//luaD_reallocstack(L, L.stacksize - EXTRA_STACK - 1);
if
(
G
(
L
).
totalbytes
>=
G
(
L
).
GCthreshold
)
luaC_step
(
L
);
}
public
static
void
luaC_barrier
(
lua_State
L
,
object
p
,
TValue
v
)
{
if
(
valiswhite
(
v
)
&&
isblack
(
obj2gco
(
p
)))
luaC_barrierf
(
L
,
obj2gco
(
p
),
gcvalue
(
v
));
}
public
static
void
luaC_barriert
(
lua_State
L
,
Table
t
,
TValue
v
)
{
if
(
valiswhite
(
v
)
&&
isblack
(
obj2gco
(
t
)))
luaC_barrierback
(
L
,
t
);
}
public
static
void
luaC_objbarrier
(
lua_State
L
,
object
p
,
object
o
)
{
if
(
iswhite
(
obj2gco
(
o
))
&&
isblack
(
obj2gco
(
p
)))
luaC_barrierf
(
L
,
obj2gco
(
p
),
obj2gco
(
o
));
}
public
static
void
luaC_objbarriert
(
lua_State
L
,
Table
t
,
object
o
)
{
if
(
iswhite
(
obj2gco
(
o
))
&&
isblack
(
obj2gco
(
t
)))
luaC_barrierback
(
L
,
t
);
}
[
CLSCompliantAttribute
(
false
)]
public
const
uint
GCSTEPSIZE
=
1024
;
public
const
int
GCSWEEPMAX
=
40
;
public
const
int
GCSWEEPCOST
=
10
;
public
const
int
GCFINALIZECOST
=
100
;
public
static
byte
maskmarks
=
(
byte
)(~(
bitmask
(
BLACKBIT
)|
WHITEBITS
));
public
static
void
makewhite
(
global_State
g
,
GCObject
x
)
{
x
.
gch
.
marked
=
(
byte
)(
x
.
gch
.
marked
&
maskmarks
|
luaC_white
(
g
));
}
public
static
void
white2gray
(
GCObject
x
)
{
reset2bits
(
ref
x
.
gch
.
marked
,
WHITE0BIT
,
WHITE1BIT
);
}
public
static
void
black2gray
(
GCObject
x
)
{
resetbit
(
ref
x
.
gch
.
marked
,
BLACKBIT
);
}
public
static
void
stringmark
(
TString
s
)
{
reset2bits
(
ref
s
.
tsv
.
marked
,
WHITE0BIT
,
WHITE1BIT
);}
public
static
bool
isfinalized
(
Udata_uv
u
)
{
return
testbit
(
u
.
marked
,
FINALIZEDBIT
);
}
public
static
void
markfinalized
(
Udata_uv
u
)
{
lu_byte
marked
=
u
.
marked
;
// can't pass properties in as ref
l_setbit
(
ref
marked
,
FINALIZEDBIT
);
u
.
marked
=
marked
;
}
public
static
int
KEYWEAK
=
bitmask
(
KEYWEAKBIT
);
public
static
int
VALUEWEAK
=
bitmask
(
VALUEWEAKBIT
);
public
static
void
markvalue
(
global_State
g
,
TValue
o
)
{
checkconsistency
(
o
);
if
(
iscollectable
(
o
)
&&
iswhite
(
gcvalue
(
o
)))
reallymarkobject
(
g
,
gcvalue
(
o
));
}
public
static
void
markobject
(
global_State
g
,
object
t
)
{
if
(
iswhite
(
obj2gco
(
t
)))
reallymarkobject
(
g
,
obj2gco
(
t
));
}
public
static
void
setthreshold
(
global_State
g
)
{
g
.
GCthreshold
=
(
uint
)((
g
.
estimate
/
100
)
*
g
.
gcpause
);
}
private
static
void
removeentry
(
Node
n
)
{
lua_assert
(
ttisnil
(
gval
(
n
)));
if
(
iscollectable
(
gkey
(
n
)))
setttype
(
gkey
(
n
),
LUA_TDEADKEY
);
/* dead key; remove it */
}
private
static
void
reallymarkobject
(
global_State
g
,
GCObject
o
)
{
lua_assert
(
iswhite
(
o
)
&&
!
isdead
(
g
,
o
));
white2gray
(
o
);
switch
(
o
.
gch
.
tt
)
{
case
LUA_TSTRING
:
{
return
;
}
case
LUA_TUSERDATA
:
{
Table
mt
=
gco2u
(
o
).
metatable
;
gray2black
(
o
);
/* udata are never gray */
if
(
mt
!=
null
)
markobject
(
g
,
mt
);
markobject
(
g
,
gco2u
(
o
).
env
);
return
;
}
case
LUA_TUPVAL
:
{
UpVal
uv
=
gco2uv
(
o
);
markvalue
(
g
,
uv
.
v
);
if
(
uv
.
v
==
uv
.
u
.
value
)
/* closed? */
gray2black
(
o
);
/* open upvalues are never black */
return
;
}
case
LUA_TFUNCTION
:
{
gco2cl
(
o
).
c
.
gclist
=
g
.
gray
;
g
.
gray
=
o
;
break
;
}
case
LUA_TTABLE
:
{
gco2h
(
o
).
gclist
=
g
.
gray
;
g
.
gray
=
o
;
break
;
}
case
LUA_TTHREAD
:
{
gco2th
(
o
).
gclist
=
g
.
gray
;
g
.
gray
=
o
;
break
;
}
case
LUA_TPROTO
:
{
gco2p
(
o
).
gclist
=
g
.
gray
;
g
.
gray
=
o
;
break
;
}
default
:
lua_assert
(
0
);
break
;
}
}
private
static
void
marktmu
(
global_State
g
)
{
GCObject
u
=
g
.
tmudata
;
if
(
u
!=
null
)
{
do
{
u
=
u
.
gch
.
next
;
makewhite
(
g
,
u
);
/* may be marked, if left from previous GC */
reallymarkobject
(
g
,
u
);
}
while
(
u
!=
g
.
tmudata
);
}
}
/* move `dead' udata that need finalization to list `tmudata' */
[
CLSCompliantAttribute
(
false
)]
public
static
uint
luaC_separateudata
(
lua_State
L
,
int
all
)
{
global_State
g
=
G
(
L
);
uint
deadmem
=
0
;
GCObjectRef
p
=
new
NextRef
(
g
.
mainthread
);
GCObject
curr
;
while
((
curr
=
p
.
get
())
!=
null
)
{
if
(!(
iswhite
(
curr
)
||
(
all
!=
0
))
||
isfinalized
(
gco2u
(
curr
)))
p
=
new
NextRef
(
curr
.
gch
);
/* don't bother with them */
else
if
(
fasttm
(
L
,
gco2u
(
curr
).
metatable
,
TMS
.
TM_GC
)
==
null
)
{
markfinalized
(
gco2u
(
curr
));
/* don't need finalization */
p
=
new
NextRef
(
curr
.
gch
);
}
else
{
/* must call its gc method */
deadmem
+=
(
uint
)
sizeudata
(
gco2u
(
curr
));
markfinalized
(
gco2u
(
curr
));
p
.
set
(
curr
.
gch
.
next
);
/* link `curr' at the end of `tmudata' list */
if
(
g
.
tmudata
==
null
)
/* list is empty? */
g
.
tmudata
=
curr
.
gch
.
next
=
curr
;
/* creates a circular list */
else
{
curr
.
gch
.
next
=
g
.
tmudata
.
gch
.
next
;
g
.
tmudata
.
gch
.
next
=
curr
;
g
.
tmudata
=
curr
;
}
}
}
return
deadmem
;
}
private
static
int
traversetable
(
global_State
g
,
Table
h
)
{
int
i
;
int
weakkey
=
0
;
int
weakvalue
=
0
;
/*const*/
TValue
mode
;
if
(
h
.
metatable
!=
null
)
markobject
(
g
,
h
.
metatable
);
mode
=
gfasttm
(
g
,
h
.
metatable
,
TMS
.
TM_MODE
);
if
((
mode
!=
null
)
&&
ttisstring
(
mode
))
{
/* is there a weak mode? */
weakkey
=
(
strchr
(
svalue
(
mode
),
'k'
)
!=
null
)
?
1
:
0
;
weakvalue
=
(
strchr
(
svalue
(
mode
),
'v'
)
!=
null
)
?
1
:
0
;
if
((
weakkey
!=
0
)
||
(
weakvalue
!=
0
))
{
/* is really weak? */
h
.
marked
&=
(
byte
)~(
KEYWEAK
|
VALUEWEAK
);
/* clear bits */
h
.
marked
|=
cast_byte
((
weakkey
<<
KEYWEAKBIT
)
|
(
weakvalue
<<
VALUEWEAKBIT
));
h
.
gclist
=
g
.
weak
;
/* must be cleared after GC, ... */
g
.
weak
=
obj2gco
(
h
);
/* ... so put in the appropriate list */
}
}
if
((
weakkey
!=
0
)
&&
(
weakvalue
!=
0
))
return
1
;
if
(
weakvalue
==
0
)
{
i
=
h
.
sizearray
;
while
((
i
--)
!=
0
)
markvalue
(
g
,
h
.
array
[
i
]);
}
i
=
sizenode
(
h
);
while
((
i
--)
!=
0
)
{
Node
n
=
gnode
(
h
,
i
);
lua_assert
(
ttype
(
gkey
(
n
))
!=
LUA_TDEADKEY
||
ttisnil
(
gval
(
n
)));
if
(
ttisnil
(
gval
(
n
)))
removeentry
(
n
);
/* remove empty entries */
else
{
lua_assert
(!
ttisnil
(
gkey
(
n
)));
if
(
weakkey
==
0
)
markvalue
(
g
,
gkey
(
n
));
if
(
weakvalue
==
0
)
markvalue
(
g
,
gval
(
n
));
}
}
return
((
weakkey
!=
0
)
||
(
weakvalue
!=
0
))
?
1
:
0
;
}
/*
** All marks are conditional because a GC may happen while the
** prototype is still being created
*/
private
static
void
traverseproto
(
global_State
g
,
Proto
f
)
{
int
i
;
if
(
f
.
source
!=
null
)
stringmark
(
f
.
source
);
for
(
i
=
0
;
i
<
f
.
sizek
;
i
++)
/* mark literals */
markvalue
(
g
,
f
.
k
[
i
]);
for
(
i
=
0
;
i
<
f
.
sizeupvalues
;
i
++)
{
/* mark upvalue names */
if
(
f
.
upvalues
[
i
]
!=
null
)
stringmark
(
f
.
upvalues
[
i
]);
}
for
(
i
=
0
;
i
<
f
.
sizep
;
i
++)
{
/* mark nested protos */
if
(
f
.
p
[
i
]
!=
null
)
markobject
(
g
,
f
.
p
[
i
]);
}
for
(
i
=
0
;
i
<
f
.
sizelocvars
;
i
++)
{
/* mark local-variable names */
if
(
f
.
locvars
[
i
].
varname
!=
null
)
stringmark
(
f
.
locvars
[
i
].
varname
);
}
}
private
static
void
traverseclosure
(
global_State
g
,
Closure
cl
)
{
markobject
(
g
,
cl
.
c
.
env
);
if
(
cl
.
c
.
isC
!=
0
)
{
int
i
;
for
(
i
=
0
;
i
<
cl
.
c
.
nupvalues
;
i
++)
/* mark its upvalues */
markvalue
(
g
,
cl
.
c
.
upvalue
[
i
]);
}
else
{
int
i
;
lua_assert
(
cl
.
l
.
nupvalues
==
cl
.
l
.
p
.
nups
);
markobject
(
g
,
cl
.
l
.
p
);
for
(
i
=
0
;
i
<
cl
.
l
.
nupvalues
;
i
++)
/* mark its upvalues */
markobject
(
g
,
cl
.
l
.
upvals
[
i
]);
}
}
private
static
void
checkstacksizes
(
lua_State
L
,
StkId
max
)
{
int
ci_used
=
cast_int
(
L
.
ci
-
L
.
base_ci
[
0
]);
/* number of `ci' in use */
int
s_used
=
cast_int
(
max
-
L
.
stack
);
/* part of stack in use */
if
(
L
.
size_ci
>
LUAI_MAXCALLS
)
/* handling overflow? */
return
;
/* do not touch the stacks */
if
(
4
*
ci_used
<
L
.
size_ci
&&
2
*
BASIC_CI_SIZE
<
L
.
size_ci
)
luaD_reallocCI
(
L
,
L
.
size_ci
/
2
);
/* still big enough... */
//condhardstacktests(luaD_reallocCI(L, ci_used + 1));
if
(
4
*
s_used
<
L
.
stacksize
&&
2
*(
BASIC_STACK_SIZE
+
EXTRA_STACK
)
<
L
.
stacksize
)
luaD_reallocstack
(
L
,
L
.
stacksize
/
2
);
/* still big enough... */
//condhardstacktests(luaD_reallocstack(L, s_used));
}
private
static
void
traversestack
(
global_State
g
,
lua_State
l
)
{
StkId
o
,
lim
;
CallInfo
ci
;
markvalue
(
g
,
gt
(
l
));
lim
=
l
.
top
;
for
(
ci
=
l
.
base_ci
[
0
];
ci
<=
l
.
ci
;
CallInfo
.
inc
(
ref
ci
))
{
lua_assert
(
ci
.
top
<=
l
.
stack_last
);
if
(
lim
<
ci
.
top
)
lim
=
ci
.
top
;
}
for
(
o
=
l
.
stack
[
0
];
o
<
l
.
top
;
StkId
.
inc
(
ref
o
))
markvalue
(
g
,
o
);
for
(;
o
<=
lim
;
StkId
.
inc
(
ref
o
))
setnilvalue
(
o
);
checkstacksizes
(
l
,
lim
);
}
/*
** traverse one gray object, turning it to black.
** Returns `quantity' traversed.
*/
private
static
l_mem
propagatemark
(
global_State
g
)
{
GCObject
o
=
g
.
gray
;
lua_assert
(
isgray
(
o
));
gray2black
(
o
);
switch
(
o
.
gch
.
tt
)
{
case
LUA_TTABLE
:
{
Table
h
=
gco2h
(
o
);
g
.
gray
=
h
.
gclist
;
if
(
traversetable
(
g
,
h
)
!=
0
)
/* table is weak? */
black2gray
(
o
);
/* keep it gray */
return
GetUnmanagedSize
(
typeof
(
Table
))
+
GetUnmanagedSize
(
typeof
(
TValue
))
*
h
.
sizearray
+
GetUnmanagedSize
(
typeof
(
Node
))
*
sizenode
(
h
);
}
case
LUA_TFUNCTION
:
{
Closure
cl
=
gco2cl
(
o
);
g
.
gray
=
cl
.
c
.
gclist
;
traverseclosure
(
g
,
cl
);
return
(
cl
.
c
.
isC
!=
0
)
?
sizeCclosure
(
cl
.
c
.
nupvalues
)
:
sizeLclosure
(
cl
.
l
.
nupvalues
);
}
case
LUA_TTHREAD
:
{
lua_State
th
=
gco2th
(
o
);
g
.
gray
=
th
.
gclist
;
th
.
gclist
=
g
.
grayagain
;
g
.
grayagain
=
o
;
black2gray
(
o
);
traversestack
(
g
,
th
);
return
GetUnmanagedSize
(
typeof
(
lua_State
))
+
GetUnmanagedSize
(
typeof
(
TValue
))
*
th
.
stacksize
+
GetUnmanagedSize
(
typeof
(
CallInfo
))
*
th
.
size_ci
;
}
case
LUA_TPROTO
:
{
Proto
p
=
gco2p
(
o
);
g
.
gray
=
p
.
gclist
;
traverseproto
(
g
,
p
);
return
GetUnmanagedSize
(
typeof
(
Proto
))
+
GetUnmanagedSize
(
typeof
(
Instruction
))
*
p
.
sizecode
+
GetUnmanagedSize
(
typeof
(
Proto
))
*
p
.
sizep
+
GetUnmanagedSize
(
typeof
(
TValue
))
*
p
.
sizek
+
GetUnmanagedSize
(
typeof
(
int
))
*
p
.
sizelineinfo
+
GetUnmanagedSize
(
typeof
(
LocVar
))
*
p
.
sizelocvars
+
GetUnmanagedSize
(
typeof
(
TString
))
*
p
.
sizeupvalues
;
}
default
:
lua_assert
(
0
);
return
0
;
}
}
private
static
uint
propagateall
(
global_State
g
)
{
uint
m
=
0
;
while
(
g
.
gray
!=
null
)
m
+=
(
uint
)
propagatemark
(
g
);
return
m
;
}
/*
** The next function tells whether a key or value can be cleared from
** a weak table. Non-collectable objects are never removed from weak
** tables. Strings behave as `values', so are never removed too. for
** other objects: if really collected, cannot keep them; for userdata
** being finalized, keep them in keys, but not in values
*/
private
static
bool
iscleared
(
TValue
o
,
bool
iskey
)
{
if
(!
iscollectable
(
o
))
return
false
;
if
(
ttisstring
(
o
))
{
stringmark
(
rawtsvalue
(
o
));
/* strings are `values', so are never weak */
return
false
;
}
return
iswhite
(
gcvalue
(
o
))
||
(
ttisuserdata
(
o
)
&&
(!
iskey
&&
isfinalized
(
uvalue
(
o
))));
}
/*
** clear collected entries from weaktables
*/
private
static
void
cleartable
(
GCObject
l
)
{
while
(
l
!=
null
)
{
Table
h
=
gco2h
(
l
);
int
i
=
h
.
sizearray
;
lua_assert
(
testbit
(
h
.
marked
,
VALUEWEAKBIT
)
||
testbit
(
h
.
marked
,
KEYWEAKBIT
));
if
(
testbit
(
h
.
marked
,
VALUEWEAKBIT
))
{
while
(
i
--!=
0
)
{
TValue
o
=
h
.
array
[
i
];
if
(
iscleared
(
o
,
false
))
/* value was collected? */
setnilvalue
(
o
);
/* remove value */
}
}
i
=
sizenode
(
h
);
while
(
i
--
!=
0
)
{
Node
n
=
gnode
(
h
,
i
);
if
(!
ttisnil
(
gval
(
n
))
&&
/* non-empty entry? */
(
iscleared
(
key2tval
(
n
),
true
)
||
iscleared
(
gval
(
n
),
false
)))
{
setnilvalue
(
gval
(
n
));
/* remove value ... */
removeentry
(
n
);
/* remove entry from Table */
}
}
l
=
h
.
gclist
;
}
}
private
static
void
freeobj
(
lua_State
L
,
GCObject
o
)
{
switch
(
o
.
gch
.
tt
)
{
case
LUA_TPROTO
:
luaF_freeproto
(
L
,
gco2p
(
o
));
break
;
case
LUA_TFUNCTION
:
luaF_freeclosure
(
L
,
gco2cl
(
o
));
break
;
case
LUA_TUPVAL
:
luaF_freeupval
(
L
,
gco2uv
(
o
));
break
;
case
LUA_TTABLE
:
luaH_free
(
L
,
gco2h
(
o
));
break
;
case
LUA_TTHREAD
:
{
lua_assert
(
gco2th
(
o
)
!=
L
&&
gco2th
(
o
)
!=
G
(
L
).
mainthread
);
luaE_freethread
(
L
,
gco2th
(
o
));
break
;
}
case
LUA_TSTRING
:
{
G
(
L
).
strt
.
nuse
--;
SubtractTotalBytes
(
L
,
sizestring
(
gco2ts
(
o
)));
luaM_freemem
(
L
,
gco2ts
(
o
));
break
;
}
case
LUA_TUSERDATA
:
{
SubtractTotalBytes
(
L
,
sizeudata
(
gco2u
(
o
)));
luaM_freemem
(
L
,
gco2u
(
o
));
break
;
}
default
:
lua_assert
(
0
);
break
;
}
}
public
static
void
sweepwholelist
(
lua_State
L
,
GCObjectRef
p
)
{
sweeplist
(
L
,
p
,
MAX_LUMEM
);
}
private
static
GCObjectRef
sweeplist
(
lua_State
L
,
GCObjectRef
p
,
lu_mem
count
)
{
GCObject
curr
;
global_State
g
=
G
(
L
);
int
deadmask
=
otherwhite
(
g
);
while
((
curr
=
p
.
get
())
!=
null
&&
count
--
>
0
)
{
if
(
curr
.
gch
.
tt
==
LUA_TTHREAD
)
/* sweep open upvalues of each thread */
sweepwholelist
(
L
,
new
OpenValRef
(
gco2th
(
curr
)
));
if
(((
curr
.
gch
.
marked
^
WHITEBITS
)
&
deadmask
)
!=
0
)
{
/* not dead? */
lua_assert
(!
isdead
(
g
,
curr
)
||
testbit
(
curr
.
gch
.
marked
,
FIXEDBIT
));
makewhite
(
g
,
curr
);
/* make it white (for next cycle) */
p
=
new
NextRef
(
curr
.
gch
);
}
else
{
/* must erase `curr' */
lua_assert
(
isdead
(
g
,
curr
)
||
deadmask
==
bitmask
(
SFIXEDBIT
));
p
.
set
(
curr
.
gch
.
next
);
if
(
curr
==
g
.
rootgc
)
/* is the first element of the list? */
g
.
rootgc
=
curr
.
gch
.
next
;
/* adjust first */
freeobj
(
L
,
curr
);
}
}
return
p
;
}
private
static
void
checkSizes
(
lua_State
L
)
{
global_State
g
=
G
(
L
);
/* check size of string hash */
if
(
g
.
strt
.
nuse
<
(
lu_int32
)(
g
.
strt
.
size
/
4
)
&&
g
.
strt
.
size
>
MINSTRTABSIZE
*
2
)
luaS_resize
(
L
,
g
.
strt
.
size
/
2
);
/* table is too big */
/* check size of buffer */
if
(
luaZ_sizebuffer
(
g
.
buff
)
>
LUA_MINBUFFER
*
2
)
{
/* buffer too big? */
uint
newsize
=
luaZ_sizebuffer
(
g
.
buff
)
/
2
;
luaZ_resizebuffer
(
L
,
g
.
buff
,
(
int
)
newsize
);
}
}
private
static
void
GCTM
(
lua_State
L
)
{
global_State
g
=
G
(
L
);
GCObject
o
=
g
.
tmudata
.
gch
.
next
;
/* get first element */
Udata
udata
=
rawgco2u
(
o
);
TValue
tm
;
/* remove udata from `tmudata' */
if
(
o
==
g
.
tmudata
)
/* last element? */
g
.
tmudata
=
null
;
else
g
.
tmudata
.
gch
.
next
=
udata
.
uv
.
next
;
udata
.
uv
.
next
=
g
.
mainthread
.
next
;
/* return it to `root' list */
g
.
mainthread
.
next
=
o
;
makewhite
(
g
,
o
);
tm
=
fasttm
(
L
,
udata
.
uv
.
metatable
,
TMS
.
TM_GC
);
if
(
tm
!=
null
)
{
lu_byte
oldah
=
L
.
allowhook
;
lu_mem
oldt
=
(
lu_mem
)
g
.
GCthreshold
;
L
.
allowhook
=
0
;
/* stop debug hooks during GC tag method */
g
.
GCthreshold
=
2
*
g
.
totalbytes
;
/* avoid GC steps */
setobj2s
(
L
,
L
.
top
,
tm
);
setuvalue
(
L
,
L
.
top
+
1
,
udata
);
L
.
top
+=
2
;
luaD_call
(
L
,
L
.
top
-
2
,
0
);
L
.
allowhook
=
oldah
;
/* restore hooks */
g
.
GCthreshold
=
(
uint
)
oldt
;
/* restore threshold */
}
}
/*
** Call all GC tag methods
*/
public
static
void
luaC_callGCTM
(
lua_State
L
)
{
while
(
G
(
L
).
tmudata
!=
null
)
GCTM
(
L
);
}
public
static
void
luaC_freeall
(
lua_State
L
)
{
global_State
g
=
G
(
L
);
int
i
;
g
.
currentwhite
=
(
byte
)(
WHITEBITS
|
bitmask
(
SFIXEDBIT
));
/* mask to collect all elements */
sweepwholelist
(
L
,
new
RootGCRef
(
g
));
for
(
i
=
0
;
i
<
g
.
strt
.
size
;
i
++)
/* free all string lists */
sweepwholelist
(
L
,
new
ArrayRef
(
g
.
strt
.
hash
,
i
));
}
private
static
void
markmt
(
global_State
g
)
{
int
i
;
for
(
i
=
0
;
i
<
NUM_TAGS
;
i
++)
if
(
g
.
mt
[
i
]
!=
null
)
markobject
(
g
,
g
.
mt
[
i
]);
}
/* mark root set */
private
static
void
markroot
(
lua_State
L
)
{
global_State
g
=
G
(
L
);
g
.
gray
=
null
;
g
.
grayagain
=
null
;
g
.
weak
=
null
;
markobject
(
g
,
g
.
mainthread
);
/* make global table be traversed before main stack */
markvalue
(
g
,
gt
(
g
.
mainthread
));
markvalue
(
g
,
registry
(
L
));
markmt
(
g
);
g
.
gcstate
=
GCSpropagate
;
}
private
static
void
remarkupvals
(
global_State
g
)
{
UpVal
uv
;
for
(
uv
=
g
.
uvhead
.
u
.
l
.
next
;
uv
!=
g
.
uvhead
;
uv
=
uv
.
u
.
l
.
next
)
{
lua_assert
(
uv
.
u
.
l
.
next
.
u
.
l
.
prev
==
uv
&&
uv
.
u
.
l
.
prev
.
u
.
l
.
next
==
uv
);
if
(
isgray
(
obj2gco
(
uv
)))
markvalue
(
g
,
uv
.
v
);
}
}
private
static
void
atomic
(
lua_State
L
)
{
global_State
g
=
G
(
L
);
uint
udsize
;
/* total size of userdata to be finalized */
/* remark occasional upvalues of (maybe) dead threads */
remarkupvals
(
g
);
/* traverse objects cautch by write barrier and by 'remarkupvals' */
propagateall
(
g
);
/* remark weak tables */
g
.
gray
=
g
.
weak
;
g
.
weak
=
null
;
lua_assert
(!
iswhite
(
obj2gco
(
g
.
mainthread
)));
markobject
(
g
,
L
);
/* mark running thread */
markmt
(
g
);
/* mark basic metatables (again) */
propagateall
(
g
);
/* remark gray again */
g
.
gray
=
g
.
grayagain
;
g
.
grayagain
=
null
;
propagateall
(
g
);
udsize
=
luaC_separateudata
(
L
,
0
);
/* separate userdata to be finalized */
marktmu
(
g
);
/* mark `preserved' userdata */
udsize
+=
propagateall
(
g
);
/* remark, to propagate `preserveness' */
cleartable
(
g
.
weak
);
/* remove collected objects from weak tables */
/* flip current white */
g
.
currentwhite
=
cast_byte
(
otherwhite
(
g
));
g
.
sweepstrgc
=
0
;
g
.
sweepgc
=
new
RootGCRef
(
g
);
g
.
gcstate
=
GCSsweepstring
;
g
.
estimate
=
g
.
totalbytes
-
udsize
;
/* first estimate */
}
private
static
l_mem
singlestep
(
lua_State
L
)
{
global_State
g
=
G
(
L
);
/*lua_checkmemory(L);*/
switch
(
g
.
gcstate
)
{
case
GCSpause
:
{
markroot
(
L
);
/* start a new collection */
return
0
;
}
case
GCSpropagate
:
{
if
(
g
.
gray
!=
null
)
return
propagatemark
(
g
);
else
{
/* no more `gray' objects */
atomic
(
L
);
/* finish mark phase */
return
0
;
}
}
case
GCSsweepstring
:
{
lu_mem
old
=
(
lu_mem
)
g
.
totalbytes
;
sweepwholelist
(
L
,
new
ArrayRef
(
g
.
strt
.
hash
,
g
.
sweepstrgc
++));
if
(
g
.
sweepstrgc
>=
g
.
strt
.
size
)
/* nothing more to sweep? */
g
.
gcstate
=
GCSsweep
;
/* end sweep-string phase */
lua_assert
(
old
>=
g
.
totalbytes
);
g
.
estimate
-=
(
uint
)(
old
-
g
.
totalbytes
);
return
GCSWEEPCOST
;
}
case
GCSsweep
:
{
lu_mem
old
=
(
lu_mem
)
g
.
totalbytes
;
g
.
sweepgc
=
sweeplist
(
L
,
g
.
sweepgc
,
GCSWEEPMAX
);
if
(
g
.
sweepgc
.
get
()
==
null
)
{
/* nothing more to sweep? */
checkSizes
(
L
);
g
.
gcstate
=
GCSfinalize
;
/* end sweep phase */
}
lua_assert
(
old
>=
g
.
totalbytes
);
g
.
estimate
-=
(
uint
)(
old
-
g
.
totalbytes
);
return
GCSWEEPMAX
*
GCSWEEPCOST
;
}
case
GCSfinalize
:
{
if
(
g
.
tmudata
!=
null
)
{
GCTM
(
L
);
if
(
g
.
estimate
>
GCFINALIZECOST
)
g
.
estimate
-=
GCFINALIZECOST
;
return
GCFINALIZECOST
;
}
else
{
g
.
gcstate
=
GCSpause
;
/* end collection */
g
.
gcdept
=
0
;
return
0
;
}
}
default
:
lua_assert
(
0
);
return
0
;
}
}
public
static
void
luaC_step
(
lua_State
L
)
{
global_State
g
=
G
(
L
);
l_mem
lim
=
(
l_mem
)((
GCSTEPSIZE
/
100
)
*
g
.
gcstepmul
);
if
(
lim
==
0
)
lim
=
(
l_mem
)((
MAX_LUMEM
-
1
)/
2
);
/* no limit */
g
.
gcdept
+=
g
.
totalbytes
-
g
.
GCthreshold
;
do
{
lim
-=
singlestep
(
L
);
if
(
g
.
gcstate
==
GCSpause
)
break
;
}
while
(
lim
>
0
);
if
(
g
.
gcstate
!=
GCSpause
)
{
if
(
g
.
gcdept
<
GCSTEPSIZE
)
g
.
GCthreshold
=
g
.
totalbytes
+
GCSTEPSIZE
;
/* - lim/g.gcstepmul;*/
else
{
g
.
gcdept
-=
GCSTEPSIZE
;
g
.
GCthreshold
=
g
.
totalbytes
;
}
}
else
{
lua_assert
(
g
.
totalbytes
>=
g
.
estimate
);
setthreshold
(
g
);
}
}
public
static
void
luaC_fullgc
(
lua_State
L
)
{
global_State
g
=
G
(
L
);
if
(
g
.
gcstate
<=
GCSpropagate
)
{
/* reset sweep marks to sweep all elements (returning them to white) */
g
.
sweepstrgc
=
0
;
g
.
sweepgc
=
new
RootGCRef
(
g
);
/* reset other collector lists */
g
.
gray
=
null
;
g
.
grayagain
=
null
;
g
.
weak
=
null
;
g
.
gcstate
=
GCSsweepstring
;
}
lua_assert
(
g
.
gcstate
!=
GCSpause
&&
g
.
gcstate
!=
GCSpropagate
);
/* finish any pending sweep phase */
while
(
g
.
gcstate
!=
GCSfinalize
)
{
lua_assert
(
g
.
gcstate
==
GCSsweepstring
||
g
.
gcstate
==
GCSsweep
);
singlestep
(
L
);
}
markroot
(
L
);
while
(
g
.
gcstate
!=
GCSpause
)
{
singlestep
(
L
);
}
setthreshold
(
g
);
}
public
static
void
luaC_barrierf
(
lua_State
L
,
GCObject
o
,
GCObject
v
)
{
global_State
g
=
G
(
L
);
lua_assert
(
isblack
(
o
)
&&
iswhite
(
v
)
&&
!
isdead
(
g
,
v
)
&&
!
isdead
(
g
,
o
));
lua_assert
(
g
.
gcstate
!=
GCSfinalize
&&
g
.
gcstate
!=
GCSpause
);
lua_assert
(
ttype
(
o
.
gch
)
!=
LUA_TTABLE
);
/* must keep invariant? */
if
(
g
.
gcstate
==
GCSpropagate
)
reallymarkobject
(
g
,
v
);
/* restore invariant */
else
/* don't mind */
makewhite
(
g
,
o
);
/* mark as white just to avoid other barriers */
}
public
static
void
luaC_barrierback
(
lua_State
L
,
Table
t
)
{
global_State
g
=
G
(
L
);
GCObject
o
=
obj2gco
(
t
);
lua_assert
(
isblack
(
o
)
&&
!
isdead
(
g
,
o
));
lua_assert
(
g
.
gcstate
!=
GCSfinalize
&&
g
.
gcstate
!=
GCSpause
);
black2gray
(
o
);
/* make table gray (again) */
t
.
gclist
=
g
.
grayagain
;
g
.
grayagain
=
o
;
}
public
static
void
luaC_link
(
lua_State
L
,
GCObject
o
,
lu_byte
tt
)
{
global_State
g
=
G
(
L
);
o
.
gch
.
next
=
g
.
rootgc
;
g
.
rootgc
=
o
;
o
.
gch
.
marked
=
luaC_white
(
g
);
o
.
gch
.
tt
=
tt
;
}
public
static
void
luaC_linkupval
(
lua_State
L
,
UpVal
uv
)
{
global_State
g
=
G
(
L
);
GCObject
o
=
obj2gco
(
uv
);
o
.
gch
.
next
=
g
.
rootgc
;
/* link upvalue into `rootgc' list */
g
.
rootgc
=
o
;
if
(
isgray
(
o
))
{
if
(
g
.
gcstate
==
GCSpropagate
)
{
gray2black
(
o
);
/* closed upvalues need barrier */
luaC_barrier
(
L
,
uv
,
uv
.
v
);
}
else
{
/* sweep phase: sweep it (turning it into white) */
makewhite
(
g
,
o
);
lua_assert
(
g
.
gcstate
!=
GCSfinalize
&&
g
.
gcstate
!=
GCSpause
);
}
}
}
}
}
Core/KopiLua/linit.cs
deleted
100644 → 0
View file @
8d677060
/*
** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $
** Initialization of libraries for lua.c
** See Copyright Notice in lua.h
*/
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
namespace
KopiLua
{
public
partial
class
Lua
{
private
readonly
static
luaL_Reg
[]
lualibs
=
{
new
luaL_Reg
(
""
,
luaopen_base
),
new
luaL_Reg
(
LUA_LOADLIBNAME
,
luaopen_package
),
new
luaL_Reg
(
LUA_TABLIBNAME
,
luaopen_table
),
new
luaL_Reg
(
LUA_IOLIBNAME
,
luaopen_io
),
new
luaL_Reg
(
LUA_OSLIBNAME
,
luaopen_os
),
new
luaL_Reg
(
LUA_STRLIBNAME
,
luaopen_string
),
new
luaL_Reg
(
LUA_MATHLIBNAME
,
luaopen_math
),
new
luaL_Reg
(
LUA_DBLIBNAME
,
luaopen_debug
),
new
luaL_Reg
(
null
,
null
)
};
public
static
void
luaL_openlibs
(
lua_State
L
)
{
for
(
int
i
=
0
;
i
<
lualibs
.
Length
-
1
;
i
++)
{
luaL_Reg
lib
=
lualibs
[
i
];
lua_pushcfunction
(
L
,
lib
.
func
);
lua_pushstring
(
L
,
lib
.
name
);
lua_call
(
L
,
1
,
0
);
}
}
}
}
Core/KopiLua/liolib.cs
deleted
100644 → 0
View file @
8d677060
/*
** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
using
System
;
using
System.IO
;
using
System.Collections.Generic
;
using
System.Text
;
using
System.Runtime.InteropServices
;
namespace
KopiLua
{
using
lua_Number
=
System
.
Double
;
using
lua_Integer
=
System
.
Int32
;
public
class
FilePtr
{
public
Stream
file
;
}
public
partial
class
Lua
{
public
const
int
IO_INPUT
=
1
;
public
const
int
IO_OUTPUT
=
2
;
private
static
readonly
string
[]
fnames
=
{
"input"
,
"output"
};
private
static
int
pushresult
(
lua_State
L
,
int
i
,
CharPtr
filename
)
{
int
en
=
errno
();
/* calls to Lua API may change this value */
if
(
i
!=
0
)
{
lua_pushboolean
(
L
,
1
);
return
1
;
}
else
{
lua_pushnil
(
L
);
if
(
filename
!=
null
)
lua_pushfstring
(
L
,
"%s: %s"
,
filename
,
strerror
(
en
));
else
lua_pushfstring
(
L
,
"%s"
,
strerror
(
en
));
lua_pushinteger
(
L
,
en
);
return
3
;
}
}
private
static
void
fileerror
(
lua_State
L
,
int
arg
,
CharPtr
filename
)
{
lua_pushfstring
(
L
,
"%s: %s"
,
filename
,
strerror
(
errno
()));
luaL_argerror
(
L
,
arg
,
lua_tostring
(
L
,
-
1
));
}
public
static
FilePtr
tofilep
(
lua_State
L
)
{
return
(
FilePtr
)
luaL_checkudata
(
L
,
1
,
LUA_FILEHANDLE
);
}
private
static
int
io_type
(
lua_State
L
)
{
object
ud
;
luaL_checkany
(
L
,
1
);
ud
=
lua_touserdata
(
L
,
1
);
lua_getfield
(
L
,
LUA_REGISTRYINDEX
,
LUA_FILEHANDLE
);
if
(
ud
==
null
||
(
lua_getmetatable
(
L
,
1
)==
0
)
||
(
lua_rawequal
(
L
,
-
2
,
-
1
)==
0
))
lua_pushnil
(
L
);
/* not a file */
else
if
(
(
ud
as
FilePtr
).
file
==
null
)
lua_pushliteral
(
L
,
"closed file"
);
else
lua_pushliteral
(
L
,
"file"
);
return
1
;
}
private
static
Stream
tofile
(
lua_State
L
)
{
FilePtr
f
=
tofilep
(
L
);
if
(
f
.
file
==
null
)
luaL_error
(
L
,
"attempt to use a closed file"
);
return
f
.
file
;
}
/*
** When creating file files, always creates a `closed' file file
** before opening the actual file; so, if there is a memory error, the
** file is not left opened.
*/
private
static
FilePtr
newfile
(
lua_State
L
)
{
FilePtr
pf
=
(
FilePtr
)
lua_newuserdata
(
L
,
typeof
(
FilePtr
));
pf
.
file
=
null
;
/* file file is currently `closed' */
luaL_getmetatable
(
L
,
LUA_FILEHANDLE
);
lua_setmetatable
(
L
,
-
2
);
return
pf
;
}
/*
** function to (not) close the standard files stdin, stdout, and stderr
*/
private
static
int
io_noclose
(
lua_State
L
)
{
lua_pushnil
(
L
);
lua_pushliteral
(
L
,
"cannot close standard file"
);
return
2
;
}
/*
** function to close 'popen' files
*/
private
static
int
io_pclose
(
lua_State
L
)
{
FilePtr
p
=
tofilep
(
L
);
int
ok
=
(
lua_pclose
(
L
,
p
.
file
)
==
0
)
?
1
:
0
;
p
.
file
=
null
;
return
pushresult
(
L
,
ok
,
null
);
}
/*
** function to close regular files
*/
private
static
int
io_fclose
(
lua_State
L
)
{
FilePtr
p
=
tofilep
(
L
);
int
ok
=
(
fclose
(
p
.
file
)
==
0
)
?
1
:
0
;
p
.
file
=
null
;
return
pushresult
(
L
,
ok
,
null
);
}
private
static
int
aux_close
(
lua_State
L
)
{
lua_getfenv
(
L
,
1
);
lua_getfield
(
L
,
-
1
,
"__close"
);
return
(
lua_tocfunction
(
L
,
-
1
))(
L
);
}
private
static
int
io_close
(
lua_State
L
)
{
if
(
lua_isnone
(
L
,
1
))
lua_rawgeti
(
L
,
LUA_ENVIRONINDEX
,
IO_OUTPUT
);
tofile
(
L
);
/* make sure argument is a file */
return
aux_close
(
L
);
}
private
static
int
io_gc
(
lua_State
L
)
{
Stream
f
=
tofilep
(
L
).
file
;
/* ignore closed files */
if
(
f
!=
null
)
aux_close
(
L
);
return
0
;
}
private
static
int
io_tostring
(
lua_State
L
)
{
Stream
f
=
tofilep
(
L
).
file
;
if
(
f
==
null
)
lua_pushliteral
(
L
,
"file (closed)"
);
else
lua_pushfstring
(
L
,
"file (%p)"
,
f
);
return
1
;
}
private
static
int
io_open
(
lua_State
L
)
{
CharPtr
filename
=
luaL_checkstring
(
L
,
1
);
CharPtr
mode
=
luaL_optstring
(
L
,
2
,
"r"
);
FilePtr
pf
=
newfile
(
L
);
pf
.
file
=
fopen
(
filename
,
mode
);
return
(
pf
.
file
==
null
)
?
pushresult
(
L
,
0
,
filename
)
:
1
;
}
/*
** this function has a separated environment, which defines the
** correct __close for 'popen' files
*/
private
static
int
io_popen
(
lua_State
L
)
{
CharPtr
filename
=
luaL_checkstring
(
L
,
1
);
CharPtr
mode
=
luaL_optstring
(
L
,
2
,
"r"
);
FilePtr
pf
=
newfile
(
L
);
pf
.
file
=
lua_popen
(
L
,
filename
,
mode
);
return
(
pf
.
file
==
null
)
?
pushresult
(
L
,
0
,
filename
)
:
1
;
}
private
static
int
io_tmpfile
(
lua_State
L
)
{
FilePtr
pf
=
newfile
(
L
);
#if XBOX
luaL_error
(
L
,
"io_tmpfile not supported on Xbox360"
);
#else
pf
.
file
=
tmpfile
();
#endif
return
(
pf
.
file
==
null
)
?
pushresult
(
L
,
0
,
null
)
:
1
;
}
private
static
Stream
getiofile
(
lua_State
L
,
int
findex
)
{
Stream
f
;
lua_rawgeti
(
L
,
LUA_ENVIRONINDEX
,
findex
);
f
=
(
lua_touserdata
(
L
,
-
1
)
as
FilePtr
).
file
;
if
(
f
==
null
)
luaL_error
(
L
,
"standard %s file is closed"
,
fnames
[
findex
-
1
]);
return
f
;
}
private
static
int
g_iofile
(
lua_State
L
,
int
f
,
CharPtr
mode
)
{
if
(!
lua_isnoneornil
(
L
,
1
))
{
CharPtr
filename
=
lua_tostring
(
L
,
1
);
if
(
filename
!=
null
)
{
FilePtr
pf
=
newfile
(
L
);
pf
.
file
=
fopen
(
filename
,
mode
);
if
(
pf
.
file
==
null
)
fileerror
(
L
,
1
,
filename
);
}
else
{
tofile
(
L
);
/* check that it's a valid file file */
lua_pushvalue
(
L
,
1
);
}
lua_rawseti
(
L
,
LUA_ENVIRONINDEX
,
f
);
}
/* return current value */
lua_rawgeti
(
L
,
LUA_ENVIRONINDEX
,
f
);
return
1
;
}
private
static
int
io_input
(
lua_State
L
)
{
return
g_iofile
(
L
,
IO_INPUT
,
"r"
);
}
private
static
int
io_output
(
lua_State
L
)
{
return
g_iofile
(
L
,
IO_OUTPUT
,
"w"
);
}
private
static
void
aux_lines
(
lua_State
L
,
int
idx
,
int
toclose
)
{
lua_pushvalue
(
L
,
idx
);
lua_pushboolean
(
L
,
toclose
);
/* close/not close file when finished */
lua_pushcclosure
(
L
,
io_readline
,
2
);
}
private
static
int
f_lines
(
lua_State
L
)
{
tofile
(
L
);
/* check that it's a valid file file */
aux_lines
(
L
,
1
,
0
);
return
1
;
}
private
static
int
io_lines
(
lua_State
L
)
{
if
(
lua_isnoneornil
(
L
,
1
))
{
/* no arguments? */
/* will iterate over default input */
lua_rawgeti
(
L
,
LUA_ENVIRONINDEX
,
IO_INPUT
);
return
f_lines
(
L
);
}
else
{
CharPtr
filename
=
luaL_checkstring
(
L
,
1
);
FilePtr
pf
=
newfile
(
L
);
pf
.
file
=
fopen
(
filename
,
"r"
);
if
(
pf
.
file
==
null
)
fileerror
(
L
,
1
,
filename
);
aux_lines
(
L
,
lua_gettop
(
L
),
1
);
return
1
;
}
}
/*
** {======================================================
** READ
** =======================================================
*/
private
static
int
read_number
(
lua_State
L
,
Stream
f
)
{
//lua_Number d;
object
[]
parms
=
{
(
object
)(
double
)
0.0
};
if
(
fscanf
(
f
,
LUA_NUMBER_SCAN
,
parms
)
==
1
)
{
lua_pushnumber
(
L
,
(
double
)
parms
[
0
]);
return
1
;
}
else
return
0
;
/* read fails */
}
private
static
int
test_eof
(
lua_State
L
,
Stream
f
)
{
int
c
=
getc
(
f
);
ungetc
(
c
,
f
);
lua_pushlstring
(
L
,
null
,
0
);
return
(
c
!=
EOF
)
?
1
:
0
;
}
private
static
int
read_line
(
lua_State
L
,
Stream
f
)
{
luaL_Buffer
b
=
new
luaL_Buffer
();
luaL_buffinit
(
L
,
b
);
for
(;;)
{
uint
l
;
CharPtr
p
=
luaL_prepbuffer
(
b
);
if
(
fgets
(
p
,
f
)
==
null
)
{
/* eof? */
luaL_pushresult
(
b
);
/* close buffer */
return
(
lua_objlen
(
L
,
-
1
)
>
0
)
?
1
:
0
;
/* check whether read something */
}
l
=
(
uint
)
strlen
(
p
);
if
(
l
==
0
||
p
[
l
-
1
]
!=
'\n'
)
luaL_addsize
(
b
,
(
int
)
l
);
else
{
luaL_addsize
(
b
,
(
int
)(
l
-
1
));
/* do not include `eol' */
luaL_pushresult
(
b
);
/* close buffer */
return
1
;
/* read at least an `eol' */
}
}
}
private
static
int
read_chars
(
lua_State
L
,
Stream
f
,
uint
n
)
{
uint
rlen
;
/* how much to read */
uint
nr
;
/* number of chars actually read */
luaL_Buffer
b
=
new
luaL_Buffer
();
luaL_buffinit
(
L
,
b
);
rlen
=
LUAL_BUFFERSIZE
;
/* try to read that much each time */
do
{
CharPtr
p
=
luaL_prepbuffer
(
b
);
if
(
rlen
>
n
)
rlen
=
n
;
/* cannot read more than asked */
nr
=
(
uint
)
fread
(
p
,
GetUnmanagedSize
(
typeof
(
char
)),
(
int
)
rlen
,
f
);
luaL_addsize
(
b
,
(
int
)
nr
);
n
-=
nr
;
/* still have to read `n' chars */
}
while
(
n
>
0
&&
nr
==
rlen
);
/* until end of count or eof */
luaL_pushresult
(
b
);
/* close buffer */
return
(
n
==
0
||
lua_objlen
(
L
,
-
1
)
>
0
)
?
1
:
0
;
}
private
static
int
g_read
(
lua_State
L
,
Stream
f
,
int
first
)
{
int
nargs
=
lua_gettop
(
L
)
-
1
;
int
success
;
int
n
;
clearerr
(
f
);
if
(
nargs
==
0
)
{
/* no arguments? */
success
=
read_line
(
L
,
f
);
n
=
first
+
1
;
/* to return 1 result */
}
else
{
/* ensure stack space for all results and for auxlib's buffer */
luaL_checkstack
(
L
,
nargs
+
LUA_MINSTACK
,
"too many arguments"
);
success
=
1
;
for
(
n
=
first
;
(
nargs
--
!=
0
)
&&
(
success
!=
0
);
n
++)
{
if
(
lua_type
(
L
,
n
)
==
LUA_TNUMBER
)
{
uint
l
=
(
uint
)
lua_tointeger
(
L
,
n
);
success
=
(
l
==
0
)
?
test_eof
(
L
,
f
)
:
read_chars
(
L
,
f
,
l
);
}
else
{
CharPtr
p
=
lua_tostring
(
L
,
n
);
luaL_argcheck
(
L
,
(
p
!=
null
)
&&
(
p
[
0
]
==
'*'
),
n
,
"invalid option"
);
switch
(
p
[
1
])
{
case
'n'
:
/* number */
success
=
read_number
(
L
,
f
);
break
;
case
'l'
:
/* line */
success
=
read_line
(
L
,
f
);
break
;
case
'a'
:
/* file */
read_chars
(
L
,
f
,
~((
uint
)
0
));
/* read MAX_uint chars */
success
=
1
;
/* always success */
break
;
default
:
return
luaL_argerror
(
L
,
n
,
"invalid format"
);
}
}
}
}
if
(
ferror
(
f
)!=
0
)
return
pushresult
(
L
,
0
,
null
);
if
(
success
==
0
)
{
lua_pop
(
L
,
1
);
/* remove last result */
lua_pushnil
(
L
);
/* push nil instead */
}
return
n
-
first
;
}
private
static
int
io_read
(
lua_State
L
)
{
return
g_read
(
L
,
getiofile
(
L
,
IO_INPUT
),
1
);
}
private
static
int
f_read
(
lua_State
L
)
{
return
g_read
(
L
,
tofile
(
L
),
2
);
}
private
static
int
io_readline
(
lua_State
L
)
{
Stream
f
=
(
lua_touserdata
(
L
,
lua_upvalueindex
(
1
))
as
FilePtr
).
file
;
int
sucess
;
if
(
f
==
null
)
/* file is already closed? */
luaL_error
(
L
,
"file is already closed"
);
sucess
=
read_line
(
L
,
f
);
if
(
ferror
(
f
)!=
0
)
return
luaL_error
(
L
,
"%s"
,
strerror
(
errno
()));
if
(
sucess
!=
0
)
return
1
;
else
{
/* EOF */
if
(
lua_toboolean
(
L
,
lua_upvalueindex
(
2
))
!=
0
)
{
/* generator created file? */
lua_settop
(
L
,
0
);
lua_pushvalue
(
L
,
lua_upvalueindex
(
1
));
aux_close
(
L
);
/* close it */
}
return
0
;
}
}
/* }====================================================== */
private
static
int
g_write
(
lua_State
L
,
Stream
f
,
int
arg
)
{
int
nargs
=
lua_gettop
(
L
)
-
1
;
int
status
=
1
;
for
(;
(
nargs
--)
!=
0
;
arg
++)
{
if
(
lua_type
(
L
,
arg
)
==
LUA_TNUMBER
)
{
/* optimization: could be done exactly as for strings */
status
=
((
status
!=
0
)
&&
(
fprintf
(
f
,
LUA_NUMBER_FMT
,
lua_tonumber
(
L
,
arg
))
>
0
))
?
1
:
0
;
}
else
{
uint
l
;
CharPtr
s
=
luaL_checklstring
(
L
,
arg
,
out
l
);
status
=
((
status
!=
0
)
&&
(
fwrite
(
s
,
GetUnmanagedSize
(
typeof
(
char
)),
(
int
)
l
,
f
)
==
l
))
?
1
:
0
;
}
}
return
pushresult
(
L
,
status
,
null
);
}
private
static
int
io_write
(
lua_State
L
)
{
return
g_write
(
L
,
getiofile
(
L
,
IO_OUTPUT
),
1
);
}
private
static
int
f_write
(
lua_State
L
)
{
return
g_write
(
L
,
tofile
(
L
),
2
);
}
private
static
int
f_seek
(
lua_State
L
)
{
int
[]
mode
=
{
SEEK_SET
,
SEEK_CUR
,
SEEK_END
};
CharPtr
[]
modenames
=
{
"set"
,
"cur"
,
"end"
,
null
};
Stream
f
=
tofile
(
L
);
int
op
=
luaL_checkoption
(
L
,
2
,
"cur"
,
modenames
);
long
offset
=
luaL_optlong
(
L
,
3
,
0
);
op
=
fseek
(
f
,
offset
,
mode
[
op
]);
if
(
op
!=
0
)
return
pushresult
(
L
,
0
,
null
);
/* error */
else
{
lua_pushinteger
(
L
,
ftell
(
f
));
return
1
;
}
}
private
static
int
f_setvbuf
(
lua_State
L
)
{
CharPtr
[]
modenames
=
{
"no"
,
"full"
,
"line"
,
null
};
int
[]
mode
=
{
_IONBF
,
_IOFBF
,
_IOLBF
};
Stream
f
=
tofile
(
L
);
int
op
=
luaL_checkoption
(
L
,
2
,
null
,
modenames
);
lua_Integer
sz
=
luaL_optinteger
(
L
,
3
,
LUAL_BUFFERSIZE
);
int
res
=
setvbuf
(
f
,
null
,
mode
[
op
],
(
uint
)
sz
);
return
pushresult
(
L
,
(
res
==
0
)
?
1
:
0
,
null
);
}
private
static
int
io_flush
(
lua_State
L
)
{
int
result
=
1
;
try
{
getiofile
(
L
,
IO_OUTPUT
).
Flush
();}
catch
{
result
=
0
;}
return
pushresult
(
L
,
result
,
null
);
}
private
static
int
f_flush
(
lua_State
L
)
{
int
result
=
1
;
try
{
tofile
(
L
).
Flush
();}
catch
{
result
=
0
;}
return
pushresult
(
L
,
result
,
null
);
}
private
readonly
static
luaL_Reg
[]
iolib
=
{
new
luaL_Reg
(
"close"
,
io_close
),
new
luaL_Reg
(
"flush"
,
io_flush
),
new
luaL_Reg
(
"input"
,
io_input
),
new
luaL_Reg
(
"lines"
,
io_lines
),
new
luaL_Reg
(
"open"
,
io_open
),
new
luaL_Reg
(
"output"
,
io_output
),
new
luaL_Reg
(
"popen"
,
io_popen
),
new
luaL_Reg
(
"read"
,
io_read
),
new
luaL_Reg
(
"tmpfile"
,
io_tmpfile
),
new
luaL_Reg
(
"type"
,
io_type
),
new
luaL_Reg
(
"write"
,
io_write
),
new
luaL_Reg
(
null
,
null
)
};
private
readonly
static
luaL_Reg
[]
flib
=
{
new
luaL_Reg
(
"close"
,
io_close
),
new
luaL_Reg
(
"flush"
,
f_flush
),
new
luaL_Reg
(
"lines"
,
f_lines
),
new
luaL_Reg
(
"read"
,
f_read
),
new
luaL_Reg
(
"seek"
,
f_seek
),
new
luaL_Reg
(
"setvbuf"
,
f_setvbuf
),
new
luaL_Reg
(
"write"
,
f_write
),
new
luaL_Reg
(
"__gc"
,
io_gc
),
new
luaL_Reg
(
"__tostring"
,
io_tostring
),
new
luaL_Reg
(
null
,
null
)
};
private
static
void
createmeta
(
lua_State
L
)
{
luaL_newmetatable
(
L
,
LUA_FILEHANDLE
);
/* create metatable for file files */
lua_pushvalue
(
L
,
-
1
);
/* push metatable */
lua_setfield
(
L
,
-
2
,
"__index"
);
/* metatable.__index = metatable */
luaL_register
(
L
,
null
,
flib
);
/* file methods */
}
private
static
void
createstdfile
(
lua_State
L
,
Stream
f
,
int
k
,
CharPtr
fname
)
{
newfile
(
L
).
file
=
f
;
if
(
k
>
0
)
{
lua_pushvalue
(
L
,
-
1
);
lua_rawseti
(
L
,
LUA_ENVIRONINDEX
,
k
);
}
lua_pushvalue
(
L
,
-
2
);
/* copy environment */
lua_setfenv
(
L
,
-
2
);
/* set it */
lua_setfield
(
L
,
-
3
,
fname
);
}
private
static
void
newfenv
(
lua_State
L
,
lua_CFunction
cls
)
{
lua_createtable
(
L
,
0
,
1
);
lua_pushcfunction
(
L
,
cls
);
lua_setfield
(
L
,
-
2
,
"__close"
);
}
public
static
int
luaopen_io
(
lua_State
L
)
{
createmeta
(
L
);
/* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
newfenv
(
L
,
io_fclose
);
lua_replace
(
L
,
LUA_ENVIRONINDEX
);
/* open library */
luaL_register
(
L
,
LUA_IOLIBNAME
,
iolib
);
/* create (and set) default files */
newfenv
(
L
,
io_noclose
);
/* close function for default files */
createstdfile
(
L
,
stdin
,
IO_INPUT
,
"stdin"
);
createstdfile
(
L
,
stdout
,
IO_OUTPUT
,
"stdout"
);
createstdfile
(
L
,
stderr
,
0
,
"stderr"
);
lua_pop
(
L
,
1
);
/* pop environment for default files */
lua_getfield
(
L
,
-
1
,
"popen"
);
newfenv
(
L
,
io_pclose
);
/* create environment for 'popen' */
lua_setfenv
(
L
,
-
2
);
/* set fenv for 'popen' */
lua_pop
(
L
,
1
);
/* pop 'popen' */
return
1
;
}
}
}
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment