Esempio n. 1
0
            /// <summary>
            /// Create the stack after this bytecode has executed, based on StackBefore.
            /// </summary>
            public StackSlot[] CreateNewStack()
            {
                switch (Code)
                {
                case AstCode.Dup_x1:
                    return(StackSlot.ModifyStackDupX1(StackBefore));

                case AstCode.Dup_x2:
                    return(StackSlot.ModifyStackDupX2(StackBefore));

                case AstCode.Dup2:
                    return(StackSlot.ModifyStackDup2(StackBefore));

                case AstCode.Dup2_x1:
                    return(StackSlot.ModifyStackDup2X1(StackBefore));

                case AstCode.Dup2_x2:
                    return(StackSlot.ModifyStackDup2X2(StackBefore));

                case AstCode.Swap:
                    return(StackSlot.ModifyStackSwap(StackBefore));

                case AstCode.Pop2:
                    return(StackSlot.ModifyStackPop2(StackBefore));

                default:
                    return(StackSlot.ModifyStack(StackBefore, PopCount ?? StackBefore.Length, PushCount, this));
                }
            }
Esempio n. 2
0
            public StackSlot SpillVariable(IRVariable var)
            {
                var slot = new StackSlot(SpillOffset++, var);

                spillVars[var] = slot;
                return(slot);
            }
Esempio n. 3
0
        public static void exec_try_write_prop(StackFrame frame,OpStep step,RunTimeScope scope)
        {
            StackSlot slot = (StackSlot)((StackSlotAccessor)step.arg1).getSlot(scope,frame);

            if (slot.stackObjects.propGetSet != null)
            {
                OpAssigning._doPropAssigning(slot.stackObjects.propGetSet,frame,step,frame.player,scope,
                                             slot.stackObjects.propBindObj
                                             ,
                                             slot.getValue()
                                             ,
                                             slot
                                             );
            }
            else if (slot.stackObjects._temp_try_write_setthisitem != null)
            {
                SetThisItemSlot sslot = (SetThisItemSlot)slot.stackObjects._temp_try_write_setthisitem;
                slot.stackObjects._temp_try_write_setthisitem = null;

                OpAssigning._doSetThisItem(
                    sslot.bindObj,sslot.set_this_item,
                    slot.getValue(),
                    sslot.setindex,
                    slot,frame,step
                    );
            }
            else
            {
                //frame.endStep(step);
                frame.endStepNoError();
            }
        }
Esempio n. 4
0
            public static StackSlot[] ModifyStackDup2(StackSlot[] stack)
            {
                if (stack[stack.Length - 1].IsCategory2)
                {
                    // Form 2
                    var value = stack[stack.Length - 1].Definitions;

                    var newStack = new StackSlot[stack.Length - 1 + 2];
                    Array.Copy(stack, newStack, stack.Length - 1);
                    newStack[newStack.Length - 2] = new StackSlot(value, null);
                    newStack[newStack.Length - 1] = new StackSlot(value, null);
                    return newStack;
                }
                else
                {
                    // Form 1
                    var value1 = stack[stack.Length - 1].Definitions;
                    var value2 = stack[stack.Length - 2].Definitions;

                    var newStack = new StackSlot[stack.Length - 2 + 4];
                    Array.Copy(stack, newStack, stack.Length - 2);
                    newStack[newStack.Length - 4] = new StackSlot(value2, null);
                    newStack[newStack.Length - 3] = new StackSlot(value1, null);
                    newStack[newStack.Length - 2] = new StackSlot(value2, null);
                    newStack[newStack.Length - 1] = new StackSlot(value1, null);
                    return newStack;
                }
            }
Esempio n. 5
0
            public static               StackSlot[] ModifyStackDup2(StackSlot[] stack)
            {
                if (stack[stack.Length - 1].IsCategory2)
                {
                    // Form 2
                    var value = stack[stack.Length - 1].Definitions;

                    var newStack = new StackSlot[stack.Length - 1 + 2];
                    Array.Copy(stack, newStack, stack.Length - 1);
                    newStack[newStack.Length - 2] = new StackSlot(value, null);
                    newStack[newStack.Length - 1] = new StackSlot(value, null);
                    return(newStack);
                }
                else
                {
                    // Form 1
                    var value1 = stack[stack.Length - 1].Definitions;
                    var value2 = stack[stack.Length - 2].Definitions;

                    var newStack = new StackSlot[stack.Length - 2 + 4];
                    Array.Copy(stack, newStack, stack.Length - 2);
                    newStack[newStack.Length - 4] = new StackSlot(value2, null);
                    newStack[newStack.Length - 3] = new StackSlot(value1, null);
                    newStack[newStack.Length - 2] = new StackSlot(value2, null);
                    newStack[newStack.Length - 1] = new StackSlot(value1, null);
                    return(newStack);
                }
            }
Esempio n. 6
0
        void IBlockCallBack.call(object args)
        {
#if DEBUG
            clear_para_slot(invokerFrame,onstackparametercount);
#else
            {
                int count = onstackparametercount;
                while (count > 0)
                {
                    --count;
                    StackSlot slot = invokerFrame.stack[invokerFrame.baseBottomSlotIndex + (--invokerFrame.call_parameter_slotCount)];
                    if (slot.refPropChanged)
                    {
                        slot.refPropChanged = false;
                        slot.stackObjects   = StackSlot.StackObjects.EMPTY;

                        if (slot.needclear)
                        {
                            slot.linktarget = null;
                            slot._cache_arraySlot.clear();
                            slot._cache_vectorSlot.clear();
                            slot._cache_prototypeSlot.clear();
                            slot._cache_setthisslot.clear();
                            slot._linkObjCache.clearRefObj();
                            slot._functionValue.Clear();
                            slot._functon_result.Clear();
                            slot.needclear = false;
                        }


                        slot.store[StackSlot.COMMREFTYPEOBJ] = ASBinCode.rtData.rtNull.nullptr;
                    }
                    slot.index = (int)RunTimeDataType.unknown;
                }
            }
#endif


            onstackparametercount = 0;
            invokerFrame.endStepNoError();
            //release();
            //人肉内联release

            if (!hasReleased)
            {
                hasReleased = true;
                callbacker  = null;

                CallFuncHeap = null;
                toCallFunc   = null;
                returnSlot   = null;
                _tempSlot    = null;
                invokerFrame = null;
                token        = null;
                tag          = null;
                function.Clear();

                player.funcCallerPool.ret(this);
            }
        }
Esempio n. 7
0
        public static void exec_delete(StackFrame frame, OpStep step, RunTimeScope scope)
        {
            {
                StackSlot slot = (StackSlot)((StackSlotAccessor)step.arg1).getSlot(scope, frame);

                var ls = slot.getLinkSlot();

                if (ls is DynamicPropertySlot)
                {
                    DynamicPropertySlot link = (DynamicPropertySlot)ls;
                    if (link._canDelete)
                    {
                        ((ASBinCode.rtti.DynamicObject)link.obj.value).deleteProperty(link._propname);
                    }
                    else
                    {
                        if (link.backup != null)
                        {
                            link.directSet(link.backup);
                        }
                    }
                }
                else if (ls is DictionarySlot)
                {
                    DictionarySlot link = (DictionarySlot)ls;
                    ((ASBinCode.rtti.DictionaryObject)link.obj.value).RemoveKey(link._key);
                }
                else if (ls is OpAccess_Dot.arraySlot) //(slot.fromArray != null)
                {
                    //slot.directSet(rtUndefined.undefined);
                    //bool success;
                    //slot.assign(rtUndefined.undefined,out success);

                    ((OpAccess_Dot.arraySlot)ls).delete();


                    //slot.fromArray.innerArray[slot.fromArrayIndex] = rtUndefined.undefined;
                }
                else if (ls is OpAccess_Dot.prototypeSlot)
                {   //原型链对象,不可删除
                }
                else if (ls is OpVector.vectorSLot)
                {
                    //数组链接,跳过
                }
                else
                {
                    frame.throwError(
                        step.token, 0,
                        "动态属性才能被delete"
                        );
                }

                slot.linkTo(null);

                frame.endStep(step);
            }
        }
