Esempio n. 1
0
 internal void CompileTopLevelEntity(ParserContext parser, ByteBuffer buffer, TopLevelEntity entity)
 {
     if (entity is FunctionDefinition)
     {
         FunctionDefinitionEncoder.Compile(this, parser, buffer, (FunctionDefinition)entity, false);
     }
     else if (entity is ClassDefinition)
     {
         this.CompileClass(parser, buffer, (ClassDefinition)entity);
     }
     else
     {
         throw new NotImplementedException("Invalid target for byte code compilation");
     }
 }
Esempio n. 2
0
        private void CompileClass(ParserContext parser, ByteBuffer buffer, ClassDefinition classDefinition)
        {
            bool hasStaticFieldsWithStartingValues = classDefinition.Fields
                                                     .Where(fd =>
                                                            fd.Modifiers.HasStatic &&
                                                            fd.DefaultValue != null &&
                                                            !(fd.DefaultValue is NullConstant))
                                                     .Count() > 0;

            if (hasStaticFieldsWithStartingValues)
            {
                if (classDefinition.StaticConstructor == null)
                {
                    classDefinition.StaticConstructor = new ConstructorDefinition(null, ModifierCollection.CreateStaticModifier(classDefinition.FirstToken), new AnnotationCollection(parser), classDefinition);
                    classDefinition.StaticConstructor.Resolve(parser);
                }

                List <Executable> staticFieldInitializers = new List <Executable>();
                foreach (FieldDefinition fd in classDefinition.Fields)
                {
                    if (fd.Modifiers.HasStatic && fd.DefaultValue != null && !(fd.DefaultValue is NullConstant))
                    {
                        FieldReference fieldRef = new FieldReference(fd.FirstToken, fd, fd);
                        fieldRef.ResolvedType = fd.ResolvedFieldType;
                        Executable assignment = new Assignment(
                            fieldRef,
                            null,
                            fd.NameToken,
                            Ops.EQUALS,
                            fd.DefaultValue,
                            fd);
                        staticFieldInitializers.Add(assignment);
                    }
                }

                staticFieldInitializers.AddRange(classDefinition.StaticConstructor.Code);
                classDefinition.StaticConstructor.Code = staticFieldInitializers.ToArray();
            }

            if (classDefinition.StaticConstructor != null)
            {
                // All static field initializers are added here.
                ConstructorDefinitionEncoder.Compile(this, parser, buffer, classDefinition.StaticConstructor, null);
            }

            foreach (FunctionDefinition fd in classDefinition.Methods)
            {
                int pc = buffer.Size;
                fd.FinalizedPC = pc;
                FunctionDefinitionEncoder.Compile(this, parser, buffer, fd, true);
            }

            int classId             = classDefinition.ClassID;
            int baseClassId         = classDefinition.BaseClass != null ? classDefinition.BaseClass.ClassID : -1;
            int nameId              = parser.GetId(classDefinition.NameToken.Value);
            int constructorId       = classDefinition.Constructor.FunctionID;
            int staticConstructorId = classDefinition.StaticConstructor != null ? classDefinition.StaticConstructor.FunctionID : -1;

            int staticFieldCount = classDefinition.Fields.Where <FieldDefinition>(fd => fd.Modifiers.HasStatic).Count();

            FieldDefinition[]      regularFields           = classDefinition.Fields.Where <FieldDefinition>(fd => !fd.Modifiers.HasStatic).ToArray();
            FunctionDefinition[]   regularMethods          = classDefinition.Methods.Where <FunctionDefinition>(fd => !fd.Modifiers.HasStatic).ToArray();
            List <int>             members                 = new List <int>();
            List <FieldDefinition> fieldsWithComplexValues = new List <FieldDefinition>();

            foreach (FieldDefinition fd in regularFields)
            {
                int memberId    = fd.MemberID;
                int fieldNameId = parser.GetId(fd.NameToken.Value);
                int initInstruction;
                int literalId = 0;

                // TODO: get rid of init instruction since everything is just 0 now.
                initInstruction = 0;
                literalId       = parser.GetLiteralId(fd.DefaultValue);
                if (literalId == -1)
                {
                    literalId = parser.GetNullConstant();
                    fieldsWithComplexValues.Add(fd);
                }

                members.AddRange(new int[] {
                    0, // flag for field
                    memberId,
                    fieldNameId,
                    initInstruction,
                    literalId,
                    EncodeAccessModifier(fd.Modifiers)
                });
            }

            foreach (FunctionDefinition fd in regularMethods)
            {
                int memberId     = fd.MemberID;
                int methodNameId = parser.GetId(fd.NameToken.Value);
                int functionId   = fd.FunctionID;

                members.AddRange(new int[] {
                    1, // flag for method
                    memberId,
                    methodNameId,
                    functionId,
                    0, // ignored value.
                    EncodeAccessModifier(fd.Modifiers),
                });
            }

            ByteBuffer initializer = new ByteBuffer();

            if (fieldsWithComplexValues.Count > 0)
            {
                foreach (FieldDefinition complexField in fieldsWithComplexValues)
                {
                    this.CompileExpression(parser, initializer, complexField.DefaultValue, true);
                    initializer.Add(complexField.FirstToken, OpCode.ASSIGN_THIS_FIELD, complexField.MemberID);
                }
            }

            ConstructorDefinitionEncoder.Compile(this, parser, buffer, classDefinition.Constructor, initializer);

            List <int> args = new List <int>()
            {
                classId,
                baseClassId,
                nameId,
                constructorId,
                staticConstructorId,
                staticFieldCount,
                classDefinition.CompilationScope.ScopeNumId,
            };

            args.AddRange(members);

            string fullyQualifiedName = classDefinition.GetFullyQualifiedLocalizedName(parser.RootScope.Locale);

            buffer.Add(classDefinition.FirstToken, OpCode.CLASS_DEFINITION, fullyQualifiedName, args.ToArray());
            foreach (FieldDefinition fd in classDefinition.Fields)
            {
                if (fd.ResolvedFieldType != parser.TypeContext.ANY && !fd.Modifiers.HasStatic)
                {
                    List <int> typeArgs = new List <int>();
                    typeArgs.Add(classDefinition.ClassID);
                    typeArgs.Add(fd.MemberID);
                    // TODO: change the last boolean to an enum to include behavior for not including FLOAT/INT conversion info
                    CastEncoder.EncodeTypeInfoToIntBuffer(typeArgs, fd.ResolvedFieldType, false);
                    buffer.Add(null, OpCode.FIELD_TYPE_INFO, typeArgs.ToArray());
                }
            }
        }