private void PerformAssignment(AstNode node, Variable variable) { // Store the value into the variable. if(variable.IsLocal()) { LocalVariable local = (LocalVariable)variable; if(local.IsPseudoLocal) { // Store the closure local. builder.CreateLoadArg(0); builder.CreatePush(1); builder.CreateStoreField((FieldVariable)local.ActualVariable); builder.CreatePop(); } else { builder.CreateStoreLocal(local); } } else if(variable.IsField()) { FieldVariable field = (FieldVariable) variable; if(field.IsStatic()) builder.CreateStoreGlobal(field); else builder.CreateStoreField(field); } else if(variable.IsArraySlot()) { ArraySlot slot = (ArraySlot)variable; builder.CreateStoreArraySlot(slot.GetArrayType()); } else if(variable.IsReferencedSlot() || variable.IsPointedSlot()) { builder.CreateStoreValue(); } else if(variable.IsSwizzleVariable()) { SwizzleVariable swizzle = (SwizzleVariable)variable; if(!swizzle.IsSettable()) Error(node, "cannot set vector members."); builder.CreateStoreSwizzle(swizzle.Components, swizzle.Mask); } else if(variable.IsProperty() || variable.IsDirectPropertySlot()) { // Get the property. PropertyVariable property; bool direct = false; if(variable.IsDirectPropertySlot()) { DirectPropertySlot directProp = (DirectPropertySlot)variable; property = directProp.Property; direct = true; } else { property = (PropertyVariable)variable; } if(property.SetAccessor == null) Error(node, "cannot set property without a set accessor."); Function setAccessor = property.SetAccessor; uint argCount = (uint)setAccessor.GetFunctionType().GetArgumentCount(); if(setAccessor.IsMethod()) { Method method = (Method)setAccessor; if((method.IsOverride() || method.IsVirtual() || method.IsAbstract() || method.IsContract()) && !method.GetParentScope().IsStructure() && !direct) builder.CreateCallVirtual(method, argCount); else builder.CreateCall(method, argCount); } else { builder.CreateCall(setAccessor, argCount); } } else if(variable.IsEvent()) { // Make sure the field is accessible. EventVariable eventVar = (EventVariable)variable; FieldVariable field = eventVar.AssociatedField; if(field == null) Error(node, "cannot invoke/modify custom explicit event."); // Check the field access. CheckMemberVisibility(node, field); // Assign the field. PerformAssignment(node, field); } else Error(node, "unimplemented variable type."); }
private void LoadVariableValue(AstNode where, Variable variable) { if(variable.IsLocal()) { LocalVariable local = (LocalVariable) variable; if(local.IsPseudoLocal) { // Load the variable in the generator closure. builder.CreateLoadArg(0); builder.CreateLoadField((FieldVariable)local.ActualVariable); } else { builder.CreateLoadLocal(local); } } else if(variable.IsArgument()) { ArgumentVariable arg = (ArgumentVariable)variable; if(arg.IsPseudoArgument) { // Load the variable in the generator closure. builder.CreateLoadArg(0); builder.CreateLoadField((FieldVariable)arg.ActualVariable); } else { builder.CreateLoadArg((byte)arg.GetArgumentIndex()); } } else if(variable.IsField()) { FieldVariable field = (FieldVariable) variable; if(field.IsStatic()) builder.CreateLoadGlobal(field); else builder.CreateLoadField(field); } else if(variable.IsArraySlot()) { ArraySlot slot = (ArraySlot)variable; builder.CreateLoadArraySlot(slot.GetArrayType()); } else if(variable.IsReferencedSlot() || variable.IsPointedSlot()) { builder.CreateLoadValue(); } else if(variable.IsTemporalReferencedSlot()) { Error(where, "cannot use here ref/out value."); } else if(variable.IsSwizzleVariable()) { SwizzleVariable swizzle = (SwizzleVariable)variable; builder.CreateLoadSwizzle(swizzle.Components, swizzle.Mask); } else if(variable.IsProperty() || variable.IsDirectPropertySlot()) { PropertyVariable property; bool direct = false; if(variable.IsDirectPropertySlot()) { DirectPropertySlot directProp = (DirectPropertySlot)variable; property = directProp.Property; direct = true; } else { // Cast into a property. property= (PropertyVariable)variable; } // Check the presence of a get accessor. if(property.GetAccessor == null) Error(where, "cannot get value from property without get accessor."); // Use the get accessor. Function getAccessor = property.GetAccessor; uint argCount = (uint)getAccessor.GetFunctionType().GetArgumentCount(); if(getAccessor.IsMethod()) { // Use the correct method invocation. Method method = (Method)getAccessor; if((method.IsOverride() || method.IsVirtual() || method.IsAbstract() || method.IsContract()) && !method.GetParentScope().IsStructure() && !direct) builder.CreateCallVirtual(method, argCount); else builder.CreateCall(method, argCount); } else { builder.CreateCall(getAccessor, argCount); } } else if(variable.IsEvent()) { // Make sure the field is accessible. EventVariable eventVar = (EventVariable)variable; FieldVariable field = eventVar.AssociatedField; if(field == null) Error(where, "cannot invoke/modify custom explicit event."); // Check the field access. CheckMemberVisibility(where, field); // Now, load the field. LoadVariableValue(where, field); } }