Esempio n. 8
0
        public static void _doSetThisItem(ASBinCode.rtData.rtObjectBase thisObj,
                                          RunTimeValueBase v,RunTimeValueBase index,StackSlot slot,StackFrame frame,OpStep step
                                          )
        {
            //***读取setter***
            RunTimeValueBase func;

            func = ((MethodGetterBase)thisObj.value._class.set_this_item.bindField).getMethod(
                thisObj
                );

            //***调用设置器***

            var funCaller = frame.player.funcCallerPool.create(frame,step.token);

            funCaller.SetFunction((ASBinCode.rtData.rtFunction)func); ((ASBinCode.rtData.rtFunction)func).Clear();
            funCaller.loadDefineFromFunction();
            if (!funCaller.createParaScope())
            {
                return;
            }

            //funCaller.releaseAfterCall = true;

            bool success;

            funCaller.pushParameter(v,0,out success);

            if (!success)
            {
                frame.endStep(step);
                return;
            }

            funCaller.pushParameter(index,1,out success);
            if (!success)
            {
                frame.endStep(step);
                return;
            }

            funCaller._tempSlot  = frame._tempSlot1;
            funCaller.returnSlot = frame._tempSlot1;

            BlockCallBackBase cb = frame.player.blockCallBackPool.create();

            cb.setCallBacker(_setthisitem_callbacker);
            cb.step = step;
            cb.args = frame;


            funCaller.callbacker = cb;
            funCaller.call();

            return;
        }
Esempio n. 9
0
 public static StackSlot[] ModifyStack(StackSlot[] stack, int popCount, int pushCount, ByteCode pushDefinition)
 {
     var newStack = new StackSlot[stack.Length - popCount + pushCount];
     Array.Copy(stack, newStack, stack.Length - popCount);
     for (int i = stack.Length - popCount; i < newStack.Length; i++)
     {
         newStack[i] = new StackSlot(new[] { pushDefinition }, null);
     }
     return newStack;
 }
Esempio n. 10
0
 public static              StackSlot[] ModifyStack(StackSlot[] stack, int popCount, int pushCount, ByteCode pushDefinition)
 {
     StackSlot[] newStack = new StackSlot[stack.Length - popCount + pushCount];
     Array.Copy(stack, newStack, stack.Length - popCount);
     for (int i = stack.Length - popCount; i < newStack.Length; i++)
     {
         newStack[i] = new StackSlot(new[] { pushDefinition }, null);
     }
     return(newStack);
 }
Esempio n. 11
0
            public static               StackSlot[] ModifyStackSwap(StackSlot[] stack)
            {
                var value1 = stack[stack.Length - 1].Definitions;
                var value2 = stack[stack.Length - 2].Definitions;

                var newStack = new StackSlot[stack.Length - 2 + 2];

                Array.Copy(stack, newStack, stack.Length - 2);
                newStack[newStack.Length - 2] = new StackSlot(value1, null);
                newStack[newStack.Length - 1] = new StackSlot(value2, null);
                return(newStack);
            }
Esempio n. 12
0
        private static void clear_para_slot(StackFrame invokerFrame,int count)
        {
            while (count > 0)
            {
#if DEBUG
                int i = invokerFrame.baseBottomSlotIndex + invokerFrame.call_parameter_slotCount;                 //invokerFrame.offset + invokerFrame.block.totalRegisters + 1 + 1 + invokerFrame.call_parameter_slotCount;
                --invokerFrame.call_parameter_slotCount;
                --i;
                --count;
                invokerFrame.stack[i].clear();
#else
                --count;

                StackSlot slot = invokerFrame.stack[invokerFrame.baseBottomSlotIndex + (--invokerFrame.call_parameter_slotCount)];
                if (slot.refPropChanged)
                {
                    slot.refPropChanged = false;
                    slot.stackObjects   = StackSlot.StackObjects.EMPTY;

                    if (slot.needclear)
                    {
                        slot.linktarget = null;
                        slot._cache_arraySlot.clear();
                        slot._cache_vectorSlot.clear();
                        slot._cache_prototypeSlot.clear();
                        slot._cache_setthisslot.clear();
                        slot._linkObjCache.clearRefObj();
                        slot._functionValue.Clear();
                        slot._functon_result.Clear();
                        slot.needclear = false;
                    }


                    slot.store[StackSlot.COMMREFTYPEOBJ] = ASBinCode.rtData.rtNull.nullptr;
                }
                slot.index = (int)RunTimeDataType.unknown;
#endif
            }


            //if (invokerFrame.call_parameter_slotCount > 0)
            //{
            //	//**清理**
            //	for (int i = invokerFrame.offset + invokerFrame.block.totalRegisters + 1 + 1;
            //		i < invokerFrame.offset + invokerFrame.block.totalRegisters + 1 + 1 + invokerFrame.call_parameter_slotCount
            //		; i++)
            //	{
            //		invokerFrame.stack[i].clear();
            //	}

            //	invokerFrame.call_parameter_slotCount = 0;
            //}
        }
Esempio n. 13
0
            public static StackSlot[] ModifyStackDupX1(StackSlot[] stack)
            {
                var value1 = stack[stack.Length - 1].Definitions;
                var value2 = stack[stack.Length - 2].Definitions;

                var newStack = new StackSlot[stack.Length - 2 + 3];
                Array.Copy(stack, newStack, stack.Length - 2);
                newStack[newStack.Length - 3] = new StackSlot(value1, null);
                newStack[newStack.Length - 2] = new StackSlot(value2, null);
                newStack[newStack.Length - 1] = new StackSlot(value1, null);
                return newStack;
            }
Esempio n. 14
0
        public void Initialize()
        {
            var blocks = transformer.RootScope.GetBasicBlocks().Cast <BasicBlock <IRInstrList> >().ToList();

            liveness = LivenessAnalysis.ComputeLiveness(blocks);

            var stackVars = new HashSet <IRVariable>();

            foreach (var blockLiveness in liveness)
            {
                foreach (var instr in blockLiveness.Key.Content)
                {
                    if (instr.OpCode != IROpCode.__LEA)
                    {
                        continue;
                    }

                    var variable = (IRVariable)instr.Operand2;
                    if (variable.VariableType != IRVariableType.Argument)
                    {
                        stackVars.Add(variable);
                    }
                }
                stackVars.UnionWith(blockLiveness.Value.OutLive);
            }

            // [BP - 2] = last argument
            // [BP - 1] = return address
            // [BP    ] = old BP
            // [BP + 1] = first local

            var offset = 1;

            globalVars = stackVars.ToDictionary(var => var, var => new StackSlot(offset++, var));
            baseOffset = offset;
            LocalSize  = baseOffset - 1;

            offset = -2;
            var parameters = transformer.Context.GetParameters();

            for (var i = parameters.Length - 1; i >= 0; i--)
            {
                var paramVar = parameters[i];
                globalVars[paramVar] = new StackSlot(offset--, paramVar);
            }

            allocation = globalVars.ToDictionary(pair => pair.Key, pair => (object)pair.Value);
        }
Esempio n. 15
0
 public static              StackSlot[] ModifyStack(StackSlot[] stack, int popCount, int pushCount, ByteCode pushDefinition)
 {
     //wicky.patch.start: get around error
     if (stack.Length < popCount)
     {
         return(new StackSlot[0]);
     }
     //wicky.patch.end
     StackSlot[] newStack = new StackSlot[stack.Length - popCount + pushCount];
     Array.Copy(stack, newStack, stack.Length - popCount);
     for (int i = stack.Length - popCount; i < newStack.Length; i++)
     {
         newStack[i] = new StackSlot(new [] { pushDefinition }, null);
     }
     return(newStack);
 }
