public void Initialize() { if (options == null) InitializeConfig(); if (compilationContext == null) { string siteRoot = AppDomain.CurrentDomain.BaseDirectory; compilationContext = new WebCompilationContext( new DirectoryInfo(siteRoot), new DirectoryInfo(options.CompilerOptions.TemporarySourceFilesDirectory)); } #region TODO //TODO: think about CommonScripts implementation in c#/VB.NET #endregion LoadCompiledViews(); if (options.CompilerOptions.AutoRecompilation) { // invalidate compiled views cache on any change to the view sources ViewSourceLoader.ViewChanged += delegate(object sender, FileSystemEventArgs e) { if (e.Name.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase)) { needsRecompiling = true; } }; } }
/// <inheritdoc/> public bool TryCompile(IReadOnlyList <MathExpression> arguments, ICompilationContext <object?> context, ITypeHintHandler typeHintHandler, [MaybeNullWhen(false)] out Expression expr) { if (arguments.Count != 1) { expr = null; return(false); } var argExpr = context.Transform(arguments.First()); if (argExpr.Type == typeof(float) || argExpr.Type == typeof(double)) { // if this is a floating point var method = Helpers.GetMethod <Action <double> >(d => Math.Log(d)) !; expr = Expression.Call(method, CompilerHelpers.ConvertToType(argExpr, typeof(double))); return(true); } else if (CompilerHelpers.IsFloating(argExpr.Type) || CompilerHelpers.IsIntegral(argExpr.Type)) { // if this is a built-in integer or decimal var method = Helpers.GetMethod <Action <decimal> >(d => DecimalMath.Ln(d)) !; expr = Expression.Call(method, CompilerHelpers.ConvertToType(argExpr, typeof(decimal))); return(true); } expr = null; return(false); }
public OfflineCompiler(ICodeProviderAdapterFactory codeProviderAdapterFactory, IPreProcessor preProcessor, ICompilationContext context, AspViewCompilerOptions options, IFileSystemAdapter fileSystem) : base(codeProviderAdapterFactory, preProcessor, context, options) { this.fileSystem = fileSystem; parameters.GenerateInMemory = false; parameters.OutputAssembly = Path.Combine(context.BinFolder.FullName, "CompiledViews.dll"); }
public void Initialize() { if (options == null) { InitializeConfig(); } if (compilationContext == null) { string siteRoot = AppDomain.CurrentDomain.BaseDirectory; compilationContext = new WebCompilationContext( new DirectoryInfo(siteRoot), new DirectoryInfo(options.CompilerOptions.TemporarySourceFilesDirectory)); } #region TODO //TODO: think about CommonScripts implementation in c#/VB.NET #endregion LoadCompiledViews(); if (options.CompilerOptions.AutoRecompilation) { // invalidate compiled views cache on any change to the view sources ViewSourceLoader.ViewChanged += delegate(object sender, FileSystemEventArgs e) { if (e.Name.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase)) { needsRecompiling = true; } }; } }
public ExpressionResult Compile( ArrayAllocationExpression expression, PreferredRegister target, ICompilationContext context ) { var codeGen = context.Generator; var linkingInfo = context.Linking; var index = context.CompileExpression(expression.Count, new PreferredRegister(Register64.R8)); var indexType = index.ValueType; var valueTypeSize = (sbyte)expression.Type.SizeOf(); Constants.LongType.AssertCanAssignImplicitly(indexType); // Array allocation compiles to function call of HeapAlloc (kernel32) index.GenerateMoveTo(Register64.R8, Constants.LongType, codeGen, linkingInfo); // Parameter 3: byte count if (valueTypeSize > 1) { codeGen.Shl(Register64.R8, (sbyte)Math.Log(valueTypeSize, 2)); // 8 byte type -> multiply count by 8 by shifting left 3 } codeGen.Add(Register64.R8, (sbyte)8); // llama length value codeGen.MovFromDereferenced4(Register64.RCX, Constants.DummyOffsetInt); linkingInfo.FixDataOffset(codeGen.StreamPosition, Constants.HeapHandleIdentifier); // Parameter 1: DefaultHeapHandle codeGen.Xor(Register64.RDX, Register64.RDX); codeGen.Add(Register64.RDX, (sbyte)(0x8 + 0x4)); // Parameter 2: HEAP_ZERO_MEMORY + HEAP_GENERATE_EXCEPTIONS codeGen.CallDereferenced4(Constants.DummyOffsetInt); linkingInfo.FixIATEntryOffset(codeGen.StreamPosition, "kernel32.dll", "HeapAlloc"); return(new ExpressionResult(new Type(expression.Type, Type.WrappingType.ArrayOf), Register64.RAX)); }
public ExpressionResult Compile( IExpression expression, PreferredRegister target, ICompilationContext context ) { switch (expression) { case ArrayAccessExpression arrayAccessExpression: return(context.CompileExpression(arrayAccessExpression, target)); case ArrayAllocationExpression arrayAllocationExpression: return(context.CompileExpression(arrayAllocationExpression, target)); case AtomicExpression atomicExpression: return(context.CompileExpression(atomicExpression, target)); case BinaryOperatorExpression binaryOperatorExpression: return(context.CompileExpression(binaryOperatorExpression, target)); case FunctionCallExpression methodCallExpression: return(context.CompileExpression(methodCallExpression, target)); case TypeCastExpression typeCastExpression: return(context.CompileExpression(typeCastExpression, target)); case UnaryOperatorExpression unaryOperatorExpression: return(context.CompileExpression(unaryOperatorExpression, target)); default: throw new NotImplementedException($"Compiler for expression type \"{expression.GetType().Name}\" has not yet been implemented"); } }
private static ExpressionResult CompileModolu( IExpression left, IExpression right, PreferredRegister target, ICompilationContext context ) { var leftRegisterPref = new PreferredRegister(Register64.RAX, target.FloatRegister); var(leftReg, rightExpr, type) = PrepareBinaryExpression( left, right, leftRegisterPref, context, true ); if (type.IsIntegerRegisterType()) { var typeIsByte = CompileIntegerDivision(context.Generator, context.Linking, type, leftReg, rightExpr); if (typeIsByte) // for byte op. the remainder is stored in 'ah' instead { context.Generator.Write(0x8A, 0xD4); // mov dl, ah } return(new ExpressionResult(type, new PreferredRegister(Register64.RDX).MakeFor(type))); } throw new NotImplementedException( $"{nameof(BinaryOperationCompiler)}: {nameof(CompileModolu)}: I do not know how to compile this type: {type}" ); }
private static ExpressionResult CompileComparison( IExpression left, IExpression right, PreferredRegister target, ICompilationContext context, Action <sbyte> comparisonJmpSigned, Action <sbyte> comparisonJmpUnsignedd, bool inverted = false ) { var(leftReg, rightExpr, type) = PrepareBinaryExpression( left, right, target, context, true ); if (type.IsIntegerRegisterType()) { rightExpr.CmpTo(leftReg, context.Generator, context.Linking); } else if (type == Constants.DoubleType) { rightExpr.ComisdTo(leftReg, context.Generator, context.Linking); } else if (type == Constants.FloatType) { rightExpr.ComissTo(leftReg, context.Generator, context.Linking); } else { throw new NotImplementedException( $"{nameof(BinaryOperationCompiler)}: {nameof(CompileComparison)}: I do not know how to compile this type: {type}" ); } var targetRegister = target.MakeFor(Constants.BoolType); var mov1CodeGen = new CodeGen(); mov1CodeGen.Mov(targetRegister.AsR32(), inverted ? 0 : 1); var mov0CodeGen = new CodeGen(); mov0CodeGen.Mov(targetRegister.AsR32(), inverted ? 1 : 0); mov0CodeGen.Jmp(mov1CodeGen.GetBufferSpan().Length); if (type.IsSignedInteger()) { comparisonJmpSigned((sbyte)mov0CodeGen.GetBufferSpan().Length); } else { comparisonJmpUnsignedd((sbyte)mov0CodeGen.GetBufferSpan().Length); } context.Generator.Write(mov0CodeGen.GetBufferSpan()); context.Generator.Write(mov1CodeGen.GetBufferSpan()); return(new ExpressionResult(Constants.BoolType, targetRegister)); }
public override Expression Compile(ICompilationContext context, BinaryExpression expression) { return(Expression.MakeBinary( expression.NodeType, serializer.Compile(context, expression.Left), serializer.Compile(context, expression.Right) )); }
protected AbstractCompiler(ICodeProviderAdapterFactory codeProviderAdapterFactory, IPreProcessor preProcessor, ICompilationContext context, AspViewCompilerOptions options) { this.preProcessor = preProcessor; this.context = context; this.options = options; codeProvider = codeProviderAdapterFactory.GetAdapter(); InitialiseCompilerParameters(options.Debug); }
public bool TryCompile(IReadOnlyList <MathExpression> arguments, ICompilationContext <object?> context, ITypeHintHandler hinting, out Expression expr) { var arg = arguments.First(); var concatMethod = Helpers.GetMethod <Action <string> >(a => string.Concat(a, a)) !; expr = Expression.Call(typeof(Convert), nameof(Convert.ToString), null, context.Transform(arg)); expr = Expression.Call(concatMethod, Expression.Constant("hello "), expr); return(true); }
public override Expression Compile(ICompilationContext context, LambdaExpression expression) { var parameters = expression.Parameters .Where(parameter => !context.ParametersValues.ContainsKey(parameter.Name)) .Select(parameter => serializer.Compile(context, parameter) as ParameterExpression); return(Expression.Lambda( serializer.Compile(context, expression.Body), false, parameters )); }
public override Expression Compile(ICompilationContext context, ParameterExpression expression) { if (!context.ParametersValues.ContainsKey(expression.Name)) { return(expression); } return(Expression.Constant( Convert.ChangeType(context.ParametersValues[expression.Name], expression.Type), expression.Type )); }
public void Compile( For statement, ICompilationContext context ) { context.Symbols.PushLocalScope(); context.CompileStatement(statement.Variable); var bodyAndIncrement = statement.Instruction.StatementAsBlock().Statements.Concat(new[] { statement.Increment }).ToArray(); var equalWhile = new While(statement.Condition, new CodeBlock(bodyAndIncrement)); _whileCompiler.Compile(equalWhile, context); context.Symbols.PopLocalScope(); }
public void Compile( While statement, ICompilationContext context ) { var codeGen = context.Generator; var conditionStart = codeGen.StreamPosition; var whileConditionResult = context.CompileExpression(statement.Condition, new PreferredRegister(Register64.RAX)); var whileConditionRegister = whileConditionResult.GetOccupiedOrVolatile(Constants.BoolType); whileConditionResult.GenerateMoveTo(whileConditionRegister, Constants.BoolType, codeGen, context.Linking); codeGen.Test(whileConditionRegister, whileConditionRegister); var childContext = context.CreateChildContext(); childContext.CompileStatement(statement.Instruction.StatementAsBlock()); var bodySpan = childContext.Generator.GetBufferSpan(); var bodyLength = bodySpan.Length + JmpIntSize; // assume far jmp will be generated if (bodyLength <= sbyte.MaxValue) { codeGen.Je((sbyte)bodyLength); } else { codeGen.Je(bodyLength); } var farJmpGuessPos = codeGen.StreamPosition; childContext.CopyToContext(context); var offsetToStart = conditionStart - codeGen.StreamPosition; if (offsetToStart >= sbyte.MinValue) { codeGen.Jmp((sbyte)(offsetToStart - JmpSbyteSize)); // near jmp has been generated, but we assume a far jmp above // if this is a near jmp, the other has to be too // so it's safe to say, we just need to edit the byte. // The new value has to fit, because the jmp becomes even nearer. codeGen.GetBufferSpan().Slice((int)farJmpGuessPos - 1, 1)[0] -= (byte)(JmpIntSize - JmpSbyteSize); } else { codeGen.Jmp((int)(offsetToStart - JmpIntSize)); } }
public void Compile( CodeBlock statement, ICompilationContext context ) { context.Symbols.PushLocalScope(); foreach (var subStatement in statement.Statements) { switch (subStatement) { case CodeBlock codeBlock: Compile(codeBlock, context); break; case Declaration declaration: context.CompileStatement(declaration); break; case For @for: context.CompileStatement(@for); break; case If @if: context.CompileStatement(@if); break; case While @while: context.CompileStatement(@while); break; case Return @return: context.CompileStatement(@return); break; case IExpression expression: context.CompileExpression( expression, new PreferredRegister(Register64.RAX, XmmRegister.XMM0) ); break; default: throw new NotImplementedException( $"{nameof(CodeBlockCompiler)}: I do not know how to compile: {subStatement.GetType().Name}" ); } } context.Symbols.PopLocalScope(); }
public void Compile( If statement, ICompilationContext context ) { var preferredRegisterCondition = new PreferredRegister(Register64.RAX); var ifConditionResult = context.CompileExpression(statement.Condition, preferredRegisterCondition); ifConditionResult.GenerateMoveTo(preferredRegisterCondition.MakeFor(Constants.BoolType), context.Generator, context.Linking); context.Generator.Test(Register8.AL, Register8.AL); var ifBody = context.CreateChildContext(); var elseBody = context.CreateChildContext(); if (statement.ElseInstruction != null) { elseBody.CompileStatement(statement.ElseInstruction.StatementAsBlock()); } ifBody.CompileStatement(statement.Instruction.StatementAsBlock()); var elseBodySpan = elseBody.Generator.GetBufferSpan(); if (elseBodySpan.Length > 0) { if (elseBodySpan.Length <= sbyte.MaxValue) { ifBody.Generator.Jmp((sbyte)elseBodySpan.Length); } else { ifBody.Generator.Jmp(elseBodySpan.Length); } } var ifBodySpan = ifBody.Generator.GetBufferSpan(); if (ifBodySpan.Length <= sbyte.MaxValue) { context.Generator.Je((sbyte)ifBodySpan.Length); } else { context.Generator.Je(ifBodySpan.Length); } ifBody.CopyToContext(context); elseBody.CopyToContext(context); }
/// <inheritdoc/> public bool TryCompile(IReadOnlyList <MathExpression> arguments, ICompilationContext <object?> context, ITypeHintHandler typeHintHandler, [MaybeNullWhen(false)] out Expression expr) { // TODO: add logging to contexts if (arguments.Count != 1) { expr = null; return(false); } expr = Expression.Call(Method, CompilerHelpers.ConvertToType( typeHintHandler.TransformWithHint(arguments.First(), typeof(double), context), typeof(double))); return(true); }
public ExpressionResult Compile( AtomicExpression expression, PreferredRegister target, ICompilationContext context ) { return(expression.Token.Kind switch { TokenKind.Identifier => CompileIdentifier(expression, context.Generator, context.Symbols), TokenKind.FloatLiteral => CompileFloatLiteral(expression), TokenKind.IntegerLiteral => CompileIntegerLiteral(expression), TokenKind.StringLiteral => CompileStringLiteral(expression, context.Generator, target, context.Linking), TokenKind.True => CompileTrue(context.Generator, target), TokenKind.False => CompileFalse(context.Generator, target), _ => throw new NotImplementedException($"Atomic expression type {expression.Token.Kind} not implemented") });
public void Compile(Declaration statement, ICompilationContext context) { context.Symbols.DefineLocal(statement.Identifier.RawText, statement.Type); if (statement.InitialValue == null) { context.Generator.Xor(Register64.RAX, Register64.RAX); context.Generator.MovToDereferenced(Register64.RSP, Register64.RAX, context.Symbols.GetLocalOffset(statement.Identifier.RawText)); } else { var initialValue = context.CompileExpression(statement.InitialValue, PreferredRegister.DefaultVolatile); var initialValueRegister = initialValue.ToRegister(statement.Type, context.Generator, context.Linking); context.Symbols.GetLocalReference(statement.Identifier.RawText) .GenerateAssign(initialValueRegister, context.Generator, context.Linking); } }
public void Compile( Return statement, ICompilationContext context ) { if (statement.ReturnValue != null) { var returnRegisters = new PreferredRegister(Register64.RAX, XmmRegister.XMM0); var returnResult = context.CompileExpression(statement.ReturnValue, returnRegisters); var myFunction = context.Symbols.GetFunctionDeclaration(context.Symbols.CurrentFunctionIdentifier); returnResult.GenerateMoveTo(returnRegisters.MakeFor(myFunction.ReturnType), myFunction.ReturnType, context.Generator, context.Linking); } context.Generator.Jmp(Constants.DummyOffsetInt); context.Linking.FixFunctionEpilogueOffset(context.Generator.StreamPosition, context.Symbols.CurrentFunctionIdentifier); }
/// <summary> /// Compiles the given expression using the provided context. /// </summary> /// <param name="expr">the <see cref="MathExpression"/> to compile</param> /// <param name="ctx">the context to compile in</param> /// <returns>the compiled <see cref="Expression"/></returns> public override Expression ApplyTo(MathExpression expr, ICompilationContext <TSettings> ctx) { try { if (!IsRootExpression(ctx)) { return(base.ApplyTo(expr, ctx)); } SetRootExpression(ctx); SetTypeHint(ctx, ctx.Settings.ExpectReturn); var subexpr = base.ApplyTo(expr, ctx); if (subexpr.Type != ctx.Settings.ExpectReturn) { subexpr = CompilerHelpers.ConvertToType(subexpr, ctx.Settings.ExpectReturn); } if (ctx.Settings is IDomainRestrictionSettings domainSettings && !domainSettings.IgnoreDomainRestrictions) { var overflowCtor = Helpers.GetConstructor <Action>(() => new OverflowException("")); subexpr = DomainRestrictionSettings.GetDomainRestrictionsFor(ctx) .Select(e => { SetTypeHint(ctx, typeof(bool)); return(x: CompilerHelpers.ConvertToType(base.ApplyTo(e, ctx), typeof(bool)), e); }) .Aggregate(subexpr, (start, restrict) => Expression.Condition(restrict.x, Expression.Throw(Expression.New(overflowCtor, Expression.Constant($"{restrict.e} not in domain")), start.Type), start)); } return(subexpr); } catch (CompilationException) { throw; } catch (Exception e) { throw new CompilationException(expr, e); } }
/// <summary> /// Evaluates two expressions, and brings them to a common type. Tries to keep the second expression as reference, for /// mor optimal code generation. /// </summary> /// <param name="first"></param> /// <param name="second"></param> /// <param name="preferredFirst"></param> /// <param name="codeGen"></param> /// <param name="storageManager"></param> /// <param name="scope"></param> /// <param name="linkingInfo"></param> /// <param name="context"></param> /// <param name="shouldDereferenceForImplicitCast">The reference may be deferenced to cast it to the common type</param> /// <returns></returns> private static (Register register, ExpressionResult reference, Type type) PrepareBinaryExpression( IExpression first, IExpression second, PreferredRegister preferredFirst, ICompilationContext context, bool shouldDereferenceForImplicitCast = false ) { var firstResult = context.CompileExpression(first, preferredFirst); var isfirstIntegerType = firstResult.ValueType.IsIntegerRegisterType(); var firstTemp = context.Storage.Allocate(isfirstIntegerType); firstTemp.Store(firstResult, context.Generator, context.Linking); var secondResult = context.CompileExpression(second, preferredFirst); var type = firstResult.ValueType; if (firstResult.ValueType != secondResult.ValueType) { if (secondResult.ValueType.CanAssignImplicitly(firstResult.ValueType)) { type = secondResult.ValueType; } else if (shouldDereferenceForImplicitCast && firstResult.ValueType.CanAssignImplicitly(secondResult.ValueType)) { type = firstResult.ValueType; var secondDerefVolatile = secondResult.GetOccupiedOrVolatile(type); secondResult.GenerateMoveTo(secondDerefVolatile, type, context.Generator, context.Linking); secondResult = new ExpressionResult(type, secondDerefVolatile); } else { throw new TypeMismatchException("Any common type", $"{firstResult.ValueType} and {secondResult.ValueType}"); } } var preferredRegister = preferredFirst.MakeFor(type); var firstRegister = secondResult.IsOccopied(preferredRegister) ? secondResult.GetUnoccupiedVolatile(type) : preferredRegister; firstTemp.AsExpressionResult(firstResult.ValueType).GenerateMoveTo(firstRegister, type, context.Generator, context.Linking); context.Storage.Release(firstTemp); return(firstRegister, secondResult, type); }
/// <inheritdoc/> public override Expression ApplyTo(Syntax.BinaryExpression expr, ICompilationContext <TSettings> ctx) { var exprType = expr.Type; var args = expr.Arguments.Select(m => { var origHint = GetTypeHint(ctx); if (exprType.IsComparisonType()) { SetTypeHint(ctx, null); } else if (exprType.IsBooleanType()) { SetTypeHint(ctx, typeof(bool)); } var applied = ApplyTo(m, ctx); SetTypeHint(ctx, origHint); return(applied); }).ToList(); var boolResType = exprType.IsComparisonType() ? typeof(bool) : GetTypeHint(ctx) ?? args.First().Type; try { return(AggregateBinaryExpr(expr.Type, args, boolResType, ctx.Settings)); } catch { // ignore } // if we fail to do it with the base implicitly gotten arguments, attempt to convert all arguments to the same (largest) type var allTypes = args.Select(e => e.Type); var convertAllTo = allTypes .OrderByDescending(CompilerHelpers.EstimateTypeSize) .Where(ty => allTypes.All(t => CompilerHelpers.HasConversionPathTo(t, ty))) .First(); // biggest one boolResType = GetTypeHint(ctx) ?? convertAllTo; // re-compile arguments with new type hint SetTypeHint(ctx, convertAllTo); args = expr.Arguments.Select(m => CompilerHelpers.ConvertToType(ApplyTo(m, ctx), convertAllTo)).ToList(); return(AggregateBinaryExpr(expr.Type, args, boolResType, ctx.Settings)); }
private static ExpressionResult CompileMultiply( IExpression left, IExpression right, PreferredRegister target, ICompilationContext context ) { var tempRegister = new PreferredRegister(Register64.RAX, target.FloatRegister); var(leftReg, rightExpr, type) = PrepareBinaryExpression( left, right, tempRegister, context, true ); if (type.IsIntegerRegisterType()) { if (type.SizeOf() == 1) { throw new NotImplementedException("Multiplications with 8-bit types are not implemented"); } rightExpr.ImulTo(leftReg, context.Generator, context.Linking); } else if (type == Constants.DoubleType) { rightExpr.MulsdTo(leftReg, context.Generator, context.Linking); } else if (type == Constants.FloatType) { rightExpr.MulssTo(leftReg, context.Generator, context.Linking); } else { throw new NotImplementedException( $"{nameof(BinaryOperationCompiler)}: {nameof(CompileMultiply)}: I do not know how to compile this type: {type}" ); } return(new ExpressionResult(type, leftReg)); }
private static ExpressionResult CompileDivide( IExpression left, IExpression right, PreferredRegister target, ICompilationContext context ) { var leftRegisterPref = new PreferredRegister(Register64.RAX, target.FloatRegister); var(leftReg, rightExpr, type) = PrepareBinaryExpression( left, right, leftRegisterPref, context, true ); if (type.IsIntegerRegisterType()) { CompileIntegerDivision(context.Generator, context.Linking, type, leftReg, rightExpr); return(new ExpressionResult(type, new PreferredRegister(Register64.RAX).MakeFor(type))); } if (type == Constants.DoubleType) { rightExpr.DivsdTo(leftReg, context.Generator, context.Linking); } else if (type == Constants.FloatType) { rightExpr.DivssTo(leftReg, context.Generator, context.Linking); } else { throw new NotImplementedException( $"{nameof(BinaryOperationCompiler)}: {nameof(CompileDivide)}: I do not know how to compile this type: {type}" ); } return(new ExpressionResult(type, leftReg)); }
public ExpressionResult Compile( ArrayAccessExpression expression, PreferredRegister target, ICompilationContext context ) { var arrayTemp = context.Storage.Allocate(true); var array = context.CompileExpression(expression.Array, arrayTemp.IsRegister ? arrayTemp.Register : Register64.RAX); var arrayType = array.ValueType; arrayTemp.Store(array, context.Generator, context.Linking); const Register64 structOffsetRegister = Register64.RCX; const Register64 arrayRegister = Register64.RAX; var arrayIndex = context.CompileExpression(expression.Index, new PreferredRegister(structOffsetRegister)); Constants.LongType.AssertCanAssignImplicitly(arrayIndex.ValueType); arrayIndex.GenerateMoveTo(structOffsetRegister, Constants.LongType, context.Generator, context.Linking); arrayTemp.AsExpressionResult(arrayType).GenerateMoveTo(arrayRegister, context.Generator, context.Linking); context.Storage.Release(arrayTemp); if (arrayType == Constants.CstrType) { return(new ExpressionResult(Constants.SbyteType, arrayRegister, structOffsetRegister, 1)); } var itemType = arrayType.Child; if (arrayType.ChildRelation == Type.WrappingType.PointerOf) { return(new ExpressionResult(itemType, arrayRegister, structOffsetRegister, (byte)itemType.SizeOf())); } if (arrayType.ChildRelation == Type.WrappingType.ArrayOf) { return(new ExpressionResult(itemType, arrayRegister, structOffsetRegister, (byte)itemType.SizeOf(), 8)); } throw new TypeMismatchException("Array or pointer", arrayType.ToString()); }
public Expression Compile(ICompilationContext context, Expression expression) { var expressionType = expression.GetType(); object handler; do { handler = serviceProvider.GetService( typeof(IExpressionCompiler <>).MakeGenericType(expressionType) ); expressionType = expressionType.GetTypeInfo().BaseType; }while (handler == null && expressionType != typeof(Expression)); if (handler == null) { throw new InvalidOperationException( $"No compiler registered for expression type {expression.GetType()}" ); } return((handler as IExpressionCompiler).Compile(context, expression)); }
/// <inheritdoc/> public bool TryCompile(IReadOnlyList <MathExpression> arguments, ICompilationContext <object?> ctx, ITypeHintHandler hintHandler, [MaybeNullWhen(false)] out Expression expr) { if (arguments.Count != 3) { expr = null; return(false); } var condition = hintHandler.TransformWithHint(arguments.First(), typeof(bool), ctx); var hint = hintHandler.CurrentHint(ctx); Expression?thenExpr = null, elseExpr = null; Type? convertAllTo, lastThen, lastElse; do { lastThen = thenExpr?.Type; lastElse = elseExpr?.Type; thenExpr = hintHandler.TransformWithHint(arguments[1], hint, ctx); elseExpr = hintHandler.TransformWithHint(arguments[2], hint, ctx); var allTypes = new[] { thenExpr.Type, elseExpr.Type }; convertAllTo = allTypes .OrderByDescending(CompilerHelpers.EstimateTypeSize) .Where(ty => allTypes.All(t => CompilerHelpers.HasConversionPathTo(t, ty))) .FirstOrDefault(); // biggest one }while (thenExpr.Type != elseExpr.Type && thenExpr.Type != convertAllTo && lastThen != thenExpr.Type && lastElse != elseExpr.Type); if (convertAllTo == null) { throw new ArgumentException("True and False branches of condition do not have a common type to be converted to"); } expr = Expression.Condition(CompilerHelpers.AsBoolean(condition), CompilerHelpers.ConvertToType(thenExpr, convertAllTo), CompilerHelpers.ConvertToType(elseExpr, convertAllTo)); return(true); }
private static ExpressionResult CompileAny( IExpression left, IExpression right, Action <ExpressionResult, Register, CodeGen, ILinkingInfo> actionInt, Action <ExpressionResult, Register, CodeGen, ILinkingInfo> actionFloat, Action <ExpressionResult, Register, CodeGen, ILinkingInfo> actionDouble, PreferredRegister target, ICompilationContext context ) { var(leftReg, rightExpr, type) = PrepareBinaryExpression( left, right, target, context, true ); if (type.IsIntegerRegisterType()) { actionInt(rightExpr, leftReg, context.Generator, context.Linking); } else if (type == Constants.DoubleType) { actionDouble(rightExpr, leftReg, context.Generator, context.Linking); } else if (type == Constants.FloatType) { actionFloat(rightExpr, leftReg, context.Generator, context.Linking); } else { throw new NotImplementedException( $"{nameof(BinaryOperationCompiler)}: {nameof(CompileAny)}: I do not know how to compile this type: {type}" ); } return(new ExpressionResult(type, leftReg)); }
private void CompileFunction(FunctionImplementation function, ICompilationContext context) { foreach (var parameter in function.Declaration.Parameters) { context.Symbols.DefineLocal(parameter.ParameterIdentifier.RawText, parameter.ParameterType); } if (function.Declaration.Identifier.RawText == "Main") { context.Generator.CallDereferenced4(Constants.DummyOffsetInt); context.Linking.FixIATEntryOffset(context.Generator.StreamPosition, "kernel32.dll", "GetProcessHeap"); context.Generator.MovToDereferenced4(Constants.DummyOffsetInt, Register64.RAX); context.Linking.FixDataOffset(context.Generator.StreamPosition, Constants.HeapHandleIdentifier); } context.CompileStatement(function.Body.StatementAsBlock()); context.Generator.InsertCode(context.Linking, 0, gen => context.Storage.CreatePrologue(gen, function.Declaration)); context.Linking.ResolveFunctionEpilogueFixes(function.Declaration.Identifier.RawText, context.Generator.StreamPosition); context.Storage.CreateEpilogue(context.Generator); context.Generator.Ret(); }
public ExpressionResult Compile(UnaryOperatorExpression expression, PreferredRegister target, ICompilationContext context) { return(expression.Operator.Operator.Kind switch { TokenKind.Minus => CompileMinus(expression, target, context), TokenKind.AddressOf => CompileAddressOf(expression, target, context), TokenKind.Not => CompileNot(expression, target, context), TokenKind.Pointer => CompileDereference(expression, target, context), _ => throw new NotImplementedException( $"{nameof(UnaryOperationCompiler)}: I do not know how to compile {expression.Operator.Operator}" ) });
void IAspViewEngineTestAccess.SetCompilationContext(ICompilationContext context) { compilationContext = context; }
public OnlineCompiler(ICodeProviderAdapterFactory codeProviderAdapterFactory, IPreProcessor preProcessor, ICompilationContext context, AspViewCompilerOptions options) : base(codeProviderAdapterFactory, preProcessor, context, options) { parameters.GenerateInMemory = true; }
public void Initialize(ICompilationContext context, AspViewEngineOptions newOptions) { options = newOptions; compilationContext = context; Initialize(); }