The main purpose of this PR is to remove the `'static` lifetime bound in
type OpCreator =
fn(state: &Arc<IsolateState>, base: &msg::Base, data: &'static mut [u8])
-> Box<Op>;
The reason is simple: it is plain wrong, the `data` is actually not `'static`. It is created when the message is sent from C side, and will be recycled when the message is responded. It violates the definition of `'static` lifetime.
If someone save this pointer somewhere else, and reuse it later again, uninitialized memory could be accessed. This kind of memory unsafety does not happen yet because the logic is carefully organized in this project. Lifetime constraints are maintained by code convention. It could be more robust if we can express this constraint by Rust's type system.
Basic idea: tie buffer's lifetime to an object's lifetime, a.k.a, RAII. The type `deno_buf` is pretty suitable for this job.
Ensure that at most one mutable Isolate reference exists at a time.
`deno_execute()` and `deno_respond()` now borrow a reference to the rust-side
isolate from the caller. When we need a reference to the isolate while one of
these functions is on the stack, `deno_get_data()` can be used to borrow back
that reference.
This is a large API refactor of deno.h which replaces
deno_send() and deno_set_response() with deno_respond().
It also adds a req_id parameter to the deno_recv_cb.
Make writeFile/writeFileSync use it.