示例#1
0
        private void Expand(XILSInstr xilsi)
        {
            var preds     = RemapPreds(xilsi.Preds);
            var expansion = Pattern.Expand(xilsi, preds);

            if (expansion == null)
            {
                ProcessDefault(xilsi);
            }
            else
            {
                foreach (XILSInstr xilsix in expansion)
                {
                    Emit(xilsix);
                }

                if (xilsi.ResultTypes.Length > 0 &&
                    !TypeStack.Peek().Equals(xilsi.ResultTypes.Last()))
                {
                    Emit(
                        DefaultInstructionSet.Instance.Convert()
                        .CreateStk(1, TypeStack.Peek(), xilsi.ResultTypes.Last()));
                }
            }
        }
示例#2
0
        private void CompileRepeat(GMLToken _tok)
        {
            VMLabel vMLabel  = new VMLabel("End", VMB);
            VMLabel vMLabel2 = new VMLabel("Repeat", VMB);

            CompileExpression(_tok.Children[0]);
            eVM_Type eVM_Type = TypeStack.Pop();

            if (eVM_Type != eVM_Type.eVMT_Int)
            {
                Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int);
            }
            Emit(eVM_Instruction.eVMI_DUP, eVM_Type.eVMT_Int);
            EmitI(eVM_Instruction.eVMI_PUSH, 0);
            Emit(eVM_Instruction.eVMI_SET_LE, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int);
            Emit(eVM_Instruction.eVMI_BTRUE, vMLabel);
            LoopEnv.Push(vMLabel2);
            LoopEndEnv.Push(vMLabel);
            vMLabel2.Mark(VMB.Buffer.Position);
            CompileStatement(_tok.Children[1]);
            EmitI(eVM_Instruction.eVMI_PUSH, 1);
            Emit(eVM_Instruction.eVMI_SUB, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int);
            Emit(eVM_Instruction.eVMI_DUP, eVM_Type.eVMT_Int);
            Emit(eVM_Instruction.eVMI_CONV, eVM_Type.eVMT_Int, eVM_Type.eVMT_Bool);
            Emit(eVM_Instruction.eVMI_BTRUE, vMLabel2);
            vMLabel.Mark(VMB.Buffer.Position);
            Emit(eVM_Instruction.eVMI_POPNULL, eVM_Type.eVMT_Int);
            LoopEnv.Pop();
            LoopEndEnv.Pop();
        }
示例#3
0
        private void HandleStoreVar(XILSInstr i)
        {
            int      readPoint;
            Variable local = i.StaticOperand as Variable;

            if (DflowAnalyzer.IsReadAfterWrite(i.Index, out readPoint))
            {
                var preds = RemapPreds(i.Preds);

                // keep expression on the stack, but bury it at the very bottom.
                for (int j = 1; j < _resultStack.Count; j++)
                {
                    var resultTypes = TypeStack.Reverse().Skip(1).Concat(TypeStack.Skip(_resultStack.Count - 1)).ToArray();
                    Emit(DefaultInstructionSet.Instance.Dig(_resultStack.Count - 1).CreateStk(
                             preds,
                             TypeStack.Reverse().ToArray(),
                             resultTypes));
                    preds = new InstructionDependency[0];
                }
                _read2write[readPoint] = _resultStack[0];
            }
            else if (local == null)
            {
                ProcessDefault(i);
            }
            else if (DflowAnalyzer.EliminableLocals.Contains(local.LocalIndex))
            {
                Emit(DefaultInstructionSet.Instance.Pop().CreateStk(1, local.Type));
            }
            else
            {
                ProcessDefault(i);
            }
        }
        /// <summary>
        /// Emit code storing the value on the stack to memory
        /// </summary>
        /// <param name="name"></param>
        /// <param name="types"></param>
        public void Store(VariableName name, TypeStack <TEmit> types)
        {
            // Update the type tracker with the newly discovered type
            _types.Store(name, types.Peek);

            if (_cache.ContainsKey(name))
            {
                var local = _cache[name];

                // Convert to the correct type for this local
                var inType = types.Peek;
                ConvertType(inType, local.Type);
                types.Pop(inType);

                // Store in appropriate local
                _emitter.StoreLocal(local.Local);

                // Mark cache dirty
                _emitter.LoadConstant(true);
                _emitter.StoreLocal(_cacheDirty[name]);
            }
            else
            {
                // Immediately convert type to YololValue
                ConvertType(types.Peek, StackType.YololValue);
                types.Pop(types.Peek);

                // Write directly to backing store
                EmitStoreValue(name);
            }
        }
