Beispiel #1
0
        public void CopyIsACopy()
        {
            var stack = new StackValue();

            var zedObject = new object();
            InvokeDelegate(stack, "PUSH", zedObject);
            var firstObject = new object();
            InvokeDelegate(stack, "PUSH", firstObject);
            var secondObject = new object();
            InvokeDelegate(stack, "PUSH", secondObject);
            var thirdObject = "third";
            InvokeDelegate(stack, "PUSH", thirdObject);

            var length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(4,length);

            var copy = InvokeDelegate(stack, "COPY") as StackValue;
            Assert.AreNotSame(stack, copy);

            var copyLength = InvokeDelegate(copy, "LENGTH");
            Assert.AreEqual(4,copyLength);

            object popped = InvokeDelegate(copy, "POP");
            Assert.AreEqual(thirdObject, popped);

            InvokeDelegate(copy, "CLEAR");

            copyLength = InvokeDelegate(copy, "LENGTH");
            Assert.AreEqual(0,copyLength);

            length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(4,length);
        }
        public static StackValue Repack(Obj obj, ProtoCore.DSASM.Heap heap)
        {
            if (obj.Type.IsIndexable)
            {
                //Unpack each of the elements
                DsasmArray arr = (DsasmArray)obj.Payload;

                StackValue[] sv = new StackValue[arr.members.Length];

                //recurse over the array
                for (int i = 0; i < sv.Length; i++)
                    sv[i] = Repack(arr.members[i], heap);

                int size = sv.Length;

                lock (heap.cslock)
                {
                    int ptr = heap.Allocate(size);
                    ++heap.Heaplist[ptr].Refcount;
                    for (int n = size - 1; n >= 0; --n)
                    {
                        heap.Heaplist[ptr].Stack[n] = sv[n];
                    }

                    StackValue overallSv = StackUtils.BuildArrayPointer(ptr);

                    return overallSv;
                }
            }

            // For non-arrays, there is nothing to repack so just return the original stackvalue
            return obj.DsasmValue;
        }
Beispiel #3
0
        public void CanClear()
        {
            var stack = new StackValue();

            InvokeDelegate(stack, "PUSH", new ScalarIntValue(1));
            InvokeDelegate(stack, "PUSH", new ScalarIntValue(2));

            var length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(new ScalarIntValue(2),length);
            InvokeDelegate(stack, "CLEAR");
            length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(new ScalarIntValue(0),length);
        }
Beispiel #4
0
        public void CanClear()
        {
            var stack = new StackValue();

            InvokeDelegate(stack, "PUSH", 1);
            InvokeDelegate(stack, "PUSH", new object());

            var length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(2,length);
            InvokeDelegate(stack, "CLEAR");
            length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(0,length);
        }
Beispiel #5
0
        public StackValueDeref(StackValue pointer)
        {
            ValueType = StackValueType.Unknown;
            ProcessedValue = false;

            if (pointer is StackValuePointerBase)
            {
                Pointer = pointer as StackValuePointerBase;
            }
            else
            {
                UnknownPointer = pointer;
            }
        }
Beispiel #6
0
        public void CanSerializeStacks()
        {
            var stack = new StackValue();
            var nested = new StackValue();

            stack.Push(new StringValue("item1"));
            stack.Push(new ScalarIntValue(2));
            stack.Push(nested);

            nested.Push(new StringValue("nested1"));

            StackValue deserialized = Deserialize(Serialize(stack)) as StackValue;

            Assert.AreEqual(new StringValue("nested1"), (deserialized.Pop() as StackValue).Pop());
            Assert.AreEqual(new ScalarIntValue(2), deserialized.Pop());
            Assert.AreEqual(new StringValue("item1"), deserialized.Pop());
        }
Beispiel #7
0
        public void CanTestContains()
        {
            var stack = new StackValue();

            var zedObject = new StringValue("abc");
            InvokeDelegate(stack, "PUSH", zedObject);
            var firstObject = ScalarIntValue.One;
            InvokeDelegate(stack, "PUSH", firstObject);
            var secondObject = ScalarIntValue.Two;
            var thirdObject = new ScalarIntValue(4);

            var length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(ScalarIntValue.Two, length);

            Assert.IsTrue((BooleanValue)InvokeDelegate(stack, "CONTAINS", zedObject));
            Assert.IsTrue((BooleanValue)InvokeDelegate(stack, "CONTAINS", firstObject));
            Assert.IsFalse((BooleanValue)InvokeDelegate(stack, "CONTAINS", secondObject));
            Assert.IsFalse((BooleanValue)InvokeDelegate(stack, "CONTAINS", thirdObject));
        }
Beispiel #8
0
        public void CanPushPopItem()
        {
            var stack = new StackValue();
            Assert.IsNotNull(stack);
            var length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(0,length);

            InvokeDelegate(stack, "PUSH", "value1");
            InvokeDelegate(stack, "PUSH", "value2");

            length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(2,length);

            object popped = InvokeDelegate(stack, "POP");
            Assert.AreEqual("value2", popped);

            popped = InvokeDelegate(stack, "POP");
            Assert.AreEqual("value1", popped);

            length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(0, length);
        }
Beispiel #9
0
        public void CanPushPopItem()
        {
            var stack = new StackValue();
            Assert.IsNotNull(stack);
            var length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(new ScalarIntValue(0), length);

            InvokeDelegate(stack, "PUSH", new StringValue("value1"));
            InvokeDelegate(stack, "PUSH", new StringValue("value2"));

            length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(ScalarIntValue.Two, length);

            object popped = InvokeDelegate(stack, "POP");
            Assert.AreEqual(new StringValue("value2"), popped);

            popped = InvokeDelegate(stack, "POP");
            Assert.AreEqual(new StringValue("value1"), popped);

            length = InvokeDelegate(stack, "LENGTH");
            Assert.AreEqual(ScalarIntValue.Zero, length);
        }
Beispiel #10
0
        public string GetClassTrace(StackValue val, Heap heap, int langblock, bool forPrint)
        {
            if (!formatParams.ContinueOutputTrace())
                return "...";

            RuntimeMemory rmem = MirrorTarget.rmem;
            Executable exe = MirrorTarget.exe;
            ClassTable classTable = MirrorTarget.RuntimeCore.DSExecutable.classTable;

            int classtype = val.metaData.type;
            if (classtype < 0 || (classtype >= classTable.ClassNodes.Count))
            {
                formatParams.RestoreOutputTraceDepth();
                return string.Empty;
            }

            ClassNode classnode = classTable.ClassNodes[classtype];
            if (classnode.IsImportedClass)
            {
                var helper = DLLFFIHandler.GetModuleHelper(FFILanguage.CSharp);
                var marshaller = helper.GetMarshaller(runtimeCore);
                var strRep = marshaller.GetStringValue(val);
                formatParams.RestoreOutputTraceDepth();
                return strRep;
            }
            else
            {
                var obj = heap.ToHeapObject<DSObject>(val);

                List<string> visibleProperties = null;
                if (null != propertyFilter)
                {
                    if (!propertyFilter.TryGetValue(classnode.Name, out visibleProperties))
                        visibleProperties = null;
                }

                StringBuilder classtrace = new StringBuilder();
                if (classnode.Symbols != null && classnode.Symbols.symbolList.Count > 0)
                {
                    bool firstPropertyDisplayed = false;
                    for (int n = 0; n < obj.Count; ++n)
                    {
                        SymbolNode symbol = classnode.Symbols.symbolList[n];
                        string propName = symbol.name;

                        if ((null != visibleProperties) && visibleProperties.Contains(propName) == false)
                            continue; // This property is not to be displayed.

                        if (firstPropertyDisplayed)
                            classtrace.Append(", ");

                        string propValue = "";
                        if (symbol.isStatic)
                        {
                            var staticSymbol = exe.runtimeSymbols[langblock].symbolList[symbol.symbolTableIndex];
                            StackValue staticProp = rmem.GetSymbolValue(staticSymbol);
                            propValue = GetStringValue(staticProp, heap, langblock, forPrint);
                        }
                        else
                        {
                            propValue = GetStringValue(obj.GetValueFromIndex(symbol.index, runtimeCore), heap, langblock, forPrint);
                        }
                        classtrace.Append(string.Format("{0} = {1}", propName, propValue));
                        firstPropertyDisplayed = true;
                    }
                }
                else
                {
                    var stringValues = obj.Values.Select(x => GetStringValue(x, heap, langblock, forPrint))
                                                      .ToList();

                    for (int n = 0; n < stringValues.Count(); ++n)
                    {
                        if (0 != n)
                            classtrace.Append(", ");

                        classtrace.Append(stringValues[n]);
                    }
                }

                formatParams.RestoreOutputTraceDepth();
                if (classtype >= (int)ProtoCore.PrimitiveType.MaxPrimitive)
                    if (forPrint)
                        return (string.Format("{0}{{{1}}}", classnode.Name, classtrace.ToString()));
                    else
                    {
                        string tempstr =  (string.Format("{0}({1})", classnode.Name, classtrace.ToString()));
                        return tempstr;
                    }

                return classtrace.ToString();
            }
        }
Beispiel #11
0
        /// <summary>
        /// array[index1][index2][...][indexN] = value, and
        /// indices = {index1, index2, ..., indexN}
        /// </summary>
        /// <param name="array"></param>
        /// <param name="indices"></param>
        /// <param name="value"></param>
        /// <param name="t"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue SetValueForIndices(StackValue array, List <StackValue> indices, StackValue value, Type t, Core core)
        {
            StackValue[][] zippedIndices = ArrayUtils.GetZippedIndices(indices, core);
            if (zippedIndices == null || zippedIndices.Length == 0)
            {
                return(StackValue.Null);
            }

            if (zippedIndices.Length == 1)
            {
                StackValue coercedData = TypeSystem.Coerce(value, t, core);
                GCUtils.GCRetain(coercedData, core);
                return(ArrayUtils.SetValueForIndices(array, zippedIndices[0], coercedData, core));
            }

            if (t.rank > 0)
            {
                t.rank = t.rank - 1;
            }

            if (value.optype == AddressType.ArrayPointer)
            {
                // Replication happens on both side.
                HeapElement dataHeapElement = GetHeapElement(value, core);
                int         length          = Math.Min(zippedIndices.Length, dataHeapElement.VisibleSize);

                StackValue[] oldValues = new StackValue[length];
                for (int i = 0; i < length; ++i)
                {
                    StackValue coercedData = TypeSystem.Coerce(dataHeapElement.Stack[i], t, core);
                    GCUtils.GCRetain(coercedData, core);
                    oldValues[i] = SetValueForIndices(array, zippedIndices[i], coercedData, core);
                }

                // The returned old values shouldn't have any key-value pairs
                return(HeapUtils.StoreArray(oldValues, null, core));
            }
            else
            {
                // Replication is only on the LHS, so collect all old values
                // and return them in an array.
                StackValue coercedData = TypeSystem.Coerce(value, t, core);
                GCUtils.GCRetain(coercedData, core);

                StackValue[] oldValues = new StackValue[zippedIndices.Length];
                for (int i = 0; i < zippedIndices.Length; ++i)
                {
                    oldValues[i] = SetValueForIndices(array, zippedIndices[i], coercedData, core);
                }

                // The returned old values shouldn't have any key-value pairs
                return(HeapUtils.StoreArray(oldValues, null, core));
            }
        }
Beispiel #12
0
        /// <summary>
        /// array[index] = value. Here index can be any type.
        ///
        /// Note this function doesn't support the replication of array indexing.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="index"></param>
        /// <param name="value"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue SetValueForIndex(StackValue array, StackValue index, StackValue value, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));

            if (StackUtils.IsNumeric(index))
            {
                index = index.AsInt();
                return(SetValueForIndex(array, (int)index.opdata, value, core));
            }
            else
            {
                HeapElement he = GetHeapElement(array, core);
                if (he.Dict == null)
                {
                    he.Dict = new Dictionary <StackValue, StackValue>(new StackValueComparer(core));
                }

                StackValue oldValue;
                if (!he.Dict.TryGetValue(index, out oldValue))
                {
                    oldValue = StackValue.Null;
                }

                GCUtils.GCRetain(index, core);
                GCUtils.GCRetain(value, core);
                he.Dict[index] = value;

                return(oldValue);
            }
        }
Beispiel #13
0
 public static int GetMaxRankForArray(StackValue array, Core core)
 {
     return(GetMaxRankForArray(array, core, 0));
 }
Beispiel #14
0
        public string GetFirstNameFromValue(StackValue v)
        {
            if (v.optype != AddressType.Pointer)
                throw new ArgumentException("SV to highlight must be a pointer");

            ProtoCore.DSASM.Executable exe = MirrorTarget.rmem.Executable;

            List<SymbolNode> symNodes = new List<SymbolNode>();

            foreach (SymbolTable symTable in exe.runtimeSymbols)
            {
                foreach (SymbolNode symNode in symTable.symbolList.Values)
                {
                    symNodes.Add(symNode);
                }

            }

            int index = MirrorTarget.rmem.Stack.FindIndex(0, value => value.opdata == v.opdata);

            List<SymbolNode> matchingNodes = symNodes.FindAll(value => value.index == index);

            if (matchingNodes.Count > 0)
                return matchingNodes[0].name;
            else
            {
                return null;
            }
        }
