Пример #1
0
        public static unsafe RuntimeIshtarMethod DecodeMethod(byte[] arr, VeinClass @class, RuntimeIshtarModule ishtarModule)
        {
            using var mem    = new MemoryStream(arr);
            using var binary = new BinaryReader(mem);
            var idx       = binary.ReadInt32();
            var flags     = (MethodFlags)binary.ReadInt16();
            var bodysize  = binary.ReadInt32();
            var stacksize = binary.ReadByte();
            var locals    = binary.ReadByte();
            var retType   = binary.ReadTypeName(ishtarModule);
            var args      = ReadArguments(binary, ishtarModule);
            var body      = binary.ReadBytes(bodysize);


            var mth = new RuntimeIshtarMethod(ishtarModule.GetConstStringByIndex(idx), flags,
                                              ishtarModule.FindType(retType, true, false),
                                              @class, args.ToArray());

            if (mth.IsExtern)
            {
                return(mth);
            }

            ConstructIL(mth, body, stacksize, ishtarModule);

            return(mth);
        }
Пример #2
0
 public static void DecodeField(BinaryReader binary, VeinClass @class, RuntimeIshtarModule ishtarModule)
 {
     foreach (var _ in..binary.ReadInt32())
     {
         var name      = FieldName.Resolve(binary.ReadInt32(), ishtarModule);
         var type_name = binary.ReadTypeName(ishtarModule);
         var type      = ishtarModule.FindType(type_name, true, false);
         var flags     = (FieldFlags)binary.ReadInt16();
         var method    = new RuntimeIshtarField(@class, name, flags, type);
         @class.Fields.Add(method);
     }
 }
Пример #3
0
        private static List <VeinArgumentRef> ReadArguments(BinaryReader binary, RuntimeIshtarModule ishtarModule)
        {
            var args = new List <VeinArgumentRef>();

            foreach (var _ in..binary.ReadInt32())
            {
                var nIdx = binary.ReadInt32();
                var type = binary.ReadTypeName(ishtarModule);
                args.Add(new VeinArgumentRef
                {
                    Name = ishtarModule.GetConstStringByIndex(nIdx),
                    Type = ishtarModule.FindType(type, true, false)
                });
            }
            return(args);
        }
Пример #4
0
        public static RuntimeIshtarClass DecodeClass(byte[] arr, RuntimeIshtarModule ishtarModule)
        {
            using var mem    = new MemoryStream(arr);
            using var binary = new BinaryReader(mem);
            var className = binary.ReadTypeName(ishtarModule);
            var flags     = (ClassFlags)binary.ReadInt16();

            var parentLen = binary.ReadInt16();

            var parents = new List <VeinClass>();

            foreach (var _ in..parentLen)
            {
                var parentIdx = binary.ReadTypeName(ishtarModule);
                parents.Add(ishtarModule.FindType(parentIdx, true, false));
            }


            var len = binary.ReadInt32();

            var @class = new RuntimeIshtarClass(className, parents.ToArray()
                                                , ishtarModule)
            {
                Flags = flags
            };

            foreach (var _ in..len)
            {
                var body =
                    binary.ReadBytes(binary.ReadInt32());
                var method = DecodeMethod(body, @class, ishtarModule);
                @class.Methods.Add(method);
            }

            DecodeField(binary, @class, ishtarModule);

            return(@class);
        }
