예제 #1
0
        private PhpTypeCode EmitNodeWrite(CodeGenerator codeGenerator)
        {
            ChainBuilder chain = codeGenerator.ChainBuilder;

            if (chain.IsMember)
            {
                // 1,4,5,6,9
                if (this.isMemberOf != null)
                {
                    // 1:  ...->a->...
                    chain.Lengthen();
                    chain.EmitEnsureProperty(isMemberOf, this, false);
                    return(PhpTypeCode.DObject);
                }
                if (chain.IsArrayItem)
                {
                    // 4,6
                    if (chain.IsLastMember)
                    {
                        // 4: a[][]
                        chain.EmitEnsureVariableIsArray(this);
                    }
                    else
                    {
                        // 6: $b->a[3]
                        ChainBuilder.ObjectFieldLazyEmitInfo object_info = chain.GetObjectForLazyEmit();
                        // Lengthen for hop over ->
                        chain.EmitEnsureProperty(object_info.ObjectForLazyEmit, this, true);
                        chain.ReleaseObjectForLazyEmit(object_info);
                        chain.IsArrayItem  = true;
                        chain.IsLastMember = false;
                    }

                    return(PhpTypeCode.PhpArray);
                }
                if (chain.Exists)
                {
                    // 5: $a->b->c->...
                    chain.EmitEnsureVariableIsObject(this);
                    return(PhpTypeCode.DObject);
                }
                else
                {
                    // 9: $a->b
                    this.EmitLoadAddress(codeGenerator);
                    return(PhpTypeCode.ObjectAddress);
                }
            }
            // 2,3,7,8
            if (this.isMemberOf != null)
            {
                // 2: $b->a
                // 8: b[]->a
                chain.Create();
                chain.Begin();
                assignmentCallback = EmitWriteField(codeGenerator, false);
                // Note: more work is done in EmitAssign

                // some data are preloaded but nothing that can be consumed is loaded on stack:
                return(PhpTypeCode.Unknown);
            }
            // 3,7
            if (codeGenerator.ChainBuilder.IsArrayItem)
            {
                // 3: a[3]
                EmitLoadAddress(codeGenerator);
                return(PhpTypeCode.ObjectAddress);
            }
            else
            {
                // 7: $a
                EmitStorePrepare(codeGenerator);
                return(PhpTypeCode.Unknown);
            }
        }
예제 #2
0
            private PhpTypeCode EmitNodeWrite(IndirectVarUse node, CodeGenerator codeGenerator)
            {
                ChainBuilder chain = codeGenerator.ChainBuilder;

                if (chain.IsMember)
                {
                    // 1,4,5,6,9
                    if (node.IsMemberOf != null)
                    {
                        // 1:  ...->$a->...
                        chain.Lengthen();
                        chain.EmitEnsureProperty(node.IsMemberOf, node, false);
                        return(PhpTypeCode.DObject);
                    }

                    if (chain.IsArrayItem)
                    {
                        // 4,6
                        if (chain.IsLastMember)
                        {
                            // 4: ${"a"}[][]
                            chain.EmitEnsureVariableIsArray(node);
                            return(PhpTypeCode.PhpArray);
                        }
                        else
                        {
                            // 6: $b->${"a"}[3]
                            ChainBuilder.ObjectFieldLazyEmitInfo object_info = chain.GetObjectForLazyEmit();
                            // Lengthen for hop over ->
                            chain.EmitEnsureProperty(object_info.ObjectForLazyEmit, node, true);
                            chain.ReleaseObjectForLazyEmit(object_info);
                            chain.IsArrayItem  = true;
                            chain.IsLastMember = false;
                            return(PhpTypeCode.PhpArray);
                        }
                    }

                    if (chain.Exists)
                    {
                        // 5: $$a->b->c->...
                        chain.EmitEnsureVariableIsObject(node);
                        return(PhpTypeCode.DObject);
                    }
                    else
                    {
                        // 9: $$a->b
                        this.EmitLoadAddress(node, codeGenerator);
                        return(PhpTypeCode.ObjectAddress);
                    }
                }

                // 2,3,7,8
                if (node.IsMemberOf != null)
                {
                    // 2: $b->a
                    // 8: b[]->a
                    chain.Create();
                    chain.Begin();
                    assignmentCallback = EmitWriteField(node, codeGenerator, false);
                    // Note: more work is done in EmitAssign
                    return(PhpTypeCode.Unknown);
                }

                // 3,7
                if (codeGenerator.ChainBuilder.IsArrayItem)
                {
                    // 3: ${"a"}[3]
                    this.EmitLoadAddress(node, codeGenerator);
                    return(PhpTypeCode.ObjectAddress);
                }

                // 7: $a
                //codeGenerator.EmitVariableStorePrepare(this);
                this.EmitStorePrepare(node, codeGenerator);
                return(PhpTypeCode.Unknown);
            }