// Generate a function body. // void GenerateFunction(SYM *sym, Statement *stmt) { char buf[20]; char *bl; int cnt, nn; AMODE *ap; ENODE *ep; SYM *sp; std::string vep; throwlab = retlab = contlab = breaklab = -1; lastsph = 0; memset(semaphores,0,sizeof(semaphores)); throwlab = nextlabel++; retlab = nextlabel++; while( lc_auto & 7 ) /* round frame size to word */ ++lc_auto; if (sym->IsInterrupt) { //GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(30*8)); //GenerateDiadic(op_sm,0,make_indirect(30), make_mask(0x9FFFFFFE)); } if (sym->prolog) { if (optimize) opt1(sym->prolog); GenerateStatement(sym->prolog); } if (!sym->IsNocall) { GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(-GetReturnBlockSize())); if (lc_auto || sym->NumParms > 0) { GenerateDiadic(op_sw,0,makereg(regBP),make_indirect(regSP)); } // if (sym->UsesPredicate) GenerateDiadic(op_sws, 0, make_string("pregs"), make_indexed(24,regSP)); GenerateDiadic(op_sw, 0, makereg(regCLP),make_indexed(32,regSP)); // For a leaf routine don't bother to store the link register or exception link register. // Since virtual functions call other functions, they can't be leaf // routines. if (!sym->IsLeaf || sym->IsVirtual) { if (exceptions) { GenerateDiadic(op_sws, 0, makebreg(regXLR), make_indexed(8,regSP)); } GenerateDiadic(op_sws, 0, makebreg(regLR), make_indexed(16,regSP)); if (exceptions) { ep = allocEnode(); ep->nodetype = en_clabcon; ep->i = throwlab; ap = allocAmode(); ap->mode = am_immed; ap->offset = ep; GenerateDiadic(op_ldis,0, makebreg(regXLR), ap); } } GenerateDiadic(op_lw,0,makereg(regCLP),make_indexed(GetReturnBlockSize(),regSP)); vep = *sym->mangledName; vep += "_VEP"; GenerateMonadic(op_fnname,0,make_string((char *)vep.c_str())); // Generate switch to call derived methods if (sym->IsVirtual || sym->derivitives) { char buf[20]; char *buf2; DerivedMethod *mthd; dfs.printf("VirtualFunction Switch"); GenerateDiadic(op_lcu,0,makereg(24),make_indirect(regCLP)); mthd = sym->derivitives; while (mthd) { sprintf(buf, "p%d", 7); buf2 = my_strdup(buf); GenerateTriadic(op_cmpi,0,make_string(buf2),makereg(24),make_immed(mthd->typeno)); vep = *(mthd->name); vep += "_VEP"; // Virtual Entry Point GeneratePredicatedMonadic(7,PredOp(op_eq),op_jmp,0, make_string((char *)vep.c_str())); // jump to the method mthd = mthd->next; } } if (lc_auto || sym->NumParms > 0) { GenerateDiadic(op_mov,0,makereg(regBP),makereg(regSP)); if (lc_auto) GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(-lc_auto)); } // Save registers used as register variables. // **** Done in Analyze.c **** //if( save_mask != 0 ) { // GenerateTriadic(op_subui,0,makereg(SP),makereg(SP),make_immed(popcnt(save_mask)*8)); // cnt = (bitsset(save_mask)-1)*8; // for (nn = 31; nn >=1 ; nn--) { // if (save_mask & (1 << nn)) { // GenerateTriadic(op_sw,0,makereg(nn),make_indexed(cnt,SP),NULL); // cnt -= 8; // } // } //} } if (optimize) sym->NumRegisterVars = opt1(stmt); GenerateStatement(stmt); GenerateEpilog(sym); // Generate code for the hidden default catch if (exceptions) { if (sym->IsLeaf){ if (sym->DoesThrow) { GenerateLabel(throwlab); ap = GetTempRegister(); GenerateDiadic(op_mfspr,0,ap,makebreg(regXLR)); GenerateDiadic(op_mtspr,0,makebreg(regLR),ap); ReleaseTempRegister(ap); GenerateMonadic(op_br,0,make_clabel(retlab)); // goto regular return cleanup code } } else { GenerateLabel(throwlab); GenerateDiadic(op_lws,0,makebreg(regLR),make_indexed(8,regBP)); // load throw return address from stack into LR GenerateDiadic(op_sws,0,makebreg(regLR),make_indexed(16,regBP)); // and store it back (so it can be loaded with the lm) GenerateMonadic(op_br,0,make_clabel(retlab)); // goto regular return cleanup code } } }
static struct membuf *GenerateLuaFile(const char *asp_path, const char *lua_path, char **error_message) { FILE *fp; struct stat asp_file_stat; const char *asp_content; const char *asp_content_begin_ptr; struct membuf *lua_content; size_t estimated_size; int lua_fd = -1; struct ParserData parser_data; if (error_message) *error_message = NULL; fp = fopen(asp_path, "rt"); if (fp == NULL) { if (error_message) *error_message = strdup(strerror(errno)); return NULL; } fstat(_fileno(fp), &asp_file_stat); asp_content = (const char *)mmap(NULL, asp_file_stat.st_size, PROT_READ, MAP_PRIVATE, _fileno(fp), 0); if (asp_content == NULL) { if (error_message) *error_message = strdup("mmap failed."); fclose(fp); return NULL; } // Check for BOM and skip if present asp_content_begin_ptr = asp_content; if (asp_file_stat.st_size >= 3) { if (strncmp(asp_content_begin_ptr, "\xEF\xBB\xBF", 3) == 0) asp_content_begin_ptr += 3; } if (lua_path != NULL) { FILE *lua_fp; lua_fp = fopen(lua_path, "wt"); if (lua_fp != NULL) { lua_fd = _dup(_fileno(lua_fp)); fclose(lua_fp); } } estimated_size = asp_file_stat.st_size * 4; lua_content = membuf_create(estimated_size, lua_fd, 0, 1); parser_data.buf = lua_content; parser_data.handler = WriteToBufferCallback; GenerateProlog(parser_data.handler, &parser_data); ParseBuffer(asp_content_begin_ptr, asp_file_stat.st_size, ParserEventHandler, &parser_data); GenerateEpilog(parser_data.handler, &parser_data); munmap(asp_content, asp_file_stat.st_size); fclose(fp); return lua_content; }