#include "Python.h"
#include "code.h"
#include "structmember.h"

#define NAME_CHARS \
	"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"

/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */

static int
all_name_chars(Py_UNICODE *s)
{
	static char ok_name_char[256];
	static unsigned char *name_chars = (unsigned char *)NAME_CHARS;

	if (ok_name_char[*name_chars] == 0) {
		unsigned char *p;
		for (p = name_chars; *p; p++)
			ok_name_char[*p] = 1;
	}
	while (*s) {
		if (*s >= 128)
			return 0;
		if (ok_name_char[*s++] == 0)
			return 0;
	}
	return 1;
}

static void
intern_strings(PyObject *tuple)
{
	Py_ssize_t i;

	for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
		PyObject *v = PyTuple_GET_ITEM(tuple, i);
		if (v == NULL || !PyUnicode_CheckExact(v)) {
			Py_FatalError("non-string found in code slot");
		}
		PyUnicode_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
	}
}


PyCodeObject *
PyCode_New(int argcount, int kwonlyargcount,
	   int nlocals, int stacksize, int flags,
	   PyObject *code, PyObject *consts, PyObject *names,
	   PyObject *varnames, PyObject *freevars, PyObject *cellvars,
	   PyObject *filename, PyObject *name, int firstlineno,
	   PyObject *lnotab)
{
	PyCodeObject *co;
	Py_ssize_t i;

	/* Check argument types */
	if (argcount < 0 || nlocals < 0 ||
	    code == NULL ||
	    consts == NULL || !PyTuple_Check(consts) ||
	    names == NULL || !PyTuple_Check(names) ||
	    varnames == NULL || !PyTuple_Check(varnames) ||
	    freevars == NULL || !PyTuple_Check(freevars) ||
	    cellvars == NULL || !PyTuple_Check(cellvars) ||
	    name == NULL || !PyUnicode_Check(name) ||
	    filename == NULL || !PyUnicode_Check(filename) ||
	    lnotab == NULL || !PyString_Check(lnotab) ||
	    !PyObject_CheckReadBuffer(code)) {
		PyErr_BadInternalCall();
		return NULL;
	}
	intern_strings(names);
	intern_strings(varnames);
	intern_strings(freevars);
	intern_strings(cellvars);
	/* Intern selected string constants */
	for (i = PyTuple_Size(consts); --i >= 0; ) {
		PyObject *v = PyTuple_GetItem(consts, i);
		if (!PyUnicode_Check(v))
			continue;
		if (!all_name_chars(PyUnicode_AS_UNICODE(v)))
			continue;
		PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i));
	}
	co = PyObject_NEW(PyCodeObject, &PyCode_Type);
	if (co != NULL) {
		co->co_argcount = argcount;
		co->co_kwonlyargcount = kwonlyargcount;
		co->co_nlocals = nlocals;
		co->co_stacksize = stacksize;
		co->co_flags = flags;
		Py_INCREF(code);
		co->co_code = code;
		Py_INCREF(consts);
		co->co_consts = consts;
		Py_INCREF(names);
		co->co_names = names;
		Py_INCREF(varnames);
		co->co_varnames = varnames;
		Py_INCREF(freevars);
		co->co_freevars = freevars;
		Py_INCREF(cellvars);
		co->co_cellvars = cellvars;
		Py_INCREF(filename);
		co->co_filename = filename;
		Py_INCREF(name);
		co->co_name = name;
		co->co_firstlineno = firstlineno;
		Py_INCREF(lnotab);
		co->co_lnotab = lnotab;
                co->co_zombieframe = NULL;
	}
	return co;
}


#define OFF(x) offsetof(PyCodeObject, x)

