Example #1
0
        void InitLocalsRefs2(CilType plainType, BoxedType boxedType, bool arg, int index)
        {
            if (arg)
            {
                code.NewInstruction(plainType.LoadOpcode, null, index);
            }
            else
            {
                code.NewInstruction(plainType.InitOpcode, null, null);
            }

            stackMap.PushStack(plainType);

            if (boxedType != null)
            {
                boxedType.BoxValue(code);
            }
            else if (plainType.IsGenericParameter)
            {
                GenericUtil.ValueClone(code);
            }
            else
            {
                CilMethod.ValueMethod(CilMethod.ValueClone, code);
                code.NewInstruction(0xC0 /* checkcast */, plainType, null);
            }

            code.NewInstruction(0x3A /* astore */, null, index);
            stackMap.PopStack(CilMain.Where);
        }
Example #2
0
        public void Length()
        {
            var stackTop = (CilType)stackMap.PopStack(CilMain.Where);

            if (object.ReferenceEquals(stackTop, GenericArrayType))
            {
                // length of a generic array T[]
                code.NewInstruction(0xB8 /* invokestatic */,
                                    new JavaType(0, 0, "java.lang.reflect.Array"),
                                    new JavaMethodRef("getLength", JavaType.IntegerType, JavaType.ObjectType));
            }
            else if (stackTop.IsArray)
            {
                code.NewInstruction(0xBE /* arraylength */, null, null);
            }
            else
            {
                throw new InvalidProgramException();
            }
            stackMap.PushStack(CilType.From(JavaType.IntegerType));
        }
Example #3
0
        void ExceptionClauseSetup(ushort instOffset, CatchClause catchClause)
        {
            // if this is the first exception for the try block:
            //
            // the offset is recorded in the exception attribute, so we need
            // to generate a stack frame for it, which matches the stack frame
            // on entry to the try block, with a pushed java.lang.Throwable.

            var tryClause = catchClause.tryClause;

            if (catchClause == tryClause.catchClauses[0])
            {
                stackMap.LoadFrame((ushort)tryClause.tryStart, false, CilMain.Where);
                stackMap.PushStack(ThrowableType);
                stackMap.SaveFrame((ushort)instOffset, true, CilMain.Where);

                if (!catchClause.finallyClause)
                {
                    code.NewInstruction(0xB8 /* invokestatic */, CilType.SystemUtilType,
                                        new JavaMethodRef("TranslateException",
                                                          ThrowableType, ThrowableType));
                }
            }

            // if this is a finally clause, we have nothing further to do.
            // but if this is a filter clause, do some additional set up.

            if (catchClause.finallyClause)
            {
                if (catchClause.hasNestedTry)
                {
                    // see also:  ScanCatchClauseForNestedTry
                    SaveExceptionObject(tryClause, false);
                }

                if (catchClause.faultClause)
                {
                    // the 'fault' clause should start with a check whether
                    // an exception was thrown, which is very similar to what
                    // 'endfinally' does at the end of a normal 'finally' block,
                    // so we can reuse the same code.
                    Translate_Endfinally(instOffset, true);
                }

                return;
            }

            //
            // if this is a filter clause, we just need to initialize loals
            //

            if (catchClause.filterCondStart != 0)
            {
                // should the filter test pass, we need push the exception
                // object.  we don't know which local the filter test uses
                // to store the exception, so we make our own copy.  this
                // will be loaded by the 'endfilter' instruction, see there.

                SaveExceptionObject(tryClause);

                return;
            }

            //
            // for a non-filter catch clause that catches any kind of
            // exception, we don't need to test the exception type at all
            //

            if (catchClause.catchType.Equals(ThrowableType))
            {
                if (catchClause.includesRethrow)
                {
                    SaveExceptionObject(tryClause);
                }
            }

            //
            // otherwise, we do need to test the exception type, and
            // possibly branch to a secondary catch clause in the chain.
            //

            if (catchClause.catchFromType == null)
            {
                // exception type is plain type.  we will use follow up
                // instructions 'ifeq == zero' and 'ifne != zero',
                // see ExceptionClauseCommon

                if (catchClause.catchType.Equals(ThrowableType))
                {
                    code.NewInstruction(0x04 /* iconst_1 */, null, null);
                    stackMap.PushStack(JavaType.IntegerType);
                }
                else
                {
                    code.NewInstruction(0x59 /* dup */, null, null);
                    stackMap.PushStack(ThrowableType);
                    code.NewInstruction(0xC1 /* instanceof */, catchClause.catchType, null);
                }
            }
            else
            {
                // exception type is a generic type.  we will use follow up
                // instructions 'ifnull' and 'ifnonnnull'.
                // see also below in ExceptionClauseCommon
                code.NewInstruction(0x59 /* dup */, null, null);
                stackMap.PushStack(ThrowableType);
                GenericUtil.CastToGenericType(catchClause.catchFromType, 0, code);
            }

            stackMap.PopStack(CilMain.Where);

            ExceptionClauseCommon(catchClause);
        }