//=====================================================================================================================
  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 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");
  }
Esempio n. 4
0
  void visitVariable(Variable *p) {
    //get value put in eax and push
      VariableIDImpl * VarId = dynamic_cast<VariableIDImpl*>(p->m_variableid);
      char * varName = strdup(VarId->m_symname->spelling());
      fprintf( m_outputfile, " movl %d(%%ebp) , %%eax\n",currMethodOffset->get_offset(varName));
      fprintf( m_outputfile, " pushl %%eax\n");

      p->visit_children(this);
         // WRITEME

  }
  //=====================================================================================================================
  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");
  }
Esempio n. 7
0
  void visitAssignment(Assignment *p) {
      fprintf( m_outputfile, "#### ASSIGNMENT\n");

// cout<<"Before assignment@@@@@@@@@@@@@@@@@@@@@@ "<<endl;
      p->visit_children(this);
// cout<<"AFTER assignment$$$$$$$$$$$$$$$$$$$$$$$$ "<<endl;
      VariableIDImpl * VarId = dynamic_cast<VariableIDImpl*>(p->m_variableid);
      char * varName = strdup(VarId->m_symname->spelling());
      // fprintf( m_outputfile, " popl %%eax\n");

      fprintf( m_outputfile, " movl %%eax , %d(%%ebp)\n",currMethodOffset->get_offset(varName));
      


         // WRITEME

  }
Esempio n. 8
0
  void visitMethodImpl(MethodImpl *p) {
    fprintf( m_outputfile, "#### METHOD IMPLEMENTATION\n");
    int localSpace, args, mem;
    int j=0;
    int methMem = 0;
    CompoundType info;
    currMethodOffset = new OffsetTable();
// cout<<"before my childen"<<endl;

//this is to make the label name
    Symbol * symbP;
    SymScope * sync;
    MethodIDImpl * MethIdP = dynamic_cast<MethodIDImpl*>(p->m_methodid);
    char * funcName = strdup(MethIdP->m_symname->spelling());
    sync = m_symboltable->get_current_scope();
    symbP = sync->lookup((const char *)"xxx");
    char * classMethName = strdup(symbP->classType.classID);
    strcat(classMethName,"_");
    strcat(classMethName,funcName);
    fprintf( m_outputfile, "_%s:\n",classMethName);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    fprintf( m_outputfile, " pushl %%ebp\n");
    fprintf( m_outputfile, " movl %%esp , %%ebp\n");
    MethodBodyImpl * MethBodP = dynamic_cast<MethodBodyImpl*>(p->m_methodbody);
    localSpace = (p->m_parameter_list->size() + MethBodP->m_declaration_list->size());

    localSpace = localSpace * wordsize;
    // currMethodOffset->insert(classMethName, localSpace, 4,symbP->classType);
    currMethodOffset->setTotalSize(localSpace);
    currMethodOffset->setParamSize(p->m_parameter_list->size() * wordsize);

//### inserting paramaters into the offset table ###########
    for (std::list<Parameter_ptr>::iterator it = p->m_parameter_list->begin() ; it != p->m_parameter_list->end(); ++it){
    ParameterImpl * param = dynamic_cast<ParameterImpl*>(*it);
      VariableIDImpl * VarId = dynamic_cast<VariableIDImpl*>(param->m_variableid);

      info.baseType = param->m_type->m_attribute.m_type.baseType; 
      if(info.baseType == 8){ 
        info.classID = param->m_type->m_attribute.m_type.classType.classID;
        }
      else{
        info.classID = "NO CLASS";
        }
        methMem -= 4;
// cout<<"Offset-> symname: "<<VarId->m_symname->spelling()<<" offset: "<<methMem<<" class type: " <<info.baseType<<endl;
      currMethodOffset->insert(VarId->m_symname->spelling(), methMem, 4,info);
      
    }
//################################  

      

//<><>Diving into Declaration <><><><>><><><><><><><><><><><>><><><><><><
       typename std::list<Declaration_ptr>::iterator it = MethBodP->m_declaration_list->begin();
       for( ; it != MethBodP->m_declaration_list->end(); ++it) {
          DeclarationImpl * DeclaP = dynamic_cast<DeclarationImpl *> (*it);
          typename std::list<VariableID_ptr>::iterator it = DeclaP->m_variableid_list->begin();
          for( ; it != DeclaP->m_variableid_list->end(); ++it) {
            methMem -= 4; // need to move to the next offset
            VariableIDImpl * VarIdP = dynamic_cast<VariableIDImpl*>(*it);
            char * var = strdup(VarIdP->m_symname->spelling());
 // cout<<"Offset-> symname: "<<var<<" Offset: "<<methMem<<" Class type: " <<endl;
            info.baseType = DeclaP->m_type->m_attribute.m_type.baseType; 
            if(info.baseType == 8){ 
              info.classID = DeclaP->m_type->m_attribute.m_type.classType.classID;
              }
            else{
              info.classID = "NO CLASS";
              }
            currMethodOffset->insert(var, methMem, 4,info);

           }

        }
//<><><><><><><><><><><><><><><><><>><><><><><><
//~~~~ allocating space on the stack and  moves parameters into local ~~~~~~   

// cout<<"param size: "<<currMethodOffset->getParamSize()<<endl;
// cout<<" LocalSpace: "<< -(methMem)<<endl;

  fprintf( m_outputfile, " subl $%d, %%esp\n",-(methMem));
   mem = -4;
   for(int i = currMethodOffset->getParamSize() + 4; i>= 8; i = i-4){
     
      fprintf( m_outputfile, " movl %d(%%ebp) , %%eax\n",i);
      fprintf( m_outputfile, " movl %%eax , %d(%%ebp)\n",mem);
      mem -= 4;
      // symbP->methodType.argsType[j].baseType;
     }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


     p->visit_children(this);
// cout<<"after the children"<<endl;
    fprintf( m_outputfile, " leave\n");
    fprintf( m_outputfile, " ret\n");  
         // WRITEME
  }
