Ejemplo n.º 1
0
int handle_vars(struct JsonlangVm *vm, PyObject *map, int code, int tla)
{
    if (map == NULL) return 1;

    PyObject *key, *val;
    Py_ssize_t pos = 0;
    
    while (PyDict_Next(map, &pos, &key, &val)) {
        const char *key_ = PyString_AsString(key);
        if (key_ == NULL) {
            jsonlang_destroy(vm);
            return 0;
        }
        const char *val_ = PyString_AsString(val);
        if (val_ == NULL) {
            jsonlang_destroy(vm);
            return 0;
        }
        if (!tla && !code) {
            jsonlang_ext_var(vm, key_, val_);
        } else if (!tla && code) {
            jsonlang_ext_code(vm, key_, val_);
        } else if (tla && !code) {
            jsonlang_tla_var(vm, key_, val_);
        } else {
            jsonlang_tla_code(vm, key_, val_);
        }
    }
    return 1;
}
Ejemplo n.º 2
0
static PyObject* evaluate_snippet(PyObject* self, PyObject* args, PyObject *keywds)
{
    const char *filename, *src;
    char *out;
    unsigned max_stack = 500, gc_min_objects = 1000, max_trace = 20;
    double gc_growth_trigger = 2;
    int debug_ast = 0, error;
    PyObject *ext_vars = NULL;
    struct jsonlangVm *vm;
    static char *kwlist[] = {"filename", "src", "max_stack", "gc_min_objects", "gc_growth_trigger", "ext_vars", "debug_ast", "max_trace", NULL};

    (void) self;

    if (!PyArg_ParseTupleAndKeywords(args, keywds, "ss|IIdOiI", kwlist,
                                     &filename, &src,
                                     &max_stack, &gc_min_objects, &gc_growth_trigger, &ext_vars, &debug_ast, &max_trace)) {
        return NULL;
    }

    vm = jsonlang_make();
    jsonlang_max_stack(vm, max_stack);
    jsonlang_gc_min_objects(vm, gc_min_objects);
    jsonlang_max_trace(vm, max_trace);
    jsonlang_gc_growth_trigger(vm, gc_growth_trigger);
    jsonlang_debug_ast(vm, debug_ast);
    if (ext_vars != NULL) {
        PyObject *key, *val;
        Py_ssize_t pos = 0;

        while (PyDict_Next(ext_vars, &pos, &key, &val)) {
            const char *key_ = PyString_AsString(key);
            if (key_ == NULL) {
                jsonlang_destroy(vm);
                return NULL;
            }
            const char *val_ = PyString_AsString(val);
            if (val_ == NULL) {
                jsonlang_destroy(vm);
                return NULL;
            }
            jsonlang_ext_var(vm, key_, val_);
        }
    }

    out = jsonlang_evaluate_snippet(vm, filename, src, &error);
    if (error) {
        PyErr_SetString(PyExc_RuntimeError, out);
        jsonlang_realloc(vm, out, 0);
        jsonlang_destroy(vm);
        return NULL;
    } else {
        PyObject *ret = PyString_FromString(out);
        jsonlang_realloc(vm, out, 0);
        jsonlang_destroy(vm);
        return ret;
    }
}
Ejemplo n.º 3
0
static PyObject *handle_result(struct JsonlangVm *vm, char *out, int error)
{
    if (error) {
        PyErr_SetString(PyExc_RuntimeError, out);
        jsonlang_realloc(vm, out, 0);
        jsonlang_destroy(vm);
        return NULL;
    } else {
        PyObject *ret = PyString_FromString(out);
        jsonlang_realloc(vm, out, 0);
        jsonlang_destroy(vm);
        return ret;
    }
}
Ejemplo n.º 4
0
int handle_import_callback(struct ImportCtx *ctx, PyObject *import_callback)
{
    if (import_callback == NULL) return 1;

    if (!PyCallable_Check(import_callback)) {
        jsonlang_destroy(ctx->vm);
        PyErr_SetString(PyExc_TypeError, "import_callback must be callable");
        return 0;
    }

    jsonlang_import_callback(ctx->vm, cpython_import_callback, ctx);

    return 1;
}
Ejemplo n.º 5
0
/** Register native callbacks with Jsonlang VM.
 *
 * Example native_callbacks = { 'name': (('p1', 'p2', 'p3'), func) }
 *
 * May set *ctxs, in which case it should be free()'d by caller.
 *
 * \returns 1 on success, 0 with exception set upon failure.
 */
static int handle_native_callbacks(struct JsonlangVm *vm, PyObject *native_callbacks,
                                   struct NativeCtx **ctxs)
{
    size_t num_natives = 0;
    PyObject *key, *val;
    Py_ssize_t pos = 0;

    if (native_callbacks == NULL) return 1;

    /* Verify the input before we allocate memory, throw all errors at this point.
     * Also, count the callbacks to see how much memory we need.
     */
    while (PyDict_Next(native_callbacks, &pos, &key, &val)) {
        Py_ssize_t i;
        Py_ssize_t num_params;
        PyObject *params;
        const char *key_ = PyString_AsString(key);
        if (key_ == NULL) {
            PyErr_SetString(PyExc_TypeError, "native callback dict keys must be string");
            goto bad;
        }
        if (!PyTuple_Check(val)) {
            PyErr_SetString(PyExc_TypeError, "native callback dict values must be tuples");
            goto bad;
        } else if (PyTuple_Size(val) != 2) {
            PyErr_SetString(PyExc_TypeError, "native callback tuples must have size 2");
            goto bad;
        }
        params = PyTuple_GetItem(val, 0);
        if (!PyTuple_Check(params)) {
            PyErr_SetString(PyExc_TypeError, "native callback params must be a tuple");
            goto bad;
        }
        /* Check the params are all strings */
        num_params = PyTuple_Size(params);
        for (i = 0; i < num_params ; ++i) {
            PyObject *param = PyTuple_GetItem(params, 0);
            if (!PyString_Check(param)) {
                PyErr_SetString(PyExc_TypeError, "native callback param must be string");
                goto bad;
            }
        }
        if (!PyCallable_Check(PyTuple_GetItem(val, 1))) {
            PyErr_SetString(PyExc_TypeError, "native callback must be callable");
            goto bad;
        }

        num_natives++;
        continue;

        bad:
        jsonlang_destroy(vm);
        return 0;
    }

    if (num_natives == 0) {
        return 1;
    }

    *ctxs = malloc(sizeof(struct NativeCtx) * num_natives);
    
    /* Re-use num_natives but just as a counter this time. */
    num_natives = 0;
    pos = 0;
    while (PyDict_Next(native_callbacks, &pos, &key, &val)) {
        Py_ssize_t i;
        Py_ssize_t num_params;
        PyObject *params;
        const char *key_ = PyString_AsString(key);
        params = PyTuple_GetItem(val, 0);
        num_params = PyTuple_Size(params);
        /* Include space for terminating NULL. */
        const char **params_c = malloc(sizeof(const char*) * (num_params + 1));
        for (i = 0; i < num_params ; ++i) {
            params_c[i] = PyString_AsString(PyTuple_GetItem(params, i));
        }
        params_c[num_params] = NULL;
        (*ctxs)[num_natives].vm = vm;
        (*ctxs)[num_natives].callback = PyTuple_GetItem(val, 1);
        (*ctxs)[num_natives].argc = num_params;
        jsonlang_native_callback(vm, key_, cpython_native_callback, &(*ctxs)[num_natives],
                                params_c);
        free(params_c);
        num_natives++;
    }

    return 1;
}