/** Save the complete script state. **/ void Script::SaveText(const char* filename) { // Open the text file to write the script state to. FILE* file = fopen(filename, "wt"); // For safety, just in case we leave something behind on the script stack. AutoBlock block(*this); // Run through all the globals. int i; Object table = GetGlobals(); PushNil(); while ((i = Next(table.GetStackIndex())) != 0) { // Retrieve the global's key and value. Object key = GetObject(GetTop() - 1); Object value = GetObject(GetTop()); // Save the global to the text file. if (strcmp(key.GetString(), "_VERSION") != 0) { WriteObject(*this, file, key.GetString(), value, 0); } // Go to the next global. Pop(); } // Close the text file. fclose(file); }
void lua_getfenv(lua_State *L, int index) { const Value* object = GetValueForIndex(L, index); Table* table = Value_GetEnv(object); if (table == NULL) { PushNil(L); } else { SetValue(L->stackTop, table); ++L->stackTop; } }
void lua_rawgeti(lua_State *L, int index, int n) { Value* table = GetValueForIndex(L, index); luai_apicheck(L, Value_GetIsTable(table) ); const Value* value = Table_GetTable(L, table->table, n); if (value == NULL) { PushNil(L); } else { PushValue(L, value); } }
int OPTpushselectImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { int i, j, limit, slimit, actions=0, *vars, push_down_delta = 0, nr_topn = 0, nr_likes = 0; InstrPtr p, *old; subselect_t subselects; memset(&subselects, 0, sizeof(subselects)); if( mb->errors) return 0; OPTDEBUGpushselect mnstr_printf(cntxt->fdout,"#Push select optimizer started\n"); (void) stk; (void) pci; vars= (int*) GDKzalloc(sizeof(int)* mb->vtop); if( vars == NULL) return 0; limit = mb->stop; slimit= mb->ssize; old = mb->stmt; /* check for bailout conditions */ for (i = 1; i < limit; i++) { int lastbat; p = old[i]; for (j = 0; j<p->retc; j++) { int res = getArg(p, j); vars[res] = i; } if (getModuleId(p) == algebraRef && (getFunctionId(p) == tintersectRef || getFunctionId(p) == tinterRef || getFunctionId(p) == tdifferenceRef || getFunctionId(p) == tdiffRef)) { GDKfree(vars); return 0; } if (getModuleId(p) == algebraRef && getFunctionId(p) == sliceRef) nr_topn++; if (isLikeOp(p)) nr_likes++; if (getModuleId(p) == sqlRef && getFunctionId(p) == deltaRef) push_down_delta++; if (getModuleId(p) == sqlRef && getFunctionId(p) == tidRef) { /* rewrite equal table ids */ int sname = getArg(p, 2), tname = getArg(p, 3), s; for (s = 0; s < subselects.nr; s++) { InstrPtr q = old[vars[subselects.tid[s]]]; int Qsname = getArg(q, 2), Qtname = getArg(q, 3); if (no_updates(old, vars, getArg(q,1), getArg(p,1)) && ((sname == Qsname && tname == Qtname) || (0 && strcmp(getVarConstant(mb, sname).val.sval, getVarConstant(mb, Qsname).val.sval) == 0 && strcmp(getVarConstant(mb, tname).val.sval, getVarConstant(mb, Qtname).val.sval) == 0))) { clrFunction(p); p->retc = 1; p->argc = 2; getArg(p, 1) = getArg(q, 0); break; } } } lastbat = lastbat_arg(mb, p); if (isSubSelect(p) && p->retc == 1 && /* no cand list */ getArgType(mb, p, lastbat) != newBatType(TYPE_oid, TYPE_oid)) { int i1 = getArg(p, 1), tid = 0; InstrPtr q = old[vars[i1]]; /* find the table ids */ while(!tid) { if (getModuleId(q) == algebraRef && getFunctionId(q) == leftfetchjoinRef) { int i1 = getArg(q, 1); InstrPtr s = old[vars[i1]]; if (getModuleId(s) == sqlRef && getFunctionId(s) == tidRef) tid = getArg(q, 1); if (s->argc == 2 && s->retc == 1) { int i1 = getArg(s, 1); InstrPtr s = old[vars[i1]]; if (getModuleId(s) == sqlRef && getFunctionId(s) == tidRef) tid = getArg(q, 1); } break; } else if (isMapOp(q) && q->argc >= 2 && isaBatType(getArgType(mb, q, 1))) { int i1 = getArg(q, 1); q = old[vars[i1]]; } else if (isMapOp(q) && q->argc >= 3 && isaBatType(getArgType(mb, q, 2))) { int i2 = getArg(q, 2); q = old[vars[i2]]; } else { break; } } if (tid && subselect_add(&subselects, tid, getArg(p, 0)) < 0) { GDKfree(vars); return 0; } } /* left hand side */ if ( (GDKdebug & (1<<15)) && isMatJoinOp(p) && p->retc == 2) { int i1 = getArg(p, 2), tid = 0; InstrPtr q = old[vars[i1]]; /* find the table ids */ while(!tid) { if (getModuleId(q) == algebraRef && getFunctionId(q) == leftfetchjoinRef) { int i1 = getArg(q, 1); InstrPtr s = old[vars[i1]]; if (getModuleId(s) == sqlRef && getFunctionId(s) == tidRef) tid = getArg(q, 1); break; } else if (isMapOp(q) && q->argc >= 2 && isaBatType(getArgType(mb, q, 1))) { int i1 = getArg(q, 1); q = old[vars[i1]]; } else if (isMapOp(q) && q->argc >= 3 && isaBatType(getArgType(mb, q, 2))) { int i2 = getArg(q, 2); q = old[vars[i2]]; } else { break; } } if (tid && subselect_add(&subselects, tid, getArg(p, 0)) < 0) { GDKfree(vars); return 0; } } /* right hand side */ if ( (GDKdebug & (1<<15)) && isMatJoinOp(p) && p->retc == 2) { int i1 = getArg(p, 3), tid = 0; InstrPtr q = old[vars[i1]]; /* find the table ids */ while(!tid) { if (getModuleId(q) == algebraRef && getFunctionId(q) == leftfetchjoinRef) { int i1 = getArg(q, 1); InstrPtr s = old[vars[i1]]; if (getModuleId(s) == sqlRef && getFunctionId(s) == tidRef) tid = getArg(q, 1); break; } else if (isMapOp(q) && q->argc >= 2 && isaBatType(getArgType(mb, q, 1))) { int i1 = getArg(q, 1); q = old[vars[i1]]; } else if (isMapOp(q) && q->argc >= 3 && isaBatType(getArgType(mb, q, 2))) { int i2 = getArg(q, 2); q = old[vars[i2]]; } else { break; } } if (tid && subselect_add(&subselects, tid, getArg(p, 1)) < 0) { GDKfree(vars); return 0; } } } if ((!subselects.nr && !nr_topn && !nr_likes) || newMalBlkStmt(mb, mb->ssize) <0 ) { GDKfree(vars); return 0; } pushInstruction(mb,old[0]); for (i = 1; i < limit; i++) { p = old[i]; /* rewrite batalgebra.like + subselect -> likesubselect */ if (getModuleId(p) == algebraRef && p->retc == 1 && getFunctionId(p) == subselectRef) { int var = getArg(p, 1); InstrPtr q = mb->stmt[vars[var]]; /* BEWARE: the optimizer may not add or remove statements ! */ if (isLikeOp(q)) { /* TODO check if getArg(p, 3) value == TRUE */ InstrPtr r = newInstruction(mb, ASSIGNsymbol); int has_cand = (getArgType(mb, p, 2) == newBatType(TYPE_oid, TYPE_oid)); int a, anti = (getFunctionId(q)[0] == 'n'), ignore_case = (getFunctionId(q)[anti?4:0] == 'i'); setModuleId(r, algebraRef); setFunctionId(r, likesubselectRef); getArg(r,0) = getArg(p,0); r = pushArgument(mb, r, getArg(q, 1)); if (has_cand) r = pushArgument(mb, r, getArg(p, 2)); for(a = 2; a<q->argc; a++) r = pushArgument(mb, r, getArg(q, a)); if (r->argc < (4+has_cand)) r = pushStr(mb, r, ""); /* default esc */ if (r->argc < (5+has_cand)) r = pushBit(mb, r, ignore_case); if (r->argc < (6+has_cand)) r = pushBit(mb, r, anti); freeInstruction(p); p = r; actions++; } } /* inject table ids into subselect * s = subselect(c, C1..) => subselect(c, t, C1..) */ if (isSubSelect(p) && p->retc == 1) { int tid = 0; if ((tid = subselect_find_tids(&subselects, getArg(p, 0))) >= 0) { int lastbat = lastbat_arg(mb, p); if (getArgType(mb, p, lastbat) == TYPE_bat) /* empty candidate list bat_nil */ getArg(p, lastbat) = tid; else p = PushArgument(mb, p, tid, lastbat+1); /* make sure to resolve again */ p->token = ASSIGNsymbol; p->typechk = TYPE_UNKNOWN; p->fcn = NULL; p->blk = NULL; actions++; } } else if ( (GDKdebug & (1<<15)) && isMatJoinOp(p) && p->retc == 2 && !(getFunctionId(p) == joinRef && p->argc > 4) ) { int ltid = 0, rtid = 0, done = 0; int range = 0; if(getFunctionId(p) == joinRef) range = (p->argc >= 4); if ((ltid = subselect_find_tids(&subselects, getArg(p, 0))) >= 0 && (rtid = subselect_find_tids(&subselects, getArg(p, 1))) >= 0) { p = PushArgument(mb, p, ltid, 4+range); p = PushArgument(mb, p, rtid, 5+range); done = 1; } else if ((ltid = subselect_find_tids(&subselects, getArg(p, 0))) >= 0) { p = PushArgument(mb, p, ltid, 4+range); p = PushNil(mb, p, 5+range, TYPE_bat); done = 1; } else if ((rtid = subselect_find_tids(&subselects, getArg(p, 1))) >= 0) { p = PushNil(mb, p, 4+range, TYPE_bat); p = PushArgument(mb, p, rtid, 5+range); done = 1; } if (done) { if(getFunctionId(p) == antijoinRef) p = pushInt(mb, p, JOIN_NE); p = pushBit(mb, p, FALSE); /* do not match nils */ p = pushNil(mb, p, TYPE_lng); /* no estimate */ /* TODO join* -> subjoin* */ if(getFunctionId(p) == joinRef) getFunctionId(p) = subjoinRef; else if(getFunctionId(p) == antijoinRef) getFunctionId(p) = subthetajoinRef; else if(getFunctionId(p) == thetajoinRef) getFunctionId(p) = subthetajoinRef; else if(getFunctionId(p) == bandjoinRef) getFunctionId(p) = subbandjoinRef; /* make sure to resolve again */ p->token = ASSIGNsymbol; p->typechk = TYPE_UNKNOWN; p->fcn = NULL; p->blk = NULL; actions++; } } /* Leftfetchjoins involving rewriten table ids need to be flattend * l = leftfetchjoin(t, c); => l = c; * and * l = leftfetchjoin(s, ntids); => l = s; */ else if (getModuleId(p) == algebraRef && getFunctionId(p) == leftfetchjoinRef) { int var = getArg(p, 1); if (subselect_find_subselect(&subselects, var) > 0) { InstrPtr q = newAssignment(mb); getArg(q, 0) = getArg(p, 0); (void) pushArgument(mb, q, getArg(p, 2)); actions++; freeInstruction(p); continue; } else { /* deletes/updates use table ids */ int var = getArg(p, 2); InstrPtr q = mb->stmt[vars[var]]; /* BEWARE: the optimizer may not add or remove statements ! */ if (q->token == ASSIGNsymbol) { var = getArg(q, 1); q = mb->stmt[vars[var]]; } if (subselect_find_subselect(&subselects, var) > 0) { InstrPtr qq = newAssignment(mb); /* TODO: check result */ getArg(qq, 0) = getArg(p, 0); (void) pushArgument(mb, qq, getArg(p, 1)); actions++; freeInstruction(p); continue; } /* c = sql.delta(b,uid,uval,ins); * l = leftfetchjoin(x, c); * into * l = sql.projectdelta(x,b,uid,uval,ins); */ else if (getModuleId(q) == sqlRef && getFunctionId(q) == deltaRef && q->argc == 5) { q = copyInstruction(q); setFunctionId(q, projectdeltaRef); getArg(q, 0) = getArg(p, 0); q = PushArgument(mb, q, getArg(p, 1), 1); freeInstruction(p); p = q; actions++; } } } pushInstruction(mb,p); } for (; i<limit; i++) if (old[i]) pushInstruction(mb,old[i]); for (; i<slimit; i++) if (old[i]) freeInstruction(old[i]); GDKfree(old); if (!push_down_delta) { GDKfree(vars); return actions; } /* now push selects through delta's */ limit = mb->stop; slimit= mb->ssize; old = mb->stmt; if (newMalBlkStmt(mb, mb->stop+(5*push_down_delta)) <0 ) { mb->stmt = old; GDKfree(vars); return actions; } pushInstruction(mb,old[0]); for (i = 1; i < limit; i++) { int lastbat; p = old[i]; for (j = 0; j<p->retc; j++) { int res = getArg(p, j); vars[res] = i; } /* push subslice under projectdelta */ if (isSlice(p) && p->retc == 1) { int var = getArg(p, 1); InstrPtr q = old[vars[var]]; if (getModuleId(q) == sqlRef && getFunctionId(q) == projectdeltaRef) { InstrPtr r = copyInstruction(p); InstrPtr s = copyInstruction(q); ValRecord cst; /* slice the candidates */ setFunctionId(r, sliceRef); getArg(r, 0) = newTmpVariable(mb, newBatType(TYPE_oid, TYPE_oid)); getArg(r, 1) = getArg(s, 1); cst.vtype = getArgType(mb, r, 2); cst.val.wval = 0; getArg(r, 2) = defConstant(mb, cst.vtype, &cst); /* start from zero */ pushInstruction(mb,r); /* dummy result for the old q, will be removed by deadcode optimizer */ getArg(q, 0) = newTmpVariable(mb, getArgType(mb, q, 0)); getArg(s, 1) = getArg(r, 0); /* use result of subslice */ pushInstruction(mb, s); } } /* c = delta(b, uid, uvl, ins) * s = subselect(c, C1..) * * nc = subselect(b, C1..) * ni = subselect(ins, C1..) * nu = subselect(uvl, C1..) * s = subdelta(nc, uid, nu, ni); * * doesn't handle Xsubselect(x, .. z, C1.. cases) ie multicolumn selects */ lastbat = lastbat_arg(mb, p); if (isSubSelect(p) && p->retc == 1 && lastbat == 2) { int var = getArg(p, 1); InstrPtr q = old[vars[var]]; if (q->token == ASSIGNsymbol) { var = getArg(q, 1); q = old[vars[var]]; } if (getModuleId(q) == sqlRef && getFunctionId(q) == deltaRef) { InstrPtr r = copyInstruction(p); InstrPtr s = copyInstruction(p); InstrPtr t = copyInstruction(p); InstrPtr u = copyInstruction(q); getArg(r, 0) = newTmpVariable(mb, newBatType(TYPE_oid, TYPE_oid)); getArg(r, 1) = getArg(q, 1); /* column */ pushInstruction(mb,r); getArg(s, 0) = newTmpVariable(mb, newBatType(TYPE_oid, TYPE_oid)); getArg(s, 1) = getArg(q, 3); /* updates */ s = ReplaceWithNil(mb, s, 2, TYPE_bat); /* no candidate list */ setArgType(mb, s, 2, newBatType(TYPE_oid,TYPE_oid)); /* make sure to resolve again */ s->token = ASSIGNsymbol; s->typechk = TYPE_UNKNOWN; s->fcn = NULL; s->blk = NULL; pushInstruction(mb,s); getArg(t, 0) = newTmpVariable(mb, newBatType(TYPE_oid, TYPE_oid)); getArg(t, 1) = getArg(q, 4); /* inserts */ pushInstruction(mb,t); setFunctionId(u, subdeltaRef); getArg(u, 0) = getArg(p,0); getArg(u, 1) = getArg(r,0); getArg(u, 2) = getArg(p,2); /* pre-cands */ getArg(u, 3) = getArg(q,2); /* update ids */ getArg(u, 4) = getArg(s,0); u = pushArgument(mb, u, getArg(t,0)); pushInstruction(mb,u); freeInstruction(p); continue; } } pushInstruction(mb,p); } for (; i<limit; i++) if (old[i]) pushInstruction(mb,old[i]); GDKfree(vars); GDKfree(old); return actions; }
void VMachine::Execute(){ int step=0; int index = -1; int index1,index2; ip = 0; void *op_lables[13]; goto PREPARE; LABEL_NOP: goto NEXT_INSTR; LABEL_PUSH: operstack.push(instr[ip]._operand); goto NEXT_INSTR; LABEL_POP: index = operstack.top(); operstack.pop(); FreeIndex.insert(index); goto NEXT_INSTR; LABEL_GETTOP: index = operstack.top(); goto NEXT_INSTR; LABEL_JMP: step = instr[ip]._operand; goto NEXT_INSTR; LABEL_IFJMP: index= operstack.top(); operstack.pop(); if(ObjTable[index].t == BOOLEAN) if(ObjTable[index].v.b ==1) step = instr[ip]._operand; goto NEXT_INSTR; LABEL_ADD: index1 = operstack.top(); operstack.pop(); index2 = operstack.top(); operstack.pop(); if(ObjTable[index1].t != ObjTable[index2].t) vmerror("diffrent type to add\n"); else{ if(ObjTable[index1].t == NUMBER){ ObjTable[index1].v.num = ObjTable[index1].v.num + ObjTable[index2].v.num; operstack.push(index1); FreeIndex.insert(index2); } else if(ObjTable[index1].t = STRING){ ObjTable[index1].v.str = strcat(ObjTable[index1].v.str,ObjTable[index2].v.str); operstack.push(index1); FreeIndex.insert(index2); } else{ vmerror("can not add this type\n"); } } goto NEXT_INSTR; LABEL_SUB: index1 = operstack.top(); operstack.pop(); index2 = operstack.top(); operstack.pop(); if(ObjTable[index1].t != ObjTable[index2].t) vmerror("diffrent type to add\n"); else{ if(ObjTable[index1].t == NUMBER){ ObjTable[index1].v.num = ObjTable[index1].v.num + ObjTable[index2].v.num; operstack.push(index1); FreeIndex.insert(index2); } else{ vmerror("can not add this type\n"); } } goto NEXT_INSTR; LABEL_MUL: index1 = operstack.top(); operstack.pop(); index2 = operstack.top(); operstack.pop(); if(ObjTable[index1].t != ObjTable[index2].t) vmerror("diffrent type to mul\n"); else if(ObjTable[index1].t != NUMBER) vmerror("can not multiply non-numeric\n"); else{ ObjTable[index1].v.num = ObjTable[index1].v.num * ObjTable[index2].v.num; operstack.push(index1); FreeIndex.insert(index2); } goto NEXT_INSTR; LABEL_DIV: index1 = operstack.top(); operstack.pop(); index2 = operstack.top(); operstack.pop(); if(ObjTable[index1].t != ObjTable[index2].t) vmerror("diffrent type to mul\n"); else if(ObjTable[index1].t != NUMBER) vmerror("can not multiply non-numeric\n"); else{ ObjTable[index1].v.num = ObjTable[index1].v.num / ObjTable[index2].v.num; operstack.push(index1); FreeIndex.insert(index2); } goto NEXT_INSTR; LABEL_EQ: index1 = operstack.top(); operstack.pop(); index2 = operstack.top(); operstack.pop(); if(ObjTable[index1].t != ObjTable[index2].t){ vmerror("diffrent type"); } else{ switch(ObjTable[index1].t){ case NUMBER: if(ObjTable[index1].v.num == ObjTable[index1].v.num) PushBoolean(1); //1表示真,压入栈vmstark else PushBoolean(0); //0表示假 break; case STRING: if(strcmp(ObjTable[index1].v.str,ObjTable[index2].v.str)==0) PushBoolean(1); else PushBoolean(0); break; case BOOLEAN: if(ObjTable[index1].v.b == ObjTable[index1].v.b) PushBoolean(1); //1表示真,压入栈vmstark else PushBoolean(0); //0表示假 break; } } goto NEXT_INSTR; LABEL_LT: index1 = operstack.top(); operstack.pop(); index2 = operstack.top(); operstack.pop(); if(ObjTable[index1].t != ObjTable[index2].t){ vmerror("diffrent type"); } else{ switch(ObjTable[index1].t){ case NUMBER: if(ObjTable[index1].v.num < ObjTable[index1].v.num) PushBoolean(1); //1表示真,压入栈vmstark else PushBoolean(0); //0表示假 break; case STRING: if(strcmp(ObjTable[index1].v.str,ObjTable[index2].v.str)<0) PushBoolean(1); else PushBoolean(0); break; case BOOLEAN: PushNil(); break; } } goto NEXT_INSTR; LABEL_GT: index1 = operstack.top(); operstack.pop(); index2 = operstack.top(); operstack.pop(); if(ObjTable[index1].t != ObjTable[index2].t){ vmerror("diffrent type"); } else{ switch(ObjTable[index1].t){ case NUMBER: if(ObjTable[index1].v.num > ObjTable[index1].v.num) PushBoolean(1); //1表示真,压入栈vmstark else PushBoolean(0); //0表示假 break; case STRING: if(strcmp(ObjTable[index1].v.str,ObjTable[index2].v.str)>0) PushBoolean(1); else PushBoolean(0); break; case BOOLEAN: PushNil(); break; } } goto NEXT_INSTR; LABLE_UNKNOWN: vmerror("unknown opcode"); goto NEXT_INSTR; PREPARE: op_lables[0] = &&LABEL_NOP; op_lables[1] = &&LABEL_PUSH; op_lables[2] = &&LABEL_POP; op_lables[3] = &&LABEL_GETTOP; op_lables[4] = &&LABEL_JMP; op_lables[5] = &&LABEL_IFJMP; op_lables[6] = &&LABEL_ADD; op_lables[7] = &&LABEL_SUB; op_lables[8] = &&LABEL_MUL; op_lables[9] = &&LABEL_DIV; op_lables[10] = &&LABEL_EQ; op_lables[11] = &&LABEL_LT; op_lables[12] = &&LABEL_GT; NEXT_INSTR: if(ip > 14) goto END; ip = ip+step; step = 1; // showFree(); showStack(); // showObj(); if(instr[ip]._opcode<256 || instr[ip]._opcode>(257+13)) goto LABLE_UNKNOWN; goto *op_lables[instr[ip]._opcode-257]; END: getchar(); }
void lua_pushnil(lua_State* L) { PushNil(L); }