Ejemplo n.º 1
0
static int
tb_printinternal(tracebackobject *tb, PyObject *f, int limit)
{
	int err = 0;
	int depth = 0;
	tracebackobject *tb1 = tb;
	while (tb1 != NULL) {
		depth++;
		tb1 = tb1->tb_next;
	}
	while (tb != NULL && err == 0) {
		if (depth <= limit) {
			if (Py_OptimizeFlag)
				tb->tb_lineno = PyCode_Addr2Line(
					tb->tb_frame->f_code, tb->tb_lasti);
			err = tb_displayline(f,
			    PyString_AsString(
				    tb->tb_frame->f_code->co_filename),
			    tb->tb_lineno,
			    PyString_AsString(tb->tb_frame->f_code->co_name));
		}
		depth--;
		tb = tb->tb_next;
		if (err == 0)
			err = PyErr_CheckSignals();
	}
	return err;
}
Ejemplo n.º 2
0
static void
dump_frame(int fd, PyFrameObject *frame)
{
    PyCodeObject *code;
    int lineno;

    code = frame->f_code;
    PUTS(fd, "  File ");
    if (code != NULL && code->co_filename != NULL
        && PyUnicode_Check(code->co_filename))
    {
        write(fd, "\"", 1);
        dump_ascii(fd, code->co_filename);
        write(fd, "\"", 1);
    } else {
        PUTS(fd, "???");
    }

    /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */
    lineno = PyCode_Addr2Line(code, frame->f_lasti);
    PUTS(fd, ", line ");
    dump_decimal(fd, lineno);
    PUTS(fd, " in ");

    if (code != NULL && code->co_name != NULL
        && PyUnicode_Check(code->co_name))
        dump_ascii(fd, code->co_name);
    else
        PUTS(fd, "???");

    write(fd, "\n", 1);
}
Ejemplo n.º 3
0
static PyObject *
pygst_debug_log (PyObject * pyobject, PyObject * string, GstDebugLevel level,
    gboolean isgstobject)
{
#ifndef GST_DISABLE_GST_DEBUG
  gchar *str;
  gchar *function;
  gchar *filename;
  int lineno;
  PyFrameObject *frame;
  GObject *object = NULL;

  if (!PyArg_ParseTuple (string, "s:gst.debug_log", &str)) {
    PyErr_SetString (PyExc_TypeError, "Need a string!");
    return NULL;
  }

  frame = PyEval_GetFrame ();
  function = PyString_AsString (frame->f_code->co_name);
  filename =
      g_path_get_basename (PyString_AsString (frame->f_code->co_filename));
  lineno = PyCode_Addr2Line (frame->f_code, frame->f_lasti);
  /* gst_debug_log : category, level, file, function, line, object, format, va_list */
  if (isgstobject)
    object = G_OBJECT (pygobject_get (pyobject));
  gst_debug_log (python_debug, level, filename, function, lineno, object,
      "%s", str);
  if (filename)
    g_free (filename);
#endif
  Py_INCREF (Py_None);
  return Py_None;
}
Ejemplo n.º 4
0
int
PyFrame_GetLineNumber(PyFrameObject *f)
{
    if (f->f_trace)
        return f->f_lineno;
    else
        return PyCode_Addr2Line(f->f_code, f->f_lasti);
}
Ejemplo n.º 5
0
int PyFrame_GetLineNumber(PyFrameObject *frame) {
	if (frame->f_trace) {
		return frame->f_lineno;
	}
	else {
		return PyCode_Addr2Line(frame->f_code, frame->f_lasti);
	}
}
Ejemplo n.º 6
0
static PyObject *
frame_getlineno(PyFrameObject *f, void *closure)
{
	int lineno;

	if (f->f_trace)
		lineno = f->f_lineno;
	else
		lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);

	return PyInt_FromLong(lineno);
}
Ejemplo n.º 7
0
PyObject* tostring(PyObject* self, PyObject* gen) {
    if(PyGen_Check(gen)) {
        PyFrameObject* frame = ((PyGenObject*)gen)->gi_frame;

        if(!frame)
            return PyString_FromString("<no frame>");

        int ilineno = PyCode_Addr2Line(frame->f_code, frame->f_lasti);
        PyObject* lineno = PyInt_FromLong(ilineno); // new ref
        PyObject* codeline = PyObject_CallFunctionObjArgs(py_getline,
                             frame->f_code->co_filename, lineno, NULL); // new ref
        Py_CLEAR(lineno);

        if(!codeline) return NULL;

        PyObject* codeline_stripped = PyObject_CallMethod(codeline, "strip", NULL); // new ref
        Py_CLEAR(codeline);

        if(!codeline_stripped) return NULL;

        PyObject* result =
            PyString_FromFormat("  File \"%s\", line %d, in %s\n    %s",
                                PyString_AsString(frame->f_code->co_filename),
                                ilineno, PyString_AsString(frame->f_code->co_name),
                                PyString_AsString(codeline_stripped)); // new ref
        Py_CLEAR(codeline_stripped);
        return result;

    } else if(gen->ob_type == &PyCompose_Type) {
        PyComposeObject* cmps = (PyComposeObject*) gen;
        PyObject* result = NULL;
        PyObject** generator = cmps->generators_base;

        while(generator < cmps->generators_top) {
            PyObject* s = tostring(NULL, *generator++);

            if(!result)
                result = s;

            else {
                PyString_ConcatAndDel(&result, PyString_FromString("\n"));
                PyString_ConcatAndDel(&result, s);
            }
        }

        return result;
    }

    PyErr_SetString(PyExc_TypeError, "tostring() expects generator");
    return NULL;
}
Ejemplo n.º 8
0
static int
frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
{
	/* We rely on f_lineno being accurate when f_trace is set. */

	PyObject* old_value = f->f_trace;

	Py_XINCREF(v);
	f->f_trace = v;

	if (v != NULL)
		f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);

	Py_XDECREF(old_value);

	return 0;
}
Ejemplo n.º 9
0
void log_NA_event(const char* event_name) {
  PyFrameObject* f = PyEval_GetFrame();

  // stolen from frame_getlineno in Objects/frameobject.c
  int lineno;
  if (f->f_trace)
    lineno = f->f_lineno;
  else
    lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);


  PG_LOG_PRINTF("{%s | %s %s:%d}\n",
                event_name,
                PyString_AsString(f->f_code->co_filename),
                PyString_AsString(f->f_code->co_name),
                lineno);
}
Ejemplo n.º 10
0
// Python interpreter retrieval routine adapted from
// https://stackoverflow.com/a/8706144
std::string getPythonInterpreterStackTrace() {
  std::stringstream stack_trace;
  AutoGIL gil;
  PyThreadState *tstate = PyThreadState_GET();
  if (NULL != tstate && NULL != tstate->frame) {
    PyFrameObject *frame = tstate->frame;

    while (NULL != frame) {
      int line = PyCode_Addr2Line(frame->f_code, frame->f_lasti);
      std::string filename = THPUtils_unpackString(frame->f_code->co_filename);
      std::string funcname = THPUtils_unpackString(frame->f_code->co_name);
      stack_trace << filename << "(" << line << "): " << funcname << "\n";
      frame = frame->f_back;
    }
  }
  return stack_trace.str();
}
Ejemplo n.º 11
0
static void
dump_frame(int fd, PyFrameObject *frame)
{
    PyCodeObject *code;
    int lineno;

    code = frame->f_code;
    PUTS(fd, "  File ");
    if (code != NULL && code->co_filename != NULL
        && PyUnicode_Check(code->co_filename))
    {
        PUTS(fd, "\"");
        _Py_DumpASCII(fd, code->co_filename);
        PUTS(fd, "\"");
    } else {
        PUTS(fd, "???");
    }

    /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */
    lineno = PyCode_Addr2Line(code, frame->f_lasti);
    PUTS(fd, ", line ");
    if (lineno >= 0) {
        _Py_DumpDecimal(fd, (unsigned long)lineno);
    }
    else {
        PUTS(fd, "???");
    }
    PUTS(fd, " in ");

    if (code != NULL && code->co_name != NULL
       && PyUnicode_Check(code->co_name)) {
        _Py_DumpASCII(fd, code->co_name);
    }
    else {
        PUTS(fd, "???");
    }

    PUTS(fd, "\n");
}
Ejemplo n.º 12
0
static PyTracebackObject *
newtracebackobject(PyTracebackObject *next, PyFrameObject *frame)
{
	PyTracebackObject *tb;
	if ((next != NULL && !PyTraceBack_Check(next)) ||
			frame == NULL || !PyFrame_Check(frame)) {
		PyErr_BadInternalCall();
		return NULL;
	}
	tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type);
	if (tb != NULL) {
		Py_XINCREF(next);
		tb->tb_next = next;
		Py_XINCREF(frame);
		tb->tb_frame = frame;
		tb->tb_lasti = frame->f_lasti;
		tb->tb_lineno = PyCode_Addr2Line(frame->f_code, 
						 frame->f_lasti);
		PyObject_GC_Track(tb);
	}
	return tb;
}
Ejemplo n.º 13
0
ScriptResult PythonEngine::parseError()
{    
    // error
    ScriptResult error;
    error.isError = true;

    PyObject *error_type = NULL;
    PyObject *error_value = NULL;
    PyObject *error_traceback = NULL;
    PyObject *error_string = NULL;
    PyErr_Fetch(&error_type, &error_value, &error_traceback);
    PyErr_NormalizeException(&error_type, &error_value, &error_traceback);

    if (error_traceback)
    {
        PyTracebackObject *traceback = (PyTracebackObject *) error_traceback;
        error.line = traceback->tb_lineno;
        error.text.append(QString("Line %1: ").arg(traceback->tb_lineno));

        while (traceback)
        {
            PyFrameObject *frame = traceback->tb_frame;

            if (frame && frame->f_code) {
                PyCodeObject* codeObject = frame->f_code;
                if (PyString_Check(codeObject->co_filename))
                    error.traceback.append(QString("File '%1'").arg(PyString_AsString(codeObject->co_filename)));

                int errorLine = PyCode_Addr2Line(codeObject, frame->f_lasti);
                error.traceback.append(QString(", line %1").arg(errorLine));

                if (PyString_Check(codeObject->co_name))
                    error.traceback.append(QString(", in %1").arg(PyString_AsString(codeObject->co_name)));
            }
            error.traceback.append(QString("\n"));

            traceback = traceback->tb_next;
        }
    }
    error.traceback = error.traceback.trimmed();

    if (error_type != NULL && (error_string = PyObject_Str(error_type)) != NULL && (PyString_Check(error_string)))
    {
        Py_INCREF(error_string);
        error.text.append(PyString_AsString(error_string));
        Py_XDECREF(error_string);
    }
    else
    {
        error.text.append("\n<unknown exception type>");
    }

    if (error_value != NULL && (error_string = PyObject_Str(error_value)) != NULL && (PyString_Check(error_string)))
    {
        Py_INCREF(error_string);
        error.text.append("\n");
        error.text.append(PyString_AsString(error_string));
        Py_XDECREF(error_string);
    }
    else
    {
        error.text.append("\n<unknown exception data>");
    }

    Py_XDECREF(error_type);
    Py_XDECREF(error_value);
    Py_XDECREF(error_traceback);

    PyErr_Clear();

    return error;
}
Ejemplo n.º 14
0
    bool PythonScript::checkRuntimeError() {
        if (!PyErr_Occurred())
            return true;

        std::string pyException = "";
        PyObject* pyError_type = nullptr;
        PyObject* pyError_value = nullptr;
        PyObject* pyError_traceback = nullptr;
        PyObject* pyError_string = nullptr;
        PyErr_Fetch(&pyError_type, &pyError_value, &pyError_traceback);
        int errorLine = -1;
        std::string stacktraceStr;

        if (pyError_traceback) {
            PyTracebackObject* traceback = (PyTracebackObject*)pyError_traceback;

            while (traceback) {
                PyFrameObject* frame = traceback->tb_frame;
                std::string stacktraceLine;

                if (frame && frame->f_code) {
                    PyCodeObject* codeObject = frame->f_code;

                    if (PyValueParser::is<std::string>(codeObject->co_filename))
                        stacktraceLine.append(std::string("  File \"") + PyValueParser::parse<std::string>(codeObject->co_filename) + std::string("\", "));

                    errorLine = PyCode_Addr2Line(codeObject, frame->f_lasti);
                    stacktraceLine.append(std::string("line ") + toString(errorLine));

                    if (PyValueParser::is<std::string>(codeObject->co_name))
                        stacktraceLine.append(std::string(", in ") + PyValueParser::parse<std::string>(codeObject->co_name));
                }

                stacktraceLine.append("\n");
                stacktraceStr = stacktraceLine + stacktraceStr;
                traceback = traceback->tb_next;
            }
        }

        std::stringstream s;
        s << errorLine;
        pyException.append(std::string("[") + s.str() + std::string("] "));

        if (pyError_value && (pyError_string = PyObject_Str(pyError_value)) != nullptr &&
            (PyValueParser::is<std::string>(pyError_string))) {
                 pyException.append(PyValueParser::parse<std::string>(pyError_string));
                 Py_XDECREF(pyError_string);
                 pyError_string = nullptr;
                 }
                 else {
                 pyException.append("<No data available>");
                 }
                 
        pyException.append("\n");

        // finally append stacktrace string
        if (!stacktraceStr.empty()) {
            pyException.append("Stacktrace (most recent call first):\n");
            pyException.append(stacktraceStr);
        }
        else {
            pyException.append("<No stacktrace available>");
            LogWarn("Failed to parse traceback");
        }

        Py_XDECREF(pyError_type);
        Py_XDECREF(pyError_value);
        Py_XDECREF(pyError_traceback);
        LogError(pyException);
        PyInviwo::getPtr()->pythonExecutionOutputEvent(pyException, sysstderr);
        return false;
    }