Beispiel #15
0
        //@TODO(Luke): Add in the methods here that correspond to each of the internal datastructures in use by the executive
        //@TODO(Jun): if this method stays static, then the Heap needs to be referenced from a parameter
        /// <summary>
        /// Do the recursive unpacking of the data structure into mirror objects
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static Obj Unpack(StackValue val, Heap heap, Core core, int type = (int)PrimitiveType.kTypePointer)
        {
            switch (val.optype)
            {
                case AddressType.ArrayPointer:
                case AddressType.String:
                    {
                        //It was a pointer that we pulled, so the value lives on the heap
                        Int64 ptr = val.opdata;

                        DsasmArray ret = new DsasmArray();

                        //Pull the item out of the heap

                        HeapElement hs = heap.Heaplist[(int)ptr];

                        StackValue[] nodes = hs.Stack;
                        ret.members = new Obj[hs.VisibleSize];

                        for (int i = 0; i < ret.members.Length; i++)
                        {
                            ret.members[i] = Unpack(nodes[i], heap, core, type);
                        }

                        // TODO Jun: ret.members[0] is hardcoded  and means we are assuming a homogenous collection
                        // How to handle mixed-type arrays?
                        Obj retO = new Obj(val) { Payload = ret, Type = core.TypeSystem.BuildTypeObject((ret.members.Length > 0) ? core.TypeSystem.GetType(ret.members[0].Type.Name) : (int)ProtoCore.PrimitiveType.kTypeVoid, true) };

                        return retO;
                    }
                case AddressType.Int:
                    {
                        Int64 data = val.opdata;
                        Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeInt, false) };
                        return o;
                    }
                case AddressType.Boolean:
                    {
                        Int64 data = val.opdata;
                        Obj o = new Obj(val) { Payload = (data != 0), Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeBool, false) };
                        return o;
                    }

                case AddressType.Null:
                    {
                        Int64 data = val.opdata;
                        Obj o = new Obj(val) { Payload = null, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeNull, false) };
                        return o;
                    }
                case AddressType.Char:
                    {
                        Int64 data = val.opdata;
                        Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeChar, false) };
                        return o;
                    }
                case AddressType.Double:
                    {
                        double data = val.opdata_d;
                        Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeDouble, false) };
                        return o;
                    }
                case AddressType.Pointer:
                    {
                        Int64 data = val.opdata;
                        Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(type, false) };
                        return o;
                    }
                case AddressType.FunctionPointer:
                    {
                        Int64 data = val.opdata;
                        Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeFunctionPointer, false) };
                        return o;
                    }
                case AddressType.Invalid:
                    {
                        return new Obj(val) {Payload = null};
                    }
                default:
                    {
                        throw new NotImplementedException(string.Format("unknown datatype {0}", val.optype.ToString()));
                    }
            }
        }
Beispiel #16
0
        /// <summary>
        /// Compiles the given method definition.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <param name="function">The function.</param>
        /// <exception cref="System.NotSupportedException"></exception>
        /// <exception cref="System.NotImplementedException"></exception>
        /// <exception cref="System.InvalidOperationException">Backward jump with a non-empty stack unknown target.</exception>
        private void CompileFunction(MethodReference methodReference, Function function)
        {
            var method = methodReference.Resolve();

            var body = method.Body;
            var codeSize = body != null ? body.CodeSize : 0;
            var functionGlobal = function.GeneratedValue;

            var functionContext = new FunctionCompilerContext(function);
            functionContext.BasicBlock = LLVM.AppendBasicBlockInContext(context, functionGlobal, string.Empty);
            LLVM.PositionBuilderAtEnd(builder, functionContext.BasicBlock);

            if (body == null && (method.ImplAttributes & MethodImplAttributes.Runtime) != 0)
            {
                var declaringClass = GetClass(function.DeclaringType);

                // Generate IL for various methods
                if (declaringClass.BaseType != null &&
                    declaringClass.BaseType.Type.TypeReference.FullName == typeof(MulticastDelegate).FullName)
                {
                    body = GenerateDelegateMethod(method, declaringClass);
                    if (body == null)
                        return;

                    codeSize = UpdateOffsets(body);
                }
            }

            if (body == null)
                return;

            var numParams = method.Parameters.Count;

            // Create stack, locals and args
            var stack = new List<StackValue>(body.MaxStackSize);
            var locals = new List<StackValue>(body.Variables.Count);
            var args = new List<StackValue>(numParams);
            var exceptionHandlers = new List<ExceptionHandlerInfo>();
            var activeTryHandlers = new List<ExceptionHandlerInfo>();

            functionContext.Stack = stack;
            functionContext.Locals = locals;
            functionContext.Arguments = args;
            functionContext.ExceptionHandlers = exceptionHandlers;
            functionContext.ActiveTryHandlers = activeTryHandlers;

            // Process locals
            foreach (var local in body.Variables)
            {
                // TODO: Anything to do on pinned objects?
                //if (local.IsPinned)
                //    throw new NotSupportedException();

                var type = CreateType(ResolveGenericsVisitor.Process(methodReference, local.VariableType));
                locals.Add(new StackValue(type.StackType, type, LLVM.BuildAlloca(builder, type.DefaultType, local.Name)));
            }

            // Process args
            for (int index = 0; index < function.ParameterTypes.Length; index++)
            {
                var argType = function.ParameterTypes[index];
                var arg = LLVM.GetParam(functionGlobal, (uint)index);

                // Copy argument on stack
                var storage = LLVM.BuildAlloca(builder, argType.DefaultType, "arg" + index.ToString());
                LLVM.BuildStore(builder, arg, storage);

                args.Add(new StackValue(argType.StackType, argType, storage));
            }

            // Some wasted space due to unused offsets, but we only keep one so it should be fine.
            // TODO: Reuse same allocated instance per thread, and grow it only if necessary
            var branchTargets = new bool[codeSize];
            var basicBlocks = new BasicBlockRef[codeSize];
            var forwardStacks = new StackValue[codeSize][];

            functionContext.BasicBlocks = basicBlocks;
            functionContext.ForwardStacks = forwardStacks;

            // Find branch targets (which will require PHI node for stack merging)
            for (int index = 0; index < body.Instructions.Count; index++)
            {
                var instruction = body.Instructions[index];

                var flowControl = instruction.OpCode.FlowControl;

                // Process branch targets
                if (flowControl == FlowControl.Cond_Branch
                    || flowControl == FlowControl.Branch)
                {
                    var targets = instruction.Operand is Instruction[] ? (Instruction[])instruction.Operand : new[] { (Instruction)instruction.Operand };

                    foreach (var target in targets)
                    {
                        // Operand Target can be reached
                        branchTargets[target.Offset] = true;
                    }
                }

                // Need to enforce a block to be created for the next instruction after a conditional branch
                // TODO: Break?
                if (flowControl == FlowControl.Cond_Branch)
                {
                    if (instruction.Next != null)
                        branchTargets[instruction.Next.Offset] = true;
                }
            }

            // Setup exception handling
            if (body.HasExceptionHandlers)
            {
                // Add an "ehselector.slot" i32 local, and a "exn.slot" Object reference local
                functionContext.ExceptionHandlerSelectorSlot = LLVM.BuildAlloca(builder, int32Type, "ehselector.slot");
                functionContext.ExceptionSlot = LLVM.BuildAlloca(builder, @object.DefaultType, "exn.slot");
                functionContext.EndfinallyJumpTarget = LLVM.BuildAlloca(builder, int32Type, "endfinally.jumptarget");

                // Create resume exception block
                functionContext.ResumeExceptionBlock = LLVM.AppendBasicBlockInContext(context, functionGlobal, "eh.resume");
                LLVM.PositionBuilderAtEnd(builder2, functionContext.ResumeExceptionBlock);
                var exceptionObject = LLVM.BuildLoad(builder2, functionContext.ExceptionSlot, "exn");
                var ehselectorValue = LLVM.BuildLoad(builder2, functionContext.ExceptionHandlerSelectorSlot, "sel");

                exceptionObject = LLVM.BuildPointerCast(builder2, exceptionObject, intPtrType, "exn");
                var landingPadValue = LLVM.BuildInsertValue(builder2, LLVM.GetUndef(caughtResultType), exceptionObject, 0, "lpad.val");
                landingPadValue = LLVM.BuildInsertValue(builder2, landingPadValue, ehselectorValue, 1, "lpad.val");

                LLVM.BuildResume(builder2, landingPadValue);

                // Exception handlers blocks are also branch targets
                foreach (var exceptionHandler in body.ExceptionHandlers)
                {
                    branchTargets[exceptionHandler.HandlerStart.Offset] = true;
                }
            }

            // Create basic block
            // TODO: Could be done during previous pass
            for (int offset = 0; offset < branchTargets.Length; offset++)
            {
                // Create a basic block if this was a branch target or an instruction after a conditional branch
                if (branchTargets[offset])
                {
                    basicBlocks[offset] = LLVM.AppendBasicBlockInContext(context, functionGlobal, string.Format("L_{0:x4}", offset));
                }
            }

            // Create catch clause stack
            if (body.HasExceptionHandlers)
            {
                // Exception handlers blocks are also branch targets
                foreach (var exceptionHandler in body.ExceptionHandlers)
                {
                    exceptionHandlers.Add(new ExceptionHandlerInfo(exceptionHandler));

                    if (exceptionHandler.HandlerType != ExceptionHandlerType.Catch)
                        continue;

                    var handlerStart = exceptionHandler.HandlerStart.Offset;

                    var catchBlock = basicBlocks[handlerStart];
                    var catchClass = GetClass(ResolveGenericsVisitor.Process(methodReference, exceptionHandler.CatchType));

                    // Extract exception
                    LLVM.PositionBuilderAtEnd(builder2, catchBlock);
                    var exceptionObject = LLVM.BuildLoad(builder2, functionContext.ExceptionSlot, string.Empty);
                    exceptionObject = LLVM.BuildPointerCast(builder2, exceptionObject, catchClass.Type.DefaultType, string.Empty);

                    // Erase exception from exn.slot (it has been handled)
                    LLVM.BuildStore(builder2, LLVM.ConstNull(@object.DefaultType), functionContext.ExceptionSlot);
                    LLVM.BuildStore(builder2, LLVM.ConstInt(int32Type, 0, false), functionContext.ExceptionHandlerSelectorSlot);
                     
                    forwardStacks[handlerStart] = new[]
                    {
                        new StackValue(catchClass.Type.StackType, catchClass.Type, exceptionObject)
                    };
                }
            }

            foreach (var instruction in body.Instructions)
            {
                try
                {
                    // Check if any exception handlers might have changed
                    if (body.HasExceptionHandlers)
                        UpdateExceptionHandlers(functionContext, instruction);

                    if (branchTargets[instruction.Offset])
                        UpdateBranching(functionContext, instruction);

                    // Reset states
                    functionContext.FlowingNextInstructionMode = FlowingNextInstructionMode.Implicit;

                    EmitInstruction(functionContext, instruction);

                    // If we do a jump, let's merge stack
                    var flowControl = instruction.OpCode.FlowControl;
                    if (flowControl == FlowControl.Cond_Branch
                        || flowControl == FlowControl.Branch)
                        MergeStacks(functionContext, instruction);
                }
                catch (Exception e)
                {
                    throw new InvalidOperationException(string.Format("Error while processing instruction {0} of method {1}", instruction, methodReference), e);
                }
            }
        }
 public static int GetMaxRankForArray(StackValue array, RuntimeCore runtimeCore)
 {
     return(GetMaxRankForArray(array, runtimeCore, 0));
 }
Beispiel #18
0
 public ArgumentAtLevel(StackValue argument, List <List <int> > indices, bool isDominant)
 {
     Indices    = indices;
     IsDominant = isDominant;
     Argument   = argument;
 }
Beispiel #19
0
 public ArgumentAtLevel(StackValue argument)
 {
     Indices    = new List <List <int> >();
     IsDominant = false;
     Argument   = argument;
 }
Beispiel #20
0
 public ElementAtLevel(StackValue element, List <int> indices)
 {
     Indices = indices;
     Element = element;
 }