Esempio n. 16
0
            public override string ToString()
            {
                StringBuilder sb = new StringBuilder();

                if (StackSlot != null)
                {
                    sb.AppendLine($"\t\t\tStack:");
                    sb.AppendLine(StackSlot.ToString());
                }
                else
                {
                    sb.AppendLine($"\t\t\tRegisterNumber: {RegisterNumber}");
                }
                sb.AppendLine($"\t\t\tFlags: {Flags}");

                return(sb.ToString());
            }
Esempio n. 17
0
            public override string ToString()
            {
                StringBuilder sb   = new StringBuilder();
                string        tab3 = new string(' ', 12);

                if (StackSlot != null)
                {
                    sb.AppendLine($"{tab3}Stack:");
                    sb.AppendLine(StackSlot.ToString());
                }
                else
                {
                    sb.AppendLine($"{tab3}RegisterNumber: {RegisterNumber}");
                }
                sb.AppendLine($"{tab3}Flags: {Flags}");

                return(sb.ToString());
            }
Esempio n. 18
0
            public override GcSlotFlags WriteTo(StringBuilder sb, Machine machine, GcSlotFlags prevFlags)
            {
                if (prevFlags != Flags)
                {
                    sb.Append(Flags.ToString());
                    sb.Append(' ');
                }

                if (StackSlot != null)
                {
                    sb.Append(StackSlot.ToString());
                }
                else
                {
                    sb.Append(GetRegisterName(RegisterNumber, machine));
                }

                return(Flags);
            }
        public static void exec_link(StackFrame frame, OpStep step, RunTimeScope scope)
        {
            StackSlot l = (StackSlot)step.reg.getSlot(scope, frame);

            int classid = ((ASBinCode.rtData.rtInt)step.arg2.getValue(scope, frame)).value;

            var outscope = frame.player.outpackage_runtimescope[classid];

            SLOT outpackagescopeslot = ((VariableBase)step.arg1).getSlot(outscope,null);

            StackSlotAccessor register = (StackSlotAccessor)step.reg;

            if (register._isassigntarget || register._hasUnaryOrShuffixOrDelete)
            {
                l.linkTo(outpackagescopeslot);
            }
            else
            {
                l.directSet(outpackagescopeslot.getValue());
            }
            frame.endStep(step);
        }
Esempio n. 20
0
            public static               StackSlot[] ModifyStackDup2X1(StackSlot[] stack)
            {
                if (stack[stack.Length - 1].IsCategory2)
                {
                    // Form 2
                    return(ModifyStackDupX1(stack));
                }
                else
                {
                    // Form 1
                    var value1 = stack[stack.Length - 1].Definitions;
                    var value2 = stack[stack.Length - 2].Definitions;
                    var value3 = stack[stack.Length - 3].Definitions;

                    var newStack = new StackSlot[stack.Length - 3 + 5];
                    Array.Copy(stack, newStack, stack.Length - 3);
                    newStack[newStack.Length - 5] = new StackSlot(value2, null);
                    newStack[newStack.Length - 4] = new StackSlot(value1, null);
                    newStack[newStack.Length - 3] = new StackSlot(value3, null);
                    newStack[newStack.Length - 2] = new StackSlot(value2, null);
                    newStack[newStack.Length - 1] = new StackSlot(value1, null);
                    return(newStack);
                }
            }
        private static ASBinCode.rtti.Object createObject(CSWC swc,Class cls,InstanceCreator creator,
                                                          out ASBinCode.rtData.rtObjectBase rtObjectBase,
                                                          out ASBinCode.rtData.rtObjectBase linkrtobj,
                                                          out string errinfo
                                                          )
        {
            ASBinCode.rtti.Object obj = null;// = new ASBinCode.rtti.Object(cls);
            rtObjectBase = null; linkrtobj = null; errinfo = null;
            if (cls.isLink_System)
            {
                if (creator != null)
                {
                    StackSlot stackSlot = creator.objectStoreToSlot as StackSlot;
                    if (stackSlot != null)
                    {
                        rtObjectBase = stackSlot.getStackCacheObject(cls);
                        return(rtObjectBase.value);
                    }
                }


                var func = (NativeFunctionBase)swc.class_Creator[cls];

                string err; int no;
                ASBinCode.rtData.rtObjectBase rtObj =
                    func.execute(null,null,cls,out err,out no) as ASBinCode.rtData.rtObjectBase;
                linkrtobj = rtObj;
                if (rtObj == null)
                {
                    errinfo = cls.ToString() + " create linksystem object failed";
                    return(null);
                }
                else
                {
                    return(rtObj.value);
                }
            }
            else if (cls.isCrossExtend)
            {
                var scls = cls.super;
                while (!scls.isLink_System)
                {
                    scls = scls.super;
                }

                var cextend = scls.staticClass.linkObjCreator;
                var func    = swc.getNativeFunction(((ClassMethodGetter)cextend.bindField).functionId);

                if (func == null)
                {
                    errinfo = cls.ToString() + " create crossextend object failed, creator function not found";
                    return(null);
                }

                string err; int no;
                ASBinCode.rtData.rtObjectBase rtObj =
                    func.execute(null,null,cls,out err,out no) as ASBinCode.rtData.rtObjectBase;
                linkrtobj = rtObj;
                if (rtObj == null)
                {
                    errinfo = cls.ToString() + " create crossextend object failed";
                    return(null);
                }
                else
                {
                    LinkSystemObject lo = (LinkSystemObject)rtObj.value;
                    return(lo);
                }
            }
            else if (
                swc.DictionaryClass != null
                &&
                ClassMemberFinder.isInherits(cls,swc.DictionaryClass))
            {
                obj = new DictionaryObject(cls);
            }
            else if (cls.dynamic)
            {
                if (cls.isUnmanaged)
                {
                    obj = new HostedDynamicObject(cls);
                }
                else
                {
                    obj = new DynamicObject(cls);
                }
            }
            else if (cls.isUnmanaged)
            {
                obj = new HostedObject(cls);
            }
            else
            {
                obj = new ASBinCode.rtti.Object(cls);
            }

            return(obj);
        }
Esempio n. 22
0
            public static               StackSlot[] ModifyStackDup2X2(StackSlot[] stack)
            {
                var s1 = stack[stack.Length - 1];
                var s2 = stack[stack.Length - 2];

                if (s1.IsCategory2 && s2.IsCategory2)
                {
                    // Form 4
                    return(ModifyStackDupX1(stack));
                }

                var s3 = stack[stack.Length - 3];

                if (s3.IsCategory2 && !s1.IsCategory2 && !s2.IsCategory2)
                {
                    // Form 3
                    var value1 = stack[stack.Length - 1].Definitions;
                    var value2 = stack[stack.Length - 2].Definitions;
                    var value3 = stack[stack.Length - 3].Definitions;

                    var newStack = new StackSlot[stack.Length - 3 + 5];
                    Array.Copy(stack, newStack, stack.Length - 3);
                    newStack[newStack.Length - 5] = new StackSlot(value2, null);
                    newStack[newStack.Length - 4] = new StackSlot(value1, null);
                    newStack[newStack.Length - 3] = new StackSlot(value3, null);
                    newStack[newStack.Length - 2] = new StackSlot(value2, null);
                    newStack[newStack.Length - 1] = new StackSlot(value1, null);
                    return(newStack);
                }

                if (s1.IsCategory2)
                {
                    // Form 2
                    var value1 = stack[stack.Length - 1].Definitions;
                    var value2 = stack[stack.Length - 2].Definitions;
                    var value3 = stack[stack.Length - 3].Definitions;

                    var newStack = new StackSlot[stack.Length - 3 + 4];
                    Array.Copy(stack, newStack, stack.Length - 3);
                    newStack[newStack.Length - 4] = new StackSlot(value1, null);
                    newStack[newStack.Length - 3] = new StackSlot(value3, null);
                    newStack[newStack.Length - 2] = new StackSlot(value2, null);
                    newStack[newStack.Length - 1] = new StackSlot(value1, null);
                    return(newStack);
                }
                else
                {
                    var value1 = stack[stack.Length - 1].Definitions;
                    var value2 = stack[stack.Length - 2].Definitions;
                    var value3 = stack[stack.Length - 3].Definitions;
                    var value4 = stack[stack.Length - 4].Definitions;

                    var newStack = new StackSlot[stack.Length - 4 + 6];
                    Array.Copy(stack, newStack, stack.Length - 4);
                    newStack[newStack.Length - 6] = new StackSlot(value2, null);
                    newStack[newStack.Length - 5] = new StackSlot(value1, null);
                    newStack[newStack.Length - 4] = new StackSlot(value4, null);
                    newStack[newStack.Length - 3] = new StackSlot(value3, null);
                    newStack[newStack.Length - 2] = new StackSlot(value2, null);
                    newStack[newStack.Length - 1] = new StackSlot(value1, null);
                    return(newStack);
                }
            }