示例#5
0
        private void CompilePop(GMLToken _tok, eVM_Type _type)
        {
            switch (_tok.Token)
            {
            case eToken.eVariable:
            case eToken.eDot:
                if (_tok.Children.Count >= 2)
                {
                    int num = 0;
                    CompileExpression(_tok.Children[0]);
                    if (TypeStack.Peek() != eVM_Type.eVMT_Int)
                    {
                        Emit(eVM_Instruction.eVMI_CONV, TypeStack.Pop(), eVM_Type.eVMT_Int);
                        TypeStack.Push(eVM_Type.eVMT_Int);
                    }
                    if (_tok.Children[1].Children.Count > 0)
                    {
                        CompileExpression(_tok.Children[1].Children[0]);
                        if (TypeStack.Peek() != eVM_Type.eVMT_Int)
                        {
                            Emit(eVM_Instruction.eVMI_CONV, TypeStack.Pop(), eVM_Type.eVMT_Int);
                            TypeStack.Push(eVM_Type.eVMT_Int);
                        }
                        if (_tok.Children[1].Children.Count > 1)
                        {
                            EmitI(eVM_Instruction.eVMI_PUSH, 32000);
                            Emit(eVM_Instruction.eVMI_MUL, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int);
                            CompileExpression(_tok.Children[1].Children[1]);
                            if (TypeStack.Peek() != eVM_Type.eVMT_Int)
                            {
                                Emit(eVM_Instruction.eVMI_CONV, TypeStack.Pop(), eVM_Type.eVMT_Int);
                                TypeStack.Push(eVM_Type.eVMT_Int);
                            }
                            Emit(eVM_Instruction.eVMI_ADD, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int);
                            TypeStack.Pop();
                        }
                        TypeStack.Pop();
                    }
                    else
                    {
                        num |= int.MinValue;
                    }
                    TypeStack.Pop();
                    EmitIVar(eVM_Instruction.eVMI_POP, _tok.Children[1].Id | num, _type);
                    TypeStack.Push(eVM_Type.eVMT_Variable);
                }
                else
                {
                    Error("Malformed variable reference", _tok);
                }
                break;

            case eToken.eConstant:
                Error("Unsure where these come from", _tok);
                break;
            }
        }
示例#6
0
        private void BinaryTypeCoercion(GMLToken _tok, int _parmNum)
        {
            eVM_Type eVM_Type = TypeStack.Peek();

            switch (_tok.Children[1].Token)
            {
            case eToken.eNot:
            case eToken.eLess:
            case eToken.eLessEqual:
            case eToken.eEqual:
            case eToken.eNotEqual:
            case eToken.eGreaterEqual:
            case eToken.eGreater:
            case eToken.eBitNegate:
                break;

            case eToken.ePlus:
            case eToken.eMinus:
            case eToken.eTime:
            case eToken.eDivide:
            case eToken.eDiv:
            case eToken.eMod:
                if (eVM_Type == eVM_Type.eVMT_Bool)
                {
                    TypeStack.Pop();
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int);
                    TypeStack.Push(eVM_Type.eVMT_Int);
                }
                break;

            case eToken.eAnd:
            case eToken.eOr:
            case eToken.eXor:
                if (eVM_Type != eVM_Type.eVMT_Bool)
                {
                    TypeStack.Pop();
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Bool);
                    TypeStack.Push(eVM_Type.eVMT_Bool);
                }
                break;

            case eToken.eBitOr:
            case eToken.eBitAnd:
            case eToken.eBitXor:
            case eToken.eBitShiftLeft:
            case eToken.eBitShiftRight:
                if (eVM_Type == eVM_Type.eVMT_Int)
                {
                    TypeStack.Pop();
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int);
                    TypeStack.Push(eVM_Type.eVMT_Int);
                }
                break;
            }
        }