Beispiel #21
0
        /// <summary>
        /// If an input is a dominant list, restructure the result based on the
        /// structure of dominant list.
        ///
        /// Note the dominant structure will be restored only if the dominant
        /// list is zipped with other arguments, or the replication is applied
        /// to the dominant list firstly.
        /// </summary>
        /// <param name="ret"></param>
        /// <param name="domStructure"></param>
        /// <param name="instructions"></param>
        /// <param name="runtimeCore"></param>
        /// <returns></returns>
        public static StackValue RestoreDominantStructure(
            StackValue ret,
            DominantListStructure domStructure,
            List <ReplicationInstruction> instructions,
            RuntimeCore runtimeCore)
        {
            if (domStructure == null)
            {
                return(ret);
            }

            var domListIndex = domStructure.ArgumentIndex;
            var indicesList  = domStructure.Indices;

            // If there is replication on the dominant list, it should be the
            // topest replicaiton.
            if (instructions != null && instructions.Any())
            {
                var firstInstruciton = instructions.First();
                if (firstInstruciton.Zipped)
                {
                    if (!firstInstruciton.ZipIndecies.Contains(domListIndex))
                    {
                        return(ret);
                    }
                }
                else
                {
                    if (firstInstruciton.CartesianIndex != domListIndex)
                    {
                        return(ret);
                    }
                }
            }

            // Allocate an empty array to hold the value
            StackValue newRet;

            try
            {
                newRet = runtimeCore.RuntimeMemory.Heap.AllocateArray(new StackValue[] { });
            }
            catch (RunOutOfMemoryException)
            {
                runtimeCore.RuntimeStatus.LogWarning(Runtime.WarningID.RunOutOfMemory, Resources.RunOutOfMemory);
                return(StackValue.Null);
            }
            var array = runtimeCore.Heap.ToHeapObject <DSArray>(newRet);

            // Write the result back
            var values           = ret.IsArray ? runtimeCore.Heap.ToHeapObject <DSArray>(ret).Values : Enumerable.Repeat(ret, 1);
            var valueIndicePairs = values.Zip(indicesList, (val, idx) => new { Value = val, Indices = idx });

            foreach (var item in valueIndicePairs)
            {
                var value   = item.Value;
                var indices = item.Indices.Select(x => StackValue.BuildInt(x)).ToArray();
                array.SetValueForIndices(indices, value, runtimeCore);
            }

            return(newRet);
        }
Beispiel #22
0
 public ElementAtLevel(StackValue element)
 {
     Indices = new List <int>();
     Element = element;
 }
        ///// <summary>
        ///// Get the maximum depth to which an object can be reduced
        ///// </summary>
        ///// <param name="obj"></param>
        ///// <returns></returns>
        //[Obsolete]
        //public static int GetMaxReductionDepth(ProtoCore.Lang.Obj obj)
        //{
        //    if (!obj.Type.IsIndexable)
        //        return 0;
        //    else
        //    {
        //        return 1 + GetMaxReductionDepth((Obj)((DSASM.Mirror.DsasmArray)obj.Payload).members[0]);
        //    }
        //}

        /// <summary>
        /// Get the maximum depth to which an element can be reduced
        /// This will include cases where only partial reduction can be performed on jagged arrays
        /// </summary>
        /// <param name="sv"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static int GetMaxReductionDepth(StackValue sv, Core core)
        {
            return(RecursiveProtectGetMaxReductionDepth(sv, core, 0));
        }
Beispiel #24
0
        private string GetArrayTrace(StackValue svArray, Heap heap, int langblock, HashSet<int> pointers, bool forPrint)
        {
            if (!formatParams.ContinueOutputTrace())
                return "...";

            StringBuilder arrayElements = new StringBuilder();
            var array = heap.ToHeapObject<DSArray>(svArray);

            int halfArraySize = -1;
            if (formatParams.MaxArraySize > 0) // If the caller did specify a max value...
            {
                // And our array is larger than that max value...
                if (array.Count > formatParams.MaxArraySize)
                    halfArraySize = (int)Math.Floor(formatParams.MaxArraySize * 0.5);
            }

            int totalElementCount = array.Count; 
            if (svArray.IsArray)
            {
                totalElementCount = heap.ToHeapObject<DSArray>(svArray).Values.Count();
            }

            for (int n = 0; n < array.Count; ++n)
            {
                // As we try to output the next element in the array, there 
                // should be a comma if there were previously output element.
                if (arrayElements.Length > 0)
                    if(forPrint)
                        arrayElements.Append(",");
                    else
                        arrayElements.Append(", ");

                StackValue sv = array.GetValueFromIndex(n, runtimeCore);
                if (sv.IsArray)
                {
                    arrayElements.Append(GetPointerTrace(sv, heap, langblock, pointers, forPrint));
                }
                else
                {
                    arrayElements.Append(GetStringValue(array.GetValueFromIndex(n, runtimeCore), heap, langblock, forPrint));
                }

                // If we need to truncate this array (halfArraySize > 0), and we have 
                // already reached the first half of it, then offset the loop counter 
                // to the next half of the array.
                if (halfArraySize > 0 && (n == halfArraySize - 1))
                {
                    arrayElements.Append(", ...");
                    n = totalElementCount - halfArraySize - 1;
                }
            }

            formatParams.RestoreOutputTraceDepth();
            return arrayElements.ToString();
        }
Beispiel #25
0
        //@TODO(Luke): Add in the methods here that correspond to each of the internal datastructures in use by the executive
        //@TODO(Jun): if this method stays static, then the Heap needs to be referenced from a parameter
        /// <summary>
        /// Do the recursive unpacking of the data structure into mirror objects
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static Obj Unpack(StackValue val, Heap heap, RuntimeCore runtimeCore, int type = (int)PrimitiveType.Pointer) 
        {
            Executable exe = runtimeCore.DSExecutable;
            switch (val.optype)
            {
                case AddressType.ArrayPointer:
                    {
                        DsasmArray ret = new DsasmArray();

                        //Pull the item out of the heap


                        var array = heap.ToHeapObject<DSArray>(val);

                        StackValue[] nodes = array.Values.ToArray();
                        ret.members = new Obj[array.Count];
                        for (int i = 0; i < ret.members.Length; i++)
                        {
                            ret.members[i] = Unpack(nodes[i], heap, runtimeCore, type);
                        }

                        // TODO Jun: ret.members[0] is hardcoded  and means we are assuming a homogenous collection
                        // How to handle mixed-type arrays?
                        Obj retO = new Obj(val) 
                        { 
                            Payload = ret, 
                        };

                        return retO;
                    }
                case AddressType.String:
                    {
                        string str = heap.ToHeapObject<DSString>(val).Value;
                        Obj o = new Obj(val)
                        {
                            Payload = str,
                        };
                        return o;
                    }
                case AddressType.Int:
                    {
                        Obj o = new Obj(val) 
                        { 
                            Payload = val.IntegerValue, 
                        };
                        return o;
                    }
                case AddressType.Boolean:
                    {
                        Obj o = new Obj(val)
                        {
                            Payload = val.BooleanValue,
                        };
                        return o;
                    }

                case AddressType.Null:
                    {
                        Obj o = new Obj(val) 
                        { 
                            Payload = null, 
                        };
                        return o;
                    }
                case AddressType.Char:
                    {
                        Obj o = new Obj(val) 
                        {
                            Payload = val.CharValue, 
                        };
                        return o;
                    }
                case AddressType.Double:
                    {
                        Obj o = new Obj(val) 
                        { 
                            Payload = val.DoubleValue,
                        };
                        return o;
                    }
                case AddressType.Pointer:
                    {
                        Obj o = new Obj(val) 
                        { 
                            Payload = val.Pointer,
                        };
                        return o;
                    }
                case AddressType.FunctionPointer:
                    {
                        Obj o = new Obj(val) 
                        { 
                            Payload = val.FunctionPointer, 
                        };
                        return o;
                    }
                case AddressType.Invalid:
                    {
                        return new Obj(val) {Payload = null};
                    }
                default:
                    {
                        throw new NotImplementedException(string.Format("unknown datatype {0}", val.optype.ToString()));
                    }
            }

        }
        /// <summary>
        /// For an array we supporting zipped replicaiton for array indexing as
        /// well. I.e., for the following expression:
        ///
        ///     a[1..3][2..4] = x;
        ///
        /// It will be expanded to
        ///
        ///     a[1][2] = x;
        ///     a[2][3] = x;
        ///     a[3][4] = x;
        ///
        /// So here we need to calculate zipped indices. The length of returned
        /// indices is decided by the shortest length of index that used in
        /// array indexing. E.g.,
        ///
        /// For array indexing
        ///
        ///     [{1, 2, 3}][{"x", "y"}][{6, 7, 8}], i.e.,
        ///
        ///     1 -> "x" -> 6
        ///     2 -> "y" -> 7
        ///     3 ->     -> 8
        ///
        /// The shortest length of index is 2 ({"x", "y"}), so function will
        /// returns:
        ///
        ///     {{1, "x", 6}, {2, "y", 7}}
        ///
        /// </summary>
        /// <param name="indices"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue[][] GetZippedIndices(List <StackValue> indices, RuntimeCore runtimeCore)
        {
            List <StackValue[]> allFlattenValues = new List <StackValue[]>();

            int zipLength = Int32.MaxValue;

            foreach (var index in indices)
            {
                int length = 1;
                if (index.IsArray)
                {
                    StackValue[] flattenValues = GetFlattenValue(index, runtimeCore);
                    allFlattenValues.Add(flattenValues);
                    length = flattenValues.Count();
                }
                else
                {
                    allFlattenValues.Add(null);
                }

                if (zipLength > length)
                {
                    zipLength = length;
                }
            }

            if (zipLength == 0)
            {
                return(null);
            }
            else
            {
                int            dims          = indices.Count;
                StackValue[][] zippedIndices = new StackValue[zipLength][];
                for (int i = 0; i < zipLength; ++i)
                {
                    zippedIndices[i] = new StackValue[dims];
                }

                for (int i = 0; i < dims; ++i)
                {
                    StackValue   index  = indices[i];
                    StackValue[] values = null;
                    if (index.IsArray)
                    {
                        values = allFlattenValues[i];
                    }

                    if (1 == zipLength)
                    {
                        if (index.IsArray)
                        {
                            zippedIndices[0][i] = values[0];
                        }
                        else
                        {
                            zippedIndices[0][i] = index;
                        }
                    }
                    else
                    {
                        for (int j = 0; j < zipLength; ++j)
                        {
                            zippedIndices[j][i] = values[j];
                        }
                    }
                }

                return(zippedIndices);
            }
        }
Beispiel #27
0
        private ValueRef BoxValueType(Class @class, StackValue valueType)
        {
            // Allocate object
            var allocatedObject = AllocateObject(@class.Type, StackValueType.Object);

            var dataPointer = GetDataPointer(allocatedObject);

            // Convert to local type
            var value = ConvertFromStackToLocal(@class.Type, valueType);

            // Copy data
            LLVM.BuildStore(builder, value, dataPointer);
            return allocatedObject;
        }
Beispiel #28
0
 /// <summary>
 /// UnMarshales a given DS object to FFI object of given System.Type
 /// </summary>
 /// <param name="dsObject">The DS object</param>
 /// <param name="context">DS execution context</param>
 /// <param name="dsi">The current runtime interpreter</param>
 /// <param name="type">Type of FFI object expected</param>
 /// <returns>Unmarshaled FFI object</returns>
 public abstract object UnMarshal(StackValue dsObject, ProtoCore.Runtime.Context context, Interpreter dsi, System.Type type);
Beispiel #29
0
        public string GetClassTrace(StackValue val, Heap heap, int langblock, bool forPrint)
        {
            if (!formatParams.ContinueOutputTrace())
                return "...";

            ClassTable classTable = MirrorTarget.rmem.Executable.classTable;

            int classtype = (int)val.metaData.type;
            if (classtype < 0 || (classtype >= classTable.ClassNodes.Count))
            {
                formatParams.RestoreOutputTraceDepth();
                return string.Empty;
            }

            ClassNode classnode = classTable.ClassNodes[classtype];
            if (classnode.IsImportedClass)
            {
                var helper = DLLFFIHandler.GetModuleHelper(FFILanguage.CSharp);
                var marshaller = helper.GetMarshaller(core);
                var strRep = marshaller.GetStringValue(val);
                formatParams.RestoreOutputTraceDepth();
                return strRep;
            }
            else
            {
                int ptr = (int)val.opdata;
                HeapElement hs = heap.Heaplist[ptr];

                List<string> visibleProperties = null;
                if (null != propertyFilter)
                {
                    if (!propertyFilter.TryGetValue(classnode.name, out visibleProperties))
                        visibleProperties = null;
                }

                StringBuilder classtrace = new StringBuilder();
                if (classnode.symbols != null && classnode.symbols.symbolList.Count > 0)
                {
                    bool firstPropertyDisplayed = false;
                    for (int n = 0; n < hs.VisibleSize; ++n)
                    {
                        SymbolNode symbol = classnode.symbols.symbolList[n];
                        string propName = symbol.name;

                        if ((null != visibleProperties) && visibleProperties.Contains(propName) == false)
                            continue; // This property is not to be displayed.

                        if (false != firstPropertyDisplayed)
                            classtrace.Append(", ");

                        string propValue = "";
                        if (symbol.isStatic)
                        {
                            StackValue opSymbol = new StackValue();
                            opSymbol.opdata = symbol.symbolTableIndex;
                            opSymbol.optype = AddressType.StaticMemVarIndex;

                            StackValue staticProp = this.core.Rmem.GetStackData(langblock, (int)opSymbol.opdata, Constants.kGlobalScope);
                            propValue = GetStringValue(staticProp, heap, langblock, forPrint);
                        }
                        else
                        {
                            propValue = GetStringValue(hs.Stack[symbol.index], heap, langblock, forPrint);
                        }
                        classtrace.Append(string.Format("{0} = {1}", propName, propValue));
                        firstPropertyDisplayed = true;
                    }
                }
                else
                {
                    for (int n = 0; n < hs.VisibleSize; ++n)
                    {
                        if (0 != n)
                            classtrace.Append(", ");

                        classtrace.Append(GetStringValue(hs.Stack[n], heap, langblock, forPrint));
                    }
                }

                formatParams.RestoreOutputTraceDepth();
                if (classtype >= (int)ProtoCore.PrimitiveType.kMaxPrimitives)
                    if (forPrint)
                        return (string.Format("{0}{{{1}}}", classnode.name, classtrace.ToString()));
                    else
                    {
                        string tempstr =  (string.Format("{0}({1})", classnode.name, classtrace.ToString()));
                        return tempstr;
                    }

                return classtrace.ToString();
            }
        }
