Skip to content

Commit

Permalink
Support for Compact Framework (2.0) on Windows CE
Browse files Browse the repository at this point in the history
Most of the changes here are wrapped in "#if WindowsCE".

SharpLua.Interactive\SharpLua.InteractiveCF20.csproj
  Project file for CE/CF version of slua.exe
  This was used to run through the test suite.

SharpLua\CFSupport.cs
  Provides central functionality to fix compatibility issues with CE/CF

  Provide dummy IReflect interface to make ProxyType happy.
  (I could not find a way to make this work out cleanly or efficiently.  Need to revisit this stuff later.)

  Create (literal) dummy class in System.Runtime.Serialization so that the unnecessary 'using System.Runtime.Serialization' placed everywhere doesn't break things.
  ThreadLocalSlot<T> provides a surrogate for [ThreadStatic]

  Create extension methods to replace overloads that don't exist in CF

SharpLua\Interfacing\MethodWrapper.cs
  Alias IReflect to Type
  Since CF does not support reflection emit, have Add method throw NotSupportedException

SharpLua\SharpLuaCF20.csproj
  Project file for CE/CF version of SharpLua.dll

SharpLua\Support\LuaCFSupport.cs
  Provides functionality to fix compatibility issues with CE/CF within the main Lua class
  Provides stdio methods (interestingly enough, since CE has the C library built-in, most of the surrogate functions could be deferred to stdio)

SharpLua\Support\errno_h.cs
  (Not CE-specific) Provides errno-like behavior

SharpLua\Support\stdlib_h.cs
  (Not CE-specific) Provide 'exit' and 'getenv'

SharpLuaCF20.sln
  Solution file for CF20 (VS2008, because VS2012 abandons support for CF2.0)

SharpLua.Interactive\Main.cs
  Replace calls to Environment.Exit with calls to Lua.exit
  Perform juggling to get full command line, including argv[0], under CE
  Also do FakeCurrentDirectory fudging under CE
  Remove calls to Application.EnableVisualStyles and SetCompatibleTextRenderingDefault, which (a) do not exist in CF, and (b) are absolutely pointless in a console application.
  Use alternative way to get full path and filename of assembly
  No LuaSourceException under CE (the new lexer/compiler are not even compiled in)

SharpLua.Interactive\Properties\AssemblyInfo.cs
  AssemblyFileVersionAttribute does not exist in CF

