Exemple #1
0
    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);
    }
Exemple #2
0
    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);
    }
Exemple #3
0
        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();
        }