Beispiel #30
0
 /// <summary>
 /// This is a callback method called when the given DS object is disposed.
 /// Marshaler gets an opportunity to clear the cache related to the given
 /// DS object.
 /// </summary>
 /// <param name="dsObject">DS object being disposed</param>
 /// <param name="context">DS execution context</param>
 /// <param name="dsi">The current runtime interpreter</param>
 public abstract void OnDispose(StackValue dsObject, ProtoCore.Runtime.Context context, Interpreter dsi); //callback method
        /// <summary>
        /// Compute the effects of the replication guides on the formal parameter lists
        /// The results of this loose data, and will not be correct on jagged arrays of hetrogenius types
        /// </summary>
        /// <param name="formalParams"></param>
        /// <param name="replicationInstructions"></param>
        /// <returns></returns>
        public static List <StackValue> EstimateReducedParams(List <StackValue> formalParams, List <ReplicationInstruction> replicationInstructions, Core core)
        {
            //Compute the reduced Type args
            List <StackValue> reducedParamTypes = new List <StackValue>();

            //Copy the types so unaffected ones get copied back directly
            foreach (StackValue sv in formalParams)
            {
                reducedParamTypes.Add(sv);
            }


            foreach (ReplicationInstruction ri in replicationInstructions)
            {
                if (ri.Zipped)
                {
                    foreach (int index in ri.ZipIndecies)
                    {
                        //This should generally be a collection, so we need to do a one phase unboxing
                        StackValue target    = reducedParamTypes[index];
                        StackValue reducedSV = StackValue.Null;

                        if (target.IsArray)
                        {
                            //Array arr = formalParams[index].Payload as Array;
                            HeapElement he = ArrayUtils.GetHeapElement(reducedParamTypes[index], core);



                            //It is a collection, so cast it to an array and pull the type of the first element
                            //@TODO(luke): Deal with sparse arrays, if the first element is null this will explode

                            Validity.Assert(he.Stack != null);

                            //The elements of the array are still type structures
                            if (he.VisibleSize == 0)
                            {
                                reducedSV = StackValue.Null;
                            }
                            else
                            {
                                reducedSV = he.Stack[0];
                            }
                        }
                        else
                        {
                            System.Console.WriteLine("WARNING: Replication unbox requested on Singleton. Trap: 437AD20D-9422-40A3-BFFD-DA4BAD7F3E5F");
                            reducedSV = target;
                        }

                        //reducedType.IsIndexable = false;
                        reducedParamTypes[index] = reducedSV;
                    }
                }
                else
                {
                    //This should generally be a collection, so we need to do a one phase unboxing
                    int        index  = ri.CartesianIndex;
                    StackValue target = reducedParamTypes[index];
                    StackValue reducedSV;

                    if (target.IsArray)
                    {
                        //ProtoCore.DSASM.Mirror.DsasmArray arr = formalParams[index].Payload as ProtoCore.DSASM.Mirror.DsasmArray;
                        HeapElement he = ArrayUtils.GetHeapElement(reducedParamTypes[index], core);

                        //It is a collection, so cast it to an array and pull the type of the first element
                        //@TODO(luke): Deal with sparse arrays, if the first element is null this will explode
                        //Validity.Assert(arr != null);
                        //Validity.Assert(arr.members[0] != null);
                        Validity.Assert(he.Stack != null);



                        //The elements of the array are still type structures
                        //reducedType = arr.members[0].Type;
                        if (he.VisibleSize == 0)
                        {
                            reducedSV = StackValue.Null;
                        }
                        else
                        {
                            reducedSV = he.Stack[0];
                        }
                    }
                    else
                    {
                        System.Console.WriteLine("WARNING: Replication unbox requested on Singleton. Trap: 437AD20D-9422-40A3-BFFD-DA4BAD7F3E5F");
                        reducedSV = target;
                    }

                    //reducedType.IsIndexable = false;
                    reducedParamTypes[index] = reducedSV;
                }
            }

            return(reducedParamTypes);
        }
Beispiel #32
0
        public static StackValue Coerce(StackValue sv, Type targetType, Core core)
        {
            //@TODO(Jun): FIX ME - abort coersion for default args
            if (sv.IsDefaultArgument)
            {
                return(sv);
            }

            if (!(
                    sv.metaData.type == targetType.UID ||
                    (core.ClassTable.ClassNodes[sv.metaData.type].ConvertibleTo(targetType.UID)) ||
                    sv.IsArray))
            {
                core.RuntimeStatus.LogWarning(Runtime.WarningID.kConversionNotPossible, Resources.kConvertNonConvertibleTypes);
                return(StackValue.Null);
            }

            //if it's an array
            if (sv.IsArray && !targetType.IsIndexable)
            {
                //This is an array rank reduction
                //this may only be performed in recursion and is illegal here
                string errorMessage = String.Format(Resources.kConvertArrayToNonArray, core.TypeSystem.GetType(targetType.UID));
                core.RuntimeStatus.LogWarning(Runtime.WarningID.kConversionNotPossible, errorMessage);
                return(StackValue.Null);
            }


            if (sv.IsArray &&
                targetType.IsIndexable)
            {
                Validity.Assert(sv.IsArray);

                //We're being asked to convert an array into an array
                //walk over the structure converting each othe elements

                var hpe = core.Heap.GetHeapElement(sv);
                //Validity.Assert(targetType.rank != -1, "Arbitrary rank array conversion not yet implemented {2EAF557F-62DE-48F0-9BFA-F750BBCDF2CB}");

                //Decrease level of reductions by one
                Type newTargetType = new Type();
                newTargetType.UID = targetType.UID;
                if (targetType.rank != Constants.kArbitraryRank)
                {
                    newTargetType.rank = targetType.rank - 1;
                }
                else
                {
                    if (ArrayUtils.GetMaxRankForArray(sv, core) == 1)
                    {
                        //Last unpacking
                        newTargetType.rank = 0;
                    }
                    else
                    {
                        newTargetType.rank = Constants.kArbitraryRank;
                    }
                }

                return(ArrayUtils.CopyArray(sv, newTargetType, core));
            }

            if (!sv.IsArray && !sv.IsNull &&
                targetType.IsIndexable &&
                targetType.rank != DSASM.Constants.kArbitraryRank)
            {
                //We're being asked to promote the value into an array
                if (targetType.rank == 1)
                {
                    Type newTargetType = new Type();
                    newTargetType.UID  = targetType.UID;
                    newTargetType.Name = targetType.Name;
                    newTargetType.rank = 0;

                    //Upcast once
                    StackValue coercedValue = Coerce(sv, newTargetType, core);
                    StackValue newSv        = core.Heap.AllocateArray(new StackValue[] { coercedValue }, null);
                    return(newSv);
                }
                else
                {
                    Validity.Assert(targetType.rank > 1, "Target rank should be greater than one for this clause");

                    Type newTargetType = new Type();
                    newTargetType.UID  = targetType.UID;
                    newTargetType.Name = targetType.Name;
                    newTargetType.rank = targetType.rank - 1;

                    //Upcast once
                    StackValue coercedValue = Coerce(sv, newTargetType, core);
                    StackValue newSv        = core.Heap.AllocateArray(new StackValue[] { coercedValue }, null);
                    return(newSv);
                }
            }

            if (sv.IsPointer)
            {
                StackValue ret = ClassCoerece(sv, targetType, core);
                return(ret);
            }

            //If it's anything other than array, just create a new copy
            switch (targetType.UID)
            {
            case (int)PrimitiveType.kInvalidType:
                Validity.Assert(false, "Can't convert invalid type");
                break;

            case (int)PrimitiveType.kTypeBool:
                return(sv.ToBoolean(core));

            case (int)PrimitiveType.kTypeChar:
            {
                StackValue newSV = sv.ShallowClone();
                newSV.metaData = new MetaData {
                    type = (int)PrimitiveType.kTypeChar
                };
                return(newSV);
            }

            case (int)PrimitiveType.kTypeDouble:
                return(sv.ToDouble());

            case (int)PrimitiveType.kTypeFunctionPointer:
                if (sv.metaData.type != (int)PrimitiveType.kTypeFunctionPointer)
                {
                    core.RuntimeStatus.LogWarning(Runtime.WarningID.kTypeMismatch, Resources.kFailToConverToFunction);
                    return(StackValue.Null);
                }
                return(sv);

            case (int)PrimitiveType.kTypeHostEntityID:
            {
                StackValue newSV = sv.ShallowClone();
                newSV.metaData = new MetaData {
                    type = (int)PrimitiveType.kTypeHostEntityID
                };
                return(newSV);
            }

            case (int)PrimitiveType.kTypeInt:
            {
                if (sv.metaData.type == (int)PrimitiveType.kTypeDouble)
                {
                    //TODO(lukechurch): Once the API is improved (MAGN-5174)
                    //Replace this with a log entry notification
                    //core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeConvertionCauseInfoLoss, Resources.kConvertDoubleToInt);
                }
                return(sv.ToInteger());
            }

            case (int)PrimitiveType.kTypeNull:
            {
                if (sv.metaData.type != (int)PrimitiveType.kTypeNull)
                {
                    core.RuntimeStatus.LogWarning(Runtime.WarningID.kTypeMismatch, Resources.kFailToConverToNull);
                    return(StackValue.Null);
                }
                return(sv);
            }

            case (int)PrimitiveType.kTypePointer:
            {
                if (sv.metaData.type != (int)PrimitiveType.kTypeNull)
                {
                    core.RuntimeStatus.LogWarning(Runtime.WarningID.kTypeMismatch, Resources.kFailToConverToPointer);
                    return(StackValue.Null);
                }
                return(sv);
            }

            case (int)PrimitiveType.kTypeString:
            {
                StackValue newSV = sv.ShallowClone();
                newSV.metaData = new MetaData {
                    type = (int)PrimitiveType.kTypeString
                };
                if (sv.metaData.type == (int)PrimitiveType.kTypeChar)
                {
                    char ch = EncodingUtils.ConvertInt64ToCharacter(newSV.opdata);
                    newSV = StackValue.BuildString(ch.ToString(), core.Heap);
                }
                return(newSV);
            }

            case (int)PrimitiveType.kTypeVar:
            {
                return(sv);
            }

            case (int)PrimitiveType.kTypeArray:
            {
                return(ArrayUtils.CopyArray(sv, targetType, core));
            }

            default:
                if (sv.IsNull)
                {
                    return(StackValue.Null);
                }
                else
                {
                    throw new NotImplementedException("Requested coercion not implemented");
                }
            }

            throw new NotImplementedException("Requested coercion not implemented");
        }
Beispiel #33
0
        /// <summary>
        /// For an array we supporting zipped replicaiton for array indexing as
        /// well. I.e., for the following expression:
        ///
        ///     a[1..3][2..4] = x;
        ///
        /// It will be expanded to
        ///
        ///     a[1][2] = x;
        ///     a[2][3] = x;
        ///     a[3][4] = x;
        ///
        /// So here we need to calculate zipped indices. The length of returned
        /// indices is decided by the shortest length of index that used in
        /// array indexing. E.g.,
        ///
        /// For array indexing
        ///
        ///     [{1, 2, 3}][{"x", "y"}][{6, 7, 8}], i.e.,
        ///
        ///     1 -> "x" -> 6
        ///     2 -> "y" -> 7
        ///     3 ->     -> 8
        ///
        /// The shortest length of index is 2 ({"x", "y"}), so function will
        /// returns:
        ///
        ///     {{1, "x", 6}, {2, "y", 7}}
        ///
        /// </summary>
        /// <param name="indices"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        private static StackValue[][] GetZippedIndices(List <StackValue> indices, Core core)
        {
            List <StackValue[]> allFlattenValues = new List <StackValue[]>();

            int zipLength = System.Int32.MaxValue;

            foreach (var index in indices)
            {
                int length = 1;
                if (StackUtils.IsArray(index))
                {
                    StackValue[] flattenValues = GetFlattenValue(index, core);
                    allFlattenValues.Add(flattenValues);
                    length = flattenValues.Count();
                }
                else
                {
                    allFlattenValues.Add(null);
                }

                if (zipLength > length)
                {
                    zipLength = length;
                }
            }

            if (zipLength == 0)
            {
                return(null);
            }
            else
            {
                int            dims          = indices.Count;
                StackValue[][] zippedIndices = new StackValue[zipLength][];
                for (int i = 0; i < zipLength; ++i)
                {
                    zippedIndices[i] = new StackValue[dims];
                }

                for (int i = 0; i < dims; ++i)
                {
                    StackValue   index  = indices[i];
                    StackValue[] values = null;
                    if (StackUtils.IsArray(index))
                    {
                        values = allFlattenValues[i];
                    }

                    if (1 == zipLength)
                    {
                        if (AddressType.ArrayPointer == index.optype)
                        {
                            zippedIndices[0][i] = values[0];
                        }
                        else
                        {
                            zippedIndices[0][i] = index;
                        }
                    }
                    else
                    {
                        for (int j = 0; j < zipLength; ++j)
                        {
                            zippedIndices[j][i] = values[j];
                        }
                    }
                }

                return(zippedIndices);
            }
        }
