Пример #1
0
        public static IshtarObject *ToIshtarObject(nint dotnet_value, CallFrame frame = null, IshtarObject **node = null)
        {
            var obj = IshtarGC.AllocObject(TYPE_RAW.AsRuntimeClass(), node);

            obj->vtable = (void **)dotnet_value;
            return(obj);
        }
Пример #2
0
        public static char ToDotnetChar(IshtarObject *obj, CallFrame frame)
        {
            FFI.StaticTypeOf(frame, &obj, TYPE_CHAR);
            var clazz = obj->decodeClass();

            return((char)(int)(int *)obj->vtable[clazz.Field["!!value"].vtable_offset]);
        }
Пример #3
0
        public static short ToDotnetInt16(IshtarObject *obj, CallFrame frame)
        {
            FFI.StaticTypeOf(frame, &obj, TYPE_I2);
            var clazz = obj->decodeClass();

            return((short)(short *)obj->vtable[clazz.Field["!!value"].vtable_offset]);
        }
Пример #4
0
        public static float ToDotnetFloat(IshtarObject *obj, CallFrame frame)
        {
            FFI.StaticTypeOf(frame, &obj, TYPE_R4);
            var clazz = obj->decodeClass();

            return(BitConverter.Int32BitsToSingle((int)(int *)obj->vtable[clazz.Field["!!value"].vtable_offset]));
        }
Пример #5
0
        public static byte ToDotnetUInt8(IshtarObject *obj, CallFrame frame)
        {
            FFI.StaticTypeOf(frame, &obj, TYPE_U1);
            var clazz = obj->decodeClass();

            return((byte)(byte *)obj->vtable[clazz.Field["!!value"].vtable_offset]);
        }
Пример #6
0
        public static ulong ToDotnetUInt64(IshtarObject *obj, CallFrame frame)
        {
            FFI.StaticTypeOf(frame, &obj, TYPE_U8);
            var clazz = obj->decodeClass();

            return((ulong)(ulong *)obj->vtable[clazz.Field["!!value"].vtable_offset]);
        }
Пример #7
0
        public static void FillStackTrace(CallFrame frame)
        {
            var str = new StringBuilder();

            if (frame is null)
            {
                Console.WriteLine($"<<DETECTED NULL FRAME>>");
                return;
            }

            if (frame.method.Owner is not null)
            {
                str.AppendLine($"\tat {frame.method.Owner.FullName.NameWithNS}.{frame.method.Name}");
            }
            else
            {
                str.AppendLine($"\tat <sys>.{frame.method.Name}");
            }

            var r = frame.parent;

            while (r != null)
            {
                str.AppendLine($"\tat {r.method.Owner.FullName.NameWithNS}.{r.method.Name}");
                r = r.parent;
            }

            frame.exception ??= new CallFrameException();
            frame.exception.stack_trace = str.ToString();
        }
Пример #8
0
        public static bool ToDotnetBoolean(IshtarObject *obj, CallFrame frame)
        {
            FFI.StaticTypeOf(frame, &obj, TYPE_BOOLEAN);
            var clazz = obj->decodeClass();

            return((int)(int *)obj->vtable[clazz.Field["!!value"].vtable_offset] == 1);
        }
Пример #9
0
        public static IshtarObject *Fmt(CallFrame frame, IshtarObject **args)
        {
            var template_obj = args[0];
            var array_obj    = args[1];

            FFI.StaticValidate(frame, &template_obj);
            FFI.StaticValidate(frame, &array_obj);

            FFI.StaticTypeOf(frame, &template_obj, TYPE_STRING);
            FFI.StaticTypeOf(frame, &array_obj, TYPE_ARRAY);


            var arr = (IshtarArray *)array_obj;

            var dotnet_arr = new string[arr->length];

            for (var i = 0ul; i != arr->length; i++)
            {
                dotnet_arr[i] = IshtarMarshal.ToDotnetString(arr->Get((uint)i, frame), frame);
            }

            var template = IshtarMarshal.ToDotnetString(template_obj, frame);

            var result = string.Format(template, dotnet_arr);

            return(IshtarMarshal.ToIshtarObject(result, frame));
        }