TEST_F(OffsetTableUnittest, Checksum)
{
    // Assert that checksum computation is correct
    const double data[4] = { 3.14, 456.1, 25.3, 0.000012 };
    const std::string checksum = computeChecksum(data, 4*sizeof(double));
    const std::string checksum_ref = "39DA3F5AEE8A68A8B5083E9BCBB252069EFE223BFCA28AEE7CD3BC49F8379C7";
    ASSERT_EQ(checksum_ref, checksum);

    // Define some savepoints
    Savepoint sp0, sp1;
    sp0.Init("FastWavesUnittest.Divergence-in");
    sp0.AddMetainfo("LargeTimeStep", 1);
    sp0.AddMetainfo("RKStageNumber", 2);
    sp0.AddMetainfo("ldyn_bbc", false);
    sp1.Init("DycoreUnittest.DoStep-out");
    sp1.AddMetainfo("LargeTimeStep", 2);
    sp1.AddMetainfo("hd", (Real).5);

    // Test that offset table recognizes checksums
    OffsetTable table;
    table.AddNewSavepoint(sp0, 0);
    table.AddNewSavepoint(sp1, 1);
    int offset;

    ASSERT_EQ(-1, offset = table.AlreadySerialized("Field1", computeChecksum(data, 4)));
    ASSERT_NO_THROW(table.AddFieldRecord(0, "Field1",   0, computeChecksum(data, 4)));
    ASSERT_EQ(-1, offset = table.AlreadySerialized("Field1", computeChecksum(data, 8)));
    ASSERT_NO_THROW(table.AddFieldRecord(1, "Field1", 100, computeChecksum(data, 8)));
    ASSERT_EQ(-1, offset = table.AlreadySerialized("Field2", computeChecksum(data, 8)));
    ASSERT_NO_THROW(table.AddFieldRecord(0, "Field2", 200, computeChecksum(data, 8)));

    ASSERT_EQ(  0, table.AlreadySerialized("Field1", computeChecksum(data,4)));
    ASSERT_EQ(100, table.AlreadySerialized("Field1", computeChecksum(data,8)));
    ASSERT_EQ(200, table.AlreadySerialized("Field2", computeChecksum(data,8)));
    ASSERT_NO_THROW(table.AddFieldRecord(1, "Field2", 200, computeChecksum(data, 8)));

    ASSERT_EQ(  0, table.GetOffset(sp0, "Field1"));
    ASSERT_EQ(100, table.GetOffset(sp1, "Field1"));
    ASSERT_EQ(200, table.GetOffset(sp0, "Field2"));
    ASSERT_EQ(200, table.GetOffset(sp1, "Field2"));
}
TEST_F(OffsetTableUnittest, TableToJSON)
{
    Savepoint sp0, sp1;
    sp0.Init("FastWavesUnittest.Divergence-in");
    sp0.AddMetainfo("LargeTimeStep", 1);
    sp0.AddMetainfo("RKStageNumber", 2);
    sp0.AddMetainfo("ldyn_bbc", false);
    sp1.Init("DycoreUnittest.DoStep-out");
    sp1.AddMetainfo("LargeTimeStep", 2);
    sp1.AddMetainfo("hd", (Real).5);

    // Just for the sake of getting some valid checksums
    double somedata[] = { 1.1, 2.2, 3.3, 4.4 };

    // Fill table
    OffsetTable table;
    ASSERT_NO_THROW(table.AddNewSavepoint(sp0, 0));
    ASSERT_NO_THROW(table.AddNewSavepoint(sp1, 1));
    ASSERT_NO_THROW(table.AddFieldRecord(sp0, "Field1",   0, computeChecksum(somedata, 4)));
    ASSERT_NO_THROW(table.AddFieldRecord(  0, "Field2",   0, computeChecksum(somedata, 8)));
    ASSERT_NO_THROW(table.AddFieldRecord(  1, "Field1", 100, computeChecksum(somedata, 12)));
    ASSERT_NO_THROW(table.AddFieldRecord(sp1, "Field2", 100, computeChecksum(somedata, 16)));

    //Generate table JSON
    JSONNode tableNode = table.TableToJSON();
    ASSERT_EQ(JSON_ARRAY, tableNode.type());
    ASSERT_EQ(2, tableNode.size());

    // Check first savepoint
    ASSERT_EQ(std::string("FastWavesUnittest.Divergence-in"), tableNode[0]["__name"].as_string());
    ASSERT_EQ(0, tableNode[0]["__id"].as_int());
    ASSERT_EQ(1, tableNode[0]["LargeTimeStep"].as_int());
    ASSERT_EQ(2, tableNode[0]["RKStageNumber"].as_int());
    ASSERT_FALSE(tableNode[0]["ldyn_bbc"].as_bool());
    ASSERT_EQ((int)JSON_ARRAY, (int)tableNode[0]["__offsets"][0].type());
    ASSERT_EQ(std::string("Field1"), tableNode[0]["__offsets"][0].name());
    ASSERT_EQ(0, tableNode[0]["__offsets"][0][0].as_int());
    ASSERT_EQ(computeChecksum(somedata, 4), tableNode[0]["__offsets"][0][1].as_string());
    ASSERT_EQ(0, tableNode[0]["__offsets"][1][0].as_int());
    ASSERT_EQ(computeChecksum(somedata, 8), tableNode[0]["__offsets"][1][1].as_string());

    // Check second savepoint
    ASSERT_EQ(std::string("DycoreUnittest.DoStep-out"), tableNode[1]["__name"].as_string());
    ASSERT_EQ(1, tableNode[1]["__id"].as_int());
    ASSERT_EQ(2, tableNode[1]["LargeTimeStep"].as_int());
    ASSERT_EQ(0.5, tableNode[1]["hd"].as_float());
    ASSERT_EQ((int)JSON_ARRAY, (int)tableNode[1]["__offsets"][0].type());
    ASSERT_EQ(std::string("Field1"), tableNode[1]["__offsets"][0].name());
    ASSERT_EQ(100, tableNode[1]["__offsets"][0][0].as_int());
    ASSERT_EQ(computeChecksum(somedata, 12), tableNode[1]["__offsets"][0][1].as_string());
    ASSERT_EQ(100, tableNode[1]["__offsets"][1][0].as_int());
    ASSERT_EQ(computeChecksum(somedata, 16), tableNode[1]["__offsets"][1][1].as_string());

    // Interpret JSON for table
    OffsetTable table2;
    table2.TableFromJSON(tableNode);

    // Check savepoints
    std::vector<Savepoint> const & sp = GetSavepoints(table2);
    ASSERT_EQ(2, sp.size());
    ASSERT_EQ(sp0, sp[0]);
    ASSERT_EQ(sp1, sp[1]);
    ASSERT_EQ(0, table2.GetSavepointID(sp[0]));
    ASSERT_EQ(1, table2.GetSavepointID(sp[1]));

    // Check methods
    ASSERT_EQ(  0, table2.GetOffset(sp0, "Field1"));
    ASSERT_EQ(  0, table2.GetOffset(sp0, "Field2"));
    ASSERT_EQ(100, table2.GetOffset(sp1, "Field1"));
    ASSERT_EQ(100, table2.GetOffset(sp1, "Field2"));
    ASSERT_EQ(  0, table2.AlreadySerialized("Field1", computeChecksum(somedata, 4)));
    ASSERT_EQ(100, table2.AlreadySerialized("Field1", computeChecksum(somedata, 12)));
    ASSERT_EQ(  0, table2.AlreadySerialized("Field2", computeChecksum(somedata, 8)));
    ASSERT_EQ(100, table2.AlreadySerialized("Field2", computeChecksum(somedata, 16)));
    ASSERT_EQ( -1, table2.AlreadySerialized("Field1", computeChecksum(somedata, 8)));
    ASSERT_EQ( -1, table2.AlreadySerialized("Field2", computeChecksum(somedata, 4)));
}