static PyMemberDef code_memberlist[] = {
	{"co_argcount",	T_INT,		OFF(co_argcount),	READONLY},
	{"co_kwonlyargcount",	T_INT,	OFF(co_kwonlyargcount),	READONLY},
	{"co_nlocals",	T_INT,		OFF(co_nlocals),	READONLY},
	{"co_stacksize",T_INT,		OFF(co_stacksize),	READONLY},
	{"co_flags",	T_INT,		OFF(co_flags),		READONLY},
	{"co_code",	T_OBJECT,	OFF(co_code),		READONLY},
	{"co_consts",	T_OBJECT,	OFF(co_consts),		READONLY},
	{"co_names",	T_OBJECT,	OFF(co_names),		READONLY},
	{"co_varnames",	T_OBJECT,	OFF(co_varnames),	READONLY},
	{"co_freevars",	T_OBJECT,	OFF(co_freevars),	READONLY},
	{"co_cellvars",	T_OBJECT,	OFF(co_cellvars),	READONLY},
	{"co_filename",	T_OBJECT,	OFF(co_filename),	READONLY},
	{"co_name",	T_OBJECT,	OFF(co_name),		READONLY},
	{"co_firstlineno", T_INT,	OFF(co_firstlineno),	READONLY},
	{"co_lnotab",	T_OBJECT,	OFF(co_lnotab),		READONLY},
	{NULL}	/* Sentinel */
};

/* Helper for code_new: return a shallow copy of a tuple that is
   guaranteed to contain exact strings, by converting string subclasses
   to exact strings and complaining if a non-string is found. */
static PyObject*
validate_and_copy_tuple(PyObject *tup)
{
	PyObject *newtuple;
	PyObject *item;
	Py_ssize_t i, len;

	len = PyTuple_GET_SIZE(tup);
	newtuple = PyTuple_New(len);
	if (newtuple == NULL)
		return NULL;

	for (i = 0; i < len; i++) {
		item = PyTuple_GET_ITEM(tup, i);
		if (PyUnicode_CheckExact(item)) {
			Py_INCREF(item);
		}
		else if (!PyUnicode_Check(item)) {
			PyErr_Format(
				PyExc_TypeError,
				"name tuples must contain only "
				"strings, not '%.500s'",
				item->ob_type->tp_name);
			Py_DECREF(newtuple);
			return NULL;
		}
		else {
			item = PyUnicode_FromUnicode(
				PyUnicode_AS_UNICODE(item),
				PyUnicode_GET_SIZE(item));
			if (item == NULL) {
				Py_DECREF(newtuple);
				return NULL;
			}
		}
		PyTuple_SET_ITEM(newtuple, i, item);
	}

	return newtuple;
}

PyDoc_STRVAR(code_doc,
"code(argcount, kwonlyargcount nlocals, stacksize, flags, codestring,\n\
      constants, names, varnames, filename, name, firstlineno,\n\
      lnotab[, freevars[, cellvars]])\n\
\n\
Create a code object.  Not for the faint of heart.");

static PyObject *
code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
	int argcount;
	int kwonlyargcount;
	int nlocals;
	int stacksize;
	int flags;
	PyObject *co = NULL;
	PyObject *code;
	PyObject *consts;
	PyObject *names, *ournames = NULL;
	PyObject *varnames, *ourvarnames = NULL;
	PyObject *freevars = NULL, *ourfreevars = NULL;
	PyObject *cellvars = NULL, *ourcellvars = NULL;
	PyObject *filename;
	PyObject *name;
	int firstlineno;
	PyObject *lnotab;

	if (!PyArg_ParseTuple(args, "iiiiiSO!O!O!UUiS|O!O!:code",
			      &argcount, &kwonlyargcount,
				  &nlocals, &stacksize, &flags,
			      &code,
			      &PyTuple_Type, &consts,
			      &PyTuple_Type, &names,
			      &PyTuple_Type, &varnames,
			      &filename, &name,
			      &firstlineno, &lnotab,
			      &PyTuple_Type, &freevars,
			      &PyTuple_Type, &cellvars))
		return NULL;

	if (argcount < 0) {
		PyErr_SetString(
			PyExc_ValueError,
			"code: argcount must not be negative");
		goto cleanup;
	}

	if (kwonlyargcount < 0) {
		PyErr_SetString(
			PyExc_ValueError,
			"code: kwonlyargcount must not be negative");
		goto cleanup;
	}
	if (nlocals < 0) {
		PyErr_SetString(
			PyExc_ValueError,
			"code: nlocals must not be negative");
		goto cleanup;
	}

	ournames = validate_and_copy_tuple(names);
	if (ournames == NULL)
		goto cleanup;
	ourvarnames = validate_and_copy_tuple(varnames);
	if (ourvarnames == NULL)
		goto cleanup;
	if (freevars)
		ourfreevars = validate_and_copy_tuple(freevars);
	else
		ourfreevars = PyTuple_New(0);
	if (ourfreevars == NULL)
		goto cleanup;
	if (cellvars)
		ourcellvars = validate_and_copy_tuple(cellvars);
	else
		ourcellvars = PyTuple_New(0);
	if (ourcellvars == NULL)
		goto cleanup;

	co = (PyObject *)PyCode_New(argcount, kwonlyargcount,
				    nlocals, stacksize, flags,
				    code, consts, ournames, ourvarnames,
				    ourfreevars, ourcellvars, filename,
				    name, firstlineno, lnotab);
  cleanup:
	Py_XDECREF(ournames);
	Py_XDECREF(ourvarnames);
	Py_XDECREF(ourfreevars);
	Py_XDECREF(ourcellvars);
	return co;
}

