internal void EmitLetFnInits(CljILGen ilg, LocalBuilder localBuilder, ObjExpr objx, IPersistentSet letFnLocals) { if (TypeBuilder != null) { // Full compile ilg.Emit(OpCodes.Castclass, TypeBuilder); for (ISeq s = RT.keys(Closes); s != null; s = s.next()) { LocalBinding lb = (LocalBinding)s.first(); if (letFnLocals.contains(lb)) { ClosedOverFieldsMap.TryGetValue(lb, out FieldBuilder fb); Type primt = lb.PrimitiveType; ilg.Emit(OpCodes.Dup); // this if (primt != null) { objx.EmitUnboxedLocal(ilg, lb); ilg.MaybeEmitVolatileOp(IsVolatile(lb)); ilg.Emit(OpCodes.Stfld, fb); } else { objx.EmitLocal(ilg, lb); ilg.MaybeEmitVolatileOp(IsVolatile(lb)); ilg.Emit(OpCodes.Stfld, fb); } } } ilg.Emit(OpCodes.Pop); } }
internal void EmitAssignLocal(CljILGen ilg, LocalBinding lb, Expr val) { if (!IsMutable(lb)) throw new ArgumentException("Cannot assign to non-mutable: ", lb.Name); FieldBuilder fb = null; bool hasField = ClosedOverFieldsMap.TryGetValue(lb, out fb); ilg.Emit(OpCodes.Ldarg_0); // this Type primt = lb.PrimitiveType; if (primt != null) { MaybePrimitiveExpr mbe = val as MaybePrimitiveExpr; if (!(mbe != null && mbe.CanEmitPrimitive)) throw new ArgumentException("Must assign primitive to primitive mutable", lb.Name); mbe.EmitUnboxed(RHC.Expression, this, ilg); } else { val.Emit(RHC.Expression, this, ilg); } if (hasField) { ilg.MaybeEmitVolatileOp(IsVolatile(lb)); ilg.Emit(OpCodes.Stfld, fb); } else ilg.Emit(OpCodes.Stloc, lb.LocalVar); }