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); }
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); } }
internal bool IsVolatile(LocalBinding lb) { return(RT.booleanCast(RT.contains(Fields, lb.Symbol)) && RT.booleanCast(RT.get(lb.Symbol.meta(), Keyword.intern("volatile-mutable")))); }
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); }