Beispiel #34
0
 public static string GetStringValue(StackValue sv, RuntimeCore runtimeCore)
 {
     ProtoCore.DSASM.Mirror.ExecutionMirror mirror = new DSASM.Mirror.ExecutionMirror(new ProtoCore.DSASM.Executive(runtimeCore), runtimeCore);
     return(mirror.GetStringValue(sv, runtimeCore.RuntimeMemory.Heap, 0, true));
 }
Beispiel #35
0
        /// <summary>
        /// array[index1][index2][...][indexN] = value, and
        /// indices = {index1, index2, ..., indexN}
        ///
        /// Note this function doesn't support the replication of array indexing.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="indices"></param>
        /// <param name="value"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue SetValueForIndices(StackValue array, StackValue[] indices, StackValue value, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));

            for (int i = 0; i < indices.Length - 1; ++i)
            {
                StackValue  index = indices[i];
                HeapElement he    = GetHeapElement(array, core);

                StackValue subArray;

                if (StackUtils.IsNumeric(index))
                {
                    index = index.AsInt();
                    int absIndex = he.ExpandByAcessingAt((int)index.opdata);
                    subArray = he.Stack[absIndex];
                }
                else
                {
                    subArray = GetValueFromIndex(array, index, core);
                }

                // auto-promotion
                if (!StackUtils.IsArray(subArray))
                {
                    subArray = HeapUtils.StoreArray(new StackValue[] { subArray }, null, core);
                    GCUtils.GCRetain(subArray, core);
                    SetValueForIndex(array, index, subArray, core);
                }

                array = subArray;
            }

            return(SetValueForIndex(array, indices[indices.Length - 1], value, core));
        }
Beispiel #36
0
        public void TestArrayGetCommonSuperType()
        {
            String code =
                @"
class A {}
class B extends A {}
class C extends B {}
tAAA = {A.A(), A.A(), A.A()};
tAAB = {A.A(), A.A(), B.B()};
tAAC = {A.A(), A.A(), C.C()};
tABA = {A.A(), B.B(), A.A()};
tABB = {A.A(), B.B(), B.B()};
tABC = {A.A(), B.B(), C.C()};
tACA = {A.A(), C.C(), A.A()};
tACB = {A.A(), C.C(), B.B()};
tACC = {A.A(), C.C(), C.C()};
//---
tBAA = {B.B(), A.A(), A.A()};
tBAB = {B.B(), A.A(), B.B()};
tBAC = {B.B(), A.A(), C.C()};
tBBA = {B.B(), B.B(), A.A()};
tBBB = {B.B(), B.B(), B.B()};
tBBC = {B.B(), B.B(), C.C()};
tBCA = {B.B(), C.C(), A.A()};
tBCB = {B.B(), C.C(), B.B()};
tBCC = {B.B(), C.C(), C.C()};
//---
tCAA = {C.C(), A.A(), A.A()};
tCAB = {C.C(), A.A(), B.B()};
tCAC = {C.C(), A.A(), C.C()};
tCBA = {C.C(), B.B(), A.A()};
tCBB = {C.C(), B.B(), B.B()};
tCBC = {C.C(), B.B(), C.C()};
tCCA = {C.C(), C.C(), A.A()};
tCCB = {C.C(), C.C(), B.B()};
tCCC = {C.C(), C.C(), C.C()};
";

            ProtoScript.Runners.ProtoScriptTestRunner fsr = new ProtoScript.Runners.ProtoScriptTestRunner();
            ExecutionMirror mirror   = fsr.Execute(code, core);
            StackValue      svAAA    = mirror.GetRawFirstValue("tAAA");
            ClassNode       superAAA = ArrayUtils.GetGreatestCommonSubclassForArray(svAAA, core);

            Assert.IsTrue(superAAA.name == "A");
            StackValue svAAB    = mirror.GetRawFirstValue("tAAB");
            ClassNode  superAAB = ArrayUtils.GetGreatestCommonSubclassForArray(svAAB, core);

            Assert.IsTrue(superAAB.name == "A");
            StackValue svAAC    = mirror.GetRawFirstValue("tAAC");
            ClassNode  superAAC = ArrayUtils.GetGreatestCommonSubclassForArray(svAAC, core);

            Assert.IsTrue(superAAC.name == "A");
            StackValue svABA    = mirror.GetRawFirstValue("tABA");
            ClassNode  superABA = ArrayUtils.GetGreatestCommonSubclassForArray(svABA, core);

            Assert.IsTrue(superABA.name == "A");
            StackValue svABB    = mirror.GetRawFirstValue("tABB");
            ClassNode  superABB = ArrayUtils.GetGreatestCommonSubclassForArray(svABB, core);

            Assert.IsTrue(superABB.name == "A");
            StackValue svABC    = mirror.GetRawFirstValue("tABC");
            ClassNode  superABC = ArrayUtils.GetGreatestCommonSubclassForArray(svABC, core);

            Assert.IsTrue(superABC.name == "A");
            StackValue svACA    = mirror.GetRawFirstValue("tACA");
            ClassNode  superACA = ArrayUtils.GetGreatestCommonSubclassForArray(svACA, core);

            Assert.IsTrue(superACA.name == "A");
            StackValue svACB    = mirror.GetRawFirstValue("tACB");
            ClassNode  superACB = ArrayUtils.GetGreatestCommonSubclassForArray(svACB, core);

            Assert.IsTrue(superACB.name == "A");
            StackValue svACC    = mirror.GetRawFirstValue("tACC");
            ClassNode  superACC = ArrayUtils.GetGreatestCommonSubclassForArray(svACC, core);

            Assert.IsTrue(superACC.name == "A");
            //----
            StackValue svBAA    = mirror.GetRawFirstValue("tBAA");
            ClassNode  superBAA = ArrayUtils.GetGreatestCommonSubclassForArray(svBAA, core);

            Assert.IsTrue(superBAA.name == "A");
            StackValue svBAB    = mirror.GetRawFirstValue("tBAB");
            ClassNode  superBAB = ArrayUtils.GetGreatestCommonSubclassForArray(svBAB, core);

            Assert.IsTrue(superBAB.name == "A");
            StackValue svBAC    = mirror.GetRawFirstValue("tBAC");
            ClassNode  superBAC = ArrayUtils.GetGreatestCommonSubclassForArray(svBAC, core);

            Assert.IsTrue(superBAC.name == "A");
            StackValue svBBA    = mirror.GetRawFirstValue("tBBA");
            ClassNode  superBBA = ArrayUtils.GetGreatestCommonSubclassForArray(svBBA, core);

            Assert.IsTrue(superBBA.name == "A");
            StackValue svBBB    = mirror.GetRawFirstValue("tBBB");
            ClassNode  superBBB = ArrayUtils.GetGreatestCommonSubclassForArray(svBBB, core);

            Assert.IsTrue(superBBB.name == "B");
            StackValue svBBC    = mirror.GetRawFirstValue("tBBC");
            ClassNode  superBBC = ArrayUtils.GetGreatestCommonSubclassForArray(svBBC, core);

            Assert.IsTrue(superBBC.name == "B");
            StackValue svBCA    = mirror.GetRawFirstValue("tBCA");
            ClassNode  superBCA = ArrayUtils.GetGreatestCommonSubclassForArray(svBCA, core);

            Assert.IsTrue(superBCA.name == "A");
            StackValue svBCB    = mirror.GetRawFirstValue("tBCB");
            ClassNode  superBCB = ArrayUtils.GetGreatestCommonSubclassForArray(svBCB, core);

            Assert.IsTrue(superBCB.name == "B");
            StackValue svBCC    = mirror.GetRawFirstValue("tBCC");
            ClassNode  superBCC = ArrayUtils.GetGreatestCommonSubclassForArray(svBCC, core);

            Assert.IsTrue(superBCC.name == "B");
            //----
            StackValue svCAA    = mirror.GetRawFirstValue("tCAA");
            ClassNode  superCAA = ArrayUtils.GetGreatestCommonSubclassForArray(svCAA, core);

            Assert.IsTrue(superCAA.name == "A");
            StackValue svCAB    = mirror.GetRawFirstValue("tCAB");
            ClassNode  superCAB = ArrayUtils.GetGreatestCommonSubclassForArray(svCAB, core);

            Assert.IsTrue(superCAB.name == "A");
            StackValue svCAC    = mirror.GetRawFirstValue("tCAC");
            ClassNode  superCAC = ArrayUtils.GetGreatestCommonSubclassForArray(svCAC, core);

            Assert.IsTrue(superCAC.name == "A");
            StackValue svCBA    = mirror.GetRawFirstValue("tCBA");
            ClassNode  superCBA = ArrayUtils.GetGreatestCommonSubclassForArray(svCBA, core);

            Assert.IsTrue(superCBA.name == "A");
            StackValue svCBB    = mirror.GetRawFirstValue("tCBB");
            ClassNode  superCBB = ArrayUtils.GetGreatestCommonSubclassForArray(svCBB, core);

            Assert.IsTrue(superCBB.name == "B");
            StackValue svCBC    = mirror.GetRawFirstValue("tCBC");
            ClassNode  superCBC = ArrayUtils.GetGreatestCommonSubclassForArray(svCBC, core);

            Assert.IsTrue(superCBC.name == "B");
            StackValue svCCA    = mirror.GetRawFirstValue("tCCA");
            ClassNode  superCCA = ArrayUtils.GetGreatestCommonSubclassForArray(svCCA, core);

            Assert.IsTrue(superCCA.name == "A");
            StackValue svCCB    = mirror.GetRawFirstValue("tCCB");
            ClassNode  superCCB = ArrayUtils.GetGreatestCommonSubclassForArray(svCCB, core);

            Assert.IsTrue(superCCB.name == "B");
            StackValue svCCC    = mirror.GetRawFirstValue("tCCC");
            ClassNode  superCCC = ArrayUtils.GetGreatestCommonSubclassForArray(svCCC, core);

            Assert.IsTrue(superCCC.name == "C");
        }
Beispiel #37
0
        public void Defect_TestArrayGetCommonSuperType()
        {
            String code =
                @"
class A{};
class B extends A{};
class C extends A{};
class D extends C{};
a = A.A();
b = B.B();
c = C.C();
d = D.D();
//ba:A = B.B();
//ca:A = C.C();
//dc:C = D.D();
tABC = { a, b, c };
tABD = { a, b, d };
tACD = { a, c, d };
tBCD = { b, c, d };
tAB = { a, b };
tAD = { a, d };
tBC = { b, c };
tBD = { b, d };
tCD = { c, d };
";

            ProtoScript.Runners.ProtoScriptTestRunner fsr = new ProtoScript.Runners.ProtoScriptTestRunner();
            ExecutionMirror mirror   = fsr.Execute(code, core);
            StackValue      svABC    = mirror.GetRawFirstValue("tABC");
            ClassNode       superABC = ArrayUtils.GetGreatestCommonSubclassForArray(svABC, core);

            Assert.IsTrue(superABC.name == "A");
            StackValue svABD    = mirror.GetRawFirstValue("tABD");
            ClassNode  superABD = ArrayUtils.GetGreatestCommonSubclassForArray(svABD, core);

            Assert.IsTrue(superABD.name == "A");
            StackValue svACD    = mirror.GetRawFirstValue("tACD");
            ClassNode  superACD = ArrayUtils.GetGreatestCommonSubclassForArray(svACD, core);

            Assert.IsTrue(superABD.name == "A");
            StackValue svBCD    = mirror.GetRawFirstValue("tBCD");
            ClassNode  superBCD = ArrayUtils.GetGreatestCommonSubclassForArray(svBCD, core);

            Assert.IsTrue(superBCD.name == "A");
            StackValue svAB    = mirror.GetRawFirstValue("tAB");
            ClassNode  superAB = ArrayUtils.GetGreatestCommonSubclassForArray(svAB, core);

            Assert.IsTrue(superAB.name == "A");
            StackValue svAD    = mirror.GetRawFirstValue("tAD");
            ClassNode  superAD = ArrayUtils.GetGreatestCommonSubclassForArray(svAD, core);

            Assert.IsTrue(superAD.name == "A");
            StackValue svBC    = mirror.GetRawFirstValue("tBC");
            ClassNode  superBC = ArrayUtils.GetGreatestCommonSubclassForArray(svBC, core);

            Assert.IsTrue(superBC.name == "A");
            StackValue svBD    = mirror.GetRawFirstValue("tBD");
            ClassNode  superBD = ArrayUtils.GetGreatestCommonSubclassForArray(svBD, core);

            Assert.IsTrue(superBD.name == "A");
            StackValue svCD    = mirror.GetRawFirstValue("tCD");
            ClassNode  superCD = ArrayUtils.GetGreatestCommonSubclassForArray(svCD, core);

            Assert.IsTrue(superCD.name == "C");
        }
