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); }
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]); }
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]); }
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])); }
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]); }
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]); }
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(); }
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); }
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)); }
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); }
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)); }
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); }
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); }
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); }
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)); }
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); }
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); }
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); }
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)); }
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); } }
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)); }
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); } }
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)); }
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); }
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); }
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);
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); }
public static IshtarObject *ToIshtarString(IshtarObject *obj, CallFrame frame) => obj->decodeClass().TypeCode switch {
public static nint ToDotnetPointer(IshtarObject *obj, CallFrame frame) { FFI.StaticTypeOf(frame, &obj, TYPE_RAW); return((nint)obj->vtable); }
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); } }