public void EmitTryGetNonInheritedValue(CodeGen cg, Slot valueOut) { typeSlot.EmitGet(cg); cg.EmitCall(typeof(UserType), "GetNamespaceDictionary"); cg.EmitInt(index); valueOut.EmitGetAddr(cg); cg.EmitCall(typeof(NamespaceDictionary), "TryGetNonInheritedValue"); }
public void EmitIndirectedSymbol(CodeGen cg, SymbolId id) { Slot value; if (!indirectSymbolIds.TryGetValue(id, out value)) { // create field, emit fix-up... value = AddStaticField(typeof(int), "symbol_" + SymbolTable.IdToString(id)); CodeGen init = GetOrMakeInitializer(); Slot localTmp = init.GetLocalTmp(typeof(SymbolId)); init.EmitString((string)SymbolTable.IdToString(id)); init.EmitCall(typeof(SymbolTable), "StringToId"); localTmp.EmitSet(init); localTmp.EmitGetAddr(init); init.EmitFieldGet(typeof(SymbolId), "Id"); value.EmitSet(init); cg.FreeLocalTmp(localTmp); indirectSymbolIds[id] = value; } value.EmitGet(cg); }
public override void EmitSet(CodeGen cg) { // Disallow "[] = l", "[], a = l, l", "[[]] = [l]", etc if (items.Length == 0) { cg.Context.AddError("can't assign to " + EmptySequenceString, this); return; } // int leftCount = items.Length; Slot leftCount = cg.GetLocalTmp(typeof(int)); cg.EmitInt(items.Length); leftCount.EmitSet(cg); // object[] values = new object[leftCount]; Slot values = cg.GetLocalTmp(typeof(object[])); leftCount.EmitGet(cg); cg.Emit(OpCodes.Newarr, typeof(object)); values.EmitSet(cg); // ie = Ops.GetEnumerator(<value on stack>) Slot ie = cg.GetLocalTmp(typeof(IEnumerator)); cg.EmitCall(typeof(Ops), "GetEnumerator"); ie.EmitSet(cg); // int rightCount = Ops.GetEnumeratorValues(ie, ref values); Slot rightCount = cg.GetLocalTmp(typeof(int)); ie.EmitGet(cg); values.EmitGetAddr(cg); cg.EmitCall(typeof(Ops), "GetEnumeratorValues"); rightCount.EmitSet(cg); // if (leftCount != rightCount) // throw Ops.ValueErrorForUnpackMismatch(leftCount, rightCount); Label equalSizes = cg.DefineLabel(); leftCount.EmitGet(cg); rightCount.EmitGet(cg); cg.Emit(OpCodes.Ceq); cg.Emit(OpCodes.Brtrue_S, equalSizes); leftCount.EmitGet(cg); rightCount.EmitGet(cg); cg.EmitCall(typeof(Ops).GetMethod("ValueErrorForUnpackMismatch")); cg.Emit(OpCodes.Throw); cg.MarkLabel(equalSizes); // for (int i = 0; i < leftCount; i++) // items[i].Assign(values[i], env); int i = 0; foreach (Expr expr in items) { values.EmitGet(cg); cg.EmitInt(i++); cg.Emit(OpCodes.Ldelem_Ref); expr.EmitSet(cg); } cg.FreeLocalTmp(leftCount); cg.FreeLocalTmp(rightCount); cg.FreeLocalTmp(values); cg.FreeLocalTmp(ie); }
public override void EmitGetAddr(CodeGen cg) { attribute.EmitGetAddr(cg); }