Beispiel #38
0
 public StackValuePointerFake(StackValue pointer)
 {
     UnknownPointer = pointer;
 }
Beispiel #39
0
        private string GetPointerTrace(StackValue ptr, Heap heap, int langblock, HashSet<int> pointers, bool forPrint)
        {
            if (pointers.Contains(ptr.ArrayPointer))
            {
                return "{ ... }";
            }
            else
            {
                pointers.Add(ptr.ArrayPointer);

                if (forPrint)
                {
                    return "{" + GetArrayTrace(ptr, heap, langblock, pointers, forPrint) + "}";
                }
                else
                {
                    return "{ " + GetArrayTrace(ptr, heap, langblock, pointers, forPrint) + " }";
                }
            }
        }
Beispiel #40
0
 /// <summary>
 /// Experimental constructor that takes in a core object
 /// Takes a core object to read static data
 /// </summary>
 /// <param name="sv"></param>
 public MirrorData(ProtoCore.Core core, StackValue sv)
 {
     this.core = core;
     svData    = sv;
 }
Beispiel #41
0
        public string GetStringValue(StackValue val, Heap heap, int langblock, int maxArraySize, int maxOutputDepth, bool forPrint = false)
        {
            if (formatParams == null)
                formatParams = new OutputFormatParameters(maxArraySize, maxOutputDepth);

            if (val.IsInteger)
            {
                return val.IntegerValue.ToString();
            }
            else if (val.IsDouble)
            {
                return val.DoubleValue.ToString("F6");
            }
            else if (val.IsNull)
            {
                return "null";
            }
            else if (val.IsPointer)
            {
                return GetClassTrace(val, heap, langblock, forPrint);
            }
            else if (val.IsArray)
            {
                HashSet<int> pointers = new HashSet<int> { val.ArrayPointer };
                string arrTrace = GetArrayTrace(val, heap, langblock, pointers, forPrint);
                if (forPrint)
                    return "{" + arrTrace + "}";
                else
                    return "{ " + arrTrace + " }";
            }
            else if (val.IsFunctionPointer)
            {
                ProcedureNode procNode;
                if (runtimeCore.DSExecutable.FuncPointerTable.TryGetFunction(val, runtimeCore, out procNode))
                {
                    string className = String.Empty;
                    if (procNode.ClassID != Constants.kGlobalScope)
                    {
                        className = runtimeCore.DSExecutable.classTable.GetTypeName(procNode.ClassID).Split('.').Last() + ".";
                    }

                    return "function: " + className + procNode.Name;
                }
                return "function: " + val.FunctionPointer.ToString();
            }
            else if (val.IsBoolean)
            {
                return val.BooleanValue ? "true" : "false";
            }
            else if (val.IsString)
            {
                if (forPrint)
                    return heap.ToHeapObject<DSString>(val).Value;
                else
                    return "\"" + heap.ToHeapObject<DSString>(val).Value + "\"";
            }
            else if (val.IsChar)
            {
                Char character = Convert.ToChar(val.CharValue);
                if (forPrint)
                    return character.ToString();
                else
                    return "'" + character + "'";
            }
            else
            {
                return "null"; // "Value not yet supported for tracing";
            }
        }
Beispiel #42
0
 /// <summary>
 /// Takes a runtime core object to read runtime data
 /// </summary>
 /// <param name="sv"></param>
 public MirrorData(ProtoCore.Core core, ProtoCore.RuntimeCore runtimeCore, StackValue sv)
 {
     this.core        = core;
     this.runtimeCore = runtimeCore;
     svData           = sv;
 }
Beispiel #43
0
        // this method is used for the IDE to query object values 
        // Copy from the the existing Unpack with some modifications
        //  1: It is a non-static method so there is no need to pass the core and heap
        //  2: It does not traverse the array, array traverse is done in method GetArrayElement
        //  3: The payload for boolean and null is changed to Boolean and null type in .NET, such that the watch windows can directly call ToString() 
        //     to print the value, otherwize for boolean it will print either 0 or 1, for null it will print 0
        public Obj Unpack(StackValue val)
        {
            Obj obj = null;


            switch (val.optype)
            {
                case AddressType.Pointer:
                    obj = new Obj(val) 
                    { 
                        Payload = val.Pointer, 
                    };
                    break;
                case AddressType.ArrayPointer:
                    obj = new Obj(val) 
                    { 
                        Payload = val.ArrayPointer, 
                    };
                    break;
       
                case AddressType.Int:
                    obj = new Obj(val) 
                    { 
                        Payload = val.IntegerValue, 
                    };
                    break;
                case AddressType.Boolean:
                    obj = new Obj(val)
                    {
                        Payload = val.BooleanValue,
                    };
                    break;
                case AddressType.Double:
                    obj = new Obj(val) 
                    { 
                        Payload = val.DoubleValue, 
                    };
                    break;
                case AddressType.Null:
                    obj = new Obj(val) 
                    { 
                        Payload = null, 
                    };
                    break;
                case AddressType.FunctionPointer:
                    obj = new Obj(val) 
                    { 
                        Payload = val.FunctionPointer, 
                    };
                    break;
                case AddressType.String:
                    obj = new Obj(val) 
                    { 
                        Payload = val.StringPointer, 
                    };
                    break;
                case AddressType.Char:
                    obj = new Obj(val) 
                    { 
                        Payload = val.CharValue, 
                    };
                    break;
            }

            return obj;
        }
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            List <Object>     parameters = new List <object>();
            List <StackValue> s          = dsi.runtime.rmem.Stack;
            Object            thisObject = null;
            FFIObjectMarshler marshaller = Module.GetMarshaller(dsi.runtime.RuntimeCore);

            if (!ReflectionInfo.IsStatic)
            {
                try
                {
                    thisObject = marshaller.UnMarshal(s.Last(), c, dsi, ReflectionInfo.DeclaringType);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(Resources.kFFIFailedToObtainThisObject, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, message);
                    return(null);
                }

                if (thisObject == null)
                {
                    return(null); //Can't call a method on null object.
                }
            }

            ParameterInfo[] paraminfos = ReflectionInfo.GetParameters();
            for (int i = 0; i < mArgTypes.Length; ++i)
            {
                // Comment Jun: FFI function stack frames do not contain locals
                int        locals   = 0;
                int        relative = 0 - ProtoCore.DSASM.StackFrame.kStackFrameSize - locals - i - 1;
                StackValue opArg    = dsi.runtime.rmem.GetAtRelative(relative);
                try
                {
                    Type   paramType = paraminfos[i].ParameterType;
                    object param     = null;
                    if (opArg.IsDefaultArgument)
                    {
                        param = Type.Missing;
                    }
                    else
                    {
                        param = marshaller.UnMarshal(opArg, c, dsi, paramType);
                    }

                    //null is passed for a value type, so we must return null
                    //rather than interpreting any value from null. fix defect 1462014
                    if (!paramType.IsGenericType && paramType.IsValueType && param == null)
                    {
                        //This is going to cause a cast exception. This is a very frequently called problem, so we want to short-cut the execution

                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation,
                                       string.Format("Null value cannot be cast to {0}", paraminfos[i].ParameterType.Name));

                        return(null);
                        //throw new System.InvalidCastException(string.Format("Null value cannot be cast to {0}", paraminfos[i].ParameterType.Name));
                    }

                    parameters.Add(param);
                }
                catch (System.InvalidCastException ex)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
                    return(null);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(Resources.kFFIFailedToObtainObject, paraminfos[i].ParameterType.Name, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, message);
                    return(null);
                }
            }

            object     ret        = null;
            StackValue dsRetValue = StackValue.Null;

            try
            {
                ret = InvokeFunctionPointer(thisObject, parameters.Count > 0 ? parameters.ToArray() : null);
                //Reduce to singleton if the attribute is specified.
                ret        = ReflectionInfo.ReduceReturnedCollectionToSingleton(ret);
                dsRetValue = marshaller.Marshal(ret, c, dsi, mReturnType);
            }
            catch (DllNotFoundException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogSemanticError(ex.InnerException.Message);
                }
                dsi.LogSemanticError(ex.Message);
            }
            catch (System.Reflection.TargetException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.Reflection.TargetInvocationException ex)
            {
                if (ex.InnerException != null)
                {
                    System.Exception exc = ex.InnerException;
                    if (exc is System.ArgumentException)
                    {
                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, ErrorString(exc));
                    }
                    else if (exc is System.NullReferenceException)
                    {
                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ErrorString(null));
                    }
                    else
                    {
                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ErrorString(exc));
                    }
                }
                else
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ErrorString(ex));
                }
            }
            catch (System.Reflection.TargetParameterCountException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.MethodAccessException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.InvalidOperationException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.NotSupportedException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.ArgumentException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, ErrorString(ex.InnerException));
                }
                else
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, ErrorString(ex));
                }
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kDefault, ErrorString(ex.InnerException));
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kDefault, ErrorString(ex));
            }

            return(dsRetValue);
        }
Beispiel #45
0
        private ValueRef ResolveVirtualMethod(FunctionCompilerContext functionContext, ref Function targetMethod, ref StackValue thisObject)
        {
            ValueRef resolvedMethod;
            if ((targetMethod.MethodReference.Resolve().Attributes & MethodAttributes.Virtual) == MethodAttributes.Virtual)
            {
                // Build indices for GEP
                var indices = new[]
                {
                    LLVM.ConstInt(int32Type, 0, false), // Pointer indirection
                    LLVM.ConstInt(int32Type, (int) ObjectFields.RuntimeTypeInfo, false), // Access RTTI
                };

                Class @class;

                var constrainedClass = functionContext.ConstrainedClass;
                if (constrainedClass != null)
                {
                    // Reset state
                    functionContext.ConstrainedClass = null;

                    if (!constrainedClass.Type.TypeReference.IsValueType)
                    {
                        // If thisType is a reference type, dereference
                        thisObject = new StackValue(constrainedClass.Type.StackType, constrainedClass.Type,
                            LLVM.BuildPointerCast(builder, LLVM.BuildLoad(builder, thisObject.Value, string.Empty),
                                constrainedClass.Type.DefaultType, string.Empty));
                    }
                    else
                    {
                        var matchingMethod = CecilExtensions.TryMatchMethod(constrainedClass, targetMethod.MethodReference,
                            false);
                        if (matchingMethod != null)
                        {
                            // If thisType is a value type and implements method, then ptr is passed unmodified
                            targetMethod = matchingMethod;

                            // Convert to appropriate type (if necessary)
                            var refType = GetType(constrainedClass.Type.TypeReference.MakeByReferenceType());
                            if (thisObject.StackType != StackValueType.Reference || thisObject.Type != refType)
                            {
                                thisObject = new StackValue(refType.StackType, refType,
                                    LLVM.BuildPointerCast(builder, thisObject.Value, refType.DefaultType, string.Empty));
                            }
                        }
                        else
                        {
                            // If thisType is a value type and doesn't implement method, dereference, box and pass as this
                            thisObject = new StackValue(constrainedClass.Type.StackType, constrainedClass.Type,
                                LLVM.BuildPointerCast(builder, LLVM.BuildLoad(builder, thisObject.Value, string.Empty),
                                    constrainedClass.Type.DefaultType, string.Empty));

                            thisObject = new StackValue(StackValueType.Object, constrainedClass.Type,
                                BoxValueType(constrainedClass, thisObject));
                        }
                    }

                    @class = constrainedClass;
                }
                else
                {
                    @class = GetClass(thisObject.Type);
                }

                // TODO: Checking actual type stored in thisObject we might be able to statically resolve method?

                // If it's a byref value type, emit a normal call
                if (thisObject.Type.TypeReference.IsByReference
                    && thisObject.Type.TypeReference.GetElementType().IsValueType
                    && MemberEqualityComparer.Default.Equals(targetMethod.DeclaringType.TypeReference, thisObject.Type.TypeReference.GetElementType()))
                {
                    resolvedMethod = targetMethod.GeneratedValue;
                }
                else
                {
                    // Get RTTI pointer
                    var rttiPointer = LLVM.BuildInBoundsGEP(builder, thisObject.Value, indices, string.Empty);
                    rttiPointer = LLVM.BuildLoad(builder, rttiPointer, string.Empty);

                    // Cast to expected RTTI type
                    rttiPointer = LLVM.BuildPointerCast(builder, rttiPointer, LLVM.TypeOf(@class.GeneratedRuntimeTypeInfoGlobal), string.Empty);

                    if (targetMethod.MethodReference.DeclaringType.Resolve().IsInterface)
                    {
                        // Interface call

                        // Get method stored in IMT slot
                        indices = new[]
                        {
                            LLVM.ConstInt(int32Type, 0, false), // Pointer indirection
                            LLVM.ConstInt(int32Type, (int) RuntimeTypeInfoFields.InterfaceMethodTable, false), // Access IMT
                            LLVM.ConstInt(int32Type, (ulong) targetMethod.VirtualSlot, false), // Access specific IMT slot
                        };

                        var imtEntry = LLVM.BuildInBoundsGEP(builder, rttiPointer, indices, string.Empty);

                        var methodPointer = LLVM.BuildLoad(builder, imtEntry, string.Empty);

                        // TODO: Compare method ID and iterate in the linked list until the correct match is found
                        // If no match is found, it's likely due to covariance/contravariance, so we will need a fallback
                        var methodId = GetMethodId(targetMethod.MethodReference);

                        // Resolve interface call
                        resolvedMethod = LLVM.BuildCall(builder, resolveInterfaceCallFunction, new[]
                        {
                            LLVM.ConstInt(int32Type, methodId, false),
                            methodPointer,
                        }, string.Empty);
                        resolvedMethod = LLVM.BuildPointerCast(builder, resolvedMethod,
                            LLVM.PointerType(targetMethod.FunctionType, 0), string.Empty);
                    }
                    else
                    {
                        // Virtual table call

                        // Get method stored in vtable slot
                        indices = new[]
                        {
                            LLVM.ConstInt(int32Type, 0, false), // Pointer indirection
                            LLVM.ConstInt(int32Type, (int) RuntimeTypeInfoFields.VirtualTable, false), // Access vtable
                            LLVM.ConstInt(int32Type, (ulong) targetMethod.VirtualSlot, false), // Access specific vtable slot
                        };

                        var vtable = LLVM.BuildInBoundsGEP(builder, rttiPointer, indices, string.Empty);
                        resolvedMethod = LLVM.BuildLoad(builder, vtable, string.Empty);
                        resolvedMethod = LLVM.BuildPointerCast(builder, resolvedMethod, LLVM.PointerType(targetMethod.FunctionType, 0), string.Empty);
                    }
                }
            }
            else
            {
                // Normal call
                // Callvirt on non-virtual function is only done to force "this" NULL check
                // However, that's probably a part of the .NET spec that we want to skip for performance reasons,
                // so maybe we should keep this as is?
                resolvedMethod = targetMethod.GeneratedValue;
            }
            return resolvedMethod;
        }