Esempio n. 23
0
        /// <summary>
        /// Update the state of the given branch targets (of the given bytecode).
        /// Add modified branch targets to the given agenda.
        /// </summary>
        private static void UpdateBranchTarget(ByteCode byteCode, ByteCode branchTarget, bool canShareNewState, StackSlot[] newStack, VariableSlot[] newVariableState, Stack <ByteCode> agenda)
        {
            if ((branchTarget.StackBefore == null) && (branchTarget.VariablesBefore == null))
            {
                // Branch target has not been processed at all
                if (canShareNewState)
                {
                    branchTarget.StackBefore     = newStack;
                    branchTarget.VariablesBefore = newVariableState;
                }
                else
                {
                    // Do not share data for several bytecodes
                    branchTarget.StackBefore     = StackSlot.ModifyStack(newStack, 0, 0, null);
                    branchTarget.VariablesBefore = VariableSlot.CloneVariableState(newVariableState);
                }
                agenda.Push(branchTarget);
                return;
            }

            // If we get here, the branch target has been processed before.
            // See the the stack size is the same and merge the state where needed.
            if ((branchTarget.StackBefore == null) || (branchTarget.StackBefore.Length != newStack.Length))
            {
                throw new Exception("Inconsistent stack size at " + byteCode.Name);
            }

            // Be careful not to change our new data - it might be reused for several branch targets.
            // In general, be careful that two bytecodes never share data structures.
            var modified = false;

            // Merge stacks - modify the target
            for (var i = 0; i < newStack.Length; i++)
            {
                var oldDefs = branchTarget.StackBefore[i].Definitions;
                var newDefs = oldDefs.Union(newStack[i].Definitions);
                if (newDefs.Length > oldDefs.Length)
                {
                    branchTarget.StackBefore[i] = new StackSlot(newDefs, null);
                    modified = true;
                }
            }

            // Merge variables - modify the target
            for (var i = 0; i < newVariableState.Length; i++)
            {
                var oldSlot = branchTarget.VariablesBefore[i];
                var newSlot = newVariableState[i];
                if (oldSlot.UnknownDefinition)
                {
                    continue;
                }

                if (newSlot.UnknownDefinition)
                {
                    branchTarget.VariablesBefore[i] = newSlot;
                    modified = true;
                }
                else
                {
                    var oldDefs = oldSlot.Definitions;
                    var newDefs = oldDefs.Union(newSlot.Definitions);
                    if (newDefs.Length > oldDefs.Length)
                    {
                        branchTarget.VariablesBefore[i] = new VariableSlot(newDefs, false);
                        modified = true;
                    }
                }
            }

            if (modified)
            {
                agenda.Push(branchTarget);
            }
        }