static void
code_dealloc(PyCodeObject *co)
{
	Py_XDECREF(co->co_code);
	Py_XDECREF(co->co_consts);
	Py_XDECREF(co->co_names);
	Py_XDECREF(co->co_varnames);
	Py_XDECREF(co->co_freevars);
	Py_XDECREF(co->co_cellvars);
	Py_XDECREF(co->co_filename);
	Py_XDECREF(co->co_name);
	Py_XDECREF(co->co_lnotab);
        if (co->co_zombieframe != NULL)
                PyObject_GC_Del(co->co_zombieframe);
	PyObject_DEL(co);
}

static PyObject *
code_repr(PyCodeObject *co)
{
	int lineno = -1;
	char *filename = "???";

	if (co->co_firstlineno != 0)
		lineno = co->co_firstlineno;
	if (co->co_filename && PyUnicode_Check(co->co_filename))
		filename = PyUnicode_AsString(co->co_filename);
	return PyUnicode_FromFormat(
	                "<code object %.100U at %p, file \"%.300s\", line %d>",
	                co->co_name, co, filename, lineno);
}

static PyObject *
code_richcompare(PyObject *self, PyObject *other, int op)
{
	PyCodeObject *co, *cp;
	int eq;
	PyObject *res;

	if ((op != Py_EQ && op != Py_NE) ||
	    !PyCode_Check(self) ||
	    !PyCode_Check(other)) {
		Py_INCREF(Py_NotImplemented);
		return Py_NotImplemented;
	}

	co = (PyCodeObject *)self;
	cp = (PyCodeObject *)other;

	eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
	if (eq <= 0) goto unequal;
	eq = co->co_argcount == cp->co_argcount;
	if (!eq) goto unequal;
	eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
	if (!eq) goto unequal;
	eq = co->co_nlocals == cp->co_nlocals;
	if (!eq) goto unequal;
	eq = co->co_flags == cp->co_flags;
	if (!eq) goto unequal;
	eq = co->co_firstlineno == cp->co_firstlineno;
	if (!eq) goto unequal;
	eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
	if (eq <= 0) goto unequal;
	eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ);
	if (eq <= 0) goto unequal;
	eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
	if (eq <= 0) goto unequal;
	eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
	if (eq <= 0) goto unequal;
	eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
	if (eq <= 0) goto unequal;
	eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
	if (eq <= 0) goto unequal;

	if (op == Py_EQ)
		res = Py_True;
	else
		res = Py_False;
	goto done;

  unequal:
	if (eq < 0)
		return NULL;
	if (op == Py_NE)
		res = Py_True;
	else
		res = Py_False;

  done:
	Py_INCREF(res);
	return res;
}