Пример #10
0
        public static IshtarObject *ToIshtarObject(string str, CallFrame frame = null, IshtarObject **node = null)
        {
            var arg   = IshtarGC.AllocObject(TYPE_STRING.AsRuntimeClass(), node);
            var clazz = IshtarUnsafe.AsRef <RuntimeIshtarClass>(arg->clazz);

            arg->vtable[clazz.Field["!!value"].vtable_offset] = StringStorage.Intern(str);
            return(arg);
        }
Пример #11
0
        public static string ToDotnetString(IshtarObject *obj, CallFrame frame)
        {
            FFI.StaticTypeOf(frame, &obj, TYPE_STRING);
            var clazz = obj->decodeClass();
            var p     = (StrRef *)obj->vtable[clazz.Field["!!value"].vtable_offset];

            return(StringStorage.GetString(p, frame));
        }
Пример #12
0
        public static IshtarObject *ToIshtarObject(long dotnet_value, CallFrame frame = null, IshtarObject **node = null)
        {
            var obj   = IshtarGC.AllocObject(TYPE_I8.AsRuntimeClass(), node);
            var clazz = IshtarUnsafe.AsRef <RuntimeIshtarClass>(obj->clazz);

            obj->vtable[clazz.Field["!!value"].vtable_offset] = (long *)dotnet_value;

            return(obj);
        }
Пример #13
0
        public static IshtarObject *ToIshtarObject(float dotnet_value, CallFrame frame = null, IshtarObject **node = null)
        {
            var obj   = IshtarGC.AllocObject(TYPE_I8.AsRuntimeClass(), node);
            var clazz = IshtarUnsafe.AsRef <RuntimeIshtarClass>(obj->clazz);

            obj->vtable[clazz.Field["!!value"].vtable_offset] = (int *)BitConverter.SingleToInt32Bits(dotnet_value);

            return(obj);
        }
Пример #14
0
        public static IshtarObject *Exit(CallFrame current, IshtarObject **args)
        {
            var exitCode = args[0];

            FFI.StaticValidate(current, &exitCode);
            FFI.StaticTypeOf(current, &exitCode, TYPE_I4);
            FFI.StaticValidateField(current, &exitCode, "!!value");

            VM.halt(IshtarMarshal.ToDotnetInt32(exitCode, current));

            return(null);
        }
Пример #15
0
        public static IshtarObject *TemplateFunctionApply(CallFrame frame, IshtarObject **args, Func <string, string> apply)
        {
            var str1 = args[0];

            FFI.StaticValidate(frame, &str1);
            FFI.StaticTypeOf(frame, &str1, TYPE_STRING);

            var clr_str = IshtarMarshal.ToDotnetString(str1, frame);

            var result = apply(clr_str);

            return(IshtarMarshal.ToIshtarObject(result, frame));
        }
Пример #16
0
        public bool init_mapping(CallFrame frame)
        {
            bool failMapping(int code)
            {
                VM.FastFail(WNE.TYPE_LOAD,
                            $"Native aspect has incorrect mapping for '{FullName}' field. [0x{code:X}]", frame);
                VM.ValidateLastError();
                return(false);
            }

            var nativeAspect = Aspects.FirstOrDefault(x => x.Name == "Native");

            if (nativeAspect is null)
            {
                return(false);
            }
            if (nativeAspect.Arguments.Count != 1)
            {
                return(failMapping(0));
            }
            var arg = nativeAspect.Arguments.First().Value;

            if (arg is not string existName)
            {
                return(failMapping(1));
            }

            var existField = Owner.FindField(existName);

            if (existField is null)
            {
                return(failMapping(2));
            }

            if (existField.FieldType != FieldType)
            {
                return(failMapping(3));
            }

            if (existField is not RuntimeIshtarField runtimeField)
            {
                return(failMapping(4));
            }

            vtable_offset = runtimeField.vtable_offset;

            return(true);
        }