Esempio n. 24
0
        List <ByteCode> StackAnalysis(MethodDefinition methodDef)
        {
            Dictionary <Instruction, ByteCode> instrToByteCode = new Dictionary <Instruction, ByteCode>();

            // Create temporary structure for the stack analysis
            List <ByteCode>    body     = new List <ByteCode>(methodDef.Body.Instructions.Count);
            List <Instruction> prefixes = null;

            foreach (Instruction inst in methodDef.Body.Instructions)
            {
                if (inst.OpCode.OpCodeType == OpCodeType.Prefix)
                {
                    if (prefixes == null)
                    {
                        prefixes = new List <Instruction>(1);
                    }
                    prefixes.Add(inst);
                    continue;
                }
                ILCode code    = (ILCode)inst.OpCode.Code;
                object operand = inst.Operand;
                ILCodeUtil.ExpandMacro(ref code, ref operand, methodDef.Body);
                ByteCode byteCode = new ByteCode()
                {
                    Offset    = inst.Offset,
                    EndOffset = inst.Next != null ? inst.Next.Offset : methodDef.Body.CodeSize,
                    Code      = code,
                    Operand   = operand,
                    PopCount  = inst.GetPopDelta(methodDef),
                    PushCount = inst.GetPushDelta()
                };
                if (prefixes != null)
                {
                    instrToByteCode[prefixes[0]] = byteCode;
                    byteCode.Offset   = prefixes[0].Offset;
                    byteCode.Prefixes = prefixes.ToArray();
                    prefixes          = null;
                }
                else
                {
                    instrToByteCode[inst] = byteCode;
                }
                body.Add(byteCode);
            }
            for (int i = 0; i < body.Count - 1; i++)
            {
                body[i].Next = body[i + 1];
            }

            Stack <ByteCode> agenda = new Stack <ByteCode>();

            int varCount = methodDef.Body.Variables.Count;

            var exceptionHandlerStarts = new HashSet <ByteCode>(methodDef.Body.ExceptionHandlers.Select(eh => instrToByteCode[eh.HandlerStart]));

            // Add known states
            if (methodDef.Body.HasExceptionHandlers)
            {
                foreach (ExceptionHandler ex in methodDef.Body.ExceptionHandlers)
                {
                    ByteCode handlerStart = instrToByteCode[ex.HandlerStart];
                    handlerStart.StackBefore     = new List <StackSlot>();
                    handlerStart.VariablesBefore = VariableSlot.MakeFullState(varCount);
                    if (ex.HandlerType == ExceptionHandlerType.Catch || ex.HandlerType == ExceptionHandlerType.Filter)
                    {
                        // Catch and Filter handlers start with the exeption on the stack
                        ByteCode ldexception = new ByteCode()
                        {
                            Code      = ILCode.Ldexception,
                            Operand   = ex.CatchType,
                            PopCount  = 0,
                            PushCount = 1
                        };
                        ldexceptions[ex] = ldexception;
                        handlerStart.StackBefore.Add(new StackSlot(ldexception));
                    }
                    agenda.Push(handlerStart);

                    if (ex.HandlerType == ExceptionHandlerType.Filter)
                    {
                        ByteCode filterStart = instrToByteCode[ex.FilterStart];
                        filterStart.StackBefore     = new List <StackSlot>();
                        filterStart.VariablesBefore = VariableSlot.MakeFullState(varCount);
                        ByteCode ldexception = new ByteCode()
                        {
                            Code      = ILCode.Ldexception,
                            Operand   = ex.CatchType,
                            PopCount  = 0,
                            PushCount = 1
                        };
                        // TODO: ldexceptions[ex] = ldexception;
                        filterStart.StackBefore.Add(new StackSlot(ldexception));
                        agenda.Push(filterStart);
                    }
                }
            }

            body[0].StackBefore     = new List <StackSlot>();
            body[0].VariablesBefore = VariableSlot.MakeEmptyState(varCount);
            agenda.Push(body[0]);

            // Process agenda
            while (agenda.Count > 0)
            {
                ByteCode byteCode = agenda.Pop();

                // Calculate new stack
                List <StackSlot> newStack = StackSlot.CloneStack(byteCode.StackBefore, byteCode.PopCount);
                for (int i = 0; i < byteCode.PushCount; i++)
                {
                    newStack.Add(new StackSlot(byteCode));
                }

                // Calculate new variable state
                VariableSlot[] newVariableState = VariableSlot.CloneVariableState(byteCode.VariablesBefore);
                if (byteCode.Code == ILCode.Stloc)
                {
                    int varIndex = ((VariableReference)byteCode.Operand).Index;
                    newVariableState[varIndex] = new VariableSlot(byteCode);
                }

                // After the leave, finally block might have touched the variables
                if (byteCode.Code == ILCode.Leave)
                {
                    newVariableState = VariableSlot.MakeFullState(varCount);
                }

                // Find all successors
                List <ByteCode> branchTargets = new List <ByteCode>();
                if (!byteCode.Code.IsUnconditionalControlFlow())
                {
                    if (exceptionHandlerStarts.Contains(byteCode.Next))
                    {
                        // Do not fall though down to exception handler
                        // It is invalid IL as per ECMA-335 §12.4.2.8.1, but some obfuscators produce it
                    }
                    else
                    {
                        branchTargets.Add(byteCode.Next);
                    }
                }
                if (byteCode.Operand is Instruction[])
                {
                    foreach (Instruction inst in (Instruction[])byteCode.Operand)
                    {
                        ByteCode target = instrToByteCode[inst];
                        branchTargets.Add(target);
                        // The target of a branch must have label
                        if (target.Label == null)
                        {
                            target.Label = new ILLabel()
                            {
                                Name = target.Name
                            };
                        }
                    }
                }
                else if (byteCode.Operand is Instruction)
                {
                    ByteCode target = instrToByteCode[(Instruction)byteCode.Operand];
                    branchTargets.Add(target);
                    // The target of a branch must have label
                    if (target.Label == null)
                    {
                        target.Label = new ILLabel()
                        {
                            Name = target.Name
                        };
                    }
                }

                // Apply the state to successors
                foreach (ByteCode branchTarget in branchTargets)
                {
                    if (branchTarget.StackBefore == null && branchTarget.VariablesBefore == null)
                    {
                        if (branchTargets.Count == 1)
                        {
                            branchTarget.StackBefore     = newStack;
                            branchTarget.VariablesBefore = newVariableState;
                        }
                        else
                        {
                            // Do not share data for several bytecodes
                            branchTarget.StackBefore     = StackSlot.CloneStack(newStack, 0);
                            branchTarget.VariablesBefore = VariableSlot.CloneVariableState(newVariableState);
                        }
                        agenda.Push(branchTarget);
                    }
                    else
                    {
                        if (branchTarget.StackBefore.Count != newStack.Count)
                        {
                            throw new Exception("Inconsistent stack size at " + byteCode.Name);
                        }

                        // Be careful not to change our new data - it might be reused for several branch targets.
                        // In general, be careful that two bytecodes never share data structures.

                        bool modified = false;

                        // Merge stacks - modify the target
                        for (int i = 0; i < newStack.Count; i++)
                        {
                            ByteCode[] oldPushedBy = branchTarget.StackBefore[i].PushedBy;
                            ByteCode[] newPushedBy = oldPushedBy.Union(newStack[i].PushedBy);
                            if (newPushedBy.Length > oldPushedBy.Length)
                            {
                                branchTarget.StackBefore[i] = new StackSlot(newPushedBy, null);
                                modified = true;
                            }
                        }

                        // Merge variables - modify the target
                        for (int i = 0; i < newVariableState.Length; i++)
                        {
                            VariableSlot oldSlot = branchTarget.VariablesBefore[i];
                            VariableSlot newSlot = newVariableState[i];
                            // All can not be unioned further
                            if (!oldSlot.StoredByAll)
                            {
                                if (newSlot.StoredByAll)
                                {
                                    branchTarget.VariablesBefore[i] = newSlot;
                                    modified = true;
                                }
                                else
                                {
                                    ByteCode[] oldStoredBy = oldSlot.StoredBy;
                                    ByteCode[] newStoredBy = oldStoredBy.Union(newSlot.StoredBy);
                                    if (newStoredBy.Length > oldStoredBy.Length)
                                    {
                                        branchTarget.VariablesBefore[i] = new VariableSlot(newStoredBy, false);
                                        modified = true;
                                    }
                                }
                            }
                        }

                        if (modified)
                        {
                            agenda.Push(branchTarget);
                        }
                    }
                }
            }

            // Occasionally the compilers or obfuscators generate unreachable code (which migt be intentonally invalid)
            // I belive it is safe to just remove it
            body.RemoveAll(b => b.StackBefore == null);

            // Genertate temporary variables to replace stack
            foreach (ByteCode byteCode in body)
            {
                int argIdx   = 0;
                int popCount = byteCode.PopCount ?? byteCode.StackBefore.Count;
                for (int i = byteCode.StackBefore.Count - popCount; i < byteCode.StackBefore.Count; i++)
                {
                    ILVariable tmpVar = new ILVariable()
                    {
                        Name = string.Format("arg_{0:X2}_{1}", byteCode.Offset, argIdx), IsGenerated = true
                    };
                    byteCode.StackBefore[i] = new StackSlot(byteCode.StackBefore[i].PushedBy, tmpVar);
                    foreach (ByteCode pushedBy in byteCode.StackBefore[i].PushedBy)
                    {
                        if (pushedBy.StoreTo == null)
                        {
                            pushedBy.StoreTo = new List <ILVariable>(1);
                        }
                        pushedBy.StoreTo.Add(tmpVar);
                    }
                    argIdx++;
                }
            }

            // Try to use single temporary variable insted of several if possilbe (especially useful for dup)
            // This has to be done after all temporary variables are assigned so we know about all loads
            foreach (ByteCode byteCode in body)
            {
                if (byteCode.StoreTo != null && byteCode.StoreTo.Count > 1)
                {
                    var locVars = byteCode.StoreTo;
                    // For each of the variables, find the location where it is loaded - there should be preciesly one
                    var loadedBy = locVars.Select(locVar => body.SelectMany(bc => bc.StackBefore).Single(s => s.LoadFrom == locVar)).ToList();
                    // We now know that all the variables have a single load,
                    // Let's make sure that they have also a single store - us
                    if (loadedBy.All(slot => slot.PushedBy.Length == 1 && slot.PushedBy[0] == byteCode))
                    {
                        // Great - we can reduce everything into single variable
                        ILVariable tmpVar = new ILVariable()
                        {
                            Name = string.Format("expr_{0:X2}", byteCode.Offset), IsGenerated = true
                        };
                        byteCode.StoreTo = new List <ILVariable>()
                        {
                            tmpVar
                        };
                        foreach (ByteCode bc in body)
                        {
                            for (int i = 0; i < bc.StackBefore.Count; i++)
                            {
                                // Is it one of the variable to be merged?
                                if (locVars.Contains(bc.StackBefore[i].LoadFrom))
                                {
                                    // Replace with the new temp variable
                                    bc.StackBefore[i] = new StackSlot(bc.StackBefore[i].PushedBy, tmpVar);
                                }
                            }
                        }
                    }
                }
            }

            // Split and convert the normal local variables
            ConvertLocalVariables(body);

            // Convert branch targets to labels
            foreach (ByteCode byteCode in body)
            {
                if (byteCode.Operand is Instruction[])
                {
                    List <ILLabel> newOperand = new List <ILLabel>();
                    foreach (Instruction target in (Instruction[])byteCode.Operand)
                    {
                        newOperand.Add(instrToByteCode[target].Label);
                    }
                    byteCode.Operand = newOperand.ToArray();
                }
                else if (byteCode.Operand is Instruction)
                {
                    byteCode.Operand = instrToByteCode[(Instruction)byteCode.Operand].Label;
                }
            }

            // Convert parameters to ILVariables
            ConvertParameters(body);

            return(body);
        }