示例#7
0
        private void CompileUnary(GMLToken _tok)
        {
            CompileExpression(_tok.Children[0]);
            eVM_Type eVM_Type = TypeStack.Peek();

            switch (_tok.Id)
            {
            case 203:
                switch (eVM_Type)
                {
                case eVM_Type.eVMT_String:
                case eVM_Type.eVMT_Error:
                    Error("Unable to Not a string", _tok);
                    break;

                case eVM_Type.eVMT_Double:
                case eVM_Type.eVMT_Float:
                case eVM_Type.eVMT_Int:
                case eVM_Type.eVMT_Long:
                case eVM_Type.eVMT_Variable:
                    TypeStack.Pop();
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Bool);
                    TypeStack.Push(eVM_Type.eVMT_Bool);
                    eVM_Type = eVM_Type.eVMT_Bool;
                    break;
                }
                Emit(eVM_Instruction.eVMI_NOT, eVM_Type);
                break;

            case 211:
                Emit(eVM_Instruction.eVMI_NEG, eVM_Type);
                break;

            case 220:
                switch (eVM_Type)
                {
                case eVM_Type.eVMT_String:
                case eVM_Type.eVMT_Error:
                    Error("Unable to Negate a string", _tok);
                    break;

                case eVM_Type.eVMT_Double:
                case eVM_Type.eVMT_Float:
                case eVM_Type.eVMT_Variable:
                    TypeStack.Pop();
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int);
                    TypeStack.Push(eVM_Type.eVMT_Int);
                    eVM_Type = eVM_Type.eVMT_Int;
                    break;
                }
                Emit(eVM_Instruction.eVMI_NOT, eVM_Type);
                break;
            }
        }
示例#8
0
        private void Dig(InstructionDependency[] preds, int index)
        {
            var otypes = new TypeDescriptor[index + 1];
            var rtypes = new TypeDescriptor[index + 1];

            for (int i = 0; i < otypes.Length; i++)
            {
                otypes[i] = TypeStack.ElementAt(index - i);
                rtypes[i] = TypeStack.ElementAt(i == index ? index : index - i - 1);
            }
            Emit(DefaultInstructionSet.Instance.Dig(index).CreateStk(preds, otypes, rtypes));
        }
示例#9
0
        protected override void ProcessInstruction(XILSInstr i)
        {
            var rTypes  = i.ResultTypes;
            var opTypes = new TypeDescriptor[i.OperandTypes.Length];

            for (int j = 0; j < opTypes.Length; j++)
            {
                opTypes[j] = TypeStack.ElementAt(opTypes.Length - 1 - j);
            }
            var inew = i.Command.CreateStk(i.Preds, opTypes, rTypes);

            base.ProcessInstruction(inew);
        }
示例#10
0
 private void CompileFunction(GMLToken _tok)
 {
     foreach (GMLToken child in _tok.Children)
     {
         CompileExpression(child);
         eVM_Type eVM_Type = TypeStack.Pop();
         if (eVM_Type != eVM_Type.eVMT_Variable)
         {
             Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Variable);
         }
     }
     EmitI(eVM_Instruction.eVMI_CALL, _tok.Id);
     TypeStack.Push(GMAssetCompiler.eVM_Type.eVMT_Variable);
 }
示例#11
0
        private void CompileConstant(GMLToken _tok)
        {
            switch (_tok.Value.Kind)
            {
            case eKind.eConstant:
                Error("constant token", _tok);
                break;

            case eKind.eNone:
                Error("None constant token", _tok);
                break;

            case eKind.eNumber:
            {
                double num = (long)_tok.Value.ValueI;
                if (num == _tok.Value.ValueI)
                {
                    long num2 = (long)_tok.Value.ValueI;
                    if (num2 > int.MaxValue || num2 < int.MinValue)
                    {
                        EmitI(eVM_Instruction.eVMI_PUSH, num2);
                        TypeStack.Push(eVM_Type.eVMT_Long);
                    }
                    else if (num2 > 32767 || num2 < -32768)
                    {
                        EmitI(eVM_Instruction.eVMI_PUSH, (int)num2);
                        TypeStack.Push(eVM_Type.eVMT_Int);
                    }
                    else
                    {
                        VMB.Add(VMBuffer.EncodeInstructionArg(192, 15) | (int)(num2 & 0xFFFF));
                        TypeStack.Push(eVM_Type.eVMT_Int);
                    }
                }
                else
                {
                    EmitI(eVM_Instruction.eVMI_PUSH, _tok.Value.ValueI);
                    TypeStack.Push(eVM_Type.eVMT_Double);
                }
                break;
            }

            case eKind.eString:
                EmitI(eVM_Instruction.eVMI_PUSH, _tok.Value.ValueS);
                TypeStack.Push(eVM_Type.eVMT_String);
                break;
            }
        }