SharpLua\Interfacing\CheckType.cs
  Rework the extractValues dictionary to remove explicit use of RuntimeTypeHandle, which doesn't work under CF
  No such thing as AppDomain.GetAssemblies() :-(
     Need to add the ability to register a set of assemblies to be scanned.
  No support for dynamic type generation in CF

SharpLua\Interfacing\Lua.cs
  No support for dynamic type generation in CF

SharpLua\Interfacing\LuaException.cs
  No built-in "Source" property in Exception in CF
  No SerializationInfo/StreamingContext in CF

SharpLua\Interfacing\LuaRegistrationHelper.cs
  No Enum.GetNames() or GetValues() in CF

SharpLua\Interfacing\Metatables.cs
  Alias IReflect to Type
  No SEHException in CF (should this even be used anymore?)
  TableToArray: Use 3-arg form of Convert.ChangeType (2-arg form missing from CF)
  matchParameters: ParameterInfo does not have handy IsIn, IsOut, IsOptional properties in CF

SharpLua\Interfacing\ObjectTranslator.cs
  Alias IReflect to Type
  loadAssembly(): Use Assembly.Load instead of Assembly.LoadWithPartialName (does not exist in CF, gives warning in FF)
  loadAssembly(): Assembly.Load(AssemblyName) does not exist in CF (use Assembly.LoadFrom)
  FindType(): Try Type.GetType() first, just in case it's an assembly-qualified class name
  FindType(): No such thing as AppDomain.GetAssemblies() :-(
  registerTable(): Not available under CF
  enumFromInt(): Use 3-arg form of Enum.Parse (2-arg form missing from CF)
  IsILua(): Always false, there's no ILuaGeneratedType in CF b/c there is no dynamic type generation
  push(): Don't bother with IsILua

SharpLua\LASM\LasmParser.cs
  TryParse doesn't exist in CF

SharpLua\LASM\bit.cs
  BitConverter.DoubleToInt64Bits does not exist in CF

SharpLua\LuaCore\Libraries\liolib.cs
  Changes to make errno work

SharpLua\LuaCore\Libraries\loadlib.cs
  setprogdir(): CE does not have the notion of a current directory(!)
  Use getenv() instead of Environment.GetEnvironmentVariable directly

SharpLua\LuaCore\Libraries\loslib.cs
  Changes to make errno work
  Make os_execute half-work under CE (it doesn't work well)
  Fix lua_opt usage in os_date; VS2008 apparently can't infer the type argument
  Change an #else-#if to the cleaner #elif
  Use new exit() method instead of Environment.Exit (which does not exist in CF)

SharpLua\LuaCore\Parser\lparser.cs
  Can't set the culture for a thread in CF; it's hard-coded(!)  This might break the parser.

SharpLua\LuaCore\VM\lapi.cs
  #if out SharpLua_OverrideLoad
  Remove explicit call to f.f.Dispose(), which is (a) marked protected in CF, and (b) implied by Close() anyway

SharpLua\LuaCore\VM\lauxlib.cs
  errno is now a property and not a function

SharpLua\LuaCore\VM\ldo.cs
  Change an #else-#if to the cleaner #elif
  Use new exit() method instead of Environment.Exit (which does not exist in CF)

SharpLua\LuaCore\VM\lundump.cs
  LoadMem: Marhshal.SizeOf(typeof(char)) returns 2 under CF
  This whole mess needs to be redone anyway

SharpLua\LuaCore\luaconf.cs
  Remove errno- replaced with errno property in errno_h.cs
  Remove strerror - moved to errno_h.cs
  Moved getenv to stdlib_h.cs
  Various stdio implementations now save the exception to the errno property
  Make stdout, stdin, and stderr work under CE
  frexp(): Math.Log(n, base) does not exist in CF
  fopen(): Add mojo to fake a current directory

SharpLua\LuaCore\printf.cs
  IntPtr.ToString(string) overload does not exist in CF

SharpLua\Properties\AssemblyInfo.cs
  AssemblyFileVersionAttribute does not exist in CF

SharpLua\SharpLuaNet20.csproj
  Add errno_h.cs and stdlib_h.cs to the project
  • Loading branch information
Stevie-O committed Oct 9, 2013
1 parent f9b68fd commit e7936f5
Show file tree
Hide file tree
Showing 30 changed files with 1,978 additions and 1,057 deletions.
54 changes: 42 additions & 12 deletions SharpLua.Interactive/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ static void die(string message)
}
static void die(string message, int exitCode)
{
Console.Error.WriteLine("Error: {0}", message);
Environment.Exit(exitCode);
Console.Error.WriteLine("Error: {0}", message);
Lua.exit(exitCode);
}

enum InteractiveOption
Expand All @@ -34,11 +34,20 @@ enum InteractiveOption
No,
}

#if WindowsCE
static string[] argv;
#endif
/// <summary>
/// A REPL (Read, Eval, Print, Loop function) for #Lua
/// </summary>
public static void Main()
public static void Main(string[] partial_argv)
{
#if WindowsCE
argv = new string[partial_argv.Length + 1];
argv[0] = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase;
partial_argv.CopyTo(argv, 1);
#endif

if (Debugger.IsAttached)
{
// if a debugger is attached, ONLY catch LuaException
Expand Down Expand Up @@ -66,6 +75,15 @@ public static void Main()
die(ex.ToString(), 127);
}
}
}

static string[] GetCommandLineArgs()
{
#if WindowsCE
return (string[]) argv.Clone();
#else
return Environment.GetCommandLineArgs();
#endif
}

static void RealMain()
Expand All @@ -75,8 +93,6 @@ static void RealMain()
InteractiveOption GoInteractive = InteractiveOption.Auto;

// Create global variables
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

//Stopwatch sw = new Stopwatch();
//sw.Start();
Expand Down Expand Up @@ -105,8 +121,11 @@ static void RealMain()

Prompt = "> ";

