//===================================================================================================================== void visitMethodImpl(MethodImpl *p) { inMethod = true; fprintf(m_outputfile, "######## METHOD\n"); // Create function label from class name and method name const char* funcname = dynamic_cast<MethodIDImpl*>(p->m_methodid)->m_symname->spelling(); fprintf(m_outputfile, "%s_%s:\n", currClassName, funcname); // Prologue - Push old ebp to stack, update ebp to current stack pointer fprintf(m_outputfile, " pushl %%ebp\n"); fprintf(m_outputfile, " movl %%esp, %%ebp\n"); // Set offset tables assert(m_classtable->exist(currClassName)); ClassNode* node = m_classtable->lookup(currClassName); currClassOffset = node->offset; currMethodOffset = new OffsetTable(); currMethodOffset->setTotalSize(4); // make space in table for %ebp // Add function to classnode's scope node->scope->insert(funcname, new Symbol()); assert(node->scope->exist(funcname)); // Iterate through parameters, saving to offset table list<Parameter_ptr> *l = p->m_parameter_list; list<Parameter_ptr>::iterator it; OffsetTable* table = currMethodOffset; ParameterImpl* param; Parameter_ptr ptr; int varSize = 4; int curroffset = 12; // leave space for return address and the 'this object' pointer for(it=l->begin(); it!=l->end(); ++it) { ptr = (Parameter_ptr)*it; param = dynamic_cast<ParameterImpl*> (ptr); table->insert(dynamic_cast<VariableIDImpl*>(param->m_variableid)->m_symname->spelling(), curroffset, varSize, param->m_type->m_attribute.m_type.classType); curroffset += varSize; } // Visit the children p->visit_children(this); // Epilogue - deallocate locals, set ebp to old ebp, return curroffset = currMethodOffset->getTotalSize(); fprintf(m_outputfile, " addl $%i, %%esp\n", curroffset-4); // everything but old ebp fprintf( m_outputfile," leave\n"); fprintf( m_outputfile," ret\n"); fprintf(m_outputfile, "########\n"); // Dereference the local offset table currMethodOffset == NULL; inMethod = false; }
//===================================================================================================================== void visitDeclarationImpl(DeclarationImpl *p) { fprintf(m_outputfile, "#### DECLARATION\n"); // Visit the children p->visit_children(this); // Get type and decide on allocated size Basetype type = p->m_type->m_attribute.m_type.baseType; assert(type == bt_boolean || type == bt_integer || type == bt_object); int varSize = 4; // Iterate through list of variables, allocating and inserting into offset table list<VariableID_ptr> *l = p->m_variableid_list; list<VariableID_ptr>::iterator it; OffsetTable* table; bool isClassDec; int offsetDir; if(inMethod) { table = currMethodOffset; isClassDec = false; offsetDir = -1; } else{ table = currClassOffset; isClassDec = true; offsetDir = 1; } VariableIDImpl* var; VariableID_ptr ptr; int curroffset; for(it=l->begin(); it!=l->end(); ++it) { ptr = (VariableID_ptr)*it; var = dynamic_cast<VariableIDImpl*> (ptr); // Allocate space in stack/heap if not a class declaration if(type == bt_object && !isClassDec) { const char* c = p->m_type->m_attribute.m_type.classType.classID; assert(c != ""); assert(m_classtable->exist(c)); ClassNode* node = m_classtable->lookup(c); fprintf( m_outputfile, " pushl %s\n",heapTop); // push current heap top to stack as pointer to obj fprintf( m_outputfile, " addl $%d, %s\n",node->offset->getTotalSize(),heapTop); // allocate in heap } else if(!isClassDec) { fprintf(m_outputfile, " subl $%i, %%esp\n", varSize); } // Insert into and update offset table curroffset = table->getTotalSize(); table->insert(var->m_symname->spelling(), offsetDir*curroffset, varSize, p->m_type->m_attribute.m_type.classType); //fprintf( m_outputfile, "%i, %i, %i, %i\n", inMethod, offsetDir, curroffset, varSize); table->setTotalSize(offsetDir*(offsetDir*curroffset+offsetDir*varSize)); } fprintf(m_outputfile, "####\n"); }