Exemple #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);
        }
Exemple #2
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);
        }
Exemple #3
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);
        }