Esempio n. 1
0
static PyObject *
frame_getlocals(PyFrameObject *f, void *closure)
{
	PyFrame_FastToLocals(f);
	Py_INCREF(f->f_locals);
	return f->f_locals;
}
Esempio n. 2
0
static int
_adbobj_trace_trampoline(AdbObject *self, PyFrameObject *frame, int what,
                PyObject *arg)
{
    int result;
#ifdef DEBUG_PRINT
    fprintf(stderr, "_adbobj_trace_trampoline...\n");
#endif
    PyFrame_FastToLocals(frame);
    result = _adbobj_trace_dispatch(self, frame, what, arg);
    PyFrame_LocalsToFast(frame, 1);
    if (result == -1) {
        PyTraceBack_Here(frame);
        PyEval_SetTrace(NULL, NULL);
        Py_XDECREF(frame->f_trace);
        frame->f_trace = NULL;
#ifdef DEBUG_PRINT
        fprintf(stderr, "..._adbobj_trace_trampoline NULL result\n");
#endif
    }
#ifdef DEBUG_PRINT
    fprintf(stderr, "..._adbobj_trace_trampoline %d\n", result);
#endif
    return result;
}
//=============================================================================
// METHOD: SPELLvariableMonitor::registerVariable()
//=============================================================================
bool SPELLvariableMonitor::registerVariable( SPELLvarInfo& var )
{
	SPELLsafePythonOperations ops("SPELLvariableMonitor::registerVariable()");

	if ((m_frame->f_globals)&&(var.isGlobal))
	{
		var.varValue = PYSSTR( PyDict_GetItemString( m_frame->f_globals, var.varName.c_str() ));
		if (var.varValue == "") var.varValue = EMPTY_STRING;
		var.varType = PYSSTR( PyObject_Type( PyDict_GetItemString( m_frame->f_globals, var.varName.c_str() )) );
		var.isGlobal = true;
		var.isRegistered = true;
		m_variables.insert( std::make_pair( var.varName, var ) );
		DEBUG("[VM] Registered global variable: " + var.varName + ", current value: " + var.varValue );
		return true;
	}
	else if ((m_frame->f_locals)&&(!var.isGlobal))
	{
		// We need to retrieve the function arguments and other locals, which are only stored in
		// fast locals by default
		PyFrame_FastToLocals(m_frame);
		var.varValue = PYSSTR( PyDict_GetItemString( m_frame->f_locals, var.varName.c_str() ));
		if (var.varValue == "") var.varValue = EMPTY_STRING;
		var.varType = PYSSTR( PyObject_Type( PyDict_GetItemString( m_frame->f_locals, var.varName.c_str() )) );
		var.isGlobal = true;
		var.isRegistered = true;
		m_variables.insert( std::make_pair( var.varName, var ) );
		DEBUG("[VM] Registered local variable: " + var.varName + ", current value: " + var.varValue );
		return true;
	}
	var.varValue = "???";
	var.varType = "???";
	var.isRegistered = false;
	DEBUG("[VM] No such variable: " + var.varName);
	return false;
}
Esempio n. 4
0
static PyObject *
frame_getattr(PyFrameObject *f, char *name)
{
	if (strcmp(name, "f_locals") == 0)
		PyFrame_FastToLocals(f);
	return PyMember_Get((char *)f, frame_memberlist, name);
}
Esempio n. 5
0
// maps the PyCodeObject to our internal pit item via hash table.
static _pit *
_code2pit(PyFrameObject *fobj)
{
    _hitem *it;
    PyCodeObject *cobj;
    _pit *pit;

    cobj = fobj->f_code;
    it = hfind(current_ctx->pits, (uintptr_t)cobj);
    if (it) {
        return ((_pit *)it->val);
    }

    pit = _create_pit();
    if (!pit)
        return NULL;
    if (!hadd(current_ctx->pits, (uintptr_t)cobj, (uintptr_t)pit))
        return NULL;

    pit->name = NULL;
    Py_INCREF(cobj->co_filename);
    pit->modname = cobj->co_filename;
    pit->lineno = cobj->co_firstlineno;

    PyFrame_FastToLocals(fobj);
    if (cobj->co_argcount) {
        const char *firstarg = PyStr_AS_CSTRING(PyTuple_GET_ITEM(cobj->co_varnames, 0));

        if (!strcmp(firstarg, "self")) {
            PyObject* locals = fobj->f_locals;
            if (locals) {
                PyObject* self = PyDict_GetItemString(locals, "self");
                if (self) {
                    PyObject *class_obj = PyObject_GetAttrString(self, "__class__");
                    if (class_obj) {
                        PyObject *class_name = PyObject_GetAttrString(class_obj, "__name__");
                        if (class_name) {
                            pit->name = PyStr_FromFormat("%s.%s", PyStr_AS_CSTRING(class_name), PyStr_AS_CSTRING(cobj->co_name));
                            Py_DECREF(class_name);
                        }
                        Py_DECREF(class_obj);
                    }
                }
            }
        }
    }
    if (!pit->name) {
        Py_INCREF(cobj->co_name);
        pit->name = cobj->co_name;
    }

    PyFrame_LocalsToFast(fobj, 0);

    return pit;
}
//=============================================================================
// METHOD: SPELLvariableMonitor::retrieveLocalVariables()
//=============================================================================
void SPELLvariableMonitor::retrieveLocalVariables(std::vector<SPELLvarInfo>& vars)
{
	DEBUG("[VM] Retrieve Locals");

	/*
	 * Bottom stack frame is discarded,
	 * as globals and locals are the same dictionary
	 */
	if (m_frame->f_back == NULL) return;

	/*
	 * Get the names defined in the current code, including arguments
	 */
	std::vector<std::string> varNames = retrieveNames();

	/*
	 * Iterate over the locals dictionary, retrieving the names contained in
	 * varNames
	 */
	PyFrame_FastToLocals(m_frame);
	PyObject* dict = m_frame->f_locals;
	DEBUG("[VM] Frame: " + PYCREPR(m_frame));
	for( unsigned int index = 0; index< varNames.size(); index++)
	{
		std::string varName = varNames[index];
		PyObject* pyVarName = SSTRPY(varName);
		if (PyDict_Contains( dict, pyVarName ))
		{
			PyObject* object = PyDict_GetItem( dict, pyVarName );

			if (!SPELLpythonHelper::instance().isInstance(object, "Database", "spell.lib.adapter.databases.database"))
			{
				if (PyCallable_Check(object)) continue;
				if (PyClass_Check(object)) continue;
				if (PyModule_Check(object)) continue;
				if (PyInstance_Check(object)) continue;
			}
			DEBUG("[VM] Processing " + varName);
			std::string type = PYSSTR( PyObject_Type(object) );
			DEBUG("[VM] Type      : " + type);
			std::string value = PYREPR( object );
			DEBUG("[VM] Value     : " + value);
			DEBUG("[VM] Global    : " + BSTR(false));
			DEBUG("[VM] Registered: " + BSTR(isRegistered(varName)));

			// Mark empty values (empty strings) as "<empty>"
			if (value == "") value = EMPTY_STRING;

			vars.push_back( SPELLvarInfo(varName, type, value, false, isRegistered(varName)) );
		}
	}
	PyFrame_LocalsToFast(m_frame,0);
}
//=============================================================================
// METHOD: SPELLvariableMonitor::getAllVariables()
//=============================================================================
std::vector<SPELLvarInfo> SPELLvariableMonitor::getLocalVariables()
{
	SPELLsafePythonOperations ops("SPELLvariableMonitor::getLocalVariables()");
	std::vector<SPELLvarInfo> vars;

	// We need to retrieve the function arguments and other locals, which are only stored in
	// fast locals by default
	PyFrame_FastToLocals(m_frame);

	retrieveLocalVariables( vars );

	return vars;
}
//=============================================================================
// METHOD: SPELLvariableMonitor::changeVariable()
//=============================================================================
void SPELLvariableMonitor::changeVariable( SPELLvarInfo& var )
{
	SPELLsafePythonOperations ops("SPELLvariableMonitor::changeVariable()");

	DEBUG("[VM] Request changing variable " + var.varName);

	// Evaluate the value for the variable
	PyObject* value = NULL;
	// If varValue is '<empty>' or empty string, do not try to evaluate it,
	// directly assign Python empty string
	if ((var.varValue == EMPTY_STRING)||(var.varValue == ""))
	{
		value = STRPY("");
	}
	else
	{
		// Build assignment expression. We need to check first, if there
		// are double quotes, convert them to single quotes
		SPELLutils::replace(var.varValue, "\"", "'");
		DEBUG("[VM] Evaluating value expression: " + var.varValue );
		// Check value correctness and evaluate it
		value = SPELLpythonHelper::instance().eval(var.varValue, false);
	}

	if ((m_frame->f_globals)&&(var.isGlobal))
	{
		DEBUG("[VM] Setting " + var.varName + " to " + PYREPR(value) + " in globals");
		PyDict_SetItemString( m_frame->f_globals, var.varName.c_str(), value );
	}
	else if ((m_frame->f_locals)&&(!var.isGlobal))
	{
		DEBUG("[VM] Setting " + var.varName + " to " + PYREPR(value) + " in locals");
		// Update locals from fast locals first
		PyFrame_FastToLocals(m_frame);
		PyDict_SetItemString( m_frame->f_locals, var.varName.c_str(), value );
		PyFrame_LocalsToFast(m_frame,0);
	}
	var.varValue = PYSSTR(value);
	if (var.varValue == "") var.varValue = EMPTY_STRING;

	// Update the variable if it is registered, and notify to listeners
	VarMap::iterator it = m_variables.find(var.varName);
	if (it != m_variables.end())
	{
		std::vector<SPELLvarInfo> changed;
		it->second.varValue = var.varValue;
		DEBUG("[VM] Variable changed by user: "******", current value: " + var.varValue );
		changed.push_back(it->second);
		m_listener->variableChanged( changed );
	}
}
//=============================================================================
// METHOD: SPELLvariableMonitor::analyze()
//=============================================================================
void SPELLvariableMonitor::analyze()
{
	std::vector<SPELLvarInfo> changed;
	bool copyFast = true;

	VarMap::iterator it;
	for( it = m_variables.begin(); it != m_variables.end(); it++ )
	{
		std::string varName = it->first;
		std::string currentValue = "";
		std::string lastValue = "";

		if ( (it->second.isGlobal) && (m_frame->f_globals) )
		{
			PyObject* pyCurrentValue = PyDict_GetItemString( m_frame->f_globals, varName.c_str() );
			currentValue = PYSSTR(pyCurrentValue);
			lastValue = it->second.varValue;
		}
		else if ( (!it->second.isGlobal) && (m_frame->f_locals) )
		{
			if (copyFast)
			{
				copyFast = false;
				// We need to retrieve the function arguments and other locals, which are only stored in
				// fast locals by default
				PyFrame_FastToLocals(m_frame);
			}
			PyObject* pyCurrentValue = PyDict_GetItemString( m_frame->f_locals, varName.c_str() );
			currentValue = PYSSTR(pyCurrentValue);
			lastValue = it->second.varValue;
		}

		if (lastValue != currentValue)
		{
			if (currentValue == "") currentValue == EMPTY_STRING;
			DEBUG("[VM] Variable change: " + varName + ", current value: " + currentValue + ", previous: " + it->second.varValue );
			it->second.varValue = currentValue;
			changed.push_back(it->second);
		}
	}
	if (changed.size()>0)
	{
		m_listener->variableChanged( changed );
	}
}
Esempio n. 10
0
//=============================================================================
// METHOD: SPELLvariableMonitor::getAllVariables()
//=============================================================================
std::vector<SPELLvarInfo> SPELLvariableMonitor::getAllVariables()
{
	SPELLsafePythonOperations ops("SPELLvariableMonitor::getAllVariables()");
	std::vector<SPELLvarInfo> vars;
	// We need to retrieve the function arguments and other locals, which are only stored in
	// fast locals by default
	PyFrame_FastToLocals(m_frame);

	/*
	 * Get locals
	 */
	retrieveLocalVariables(vars);

	/*
	 * Get the name of the found locals to filter them while retrieving
	 * the locals
	 */
	std::set<std::string> locals;
	/*
	 * TODO maybe we should filter globals variables whose names are the same as
	 * variables found in the local scope
	 * To do this, uncomment the following loop
	 */
	/*for (unsigned int index = 0; index< vars.size(); index++)
	{
		SPELLvarInfo var = vars[index];
		locals.insert(var.varName);
	}*/

	/*
	 * Get globals
	 */
	retrieveGlobalVariables(vars, locals);

	return vars;
}
Esempio n. 11
0
static PyObject *
CapObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {

    if (kwds == NULL) {
        // PyThreadState *tstate = PyEval_SaveThread();
        PyFrameObject *frame = PyThreadState_GET()->frame;
        PyFrame_FastToLocals(frame);
        kwds = frame->f_locals;
        // PyFrame_LocalsToFast(frame, 0);
        // PyEval_RestoreThread(tstate);
    }

    PyDictObject *environ = (PyDictObject *)kwds;

    PyObject *env, *keys;
    Py_ssize_t i, size;

    Py_ssize_t mask, key_len;
    PyObject *key, *value;
    PyDictEntry *entries;
	const char* key_str;

    /* Preallocate the list of tuples, to avoid allocations during
     * the loop over the items, which could trigger GC, which
     * could resize the dict. :-(
     */

    again:

    size = environ->ma_used;

    keys = PyList_New(0);
    if (keys == NULL)
        return NULL;

    env = PyList_New(0);
    if (env == NULL)
        return NULL;

    if (size != environ->ma_used) {
        /* Durnit.  The allocations caused the dict to resize.
         * Just start over, this shouldn't normally happen.
         */
        Py_DECREF(keys);
        Py_DECREF(env);
        goto again;
    }

    entries = environ->ma_table;
    mask = environ->ma_mask;

    for (i = 0; i <= mask; i++) {
        if ((value=entries[i].me_value) != NULL) {
            key = entries[i].me_key;
            if (!PyString_CheckExact(key)) {
                Py_DECREF(keys);
                Py_DECREF(env);
                PyErr_SetString(PyExc_ValueError, "Only string keys can be used in Objects.");
                return NULL;
            }
            key_len = PyString_GET_SIZE(key);
            if (!key_len)
                continue;
            key_str = PyString_AS_STRING(key);
            if (!memcmp(key_str, single_underscore, 1)) {
                if (key_len == 1 || (memcmp(key_str, double_underscore, 2)))
                    continue;
            }
            Py_INCREF(key);
            PyList_Append(keys, key);
            Py_INCREF(value);
            PyList_Append(env, value);
       }
    }

    /* We could save more memory by sorting the keys. */

    PyObject *keys_tuple;
    PyObject **p, **q;

    size = Py_SIZE(keys);
    keys_tuple = PyTuple_New(size);
    if (keys_tuple == NULL)
        return NULL;

    p = ((PyTupleObject *)keys_tuple)->ob_item;
    q = ((PyListObject *)keys)->ob_item;

    while (--size >= 0) {
        Py_INCREF(*q);
        *p = *q;
        p++;
        q++;
    }

    long hash;
    long id;

    hash = PyObject_Hash(keys_tuple);
    if (hash == -1) {
        PyErr_SetString(PyExc_ValueError, "Cannot hash the environ keys.");
        return NULL;
    }

    environ = (PyDictObject *)_key2id_store;
    entries = (environ->ma_lookup)(environ, keys_tuple, hash);

    if ((entries == NULL) || (entries->me_value == NULL)) {
        id = _id_counter;
        _id_counter++;
        value = PyLong_FromLong(id);
        if (value == NULL)
            return NULL;
        PyDict_SetItem(_key2id_store, keys_tuple, value);
        PyDict_SetItem(_id2key_store, value, keys_tuple);
    } else {
        id = PyLong_AsLong(entries->me_value);
        if (id == -1)
            return NULL;
    }

    CapObject *self;

    self = (CapObject *)type->tp_alloc(type, 0);
    if (self != NULL) {
        self->id = id;
        self->env = env;
        self->__weakref__ = NULL;
    }

    return (PyObject *)self;

}