pub unsafe fn run(&self, context: &mut WeldContext, arg: &WeldValue) -> WeldResult<WeldValue> {
        let start = PreciseTime::now();
        let nworkers = context.context.borrow().threads();
        let mem_limit = context.context.borrow().memory_limit();

        // Borrow the inner context mutably since we pass a mutable pointer to it to the compiled
        // module. This enforces the single-mutable-borrow rule manually for contexts.
        let mut context_borrowed = context.context.borrow_mut();

        let (raw, result) = {
            // This is the required input format of data passed into a compiled module.
            let input = Box::new(codegen::WeldInputArgs {
                input: arg.data as i64,
                nworkers,
                mem_limit,
                run: context.context.as_ptr() as i64,
            });
            let ptr = Box::into_raw(input) as i64;

            // Runs the Weld program.
            let raw = self.llvm_module.run(ptr) as *const codegen::WeldOutputArgs;
            let result = (*raw).clone();

            // Free the boxed input.
            let _ = Box::from_raw(ptr as *mut codegen::WeldInputArgs);

            (raw, result)
        };

        let value = WeldValue {
            data: result.output as Data,
            run: None,
            context: Some(context.clone()),
        };

        let end = PreciseTime::now();
        let duration = start.to(end);
        let us = duration.num_microseconds().unwrap_or(std::i64::MAX);
        let ms: f64 = us as f64 / 1000.0;
        debug!(
            "Ran module UUID={} in {} ms",
            self.module_id.to_hyphenated(),
            ms
        );

        // Check whether the run was successful -- if not, free the data in the module, andn return
        // an error indicating what went wrong.
        if result.errno != WeldRuntimeErrno::Success {
            // The WeldValue is automatically dropped and freed here.
            let message =
                CString::new(format!("Weld program failed with error {:?}", result.errno)).unwrap();
            Err(WeldError::new(message, result.errno))
        } else {
            // Free the WeldOutputArgs struct.
            context_borrowed.free(raw as *mut u8);
            Ok(value)
        }
    }
Run this `WeldModule` with a context and argument.

This is the entry point for running a Weld program. The argument is a `WeldValue` that
encapsulates a pointer to the argument. See the section below about how this argument
should be structured.

The context captures _state_: in particular, it holds the memory allocated by a `run`.
Contexts can be reused across runs and modules. Contexts are primarily useful for passing
mutable state---builders---in and out of Weld and updating them in place. For example, a
program can compute some partial result, return a builder, and then pass the builder as a
`WeldValue` back into `run` _with the same context_ to continue updating that builder.

Contexts are not thread-safe---this is enforced in Rust by having this function take a
mutable reference to a context. If a context is cloned, this constraint is maintained via
_interior mutability_: contexts internally hold a `RefCell` that is mutably borrowed by
this function, so a panic will be thrown if multiple callers try to `run` a module with the
same context.

# Structuring Arguments

This function takes a `WeldValue` initialized using `WeldValue::new_from_data` or another Weld
program. The value must encapsulate a valid pointer in a "Weld-compatible" format as
specified by the [specification](https://github.com/weld-project/weld/blob/master/docs/api.md).
This method is, as a result, `unsafe` because passing invalid data into a Weld program will
cause undefined behavior.

Note that most Rust values cannot be passed into Weld directly. For example, it is *not*
safe to simply pass a raw pointer to a `Vec<T>` into Weld directly.

# Errors

This method may return any of the errors specified in `WeldRuntimeErrno`, if a runtime
error occurs during the execution of the program. Currently, the implementation panics if a
runtime error is thrown.

# Panics

The current implementation panics whenever the runtime throws an error. This function will
also panic if the same context is passed to `run` at once (this is possible if, e.g., if a
context is cloned).

# Examples

```rust,no_run
use weld::*;
use std::cell::Cell;

// Wrap in Cell so we can get a raw pointer
let input = Cell::new(1 as i32);
let conf = &WeldConf::new();

// Program that adds one to an i32.
let mut module = WeldModule::compile("|x: i32| x + 1", conf).unwrap();
let input_value = &WeldValue::new_from_data(input.as_ptr() as Data);
let context = &mut WeldContext::new(conf).unwrap();

// Running is unsafe, since we're outside of Rust in JIT'd code, operating over
// raw pointers.
let result = unsafe { module.run(context, input_value).unwrap() };

assert!(result.context().is_some());

// Unsafe to read raw pointers!
unsafe {
// The data is just a raw pointer: cast it to the expected type.
let data = result.data() as *const i32;

let result = (*data).clone();
assert_eq!(input.get() + 1, result);
}
```
weld/src/lib.rs