//===================================================================================================================== void visitAssignment(Assignment *p) { fprintf(m_outputfile, "#### ASSIGN\n"); // Visit the children p->visit_children(this); // Look up variable offset in offset table OffsetTable* table = currMethodOffset; bool inClass = false; const char* name = dynamic_cast<VariableIDImpl*>(p->m_variableid)->m_symname->spelling(); if(!table->exist(name)) {table = currClassOffset; inClass = true;} assert(table->exist(name)); int offset = table->get_offset(name); // Pop from stack and save to either stack or heap if(!inClass) { fprintf(m_outputfile, " popl %%eax\n"); fprintf(m_outputfile, " movl %%eax, %i(%%ebp)\n", offset); } else { fprintf(m_outputfile, " popl %%eax\n"); fprintf(m_outputfile, " movl 8(%%ebp), %%ebx\n"); fprintf(m_outputfile, " movl %%eax, %i(%%ebx)\n", offset); } fprintf(m_outputfile, "####\n"); }
//===================================================================================================================== void visitMethodCall(MethodCall *p) { fprintf(m_outputfile, "#### METHC\n"); // Visit variable and method name p->m_methodid->accept(this); p->m_variableid->accept(this); // Grab variable's classname (for jump label) from offset table OffsetTable* table = currMethodOffset; bool inClass=false; const char* varname = dynamic_cast<VariableIDImpl*>(p->m_variableid)->m_symname->spelling(); if(!table->exist(varname)) {table = currClassOffset; inClass=true;} assert(table->exist(varname)); CompoundType type = table->get_type(varname); const char* name; name = type.classID; // Visit parameters in reverse order, so their results will end up on the stack in x86 convention order int numparams = 0; list<Expression_ptr> *l = p->m_expression_list; list<Expression_ptr>::iterator it; Expression* exp; Expression_ptr ptr; for(it=l->end(); it!=l->begin();) { --it; ptr = (Expression_ptr)*it; exp = dynamic_cast<Expression*> (ptr); exp->accept(this); numparams++; } // Push referenced object's pointer to stack as final parameter if(!inClass) { fprintf( m_outputfile, " pushl %i(%%ebp)\n", table->get_offset(varname)); } else { fprintf( m_outputfile, " movl 8(%%ebp), %%ebx\n"); fprintf( m_outputfile, " pushl %i(%%ebx)\n", table->get_offset(varname)); } numparams++; // Find class/superclass that contains the function const char* funcname = dynamic_cast<MethodIDImpl*>(p->m_methodid)->m_symname->spelling(); ClassNode* node = m_classtable->lookup(name); assert(node!=NULL); while(!(node->scope->exist(funcname))) { assert(node->superClass != NULL); node = m_classtable->lookup(node->superClass); } // Call the function fprintf(m_outputfile, " call %s_%s\n", node->name->spelling(), funcname); // Clean up parameters fprintf(m_outputfile, " addl $%i, %%esp\n", numparams*4); // Push return value fprintf(m_outputfile, " pushl %%ebx\n"); fprintf(m_outputfile, "####\n"); }
//===================================================================================================================== void visitVariable(Variable *p) { fprintf(m_outputfile, "## VAR\n"); // Visit the children p->visit_children(this); // Look up variable offset and type in offset table OffsetTable* table = currMethodOffset; bool inClass=false; const char* name = dynamic_cast<VariableIDImpl*>(p->m_variableid)->m_symname->spelling(); if(!table->exist(name)) {table = currClassOffset; inClass=true;} assert(table->exist(name)); int offset = table->get_offset(name); // Push from either stack or heap, depending on where variable is located if(!inClass) fprintf(m_outputfile, " pushl %i(%%ebp)\n", offset); else { fprintf(m_outputfile, " mov 8(%%ebp), %%eax\n", offset); fprintf(m_outputfile, " pushl %i(%%eax)\n", offset); } fprintf(m_outputfile, "##\n"); }