public static int get_order(IntPtr l) { int result; try { DefaultExecutionOrder defaultExecutionOrder = (DefaultExecutionOrder)LuaObject.checkSelf(l); LuaObject.pushValue(l, true); LuaObject.pushValue(l, defaultExecutionOrder.order); result = 2; } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
public static int constructor(IntPtr l) { int result; try { int order; LuaObject.checkType(l, 2, out order); DefaultExecutionOrder o = new DefaultExecutionOrder(order); LuaObject.pushValue(l, true); LuaObject.pushValue(l, o); result = 2; } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
public void Emit() { _returnValue = RootTable.CreateInternalValue(GetTypeSymbol(SpecialType.System_UInt32), "returnJump"); CurrentNode = EmitType.RoslynSymbol.DeclaringSyntaxReferences.First().GetSyntax(); DefaultExecutionOrder executionOrder = EmitType.GetAttribute <DefaultExecutionOrder>(); if (executionOrder != null) { if (executionOrder.order < (int.MinValue + 1000000)) { throw new CompilerException($"Execution orders below int.MinValue + 1000000 are reserved for internal use in U#"); } Module.ExecutionOrder = executionOrder.order; } TypeSymbol udonSharpBehaviourType = GetTypeSymbol(typeof(UdonSharpBehaviour)); Stack <TypeSymbol> emitTypeBases = new Stack <TypeSymbol>(); TypeSymbol currentEmitType = EmitType; while (currentEmitType.BaseType != null) { emitTypeBases.Push(currentEmitType); currentEmitType = currentEmitType.BaseType; if (currentEmitType == udonSharpBehaviourType) { break; } } if (currentEmitType != udonSharpBehaviourType) { throw new NotSupportedException("U# behaviour must inherit from UdonSharpBehaviour", currentEmitType.RoslynSymbol.DeclaringSyntaxReferences.First().GetSyntax().GetLocation()); } List <MethodSymbol> rootMethods = new List <MethodSymbol>(); List <FieldSymbol> userFields = new List <FieldSymbol>(); HashSet <FieldSymbol> visitedFields = new HashSet <FieldSymbol>(); // Visits each base class and searches for the most derived version of a method if it is overriden // The intention with this is to ensure a consistent ordering between all inheritors of a base class // This means that we can know that all inheritors of a class have the same method names and parameter symbol allocations // which allows people to call virtual methods on UdonSharpBehaviours and have Udon just make it work while (emitTypeBases.Count > 0) { TypeSymbol currentBase = emitTypeBases.Pop(); // Make sure fields get emitted foreach (FieldSymbol field in currentBase.GetMembers <FieldSymbol>(this)) { if (field.IsConst) { continue; } if (!visitedFields.Contains(field)) { userFields.Add(field); visitedFields.Add(field); } GetUserValue(field); } foreach (MethodSymbol methodSymbol in currentBase.GetMembers <MethodSymbol>(this)) { if (methodSymbol.RoslynSymbol.IsImplicitlyDeclared || methodSymbol.RoslynSymbol.IsStatic) { continue; } if (methodSymbol.HasOverrides) { MethodSymbol derivedMethod = GetMostDerivedMethod(methodSymbol); if (derivedMethod.RoslynSymbol.IsAbstract) { continue; } if (!rootMethods.Contains(derivedMethod)) { rootMethods.Add(derivedMethod); } } else if (!rootMethods.Contains(methodSymbol)) { if (methodSymbol.RoslynSymbol.IsAbstract) { continue; } rootMethods.Add(methodSymbol); } } } DeclaredFields = userFields.ToImmutableArray(); InitConstFields(); HashSet <MethodSymbol> emittedSet = new HashSet <MethodSymbol>(); HashSet <MethodSymbol> setToEmit = new HashSet <MethodSymbol>(); // Do not roll this into the while loop, the order must be maintained for the root symbols so calls across behaviours work consistently foreach (MethodSymbol methodSymbol in rootMethods) { using (new MethodEmitScope(methodSymbol, this)) { methodSymbol.Emit(this); } emittedSet.Add(methodSymbol); setToEmit.UnionWith(methodSymbol.DirectDependencies.OfType <MethodSymbol>()); } while (setToEmit.Count > 0) { HashSet <MethodSymbol> newEmitSet = new HashSet <MethodSymbol>(); foreach (var methodSymbol in setToEmit) { if (emittedSet.Contains(methodSymbol)) { continue; } if (methodSymbol.RoslynSymbol != null) { if (methodSymbol.RoslynSymbol.IsAbstract || methodSymbol.IsUntypedGenericMethod) { continue; } } if (!methodSymbol.IsStatic && methodSymbol.ContainingType.IsUdonSharpBehaviour) // Prevent other behaviour type's methods from leaking into this type from calls across behaviours { TypeSymbol topType = EmitType; bool foundType = false; while (topType != udonSharpBehaviourType) { if (methodSymbol.ContainingType == topType) { foundType = true; break; } topType = topType.BaseType; } if (!foundType) { continue; } } using (new MethodEmitScope(methodSymbol, this)) { methodSymbol.Emit(this); } emittedSet.Add(methodSymbol); newEmitSet.UnionWith(methodSymbol.DirectDependencies.OfType <MethodSymbol>()); } setToEmit = newEmitSet; } if (_recursiveStackVal != null) { _recursiveStackVal.DefaultValue = new object[_maxRecursiveStackPush]; } DebugInfo.FinalizeAssemblyInfo(); }