Пример #17
0
        public static RuntimeIshtarClass GetClass(uint index, VeinModule module, CallFrame frame)
        {
            var name = module.types_table.GetValueOrDefault((int)index);

            Assert(name is not null, WNE.TYPE_LOAD, $"Cant find '{index}' in class_table.", frame);
            var type = module.FindType(name, true, false);

            if (type is UnresolvedVeinClass)
            {
                FastFail(WNE.MISSING_TYPE, $"Cant load '{name.NameWithNS}' in '{name.AssemblyName}'", frame);
                ValidateLastError();
                return(null);
            }
            Assert(type is RuntimeIshtarClass, WNE.TYPE_LOAD, $"metadata is corrupted.");
            return(type as RuntimeIshtarClass);
        }
Пример #18
0
 public static IshtarObject *IsInstanceOf(CallFrame frame, IshtarObject * @this, RuntimeIshtarClass @class)
 {
     if ([email protected]_inited)
     {
         @class.init_vtable();
     }
     if (@this == null)
     {
         return(null);
     }
     if (@class.IsInterface)
     {
         return(IsInstanceOfByRef(frame, @this, @class));
     }
     return(IsAssignableFrom(frame, @class, @this->decodeClass()) ? @this : null);
 }
Пример #19
0
        public static IshtarObject *StrEqual(CallFrame frame, IshtarObject **args)
        {
            var i_str1 = args[0];
            var i_str2 = args[1];

            FFI.StaticValidate(frame, &i_str1);
            FFI.StaticValidate(frame, &i_str2);
            FFI.StaticTypeOf(frame, &i_str1, TYPE_STRING);
            FFI.StaticTypeOf(frame, &i_str2, TYPE_STRING);

            var str1 = IshtarMarshal.ToDotnetString(i_str1, frame);
            var str2 = IshtarMarshal.ToDotnetString(i_str2, frame);

            var result = str1.Equals(str2);

            return(IshtarMarshal.ToIshtarObject(result, frame));
        }
Пример #20
0
        public static X ToDotnet <X>(IshtarObject *obj, CallFrame frame)
        {
            switch (typeof(X))
            {
            case { } when typeof(X) == typeof(nint):
                return((X)(object)ToDotnetPointer(obj, frame));

            case { } when typeof(X) == typeof(sbyte):
                return((X)(object)ToDotnetInt8(obj, frame));

            case { } when typeof(X) == typeof(byte):
                return((X)(object)ToDotnetUInt8(obj, frame));

            case { } when typeof(X) == typeof(short):
                return((X)(object)ToDotnetInt16(obj, frame));

            case { } when typeof(X) == typeof(ushort):
                return((X)(object)ToDotnetUInt16(obj, frame));

            case { } when typeof(X) == typeof(int):
                return((X)(object)ToDotnetInt32(obj, frame));

            case { } when typeof(X) == typeof(uint):
                return((X)(object)ToDotnetUInt32(obj, frame));

            case { } when typeof(X) == typeof(long):
                return((X)(object)ToDotnetInt64(obj, frame));

            case { } when typeof(X) == typeof(ulong):
                return((X)(object)ToDotnetUInt64(obj, frame));

            case { } when typeof(X) == typeof(bool):
                return((X)(object)ToDotnetBoolean(obj, frame));

            case { } when typeof(X) == typeof(char):
                return((X)(object)ToDotnetChar(obj, frame));

            case { } when typeof(X) == typeof(string):
                return((X)(object)ToDotnetString(obj, frame));

            default:
                VM.FastFail(WNE.TYPE_MISMATCH,
                            $"[marshal::ToDotnet] converter for '{typeof(X).Name}' not support.", frame);
                return(default);
            }
        }