static long
code_hash(PyCodeObject *co)
{
	long h, h0, h1, h2, h3, h4, h5, h6;
	h0 = PyObject_Hash(co->co_name);
	if (h0 == -1) return -1;
	h1 = PyObject_Hash(co->co_code);
	if (h1 == -1) return -1;
	h2 = PyObject_Hash(co->co_consts);
	if (h2 == -1) return -1;
	h3 = PyObject_Hash(co->co_names);
	if (h3 == -1) return -1;
	h4 = PyObject_Hash(co->co_varnames);
	if (h4 == -1) return -1;
	h5 = PyObject_Hash(co->co_freevars);
	if (h5 == -1) return -1;
	h6 = PyObject_Hash(co->co_cellvars);
	if (h6 == -1) return -1;
	h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
		co->co_argcount ^ co->co_kwonlyargcount ^
		co->co_nlocals ^ co->co_flags;
	if (h == -1) h = -2;
	return h;
}

/* XXX code objects need to participate in GC? */

PyTypeObject PyCode_Type = {
	PyVarObject_HEAD_INIT(&PyType_Type, 0)
	"code",
	sizeof(PyCodeObject),
	0,
	(destructor)code_dealloc, 	/* tp_dealloc */
	0,				/* tp_print */
	0, 				/* tp_getattr */
	0,				/* tp_setattr */
	0,		 		/* tp_compare */
	(reprfunc)code_repr,		/* tp_repr */
	0,				/* tp_as_number */
	0,				/* tp_as_sequence */
	0,				/* tp_as_mapping */
	(hashfunc)code_hash, 		/* tp_hash */
	0,				/* tp_call */
	0,				/* tp_str */
	PyObject_GenericGetAttr,	/* tp_getattro */
	0,				/* tp_setattro */
	0,				/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT,		/* tp_flags */
	code_doc,			/* tp_doc */
	0,				/* tp_traverse */
	0,				/* tp_clear */
	code_richcompare,		/* tp_richcompare */
	0,				/* tp_weaklistoffset */
	0,				/* tp_iter */
	0,				/* tp_iternext */
	0,				/* tp_methods */
	code_memberlist,		/* tp_members */
	0,				/* tp_getset */
	0,				/* tp_base */
	0,				/* tp_dict */
	0,				/* tp_descr_get */
	0,				/* tp_descr_set */
	0,				/* tp_dictoffset */
	0,				/* tp_init */
	0,				/* tp_alloc */
	code_new,			/* tp_new */
};

/* All about c_lnotab.

c_lnotab is an array of unsigned bytes disguised as a Python string.  In -O
mode, SET_LINENO opcodes aren't generated, and bytecode offsets are mapped
to source code line #s (when needed for tracebacks) via c_lnotab instead.
The array is conceptually a list of
    (bytecode offset increment, line number increment)
pairs.  The details are important and delicate, best illustrated by example:

    byte code offset    source code line number
        0		    1
        6		    2
       50		    7
      350                 307
      361                 308

The first trick is that these numbers aren't stored, only the increments
from one row to the next (this doesn't really work, but it's a start):

    0, 1,  6, 1,  44, 5,  300, 300,  11, 1

The second trick is that an unsigned byte can't hold negative values, or
values larger than 255, so (a) there's a deep assumption that byte code
offsets and their corresponding line #s both increase monotonically, and (b)
if at least one column jumps by more than 255 from one row to the next, more
than one pair is written to the table. In case #b, there's no way to know
from looking at the table later how many were written.  That's the delicate
part.  A user of c_lnotab desiring to find the source line number
corresponding to a bytecode address A should do something like this

    lineno = addr = 0
    for addr_incr, line_incr in c_lnotab:
        addr += addr_incr
        if addr > A:
            return lineno
        lineno += line_incr

In order for this to work, when the addr field increments by more than 255,
the line # increment in each pair generated must be 0 until the remaining addr
increment is < 256.  So, in the example above, com_set_lineno should not (as
was actually done until 2.2) expand 300, 300 to 255, 255,  45, 45, but to
255, 0,  45, 255,  0, 45.
*/

int
PyCode_Addr2Line(PyCodeObject *co, int addrq)
{
	int size = PyString_Size(co->co_lnotab) / 2;
	unsigned char *p = (unsigned char*)PyString_AsString(co->co_lnotab);
	int line = co->co_firstlineno;
	int addr = 0;
	while (--size >= 0) {
		addr += *p++;
		if (addr > addrq)
			break;
		line += *p++;
	}
	return line;
}