示例#12
0
 private void AnalyzeUsage(INamedTypeSymbol symbol)
 {
     if (!ValidateUsage(symbol))
     {
         return;
     }
     if (symbol.ContainingAssembly != Assembly)
     {
         if (!SolutionAssemblyNames.Contains(symbol.ContainingAssembly.MetadataName))
         {
             // filter out target types from outside of our solution assemblies
             return;
         }
         ExternalTypesUsed.Add(symbol);
         if (TypeStack.Count > 0)
         {
             var dependentSet = GetDependentsSet(symbol);
             dependentSet.Add(TypeStack.Peek());
         }
     }
 }
示例#13
0
        private bool SubsumedInner(DataType type1, DataType type2, TypeStack typeStack)
        {
            if (typeStack.Contains(type1, type2))
            {
                return(true);
            }

            if (type1.IsUnknownType() || type1 == DataType.None || type1.Equals(type2))
            {
                return(true);
            }

            if (type1 is TupleType tuple1 && type2 is TupleType tuple2)
            {
                List <DataType> elems1 = tuple1.eltTypes;
                List <DataType> elems2 = tuple2.eltTypes;

                if (elems1.Count == elems2.Count)
                {
                    typeStack.Push(type1, type2);
                    for (int i = 0; i < elems1.Count; i++)
                    {
                        if (!SubsumedInner(elems1[i], elems2[i], typeStack))
                        {
                            typeStack.Pop(type1, type2);
                            return(false);
                        }
                    }
                }
                return(true);
            }

            if (type1 is ListType list1 && type2 is ListType list2)
            {
                return(SubsumedInner(list1.ToTupleType(), list2.ToTupleType(), typeStack));
            }
            return(false);
        }
示例#14
0
        private bool subsumedInner(DataType type1, DataType type2, TypeStack typeStack)
        {
            if (typeStack.contains(type1, type2))
            {
                return(true);
            }

            if (type1.isUnknownType() || type1 == DataType.None || type1.Equals(type2))
            {
                return(true);
            }

            if (type1 is TupleType && type2 is TupleType)
            {
                List <DataType> elems1 = ((TupleType)type1).eltTypes;
                List <DataType> elems2 = ((TupleType)type2).eltTypes;

                if (elems1.Count == elems2.Count)
                {
                    typeStack.push(type1, type2);
                    for (int i = 0; i < elems1.Count; i++)
                    {
                        if (!subsumedInner(elems1[i], elems2[i], typeStack))
                        {
                            typeStack.pop(type1, type2);
                            return(false);
                        }
                    }
                }
                return(true);
            }

            if (type1 is ListType && type2 is ListType)
            {
                return(subsumedInner(((ListType)type1).toTupleType(), ((ListType)type2).toTupleType(), typeStack));
            }
            return(false);
        }
示例#15
0
        private void ProcessStoreVariable(XILSInstr i)
        {
            var lit   = (IStorableLiteral)i.StaticOperand;
            var local = lit as Variable;
            IStorableLiteral newLit;

            if (local != null)
            {
                Variable newLocal;
                if (!_localDic.TryGetValue(local.Name, out newLocal))
                {
                    newLocal = new Variable(TypeStack.Peek())
                    {
                        Name = local.Name
                    };
                    _localDic[local.Name] = newLocal;
                }
                newLit = newLocal;
            }
            else
            {
                newLit = lit;
            }
            var preds = RemapPreds(i.Preds);

            if (!TypeStack.Peek().Equals(newLit.Type))
            {
                Convert(preds, TypeStack.Peek(), newLit.Type);
                preds = new InstructionDependency[0];
            }
            var inew = new XILSInstr(
                DefaultInstructionSet.Instance.StoreVar(newLit),
                preds,
                new TypeDescriptor[] { newLit.Type },
                new TypeDescriptor[0]);

            Emit(inew);
        }
        /// <summary>
        /// Emit code to load a value onto the stack
        /// </summary>
        /// <param name="name"></param>
        /// <param name="types"></param>
        public void Load(VariableName name, TypeStack <TEmit> types)
        {
            // Check if we know what type this variable is
            var type = _types.TypeOf(name) ?? StackType.YololValue;

            if (_cache.ContainsKey(name))
            {
                var local = _cache[name];
                _emitter.LoadLocal(local.Local);

                ConvertType(local.Type, type);
                types.Push(type);
            }
            else
            {
                // Load from backing store
                EmitLoadValue(name);

                // Unbox it to that type (bypassing dynamic type checking)
                StaticUnbox(type);
                types.Push(type);
            }
        }