Пример #21
0
 public static IshtarObject *GetOSValue(CallFrame current, IshtarObject **args)
 {
     // TODO remove using RuntimeInformation
     if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
     {
         return(IshtarMarshal.ToIshtarObject(0, current));
     }
     if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
     {
         return(IshtarMarshal.ToIshtarObject(1, current));
     }
     if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
     {
         return(IshtarMarshal.ToIshtarObject(2, current));
     }
     return(IshtarMarshal.ToIshtarObject(-1, current));
 }
Пример #22
0
        public static IshtarObject *ToIshtarObject <X>(X value, CallFrame frame, IshtarObject **node = null)
        {
            switch (typeof(X))
            {
            case { } when typeof(X) == typeof(nint):
                return(ToIshtarObject(cast <nint>(value), frame, node));

            case { } when typeof(X) == typeof(sbyte):
                return(ToIshtarObject(cast <sbyte>(value), frame, node));

            case { } when typeof(X) == typeof(byte):
                return(ToIshtarObject(cast <byte>(value), frame, node));

            case { } when typeof(X) == typeof(short):
                return(ToIshtarObject(cast <short>(value), frame, node));

            case { } when typeof(X) == typeof(ushort):
                return(ToIshtarObject(cast <ushort>(value), frame, node));

            case { } when typeof(X) == typeof(int):
                return(ToIshtarObject(cast <int>(value), frame, node));

            case { } when typeof(X) == typeof(uint):
                return(ToIshtarObject(cast <uint>(value), frame, node));

            case { } when typeof(X) == typeof(long):
                return(ToIshtarObject(cast <long>(value), frame, node));

            case { } when typeof(X) == typeof(ulong):
                return(ToIshtarObject(cast <ulong>(value), frame, node));

            case { } when typeof(X) == typeof(char):
                return(ToIshtarObject(cast <char>(value), frame, node));

            case { } when typeof(X) == typeof(string):
                return(ToIshtarObject(cast <string>(value), frame, node));

            default:
                VM.FastFail(WNE.TYPE_MISMATCH,
                            $"[marshal::ToIshtarObject] converter for '{typeof(X).Name}' not support.", frame);
                return(default);
            }
        }
Пример #23
0
 public static bool IsAssignableFrom(CallFrame frame, RuntimeIshtarClass c1, RuntimeIshtarClass c2)
 {
     if (!c1.is_inited)
     {
         c1.init_vtable();
     }
     if (!c2.is_inited)
     {
         c2.init_vtable();
     }
     // TODO: Array detection
     // TODO: Generic detection
     // TODO: Interfrace detection
     if (c1.FullName == VeinCore.ObjectClass.FullName)
     {
         return(true);
     }
     return(c1.IsInner(c2));
 }
Пример #24
0
        public static IshtarObject *SwitchFlag(CallFrame current, IshtarObject **args)
        {
            var key   = args[0];
            var value = args[1];

            FFI.StaticValidate(current, &key);
            FFI.StaticTypeOf(current, &key, TYPE_STRING);
            FFI.StaticValidate(current, &value);
            FFI.StaticTypeOf(current, &value, TYPE_BOOLEAN);

            FFI.StaticValidateField(current, &key, "!!value");
            FFI.StaticValidateField(current, &value, "!!value");

            var clr_key   = IshtarMarshal.ToDotnetString(key, current);
            var clr_value = IshtarMarshal.ToDotnetBoolean(value, current);

            VM.Config.Set(clr_key, clr_value);

            return(null);
        }
Пример #25
0
        public static IshtarObject *FPrintLn(CallFrame current, IshtarObject **args)
        {
            var arg1 = args[0];

            if (arg1 == null)
            {
                current.ThrowException(KnowTypes.NullPointerException(current));
                return(null);
            }

            FFI.StaticValidate(current, &arg1);
            FFI.StaticTypeOf(current, &arg1, TYPE_STRING);
            var @class = arg1->decodeClass();

            var str = IshtarMarshal.ToDotnetString(arg1, current);

            Out.WriteLine();
            Out.WriteLine($"\t{str}");
            Out.WriteLine();

            return(null);
        }
