예제 #1
0
        public virtual bool ValidateImports(ModuleImportDescriptor descriptor)
        {
            foreach (MethodImportDescriptor method in descriptor.Imports)
            {
                if (!_methods.ContainsKey(HashMethod(method.Name, method.Signature)))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #2
0
        public bool ValidateImports(ModuleImportDescriptor descriptor)
        {
            foreach (MethodImportDescriptor method in descriptor.Imports)
            {
                if (Exports.FirstOrDefault(lnk => lnk.Signature == method.Signature && lnk.Name == method.Name) == null)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #3
0
        IModule GetModule(string path, ModuleImportDescriptor descriptor)
        {
            IModule result;

            if (!_loadedModules.TryGetValue(path, out result))
            {
                ObjectFile obj = ObjectFile.FromFile(path);
                if (obj == null)
                {
                    return(null);
                }

                result = Module.FromObjectFile(this, obj);
                _loadedModules[path] = result;
            }

            if (!result.ValidateImports(descriptor))
            {
                return(null);
            }

            return(result);
        }
예제 #4
0
        void ExecuteInstruction()
        {
            switch (_currentInstruction.Opcode)
            {
            case Op.addb:
            {
                byte src    = ReadSourceAsByte();
                byte middle = ReadMiddleAsByte();
                WriteDestinationAsByte((byte)((src + middle) & 0xff));
                break;
            }

            case Op.addc:
            {
                DisString src    = ReadSourceAsObject <DisString> () ?? DisString.Empty;
                DisString middle = ReadMiddleAsObject <DisString> () ?? DisString.Empty;
                DisString result = new DisString(middle.NativeValue + src.NativeValue);
                WriteDestinationAsObject(result);

                break;
            }

            case Op.addf:
            {
                double src    = ReadSourceAsFloat();
                double middle = ReadMiddleAsFloat();
                WriteDestinationAsFloat(src + middle);
                break;
            }

            case Op.addl:
            {
                long src    = ReadSourceAsInt64();
                long middle = ReadMiddleAsInt64();
                WriteDestinationAsInt64(src + middle);
                break;
            }

            case Op.addw:
            {
                int src    = ReadSourceAsInt32();
                int middle = ReadMiddleAsInt32();
                WriteDestinationAsInt32(src + middle);
                break;
            }

            case Op.alt:
                break;

            case Op.andb:
                WriteDestinationAsByte((byte)((ReadSourceAsByte() & ReadMiddleAsByte()) & 0xff));
                break;

            case Op.andl:
                WriteDestinationAsInt64(ReadSourceAsInt64() & ReadMiddleAsInt64());
                break;

            case Op.andw:
                WriteDestinationAsInt32(ReadSourceAsInt32() & ReadMiddleAsInt32());
                break;

            case Op.beqb:
            {
                if (ReadSourceAsByte() == ReadMiddleAsByte())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.beqc:
                break;

            case Op.beqf:
            {
                if (ReadSourceAsFloat() == ReadMiddleAsFloat())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.beql:
            {
                if (ReadSourceAsInt64() == ReadMiddleAsInt64())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.beqw:
            {
                if (ReadSourceAsInt32() == ReadMiddleAsInt32())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bgeb:
            {
                if (ReadSourceAsByte() >= ReadMiddleAsByte())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bgec:
                break;

            case Op.bgef:
            {
                if (ReadSourceAsFloat() >= ReadMiddleAsFloat())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bgel:
            {
                if (ReadSourceAsInt64() >= ReadMiddleAsInt64())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bgew:
            {
                if (ReadSourceAsInt32() >= ReadMiddleAsInt32())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bgtb:
            {
                if (ReadSourceAsByte() > ReadMiddleAsByte())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bgtc:
                break;

            case Op.bgtf:
            {
                if (ReadSourceAsFloat() > ReadMiddleAsFloat())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bgtl:
            {
                if (ReadSourceAsInt64() > ReadMiddleAsInt64())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bgtw:
            {
                if (ReadSourceAsInt32() > ReadMiddleAsInt32())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bleb:
            {
                if (ReadSourceAsByte() <= ReadMiddleAsByte())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.blec:
                break;

            case Op.blef:
            {
                if (ReadSourceAsFloat() <= ReadMiddleAsFloat())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.blel:
            {
                if (ReadSourceAsInt64() <= ReadMiddleAsInt64())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.blew:
            {
                if (ReadSourceAsInt32() <= ReadMiddleAsInt32())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bltb:
            {
                if (ReadSourceAsByte() < ReadMiddleAsByte())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bltc:
                break;

            case Op.bltf:
            {
                if (ReadSourceAsFloat() < ReadMiddleAsFloat())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bltl:
            {
                if (ReadSourceAsInt64() < ReadMiddleAsInt64())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bltw:
            {
                if (ReadSourceAsInt32() < ReadMiddleAsInt32())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bneb:
            {
                if (ReadSourceAsByte() != ReadMiddleAsByte())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bnec:
                break;

            case Op.bnef:
            {
                if (ReadSourceAsFloat() != ReadMiddleAsFloat())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bnel:
            {
                if (ReadSourceAsInt64() != ReadMiddleAsInt64())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.bnew:
            {
                if (ReadSourceAsInt32() != ReadMiddleAsInt32())
                {
                    _currentThread.PC = ReadDestinationAsInt32();
                }
                break;
            }

            case Op.call:
            {
                int currentSize = _frames.Peek().Size;
                PushCallFrame(new IntPtr(ReadSourceAsInt32()));
                _currentThread.PC = ReadDestinationAsInt32();

                int frame = PointerToCurrentFrame().ToInt32();

                FP = ReadSourceAsInt32() - frame;
                break;
            }

            case Op.@case:
                break;

            case Op.casec:
                break;

            case Op.consb:
                break;

            case Op.consf:
                break;

            case Op.consl:
                break;

            case Op.consm:
                break;

            case Op.consmp:
                break;

            case Op.consp:
                break;

            case Op.consw:
                break;

            case Op.cvtac:
            {
                DisByteArray array = ReadSourceAsObject <DisByteArray> ();
                WriteDestinationAsObject(new DisString(array.InnerArray));
                break;
            }

            case Op.cvtbw:
                WriteDestinationAsInt32(ReadSourceAsByte());
                break;

            case Op.cvtca:
            {
                DisString str = ReadSourceAsObject <DisString> ();
                WriteDestinationAsObject(new DisByteArray(str.Bytes));
                break;
            }

            case Op.cvtcf:
            {
                DisString str = ReadSourceAsObject <DisString> ();
                WriteDestinationAsFloat(Double.Parse(str.NativeValue));
                break;
            }

            case Op.cvtcl:
            {
                DisString str = ReadSourceAsObject <DisString> ();
                WriteDestinationAsInt64(Int64.Parse(str.NativeValue));
                break;
            }

            case Op.cvtcw:
            {
                DisString str = ReadSourceAsObject <DisString> ();
                WriteDestinationAsInt32(Int32.Parse(str.NativeValue));
                break;
            }

            case Op.cvtfc:
                WriteDestinationAsObject(new DisString(ReadSourceAsFloat().ToString()));
                break;

            case Op.cvtfl:
                WriteDestinationAsInt64((Int64)ReadSourceAsFloat());
                break;

            case Op.cvtfr:
                WriteDestinationAsSingle((Single)ReadSourceAsFloat());
                break;

            case Op.cvtfw:
                WriteDestinationAsInt32((Int32)ReadSourceAsFloat());
                break;

            case Op.cvtlc:
                WriteDestinationAsObject(new DisString(ReadSourceAsFloat().ToString()));
                break;

            case Op.cvtlf:
                WriteDestinationAsFloat(ReadSourceAsInt64());
                break;

            case Op.cvtlw:
                WriteDestinationAsInt32((int)ReadSourceAsInt64());
                break;

            case Op.cvtrf:
                WriteDestinationAsFloat((Double)ReadSourceAsSingle());
                break;

            case Op.cvtsw:
                WriteDestinationAsInt32((Int32)ReadSourceAsInt16());
                break;

            case Op.cvtwb:
                WriteDestinationAsByte((byte)ReadSourceAsInt32());
                break;

            case Op.cvtwc:
                WriteDestinationAsObject(new DisString(ReadSourceAsInt32().ToString()));
                break;

            case Op.cvtwf:
                WriteDestinationAsFloat(ReadSourceAsInt32());
                break;

            case Op.cvtwl:
                WriteDestinationAsInt64(ReadSourceAsInt32());
                break;

            case Op.cvtws:
                WriteDestinationAsInt16((Int16)ReadSourceAsInt32());
                break;

            case Op.divb:
                WriteDestinationAsByte((byte)(ReadMiddleAsByte() / ReadSourceAsByte()));
                break;

            case Op.divf:
                WriteDestinationAsFloat(ReadMiddleAsFloat() / ReadSourceAsFloat());
                break;

            case Op.divl:
                WriteDestinationAsInt64(ReadMiddleAsInt64() / ReadSourceAsInt64());
                break;

            case Op.divw:
                WriteDestinationAsInt32(ReadMiddleAsInt32() / ReadSourceAsInt32());
                break;

            case Op.eclr:
                break;

            case Op.exit:
                break;

            case Op.frame:
            {
                int    type = ReadSourceAsInt32();
                IntPtr ptr  = PointerToFrame(FP + _currentModule.Types[type].Size);
                WriteDestinationAsInt32(ptr.ToInt32());
                break;
            }

            case Op.@goto:
                break;

            case Op.headb:
                break;

            case Op.headf:
                break;

            case Op.headl:
                break;

            case Op.headm:
                break;

            case Op.headmp:
                break;

            case Op.headp:
                break;

            case Op.headw:
                break;

            case Op.indc:
            {
                DisString str = ReadSourceAsObject <DisString> ();
                WriteDestinationAsInt32((int)str.NativeValue[ReadMiddleAsInt32()]);
                break;
            }

            case Op.indb:
            case Op.indf:
            case Op.indl:
            case Op.indw:
            case Op.indx:
            {
                DisArray array = ReadSourceAsObject <DisArray> ();
                WriteMiddleAsInt32((int)array.GetPointerAt(ReadDestinationAsInt32()));
                break;
            }

            case Op.insc:
            {
                DisString str = ReadSourceAsObject <DisString> ();
                str.InsertCharAt(ReadMiddleAsInt32(), (char)ReadDestinationAsInt32());
                break;
            }

            case Op.jmp:
                _currentThread.PC = ReadDestinationAsInt32();
                break;

            case Op.lea:
            {
                WriteDestinationAsInt32((int)GetSourcePointer());
                break;
            }

            case Op.lena:
            {
                DisArray array = ReadSourceAsObject <DisArray> ();
                WriteDestinationAsInt32(array.Length);
                break;
            }

            case Op.lenc:
            {
                DisString str = ReadSourceAsObject <DisString> () ?? DisString.Empty;
                WriteDestinationAsInt32(Encoding.UTF8.GetCharCount(str.Bytes));
                break;
            }

            case Op.lenl:
                break;

            case Op.load:
            {
                string path = ReadSourceAsObject <DisString> ().NativeValue;

                int linkId = ReadMiddleAsInt32();

                ModuleImportDescriptor descriptor = _currentModule.ImportedModules[linkId];
                IModule m = GetModule(path, descriptor);
                if (m == null)
                {
                    WriteDestinationAsObject(null);
                }
                else
                {
                    DisModuleRef moduleRef = new DisModuleRef {
                        Module = m,
                        LinkId = linkId
                    };

                    WriteDestinationAsObject(moduleRef);
                }
                break;
            }

            case Op.lsrl:
                break;

            case Op.lsrw:
                break;

            case Op.mcall:
            {
                PushCallFrame(new IntPtr(ReadSourceAsInt32()));

                int currentSize = _frames.Peek().Size;

                int frame = PointerToCurrentFrame().ToInt32();
                FP = ReadSourceAsInt32() - frame;

                DisModuleRef           moduleRef = ReadDestinationAsObject <DisModuleRef> ();
                ModuleImportDescriptor mimp      = _currentModule.ImportedModules[moduleRef.LinkId];
                MethodImportDescriptor method    = mimp.Imports[ReadMiddleAsInt32()];

                if (moduleRef.Module is Module)
                {
                    _currentModule    = (Module)moduleRef.Module;
                    _currentThread.PC = _currentModule.Exports.FirstOrDefault(m => m.Signature == method.Signature && m.Name == method.Name).PC;
                }
                else
                {
                    NativeModule native = (NativeModule)moduleRef.Module;
                    var          m      = native.GetMethod(method.Name, method.Signature);
                    m.Invoke(this);
                }

                break;
            }

            case Op.mframe:
            {
                DisModuleRef           moduleRef  = ReadSourceAsObject <DisModuleRef> ();
                ModuleImportDescriptor descriptor = _currentModule.ImportedModules[moduleRef.LinkId];
                MethodImportDescriptor method     = descriptor.Imports[ReadMiddleAsInt32()];

                IntPtr ptr = PointerToFrame(FP + moduleRef.Module.GetFrameSize(method.Name, method.Signature));
                WriteDestinationAsInt32(ptr.ToInt32());
                break;
            }

            case Op.mnewz:
                break;

            case Op.modb:
                WriteDestinationAsByte((byte)((ReadMiddleAsByte() % ReadSourceAsByte()) & 0xff));
                break;

            case Op.modl:
                WriteDestinationAsInt64(ReadMiddleAsInt64() % ReadSourceAsInt64());
                break;

            case Op.modw:
                WriteDestinationAsInt32(ReadMiddleAsInt32() % ReadSourceAsInt32());
                break;

            case Op.movb:
                WriteDestinationAsByte(ReadSourceAsByte());
                break;

            case Op.movf:
                WriteDestinationAsFloat(ReadSourceAsFloat());
                break;

            case Op.movl:
                WriteDestinationAsInt64(ReadSourceAsInt64());
                break;

            case Op.movm:
                break;

            case Op.movmp:
                break;

            case Op.movp:
            {
                WriteDestinationAsObject(ReadSourceAsObject <DisObject> ());
                break;
            }

            case Op.movpc:
                break;

            case Op.movw:
            {
                WriteDestinationAsInt32(ReadSourceAsInt32());
                break;
            }

            case Op.mspawn:
                break;

            case Op.mulb:
                WriteDestinationAsByte((byte)((ReadMiddleAsByte() * ReadSourceAsByte()) & 0xff));
                break;

            case Op.mulf:
                WriteDestinationAsFloat(ReadMiddleAsFloat() * ReadSourceAsFloat());
                break;

            case Op.mull:
                WriteDestinationAsInt64(ReadMiddleAsInt64() * ReadSourceAsInt64());
                break;

            case Op.mulw:
                WriteDestinationAsInt32(ReadMiddleAsInt32() * ReadSourceAsInt32());
                break;

            case Op.nbalt:
                break;

            case Op.negf:
                WriteDestinationAsFloat(ReadSourceAsFloat() * -1.0);
                break;

            case Op.@new:
                break;

            case Op.newa:
            {
                int count = ReadSourceAsInt32();
                int type  = ReadMiddleAsInt32();
                int size  = _currentModule.Types[type].Size;

                DisArray array;
                switch (size)
                {
                case 4:
                    array = new DisInt32Array(count);
                    break;

                case 8:
                    array = new DisInt64Array(count);
                    break;

                default:
                    array = null;
                    break;
                }

                WriteDestinationAsObject(array);
                break;
            }

            case Op.newaz:
                break;

            case Op.newcb:
                break;

            case Op.newcf:
                break;

            case Op.newcl:
                break;

            case Op.newcm:
                break;

            case Op.newcmp:
                break;

            case Op.newcp:
                break;

            case Op.newcw:
                break;

            case Op.newz:
                break;

            case Op.nop:
                break;

            case Op.orb:
                WriteDestinationAsByte((byte)((ReadSourceAsByte() * ReadMiddleAsByte()) & 0xff));
                break;

            case Op.orl:
                WriteDestinationAsInt64(ReadSourceAsInt64() * ReadMiddleAsInt64());
                break;

            case Op.orw:
                WriteDestinationAsInt32(ReadSourceAsInt32() * ReadMiddleAsInt32());
                break;

            case Op.recv:
                break;

            case Op.ret:
            {
                PopCallFrame();
                break;
            }

            case Op.runt:
                break;

            case Op.send:
                break;

            case Op.shlb:
                break;

            case Op.shll:
                break;

            case Op.shlw:
                break;

            case Op.shrb:
                break;

            case Op.shrl:
                break;

            case Op.shrw:
                break;

            case Op.slicea:
                break;

            case Op.slicec:
                break;

            case Op.slicela:
                break;

            case Op.spawn:
                break;

            case Op.subb:
                WriteDestinationAsByte((byte)((ReadMiddleAsByte() - ReadSourceAsByte()) & 0xff));
                break;

            case Op.subf:
                WriteDestinationAsFloat(ReadMiddleAsFloat() - ReadSourceAsFloat());
                break;

            case Op.subl:
                WriteDestinationAsInt64(ReadMiddleAsInt64() - ReadSourceAsInt64());
                break;

            case Op.subw:
                WriteDestinationAsInt32(ReadMiddleAsInt32() - ReadSourceAsInt32());
                break;

            case Op.tail:
                break;

            case Op.tcmp:
            {
                DisObject src  = ReadSourceAsObject <DisObject> ();
                DisObject dest = ReadDestinationAsObject <DisObject> ();
                if (src.GetType() != dest.GetType())
                {
                    ;         // error ("typecheck")
                }
                break;
            }

            case Op.xorb:
                WriteDestinationAsByte((byte)((ReadSourceAsByte() ^ ReadMiddleAsByte()) & 0xff));
                break;

            case Op.xorl:
                WriteDestinationAsInt64(ReadSourceAsInt64() ^ ReadMiddleAsInt64());
                break;

            case Op.xorw:
                WriteDestinationAsInt32(ReadSourceAsInt32() ^ ReadMiddleAsInt32());
                break;
            }
        }
예제 #5
0
        public static ObjectFile FromReader(DisReader reader)
        {
            int magic = reader.ReadOP();

            if ((magic != XMAGIC) && (magic != SMAGIC))
            {
                throw new InvalidDataException("Invalid magic number");
            }

            if (magic == SMAGIC)
            {
                int    slength   = reader.ReadOP();
                byte[] signature = reader.ReadBytes(slength);
            }

            int runtimeFlag = reader.ReadOP();
            int stackExtent = reader.ReadOP();
            int codeSize    = reader.ReadOP();
            int dataSize    = reader.ReadOP();
            int typeSize    = reader.ReadOP();
            int linkSize    = reader.ReadOP();
            int entryPc     = reader.ReadOP();
            int entryType   = reader.ReadOP();

            ObjectFile result = new ObjectFile();

            result.ShareMP        = ((runtimeFlag & FLAG_SHAREMP) != 0);
            result.StackExtent    = stackExtent;
            result.EntryPC        = entryPc;
            result.EntryFrameType = entryType;

            result.Instructions = new Instruction[codeSize];
            for (int i = 0; i < codeSize; i++)
            {
                Instruction inst = Instruction.FromReader(reader);
                result.Instructions[i] = inst;
            }

            result.Types = new TypeDescriptor[typeSize];
            for (int i = 0; i < typeSize; i++)
            {
                result.Types[i] = TypeDescriptor.FromReader(reader);
            }


            List <DataDescriptor> data = new List <DataDescriptor> ();

            while (true)
            {
                DataDescriptor descriptor = DataDescriptor.FromReader(reader);
                if (descriptor.Code == 0)
                {
                    break;
                }

                data.Add(descriptor);
            }
            result.Data = data.ToArray();

            result.Name = reader.ReadString();

            result.Link = new ExportDescriptor[linkSize];
            for (int i = 0; i < linkSize; i++)
            {
                ExportDescriptor desc = ExportDescriptor.FromReader(reader);
                desc.FrameSize = result.Types[desc.FrameTypeId].Size;

                result.Link[i] = desc;
            }

            if (!reader.AtEndOfStream)
            {
                int importCount = reader.ReadOP();

                List <ModuleImportDescriptor> imports = new List <ModuleImportDescriptor> (importCount);
                for (int i = 0; i < importCount; i++)
                {
                    imports.Add(ModuleImportDescriptor.FromReader(reader));
                }

                result.Imports = imports.ToArray();
            }

            if (!reader.AtEndOfStream)
            {
                int handlerCount = reader.ReadOP();

                List <HandlerDescriptor> handlers = new List <HandlerDescriptor> (handlerCount);
                for (int i = 0; i < handlerCount; i++)
                {
                    handlers.Add(HandlerDescriptor.FromReader(reader));
                }

                result.Handlers = handlers.ToArray();
            }

            return(result);
        }