示例#17
0
        private void Initialize()
        {
            Contexts.Push(this);
            TypeStack.Push(ModelType);

            var serializable = Model as ISerializable;

            if (serializable != null)
            {
                var registrationInfo = ReferenceManager.GetInfo(serializable, Context.ShouldAutoGenerateGraphIds(this));

                //// Note: we need to use the x.Tag instead of x.Instance.ContextMode here because we might be serializing a different thing
                //switch ((SerializationContextMode)x.Tag)
                switch (ContextMode)
                {
                case SerializationContextMode.Serialization:
                    if (!registrationInfo.HasCalledSerializing)
                    {
                        serializable.StartSerialization();
                        registrationInfo.HasCalledSerializing = true;
                    }
                    break;

                case SerializationContextMode.Deserialization:
                    if (!registrationInfo.HasCalledDeserializing)
                    {
                        serializable.StartDeserialization();
                        registrationInfo.HasCalledDeserializing = true;
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
示例#18
0
        private void Uninitialize()
        {
            var serializable = Model as ISerializable;

            if (serializable != null)
            {
                var registrationInfo = ReferenceManager.GetInfo(serializable);

                //// Note: we need to use the x.Tag instead of x.Instance.ContextMode here because we might be serializing a different thing
                //switch ((SerializationContextMode)x.Tag)
                switch (ContextMode)
                {
                case SerializationContextMode.Serialization:
                    if (!registrationInfo.HasCalledSerialized)
                    {
                        serializable.FinishSerialization();
                        registrationInfo.HasCalledSerialized = true;
                    }
                    break;

                case SerializationContextMode.Deserialization:
                    if (!registrationInfo.HasCalledDeserialized)
                    {
                        serializable.FinishDeserialization();
                        registrationInfo.HasCalledDeserialized = true;
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            TypeStack.Pop();
            Contexts.Pop();
        }
示例#19
0
        private void HandleLoadVar(XILSInstr i)
        {
            Tuple <int, int> stackRef;

            if (_read2write.TryGetValue(i.Index, out stackRef))
            {
                int stackP = _resultStack.IndexOf(stackRef);
                Debug.Assert(stackP >= 0);
                Debug.Assert(_resultStack.Count == TypeStack.Count);
                int depth = _resultStack.Count;
                int relP  = depth - stackP - 1;
                if (relP > 0)
                {
                    var preds = RemapPreds(i.Preds);
                    TypeDescriptor[] opTypes = TypeStack.Take(depth - stackP).Reverse().ToArray();
                    Debug.Assert(opTypes.First().Equals(i.ResultTypes[0]));
                    TypeDescriptor[] rTypes = (TypeDescriptor[])opTypes.Clone();
                    for (int j = 1; j <= relP; j++)
                    {
                        var tmp = rTypes[j];
                        rTypes[j]     = rTypes[j - 1];
                        rTypes[j - 1] = tmp;

                        var tmpi = _resultStack[stackP + j];
                        _resultStack[stackP + j]     = _resultStack[stackP + j - 1];
                        _resultStack[stackP + j - 1] = tmpi;
                    }
                    TypeDescriptor[] allTypes = opTypes.Concat(rTypes).ToArray();
                    base.Emit(DefaultInstructionSet.Instance.Dig(relP).CreateStk(preds, opTypes.Length, allTypes));
                }
            }
            else
            {
                ProcessDefault(i);
            }
        }
示例#20
0
        private void CompileBinary(GMLToken _tok)
        {
            CompileExpression(_tok.Children[0]);
            BinaryTypeCoercion(_tok, 1);
            CompileExpression(_tok.Children[2]);
            BinaryTypeCoercion(_tok, 2);
            eVM_Type eVM_Type  = TypeStack.Pop();
            eVM_Type eVM_Type2 = TypeStack.Pop();
            int      num       = TypeSize(eVM_Type);
            int      num2      = TypeSize(eVM_Type2);
            eVM_Type item      = (num > num2) ? eVM_Type : eVM_Type2;

            switch (_tok.Children[1].Token)
            {
            case eToken.eTime:
                Emit(eVM_Instruction.eVMI_MUL, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eDivide:
                Emit(eVM_Instruction.eVMI_DIV, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eDiv:
                Emit(eVM_Instruction.eVMI_REM, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eMod:
                Emit(eVM_Instruction.eVMI_MOD, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.ePlus:
                Emit(eVM_Instruction.eVMI_ADD, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eMinus:
                Emit(eVM_Instruction.eVMI_SUB, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eLess:
                Emit(eVM_Instruction.eVMI_SET_LT, eVM_Type, eVM_Type2);
                TypeStack.Push(eVM_Type.eVMT_Bool);
                break;

            case eToken.eLessEqual:
                Emit(eVM_Instruction.eVMI_SET_LE, eVM_Type, eVM_Type2);
                TypeStack.Push(eVM_Type.eVMT_Bool);
                break;

            case eToken.eAssign:
            case eToken.eEqual:
                Emit(eVM_Instruction.eVMI_SET_EQ, eVM_Type, eVM_Type2);
                TypeStack.Push(eVM_Type.eVMT_Bool);
                break;

            case eToken.eNotEqual:
                Emit(eVM_Instruction.eVMI_SET_NE, eVM_Type, eVM_Type2);
                TypeStack.Push(eVM_Type.eVMT_Bool);
                break;

            case eToken.eGreaterEqual:
                Emit(eVM_Instruction.eVMI_SET_GE, eVM_Type, eVM_Type2);
                TypeStack.Push(eVM_Type.eVMT_Bool);
                break;

            case eToken.eGreater:
                Emit(eVM_Instruction.eVMI_SET_GT, eVM_Type, eVM_Type2);
                TypeStack.Push(eVM_Type.eVMT_Bool);
                break;

            case eToken.eAnd:
            case eToken.eBitAnd:
                Emit(eVM_Instruction.eVMI_AND, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eOr:
            case eToken.eBitOr:
                Emit(eVM_Instruction.eVMI_OR, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eXor:
            case eToken.eBitXor:
                Emit(eVM_Instruction.eVMI_XOR, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eBitShiftLeft:
                Emit(eVM_Instruction.eVMI_SHL, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;

            case eToken.eBitShiftRight:
                Emit(eVM_Instruction.eVMI_SHR, eVM_Type, eVM_Type2);
                TypeStack.Push(item);
                break;
            }
        }
示例#21
0
 private void Swap(InstructionDependency[] preds)
 {
     Emit(DefaultInstructionSet.Instance.Dig(1).CreateStk(preds, 2,
                                                          TypeStack.ElementAt(1), TypeStack.Peek(),
                                                          TypeStack.Peek(), TypeStack.ElementAt(1)));
 }
示例#22
0
        private void EmitIndexComputation(Array array)
        {
            MemoryMappedStorage mms    = GetDataLayout(array);
            ArrayMemoryLayout   layout = mms.Layout as ArrayMemoryLayout;

            if (layout.ElementsPerWord > 1)
            {
                throw new NotImplementedException("Multiple elements per word not yet implemented");
            }
            MemoryRegion region = mms.Region;
            IMarshalInfo minfo  = region.MarshalInfo;

            int            shiftWidth = MathExt.CeilLog2(mms.Region.AddressWidth);
            TypeDescriptor indexType  = TypeDescriptor.GetTypeOf(mms.BaseAddress);

            for (int i = 0; i < layout.Strides.Length; i++)
            {
                TypeDescriptor orgIndexType;
                if (i > 0)
                {
                    orgIndexType = TypeStack.Skip(1).First();
                    Emit(_iset.Swap().CreateStk(2, orgIndexType, indexType, indexType, orgIndexType));
                }
                else
                {
                    orgIndexType = TypeStack.Peek();
                }

                ulong stride = layout.Strides[layout.Strides.Length - i - 1];

                if (MathExt.IsPow2(stride))
                {
                    Emit(_iset.Convert().CreateStk(1, orgIndexType, indexType));
                    int ishift = MathExt.CeilLog2(stride);
                    if (ishift > 0)
                    {
                        Unsigned       shift     = Unsigned.FromULong((ulong)ishift, shiftWidth);
                        TypeDescriptor shiftType = TypeDescriptor.GetTypeOf(shift);
                        Emit(_iset.LdConst(shift).CreateStk(0, shiftType));
                        Emit(_iset.LShift().CreateStk(2, indexType, shiftType, indexType));
                    }
                }
                else
                {
                    throw new NotImplementedException("Stride ain't a power of 2");
                }

                if (i > 0)
                {
                    Emit(_iset.Or().CreateStk(2, indexType, indexType, indexType));
                }
            }

            if (mms.BaseAddress.ULongValue != 0)
            {
                Emit(_iset.LdConst(mms.BaseAddress).CreateStk(0, indexType));
                if (minfo.UseStrongPow2Alignment)
                {
                    Emit(_iset.Or().CreateStk(2, indexType, indexType, indexType));
                }
                else
                {
                    Emit(_iset.Add().CreateStk(2, indexType, indexType, indexType));
                }
            }
        }
示例#23
0
        private void CompileAssign(GMLToken _tok)
        {
            switch (_tok.Children[1].Token)
            {
            case eToken.eAssign:
                CompileExpression(_tok.Children[2]);
                CompilePop(_tok.Children[0], TypeStack.Pop());
                break;

            case eToken.eAssignPlus:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type3 = TypeStack.Pop();
                if (eVM_Type3 == eVM_Type.eVMT_Bool)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type3, eVM_Type.eVMT_Int);
                    eVM_Type3 = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_ADD, eVM_Type3, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }

            case eToken.eAssignMinus:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type7 = TypeStack.Pop();
                if (eVM_Type7 == eVM_Type.eVMT_Bool)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type7, eVM_Type.eVMT_Int);
                    eVM_Type7 = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_SUB, eVM_Type7, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }

            case eToken.eAssignTimes:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type2 = TypeStack.Pop();
                if (eVM_Type2 == eVM_Type.eVMT_Bool)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type2, eVM_Type.eVMT_Int);
                    eVM_Type2 = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_MUL, eVM_Type2, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }

            case eToken.eAssignDivide:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type6 = TypeStack.Pop();
                if (eVM_Type6 == eVM_Type.eVMT_Bool)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type6, eVM_Type.eVMT_Int);
                    eVM_Type6 = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_DIV, eVM_Type6, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }

            case eToken.eAssignOr:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type4 = TypeStack.Pop();
                if (eVM_Type4 != eVM_Type.eVMT_Int && eVM_Type4 != eVM_Type.eVMT_Long)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type4, eVM_Type.eVMT_Int);
                    eVM_Type4 = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_OR, eVM_Type4, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }

            case eToken.eAssignAnd:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type5 = TypeStack.Pop();
                if (eVM_Type5 != eVM_Type.eVMT_Int && eVM_Type5 != eVM_Type.eVMT_Long)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type5, eVM_Type.eVMT_Int);
                    eVM_Type5 = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_AND, eVM_Type5, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }

            case eToken.eAssignXor:
            {
                CompileVariable(_tok.Children[0]);
                TypeStack.Pop();
                CompileExpression(_tok.Children[2]);
                eVM_Type eVM_Type = TypeStack.Pop();
                if (eVM_Type != eVM_Type.eVMT_Int && eVM_Type != eVM_Type.eVMT_Long)
                {
                    Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int);
                    eVM_Type = eVM_Type.eVMT_Int;
                }
                Emit(eVM_Instruction.eVMI_XOR, eVM_Type, eVM_Type.eVMT_Variable);
                CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable);
                break;
            }
            }
        }
示例#24
0
 public State()
 {
     stack = new TypeStack();
 }