Пример #5
0
        public static RuntimeIshtarModule Read(AppVault vault, byte[] arr, IReadOnlyList <VeinModule> deps, Func <string, Version, VeinModule> resolver)
        {
            var module = new RuntimeIshtarModule(vault);

            using var mem    = new MemoryStream(arr);
            using var reader = new BinaryReader(mem);
            module.Deps.AddRange(deps);

            var idx       = reader.ReadInt32(); // name index
            var vdx       = reader.ReadInt32(); // version index
            var ilVersion = reader.ReadInt32();

            if (ilVersion != OpCodes.SetVersion)
            {
                var exp = new ILCompatibleException(ilVersion, OpCodes.SetVersion);

                VM.FastFail(WNE.ASSEMBLY_COULD_NOT_LOAD, $"Unable to load assembly: '{exp.Message}'.", sys_frame);
                VM.ValidateLastError();
                return(null);
            }

            // read strings table
            foreach (var _ in..reader.ReadInt32())
            {
                var key   = reader.ReadInt32();
                var value = reader.ReadIshtarString();
                module.strings_table.Add(key, value);
            }
            // read types table
            foreach (var _ in..reader.ReadInt32())
            {
                var key     = reader.ReadInt32();
                var asmName = reader.ReadIshtarString();
                var ns      = reader.ReadIshtarString();
                var name    = reader.ReadIshtarString();
                module.types_table.Add(key, new QualityTypeName(asmName, name, ns));
            }
            // read fields table
            foreach (var _ in..reader.ReadInt32())
            {
                var key   = reader.ReadInt32();
                var name  = reader.ReadIshtarString();
                var clazz = reader.ReadIshtarString();
                module.fields_table.Add(key, new FieldName(name, clazz));
            }

            // read deps refs
            foreach (var _ in..reader.ReadInt32())
            {
                var name = reader.ReadIshtarString();
                var ver  = Version.Parse(reader.ReadIshtarString());
                if (module.Deps.Any(x => x.Version.Equals(ver) && x.Name.Equals(name)))
                {
                    continue;
                }
                var dep = resolver(name, ver);
                module.Deps.Add(dep);
            }
            // read class storage
            foreach (var _ in..reader.ReadInt32())
            {
                var body   = reader.ReadBytes(reader.ReadInt32());
                var @class = DecodeClass(body, module);
                module.class_table.Add(@class);
                if (@class.IsSpecial)
                {
                    if (VeinCore.All.Any(x => x.FullName == @class.FullName))
                    {
                        TypeForwarder.Indicate(@class);
                    }
                }
            }
            // restore unresolved types
            foreach (var @class in module.class_table)
            {
                for (var index = 0; index < @class.Parents.Count; index++)
                {
                    var parent = @class.Parents[index];
                    if (parent is not UnresolvedVeinClass)
                    {
                        continue;
                    }
                    @class.Parents[index] =
                        parent.FullName != @class.FullName
                            ? module.FindType(parent.FullName, true)
                            : null;
                }
            }
            // restore unresolved types
            foreach (var @class in module.class_table)
            {
                foreach (var method in @class.Methods)
                {
                    if (method.ReturnType is not UnresolvedVeinClass)
                    {
                        continue;
                    }
                    method.ReturnType = module.FindType(method.ReturnType.FullName, true);
                }

                foreach (var method in @class.Methods)
                {
                    foreach (var argument in method.Arguments)
                    {
                        if (argument.Type is not UnresolvedVeinClass)
                        {
                            continue;
                        }
                        argument.Type = module.FindType(argument.Type.FullName, true);
                    }
                }
                foreach (var field in @class.Fields)
                {
                    if (field.FieldType is not UnresolvedVeinClass)
                    {
                        continue;
                    }
                    field.FieldType = module.FindType(field.FieldType.FullName, true);
                }
            }

            var const_body_len = reader.ReadInt32();
            var const_body     = reader.ReadBytes(const_body_len);

            module.const_table = const_body.ToConstStorage();

            module.Name    = module.GetConstStringByIndex(idx);
            module.Version = Version.Parse(module.GetConstStringByIndex(vdx));
            module.aspects.AddRange(Aspect.Deconstruct(module.const_table.storage));

            module.SetupBootstraper(vault);

            DistributionAspects(module);
            ValidateRuntimeTokens(module);
            LinkFFIMethods(module);
            InitVTables(module);

            return(module);
        }