Skip to content

Commit

Permalink
Added DLLStruct-Parser and began impelementing DLLCall (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
Unknown6656 committed Jul 27, 2020
1 parent 5a0d050 commit 7a18abb
Show file tree
Hide file tree
Showing 21 changed files with 294 additions and 97 deletions.
12 changes: 6 additions & 6 deletions new/AutoItInterpreter/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@

//////////////////////////////////////////////////////////////////////////
// Auto-generated 2020-07-27 18:34:41.779 //
// Auto-generated 2020-07-28 01:02:13.149 //
// ANY CHANGES TO THIS DOCUMENT WILL BE LOST UPON RE-GENERATION //
//////////////////////////////////////////////////////////////////////////

using System.Reflection;
using System;

[assembly: AssemblyVersion("0.6.1267.7329")]
[assembly: AssemblyFileVersion("0.6.1267.7329")]
[assembly: AssemblyInformationalVersion("b877e1ddbae1587279e88674b832e197076fe331")]
[assembly: AssemblyVersion("0.6.1282.7330")]
[assembly: AssemblyFileVersion("0.6.1282.7330")]
[assembly: AssemblyInformationalVersion("v.0.6.1282.7330, commit: 5a0d0508612f1085ea3b9a5bd34d3af5c215dc7d")]
[assembly: AssemblyCompany("Unknown6656")]
[assembly: AssemblyCopyright("Copyright © 2018 - 2020, Unknown6656")]
[assembly: AssemblyProduct("AutoIt3 Interpreter by Unknown6656")]
Expand All @@ -35,11 +35,11 @@ public static class __module__
/// <summary>
/// The interpreter's current version.
/// </summary>
public static Version? InterpreterVersion { get; } = Version.Parse("0.6.1267.7329");
public static Version? InterpreterVersion { get; } = Version.Parse("0.6.1282.7330");
/// <summary>
/// The Git hash associated with the current build.
/// </summary>
public const string GitHash = "b877e1ddbae1587279e88674b832e197076fe331";
public const string GitHash = "5a0d0508612f1085ea3b9a5bd34d3af5c215dc7d";
/// <summary>
/// The URL of this project's Git(Hub) repository.
/// </summary>
Expand Down
10 changes: 9 additions & 1 deletion new/AutoItInterpreter/AutoItInterpreter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,17 @@
<AssemblyName>autoit3</AssemblyName>
<OutputPath>$(SolutionDir)bin</OutputPath>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
<PackageProjectUrl>https://github.com/Unknown6656/AutoIt-Interpreter</PackageProjectUrl>
<PackageIcon>icon.png</PackageIcon>
<RepositoryType>Git</RepositoryType>
<PackageTags>unknown6656; AutoIt; AutoIt3; Interpreter; Compiler</PackageTags>
</PropertyGroup>
<ItemGroup>
<None Remove="lang\lang-en.yml" />
<None Include="..\artwork\icon.png">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<Reference Include="Piglet">
Expand Down Expand Up @@ -61,7 +69,7 @@
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AutoItExpressionParser\AutoItParser.fsproj" />
<ProjectReference Include="..\AutoItParser\AutoItParser.fsproj" />
<ProjectReference Include="..\util\AutoIt3.Common\AutoIt3.Common.csproj" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
using Unknown6656.AutoIt3.COM;
using Unknown6656.Common;
using Unknown6656.IO;
using System.Reflection.Metadata;

namespace Unknown6656.AutoIt3.Extensibility.Plugins.Au3Framework
{
using static Unknown6656.AutoIt3.Parser.DLLStructParser.AST;
using TCPHandle = Union<TcpListener, TcpClient>;

public sealed class FrameworkFunctions
Expand Down Expand Up @@ -662,23 +664,20 @@ internal static FunctionReturnValue DllCall(CallFrame frame, Variant[] args)
if (dllhandle?.IsLoaded is null or false)
return FunctionReturnValue.Error(1);

List<(string type, Variant value)> arguments = new();
string? ret_type = TranslateDllType(args[1].ToString());
string funcname = args[2].ToString();

if (ret_type is null)
return FunctionReturnValue.Error(2);

int argc = frame.PassedArguments.Length - 3;

if ((argc % 2) != 0)
return FunctionReturnValue.Error(4);

for (int i = 0; i < argc / 2; ++i)
if (TranslateDllType(args[2 * i + 3].ToString()) is string type)
arguments.Add((type, args[2 * i + 4]));
else
return FunctionReturnValue.Error(5);
Variant[] arguments = args.Skip(3).Take(argc).Where((_, i) => (i % 2) == 1).ToArray();
string raw_signature = args.Skip(3).Take(argc).Where((_, i) => (i % 2) == 0).Prepend(args[1]).StringJoin(", ");
SIGNATURE signature;

if (frame.Interpreter.ParserProvider.DLLStructParser.TryParse(raw_signature, out var result) && result is { })
signature = result.ParsedValue;
else
return FunctionReturnValue.Error(3);

nint funcptr = NativeInterop.DoPlatformDependent<Func<nint, string, nint>>(
NativeInterop.GetProcAddress,
Expand All @@ -690,26 +689,14 @@ internal static FunctionReturnValue DllCall(CallFrame frame, Variant[] args)
return FunctionReturnValue.Error(3);





Delegate.CreateDelegate()
Marshal.GetDelegateForFunctionPointer(funcptr);
var delegatetype = DelegateBuilder.Instance.CreateDelegateType(signature.ReturnType, signature.ParameterTypes);

// TODO


throw new NotImplementedException();
}

public static void CreateDelegate(Type ret, Type[] pars)
{

}




// TODO : DllGetAddress ?

// internal static FunctionReturnValue DllCallAddress(CallFrame frame, Variant[] args)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System.IO;
using System;

using Unknown6656.AutoIt3.ExpressionParser;
using Unknown6656.AutoIt3.Parser.ExpressionParser;
using Unknown6656.AutoIt3.Runtime.Native;
using Unknown6656.AutoIt3.Runtime;
using Unknown6656.Common;
Expand Down
6 changes: 4 additions & 2 deletions new/AutoItInterpreter/MainProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
using Unknown6656.Common;

using OperatingSystem = Unknown6656.AutoIt3.Runtime.Native.OperatingSystem;
using CLParser = CommandLine.Parser;


[assembly: AssemblyUsage(@"
Run the interpreter quietly (only print the script's output):
Expand Down Expand Up @@ -100,7 +102,7 @@ public sealed class CommandLineOptions
public string? FilePath { set; get; } = null;


public override string ToString() => Parser.Default.FormatCommandLine(this);
public override string ToString() => CLParser.Default.FormatCommandLine(this);
}

public static class MainProgram
Expand Down Expand Up @@ -167,7 +169,7 @@ public static int Start(string[] argv)

Telemetry.Measure(TelemetryCategory.ParseCommandLine, delegate
{
using Parser parser = new Parser(p => p.HelpWriter = null);
using CLParser parser = new CLParser(p => p.HelpWriter = null);

ParserResult<CommandLineOptions> result = parser.ParseArguments<CommandLineOptions>(argv);

Expand Down
4 changes: 2 additions & 2 deletions new/AutoItInterpreter/Runtime/CallFrame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@

using Unknown6656.AutoIt3.Extensibility.Plugins.Au3Framework;
using Unknown6656.AutoIt3.Extensibility.Plugins.Internals;
using Unknown6656.AutoIt3.ExpressionParser;
using Unknown6656.AutoIt3.Parser.ExpressionParser;
using Unknown6656.AutoIt3.Extensibility;
using Unknown6656.Common;

using static Unknown6656.AutoIt3.ExpressionParser.AST;
using static Unknown6656.AutoIt3.Parser.ExpressionParser.AST;

namespace Unknown6656.AutoIt3.Runtime
{
Expand Down
146 changes: 110 additions & 36 deletions new/AutoItInterpreter/Runtime/DelegateBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Reflection.Emit;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Linq;
using System;

using Unknown6656.AutoIt3.Parser.DLLStructParser;
using Unknown6656.Common;

namespace Unknown6656.AutoIt3.Runtime
{
using static AST;

public sealed class DelegateBuilder
{
public static DelegateBuilder Instance { get; } = new DelegateBuilder();
Expand All @@ -25,34 +27,64 @@ private DelegateBuilder()
_module = _assembly.DefineDynamicModule(nameof(DelegateBuilder));
}

public Type? CreateDelegateType(Type return_type, params Type[] parameters)
public Type? CreateDelegateType(ANNOTATED_TYPE return_type, params TYPE[] parameters)
{
try
{
string delegate_name = Guid.NewGuid().ToString("N");
TypeBuilder delegate_builder = _module.DefineType(delegate_name, TypeAttributes.Sealed | TypeAttributes.Public, typeof(MulticastDelegate));
TypeBuilder delegate_builder = _module.DefineType(Guid.NewGuid().ToString("N"), TypeAttributes.Sealed | TypeAttributes.Public, typeof(MulticastDelegate));

delegate_builder.SetCustomAttribute(new CustomAttributeBuilder(
typeof(UnmanagedFunctionPointerAttribute).GetConstructor(new[] { typeof(CallingConvention) })!,
new object[]
{
return_type.CallConvention.IsFastcall ? CallingConvention.FastCall :
return_type.CallConvention.IsStdcall ? CallingConvention.StdCall :
return_type.CallConvention.IsThiscall ? CallingConvention.ThisCall :
return_type.CallConvention.IsWinAPI ? CallingConvention.Winapi : CallingConvention.Cdecl
}
));
delegate_builder.DefineConstructor(
MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public,
CallingConventions.Standard,
new[] { typeof(object), typeof(nint) }
).SetImplementationFlags(MethodImplAttributes.CodeTypeMask);

Type?[] @params = parameters.ToArray(t => ConvertType(t, true));

MethodBuilder invoke = delegate_builder.DefineMethod(
"Invoke",
MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Public,
return_type,
parameters
MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Public,
ConvertType(return_type.Type, false),
@params!
);
invoke.SetImplementationFlags(MethodImplAttributes.CodeTypeMask);

for (int i = 0; i < parameters.Length; i++)
ParameterBuilder ProcessParameter(int index, TYPE type)
{
ParameterBuilder par = invoke.DefineParameter(i + 1, ParameterAttributes.None, "p" + i);
ParameterAttributes attr = index is 0 ? ParameterAttributes.Retval : ParameterAttributes.None;

// par.SetCustomAttribute(new CustomAttributeBuilder(parameters[i].attributes[0].GetType().GetConstructor()))
if (type.IsWSTR || type.IsSTR)
attr |= ParameterAttributes.HasFieldMarshal;

ParameterBuilder parameter = invoke.DefineParameter(index, attr, index is 0 ? null : "item" + index);

if (type.IsWSTR || type.IsSTR)
parameter.SetCustomAttribute(new CustomAttributeBuilder(
typeof(MarshalAsAttribute).GetConstructor(new[] { typeof(UnmanagedType) })!,
new object[] { type.IsWSTR ? UnmanagedType.LPWStr : UnmanagedType.LPStr }
));

return parameter;
}

ProcessParameter(0, return_type.Type);

for (int i = 0; i < @params.Length; i++)
if (@params[i] is null)
return null;
else
ProcessParameter(i + 1, parameters[i]);

return delegate_builder.CreateType();
}
catch
Expand All @@ -61,29 +93,71 @@ private DelegateBuilder()
}
}

public static Type? TranslateDLLType(string typestring) => typestring.ToUpperInvariant() switch
private Type? ConvertType(TYPE type, bool is_parameter)
{
"U0" or "NONE" => typeof(void),
"U1" or "BYTE" or "BOOLEAN" => typeof(byte),
"I2" or "SHORT" => typeof(short),
"U2" or "USHORT" or "WORD" => typeof(ushort),
"I4" or "INT" or "LONG" or "BOOL" or "HANDLE" => typeof(int),
"U4" or "UINT" or "ULONG" or "DWORD" => typeof(uint),
"I8" or "INT64" or "LONGLONG" or "LARGE_INTEGER" => typeof(long),
"U8" or "UINT64" or "ULONGLONG" or "ULARGE_INTEGER" => typeof(ulong),
"R4" or "FLOAT" => typeof(float),
"R8" or "DOUBLE" => typeof(double),
"INT_PTR" or "LONG_PTR" or "LRESULT" or "LPARAM" => typeof(nint),
"UINT_PTR" or "ULONG_PTR" or "DWORD_PTR" or "WPARAM" or "ULONG_PTR" => typeof(nuint),
"I2" or "PTR" or "LPVOID" or "HANDLE" or "HWND" or "HINSTANCE" or "STRUCT*" or "LPSTRUCT" => typeof(nint), // void*
"STR" or "LPCSTR" or "LPSTR" => typeof(string), // ansi
"WSTR" or "LPCWSTR" or "LPWSTR" => typeof(string), // utf16
{ Length: > 2 } s when s[..2] == "LP" => TranslateDLLType(s + '*'),
{ Length: > 1 } s when s[^1] == '*' => typeof(nint),

"STRUCT" => throw new NotImplementedException(),
_ => throw new NotImplementedException(),
};
if (type.IsU0)
return is_parameter ? null : typeof(void);
else if (type.IsU8)
return typeof(byte);
else if (type.IsU16)
return typeof(ushort);
else if (type.IsU32)
return typeof(uint);
else if (type.IsU64)
return typeof(ulong);
else if (type.IsI16)
return typeof(short);
else if (type.IsI32)
return typeof(int);
else if (type.IsI64)
return typeof(long);
else if (type.IsR32)
return typeof(float);
else if (type.IsR64)
return typeof(double);
else if (type.IsR128)
return typeof(decimal);
else if (type.IsSTR || type.IsWSTR)
return typeof(StringBuilder);
else if (type.IsPTR)
return typeof(nint);
else if (type.IsStruct)
; // TODO
else if (type is TYPE.Composite { Item: { } types })
{
TYPE[] otypes = types.ToArray();
Type?[] fields = types.ToArray(t => ConvertType(t, true));
bool unicode = otypes.Any(t => t.IsWSTR);

TypeBuilder builder = _module.DefineType(
Guid.NewGuid().ToString("N"),
TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.SequentialLayout | TypeAttributes.BeforeFieldInit | (unicode ? TypeAttributes.UnicodeClass : TypeAttributes.AnsiClass),
typeof(ValueType)
);

for (int i = 0; i < fields.Length; i++)
if (fields[i] is Type ftype)
{
FieldAttributes attr = FieldAttributes.Public;

if (otypes[i].IsWSTR || otypes[i].IsSTR)
attr |= FieldAttributes.HasFieldMarshal;

FieldBuilder field = builder.DefineField("Item" + i, ftype, attr);

if (otypes[i].IsWSTR || otypes[i].IsSTR)
field.SetCustomAttribute(new CustomAttributeBuilder(
typeof(MarshalAsAttribute).GetConstructor(new[] { typeof(UnmanagedType) })!,
new object[] { otypes[i].IsWSTR ? UnmanagedType.LPWStr : UnmanagedType.LPStr }
));
}
else
return null;

return builder.CreateType();
}

return null; // TODO
}
}
}
2 changes: 1 addition & 1 deletion new/AutoItInterpreter/Runtime/Interpreter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;

using Unknown6656.AutoIt3.ExpressionParser;
using Unknown6656.AutoIt3.Parser.ExpressionParser;
using Unknown6656.AutoIt3.Extensibility;
using Unknown6656.AutoIt3.Runtime.ExternalServices;
using Unknown6656.AutoIt3.Runtime.Native;
Expand Down
Loading

0 comments on commit 7a18abb

Please sign in to comment.