/* ** Return the opcode for a given address. If the address is -1, then ** return the most recently inserted opcode. ** ** If a memory allocation error has occurred prior to the calling of this ** routine, then a pointer to a dummy VdbeOp will be returned. That opcode ** is readable and writable, but it has no effect. The return of a dummy ** opcode allows the call to continue functioning after a OOM fault without ** having to check to see if the return from this routine is a valid pointer. ** ** About the #if SQLITE_OMIT_TRACE: Normally, this routine is never called ** unless p->nOp>0. This is because in the absense of SQLITE_OMIT_TRACE, ** an OP_Trace instruction is always inserted by sqlite3VdbeGet() as soon as ** a new VDBE is created. So we are free to set addr to p->nOp-1 without ** having to double-check to make sure that the result is non-negative. But ** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to ** check the value of p->nOp-1 before continuing. */ static VdbeOp sqlite3VdbeGetOp( Vdbe p, int addr ) { Debug.Assert( p.magic == VDBE_MAGIC_INIT ); if ( addr < 0 ) { #if SQLITE_OMIT_TRACE VdbeOp dummy = new VdbeOp(); if( p.nOp==0 ) return dummy; #endif addr = p.nOp - 1; } Debug.Assert( ( addr >= 0 && addr < p.nOp ) /* || p.db.mallocFailed != 0 */); //if ( p.db.mallocFailed != 0 ) //{ // return dummy; //} //else { return p.aOp[addr]; } }
public int AddOp3(OP op, int p1, int p2, int p3) { int i = Ops.length; Debug.Assert(Magic == VDBE_MAGIC_INIT); Debug.Assert((int)op > 0 && (int)op < 0xff); if (OpsAlloc <= i) if (GrowOps(this) != RC.OK) return 1; Ops.length++; if (Ops[i] == null) Ops[i] = new VdbeOp(); VdbeOp opAsObj = Ops[i]; opAsObj.Opcode = op; opAsObj.P5 = 0; opAsObj.P1 = p1; opAsObj.P2 = p2; opAsObj.P3 = p3; opAsObj.P4.P = null; opAsObj.P4Type = Vdbe.P4T.NOTUSED; #if DEBUG opAsObj.Comment = null; if ((Ctx.Flags & BContext.FLAG.VdbeAddopTrace) != 0) PrintOp(null, i, Ops[i]); #endif #if VDBE_PROFILE opAsObj.Cycles = 0; opAsObj.Cnt = 0; #endif return i; }
public static void PrintOp(FILE out_, int pc, VdbeOp op) { if (out_ == null) out_ = Console.Out; StringBuilder ptr = new StringBuilder(50); string p4 = DisplayP4(op, ptr, ptr.Length); StringBuilder out2_ = new StringBuilder(10); C.__snprintf(out2_, 999, "%4d %-13s %4d %4d %4d %-4s %.2X %s\n", pc, OpcodeName(op.Opcode), op.P1, op.P2, op.P3, p4, op.P5, #if DEBUG (op.Comment != null ? op.Comment : string.Empty) #else string.Empty #endif ); out_.Write(out2_); }
//static StringBuilder temp = new StringBuilder(100); static string DisplayP4(VdbeOp op, StringBuilder temp, int tempLength) { temp.Length = 0; Debug.Assert(tempLength >= 20); switch (op.P4Type) { case P4T.KEYINFO_STATIC: case P4T.KEYINFO: { KeyInfo keyInfo = op.P4.KeyInfo; Debug.Assert(keyInfo.SortOrders != null); C.__snprintf(temp, tempLength, "keyinfo(%d", keyInfo.Fields); int i = temp.Length; for (int j = 0; j < keyInfo.Fields; j++) { CollSeq coll = keyInfo.Colls[j]; if (coll != null) { string collName = coll.Name; int collNameLength = collName.Length; if (i + collNameLength > tempLength) { temp.Append(",..."); break; } temp.Append(","); if (keyInfo.SortOrders != null && keyInfo.SortOrders[j] != 0) temp.Append("-"); temp.Append(coll.Name); i += collNameLength; } else if (i + 4 < tempLength) { temp.Append(",nil"); i += 4; } } temp.Append(")"); Debug.Assert(i < tempLength); break; } case P4T.COLLSEQ: { CollSeq coll = op.P4.Coll; C.__snprintf(temp, tempLength, "collseq(%.20s)", (coll != null ? coll.Name : "null")); break; } case P4T.FUNCDEF: { FuncDef def = op.P4.Func; C.__snprintf(temp, tempLength, "%s(%d)", def.Name, def.Args); break; } case P4T.INT64: { C.__snprintf(temp, tempLength, "%lld", op.P4.I64); break; } case P4T.INT32: { C.__snprintf(temp, tempLength, "%d", op.P4.I); break; } case P4T.REAL: { C.__snprintf(temp, tempLength, "%.16g", op.P4.Real); break; } case P4T.MEM: { Mem mem = op.P4.Mem; Debug.Assert((mem.Flags & MEM.Null) == 0); if ((mem.Flags & MEM.Str) != 0) temp.Append(mem.Z); else if ((mem.Flags & MEM.Int) != 0) C.__snprintf(temp, tempLength, "%lld", mem.u.I); else if ((mem.Flags & MEM.Real) != 0) C.__snprintf(temp, tempLength, "%.16g", mem.R); else { Debug.Assert((mem.Flags & MEM.Blob) != 0); temp = new StringBuilder("(blob)"); } break; } #if !OMIT_VIRTUALTABLE case P4T.VTAB: { IVTable vtable = op.P4.VTable.IVTable; C.__snprintf(temp, tempLength, "vtab:%p:%p", vtable, vtable.IModule); break; } #endif case P4T.INTARRAY: { C.__snprintf(temp, tempLength, "intarray"); break; } case P4T.SUBPROGRAM: { C.__snprintf(temp, tempLength, "program"); break; } default: { if (op.P4.Z != null) temp.Append(op.P4.Z); break; } } Debug.Assert(temp != null); return temp.ToString(); }
static void VdbeFreeOpArray(Context ctx, ref VdbeOp[] ops, int opsLength) { if (ops != null) { for (int opIdx = ops.Length; opIdx < opsLength; opIdx++) { VdbeOp op = ops[opIdx]; FreeP4(ctx, op.P4Type, op.P4.P); #if DEBUG C._tagfree(ctx, ref op.Comment); #endif } } C._tagfree(ctx, ref ops); }
public int AddOpList(int opsLength, VdbeOpList[] ops) { Debug.Assert(Magic == VDBE_MAGIC_INIT); if (Ops.length + opsLength > OpsAlloc && GrowOps(this) != 0) return 0; int addr = Ops.length; if (C._ALWAYS(opsLength > 0)) { VdbeOpList in_; for (int i = 0; i < opsLength; i++) { in_ = ops[i]; int p2 = in_.P2; if (Ops[i + addr] == null) Ops[i + addr] = new VdbeOp(); VdbeOp out_ = Ops[i + addr]; out_.Opcode = in_.Opcode; out_.P1 = in_.P1; out_.P2 = (p2 < 0 && ((OPFLG)E._opcodeProperty[(int)out_.Opcode] & OPFLG.JUMP) != 0 ? addr + (-1 - p2) : p2); out_.P3 = in_.P3; out_.P4Type = Vdbe.P4T.NOTUSED; out_.P4.P = null; out_.P5 = 0; #if DEBUG out_.Comment = null; if ((Ctx.Flags & BContext.FLAG.VdbeAddopTrace) != 0) PrintOp(null, i + addr, Ops[i + addr]); #endif } Ops.length += opsLength; } return addr; }