Beispiel #46
0
 public string PrintClass(StackValue val, Heap heap, int langblock, bool forPrint)
 {
     return PrintClass(val, heap, langblock, -1, -1, forPrint);
 }
Beispiel #47
0
        /// <summary>
        /// Merges the stack.
        /// </summary>
        /// <param name="sourceStack">The source stack.</param>
        /// <param name="sourceBasicBlock">The source basic block.</param>
        /// <param name="targetStack">The target stack.</param>
        /// <param name="targetBasicBlock">The target basic block.</param>
        private void MergeStack(List<StackValue> sourceStack, BasicBlockRef sourceBasicBlock, ref StackValue[] targetStack, BasicBlockRef targetBasicBlock)
        {
            // First time? Need to create stack and position builder
            if (targetStack == null)
            {
                targetStack = new StackValue[sourceStack.Count];
                if (LLVM.GetLastInstruction(targetBasicBlock).Value != IntPtr.Zero && sourceStack.Count != 0)
                    throw new InvalidOperationException("Target basic block should have no instruction yet, or stack should be empty.");
            }

            for (int index = 0; index < sourceStack.Count; index++)
            {
                var stackValue = sourceStack[index];

                var mergedStackValue = targetStack[index];

                // First time? Need to create PHI node
                if (mergedStackValue == null)
                {
                    // TODO: Check stack type during merging?
                    LLVM.PositionBuilderAtEnd(builder2, targetBasicBlock);
                    mergedStackValue = new StackValue(stackValue.StackType, stackValue.Type, LLVM.BuildPhi(builder2, LLVM.TypeOf(stackValue.Value), string.Empty));
                    targetStack[index] = mergedStackValue;
                }

                // Convert type (if necessary)
                // TOOD: Reuse common code with cast/conversion code
                var value = stackValue.Value;
                if (LLVM.TypeOf(value) != LLVM.TypeOf(mergedStackValue.Value) && LLVM.GetTypeKind(LLVM.TypeOf(mergedStackValue.Value)) == TypeKind.PointerTypeKind)
                {
                    // Position before last instruction (which should be a branching instruction)
                    LLVM.PositionBuilderBefore(builder2, LLVM.GetLastInstruction(sourceBasicBlock));
                    value = LLVM.BuildPointerCast(builder2, value, LLVM.TypeOf(mergedStackValue.Value), string.Empty);
                }

                // Add values from previous stack value
                LLVM.AddIncoming(mergedStackValue.Value, new[] { value }, new[] { sourceBasicBlock });
            }
        }
Beispiel #48
0
        // this method is used for the IDE to query object values
        // Copy from the the existing Unpack with some modifications
        //  1: It is a non-static method so there is no need to pass the core and heap
        //  2: It does not traverse the array, array traverse is done in method GetArrayElement
        //  3: The payload for boolean and null is changed to Boolean and null type in .NET, such that the watch windows can directly call ToString()
        //     to print the value, otherwize for boolean it will print either 0 or 1, for null it will print 0
        public Obj Unpack(StackValue val)
        {
            Obj obj = null;

            switch (val.optype)
            {
                case AddressType.Pointer:
                    obj = new Obj(val) { Payload = val.opdata, Type = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypePointer, false) };
                    break;
                case AddressType.ArrayPointer:
                    obj = new Obj(val) { Payload = val.opdata, Type = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeArray, true) };
                    break;
                case AddressType.Int:
                    obj = new Obj(val) { Payload = val.opdata, Type = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeInt, false) };
                    break;
                case AddressType.Boolean:
                    obj = new Obj(val) { Payload = val.opdata == 0 ? false : true, Type = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeBool, false) };
                    break;
                case AddressType.Double:
                    obj = new Obj(val) { Payload = val.opdata_d, Type = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeDouble, false) };
                    break;
                case AddressType.Null:
                    obj = new Obj(val) { Payload = null, Type = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeNull, false) };
                    break;
                case AddressType.FunctionPointer:
                    obj = new Obj(val) { Payload = val.opdata, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeFunctionPointer, false) };
                    break;
                case AddressType.String:
                    obj = new Obj(val) { Payload = val.opdata, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeString, true, Constants.kPrimitiveSize) };
                    break;
                case AddressType.Char:
                    obj = new Obj(val) { Payload = val.opdata, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeChar, false) };
                    break;
            }

            return obj;
        }
Beispiel #49
0
        public static Obj Unpack(StackValue val, Core core)
        {
            switch (val.optype)
            {
                case AddressType.ArrayPointer:
                    {
                        //It was a pointer that we pulled, so the value lives on the heap
                        Int64 ptr = val.opdata;

                        DsasmArray ret = new DsasmArray();
                        HeapElement hs = core.Heap.Heaplist[(int)ptr];

                        StackValue[] nodes = hs.Stack;
                        ret.members = new Obj[nodes.Length];

                        for (int i = 0; i < ret.members.Length; i++)
                        {
                            ret.members[i] = Unpack(nodes[i], core);
                        }

                        Obj retO = new Obj(val) { Payload = ret, Type = core.TypeSystem.BuildTypeObject((ret.members.Length > 0) ? core.TypeSystem.GetType(ret.members[0].Type.Name) : (int)ProtoCore.PrimitiveType.kTypeVar, true) };

                        return retO;
                    }
                case AddressType.Int:
                    {
                        Int64 data = val.opdata;
                        Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeInt, false) };
                        return o;
                    }
                case AddressType.Boolean:
                    {
                        Obj o = new Obj(val) { Payload = val.opdata == 0 ? false : true, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeBool, false) };
                        return o;
                    }
                case AddressType.Null:
                    {
                        Obj o = new Obj(val) { Payload = null, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeNull, false) };
                        return o;
                    }
                case AddressType.Double:
                    {
                        double data = val.opdata_d;
                        Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeDouble, false) };
                        return o;
                    }
                case AddressType.Char:
                    {
                        Int64 data = val.opdata;
                        Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeChar, false) };
                        return o;
                    }
                case AddressType.Pointer:
                    {
                        Int64 data = val.opdata;
                        Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject((int)val.metaData.type, false) };
                        return o;
                    }
                case AddressType.DefaultArg:
                    {
                        Int64 data = val.opdata;
                        Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeVar, false) };
                        return o;
                    }
                case AddressType.FunctionPointer:
                    {
                        Int64 data = val.opdata;
                        Obj o = new Obj(val) { Payload = data, Type = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeFunctionPointer, false) };
                        return o;
                    }
                default:
                    {
                        throw new NotImplementedException(string.Format("unknown datatype {0}", val.optype.ToString()));
                    }
            }
        }
Beispiel #50
0
        public string GetStringValue(StackValue val, Heap heap, int langblock, int maxArraySize, int maxOutputDepth, bool forPrint = false)
        {
            if (formatParams == null)
                formatParams = new OutputFormatParameters(maxArraySize, maxOutputDepth);

            switch (val.optype)
            {
                case AddressType.Int:
                    return val.opdata.ToString();
                case AddressType.Double:
                    return val.opdata_d.ToString(core.Options.FormatToPrintFloatingPoints);
                case AddressType.Null:
                    return "null";
                case AddressType.Pointer:
                    return GetClassTrace(val, heap, langblock, forPrint);
                case AddressType.ArrayPointer:
                    HashSet<int> pointers = new HashSet<int>{(int)val.opdata};
                    string arrTrace = GetArrayTrace((int)val.opdata, heap, langblock, pointers, forPrint);
                    if (forPrint)
                        return "{" + arrTrace + "}";
                    else
                        return "{ " + arrTrace + " }";
                case AddressType.FunctionPointer:
                    return "fptr: " + val.opdata.ToString();
                case AddressType.Boolean:
                    return (val.opdata == 0) ? "false" : "true";
                case AddressType.String:
                    if (forPrint)
                        return GetStringTrace((int)val.opdata, heap);
                    else
                        return "\"" + GetStringTrace((int)val.opdata, heap) + "\"";
                case AddressType.Char:
                    Char character = ProtoCore.Utils.EncodingUtils.ConvertInt64ToCharacter(val.opdata);
                    if (forPrint)
                        return character.ToString();
                    else
                        return "'" + character + "'";
                default:
                    return "null"; // "Value not yet supported for tracing";
            }
        }
Beispiel #51
0
        public Obj GetDebugValue(string name)
        {
            int classcope;
            int block = core.GetCurrentBlockId();

            RuntimeMemory rmem = core.Rmem;
            SymbolNode symbol;
            int index = GetSymbolIndex(name, out classcope, ref block, out symbol);
            StackValue sv = new StackValue();
            if (symbol.functionIndex == -1 && classcope != Constants.kInvalidIndex)
                sv = rmem.GetMemberData(index, classcope);
            else
                sv = rmem.GetStackData(block, index, classcope);

            if (sv.optype == AddressType.Invalid)
                throw new UninitializedVariableException { Name = name };

            return Unpack(sv);
        }
        public StackValue Evaluate(List <StackValue> args, StackFrame stackFrame)
        {
            // Build the stackframe
            var runtimeCore = interpreter.runtime.Core;

            int        classScopeCaller = (int)stackFrame.GetAt(StackFrame.AbsoluteIndex.kClass).opdata;
            int        returnAddr       = (int)stackFrame.GetAt(StackFrame.AbsoluteIndex.kReturnAddress).opdata;
            int        blockDecl        = procNode.runtimeIndex;
            int        blockCaller      = (int)stackFrame.GetAt(StackFrame.AbsoluteIndex.kFunctionCallerBlock).opdata;
            int        framePointer     = runtimeCore.Rmem.FramePointer;
            StackValue thisPtr          = StackValue.BuildPointer(-1);

            // Functoion has variable input parameter. This case only happen
            // for FFI functions whose last parameter's type is (params T[]).
            // In this case, we need to convert argument list from
            //
            //    {a1, a2, ..., am, v1, v2, ..., vn}
            //
            // to
            //
            //    {a1, a2, ..., am, {v1, v2, ..., vn}}
            if (procNode.isVarArg)
            {
                int paramCount = procNode.argInfoList.Count;
                Validity.Assert(paramCount >= 1);

                int varParamCount = args.Count - (paramCount - 1);
                var varParams     = args.GetRange(paramCount - 1, varParamCount).ToArray();
                args.RemoveRange(paramCount - 1, varParamCount);

                var packedParams = HeapUtils.StoreArray(varParams, null, interpreter.runtime.Core);
                args.Add(packedParams);
            }

            bool isCallingMemberFunciton = procNode.classScope != Constants.kInvalidIndex &&
                                           !procNode.isConstructor &&
                                           !procNode.isStatic;

            bool isValidThisPointer = true;

            if (isCallingMemberFunciton)
            {
                Validity.Assert(args.Count >= 1);
                thisPtr = args[0];
                if (thisPtr.IsArray)
                {
                    isValidThisPointer = ArrayUtils.GetFirstNonArrayStackValue(thisPtr, ref thisPtr, runtimeCore);
                }
                else
                {
                    args.RemoveAt(0);
                }
            }

            if (!isValidThisPointer || (!thisPtr.IsPointer && !thisPtr.IsArray))
            {
                runtimeCore.RuntimeStatus.LogWarning(WarningID.kDereferencingNonPointer,
                                                     WarningMessage.kDeferencingNonPointer);
                return(StackValue.Null);
            }

            var callerType = (StackFrameType)stackFrame.GetAt(StackFrame.AbsoluteIndex.kStackFrameType).opdata;

            interpreter.runtime.TX = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.kImplicit);

            StackValue svBlockDecl = StackValue.BuildBlockIndex(blockDecl);

            interpreter.runtime.SX = svBlockDecl;

            var repGuides = new List <List <ProtoCore.ReplicationGuide> >();

            List <StackValue> registers = new List <StackValue>();

            interpreter.runtime.SaveRegisters(registers);
            var newStackFrame = new StackFrame(thisPtr,
                                               classScopeCaller,
                                               1,
                                               returnAddr,
                                               blockDecl,
                                               blockCaller,
                                               callerType,
                                               StackFrameType.kTypeFunction,
                                               0,   // depth
                                               framePointer,
                                               registers,
                                               null);

            bool isInDebugMode = runtimeCore.Options.IDEDebugMode &&
                                 runtimeCore.ExecMode != InterpreterMode.kExpressionInterpreter;

            if (isInDebugMode)
            {
                runtimeCore.DebugProps.SetUpCallrForDebug(runtimeCore,
                                                          interpreter.runtime,
                                                          procNode,
                                                          returnAddr - 1,
                                                          false,
                                                          callsite,
                                                          args,
                                                          repGuides,
                                                          newStackFrame);
            }

            StackValue rx = callsite.JILDispatchViaNewInterpreter(
                new Runtime.Context(),
                args,
                repGuides,
                newStackFrame,
                runtimeCore);

            if (isInDebugMode)
            {
                runtimeCore.DebugProps.RestoreCallrForNoBreak(runtimeCore, procNode);
            }

            interpreter.runtime.DecRefCounter(rx);

            return(rx);
        }