/* 
   Check whether the current instruction is at the start of a line.

 */

	/* The theory of SET_LINENO-less tracing.

	   In a nutshell, we use the co_lnotab field of the code object
	   to tell when execution has moved onto a different line.

	   As mentioned above, the basic idea is so set things up so
	   that

	         *instr_lb <= frame->f_lasti < *instr_ub

	   is true so long as execution does not change lines.

	   This is all fairly simple.  Digging the information out of
	   co_lnotab takes some work, but is conceptually clear.

	   Somewhat harder to explain is why we don't *always* call the
	   line trace function when the above test fails.

	   Consider this code:

	   1: def f(a):
	   2:     if a:
	   3:        print 1
	   4:     else:
	   5:        print 2

	   which compiles to this:

	   2           0 LOAD_FAST                0 (a)
		       3 JUMP_IF_FALSE            9 (to 15)
		       6 POP_TOP

	   3           7 LOAD_CONST               1 (1)
		      10 PRINT_ITEM
		      11 PRINT_NEWLINE
		      12 JUMP_FORWARD             6 (to 21)
		 >>   15 POP_TOP

	   5          16 LOAD_CONST               2 (2)
		      19 PRINT_ITEM
		      20 PRINT_NEWLINE
		 >>   21 LOAD_CONST               0 (None)
		      24 RETURN_VALUE

	   If 'a' is false, execution will jump to instruction at offset
	   15 and the co_lnotab will claim that execution has moved to
	   line 3.  This is at best misleading.  In this case we could
	   associate the POP_TOP with line 4, but that doesn't make
	   sense in all cases (I think).

	   What we do is only call the line trace function if the co_lnotab
	   indicates we have jumped to the *start* of a line, i.e. if the
	   current instruction offset matches the offset given for the
	   start of a line by the co_lnotab.

	   This also takes care of the situation where 'a' is true.
	   Execution will jump from instruction offset 12 to offset 21.
	   Then the co_lnotab would imply that execution has moved to line
	   5, which is again misleading.

	   Why do we set f_lineno when tracing?  Well, consider the code
	   above when 'a' is true.  If stepping through this with 'n' in
	   pdb, you would stop at line 1 with a "call" type event, then
	   line events on lines 2 and 3, then a "return" type event -- but
	   you would be shown line 5 during this event.  This is a change
	   from the behaviour in 2.2 and before, and I've found it
	   confusing in practice.  By setting and using f_lineno when
	   tracing, one can report a line number different from that
	   suggested by f_lasti on this one occasion where it's desirable.
	*/


int 
PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
{
        int size, addr, line;
        unsigned char* p;

        p = (unsigned char*)PyString_AS_STRING(co->co_lnotab);
        size = PyString_GET_SIZE(co->co_lnotab) / 2;

        addr = 0;
        line = co->co_firstlineno;
        assert(line > 0);

        /* possible optimization: if f->f_lasti == instr_ub
           (likely to be a common case) then we already know
           instr_lb -- if we stored the matching value of p
           somwhere we could skip the first while loop. */

        /* see comments in compile.c for the description of
           co_lnotab.  A point to remember: increments to p
           should come in pairs -- although we don't care about
           the line increments here, treating them as byte
           increments gets confusing, to say the least. */

        bounds->ap_lower = 0;
        while (size > 0) {
                if (addr + *p > lasti)
                        break;
                addr += *p++;
                if (*p) 
                        bounds->ap_lower = addr;
                line += *p++;
                --size;
        }

        /* If lasti and addr don't match exactly, we don't want to
           change the lineno slot on the frame or execute a trace
           function.  Return -1 instead.
        */
        if (addr != lasti)
                line = -1;
        
        if (size > 0) {
                while (--size >= 0) {
                        addr += *p++;
                        if (*p++)
                                break;
                }
                bounds->ap_upper = addr;
        }
        else {
                bounds->ap_upper = INT_MAX;
        }

        return line;
}