Esempio n. 25
0
        /// <summary>
        /// Update the state of the given branch targets (of the given bytecode).
        /// Add modified branch targets to the given agenda.
        /// </summary>
        private static void UpdateBranchTarget(ByteCode byteCode, ByteCode branchTarget, bool canShareNewState, StackSlot[] newStack, VariableSlot[] newVariableState, Stack<ByteCode> agenda)
        {
            if ((branchTarget.StackBefore == null) && (branchTarget.VariablesBefore == null))
            {
                // Branch target has not been processed at all
                if (canShareNewState)
                {
                    branchTarget.StackBefore = newStack;
                    branchTarget.VariablesBefore = newVariableState;
                }
                else
                {
                    // Do not share data for several bytecodes
                    branchTarget.StackBefore = StackSlot.ModifyStack(newStack, 0, 0, null);
                    branchTarget.VariablesBefore = VariableSlot.CloneVariableState(newVariableState);
                }
                agenda.Push(branchTarget);
                return;
            }

            // If we get here, the branch target has been processed before.
            // See the the stack size is the same and merge the state where needed.
            if ((branchTarget.StackBefore == null) || (branchTarget.StackBefore.Length != newStack.Length))
            {
                throw new Exception("Inconsistent stack size at " + byteCode.Name);
            }

            // Be careful not to change our new data - it might be reused for several branch targets.
            // In general, be careful that two bytecodes never share data structures.
            var modified = false;

            // Merge stacks - modify the target
            for (var i = 0; i < newStack.Length; i++)
            {
                var oldDefs = branchTarget.StackBefore[i].Definitions;
                var newDefs = oldDefs.Union(newStack[i].Definitions);
                if (newDefs.Length > oldDefs.Length)
                {
                    branchTarget.StackBefore[i] = new StackSlot(newDefs, null);
                    modified = true;
                }
            }

            // Merge variables - modify the target
            for (var i = 0; i < newVariableState.Length; i++)
            {
                var oldSlot = branchTarget.VariablesBefore[i];
                var newSlot = newVariableState[i];
                if (oldSlot.UnknownDefinition)
                    continue;

                if (newSlot.UnknownDefinition)
                {
                    branchTarget.VariablesBefore[i] = newSlot;
                    modified = true;
                }
                else
                {
                    var oldDefs = oldSlot.Definitions;
                    var newDefs = oldDefs.Union(newSlot.Definitions);
                    if (newDefs.Length > oldDefs.Length)
                    {
                        branchTarget.VariablesBefore[i] = new VariableSlot(newDefs, false);
                        modified = true;
                    }
                }
            }

            if (modified)
            {
                agenda.Push(branchTarget);
            }
        }
Esempio n. 26
0
        public static void _doPropAssigning(ClassPropertyGetter prop,StackFrame frame,
                                            OpStep step,Player player,RunTimeScope scope,
                                            ASBinCode.rtData.rtObjectBase bindobj,RunTimeValueBase v,StackSlot sslot)
        {
            do
            {
                if (prop.setter == null)
                {
                    frame.throwError(
                        step.token,0,"Illegal write to read-only property "
                        );
                    break;
                }
                //检查访问权限
                CodeBlock block = player.swc.blocks[scope.blockId];
                Class     finder;
                if (block.isoutclass)
                {
                    var c = prop._class;
                    if (c.instanceClass != null)
                    {
                        c = c.instanceClass;
                    }
                    if (c.mainClass != null)
                    {
                        c = c.mainClass;
                    }

                    if (block.define_class_id == c.classid)
                    {
                        finder = player.swc.classes[block.define_class_id];
                    }
                    else
                    {
                        finder = null;
                    }
                }
                else
                {
                    finder = player.swc.classes[block.define_class_id];
                }

                var setter = ClassMemberFinder.find(prop._class,prop.setter.name,finder);
                if (setter == null || setter.bindField != prop.setter)
                {
                    frame.throwError(
                        step.token,0,"Illegal write to read-only property "
                        );
                    break;
                }

                //***读取setter***
                RunTimeValueBase func;

                if (sslot.stackObjects.superPropBindClass != null)
                {
                    func = ((MethodGetterBase)setter.bindField).getSuperMethod(
                        bindobj.objScope,
                        sslot.stackObjects.superPropBindClass
                        );
                }
                else
                {
                    func = ((MethodGetterBase)setter.bindField).getMethod(
                        bindobj
                        );
                }
                //***调用设置器***

                var funCaller = frame.player.funcCallerPool.create(frame,step.token);
                funCaller.SetFunction((ASBinCode.rtData.rtFunction)func); ((ASBinCode.rtData.rtFunction)func).Clear();
                funCaller.loadDefineFromFunction();
                if (!funCaller.createParaScope())
                {
                    return;
                }

                //funCaller.releaseAfterCall = true;

                bool success;
                funCaller.pushParameter(v,0,out success);
                if (!success)
                {
                    frame.endStep(step);
                    return;
                }

                funCaller._tempSlot  = frame._tempSlot1;
                funCaller.returnSlot = frame._tempSlot1;

                BlockCallBackBase cb = frame.player.blockCallBackPool.create();
                cb.setCallBacker(_assign_callbacker);
                cb.step = step;
                cb.args = frame;

                funCaller.callbacker = cb;
                funCaller.call();

                return;
            } while (false);


            frame.endStep(step);
        }
Esempio n. 27
0
        public static void execAssigning(StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope)
        {
            ASBinCode.SLOT slot = step.reg.getSlotForAssign(scope,frame);

            ASBinCode.RunTimeValueBase v = step.arg1.getValue(scope,frame);
            bool success;

            var lt = slot.assign(v,out success);


            if (!success)                 //(!slot.directSet(v))
            {
                if (!(slot is StackSlot)) //直接赋值时
                {
                    //ext = "Illegal assignment to function " + ((MethodGetterBase)step.reg).name + ".";
                }
                else
                {
                    StackSlot oslot = (StackSlot)slot;
                    //if (oslot.linktarget != null)
                    {
                        //slot = oslot.linktarget;
                        slot = lt;
                    }

                    if (step.arg1 is IMemReg)
                    {
                        //将其暂存到临时槽内
                        frame._tempSlot2.directSet(v);
                        v = frame._tempSlot2.getValue();
                    }

                    if (slot is SetThisItemSlot)
                    {
                        _doSetThisItem(((SetThisItemSlot)slot).bindObj,v,((SetThisItemSlot)slot).setindex,oslot,frame,step);

                        return;
                    }

                    if (slot is ClassPropertyGetter.PropertySlot)
                    {
                        ClassPropertyGetter.PropertySlot propslot =
                            (ASBinCode.ClassPropertyGetter.PropertySlot)slot;
                        //***调用访问器。***
                        ASBinCode.ClassPropertyGetter prop = oslot.stackObjects.propGetSet;                         //propslot.property;

                        _doPropAssigning(prop,frame,step,frame.player,scope,
                                         //propslot.bindObj
                                         oslot.stackObjects.propBindObj
                                         ,v,
                                         oslot
                                         );
                        return;
                    }

                    if (slot is OpVector.vectorSLot)                        //Vector类型不匹配
                    {
                        BlockCallBackBase cb = frame.player.blockCallBackPool.create();
                        cb.scope = scope;
                        cb.step  = step;
                        cb.args  = frame;
                        cb.setCallBacker(_vectorConvertCallBacker);
                        cb.cacheObjects[0] = slot;

                        //***调用强制类型转换***
                        OpCast.CastValue(v,((OpVector.vectorSLot)slot).vector_data.vector_type,
                                         frame,step.token,scope,frame._tempSlot1,cb,false);

                        return;
                    }

                    if (slot is ObjectMemberSlot && !((ObjectMemberSlot)slot).isConstMember)
                    {
                        BlockCallBackBase cb = frame.player.blockCallBackPool.create();
                        cb.scope = scope;
                        cb.step  = step;
                        cb.args  = frame;
                        cb.setCallBacker(_objectmemberslotConvertCallbacker);
                        cb.cacheObjects[0] = slot;

                        //***调用强制类型转换***
                        OpCast.CastValue(v,((ObjectMemberSlot)slot).slottype,
                                         frame,step.token,scope,frame._tempSlot1,cb,false);

                        return;
                    }
                }
                string ext = String.Empty;

                if (slot is MethodGetterBase.MethodSlot)
                {
                    ext = "Cannot assign to a method ";                    // + ((ASBinCode.ClassMethodGetter.MethodSlot)slot).method;
                }
                else if (slot is ObjectMemberSlot)
                {
                    ext = "Illegal write to read-only property ";
                    //+ ((ObjectMemberSlot)slot).obj.value._class.name
                    //+" on ppp.PPC."
                }
                else if (slot is ClassPropertyGetter.PropertySlot)
                {
                    ext = "Illegal write to read-only property ";
                }
                else if (slot is OpAccess_Dot.prototypeSlot)
                {
                    ext = "Cannot create property "
                          + ((OpAccess_Dot.prototypeSlot)slot)._protoname +
                          " on " + ((OpAccess_Dot.prototypeSlot)slot)._protoRootObj.value._class.name;
                }

                frame.throwError(
                    step.token,0,ext
                    );
                frame.endStep(step);
            }
            else
            {
                frame.endStepNoError();
            }
        }