Beispiel #53
0
 public string GetStringValue(StackValue val, Heap heap, int langblock, bool forPrint = false)
 {
     return GetStringValue(val, heap, langblock, -1, -1, forPrint);
 }
        public static List <List <StackValue> > ComputeReducedParamsSuperset(List <StackValue> formalParams, List <ReplicationInstruction> replicationInstructions, Core core)
        {
            //Compute the reduced Type args
            List <List <StackValue> > reducedParams = new List <List <StackValue> >();

            List <StackValue> basicList = new List <StackValue>();

            //Copy the types so unaffected ones get copied back directly
            foreach (StackValue sv in formalParams)
            {
                basicList.Add(sv);
            }

            reducedParams.Add(basicList);


            foreach (ReplicationInstruction ri in replicationInstructions)
            {
                if (ri.Zipped)
                {
                    foreach (int index in ri.ZipIndecies)
                    {
                        //This should generally be a collection, so we need to do a one phase unboxing
                        StackValue target    = basicList[index];
                        StackValue reducedSV = StackValue.Null;

                        if (target.IsArray)
                        {
                            //Array arr = formalParams[index].Payload as Array;
                            HeapElement he = ArrayUtils.GetHeapElement(basicList[index], core);

                            Validity.Assert(he.Stack != null);

                            //The elements of the array are still type structures
                            if (he.VisibleSize == 0)
                            {
                                reducedSV = StackValue.Null;
                            }
                            else
                            {
                                var arrayStats = ArrayUtils.GetTypeExamplesForLayer(basicList[index], core).Values;

                                List <List <StackValue> > clonedList = new List <List <StackValue> >();

                                foreach (List <StackValue> list in reducedParams)
                                {
                                    clonedList.Add(list);
                                }

                                reducedParams.Clear();

                                foreach (StackValue sv in arrayStats)
                                {
                                    foreach (List <StackValue> lst in clonedList)
                                    {
                                        List <StackValue> newArgs = new List <StackValue>();

                                        newArgs.AddRange(lst);
                                        newArgs[index] = sv;

                                        reducedParams.Add(newArgs);
                                    }
                                }
                            }
                        }
                        else
                        {
                            System.Console.WriteLine("WARNING: Replication unbox requested on Singleton. Trap: 437AD20D-9422-40A3-BFFD-DA4BAD7F3E5F");
                            reducedSV = target;
                        }

                        //reducedType.IsIndexable = false;
                        //reducedParamTypes[index] = reducedSV;
                    }
                }
                else
                {
                    //This should generally be a collection, so we need to do a one phase unboxing
                    int index = ri.CartesianIndex;
                    //This should generally be a collection, so we need to do a one phase unboxing
                    StackValue target    = basicList[index];
                    StackValue reducedSV = StackValue.Null;

                    if (target.IsArray)
                    {
                        //Array arr = formalParams[index].Payload as Array;
                        HeapElement he = ArrayUtils.GetHeapElement(basicList[index], core);



                        //It is a collection, so cast it to an array and pull the type of the first element
                        //@TODO(luke): Deal with sparse arrays, if the first element is null this will explode

                        Validity.Assert(he.Stack != null);

                        //The elements of the array are still type structures
                        if (he.VisibleSize == 0)
                        {
                            reducedSV = StackValue.Null;
                        }
                        else
                        {
                            var arrayStats = ArrayUtils.GetTypeExamplesForLayer(basicList[index], core).Values;

                            List <List <StackValue> > clonedList = new List <List <StackValue> >();

                            foreach (List <StackValue> list in reducedParams)
                            {
                                clonedList.Add(list);
                            }

                            reducedParams.Clear();


                            foreach (StackValue sv in arrayStats)
                            {
                                foreach (List <StackValue> lst in clonedList)
                                {
                                    List <StackValue> newArgs = new List <StackValue>();

                                    newArgs.AddRange(lst);
                                    newArgs[index] = sv;

                                    reducedParams.Add(newArgs);
                                }
                            }
                        }
                    }
                    else
                    {
                        System.Console.WriteLine("WARNING: Replication unbox requested on Singleton. Trap: 437AD20D-9422-40A3-BFFD-DA4BAD7F3E5F");
                        reducedSV = target;
                    }
                }
            }

            return(reducedParams);
        }
        private WatchViewModel ProcessThing(object value, ProtoCore.RuntimeCore runtimeCore, string tag, bool showRawData, WatchHandlerCallback callback, List <string> preferredDictionaryOrdering = null)
        {
            if (value is DesignScript.Builtin.Dictionary || value is IDictionary)
            {
                IEnumerable <string> keys;
                IEnumerable <object> values;
                if (value is DesignScript.Builtin.Dictionary)
                {
                    var dict = value as DesignScript.Builtin.Dictionary;
                    keys   = dict.Keys;
                    values = dict.Values;
                    if (preferredDictionaryOrdering != null && preferredDictionaryOrdering.Count > 1)
                    {
                        keys   = preferredDictionaryOrdering;
                        values = keys.Select(k => dict.ValueAtKey(k));
                    }
                }
                else
                {
                    var dict = value as IDictionary;
                    keys   = dict.Keys.Cast <string>();
                    values = dict.Values.Cast <object>();
                }

                var node = new WatchViewModel(keys.Any() ? WatchViewModel.DICTIONARY : WatchViewModel.EMPTY_DICTIONARY, tag, RequestSelectGeometry, true);

                foreach (var e in keys.Zip(values, (key, val) => new { key, val }))
                {
                    node.Children.Add(ProcessThing(e.val, runtimeCore, tag + ":" + e.key, showRawData, callback));
                }

                return(node);
            }

            if (!(value is string) && value is IEnumerable)
            {
                var list = (value as IEnumerable).Cast <dynamic>().ToList();

                var node = new WatchViewModel(list.Count == 0 ? WatchViewModel.EMPTY_LIST : WatchViewModel.LIST, tag, RequestSelectGeometry, true);
                foreach (var e in list.Select((element, idx) => new { element, idx }))
                {
                    node.Children.Add(callback(e.element, null, runtimeCore, tag + ":" + e.idx, showRawData));
                }

                return(node);
            }

            if (runtimeCore != null && value is StackValue)
            {
                StackValue stackValue  = (StackValue)value;
                string     stringValue = string.Empty;

                if (stackValue.IsFunctionPointer)
                {
                    stringValue = StringUtils.GetStringValue(stackValue, runtimeCore);
                }
                else
                {
                    int typeId = runtimeCore.DSExecutable.TypeSystem.GetType(stackValue);
                    stringValue = runtimeCore.DSExecutable.classTable.ClassNodes[typeId].Name;
                }
                return(new WatchViewModel(stringValue, tag, RequestSelectGeometry));
            }

            if (value is Enum)
            {
                return(new WatchViewModel(((Enum)value).GetDescription(), tag, RequestSelectGeometry));
            }

            return(new WatchViewModel(ToString(value), tag, RequestSelectGeometry));
        }
Beispiel #56
0
        /// <summary>
        /// If an empty array is passed, the result will be null
        /// if there are instances, but they share no common supertype the result will be var
        /// </summary>
        /// <param name="array"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static ClassNode GetGreatestCommonSubclassForArray(StackValue array, Core core)
        {
            if (!StackUtils.IsArray(array))
            {
                throw new ArgumentException("The stack value provided was not an array");
            }

            Dictionary <ClassNode, int> typeStats = GetTypeStatisticsForArray(array, core);


            //@PERF: This could be improved with a
            List <List <int> > chains        = new List <List <int> >();
            HashSet <int>      commonTypeIDs = new HashSet <int>();

            foreach (ClassNode cn in typeStats.Keys)
            {
//<<<<<<< .mine
                List <int> chain = ClassUtils.GetClassUpcastChain(cn, core);

                //Now add in the other conversions - as we don't have a common superclass yet
                //@TODO(Jun): Remove this hack when we have a proper casting structure
                foreach (int id in cn.coerceTypes.Keys)
                {
                    if (!chain.Contains(id))
                    {
                        chain.Add((id));
                    }
                }

//=======
//                List<int> chain = GetConversionChain(cn, core);
//>>>>>>> .r2886
                chains.Add(chain);

                foreach (int nodeId in chain)
                {
                    commonTypeIDs.Add(nodeId);
                }
            }

            //Remove nulls if they exist
            {
                if (commonTypeIDs.Contains(
                        (int)PrimitiveType.kTypeNull))
                {
                    commonTypeIDs.Remove((int)PrimitiveType.kTypeNull);
                }

                List <List <int> > nonNullChains = new List <List <int> >();

                foreach (List <int> chain in chains)
                {
                    if (chain.Contains((int)PrimitiveType.kTypeNull))
                    {
                        chain.Remove((int)PrimitiveType.kTypeNull);
                    }

                    if (chain.Count > 0)
                    {
                        nonNullChains.Add(chain);
                    }
                }

                chains = nonNullChains;
            }


            //Contract the hashset so that it contains only the nodes present in all chains
            //@PERF: this is very inefficent
            {
                foreach (List <int> chain in chains)
                {
                    commonTypeIDs.IntersectWith(chain);
                }
            }

            //No common subtypes
            if (commonTypeIDs.Count == 0)
            {
                return(null);
            }

            if (commonTypeIDs.Count == 1)
            {
                return(core.ClassTable.ClassNodes[commonTypeIDs.First()]);
            }


            List <int> lookupChain = chains[0];


            //Insertion sort the IDs, we may only have a partial ordering on them.
            List <int> orderedTypes = new List <int>();

            foreach (int typeToInsert in commonTypeIDs)
            {
                bool inserted = false;

                for (int i = 0; i < orderedTypes.Count; i++)
                {
                    int orderedType = orderedTypes[i];

                    if (lookupChain.IndexOf(typeToInsert) < lookupChain.IndexOf(orderedType))
                    {
                        inserted = true;
                        orderedTypes.Insert(i, typeToInsert);
                        break;
                    }
                }

                if (!inserted)
                {
                    orderedTypes.Add(typeToInsert);
                }
            }

            return(core.ClassTable.ClassNodes[orderedTypes.First()]);
        }
Beispiel #57
0
        public string PrintClass(StackValue val, Heap heap, int langblock, int maxArraySize, int maxOutputDepth, bool forPrint)
        {
            if (null == formatParams)
                formatParams = new OutputFormatParameters(maxArraySize, maxOutputDepth);

            return GetClassTrace(val, heap, langblock, forPrint);
        }
Beispiel #58
0
        /// <summary>
        /// Simply copy an array.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue CopyArray(StackValue array, Core core)
        {
            Type anyType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, Constants.kArbitraryRank);

            return(CopyArray(array, anyType, core));
        }
Beispiel #59
0
 public override void Execute(SharedObjects shared)
 {
     Structure[] argArray = new Structure[CountRemainingArgs(shared)];
     for (int i = argArray.Length - 1 ; i >= 0 ; --i)
         argArray[i] = PopStructureAssertEncapsulated(shared); // fill array in reverse order because .. stack args.
     AssertArgBottomAndConsume(shared);
     var stackValue = new StackValue(argArray.ToList());
     ReturnValue = stackValue;
 }
Beispiel #60
0
        /// <summary>
        /// Get all values from an array.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue[] GetValues(StackValue array, Core core)
        {
            List <StackValue> values = GetValues <StackValue>(array, core, (StackValue sv) => sv);

            return(values.ToArray());
        }