///|
priv struct AsyncJsonTaskHandler {
callback : async (String) -> Result[String, String]
use_json_error : Bool
}
///|
priv struct AsyncBytesTaskHandler {
callback : async (Bytes) -> Result[Bytes, String]
use_json_error : Bool
}
///|
priv struct RuntimeAsyncLoopState {
json_handlers : Map[String, AsyncJsonTaskHandler]
bytes_handlers : Map[String, AsyncBytesTaskHandler]
mut pending_tasks : Int
mut is_running : Bool
}
///|
priv struct RuntimeResourceEntry {
name : String
on_close : (() -> Unit)?
is_ref : Bool
}
///|
priv struct RuntimeResourceTableState {
mut next_rid : Int
entries : Map[Int, RuntimeResourceEntry]
}
///|
priv struct RuntimeCompatState {
mut has_deno_core_compat : Bool
mut has_node_compat : Bool
}
///|
pub struct RuntimeResource {
rid : Int
name : String
is_ref : Bool
}
///|
struct RuntimeState {
mut handle : UInt64
async_loop : RuntimeAsyncLoopState
resources : RuntimeResourceTableState
compat : RuntimeCompatState
}
///|
pub struct Runtime {
priv state : Ref[RuntimeState]
}
///|
pub fn version() -> String {
@utf8.decode_lossy(version_bytes_native())
}
///|
pub fn snapshot_create(source : String) -> Result[Bytes, V8Error] {
let err_ptr = make_ptr_buffer()
native_ptr_clear(err_ptr)
let source_bytes = @utf8.encode(source)
let snapshot = snapshot_create_native(
source_bytes,
source_bytes.length(),
err_ptr,
)
if not(native_ptr_is_null(err_ptr)) {
Err(
take_native_error(
err_ptr,
V8Error::NativeError("snapshot_create_native failed"),
),
)
} else {
Ok(snapshot)
}
}
///|
pub fn snapshot_extend(
snapshot : Bytes,
source : String,
) -> Result[Bytes, V8Error] {
let err_ptr = make_ptr_buffer()
native_ptr_clear(err_ptr)
let source_bytes = @utf8.encode(source)
let extended = snapshot_extend_native(
snapshot,
snapshot.length(),
source_bytes,
source_bytes.length(),
err_ptr,
)
if not(native_ptr_is_null(err_ptr)) {
Err(
take_native_error(
err_ptr,
V8Error::NativeError("snapshot_extend_native failed"),
),
)
} else {
Ok(extended)
}
}
///|
fn runtime_from_handle(
handle : UInt64,
err_ptr : Bytes,
fallback : V8Error,
) -> Result[Runtime, V8Error] {
if handle == 0 {
Err(take_native_error(err_ptr, fallback))
} else if not(native_ptr_is_null(err_ptr)) {
Err(take_native_error(err_ptr, fallback))
} else {
Ok(Runtime::{
state: Ref::new(RuntimeState::{
handle,
async_loop: RuntimeAsyncLoopState::{
json_handlers: Map::new(),
bytes_handlers: Map::new(),
pending_tasks: 0,
is_running: false,
},
resources: RuntimeResourceTableState::{
next_rid: 1,
entries: Map::new(),
},
compat: RuntimeCompatState::{
has_deno_core_compat: false,
has_node_compat: false,
},
}),
})
}
}
///|
pub fn runtime_new() -> Result[Runtime, V8Error] {
let err_ptr = make_ptr_buffer()
native_ptr_clear(err_ptr)
let handle = runtime_new_native(err_ptr)
runtime_from_handle(
handle,
err_ptr,
V8Error::DependencyMissing("failed to initialize V8 runtime"),
)
}
///|
pub fn runtime_new_with_snapshot(snapshot : Bytes) -> Result[Runtime, V8Error] {
let err_ptr = make_ptr_buffer()
native_ptr_clear(err_ptr)
let handle = runtime_new_with_snapshot_native(
snapshot,
snapshot.length(),
err_ptr,
)
runtime_from_handle(
handle,
err_ptr,
V8Error::NativeError("runtime_new_with_snapshot_native failed"),
)
}
///|
pub fn Runtime::is_closed(self : Runtime) -> Bool {
self.state.val.handle == 0
}
///|
pub fn Runtime::dispose(self : Runtime) -> Unit {
let handle = self.state.val.handle
if handle != 0 {
runtime_close_all_resources(self)
runtime_delete_native(handle)
self.state.val.handle = 0
}
}
///|
pub fn Runtime::load_module(
self : Runtime,
specifier : String,
source : String,
) -> Result[Unit, V8Error] {
let handle = self.state.val.handle
if handle == 0 {
return Err(V8Error::RuntimeClosed)
}
let err_ptr = make_ptr_buffer()
native_ptr_clear(err_ptr)
let specifier_bytes = @utf8.encode(specifier)
let source_bytes = @utf8.encode(source)
runtime_load_module_native(
handle,
specifier_bytes,
specifier_bytes.length(),
source_bytes,
source_bytes.length(),
err_ptr,
)
if not(native_ptr_is_null(err_ptr)) {
Err(
take_native_error(
err_ptr,
V8Error::NativeError("runtime_load_module_native failed"),
),
)
} else {
Ok(())
}
}
///|
pub fn Runtime::eval_string(
self : Runtime,
source : String,
) -> Result[String, V8Error] {
let handle = self.state.val.handle
if handle == 0 {
return Err(V8Error::RuntimeClosed)
}
let err_ptr = make_ptr_buffer()
native_ptr_clear(err_ptr)
let source_bytes = @utf8.encode(source)
let result_bytes = runtime_eval_native(
handle,
source_bytes,
source_bytes.length(),
err_ptr,
)
if not(native_ptr_is_null(err_ptr)) {
Err(
take_native_error(
err_ptr,
V8Error::NativeError("runtime_eval_native failed"),
),
)
} else {
Ok(@utf8.decode_lossy(result_bytes))
}
}
///|
pub fn Runtime::eval_string_with_name(
self : Runtime,
resource_name : String,
source : String,
) -> Result[String, V8Error] {
let handle = self.state.val.handle
if handle == 0 {
return Err(V8Error::RuntimeClosed)
}
let err_ptr = make_ptr_buffer()
native_ptr_clear(err_ptr)
let resource_name_bytes = @utf8.encode(resource_name)
let source_bytes = @utf8.encode(source)
let result_bytes = runtime_eval_with_name_native(
handle,
resource_name_bytes,
resource_name_bytes.length(),
source_bytes,
source_bytes.length(),
err_ptr,
)
if not(native_ptr_is_null(err_ptr)) {
Err(
take_native_error(
err_ptr,
V8Error::NativeError("runtime_eval_with_name_native failed"),
),
)
} else {
Ok(@utf8.decode_lossy(result_bytes))
}
}
///|
pub fn Runtime::perform_microtask_checkpoint(
self : Runtime,
) -> Result[Unit, V8Error] {
let handle = self.state.val.handle
if handle == 0 {
return Err(V8Error::RuntimeClosed)
}
let err_ptr = make_ptr_buffer()
native_ptr_clear(err_ptr)
runtime_perform_microtask_checkpoint_native(handle, err_ptr)
if not(native_ptr_is_null(err_ptr)) {
Err(
take_native_error(
err_ptr,
V8Error::NativeError(
"runtime_perform_microtask_checkpoint_native failed",
),
),
)
} else {
Ok(())
}
}
///|
pub fn Runtime::eval_async_string_with_name(
self : Runtime,
resource_name : String,
source : String,
) -> Result[String, V8Error] {
let handle = self.state.val.handle
if handle == 0 {
return Err(V8Error::RuntimeClosed)
}
let err_ptr = make_ptr_buffer()
native_ptr_clear(err_ptr)
let resource_name_bytes = @utf8.encode(resource_name)
let source_bytes = @utf8.encode(source)
let result_bytes = runtime_eval_async_with_name_native(
handle,
resource_name_bytes,
resource_name_bytes.length(),
source_bytes,
source_bytes.length(),
err_ptr,
)
if not(native_ptr_is_null(err_ptr)) {
Err(
take_native_error(
err_ptr,
V8Error::NativeError("runtime_eval_async_with_name_native failed"),
),
)
} else {
Ok(@utf8.decode_lossy(result_bytes))
}
}
///|
pub fn Runtime::eval_async_string(
self : Runtime,
source : String,
) -> Result[String, V8Error] {
let handle = self.state.val.handle
if handle == 0 {
return Err(V8Error::RuntimeClosed)
}
let err_ptr = make_ptr_buffer()
native_ptr_clear(err_ptr)
let source_bytes = @utf8.encode(source)
let result_bytes = runtime_eval_async_native(
handle,
source_bytes,
source_bytes.length(),
err_ptr,
)
if not(native_ptr_is_null(err_ptr)) {
Err(
take_native_error(
err_ptr,
V8Error::NativeError("runtime_eval_async_native failed"),
),
)
} else {
Ok(@utf8.decode_lossy(result_bytes))
}
}
///|
pub fn Runtime::eval_module_string_with_specifier(
self : Runtime,
specifier : String,
source : String,
) -> Result[String, V8Error] {
let handle = self.state.val.handle
if handle == 0 {
return Err(V8Error::RuntimeClosed)
}
let err_ptr = make_ptr_buffer()
native_ptr_clear(err_ptr)
let specifier_bytes = @utf8.encode(specifier)
let source_bytes = @utf8.encode(source)
let result_bytes = runtime_eval_module_with_specifier_native(
handle,
specifier_bytes,
specifier_bytes.length(),
source_bytes,
source_bytes.length(),
err_ptr,
)
if not(native_ptr_is_null(err_ptr)) {
Err(
take_native_error(
err_ptr,
V8Error::NativeError("runtime_eval_module_with_specifier_native failed"),
),
)
} else {
Ok(@utf8.decode_lossy(result_bytes))
}
}
///|
pub fn Runtime::eval_module_string(
self : Runtime,
source : String,
) -> Result[String, V8Error] {
let handle = self.state.val.handle
if handle == 0 {
return Err(V8Error::RuntimeClosed)
}
let err_ptr = make_ptr_buffer()
native_ptr_clear(err_ptr)
let source_bytes = @utf8.encode(source)
let result_bytes = runtime_eval_module_native(
handle,
source_bytes,
source_bytes.length(),
err_ptr,
)
if not(native_ptr_is_null(err_ptr)) {
Err(
take_native_error(
err_ptr,
V8Error::NativeError("runtime_eval_module_native failed"),
),
)
} else {
Ok(@utf8.decode_lossy(result_bytes))
}
}
///|
pub fn[T] with_runtime(
f : (Runtime) -> Result[T, V8Error],
) -> Result[T, V8Error] {
match runtime_new() {
Ok(runtime) => {
let result = f(runtime)
runtime.dispose()
result
}
Err(err) => Err(err)
}
}
///|
pub fn[T] with_runtime_with_snapshot(
snapshot : Bytes,
f : (Runtime) -> Result[T, V8Error],
) -> Result[T, V8Error] {
match runtime_new_with_snapshot(snapshot) {
Ok(runtime) => {
let result = f(runtime)
runtime.dispose()
result
}
Err(err) => Err(err)
}
}
///|
pub async fn[T] with_runtime_async(
f : async (Runtime) -> Result[T, V8Error],
) -> Result[T, V8Error] {
match runtime_new() {
Ok(runtime) => {
defer runtime.dispose()
f(runtime)
}
Err(err) => Err(err)
}
}
///|
pub async fn[T] with_runtime_with_snapshot_async(
snapshot : Bytes,
f : async (Runtime) -> Result[T, V8Error],
) -> Result[T, V8Error] {
match runtime_new_with_snapshot(snapshot) {
Ok(runtime) => {
defer runtime.dispose()
f(runtime)
}
Err(err) => Err(err)
}
}
///|
pub fn eval_string(source : String) -> Result[String, V8Error] {
with_runtime(fn(runtime) { runtime.eval_string(source) })
}
///|
pub fn eval_string_with_name(
resource_name : String,
source : String,
) -> Result[String, V8Error] {
with_runtime(fn(runtime) {
runtime.eval_string_with_name(resource_name, source)
})
}
///|
pub fn eval_async_string(source : String) -> Result[String, V8Error] {
with_runtime(fn(runtime) { runtime.eval_async_string(source) })
}
///|
pub fn eval_async_string_with_name(
resource_name : String,
source : String,
) -> Result[String, V8Error] {
with_runtime(fn(runtime) {
runtime.eval_async_string_with_name(resource_name, source)
})
}
///|
pub fn eval_module_string(source : String) -> Result[String, V8Error] {
with_runtime(fn(runtime) { runtime.eval_module_string(source) })
}
///|
pub fn eval_module_string_with_specifier(
specifier : String,
source : String,
) -> Result[String, V8Error] {
with_runtime(fn(runtime) {
runtime.eval_module_string_with_specifier(specifier, source)
})
}