Esempio n. 28
0
        public static void exec_try_read_prop(StackFrame frame, OpStep step, RunTimeScope scope)
        {
            ASBinCode.SLOT slot = ((StackSlotAccessor)step.arg1).getSlot(scope,frame);

            if (slot.isPropGetterSetter)
            {
                ((StackSlot)slot).linkTo(null);
                _do_prop_read(

                    ((StackSlot)slot).stackObjects.propGetSet,
                    frame,step,frame.player,scope,((StackSlot)slot).stackObjects.propBindObj,((StackSlot)slot).stackObjects.superPropBindClass
                    );
            }
            else if (slot.isSetThisItem)
            {
                SetThisItemSlot sslot = (SetThisItemSlot)((StackSlot)slot).getLinkSlot();

                ((StackSlot)slot).linkTo(null);

                //***调用索引器get***
                RunTimeValueBase func;
                var rtObj  = sslot.bindObj;
                var player = frame.player;
                var v2     = sslot.setindex;
                func = ((MethodGetterBase)sslot.get_this_item.bindField).getMethod(
                    rtObj
                    );

                var funCaller = player.funcCallerPool.create(frame,step.token);
                funCaller.SetFunction((ASBinCode.rtData.rtFunction)func); ((ASBinCode.rtData.rtFunction)func).Clear();
                funCaller.loadDefineFromFunction();
                if (!funCaller.createParaScope())
                {
                    return;
                }

                //funCaller.releaseAfterCall = true;

                bool success;
                funCaller.pushParameter(v2,0,out success);
                if (!success)
                {
                    frame.endStep(step);
                    return;
                }

                funCaller._tempSlot  = frame._tempSlot1;
                funCaller.returnSlot = step.reg.getSlot(scope,frame);

                StackSlot ret = (StackSlot)funCaller.returnSlot;
                ret.stackObjects._temp_try_write_setthisitem = ret._cache_setthisslot; ret.refPropChanged = true;
                ret._cache_setthisslot.bindObj       = rtObj;
                ret._cache_setthisslot.setindex      = v2;
                ret._cache_setthisslot.set_this_item = sslot.set_this_item;

                BlockCallBackBase cb = frame.player.blockCallBackPool.create();
                cb.setCallBacker(D_get_this_item_callbacker);
                cb.step = step;
                cb.args = frame;

                funCaller.callbacker = cb;
                funCaller.call();

                return;
            }
            else
            {
                SLOT regslot = step.reg.getSlot(scope,frame);

                StackSlot d = regslot as StackSlot;
                StackSlot s = slot as StackSlot;

                if (d != null && s != null && s.getLinkSlot() != null)
                {
                    d.linkTo(s.getLinkSlot());
                    s.linkTo(null);
                }
                else
                {
                    regslot.directSet(slot.getValue());
                }
                //frame.endStep(step);
                frame.endStepNoError();
            }
        }
Esempio n. 29
0
            public static StackSlot[] ModifyStackDup2X2(StackSlot[] stack)
            {
                var s1 = stack[stack.Length - 1];
                var s2 = stack[stack.Length - 2];
                if (s1.IsCategory2 && s2.IsCategory2)
                {
                    // Form 4
                    return ModifyStackDupX1(stack);
                }

                var s3 = stack[stack.Length - 3];
                if (s3.IsCategory2 && !s1.IsCategory2 && !s2.IsCategory2)
                {
                    // Form 3
                    var value1 = stack[stack.Length - 1].Definitions;
                    var value2 = stack[stack.Length - 2].Definitions;
                    var value3 = stack[stack.Length - 3].Definitions;

                    var newStack = new StackSlot[stack.Length - 3 + 5];
                    Array.Copy(stack, newStack, stack.Length - 3);
                    newStack[newStack.Length - 5] = new StackSlot(value2, null);
                    newStack[newStack.Length - 4] = new StackSlot(value1, null);
                    newStack[newStack.Length - 3] = new StackSlot(value3, null);
                    newStack[newStack.Length - 2] = new StackSlot(value2, null);
                    newStack[newStack.Length - 1] = new StackSlot(value1, null);
                    return newStack;
                }
                
                if (s1.IsCategory2)
                {
                    // Form 2
                    var value1 = stack[stack.Length - 1].Definitions;
                    var value2 = stack[stack.Length - 2].Definitions;
                    var value3 = stack[stack.Length - 3].Definitions;

                    var newStack = new StackSlot[stack.Length - 3 + 4];
                    Array.Copy(stack, newStack, stack.Length - 3);
                    newStack[newStack.Length - 4] = new StackSlot(value1, null);
                    newStack[newStack.Length - 3] = new StackSlot(value3, null);
                    newStack[newStack.Length - 2] = new StackSlot(value2, null);
                    newStack[newStack.Length - 1] = new StackSlot(value1, null);
                    return newStack;
                }
                else
                {
                    var value1 = stack[stack.Length - 1].Definitions;
                    var value2 = stack[stack.Length - 2].Definitions;
                    var value3 = stack[stack.Length - 3].Definitions;
                    var value4 = stack[stack.Length - 4].Definitions;

                    var newStack = new StackSlot[stack.Length - 4 + 6];
                    Array.Copy(stack, newStack, stack.Length - 4);
                    newStack[newStack.Length - 6] = new StackSlot(value2, null);
                    newStack[newStack.Length - 5] = new StackSlot(value1, null);
                    newStack[newStack.Length - 4] = new StackSlot(value4, null);
                    newStack[newStack.Length - 3] = new StackSlot(value3, null);
                    newStack[newStack.Length - 2] = new StackSlot(value2, null);
                    newStack[newStack.Length - 1] = new StackSlot(value1, null);
                    return newStack;
                }
            }