Пример #26
0
 public void validate(CallFrame frame, VeinTypeCode typeCode) =>
 VM.Assert(type == VeinTypeCode.TYPE_ARRAY, WNE.TYPE_MISMATCH,
           $"stack type mismatch, current: '{type}', expected: '{typeCode}'. opcode: '{frame.last_ip}'", frame);
Пример #27
0
        public static RuntimeIshtarField GetField(uint index, RuntimeIshtarClass owner, VeinModule module, CallFrame frame)
        {
            var name  = module.GetFieldNameByIndex((int)index);
            var field = owner.FindField(name.Name);

            if (field is null)
            {
                FastFail(WNE.MISSING_FIELD, $"Field '{name}' not found in '{owner.FullName.NameWithNS}'", frame);
                ValidateLastError();
                return(null);
            }
            return(field);
        }
Пример #28
0
 public static IshtarObject *ToIshtarString(IshtarObject *obj, CallFrame frame) => obj->decodeClass().TypeCode switch
 {
Пример #29
0
 public static nint ToDotnetPointer(IshtarObject *obj, CallFrame frame)
 {
     FFI.StaticTypeOf(frame, &obj, TYPE_RAW);
     return((nint)obj->vtable);
 }
Пример #30
0
        private static void A_OP(stackval *sp, int a_t, uint *ip, CallFrame frame)
        {
            if (sp[-1].type != sp[0].type)
            {
                FastFail(WNE.TYPE_MISMATCH, $"Currently math operation for '{sp[-1].type}' and '{sp[0].type}' not supported.", frame);
                ValidateLastError();
                return;
            }

            if (sp->type == TYPE_I4) /*first check int32, most frequent type*/
            {
                act(ref sp[-1].data.i, ref sp[0].data.i, (ref int i1, ref int i2) =>
                {
                    switch (a_t)
                    {
                    case 0:
                        i1 += i2;
                        break;

                    case 1:
                        i1 -= i2;
                        break;

                    case 2:
                        i1 *= i2;
                        break;

                    case 3:
                        if (i2 == 0)
                        {
                            // TODO
                            FastFail(WNE.ACCESS_VIOLATION, $"YOUR JUST OPEN A BLACKHOLE!!! [DivideByZeroError]", frame);
                            ValidateLastError();
                        }
                        i1 /= i2;
                        break;

                    case 4:
                        i1 %= i2;
                        break;
                    }
                });
            }
            else if (sp->type == TYPE_I8)
            {
                act(ref sp[-1].data.l, ref sp[0].data.l, (ref long i1, ref long i2) =>
                {
                    switch (a_t)
                    {
                    case 0:
                        i1 += i2;
                        break;

                    case 1:
                        i1 -= i2;
                        break;

                    case 2:
                        i1 *= i2;
                        break;

                    case 3:
                        i1 /= i2;
                        break;

                    case 4:
                        i1 %= i2;
                        break;
                    }
                });
            }
            else if (sp->type == TYPE_I2)
            {
                act(ref sp[-1].data.s, ref sp[0].data.s, (ref short i1, ref short i2) =>
                {
                    switch (a_t)
                    {
                    case 0:
                        i1 += i2;
                        break;

                    case 1:
                        i1 -= i2;
                        break;

                    case 2:
                        i1 *= i2;
                        break;

                    case 3:
                        i1 /= i2;
                        break;

                    case 4:
                        i1 %= i2;
                        break;
                    }
                });
            }
            else if (sp->type == TYPE_I1)
            {
                act(ref sp[-1].data.b, ref sp[0].data.b, (ref sbyte i1, ref sbyte i2) =>
                {
                    switch (a_t)
                    {
                    case 0:
                        i1 += i2;
                        break;

                    case 1:
                        i1 -= i2;
                        break;

                    case 2:
                        i1 *= i2;
                        break;

                    case 3:
                        i1 /= i2;
                        break;

                    case 4:
                        i1 %= i2;
                        break;
                    }
                });
            }
            else if (sp->type == TYPE_U4)
            {
                act(ref sp[-1].data.ui, ref sp[0].data.ui, (ref uint i1, ref uint i2) =>
                {
                    switch (a_t)
                    {
                    case 0:
                        i1 += i2;
                        break;

                    case 1:
                        i1 -= i2;
                        break;

                    case 2:
                        i1 *= i2;
                        break;

                    case 3:
                        i1 /= i2;
                        break;

                    case 4:
                        i1 %= i2;
                        break;
                    }
                });
            }
            else if (sp->type == TYPE_U1)
            {
                act(ref sp[-1].data.ub, ref sp[0].data.ub, (ref byte i1, ref byte i2) =>
                {
                    switch (a_t)
                    {
                    case 0:
                        i1 += i2;
                        break;

                    case 1:
                        i1 -= i2;
                        break;

                    case 2:
                        i1 *= i2;
                        break;

                    case 3:
                        i1 /= i2;
                        break;

                    case 4:
                        i1 %= i2;
                        break;
                    }
                });
            }
            else if (sp->type == TYPE_U2)
            {
                act(ref sp[-1].data.us, ref sp[0].data.us, (ref ushort i1, ref ushort i2) =>
                {
                    switch (a_t)
                    {
                    case 0:
                        i1 += i2;
                        break;

                    case 1:
                        i1 -= i2;
                        break;

                    case 2:
                        i1 *= i2;
                        break;

                    case 3:
                        i1 /= i2;
                        break;

                    case 4:
                        i1 %= i2;
                        break;
                    }
                });
            }
            else if (sp->type == TYPE_U8)
            {
                act(ref sp[-1].data.ul, ref sp[0].data.ul, (ref ulong i1, ref ulong i2) =>
                {
                    switch (a_t)
                    {
                    case 0:
                        i1 += i2;
                        break;

                    case 1:
                        i1 -= i2;
                        break;

                    case 2:
                        i1 *= i2;
                        break;

                    case 3:
                        i1 /= i2;
                        break;

                    case 4:
                        i1 %= i2;
                        break;
                    }
                });
            }
            else if (sp->type == TYPE_R8)
            {
                act(ref sp[-1].data.f, ref sp[0].data.f, (ref double i1, ref double i2) =>
                {
                    switch (a_t)
                    {
                    case 0:
                        i1 += i2;
                        break;

                    case 1:
                        i1 -= i2;
                        break;

                    case 2:
                        i1 *= i2;
                        break;

                    case 3:
                        i1 /= i2;
                        break;

                    case 4:
                        i1 %= i2;
                        break;
                    }
                });
            }
            else if (sp->type == TYPE_R4)
            {
                act(ref sp[-1].data.f_r4, ref sp[0].data.f_r4, (ref float i1, ref float i2) =>
                {
                    switch (a_t)
                    {
                    case 0:
                        i1 += i2;
                        break;

                    case 1:
                        i1 -= i2;
                        break;

                    case 2:
                        i1 *= i2;
                        break;

                    case 3:
                        i1 /= i2;
                        break;

                    case 4:
                        i1 %= i2;
                        break;
                    }
                });
            }
            else if (sp->type == TYPE_R16)
            {
                act(ref sp[-1].data.d, ref sp[0].data.d, (ref decimal i1, ref decimal i2) =>
                {
                    switch (a_t)
                    {
                    case 0:
                        i1 += i2;
                        break;

                    case 1:
                        i1 -= i2;
                        break;

                    case 2:
                        i1 *= i2;
                        break;

                    case 3:
                        i1 /= i2;
                        break;

                    case 4:
                        i1 %= i2;
                        break;
                    }
                });
            }
            else if (sp[-1].type == TYPE_NONE)
            {
                FastFail(WNE.TYPE_MISMATCH, $"@{(OpCodeValue)(*(ip - 1))} 'sp[-1]' incorrect stack type: {sp[-1].type}",
                         frame);
            }
        }