// This gets the real, 100%, full command line, including argv[0]
string[] args = Environment.GetCommandLineArgs();
// This gets the real, 100%, full command line, including argv[0]
string[] args = GetCommandLineArgs();
#if WindowsCE
Lua.FakeCurrentDirectory = Path.GetDirectoryName(args[0]); // default 'fake current directory' to the one where the executable resides
#endif
bool did_e = false;
int argi;
for (argi = 1; argi < args.Length; argi++)
Expand Down Expand Up @@ -159,7 +178,7 @@ static void RealMain()
break;
case 'v':
LuaRuntime.PrintBanner();
Environment.Exit(0);
Lua.exit(0);
break;
default:
die("Undefined option: " + arg);
Expand All @@ -177,11 +196,20 @@ static void RealMain()
for (int i3 = 0; i3 < args.Length; i3++)
t[i3 - argi] = args[i3];
t["n"] = args.Length - argi;
*/
if (File.Exists(args[argi]))
LuaRuntime.SetVariable("_WORKDIR", Path.GetDirectoryName(args[argi]));
*/
if (File.Exists(args[argi]))
{
string script_dir = Path.GetDirectoryName(Path.GetFullPath(args[argi]));
#if WindowsCE
if (!string.IsNullOrEmpty(script_dir))
Lua.FakeCurrentDirectory = script_dir;
#endif
LuaRuntime.SetVariable("_WORKDIR", script_dir);
}
#if !WindowsCE
else
LuaRuntime.SetVariable("_WORKDIR", Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath));
#endif
LuaRuntime.RunFile(args[argi], args, argi);
}

