public UpvalueExpressionGenerator(AllocatedLocal upvalList, int index, LocalVariableDefinitionSyntaxNode definition) : base(0) { _upvalList = upvalList; _index = index; _type = definition.Specialization.GetVMSpecializationType(); }
public static (bool num, bool obj) GetStorageType(this VMSpecializationType specType) { return((specType & VMSpecializationType.StorageBits) switch { VMSpecializationType.StorageRef => (false, true), VMSpecializationType.StorageValue => (true, false), _ => (true, true), });
//This is used by the public ctor and ComparisonBinaryExpressionGenerator. protected BinaryExpressionGenerator(GeneratorFactory factory, BlockGenerator block, ExpressionGenerator left, ExpressionGenerator right, VMSpecializationType type) : base(factory) { _type = type; _left = left; _right = right; var leftType = left.GetSingleType(); var rightType = right.GetSingleType(); if (leftType != VMSpecializationType.Polymorphic || rightType != VMSpecializationType.Polymorphic || _type != VMSpecializationType.Polymorphic) { throw new NotImplementedException(); } //Determine whether we can share the dest slot with one of the operands. //This saves a stack slot. // ? = (expr) + a //will be generated as // dest = (expr) // dest = dest + a //Note that at this point we have no idea what variable (or temp variable) //will be assigned to this binary expr, so for the code // a = (expr) + a //we will get an invalid code if we use the above pattern: // a = (expr) // a = a + a --> Wrong, the value that was in the second a has been lost! //This special case is handled during emit stage. var leftOnStack = left.TryGetFromStack(out _); var rightOnStack = right.TryGetFromStack(out _); if (leftType == _type && !leftOnStack) { _mode = CalcMode.LeftToDest; _rightTemp = block.TempAllocator.Allocate(rightType); } else if (rightType == _type && !rightOnStack) { _mode = CalcMode.RightToDest; _leftTemp = block.TempAllocator.Allocate(leftType); } else { _mode = CalcMode.Normal; if (!leftOnStack) { _leftTemp = block.TempAllocator.Allocate(leftType); } if (!rightOnStack) { _rightTemp = block.TempAllocator.Allocate(rightType); } } }
public override bool TryGetSingleType(out VMSpecializationType type) { if (_isVararg) { type = default; return(false); } type = _type; return(true); }
public UnaryExpressionGenerator(GeneratorFactory factory, BlockGenerator block, UnaryExpressionSyntaxNode expr) : base(factory) { _operand = factory.CreateExpression(block, expr.Operand); _operator = expr.Operator; _type = expr.SpecializationType.GetVMSpecializationType(); if (!_operand.TryGetFromStack(out _)) { _tmpSlot = block.TempAllocator.Allocate(_operand.GetSingleType()); } }
public override void EmitSet(InstructionWriter writer, AllocatedLocal src, VMSpecializationType type) { if (type != _type) { throw new NotImplementedException(); } var srcIndex = src.Offset; var offset = _localInfo.Offset; if (offset > 255 || srcIndex > 255) { throw new NotImplementedException(); } writer.WriteUUU(Opcodes.MOV, offset, srcIndex, 0); }
public IndexVariableGenerator(GeneratorFactory factory, BlockGenerator block, IndexVariableSyntaxNode expr) : base(factory) { _table = factory.CreateExpression(block, expr.Table); _key = factory.CreateExpression(block, expr.Key); _type = expr.SpecializationType.GetVMSpecializationType(); if (!_table.TryGetFromStack(out _)) { _tableStack = block.TempAllocator.Allocate(expr.Table); } if (!_key.TryGetFromStack(out _)) { _keyStack = block.TempAllocator.Allocate(expr.Key); } }
public override void EmitSet(InstructionWriter writer, AllocatedLocal src, VMSpecializationType type) { if (type != _type) { throw new NotImplementedException(); } var srcIndex = src.Offset; var listOffset = _upvalList.Offset; if (srcIndex > 255 | listOffset > 255 | _index > 255) { throw new NotImplementedException(); } writer.WriteUUU(OpCodes.USET, srcIndex, listOffset, _index); }
public AndOrExpressionGenerator(GeneratorFactory factory, BlockGenerator block, BinaryExpressionSyntaxNode expr) : base(factory) { _type = expr.SpecializationType.GetVMSpecializationType(); _left = factory.CreateExpression(block, expr.Left); _right = factory.CreateExpression(block, expr.Right); if (_left.GetSingleType() != _type) { _leftStack = block.TempAllocator.Allocate(_left.GetSingleType()); } if (_right.GetSingleType() != _type) { _rightStack = block.TempAllocator.Allocate(_right.GetSingleType()); } _opcode = expr.Operator.V == BinaryOperator.Raw.And ? OpCodes.ISFC : OpCodes.ISTC; }
public override void EmitSet(InstructionWriter writer, AllocatedLocal src, VMSpecializationType type) { if (!_table.TryGetFromStack(out var tableStack)) { tableStack = _tableStack.Value; } if (!_key.TryGetFromStack(out var keyStack)) { keyStack = _keyStack.Value; } if (tableStack.Offset > 255 || keyStack.Offset > 255 || src.Offset > 255) { throw new NotImplementedException(); } writer.WriteUUU(Opcodes.TSET, src.Offset, tableStack.Offset, keyStack.Offset); }
public LiteralExpressionGenerator(FunctionGenerator func, LiteralExpressionSyntaxNode expr) : base(0) { var type = expr.SpecializationType.GetVMSpecializationType(); var k = func.Constants; _constIndex = type switch { VMSpecializationType.Nil => k.GetUnspecializedNil(), VMSpecializationType.Bool => expr.BoolValue ? k.GetUnspecializedTrue() : k.GetUnspecializedFalse(), VMSpecializationType.Double => k.AddUnspecialized(TypedValue.MakeDouble(expr.DoubleValue)), VMSpecializationType.Int => k.AddUnspecialized(TypedValue.MakeInt(expr.Int32Value)), VMSpecializationType.String => k.AddUnspecialized(TypedValue.MakeString(expr.StringValue)), _ => throw new Exception(), //Internal exception. }; _type = type.Deoptimize(); }
public LocalVariableExpressionGenerator(BlockStackFragment stack, LocalVariableDefinitionSyntaxNode definition) : base(0) { _type = definition.Specialization.GetVMSpecializationType(); _localInfo = stack.AddSpecializedType(_type); }
//For variables: set the value of the variable to the value at src. //EmitPrep will be called before this. public virtual void EmitSet(InstructionWriter writer, AllocatedLocal src, VMSpecializationType type) { throw new NotSupportedException(); }
public VarargExpressionGenerator(GeneratorFactory factory, FunctionDefinitionSyntaxNode func, VarargExpressionSyntaxNode expr) : base(0) { _isVararg = expr.ReceiverMultiRetState == ExpressionReceiverMultiRetState.Variable; _type = func.VarargType.GetVMSpecializationType(); _funcVarargSig = factory.Function.VarargSignature; }
public VarargExpressionGenerator(FunctionDefinitionSyntaxNode func, VarargExpressionSyntaxNode expr) : base(0) { _isVararg = expr.ReceiverMultiRetState == ExpressionReceiverMultiRetState.Variable; _type = func.VarargType.GetVMSpecializationType(); }
public override bool TryGetSingleType(out VMSpecializationType type) { type = _type; return(true); }
public AllocatedLocal Allocate(VMSpecializationType type) { //Allocate a new slot for each temp var. return(_stack.AddSpecializedType(type)); }
public abstract bool TryGetSingleType(out VMSpecializationType type);