Esempio n. 30
0
 public static StackSlot[] ModifyStackPop2(StackSlot[] stack) 
 {
     if (stack[stack.Length - 1].IsCategory2)
     {
         // Form 2
         return ModifyStack(stack, 1, 0, null);
     }
     else
     {
         // Form 1
         return ModifyStack(stack, 2, 0, null);
     }
 }
        public static void exec_AccessorBind_ConvertIdx(StackFrame frame, OpStep step, RunTimeScope scope)
        {
            RunTimeValueBase obj = step.arg1.getValue(scope, frame);

            if (rtNull.nullptr.Equals(obj))
            {
                frame.throwError(

                    step.token, 1009, "Cannot access a property or method of a null object reference."

                    );
                frame.endStep();
                return;
            }
            ASBinCode.rtti.Vector_Data vector =
                (ASBinCode.rtti.Vector_Data)((ASBinCode.rtti.HostedObject)((ASBinCode.rtData.rtObjectBase)obj).value).hosted_object;


            var idxvalue = step.arg2.getValue(scope, frame);

            double idx = double.NaN;

            if (idxvalue.rtType > RunTimeDataType.unknown)
            {
                RunTimeDataType ot;
                if (TypeConverter.Object_CanImplicit_ToPrimitive(idxvalue.rtType, frame.player.swc, out ot))
                {
                    var v = TypeConverter.ObjectImplicit_ToPrimitive((rtObjectBase)idxvalue);
                    idx = TypeConverter.ConvertToNumber(v);
                }
            }
            else if (idxvalue.rtType == RunTimeDataType.rt_string ||
                     idxvalue.rtType == RunTimeDataType.rt_int ||
                     idxvalue.rtType == RunTimeDataType.rt_number ||
                     idxvalue.rtType == RunTimeDataType.rt_uint
                     )
            {
                idx = TypeConverter.ConvertToNumber(idxvalue);
            }

            if (double.IsNaN(idx))
            {
                frame.throwError(

                    step.token, 0,
                    "索引" + idxvalue + "不能转为int"

                    );
            }
            else
            {
                int index = (int)idx;

                if (index < 0 || index > vector.innnerList.Count)
                {
                    frame.throwError(step.token, 1125,
                                     "The index " + index + " is out of range " + vector.innnerList.Count + ".");
                }

                StackSlotAccessor reg = (StackSlotAccessor)step.reg;

                if (idx == vector.innnerList.Count)
                {
                    if (vector.isFixed || !reg._isassigntarget)
                    {
                        frame.throwError(step.token,
                                         1125,
                                         "The index " + idx + " is out of range " + vector.innnerList.Count + ".");
                        frame.endStep(step);
                        return;
                    }
                    else
                    {
                        vector.innnerList.Add(TypeConverter.getDefaultValue(vector.vector_type).getValue(null, null));
                    }
                }


                StackSlot slot = (StackSlot)step.reg.getSlot(scope, frame);

                if (reg._isassigntarget || reg._hasUnaryOrShuffixOrDelete)
                {
                    slot._cache_vectorSlot.idx         = index;
                    slot._cache_vectorSlot.vector_data = vector;

                    slot.linkTo(slot._cache_vectorSlot);
                }
                else
                {
                    slot.directSet(vector.innnerList[index]);
                }
            }


            frame.endStep(step);
        }
        public static void exec_AccessorBind(StackFrame frame, OpStep step, RunTimeScope scope)
        {
            RunTimeValueBase obj = step.arg1.getValue(scope, frame);

            if (rtNull.nullptr.Equals(obj))
            {
                frame.throwError(

                    step.token, 1009, "Cannot access a property or method of a null object reference."

                    );
                frame.endStep();
                return;
            }


            ASBinCode.rtti.Vector_Data vector =
                (ASBinCode.rtti.Vector_Data)((ASBinCode.rtti.HostedObject)((rtObjectBase)obj).value).hosted_object;

            int idx = TypeConverter.ConvertToInt(step.arg2.getValue(scope, frame));

            if (idx < 0 || idx > vector.innnerList.Count)
            {
                frame.throwError(step.token, 1125,
                                 "The index " + idx + " is out of range " + vector.innnerList.Count + ".");
            }

            StackSlotAccessor reg = (StackSlotAccessor)step.reg;

            if (idx == vector.innnerList.Count)
            {
                if (vector.isFixed || !reg._isassigntarget)
                {
                    frame.throwError(step.token, 1125,
                                     "The index " + idx + " is out of range " + vector.innnerList.Count + "."
                                     );
                    frame.endStep(step);
                    return;
                }
                else
                {
                    vector.innnerList.Add(TypeConverter.getDefaultValue(vector.vector_type).getValue(null, null));
                }
            }



            StackSlot slot = (StackSlot)step.reg.getSlot(scope, frame);

            if (reg._isassigntarget || reg._hasUnaryOrShuffixOrDelete)
            {
                slot._cache_vectorSlot.idx         = idx;
                slot._cache_vectorSlot.vector_data = vector;

                slot.linkTo(slot._cache_vectorSlot);
            }
            else
            {
                slot.directSet(vector.innnerList[idx]);
            }

            frame.endStep(step);
        }
Esempio n. 33
0
        List <ILNode> ConvertToAst(List <ByteCode> body)
        {
            List <ILNode> ast = new List <ILNode>();

            // Convert stack-based IL code to ILAst tree
            foreach (ByteCode byteCode in body)
            {
                ILRange ilRange = new ILRange()
                {
                    From = byteCode.Offset, To = byteCode.EndOffset
                };

                if (byteCode.StackBefore == null)
                {
                    // Unreachable code
                    continue;
                }

                ILExpression expr = new ILExpression(byteCode.Code, byteCode.Operand);
                expr.ILRanges.Add(ilRange);
                if (byteCode.Prefixes != null && byteCode.Prefixes.Length > 0)
                {
                    ILExpressionPrefix[] prefixes = new ILExpressionPrefix[byteCode.Prefixes.Length];
                    for (int i = 0; i < prefixes.Length; i++)
                    {
                        prefixes[i] = new ILExpressionPrefix((ILCode)byteCode.Prefixes[i].OpCode.Code, byteCode.Prefixes[i].Operand);
                    }
                    expr.Prefixes = prefixes;
                }

                // Label for this instruction
                if (byteCode.Label != null)
                {
                    ast.Add(byteCode.Label);
                }

                // Reference arguments using temporary variables
                int popCount = byteCode.PopCount ?? byteCode.StackBefore.Count;
                for (int i = byteCode.StackBefore.Count - popCount; i < byteCode.StackBefore.Count; i++)
                {
                    StackSlot slot = byteCode.StackBefore[i];
                    expr.Arguments.Add(new ILExpression(ILCode.Ldloc, slot.LoadFrom));
                }

                // Store the result to temporary variable(s) if needed
                if (byteCode.StoreTo == null || byteCode.StoreTo.Count == 0)
                {
                    ast.Add(expr);
                }
                else if (byteCode.StoreTo.Count == 1)
                {
                    ast.Add(new ILExpression(ILCode.Stloc, byteCode.StoreTo[0], expr));
                }
                else
                {
                    ILVariable tmpVar = new ILVariable()
                    {
                        Name = "expr_" + byteCode.Offset.ToString("X2"), IsGenerated = true
                    };
                    ast.Add(new ILExpression(ILCode.Stloc, tmpVar, expr));
                    foreach (ILVariable storeTo in byteCode.StoreTo.AsEnumerable().Reverse())
                    {
                        ast.Add(new ILExpression(ILCode.Stloc, storeTo, new ILExpression(ILCode.Ldloc, tmpVar)));
                    }
                }
            }

            return(ast);
        }
Esempio n. 34
0
            public static StackSlot[] ModifyStackDup2X1(StackSlot[] stack)
            {
                if (stack[stack.Length - 1].IsCategory2)
                {
                    // Form 2
                    return ModifyStackDupX1(stack);
                }
                else
                {
                    // Form 1
                    var value1 = stack[stack.Length - 1].Definitions;
                    var value2 = stack[stack.Length - 2].Definitions;
                    var value3 = stack[stack.Length - 3].Definitions;

                    var newStack = new StackSlot[stack.Length - 3 + 5];
                    Array.Copy(stack, newStack, stack.Length - 3);
                    newStack[newStack.Length - 5] = new StackSlot(value2, null);
                    newStack[newStack.Length - 4] = new StackSlot(value1, null);
                    newStack[newStack.Length - 3] = new StackSlot(value3, null);
                    newStack[newStack.Length - 2] = new StackSlot(value2, null);
                    newStack[newStack.Length - 1] = new StackSlot(value1, null);
                    return newStack;
                }
            }