Ejemplo n.º 15
0
/* Returns 0 on error (no new refs), 1 on success */
static int
setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
              PyObject **module, PyObject **registry)
{
    PyObject *globals;

    /* Setup globals and lineno. */
    PyFrameObject *f = PyThreadState_GET()->frame;
    while (--stack_level > 0 && f != NULL)
        f = f->f_back;

    if (f == NULL) {
        globals = PyThreadState_Get()->interp->sysdict;
        *lineno = 1;
    }
    else {
        globals = f->f_globals;
        *lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
    }

    *module = NULL;

    /* Setup registry. */
    assert(globals != NULL);
    assert(PyDict_Check(globals));
    *registry = PyDict_GetItemString(globals, "__warningregistry__");
    if (*registry == NULL) {
        int rc;

        *registry = PyDict_New();
        if (*registry == NULL)
            return 0;

         rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
         if (rc < 0)
            goto handle_error;
    }
    else
        Py_INCREF(*registry);

    /* Setup module. */
    *module = PyDict_GetItemString(globals, "__name__");
    if (*module == NULL) {
        *module = PyString_FromString("<string>");
        if (*module == NULL)
            goto handle_error;
    }
    else
        Py_INCREF(*module);

    /* Setup filename. */
    *filename = PyDict_GetItemString(globals, "__file__");
    if (*filename != NULL) {
	    Py_ssize_t len = PyString_Size(*filename);
        const char *file_str = PyString_AsString(*filename);
	    if (file_str == NULL || (len < 0 && PyErr_Occurred()))
            goto handle_error;

        /* if filename.lower().endswith((".pyc", ".pyo")): */
        if (len >= 4 &&
            file_str[len-4] == '.' &&
            tolower(file_str[len-3]) == 'p' &&
            tolower(file_str[len-2]) == 'y' &&
            (tolower(file_str[len-1]) == 'c' ||
                tolower(file_str[len-1]) == 'o'))
        {
            *filename = PyString_FromStringAndSize(file_str, len-1);
	        if (*filename == NULL)
		        goto handle_error;
	    }
	    else
            Py_INCREF(*filename);
    }
    else {
        const char *module_str = PyString_AsString(*module);
        if (module_str && strcmp(module_str, "__main__") == 0) {
            PyObject *argv = PySys_GetObject("argv");
            if (argv != NULL && PyList_Size(argv) > 0) {
                int is_true;
                *filename = PyList_GetItem(argv, 0);
                Py_INCREF(*filename);
                /* If sys.argv[0] is false, then use '__main__'. */
                is_true = PyObject_IsTrue(*filename);
                if (is_true < 0) {
                    Py_DECREF(*filename);
                    goto handle_error;
                }
                else if (!is_true) {
                    Py_DECREF(*filename);
                    *filename = PyString_FromString("__main__");
                    if (*filename == NULL)
                        goto handle_error;
                }
            }
            else {
                /* embedded interpreters don't have sys.argv, see bug #839151 */
                *filename = PyString_FromString("__main__");
	            if (*filename == NULL)
	                goto handle_error;
            }
        }
        if (*filename == NULL) {
            *filename = *module;
            Py_INCREF(*filename);
        }
    }

    return 1;

 handle_error:
    /* filename not XDECREF'ed here as there is no way to jump here with a
       dangling reference. */
    Py_XDECREF(*registry);
    Py_XDECREF(*module);
    return 0;
}
Ejemplo n.º 16
0
ErrorResult PythonEngine::parseError()
{
    QString traceback;
    QString text;
    int line = -1;

    PyErr_NormalizeException(&errorType, &errorValue, &errorTraceback);

    if (errorTraceback)
    {
        PyTracebackObject *tb = (PyTracebackObject *) errorTraceback;
        line = tb->tb_lineno;
        text.append(QString("Line %1: ").arg(tb->tb_lineno));

        while (tb)
        {
            PyFrameObject *frame = tb->tb_frame;

            if (frame && frame->f_code) {
                PyCodeObject* codeObject = frame->f_code;
                if (PyString_Check(codeObject->co_filename))
                    traceback.append(QString("File '%1'").arg(PyString_AsString(codeObject->co_filename)));

                int errorLine = PyCode_Addr2Line(codeObject, frame->f_lasti);
                traceback.append(QString(", line %1").arg(errorLine));

                if (PyString_Check(codeObject->co_name))
                    traceback.append(QString(", in %1").arg(PyString_AsString(codeObject->co_name)));
            }
            traceback.append(QString("\n"));

            tb = tb->tb_next;
        }
    }
    traceback = traceback.trimmed();

    PyObject *errorString = NULL;
    if (errorType != NULL && (errorString = PyObject_Str(errorType)) != NULL && (PyString_Check(errorString)))
    {
        Py_INCREF(errorString);
        text.append(PyString_AsString(errorString));
        Py_XDECREF(errorString);
    }
    else
    {
        text.append("\n<unknown exception type>");
    }

    if (errorValue != NULL && (errorString = PyObject_Str(errorValue)) != NULL && (PyString_Check(errorString)))
    {
        Py_INCREF(errorString);
        text.append("\n");
        text.append(PyString_AsString(errorString));
        Py_XDECREF(errorString);
    }
    else
    {
        text.append("\n<unknown exception data>");
    }

    Py_XDECREF(errorType);
    errorType = NULL;
    Py_XDECREF(errorValue);
    errorValue = NULL;
    Py_XDECREF(errorTraceback);
    errorTraceback = NULL;

    PyErr_Clear();

    return ErrorResult(text, traceback, line);
}
Ejemplo n.º 17
0
//=============================================================================
// METHOD     : SPELLbytecode::analyze
//=============================================================================
void SPELLbytecode::analyze()
{
    assert( m_code != NULL );
    // Pointer to initial instruction (used by macros)
    unsigned char* first_instr = (unsigned char*) PyString_AS_STRING(m_code->co_code);
    // Pointer to current instruction (used by macros)
    register unsigned char* next_instr = first_instr;
    // Opcode argument
    unsigned int oparg;
    // Stores the previous line
    unsigned int prevLine = 0;
    // Stores the last opcode
    unsigned int prevOpCode = 0;
    // Opcode count in line
    unsigned short opcodeCount = 0;

    // Will be true when there is no more bytecode to process
    bool finished = false;
    unsigned int callDepth = 0;
    // Try block structure
	TryBlock tb;
	tb.try_lineno = 0;
	tb.end_try_lineno = 0;
	tb.except_lineno = 0;
	tb.end_except_lineno = 0;
	tb.end_lineno = 0;
	// Holds the bytecode offset for except and finally statements
	unsigned int except_offset = 0;
	unsigned int finally_offset = 0;

	while(not finished)
    {
        // Create one BLine info structure per bytecode instruction
        BLine info;
        // Get the instruction offset
        info.offset = INSTR_OFFSET();
        // Get the corresponding script line
        info.lineno = PyCode_Addr2Line(m_code, info.offset);
        // Obtain the opcode
        info.opcode = NEXTOP();

        // Track the number of opcodes per line in the lnotab.
        if ((prevLine>0) && (info.lineno != prevLine))
        {
        	opcodeCount = 0;
        }
        else
        {
        	opcodeCount++;
        }

        //////////////////////////////////////////////////////////////////////////////////
        // PHASE 1 - UPDATE PREVIOUS LINE INFORMATION (ALREADY STORED) IF NEEDED
        //////////////////////////////////////////////////////////////////////////////////

        // #1 Detect binary add. This helps us detect lines that shall be executed together
        // like when statements spread over several lines with binary add (+\)
        if ((opcodeCount == 0)&&(prevOpCode == BINARY_ADD)&&(info.opcode==LOAD_CONST))
        {
        	LineList::iterator it = m_lines.end();
        	it--;
        	BLine prev = *it;
        	m_lines.pop_back();
        	prev.keepWithNext = true;
        	m_lines.push_back(prev);
        }

        //////////////////////////////////////////////////////////////////////////////////
        // #2 Special checks for return statements: we may need to update the previous line
		if (info.opcode == RETURN_VALUE && ((prevOpCode == LOAD_FAST || prevOpCode == LOAD_CONST)))
		{
        	LineList::iterator it = m_lines.end();
        	it--;
        	BLine prev = *it;
        	m_lines.pop_back();
        	prev.returnConst = true;
        	m_lines.push_back(prev);
		}


		// We will ignore this, for the moment
		oparg  = 0;
		// To decide wether store the bline information or not
		bool storeit = false;
		if (HAS_ARG(info.opcode)) oparg = NEXTARG();

		//////////////////////////////////////////////////////////////////////////////////
		// PHASE 2 - BUILD AND STORE NEXT BLINE INFORMATION
		//////////////////////////////////////////////////////////////////////////////////
        if (( prevLine > 0 ) && ( info.lineno != prevLine ))
        {
        	// Default values
        	info.executable   = false;
			info.returnConst  = false;
			info.keepWithNext = false;

        	/** \todo
			// Depending on the bytecode, either set the block as active,
			// or finish the loop (RETURN_VALUE is found at the end of the script)
			// This is maybe wrong, need to check if RETURN_VALUE is found
			// in function code objects, probably yes... */
			switch(info.opcode)
			{
			case LOAD_NAME:
			case LOAD_GLOBAL:
			case LOAD_CONST:
				callDepth++;
				info.executable = true;
				break;
			case CALL_FUNCTION:
				callDepth--;
				info.executable = true;
				break;
			case STORE_NAME:
			case IMPORT_NAME:
			case JUMP_FORWARD:
			case JUMP_IF_FALSE:
			case JUMP_IF_TRUE:
			case JUMP_ABSOLUTE:
			case RETURN_VALUE:
			{
				info.executable = (callDepth==0);
				break;
			}
			default:
				info.executable = true;
				break;
			}

            // Store the info
            m_lines.push_back(info);
        }
        // The very first line is always executable, and needs to be stored explicitly
        else if (prevLine == 0)
        {
        	info.executable = true;
            // Store the info
            m_lines.push_back(info);
        }

		//////////////////////////////////////////////////////////////////////////////////
		// PHASE 3 - ADDITIONAL INFORMATION FOR TRY BLOCKS, LAST ADDRESS, LAST LINE
		//////////////////////////////////////////////////////////////////////////////////
        switch(info.opcode)
        {
        case RETURN_VALUE:
			m_lastAddr = info.offset;
        	finished = true;
        	break;
        case SETUP_EXCEPT:
			tb.try_lineno = info.lineno;
			except_offset = info.offset + oparg + 3; // This is the real destination offset
			break;
        case SETUP_FINALLY:
        	finally_offset = info.offset + oparg + 3; // This is the 'finally' destination offset
        	break;
        case END_FINALLY:
        	if (tb.try_lineno != 0 && tb.end_lineno == 0)
        	{
				tb.end_lineno = info.lineno;
				tb.end_except_lineno = info.lineno;
				m_tryBlocks.push_back( tb );
				tb.try_lineno = 0;
				tb.end_try_lineno = 0;
				tb.except_lineno = 0;
				tb.end_except_lineno = 0;
				tb.end_lineno = 0;
        	}
        	else
        	{
        		// Update the last try block to update it with the finally block
        		TryBlockList::iterator it = m_tryBlocks.end();
            	it--;
            	TryBlock prev = *it;
            	m_tryBlocks.pop_back();
            	prev.end_except_lineno = prev.end_lineno;
				prev.end_lineno = info.lineno;
				m_tryBlocks.push_back( prev );
        	}
			break;
		}

        // This should always happen between a SETUP_EXCEPT and an END_FINALLY
        if ( (tb.try_lineno >0) && (except_offset == info.offset))
        {
        	// The last line before the except
        	tb.end_try_lineno = prevLine;
        	// The line of the except
        	tb.except_lineno = info.lineno;
        }

        prevLine = info.lineno;
        prevOpCode = info.opcode;
        m_lastLine = info.lineno;
    }
}