Expand All @@ -191,7 +219,7 @@ static void RealMain()
{
if (!did_e)
LuaRuntime.PrintBanner();
LuaRuntime.SetVariable("_WORKDIR", Path.GetDirectoryName(typeof(Program).Assembly.Location));
LuaRuntime.SetVariable("_WORKDIR", Path.GetDirectoryName(typeof(Program).Assembly.GetName().CodeBase));
while (true)
{
Console.Write(Prompt);
Expand Down Expand Up @@ -226,6 +254,7 @@ static void RealMain()
Console.WriteLine();
}
}
#if !WindowsCE
catch (LuaSourceException ex)
{
for (int i = 1; i < ex.Column; i++)
Expand All @@ -241,6 +270,7 @@ static void RealMain()
Console.WriteLine("^");
Console.WriteLine(ex.GenerateMessage("<stdin>"));
}
#endif
catch (Exception error)
{
object dbg = LuaRuntime.GetVariable("DEBUG");
Expand Down
3 changes: 3 additions & 0 deletions SharpLua.Interactive/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
#if !WindowsCE
[assembly: AssemblyFileVersion("1.0.0.0")]
#endif

79 changes: 79 additions & 0 deletions SharpLua.Interactive/SharpLua.InteractiveCF20.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{B7A7E721-4E38-40E9-A275-CCDF28669B69}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SharpLua.Interactive</RootNamespace>
<AssemblyName>slua</AssemblyName>
<ProjectTypeGuids>{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<PlatformFamilyName>PocketPC</PlatformFamilyName>
<PlatformID>4118C335-430C-497f-BE48-11C3316B135E</PlatformID>
<OSVersion>5.01</OSVersion>
<DeployDirSuffix>SharpLua.InteractiveCF20</DeployDirSuffix>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<NativePlatformName>Windows Mobile 5.0 Pocket PC SDK</NativePlatformName>
<FormFactorID>
</FormFactorID>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\bin\Debug\CF20\</OutputPath>
<DefineConstants>TRACE;DEBUG;WindowsCE</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<FileAlignment>512</FileAlignment>
<WarningLevel>4</WarningLevel>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\bin\Release\CF20\</OutputPath>
<DefineConstants>TRACE;WindowsCE</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<FileAlignment>512</FileAlignment>
<WarningLevel>4</WarningLevel>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SharpLua\SharpLuaCF20.csproj">
<Project>{85EE2E82-B643-4AAE-BBD2-0B3EB0DE842E}</Project>
<Name>SharpLuaCF20</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}">
<HostingProcess disable="1" />
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<!-- 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>
176 changes: 176 additions & 0 deletions SharpLua/CFSupport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Threading;
using System.Globalization;

// placeholder types for Compact Framework

#if WindowsCE

namespace System.Reflection
{
interface IReflect
{
Type UnderlyingSystemType { get; }
}
// this didn't work so well :(
#if false
struct IReflect
{
// the guts of this structure were copied from ProxyType
Type proxy;

public IReflect(Type proxy)
{
this.proxy = proxy;
}

/// <summary>
/// Provide human readable short hand for this proxy object
/// </summary>
/// <returns></returns>
public override string ToString()
{
return UnderlyingSystemType.ToString();
}


public Type UnderlyingSystemType
{
get
{
return proxy;
}
}

public FieldInfo GetField(string name, BindingFlags bindingAttr)
{
return proxy.GetField(name, bindingAttr);
}

public FieldInfo[] GetFields(BindingFlags bindingAttr)
{
return proxy.GetFields(bindingAttr);
}

public MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
{
return proxy.GetMember(name, bindingAttr);
}

public MemberInfo[] GetMembers(BindingFlags bindingAttr)
{
return proxy.GetMembers(bindingAttr);
}

public MethodInfo GetMethod(string name, BindingFlags bindingAttr)
{
return proxy.GetMethod(name, bindingAttr);
}

public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
{
return proxy.GetMethod(name, bindingAttr, binder, types, modifiers);
}

public MethodInfo[] GetMethods(BindingFlags bindingAttr)
{
return proxy.GetMethods(bindingAttr);
}

public PropertyInfo GetProperty(string name, BindingFlags bindingAttr)
{
return proxy.GetProperty(name, bindingAttr);
}

public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
{
return proxy.GetProperty(name, bindingAttr, binder, returnType, types, modifiers);
}

public PropertyInfo[] GetProperties(BindingFlags bindingAttr)
{
return proxy.GetProperties(bindingAttr);
}

public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
{
return proxy.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
}

public static implicit operator IReflect(Type t) { return new IReflect(t); }
public static explicit operator Type(IReflect r) { return r.proxy; }
public static bool operator ==(IReflect a, Type t) { return a.proxy == t; }
public static bool operator ==(Type t, IReflect a) { return a.proxy == t; }
public static bool operator !=(IReflect a, Type t) { return a.proxy != t; }
public static bool operator !=(Type t, IReflect a) { return a.proxy != t; }
public override int GetHashCode() { return proxy.GetHashCode(); }
public override bool Equals(object obj)
{
// this is not transitive
//if (obj == null) return this.proxy == null;
//if (obj is Type) return this.proxy == ((Type)obj);
if (obj is IReflect) return this.proxy == ((IReflect)obj).proxy;
return false;
}
}
#endif
}

namespace System.Runtime.Serialization
{
static class dummy { }
}

namespace SharpLua
{

class ThreadLocalSlot<T>
{
readonly LocalDataStoreSlot _slot = Thread.AllocateDataSlot();
public T Value
{
get
{
object tmp = Thread.GetData(_slot);
if (tmp == null) return default(T);
return (T)tmp;
}
set { Thread.SetData(_slot, value); }
}
} // class ThreadLocalSlot<T>

static class ExtensionMethods
{
public static StringBuilder AppendFormat(this StringBuilder sb, string format, params object[] args)
{
return sb.AppendFormat(null, format, args);
}

public static MemberInfo[] GetMember(this Type t, string memberName, MemberTypes memberTypes, BindingFlags bindingFlags)
{
MemberInfo[] members = t.GetMember(memberName, bindingFlags);
if (members == null || members.Length == 0) return members;
int i;
for (i = 0; i < members.Length; i++)
{
if ((members[i].MemberType & memberTypes) == 0) break;
}
if (i == members.Length) return members; // all members were valid
List<MemberInfo> memberList = new List<MemberInfo>(members);
for (; i < memberList.Count; i++)
{
if ((memberList[i].MemberType & memberTypes) == 0)
{
memberList.RemoveAt(i);
i--;
}
}
return memberList.ToArray();
}
}
}

#endif
Loading

0 comments on commit e7936f5

Please sign in to comment.