コード例 #1
0
 bool IsMutable(LocalBinding lb)
 {
     return(IsVolatile(lb)
            ||
            RT.booleanCast(RT.contains(Fields, lb.Symbol)) &&
            RT.booleanCast(RT.get(lb.Symbol.meta(), Keyword.intern("unsynchronized-mutable")))
            ||
            lb.IsByRef);
 }
コード例 #2
0
        public void DoEmit(RHC rhc, ObjExpr objx, CljILGen ilg, bool emitUnboxed)
        {
            GenContext.EmitDebugInfo(ilg, _sourceSpan);

            Label defaultLabel = ilg.DefineLabel();
            Label endLabel     = ilg.DefineLabel();

            SortedDictionary <int, Label> labels = new SortedDictionary <int, Label>();

            foreach (int i in _tests.Keys)
            {
                labels[i] = ilg.DefineLabel();
            }

            Type primExprType = Compiler.MaybePrimitiveType(_expr);

            if (_testType == _intKey)
            {
                EmitExprForInts(objx, ilg, primExprType, defaultLabel);
            }
            else
            {
                EmitExprForHashes(objx, ilg);
            }

            if (_switchType == _sparseKey)
            {
                Label[] la = labels.Values.ToArray <Label>();
                ilg.Emit(OpCodes.Switch, la);
                ilg.Emit(OpCodes.Br, defaultLabel);
            }
            else
            {
                Label[] la = new Label[(_high - _low) + 1];
                for (int i = _low; i <= _high; i++)
                {
                    la[i - _low] = labels.ContainsKey(i) ? labels[i] : defaultLabel;
                }
                ilg.EmitInt(_low);
                ilg.Emit(OpCodes.Sub);
                ilg.Emit(OpCodes.Switch, la);
                ilg.Emit(OpCodes.Br, defaultLabel);
            }

            foreach (int i in labels.Keys)
            {
                ilg.MarkLabel(labels[i]);
                if (_testType == _intKey)
                {
                    EmitThenForInts(objx, ilg, primExprType, _tests[i], _thens[i], defaultLabel, emitUnboxed);
                }
                else if ((bool)RT.contains(_skipCheck, i))
                {
                    EmitExpr(objx, ilg, _thens[i], emitUnboxed);
                }
                else
                {
                    EmitThenForHashes(objx, ilg, _tests[i], _thens[i], defaultLabel, emitUnboxed);
                }
                if (_thens[i].HasNormalExit())
                {
                    ilg.Emit(OpCodes.Br, endLabel);
                }
            }
            ilg.MarkLabel(defaultLabel);
            EmitExpr(objx, ilg, _defaultExpr, emitUnboxed);
            ilg.MarkLabel(endLabel);
            if (rhc == RHC.Statement)
            {
                ilg.Emit(OpCodes.Pop);
            }
        }
コード例 #3
0
 internal bool IsVolatile(LocalBinding lb)
 {
     return(RT.booleanCast(RT.contains(Fields, lb.Symbol)) &&
            RT.booleanCast(RT.get(lb.Symbol.meta(), Keyword.intern("volatile-mutable"))));
 }
コード例 #4
0
        Expression GenCode(RHC rhc, ObjExpr objx, GenContext context, bool genUnboxed)
        {
            Type retType = HasClrType ? ClrType : typeof(object);

            LabelTarget defaultLabel = Expression.Label("default");
            LabelTarget endLabel     = Expression.Label(retType, "end");

            Type primExprType = Compiler.MaybePrimitiveType(_expr);

            List <SwitchCase> cases = new List <SwitchCase>();

            foreach (KeyValuePair <int, Expr> pair in _tests)
            {
                int  i    = pair.Key;
                Expr test = pair.Value;

                Expression testExpr;

                if (_testType == _intKey)
                {
                    testExpr = GenTestForInts(objx, context, primExprType, test, genUnboxed);
                }
                else if (RT.booleanCast(RT.contains(_skipCheck, i)))
                {
                    testExpr = Expression.Constant(true, typeof(Boolean));
                }
                else
                {
                    testExpr = GenTestForHashes(objx, context, test, genUnboxed);
                }

                Expression result = GenResult(objx, context, _thens[i], genUnboxed, retType);

                Expression body =
                    Expression.Condition(
                        testExpr,
                        Expression.Return(endLabel, result),
                        Expression.Goto(defaultLabel));

                cases.Add(Expression.SwitchCase(body, Expression.Constant(i)));
            }


            Expression switchTestExpr = _testType == _intKey
                ? GenTestExprForInts(objx, context, primExprType, defaultLabel)
                : GenTestExprForHashes(objx, context);


            Expression defaultExpr =
                Expression.Block(
                    Expression.Label(defaultLabel),
                    Expression.Return(endLabel, GenResult(objx, context, _defaultExpr, genUnboxed, retType)));

            Expression switchExpr = switchTestExpr is GotoExpression
                ? defaultExpr // we know the test fails, the test code is GOTO(default)
                : Expression.Switch(switchTestExpr, Expression.Goto(defaultLabel), cases.ToArray <SwitchCase>());


            Expression block =
                Expression.Block(retType,
                                 switchExpr,
                                 defaultExpr,
                                 Expression.Label(endLabel, Expression.Default(retType)));

            block = Compiler.MaybeAddDebugInfo(block, _sourceSpan, context.IsDebuggable);
            return(block);
        }